Date: Tue, 7 Nov 2006 18:04:07 GMT From: Matt Jacob <mjacob@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 109456 for review Message-ID: <200611071804.kA7I47lx013444@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=109456 Change 109456 by mjacob@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. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611071804.kA7I47lx013444>