Make SCSI_DELAY setable at boot time and runtime via the
kern.cam.scsi_delay tunable/sysctl. Reviewed by: mdodd, njl
This commit is contained in:
parent
60c1ef970b
commit
3a93719872
@ -90,6 +90,7 @@ module_path="/boot/kernel;/boot/modules;/modules" # Set the module search path
|
||||
#kern.nbuf="" # Set the number of buffer headers
|
||||
#kern.ncallout="" # Set the maximum # of timer events
|
||||
#kern.sgrowsiz="" # Set the amount to grow stack
|
||||
#kern.cam.scsi_delay="2000" # Delay (in ms) before probing SCSI
|
||||
#kern.ipc.maxsockets="" # Set the maximum number of sockets avaliable
|
||||
#kern.ipc.nmbclusters="" # Set the number of mbuf clusters
|
||||
#kern.ipc.nmbufs="" # Set the maximum number of mbufs
|
||||
|
@ -1126,7 +1126,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:
|
||||
|
@ -5487,7 +5487,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);
|
||||
}
|
||||
@ -6760,9 +6760,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) {
|
||||
printf("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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -871,7 +871,9 @@ device pass #CAM passthrough 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user