Date: Wed, 28 Aug 2002 10:39:33 -0700 From: Brooks Davis <brooks@one-eyed-alien.net> To: scsi@freebsd.org Subject: [PATCH] make SCSI_DELAY tunable Message-ID: <20020828103933.A24804@Odin.AC.HMC.Edu>
next in thread | raw e-mail | index | archive | help
--azLHFNyN32YCQGCU Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable I've attached a patch which makes the value of SCSI_DELAY setable and boot time via a tunable and runtime via sysctl. With it applied you can set SCSI delay is follows: - The classic "options SCSI_DELAY=3D####" kernel option - "kern.cam.scsi_delay=3D####" in /boot/loader.conf - Stop the boot in the loader and enter "set kern.cam.scsi_delay=3D####" - sysctl kern.cam.scsi_delay=3D#### I wrote this to allow me to reduce the annoying boot delay without recompiling my kernel and it works well for that. My hope is that for 5.0 we can use this functionality to stop punishing everyone who uses SCSI for the sins of a few devices. This should allow us to remove "options SCSI_DELAY=3D15000" from GENERIC without impacting the ability to install on slow devices. I've tested the value setting on current and verified that it actually works with a slightly different patch to stable. Comments? Suggestions? -- Brooks Index: cam_periph.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /usr/cvs/src/sys/cam/cam_periph.c,v retrieving revision 1.41 diff -u -p -r1.41 cam_periph.c --- cam_periph.c 24 Aug 2002 02:51:28 -0000 1.41 +++ cam_periph.c 24 Aug 2002 08:08:23 -0000 @@ -1126,7 +1126,7 @@ cam_periph_async(struct cam_periph *peri 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: cam_xpt.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /usr/cvs/src/sys/cam/cam_xpt.c,v retrieving revision 1.125 diff -u -p -r1.125 cam_xpt.c --- cam_xpt.c 25 Aug 2002 13:16:48 -0000 1.125 +++ cam_xpt.c 27 Aug 2002 04:18:32 -0000 @@ -5487,7 +5487,7 @@ proberegister(struct cam_periph *periph, * 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 >=3D 2000) { + if (busses_to_reset > 0 && scsi_delay >=3D 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); } Index: scsi/scsi_all.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /usr/cvs/src/sys/cam/scsi/scsi_all.c,v retrieving revision 1.36 diff -u -p -r1.36 scsi_all.c --- scsi/scsi_all.c 26 Aug 2002 17:13:35 -0000 1.36 +++ scsi/scsi_all.c 27 Aug 2002 04:18:33 -0000 @@ -36,6 +36,8 @@ =20 #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 */ =20 +/* + * 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 v= alue" +#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 =20 #if !defined(SCSI_NO_OP_STRINGS) =20 @@ -2876,3 +2906,53 @@ scsi_static_inquiry_match(caddr_t inqbuf } return (-1); } + +#ifdef _KERNEL +static void +init_scsi_delay(void) +{ + int delay; + + delay =3D SCSI_DELAY; + TUNABLE_INT_FETCH("kern.cam.scsi_delay", &delay); + + if (set_scsi_delay(delay) !=3D 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 =3D scsi_delay; + error =3D sysctl_handle_int(oidp, &delay, sizeof(delay), req); + if (error !=3D 0 || req->newptr =3D=3D 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 =3D=3D 0) { + printf("cam: using minimum scsi_delay (%dms)\n", + SCSI_MIN_DELAY); + delay =3D SCSI_MIN_DELAY; + } + if (delay < SCSI_MIN_DELAY) + return (EINVAL); + scsi_delay =3D delay; + return (0); +} +#endif /* _KERNEL */ Index: scsi/scsi_all.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /usr/cvs/src/sys/cam/scsi/scsi_all.h,v retrieving revision 1.19 diff -u -p -r1.19 scsi_all.h --- scsi/scsi_all.h 4 Jun 2002 17:41:47 -0000 1.19 +++ scsi/scsi_all.h 16 Aug 2002 19:10:59 -0000 @@ -27,30 +27,11 @@ #include <sys/cdefs.h> =20 #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 =3D=3D 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 v= alue" -#endif +extern int scsi_delay; #endif /* _KERNEL */ =20 /* --azLHFNyN32YCQGCU Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQE9bQrUXY6L6fI4GtQRAuosAJ0b4xcvO4z1O8u5AHy4NovfCg/n1QCePP/2 01ONTM4OIHU3uI5BQuABdtw= =6ECY -----END PGP SIGNATURE----- --azLHFNyN32YCQGCU-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020828103933.A24804>