Fix reported_gone setting, missed in some cases.

This makes driver better track reported CAM_SEL_TIMEOUTs to properly
report device reappearance later.  This fixes target 0 not reappearing
after initiator mode disabled and then reenabled.

MFC after:	3 days
This commit is contained in:
Alexander Motin 2015-06-24 09:06:12 +00:00
parent 29033246a8
commit 5cbe3e8eee

View File

@ -4943,6 +4943,8 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
isp = (ispsoftc_t *)cam_sim_softc(sim);
mtx_assert(&isp->isp_lock, MA_OWNED);
isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
ISP_PCMD(ccb) = NULL;
if (isp->isp_state != ISP_RUNSTATE && ccb->ccb_h.func_code == XPT_SCSI_IO) {
isp_init(isp);
@ -4950,15 +4952,12 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
/*
* Lie. Say it was a selection timeout.
*/
ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
xpt_freeze_devq(ccb->ccb_h.path, 1);
xpt_done(ccb);
ccb->ccb_h.status = CAM_SEL_TIMEOUT;
isp_done((struct ccb_scsiio *) ccb);
return;
}
isp->isp_state = ISP_RUNSTATE;
}
isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
ISP_PCMD(ccb) = NULL;
switch (ccb->ccb_h.func_code) {
case XPT_SCSI_IO: /* Execute the requested I/O operation */
@ -4969,7 +4968,7 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
ccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(ccb);
isp_done((struct ccb_scsiio *) ccb);
break;
}
}
@ -4992,6 +4991,7 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
isp_prt(isp, ISP_LOGWARN, "out of PCMDs");
cam_freeze_devq(ccb->ccb_h.path);
cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
break;
}
@ -5024,10 +5024,8 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
} else {
isp_prt(isp, ISP_LOGDEBUG0, "%d.%d downtime (%d) > lim (%d)", XS_TGT(ccb), XS_LUN(ccb), ISP_FC_PC(isp, bus)->loop_down_time, lim);
}
ccb->ccb_h.status = CAM_SEL_TIMEOUT|CAM_DEV_QFRZN;
xpt_freeze_devq(ccb->ccb_h.path, 1);
isp_free_pcmd(isp, ccb);
xpt_done(ccb);
ccb->ccb_h.status = CAM_SEL_TIMEOUT;
isp_done((struct ccb_scsiio *) ccb);
break;
}
isp_prt(isp, ISP_LOGDEBUG0, "%d.%d retry later", XS_TGT(ccb), XS_LUN(ccb));
@ -5646,7 +5644,7 @@ isp_done(XS_T *sccb)
* gone. If it reappears, we'll need to issue a
* rescan.
*/
if (hdlidx > 0 && hdlidx < MAX_FC_TARG)
if (hdlidx >= 0 && hdlidx < MAX_FC_TARG)
fcp->portdb[hdlidx].reported_gone = 1;
}
if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
@ -5659,9 +5657,11 @@ isp_done(XS_T *sccb)
xpt_print(sccb->ccb_h.path, "cam completion status 0x%x\n", sccb->ccb_h.status);
}
if (callout_active(&PISP_PCMD(sccb)->wdog))
callout_stop(&PISP_PCMD(sccb)->wdog);
isp_free_pcmd(isp, (union ccb *) sccb);
if (ISP_PCMD(sccb)) {
if (callout_active(&PISP_PCMD(sccb)->wdog))
callout_stop(&PISP_PCMD(sccb)->wdog);
isp_free_pcmd(isp, (union ccb *) sccb);
}
xpt_done((union ccb *) sccb);
}