PERFORCE change 109456 for review
Matt Jacob
mjacob at FreeBSD.org
Tue Nov 7 18:04:09 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=109456
Change 109456 by mjacob at newisp on 2006/11/07 18:03:41
Move code that cleans up after dead or new devices into
the outer layer where policy can be applied.
Affected files ...
.. //depot/projects/newisp/dev/isp/isp.c#27 edit
.. //depot/projects/newisp/dev/isp/isp_freebsd.c#19 edit
.. //depot/projects/newisp/dev/isp/ispvar.h#11 edit
Differences ...
==== //depot/projects/newisp/dev/isp/isp.c#27 (text+ko) ====
@@ -2757,11 +2757,10 @@
switch (lp->state) {
case FC_PORTDB_STATE_PROBATIONAL:
case FC_PORTDB_STATE_DEAD:
+ /*
+ * It's up to the outer layers to clear isp_ini_map.
+ */
isp_async(isp, ISPASYNC_DEV_GONE, lp);
- if (lp->ini_map_idx) {
- fcp->isp_ini_map[lp->ini_map_idx-1] = 0;
- lp->ini_map_idx = 0;
- }
lp->state = FC_PORTDB_STATE_NIL;
if (lp->autologin == 0) {
if (IS_24XX(isp)) {
@@ -2790,53 +2789,40 @@
*/
lp->portid = lp->new_portid;
lp->roles = lp->new_roles;
+ /*
+ * It's up to the outer layers to assign a virtual
+ * target id in isp_ini_map (if any).
+ */
+ isp_async(isp, ISPASYNC_DEV_ARRIVED, lp);
lp->state = FC_PORTDB_STATE_VALID;
- if ((isp->isp_role & ISP_ROLE_INITIATOR) &&
- (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
- int i, t = dbidx;
- for (i = 0; i < MAX_FC_TARG; i++) {
- if (i < FL_ID || i > SNS_ID) {
- if (fcp->isp_ini_map[t] == 0) {
- break;
- }
- }
- if (++t == MAX_FC_TARG) {
- t = 0;
- }
- }
- if (i < MAX_FC_TARG) {
- fcp->isp_ini_map[t] = dbidx + 1;
- lp->ini_map_idx = t + 1;
- } else {
- isp_prt(isp, ISP_LOGWARN,
- "out of target ids");
- }
- }
- isp_async(isp, ISPASYNC_DEV_ARRIVED, lp);
lp->new_roles = 0;
lp->new_portid = 0;
break;
case FC_PORTDB_STATE_CHANGED:
+ /*
+ * For now, just have a policy of accepting 'changed'
+ * devices.
+ */
lp->portid = lp->new_portid;
lp->roles = lp->new_roles;
- lp->state = FC_PORTDB_STATE_VALID;
if (lp->ini_map_idx) {
int t = lp->ini_map_idx - 1;
fcp->isp_ini_map[t] = dbidx + 1;
}
isp_async(isp, ISPASYNC_DEV_CHANGED, lp);
+ lp->state = FC_PORTDB_STATE_VALID;
lp->new_roles = 0;
lp->new_portid = 0;
break;
case FC_PORTDB_STATE_PENDING_VALID:
lp->portid = lp->new_portid;
lp->roles = lp->new_roles;
- lp->state = FC_PORTDB_STATE_VALID;
if (lp->ini_map_idx) {
int t = lp->ini_map_idx - 1;
fcp->isp_ini_map[t] = dbidx + 1;
}
isp_async(isp, ISPASYNC_DEV_STAYED, lp);
+ lp->state = FC_PORTDB_STATE_VALID;
if (dbidx != FL_ID) {
lp->new_roles = 0;
lp->new_portid = 0;
@@ -3950,7 +3936,7 @@
ispreq_t *reqp, *qep;
void *cdbp;
uint16_t *tptr;
- int target, i;
+ int target, i, hdlidx = 0;
XS_INITERR(xs);
isp = XS_ISP(xs);
@@ -4006,14 +3992,14 @@
return (CMD_COMPLETE);
}
- i = fcp->isp_ini_map[XS_TGT(xs)];
+ hdlidx = fcp->isp_ini_map[XS_TGT(xs)] - 1;
isp_prt(isp, ISP_LOGDEBUG1, "XS_TGT(xs)=%d- handle value %d",
- XS_TGT(xs), i);
- if (i < 1 || i >= MAX_FC_TARG) {
+ XS_TGT(xs), hdlidx);
+ if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
XS_SETERR(xs, HBA_SELTIMEOUT);
return (CMD_COMPLETE);
}
- target = fcp->portdb[i - 1].handle;
+ target = fcp->portdb[hdlidx].handle;
}
/*
@@ -4141,9 +4127,7 @@
} else if (IS_24XX(isp)) {
fcportdb_t *lp;
- i = FCPARAM(isp)->isp_ini_map[XS_TGT(xs)] - 1;
- lp = &FCPARAM(isp)->portdb[i];
-
+ lp = &FCPARAM(isp)->portdb[hdlidx];
((ispreqt7_t *)reqp)->req_nphdl = target;
((ispreqt7_t *)reqp)->req_tidlo = lp->portid;
((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16;
==== //depot/projects/newisp/dev/isp/isp_freebsd.c#19 (text+ko) ====
@@ -49,6 +49,7 @@
int isp_fabric_hysteresis = 5;
int isp_loop_down_limit = 300; /* default loop down limit */
int isp_quickboot_time = 5; /* don't wait more than N secs for loop up */
+int isp_lost_device_time = 30; /* grace time before reporting device lost */
static d_ioctl_t ispioctl;
static void isp_intr_enable(void *);
@@ -2918,7 +2919,26 @@
break;
case ISPASYNC_DEV_ARRIVED:
lp = arg;
+ if ((isp->isp_role & ISP_ROLE_INITIATOR) &&
+ (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
+ int dbidx = lp - FCPARAM(isp)->portdb;
+ int i;
+ for (i = 0; i < MAX_FC_TARG; i++) {
+ if (i >= FL_ID || i <= SNS_ID) {
+ continue;
+ }
+ if (FCPARAM(isp)->isp_ini_map[i] == 0) {
+ break;
+ }
+ }
+ if (i < MAX_FC_TARG) {
+ FCPARAM(isp)->isp_ini_map[i] = dbidx + 1;
+ lp->ini_map_idx = i + 1;
+ } else {
+ isp_prt(isp, ISP_LOGWARN, "out of target ids");
+ }
+ }
if (lp->ini_map_idx) {
tgt = lp->ini_map_idx - 1;
isp_prt(isp, ISP_LOGCONFIG, prom2,
@@ -2995,7 +3015,12 @@
case ISPASYNC_DEV_GONE:
lp = arg;
if (lp->ini_map_idx) {
+/*
+ * XXX: HERE IS WHERE WE'D START A TIMER
+ */
tgt = lp->ini_map_idx - 1;
+ FCPARAM(isp)->isp_ini_map[tgt] = 0;
+ lp->ini_map_idx = 0;
isp_prt(isp, ISP_LOGCONFIG, prom2,
lp->portid, lp->handle,
roles[lp->roles & 0x3], "departed from", tgt,
==== //depot/projects/newisp/dev/isp/ispvar.h#11 (text+ko) ====
@@ -75,7 +75,7 @@
* Overall parameters
*/
#define MAX_TARGETS 16
-#define MAX_FC_TARG 256
+#define MAX_FC_TARG 512
#define ISP_MAX_TARGETS(isp) (IS_FC(isp)? MAX_FC_TARG : MAX_TARGETS)
#define ISP_MAX_LUNS(isp) (isp)->isp_maxluns
@@ -303,7 +303,26 @@
* value.
*/
typedef struct {
+ /*
+ * This is the handle that the firmware needs in order for us to
+ * send commands to the device. For pre-24XX cards, this would be
+ * the 'loopid'.
+ */
uint16_t handle;
+ /*
+ * The ini_map_idx, if nonzero, is the system virtual target ID (+1)
+ * as a cross-reference with the isp_ini_map.
+ *
+ * A device is 'autologin' if the firmware automatically logs into
+ * it (re-logins as needed). Basically, local private loop devices.
+ *
+ * The state is the current state of thsi entry.
+ *
+ * Role is Initiator, Target, Both
+ *
+ * Portid is obvious, as or node && port WWNs. The new_role and
+ * new_portid is for when we are pending a change.
+ */
uint16_t ini_map_idx : 12,
autologin : 1, /* F/W does PLOGI/PLOGO */
state : 3;
@@ -357,8 +376,21 @@
uint16_t isp_maxfrmlen;
uint64_t isp_nodewwn;
uint64_t isp_portwwn;
+
+ /*
+ * Our Port Data Base
+ */
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_ini_map[MAX_FC_TARG];
+
/*
* Scratch DMA mapped in area to fetch Port Database stuff, etc.
*/
More information about the p4-projects
mailing list