Make SCSI_DELAY setable at boot time and runtime via the
authorPeter Avalos <pavalos@dragonflybsd.org>
Sat, 24 Nov 2007 19:19:43 +0000 (19:19 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Sat, 24 Nov 2007 19:19:43 +0000 (19:19 +0000)
kern.cam.scsi_delay tunable/sysctl.

Obtained-from: FreeBSD

sys/bus/cam/cam_periph.c
sys/bus/cam/cam_xpt.c
sys/bus/cam/scsi/scsi_all.c
sys/bus/cam/scsi/scsi_all.h
sys/config/LINT

index 56894bc..9775f8e 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/cam/cam_periph.c,v 1.24.2.3 2003/01/25 19:04:40 dillon Exp $
- * $DragonFly: src/sys/bus/cam/cam_periph.c,v 1.30 2007/11/24 18:55:27 pavalos Exp $
+ * $DragonFly: src/sys/bus/cam/cam_periph.c,v 1.31 2007/11/24 19:19:43 pavalos Exp $
  */
 
 #include <sys/param.h>
@@ -1105,7 +1105,7 @@ cam_periph_async(struct cam_periph *periph, u_int32_t code,
        case AC_SENT_BDR:
        case AC_BUS_RESET:
        {
-               cam_periph_bus_settle(periph, SCSI_DELAY);
+               cam_periph_bus_settle(periph, scsi_delay);
                break;
        }
        default:
index 4da668b..2e94ed2 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/cam/cam_xpt.c,v 1.80.2.18 2002/12/09 17:31:55 gibbs Exp $
- * $DragonFly: src/sys/bus/cam/cam_xpt.c,v 1.42 2007/11/21 20:29:34 pavalos Exp $
+ * $DragonFly: src/sys/bus/cam/cam_xpt.c,v 1.43 2007/11/24 19:19:43 pavalos Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -5358,7 +5358,7 @@ proberegister(struct cam_periph *periph, void *arg)
         * For HBAs that don't do bus resets, this won't make a difference.
         */
        cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset,
-                                     SCSI_DELAY);
+                                     scsi_delay);
        probeschedule(periph);
        return(CAM_REQ_CMP);
 }
@@ -6632,9 +6632,9 @@ xpt_config(void *arg)
                /* Call manually because we don't have any busses */
                xpt_finishconfig(xpt_periph, NULL);
        } else  {
-               if (busses_to_reset > 0 && SCSI_DELAY >= 2000) {
+               if (busses_to_reset > 0 && scsi_delay >= 2000) {
                        kprintf("Waiting %d seconds for SCSI "
-                              "devices to settle\n", SCSI_DELAY/1000);
+                              "devices to settle\n", scsi_delay/1000);
                }
                xpt_for_all_busses(xptconfigfunc, NULL);
        }
index 3314e80..6654bb0 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.14.2.11 2003/10/30 15:06:35 thomas Exp $
- * $DragonFly: src/sys/bus/cam/scsi/scsi_all.c,v 1.19 2007/11/24 03:48:31 pavalos Exp $
+ * $DragonFly: src/sys/bus/cam/scsi/scsi_all.c,v 1.20 2007/11/24 19:19:43 pavalos Exp $
  */
 
 #include <sys/param.h>
@@ -37,6 +37,8 @@
 #include <opt_scsi.h>
 #include <sys/systm.h>
 #include <sys/libkern.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
 
 #else
 
 #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)
 
@@ -2934,6 +2964,56 @@ scsi_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) {
+               kprintf("cam: invalid value for tunable kern.cam.scsi_delay\n");
+               set_scsi_delay(SCSI_DELAY);
+       }
+}
+SYSINIT(scsi_delay, SI_BOOT1_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) {
+               kprintf("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 */
+
 /*      
  * Try make as good a match as possible with
  * available sub drivers
index 2779250..1759afa 100644 (file)
@@ -15,7 +15,7 @@
  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
  *
  * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.14.2.5 2003/08/24 03:26:37 ken Exp $
- * $DragonFly: src/sys/bus/cam/scsi/scsi_all.h,v 1.10 2007/11/24 03:48:31 pavalos Exp $
+ * $DragonFly: src/sys/bus/cam/scsi/scsi_all.h,v 1.11 2007/11/24 19:19:43 pavalos Exp $
  */
 
 /*
 #endif
 
 #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 */
 
 /*
index 0e71ac0..9f03dd2 100644 (file)
@@ -3,7 +3,7 @@
 #      as much of the source tree as it can.
 #
 # $FreeBSD: src/sys/i386/conf/LINT,v 1.749.2.144 2003/06/04 17:56:59 sam Exp $
-# $DragonFly: src/sys/config/LINT,v 1.141 2007/11/19 18:49:06 swildner Exp $
+# $DragonFly: src/sys/config/LINT,v 1.142 2007/11/24 19:19:43 pavalos Exp $
 #
 # NB: You probably don't want to try running a kernel built from this
 # file.  Instead, you should start from GENERIC, and add options from
@@ -938,7 +938,9 @@ device              ses                     #SCSI SES/SAF-TE driver
 # SCSI_NO_OP_STRINGS: When defined disables opcode descriptions
 # SCSI_DELAY: The number of MILLISECONDS to freeze the SIM (scsi adapter)
 #             queue after a bus reset, and the number of milliseconds to
-#             freeze the device queue after a bus device reset.
+#             freeze the device queue after a bus device reset.  This
+#             can be changed at boot and runtime with the
+#             kern.cam.scsi_delay tunable/sysctl.
 options        CAMDEBUG
 options        CAM_DEBUG_BUS=-1
 options        CAM_DEBUG_TARGET=-1