diff options
author | brooks <brooks@FreeBSD.org> | 2002-09-02 20:10:19 +0000 |
---|---|---|
committer | brooks <brooks@FreeBSD.org> | 2002-09-02 20:10:19 +0000 |
commit | 72b448e706244b9c665f0ca48de5089bbf50d3d6 (patch) | |
tree | 0ecb65789811cff145c2da6d43f3e4a676db3941 /sys/cam/scsi | |
parent | f72048605bd3c2d2e2d67f14af1e86ec5068b6d1 (diff) | |
download | FreeBSD-src-72b448e706244b9c665f0ca48de5089bbf50d3d6.zip FreeBSD-src-72b448e706244b9c665f0ca48de5089bbf50d3d6.tar.gz |
Make SCSI_DELAY setable at boot time and runtime via the
kern.cam.scsi_delay tunable/sysctl.
Reviewed by: mdodd, njl
Diffstat (limited to 'sys/cam/scsi')
-rw-r--r-- | sys/cam/scsi/scsi_all.c | 80 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_all.h | 21 |
2 files changed, 81 insertions, 20 deletions
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c index b6ca87d..d512ede 100644 --- a/sys/cam/scsi/scsi_all.c +++ b/sys/cam/scsi/scsi_all.c @@ -36,6 +36,8 @@ #include <sys/systm.h> #include <sys/libkern.h> +#include <sys/kernel.h> +#include <sys/sysctl.h> #else #include <errno.h> #include <stdio.h> @@ -61,12 +63,40 @@ #define EJUSTRETURN -2 /* don't modify regs, just return */ #endif /* !_KERNEL */ +/* + * This is the default number of seconds we wait for devices to settle + * after a SCSI bus reset. + */ +#ifndef SCSI_DELAY +#define SCSI_DELAY 2000 +#endif +/* + * All devices need _some_ sort of bus settle delay, so we'll set it to + * a minimum value of 100ms. + */ +#ifndef SCSI_MIN_DELAY +#define SCSI_MIN_DELAY 100 +#endif +/* + * Make sure the user isn't using seconds instead of milliseconds. + */ +#if (SCSI_DELAY < SCSI_MIN_DELAY) +#error "SCSI_DELAY is in milliseconds, not seconds! Please use a larger value" +#endif + +int scsi_delay; + static int ascentrycomp(const void *key, const void *member); static int senseentrycomp(const void *key, const void *member); static void fetchtableentries(int sense_key, int asc, int ascq, struct scsi_inquiry_data *, const struct sense_key_table_entry **, const struct asc_table_entry **); +#ifdef _KERNEL +static void init_scsi_delay(void); +static int sysctl_scsi_delay(SYSCTL_HANDLER_ARGS); +static int set_scsi_delay(int delay); +#endif #if !defined(SCSI_NO_OP_STRINGS) @@ -2876,3 +2906,53 @@ scsi_static_inquiry_match(caddr_t inqbuffer, caddr_t table_entry) } return (-1); } + +#ifdef _KERNEL +static void +init_scsi_delay(void) +{ + int delay; + + delay = SCSI_DELAY; + TUNABLE_INT_FETCH("kern.cam.scsi_delay", &delay); + + if (set_scsi_delay(delay) != 0) { + printf("cam: invalid value for tunable kern.cam.scsi_delay\n"); + set_scsi_delay(SCSI_DELAY); + } +} +SYSINIT(scsi_delay, SI_SUB_TUNABLES, SI_ORDER_ANY, init_scsi_delay, NULL); + +static int +sysctl_scsi_delay(SYSCTL_HANDLER_ARGS) +{ + int error, delay; + + delay = scsi_delay; + error = sysctl_handle_int(oidp, &delay, sizeof(delay), req); + if (error != 0 || req->newptr == NULL) + return (error); + return (set_scsi_delay(delay)); +} +SYSCTL_PROC(_kern_cam, OID_AUTO, scsi_delay, CTLTYPE_INT|CTLFLAG_RW, + 0, 0, sysctl_scsi_delay, "I", + "Delay to allow devices to settle after a SCSI bus reset (ms)"); + +static int +set_scsi_delay(int delay) +{ + /* + * If someone sets this to 0, we assume that they want the + * minimum allowable bus settle delay. + */ + if (delay == 0) { + printf("cam: using minimum scsi_delay (%dms)\n", + SCSI_MIN_DELAY); + delay = SCSI_MIN_DELAY; + } + if (delay < SCSI_MIN_DELAY) + return (EINVAL); + scsi_delay = delay; + return (0); +} +#endif /* _KERNEL */ diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h index 9c5993b..beef3d8 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -27,30 +27,11 @@ #include <sys/cdefs.h> #ifdef _KERNEL -#include "opt_scsi.h" /* * This is the number of seconds we wait for devices to settle after a SCSI * bus reset. */ -#ifndef SCSI_DELAY -#define SCSI_DELAY 2000 -#endif -/* - * If someone sets this to 0, we assume that they want the minimum - * allowable bus settle delay. All devices need _some_ sort of bus settle - * delay, so we'll set it to a minimum value of 100ms. - */ -#if (SCSI_DELAY == 0) -#undef SCSI_DELAY -#define SCSI_DELAY 100 -#endif - -/* - * Make sure the user isn't using seconds instead of milliseconds. - */ -#if (SCSI_DELAY < 100) -#error "SCSI_DELAY is in milliseconds, not seconds! Please use a larger value" -#endif +extern int scsi_delay; #endif /* _KERNEL */ /* |