diff options
author | mjacob <mjacob@FreeBSD.org> | 2006-10-01 20:23:50 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2006-10-01 20:23:50 +0000 |
commit | 6cd68f97024a4b96cccfc1e2d8dc99eabb1b2d89 (patch) | |
tree | fe95b26fbf2bc4fad9ba0d475b0ae79b1509195b /sys | |
parent | edf77ea5221566cc3b11741ce41f3eab02586221 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/cam/cam_periph.c | 24 |
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) { |