summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2006-10-01 20:23:50 +0000
committermjacob <mjacob@FreeBSD.org>2006-10-01 20:23:50 +0000
commit6cd68f97024a4b96cccfc1e2d8dc99eabb1b2d89 (patch)
treefe95b26fbf2bc4fad9ba0d475b0ae79b1509195b /sys/cam
parentedf77ea5221566cc3b11741ce41f3eab02586221 (diff)
downloadFreeBSD-src-6cd68f97024a4b96cccfc1e2d8dc99eabb1b2d89.zip
FreeBSD-src-6cd68f97024a4b96cccfc1e2d8dc99eabb1b2d89.tar.gz
Put a bit of hysteresis into both BUSY SCSI status returns
and CAM_RESRC_UNAVAIL returns. Delay a tunable amount for either between retries. This came up because the MPT IOC was returning "IOC out of resources" for some user and this caused a CAM_RESRC_UNAVAIL return. Putting a bit of delay between retries helped them out. There was some discussion that an async event should be used to clear CAM_RESRC_UNAVAIL. That's probably a better notion eventually. Reviewed by: scsi@freebsd.org (ade, scott) MFC after: 1 week
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/cam_periph.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index 35bfdbd..fcc80b8 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -86,6 +86,14 @@ struct periph_driver **periph_drivers;
MALLOC_DEFINE(M_CAMPERIPH, "CAM periph", "CAM peripheral buffers");
+static int periph_selto_delay = 1000;
+TUNABLE_INT("kern.cam.periph_selto_delay", &periph_selto_delay);
+static int periph_noresrc_delay = 500;
+TUNABLE_INT("kern.cam.periph_noresrc_delay", &periph_noresrc_delay);
+static int periph_busy_delay = 500;
+TUNABLE_INT("kern.cam.periph_busy_delay", &periph_busy_delay);
+
+
void
periphdriver_register(void *data)
{
@@ -1544,7 +1552,7 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
int error, printed = 0;
int openings;
u_int32_t relsim_flags;
- u_int32_t timeout;
+ u_int32_t timeout = 0;
action_string = NULL;
status = ccb->ccb_h.status;
@@ -1636,11 +1644,11 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
}
/*
- * Wait a second to give the device
+ * Wait a bit to give the device
* time to recover before we try again.
*/
relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT;
- timeout = 1000;
+ timeout = periph_selto_delay;
break;
}
}
@@ -1699,8 +1707,16 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
}
break;
case CAM_RESRC_UNAVAIL:
+ /* Wait a bit for the resource shortage to abate. */
+ timeout = periph_noresrc_delay;
+ /* FALLTHROUGH */
case CAM_BUSY:
- /* timeout??? */
+ if (timeout == 0) {
+ /* Wait a bit for the busy condition to abate. */
+ timeout = periph_busy_delay;
+ }
+ relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT;
+ /* FALLTHROUGH */
default:
/* decrement the number of retries */
if (ccb->ccb_h.retry_count > 0) {
OpenPOWER on IntegriCloud