summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-10-05 08:29:31 +0000
committermav <mav@FreeBSD.org>2015-10-05 08:29:31 +0000
commit587443b8f97f656b62f9baeabd7245ca7841a5fc (patch)
tree894c122d6c7d85eda1a1e1b4561200b442eaf1fb
parent276dc40196dce997277c3b88e26589ad7fc29d3b (diff)
downloadFreeBSD-src-587443b8f97f656b62f9baeabd7245ca7841a5fc.zip
FreeBSD-src-587443b8f97f656b62f9baeabd7245ca7841a5fc.tar.gz
MFC r285154: Remove extra level of target ID indirection (isp_dev_map).
FreeBSD never had limitation on number of target IDs, and there is no any other requirement to allocate them densely. Since slots of port database already populated just sequentially, there is no much need for another indirection to allocate sequentially too.
-rw-r--r--sys/dev/isp/isp.c79
-rw-r--r--sys/dev/isp/isp_freebsd.c65
-rw-r--r--sys/dev/isp/ispvar.h17
3 files changed, 39 insertions, 122 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index dd203a4..0e600d1 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -2233,9 +2233,6 @@ isp_del_all_init_entries(ispsoftc_t *isp, int chan)
lp = &fcp->portdb[i];
if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode)
continue;
- /*
- * It's up to the outer layers to clear isp_dev_map.
- */
lp->state = FC_PORTDB_STATE_NIL;
isp_async(isp, ISPASYNC_DEV_GONE, chan, lp, 1);
if (lp->autologin == 0) {
@@ -3007,9 +3004,6 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
switch (lp->state) {
case FC_PORTDB_STATE_PROBATIONAL:
case FC_PORTDB_STATE_DEAD:
- /*
- * It's up to the outer layers to clear isp_dev_map.
- */
lp->state = FC_PORTDB_STATE_NIL;
isp_async(isp, ISPASYNC_DEV_GONE, chan, lp, 0);
if (lp->autologin == 0) {
@@ -3029,10 +3023,6 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
*/
break;
case FC_PORTDB_STATE_NEW:
- /*
- * It's up to the outer layers to assign a virtual
- * target id in isp_dev_map (if any).
- */
lp->portid = lp->new_portid;
lp->prli_word3 = lp->new_prli_word3;
lp->state = FC_PORTDB_STATE_VALID;
@@ -3054,10 +3044,6 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
case FC_PORTDB_STATE_PENDING_VALID:
lp->portid = lp->new_portid;
lp->prli_word3 = lp->new_prli_word3;
- if (lp->dev_map_idx) {
- int t = lp->dev_map_idx - 1;
- fcp->isp_dev_map[t] = dbidx + 1;
- }
lp->state = FC_PORTDB_STATE_VALID;
isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
if (dbidx != FL_ID) {
@@ -4354,7 +4340,8 @@ isp_start(XS_T *xs)
ispreq_t *reqp;
void *cdbp, *qep;
uint16_t *tptr;
- int target, dmaresult, hdlidx = 0;
+ fcportdb_t *lp;
+ int target, dmaresult;
XS_INITERR(xs);
isp = XS_ISP(xs);
@@ -4403,29 +4390,23 @@ isp_start(XS_T *xs)
return (CMD_RQLATER);
}
- if (XS_TGT(xs) >= MAX_FC_TARG) {
- isp_prt(isp, ISP_LOG_WARN1, "%d.%d.%d target too big", XS_CHANNEL(xs), target, XS_LUN(xs));
+ isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d", target);
+ lp = &fcp->portdb[target];
+ if (target < 0 || target >= MAX_FC_TARG ||
+ lp->dev_map_idx == 0) {
XS_SETERR(xs, HBA_SELTIMEOUT);
return (CMD_COMPLETE);
}
-
- hdlidx = fcp->isp_dev_map[XS_TGT(xs)] - 1;
- isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d- hdlidx value %d", XS_TGT(xs), hdlidx);
- if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
- return (CMD_COMPLETE);
- }
- if (fcp->portdb[hdlidx].state == FC_PORTDB_STATE_ZOMBIE) {
+ if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
isp_prt(isp, ISP_LOGDEBUG1, "%d.%d.%d target zombie", XS_CHANNEL(xs), target, XS_LUN(xs));
return (CMD_RQLATER);
}
- if (fcp->portdb[hdlidx].state != FC_PORTDB_STATE_VALID) {
- isp_prt(isp, ISP_LOGDEBUG1, "%d.%d.%d bad db port state 0x%x", XS_CHANNEL(xs), target, XS_LUN(xs), fcp->portdb[hdlidx].state);
+ if (lp->state != FC_PORTDB_STATE_VALID) {
+ isp_prt(isp, ISP_LOGDEBUG1, "%d.%d.%d bad db port state 0x%x", XS_CHANNEL(xs), target, XS_LUN(xs), lp->state);
XS_SETERR(xs, HBA_SELTIMEOUT);
return (CMD_COMPLETE);
}
- target = fcp->portdb[hdlidx].handle;
- fcp->portdb[hdlidx].dirty = 1;
+ lp->dirty = 1;
} else {
sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
if ((sdp->role & ISP_ROLE_INITIATOR) == 0) {
@@ -4567,7 +4548,6 @@ isp_start(XS_T *xs)
reqp->req_cdblen = cdblen;
} else if (IS_24XX(isp)) {
ispreqt7_t *t7 = (ispreqt7_t *)local;
- fcportdb_t *lp;
if (cdblen > sizeof (t7->req_cdb)) {
isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
@@ -4575,8 +4555,7 @@ isp_start(XS_T *xs)
return (CMD_COMPLETE);
}
- lp = &FCPARAM(isp, XS_CHANNEL(xs))->portdb[hdlidx];
- t7->req_nphdl = target;
+ t7->req_nphdl = lp->handle;
t7->req_tidlo = lp->portid;
t7->req_tidhi = lp->portid >> 16;
t7->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
@@ -4596,14 +4575,12 @@ isp_start(XS_T *xs)
cdbp = t7->req_cdb;
} else {
ispreqt2_t *t2 = (ispreqt2_t *)local;
- fcportdb_t *lp;
if (cdblen > sizeof t2->req_cdb) {
isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
XS_SETERR(xs, HBA_BOTCH);
return (CMD_COMPLETE);
}
- lp = &FCPARAM(isp, XS_CHANNEL(xs))->portdb[hdlidx];
if (FCPARAM(isp, XS_CHANNEL(xs))->fctape_enabled && (lp->prli_word3 & PRLI_WD3_RETRY)) {
if (FCP_NEXT_CRN(isp, &t2->req_crn, xs)) {
isp_prt(isp, ISP_LOG_WARN1, "%d.%d.%d cannot generate next CRN", XS_CHANNEL(xs), target, XS_LUN(xs));
@@ -4613,16 +4590,16 @@ isp_start(XS_T *xs)
}
if (ISP_CAP_2KLOGIN(isp)) {
ispreqt2e_t *t2e = (ispreqt2e_t *)local;
- t2e->req_target = target;
+ t2e->req_target = lp->handle;
t2e->req_scclun = XS_LUN(xs);
cdbp = t2e->req_cdb;
} else if (ISP_CAP_SCCFW(isp)) {
ispreqt2_t *t2 = (ispreqt2_t *)local;
- t2->req_target = target;
+ t2->req_target = lp->handle;
t2->req_scclun = XS_LUN(xs);
cdbp = t2->req_cdb;
} else {
- t2->req_target = target;
+ t2->req_target = lp->handle;
t2->req_lun_trn = XS_LUN(xs);
cdbp = t2->req_cdb;
}
@@ -4720,16 +4697,15 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
isp24xx_statusreq_t *sp;
fcparam *fcp = FCPARAM(isp, chan);
fcportdb_t *lp;
- int hdlidx;
- hdlidx = fcp->isp_dev_map[tgt] - 1;
- if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
- isp_prt(isp, ISP_LOGWARN, "Chan %d bad handle %d trying to reset target %d", chan, hdlidx, tgt);
+ if (tgt < 0 || tgt >= MAX_FC_TARG) {
+ isp_prt(isp, ISP_LOGWARN, "Chan %d trying to reset bad target %d", chan, tgt);
break;
}
- lp = &fcp->portdb[hdlidx];
- if (lp->state != FC_PORTDB_STATE_VALID) {
- isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d for abort of target %d no longer valid", chan, hdlidx, tgt);
+ lp = &fcp->portdb[tgt];
+ if (lp->dev_map_idx == 0 ||
+ lp->state != FC_PORTDB_STATE_VALID) {
+ isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
break;
}
@@ -4810,17 +4786,16 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
isp24xx_abrt_t local, *ab = &local, *ab2;
fcparam *fcp;
fcportdb_t *lp;
- int hdlidx;
fcp = FCPARAM(isp, chan);
- hdlidx = fcp->isp_dev_map[tgt] - 1;
- if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
- isp_prt(isp, ISP_LOGWARN, "Chan %d bad handle %d trying to abort target %d", chan, hdlidx, tgt);
+ if (tgt < 0 || tgt >= MAX_FC_TARG) {
+ isp_prt(isp, ISP_LOGWARN, "Chan %d trying to abort bad target %d", chan, tgt);
break;
}
- lp = &fcp->portdb[hdlidx];
- if (lp->state != FC_PORTDB_STATE_VALID) {
- isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d for abort of target %d no longer valid", chan, hdlidx, tgt);
+ lp = &fcp->portdb[tgt];
+ if (lp->dev_map_idx == 0 ||
+ lp->state != FC_PORTDB_STATE_VALID) {
+ isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
break;
}
isp_prt(isp, ISP_LOGALL, "Chan %d Abort Cmd for N-Port 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
@@ -4860,7 +4835,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
return (0);
}
- isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d abort returned 0x%x", chan, hdlidx, ab->abrt_nphdl);
+ isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d abort returned 0x%x", chan, tgt, ab->abrt_nphdl);
break;
} else if (IS_FC(isp)) {
if (ISP_CAP_SCCFW(isp)) {
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index ba49baa..194049a 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -4684,7 +4684,7 @@ isp_gdt_task(void *arg, int pending)
ispsoftc_t *isp = fc->isp;
int chan = fc - isp->isp_osinfo.pc.fc;
fcportdb_t *lp;
- int dbidx, tgt, more_to_do = 0;
+ int dbidx, more_to_do = 0;
ISP_LOCK(isp);
isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GDT timer expired", chan);
@@ -4703,12 +4703,10 @@ isp_gdt_task(void *arg, int pending)
more_to_do++;
continue;
}
- tgt = lp->dev_map_idx - 1;
- FCPARAM(isp, chan)->isp_dev_map[tgt] = 0;
lp->dev_map_idx = 0;
lp->state = FC_PORTDB_STATE_NIL;
- isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, tgt, "Gone Device Timeout");
- isp_make_gone(isp, lp, chan, tgt);
+ isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, dbidx, "Gone Device Timeout");
+ isp_make_gone(isp, lp, chan, dbidx);
}
if (fc->ready) {
if (more_to_do) {
@@ -4744,7 +4742,7 @@ isp_ldt_task(void *arg, int pending)
ispsoftc_t *isp = fc->isp;
int chan = fc - isp->isp_osinfo.pc.fc;
fcportdb_t *lp;
- int dbidx, tgt, i;
+ int dbidx, i;
ISP_LOCK(isp);
isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop Down Timer expired @ %lu", chan, (unsigned long) time_uptime);
@@ -4777,7 +4775,7 @@ isp_ldt_task(void *arg, int pending)
if ((xs = isp->isp_xflist[i].cmd) == NULL) {
continue;
}
- if (dbidx != (FCPARAM(isp, chan)->isp_dev_map[XS_TGT(xs)] - 1)) {
+ if (dbidx != XS_TGT(xs)) {
continue;
}
isp_prt(isp, ISP_LOGWARN, "command handle 0x%x for %d.%d.%d orphaned by loop down timeout",
@@ -4788,20 +4786,10 @@ isp_ldt_task(void *arg, int pending)
* Mark that we've announced that this device is gone....
*/
lp->announced = 1;
-
- /*
- * but *don't* change the state of the entry. Just clear
- * any target id stuff and announce to CAM that the
- * device is gone. This way any necessary PLOGO stuff
- * will happen when loop comes back up.
- */
-
- tgt = lp->dev_map_idx - 1;
- FCPARAM(isp, chan)->isp_dev_map[tgt] = 0;
lp->dev_map_idx = 0;
lp->state = FC_PORTDB_STATE_NIL;
- isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, tgt, "Loop Down Timeout");
- isp_make_gone(isp, lp, chan, tgt);
+ isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, dbidx, "Loop Down Timeout");
+ isp_make_gone(isp, lp, chan, dbidx);
}
if (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR) {
@@ -5297,7 +5285,6 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
fcparam *fcp = FCPARAM(isp, bus);
struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc;
- unsigned int hdlidx;
cts->protocol = PROTO_SCSI;
cts->protocol_version = SCSI_REV_2;
@@ -5309,9 +5296,8 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
fc->valid = CTS_FC_VALID_SPEED;
fc->bitrate = 100000;
fc->bitrate *= fcp->isp_gbspeed;
- hdlidx = fcp->isp_dev_map[tgt] - 1;
- if (hdlidx < MAX_FC_TARG) {
- fcportdb_t *lp = &fcp->portdb[hdlidx];
+ if (tgt < MAX_FC_TARG) {
+ fcportdb_t *lp = &fcp->portdb[tgt];
fc->wwnn = lp->node_wwn;
fc->wwpn = lp->port_wwn;
fc->port = lp->portid;
@@ -5632,17 +5618,9 @@ isp_done(XS_T *sccb)
else if ((IS_FC(isp))
&& (XS_TGT(sccb) < MAX_FC_TARG)) {
fcparam *fcp;
- int hdlidx;
fcp = FCPARAM(isp, XS_CHANNEL(sccb));
- hdlidx = fcp->isp_dev_map[XS_TGT(sccb)] - 1;
- /*
- * Note that we have reported that this device is
- * gone. If it reappears, we'll need to issue a
- * rescan.
- */
- if (hdlidx >= 0 && hdlidx < MAX_FC_TARG)
- fcp->portdb[hdlidx].reported_gone = 1;
+ fcp->portdb[XS_TGT(sccb)].reported_gone = 1;
}
if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
sccb->ccb_h.status |= CAM_DEV_QFRZN;
@@ -5811,24 +5789,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
lp->announced = 0;
lp->gone_timer = 0;
if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) && (lp->prli_word3 & PRLI_WD3_TARGET_FUNCTION)) {
- int dbidx = lp - FCPARAM(isp, bus)->portdb;
- int i;
-
- for (i = 0; i < MAX_FC_TARG; i++) {
- if (i >= FL_ID && i <= SNS_ID) {
- continue;
- }
- if (FCPARAM(isp, bus)->isp_dev_map[i] == 0) {
- break;
- }
- }
- if (i < MAX_FC_TARG) {
- FCPARAM(isp, bus)->isp_dev_map[i] = dbidx + 1;
- lp->dev_map_idx = i + 1;
- } else {
- isp_prt(isp, ISP_LOGWARN, "out of target ids");
- isp_dump_portdb(isp, bus);
- }
+ lp->dev_map_idx = (lp - FCPARAM(isp, bus)->portdb) + 1;
}
isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
if (lp->dev_map_idx) {
@@ -5852,7 +5813,6 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
lp->state = FC_PORTDB_STATE_NIL;
if (lp->dev_map_idx) {
tgt = lp->dev_map_idx - 1;
- FCPARAM(isp, bus)->isp_dev_map[tgt] = 0;
lp->dev_map_idx = 0;
isp_prt(isp, ISP_LOGCONFIG, prom3, bus, lp->portid, tgt, "change is bad");
isp_make_gone(isp, lp, bus, tgt);
@@ -5866,8 +5826,6 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
lp->prli_word3 = lp->new_prli_word3;
isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
if (lp->dev_map_idx) {
- int t = lp->dev_map_idx - 1;
- FCPARAM(isp, bus)->isp_dev_map[t] = (lp - FCPARAM(isp, bus)->portdb) + 1;
tgt = lp->dev_map_idx - 1;
isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "changed at", tgt,
(uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
@@ -5922,7 +5880,6 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
if (lp->dev_map_idx && lp->announced == 0 && now) {
lp->announced = 1;
tgt = lp->dev_map_idx - 1;
- FCPARAM(isp, bus)->isp_dev_map[tgt] = 0;
lp->dev_map_idx = 0;
isp_make_gone(isp, lp, bus, tgt);
isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "gone at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index 150073e..27167fa 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -344,12 +344,7 @@ typedef struct {
* devices) or by the driver (e.g., for fabric devices).
*
* It has a state. If the state if VALID, that means that we've logged into
- * the device. We also *may* have a initiator map index entry. This is a value
- * from 0..MAX_FC_TARG that is used to index into the isp_dev_map array. If
- * the value therein is non-zero, then that value minus one is used to index
- * into the Port Database to find the handle for forming commands. There is
- * back-index minus one value within to Port Database entry that tells us
- * which entry in isp_dev_map points to us (to avoid searching).
+ * the device.
*
* Local loop devices the firmware automatically performs PLOGI on for us
* (which is why that handle is imposed upon us). Fabric devices we assign
@@ -395,7 +390,6 @@ typedef struct {
/*
* The dev_map_idx, if nonzero, is the system virtual target ID (+1)
- * as a cross-reference with the isp_dev_map.
*
* A device is 'autologin' if the firmware automatically logs into
* it (re-logins as needed). Basically, local private loop devices.
@@ -491,15 +485,6 @@ typedef struct {
*/
fcportdb_t portdb[MAX_FC_TARG];
- /*
- * This maps system virtual 'target' id to a portdb entry.
- *
- * The mapping function is to take any non-zero entry and
- * subtract one to get the portdb index. This means that
- * entries which are zero are unmapped (i.e., don't exist).
- */
- uint16_t isp_dev_map[MAX_FC_TARG];
-
#ifdef ISP_TARGET_MODE
/*
* This maps N-Port Handle to portdb entry so we
OpenPOWER on IntegriCloud