Remove ISP_SMPLOCK stuff- we're just using locking now.

Correctly reintroduce loop_seen_once semantics- that is, if we've never
seen good link, start bouncing commands with CAM_SEL_TIMEOUT. But we
have to be careful to have let ourselves try (in isp_kthread) to check
for loop up at least once.

PR:		28992
MFC after:	1 week
This commit is contained in:
Matt Jacob 2001-07-25 04:23:52 +00:00
parent 3910362ab8
commit f44257c29a

View File

@ -1681,7 +1681,8 @@ isp_watchdog(void *arg)
ISP_UNLOCK(isp);
}
#ifdef ISP_SMPLOCK
static int isp_ktmature = 0;
static void
isp_kthread(void *arg)
{
@ -1692,14 +1693,22 @@ isp_kthread(void *arg)
for (;;) {
isp_prt(isp, ISP_LOGDEBUG0, "kthread checking FC state");
while (isp_fc_runstate(isp, 2 * 1000000) != 0) {
#if 0
msleep(&lbolt, &isp->isp_lock,
PRIBIO, "isp_fcthrd", 0);
#else
if (FCPARAM(isp)->isp_fwstate != FW_READY ||
FCPARAM(isp)->isp_loopstate < LOOP_PDB_RCVD) {
if (FCPARAM(isp)->loop_seen_once == 0 ||
isp_ktmature == 0) {
break;
}
}
msleep(isp_kthread, &isp->isp_lock,
PRIBIO, "isp_fcthrd", hz);
#endif
}
/*
* Even if we didn't get good loop state we may be
* unfreezing the SIMQ so that we can kill off
* commands (if we've never seen loop before, e.g.)
*/
isp_ktmature = 1;
wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN;
isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
@ -1711,31 +1720,7 @@ isp_kthread(void *arg)
cv_wait(&isp->isp_osinfo.kthread_cv, &isp->isp_lock);
}
}
#else
static void
isp_kthread(void *arg)
{
int wasfrozen;
struct ispsoftc *isp = arg;
mtx_lock(&Giant);
for (;;) {
isp_prt(isp, ISP_LOGDEBUG0, "kthread checking FC state");
while (isp_fc_runstate(isp, 2 * 1000000) != 0) {
tsleep(isp_kthread, PRIBIO, "isp_fcthrd", hz);
}
wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN;
isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
isp_prt(isp, ISP_LOGDEBUG0, "kthread up release simq");
ISPLOCK_2_CAMLOCK(isp);
xpt_release_simq(isp->isp_sim, 1);
CAMLOCK_2_ISPLOCK(isp);
}
tsleep(&isp->isp_osinfo.kthread_cv, PRIBIO, "isp_fc_worker", 0);
}
}
#endif
static void
isp_action(struct cam_sim *sim, union ccb *ccb)
{
@ -1820,20 +1805,21 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
ISPLOCK_2_CAMLOCK(isp);
break;
case CMD_RQLATER:
#ifdef ISP_SMPLOCK
/*
* This can only happen for Fibre Channel
*/
KASSERT((IS_FC(isp)), ("CMD_RQLATER for FC only"));
if (FCPARAM(isp)->loop_seen_once == 0 && isp_ktmature) {
ISPLOCK_2_CAMLOCK(isp);
XS_SETERR(ccb, CAM_SEL_TIMEOUT);
xpt_done(ccb);
break;
}
cv_signal(&isp->isp_osinfo.kthread_cv);
#else
wakeup(&isp->isp_osinfo.kthread_cv);
#endif
if (isp->isp_osinfo.simqfrozen == 0) {
isp_prt(isp, ISP_LOGDEBUG2,
"RQLATER freeze simq");
#if 0
isp->isp_osinfo.simqfrozen |= SIMQFRZ_TIMED;
timeout(isp_relsim, isp, 500);
#else
isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
#endif
ISPLOCK_2_CAMLOCK(isp);
xpt_freeze_simq(sim, 1);
} else {
@ -2534,8 +2520,8 @@ isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
xpt_setup_ccb(&cts.ccb_h, tmppath, 1);
ISPLOCK_2_CAMLOCK(isp);
xpt_async(AC_TRANSFER_NEG, tmppath, &cts);
CAMLOCK_2_ISPLOCK(isp);
xpt_free_path(tmppath);
CAMLOCK_2_ISPLOCK(isp);
break;
}
case ISPASYNC_BUS_RESET:
@ -2609,6 +2595,7 @@ isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
};
fcparam *fcp = isp->isp_param;
int tgt = *((int *) arg);
int is_tgt_mask = (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
struct lportdb *lp = &fcp->portdb[tgt];
isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid,
@ -2625,29 +2612,29 @@ isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
CAMLOCK_2_ISPLOCK(isp);
break;
}
if (lp->valid && (lp->roles &
(SVC3_INI_ROLE >> SVC3_ROLE_SHIFT))) {
xpt_async(AC_FOUND_DEVICE, tmppath, NULL);
} else {
xpt_async(AC_LOST_DEVICE, tmppath, NULL);
/*
* Policy: only announce targets.
*/
if (lp->roles & is_tgt_mask) {
if (lp->valid) {
xpt_async(AC_FOUND_DEVICE, tmppath, NULL);
} else {
xpt_async(AC_LOST_DEVICE, tmppath, NULL);
}
}
CAMLOCK_2_ISPLOCK(isp);
xpt_free_path(tmppath);
CAMLOCK_2_ISPLOCK(isp);
break;
}
case ISPASYNC_CHANGE_NOTIFY:
if (arg == (void *) 1) {
if (arg == ISPASYNC_CHANGE_PDB) {
isp_prt(isp, ISP_LOGINFO,
"Name Server Database Changed");
} else {
"Port Database Changed");
} else if (arg == ISPASYNC_CHANGE_SNS) {
isp_prt(isp, ISP_LOGINFO,
"Name Server Database Changed");
}
#ifdef ISP_SMPLOCK
cv_signal(&isp->isp_osinfo.kthread_cv);
#else
wakeup(&isp->isp_osinfo.kthread_cv);
#endif
break;
case ISPASYNC_FABRIC_DEV:
{