summaryrefslogtreecommitdiffstats
path: root/sys/cam/scsi
diff options
context:
space:
mode:
authorbrooks <brooks@FreeBSD.org>2002-09-02 20:10:19 +0000
committerbrooks <brooks@FreeBSD.org>2002-09-02 20:10:19 +0000
commit72b448e706244b9c665f0ca48de5089bbf50d3d6 (patch)
tree0ecb65789811cff145c2da6d43f3e4a676db3941 /sys/cam/scsi
parentf72048605bd3c2d2e2d67f14af1e86ec5068b6d1 (diff)
downloadFreeBSD-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.c80
-rw-r--r--sys/cam/scsi/scsi_all.h21
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 */
/*
OpenPOWER on IntegriCloud