Add in a watchdog routine to catch cases where we've dropped the command.

Apparently the f/w has finished the command, but somehow an interrupt is
being lost. So, we just plain wedge when booting alphas.

This is a general routine we've needed for a while.
This commit is contained in:
Matt Jacob 2000-05-09 01:08:21 +00:00
parent 8df53a80dc
commit cc8df88b70
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=60220

View file

@ -37,8 +37,10 @@
static void isp_cam_async(void *, u_int32_t, struct cam_path *, void *);
static void isp_poll(struct cam_sim *);
static void isp_relsim(void *);
static timeout_t isp_timeout;
static void isp_action(struct cam_sim *, union ccb *);
static struct ispsoftc *isplist = NULL;
/* #define ISP_LUN0_ONLY 1 */
#ifdef DEBUG
@ -1195,6 +1197,28 @@ isp_relsim(void *arg)
splx(s);
}
static void
isp_timeout(void *arg)
{
ISP_SCSI_XFER_T *xs = arg;
struct ispsoftc *isp = XS_ISP(xs);
u_int32_t handle;
int s = splcam();
/*
* We've decide this command is dead. Make sure we're not trying
* to kill a command that's already dead by getting it's handle.
*/
handle = isp_find_handle(isp, xs);
if (handle) {
isp_destroy_handle(isp, handle);
xpt_print_path(xs->ccb_h.path);
printf("watchdog timeout (handle 0x%x)\n", handle);
XS_SETERR(xs, CAM_CMD_TIMEOUT);
isp_done(xs);
}
(void) splx(s);
}
static void
isp_action(struct cam_sim *sim, union ccb *ccb)
{
@ -1265,6 +1289,13 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
switch (error) {
case CMD_QUEUED:
ccb->ccb_h.status |= CAM_SIM_QUEUED;
if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT)
ccb->ccb_h.timeout = 5 * 1000;
ccb->ccb_h.timeout_ch =
timeout(isp_timeout, (caddr_t)ccb,
(ccb->ccb_h.timeout * hz) / 1000);
}
break;
case CMD_RQLATER:
if (isp->isp_osinfo.simqfrozen == 0) {
@ -1308,8 +1339,6 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
break;
case XPT_NOTIFY_ACK: /* recycle notify ack */
xpt_print_path(ccb->ccb_h.path);
printf("notify ack\n");
case XPT_IMMED_NOTIFY: /* Add Immediate Notify Resource */
case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */
{
@ -1728,6 +1757,7 @@ isp_done(struct ccb_scsiio *sccb)
xpt_print_path(sccb->ccb_h.path);
printf("cam completion status 0x%x\n", sccb->ccb_h.status);
}
untimeout(isp_timeout, (caddr_t)sccb, sccb->ccb_h.timeout_ch);
xpt_done((union ccb *) sccb);
}