From f0f25b9c80d8039952cb10874ee0748e5f9cb8a6 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 7 Jun 2012 10:05:51 +0000 Subject: [PATCH] To make CAM debugging easier, compile in some debug flags (CAM_DEBUG_INFO, CAM_DEBUG_CDB, CAM_DEBUG_PERIPH and CAM_DEBUG_PROBE) by default. List of these flags can be modified with CAM_DEBUG_COMPILE kernel option. CAMDEBUG kernel option still enables all possible debug, if not overriden. Additional 50KB of kernel size is a good price for the ability to debug problems without rebuilding the kernel. In case where size is important, debugging can be compiled out by setting CAM_DEBUG_COMPILE option to 0. --- share/man/man4/scsi.4 | 69 +++++++++++++++++--------------------- sys/cam/cam_debug.h | 50 +++++++++++++++++++++------ sys/cam/cam_xpt.c | 36 ++++++-------------- sys/cam/cam_xpt.h | 22 ------------ sys/cam/scsi/scsi_sa.c | 6 ---- sys/cam/scsi/scsi_target.c | 4 --- sys/conf/NOTES | 19 ++++++----- sys/conf/options | 1 + 8 files changed, 90 insertions(+), 117 deletions(-) diff --git a/share/man/man4/scsi.4 b/share/man/man4/scsi.4 index ad52663c070d..fa5e05d589b9 100644 --- a/share/man/man4/scsi.4 +++ b/share/man/man4/scsi.4 @@ -24,7 +24,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd March 4, 2010 +.Dd June 7, 2012 .Dt CAM 4 .Os .Sh NAME @@ -43,6 +43,7 @@ .Cd "options CAM_DEBUG_BUS=-1" .Cd "options CAM_DEBUG_TARGET=-1" .Cd "options CAM_DEBUG_LUN=-1" +.Cd "options CAM_DEBUG_COMPILE=CAM_DEBUG_INFO|CAM_DEBUG_CDB|CAM_DEBUG_PROBE" .Cd "options CAM_DEBUG_FLAGS=CAM_DEBUG_INFO|CAM_DEBUG_CDB" .Cd "options CAM_MAX_HIGHPOWER=4" .Cd "options SCSI_NO_SENSE_STRINGS" @@ -72,12 +73,11 @@ There are a number of generic kernel configuration options for the subsystem: .Bl -tag -width SCSI_NO_SENSE_STRINGS .It Dv CAMDEBUG -This option enables the +This option compiles in all the .Nm debugging printf code. This will not actually cause any debugging information to be printed out when included by itself. -Enabling printouts requires additional configuration. See below for details. .It Dv "CAM_MAX_HIGHPOWER=4" This sets the maximum allowable number of concurrent "high power" commands. @@ -248,54 +248,53 @@ see other .Nm device entries. .Sh DIAGNOSTICS -When the kernel is compiled with options CAMDEBUG, an XPT_DEBUG CCB can be -used to enable various amounts of tracing information on any -specific device. -Devices not being traced will not produce trace information. -There are currently four debugging flags that may be turned on: +An XPT_DEBUG CCB can be used to enable various amounts of tracing information +on any specific bus/device from the list of options compiled into the kernel. +There are currently seven debugging flags that may be compiled in and used: .Bl -tag -width CAM_DEBUG_SUBTRACE .It Dv CAM_DEBUG_INFO -This debugging flag enables general informational printfs for the device +This flag enables general informational printfs for the device or devices in question. .It Dv CAM_DEBUG_TRACE -This debugging flag enables function-level command flow tracing. +This flag enables function-level command flow tracing. i.e.\& kernel printfs will happen at the entrance and exit of various functions. .It Dv CAM_DEBUG_SUBTRACE -This debugging flag enables debugging output internal to various functions. +This flag enables debugging output internal to various functions. .It Dv CAM_DEBUG_CDB -This debugging flag will cause the kernel to print out all +This flag will cause the kernel to print out all +.Tn ATA +and .Tn SCSI commands sent to a particular device or devices. +.It Dv CAM_DEBUG_XPT +This flag will enable command scheduler tracing. +.It Dv CAM_DEBUG_PERIPH +This flag will enable peripheral drivers messages. +.It Dv CAM_DEBUG_PROBE +This flag will enable devices probe process tracing. .El .Pp Some of these flags, most notably .Dv CAM_DEBUG_TRACE and -.Dv CAM_DEBUG_SUBTRACE -will produce kernel printfs in EXTREME numbers, -and because of that, they are not especially useful. -There are not many things logged at the -.Dv CAM_DEBUG_INFO -level, so it is not especially useful. -The most useful debugging flag is the -.Dv CAM_DEBUG_CDB -flag. +.Dv CAM_DEBUG_SUBTRACE , +will produce kernel printfs in EXTREME numbers. +.Pp Users can enable debugging from their kernel config file, by using the following kernel config options: -.Bl -tag -width CAM_DEBUG_TARGET +.Bl -tag -width CAM_DEBUG_COMPILE .It Dv CAMDEBUG -This enables +This builds into the kernel all possible .Nm debugging. -Without this option, users will not even be able -to turn on debugging from userland via -.Xr camcontrol 8 . -.It Dv CAM_DEBUG_FLAGS -This allows the user to set the various debugging flags described above -in a kernel config file. +.It Dv CAM_DEBUG_COMPILE +This allows to specify support for which debugging flags described above +should be built into the kernel. Flags may be ORed together if the user wishes to see printfs for multiple debugging levels. +.It Dv CAM_DEBUG_FLAGS +This allows to set the various debugging flags from a kernel config file. .It Dv CAM_DEBUG_BUS Specify a bus to debug. To debug all busses, set this to -1. @@ -307,17 +306,9 @@ Specify a lun to debug. To debug all luns, set this to -1. .El .Pp -When specifying a bus, target or lun to debug, you -.Em MUST -specify all three bus/target/lun options above. -Using wildcards, you -should be able to enable debugging on most anything. -.Pp -Users may also enable debugging printfs on the fly, if the -.Dv CAMDEBUG -option is their config file, by using the +Users may also enable debugging on the fly by using the .Xr camcontrol 8 -utility. +utility, if wanted options built into the kernel. See .Xr camcontrol 8 for details. diff --git a/sys/cam/cam_debug.h b/sys/cam/cam_debug.h index 857fa43c12af..e072ec1c715e 100644 --- a/sys/cam/cam_debug.h +++ b/sys/cam/cam_debug.h @@ -44,7 +44,35 @@ typedef enum { CAM_DEBUG_PROBE = 0x40 /* print out probe actions */ } cam_debug_flags; -#if defined(CAMDEBUG) && defined(_KERNEL) +#if defined(_KERNEL) + +#ifndef CAM_DEBUG_FLAGS +#define CAM_DEBUG_FLAGS CAM_DEBUG_NONE +#endif + +#ifndef CAM_DEBUG_COMPILE +#ifdef CAMDEBUG +#define CAM_DEBUG_COMPILE (-1) +#else +#define CAM_DEBUG_COMPILE (CAM_DEBUG_INFO | CAM_DEBUG_CDB | \ + CAM_DEBUG_PERIPH | CAM_DEBUG_PROBE | \ + CAM_DEBUG_FLAGS) +#endif +#endif + +#ifndef CAM_DEBUG_BUS +#define CAM_DEBUG_BUS (-1) +#endif +#ifndef CAM_DEBUG_TARGET +#define CAM_DEBUG_TARGET (-1) +#endif +#ifndef CAM_DEBUG_LUN +#define CAM_DEBUG_LUN (-1) +#endif + +#ifndef CAM_DEBUG_DELAY +#define CAM_DEBUG_DELAY 0 +#endif /* Path we want to debug */ extern struct cam_path *cam_dpath; @@ -52,48 +80,48 @@ extern struct cam_path *cam_dpath; extern u_int32_t cam_dflags; /* Printf delay value (to prevent scrolling) */ extern u_int32_t cam_debug_delay; - + /* Debugging macros. */ #define CAM_DEBUGGED(path, flag) \ - ((cam_dflags & (flag)) \ + (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \ && (cam_dpath != NULL) \ && (xpt_path_comp(cam_dpath, path) >= 0) \ && (xpt_path_comp(cam_dpath, path) < 2)) #define CAM_DEBUG(path, flag, printfargs) \ - if ((cam_dflags & (flag)) \ + if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \ && (cam_dpath != NULL) \ && (xpt_path_comp(cam_dpath, path) >= 0) \ && (xpt_path_comp(cam_dpath, path) < 2)) { \ xpt_print_path(path); \ - printf printfargs; \ + printf printfargs; \ if (cam_debug_delay != 0) \ DELAY(cam_debug_delay); \ } #define CAM_DEBUG_PRINT(flag, printfargs) \ - if (cam_dflags & (flag)) { \ + if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)) { \ printf("cam_debug: "); \ - printf printfargs; \ + printf printfargs; \ if (cam_debug_delay != 0) \ DELAY(cam_debug_delay); \ } #define CAM_DEBUG_PATH_PRINT(flag, path, printfargs) \ - if (cam_dflags & (flag)) { \ + if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)) { \ xpt_print(path, "cam_debug: "); \ - printf printfargs; \ + printf printfargs; \ if (cam_debug_delay != 0) \ DELAY(cam_debug_delay); \ } -#else /* !CAMDEBUG || !_KERNEL */ +#else /* !_KERNEL */ #define CAM_DEBUGGED(A, B) 0 #define CAM_DEBUG(A, B, C) #define CAM_DEBUG_PRINT(A, B) #define CAM_DEBUG_PATH_PRINT(A, B, C) -#endif /* CAMDEBUG && _KERNEL */ +#endif /* _KERNEL */ #endif /* _CAM_CAM_DEBUG_H */ diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index b5bfccec56a3..0dc763df8e70 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -188,21 +188,15 @@ static struct cdevsw xpt_cdevsw = { }; /* Storage for debugging datastructures */ -#ifdef CAMDEBUG struct cam_path *cam_dpath; -#ifdef CAM_DEBUG_FLAGS u_int32_t cam_dflags = CAM_DEBUG_FLAGS; -#else -u_int32_t cam_dflags = CAM_DEBUG_NONE; -#endif TUNABLE_INT("kern.cam.dflags", &cam_dflags); SYSCTL_UINT(_kern_cam, OID_AUTO, dflags, CTLFLAG_RW, - &cam_dflags, 0, "Cam Debug Flags"); -u_int32_t cam_debug_delay; + &cam_dflags, 0, "Enabled debug flags"); +u_int32_t cam_debug_delay = CAM_DEBUG_DELAY; TUNABLE_INT("kern.cam.debug_delay", &cam_debug_delay); SYSCTL_UINT(_kern_cam, OID_AUTO, debug_delay, CTLFLAG_RW, - &cam_debug_delay, 0, "Cam Debug Flags"); -#endif + &cam_debug_delay, 0, "Delay in us after each debug message"); /* Our boot-time initialization hook */ static int cam_module_event_handler(module_t, int /*modeventtype_t*/, void *); @@ -2472,9 +2466,7 @@ xpt_action(union ccb *start_ccb) void xpt_action_default(union ccb *start_ccb) { -#ifdef CAMDEBUG char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1]; -#endif struct cam_path *path; path = start_ccb->ccb_h.path; @@ -2980,16 +2972,17 @@ xpt_action_default(union ccb *start_ccb) break; } case XPT_DEBUG: { -#ifdef CAMDEBUG -#ifdef CAM_DEBUG_DELAY - cam_debug_delay = CAM_DEBUG_DELAY; -#endif + /* Check that all request bits are supported. */ + if (start_ccb->cdbg.flags & ~CAM_DEBUG_COMPILE) { + start_ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; + break; + } + cam_dflags = start_ccb->cdbg.flags; if (cam_dpath != NULL) { xpt_free_path(cam_dpath); cam_dpath = NULL; } - if (cam_dflags != CAM_DEBUG_NONE) { if (xpt_create_path(&cam_dpath, xpt_periph, start_ccb->ccb_h.path_id, @@ -3007,9 +3000,6 @@ xpt_action_default(union ccb *start_ccb) cam_dpath = NULL; start_ccb->ccb_h.status = CAM_REQ_CMP; } -#else /* !CAMDEBUG */ - start_ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; -#endif /* CAMDEBUG */ break; } case XPT_FREEZE_QUEUE: @@ -4760,9 +4750,7 @@ xpt_config(void *arg) * Now that interrupts are enabled, go find our devices */ -#ifdef CAMDEBUG - /* Setup debugging flags and path */ -#ifdef CAM_DEBUG_BUS + /* Setup debugging path */ if (cam_dflags != CAM_DEBUG_NONE) { /* * Locking is specifically omitted here. No SIMs have @@ -4779,10 +4767,6 @@ xpt_config(void *arg) } } else cam_dpath = NULL; -#else /* !CAM_DEBUG_BUS */ - cam_dpath = NULL; -#endif /* CAM_DEBUG_BUS */ -#endif /* CAMDEBUG */ periphdriver_init(1); xpt_hold_boot(); diff --git a/sys/cam/cam_xpt.h b/sys/cam/cam_xpt.h index 1d0e7f7d2381..492fa3a49561 100644 --- a/sys/cam/cam_xpt.h +++ b/sys/cam/cam_xpt.h @@ -63,28 +63,6 @@ struct async_node { SLIST_HEAD(async_list, async_node); SLIST_HEAD(periph_list, cam_periph); -#if defined(CAM_DEBUG_FLAGS) && !defined(CAMDEBUG) -#error "You must have options CAMDEBUG to use options CAM_DEBUG_FLAGS" -#endif - -/* - * In order to enable the CAM_DEBUG_* options, the user must have CAMDEBUG - * enabled. Also, the user must have either none, or all of CAM_DEBUG_BUS, - * CAM_DEBUG_TARGET, and CAM_DEBUG_LUN specified. - */ -#if defined(CAM_DEBUG_BUS) || defined(CAM_DEBUG_TARGET) \ - || defined(CAM_DEBUG_LUN) -#ifdef CAMDEBUG -#if !defined(CAM_DEBUG_BUS) || !defined(CAM_DEBUG_TARGET) \ - || !defined(CAM_DEBUG_LUN) -#error "You must define all or none of CAM_DEBUG_BUS, CAM_DEBUG_TARGET \ - and CAM_DEBUG_LUN" -#endif /* !CAM_DEBUG_BUS || !CAM_DEBUG_TARGET || !CAM_DEBUG_LUN */ -#else /* !CAMDEBUG */ -#error "You must use options CAMDEBUG if you use the CAM_DEBUG_* options" -#endif /* CAMDEBUG */ -#endif /* CAM_DEBUG_BUS || CAM_DEBUG_TARGET || CAM_DEBUG_LUN */ - void xpt_action(union ccb *new_ccb); void xpt_action_default(union ccb *new_ccb); union ccb *xpt_alloc_ccb(void); diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c index 42761bf5bacb..45e1d148b43d 100644 --- a/sys/cam/scsi/scsi_sa.c +++ b/sys/cam/scsi/scsi_sa.c @@ -1482,10 +1482,6 @@ saregister(struct cam_periph *periph, void *arg) softc->quirks = ((struct sa_quirk_entry *)match)->quirks; softc->last_media_blksize = ((struct sa_quirk_entry *)match)->prefblk; -#ifdef CAMDEBUG - xpt_print(periph->path, "found quirk entry %d\n", - (int) (((struct sa_quirk_entry *) match) - sa_quirk_table)); -#endif } else softc->quirks = SA_QUIRK_NONE; @@ -1798,13 +1794,11 @@ sadone(struct cam_periph *periph, union ccb *done_ccb) */ if (error || (softc->flags & SA_FLAG_ERR_PENDING)) cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0); -#ifdef CAMDEBUG if (error || bp->bio_resid) { CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("error %d resid %ld count %ld\n", error, bp->bio_resid, bp->bio_bcount)); } -#endif biofinish(bp, softc->device_stats, 0); break; } diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c index 65f2388ddb1e..c45e8d5e4dbf 100644 --- a/sys/cam/scsi/scsi_target.c +++ b/sys/cam/scsi/scsi_target.c @@ -266,7 +266,6 @@ targioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *t break; case TARGIOCDEBUG: { -#ifdef CAMDEBUG struct ccb_debug cdbg; /* If no periph available, disallow debugging changes */ @@ -287,9 +286,6 @@ targioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *t xpt_action((union ccb *)&cdbg); cam_periph_unlock(softc->periph); status = cdbg.ccb_h.status & CAM_STATUS_MASK; -#else - status = CAM_FUNC_NOTAVAIL; -#endif break; } default: diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 354362a8302c..1d4b29fde0ee 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1305,14 +1305,13 @@ device ctl #CAM Target Layer # CAM OPTIONS: # debugging options: -# -- NOTE -- If you specify one of the bus/target/lun options, you must -# specify them all! -# CAMDEBUG: When defined enables debugging macros -# CAM_DEBUG_BUS: Debug the given bus. Use -1 to debug all busses. -# CAM_DEBUG_TARGET: Debug the given target. Use -1 to debug all targets. -# CAM_DEBUG_LUN: Debug the given lun. Use -1 to debug all luns. -# CAM_DEBUG_FLAGS: OR together CAM_DEBUG_INFO, CAM_DEBUG_TRACE, -# CAM_DEBUG_SUBTRACE, and CAM_DEBUG_CDB +# CAMDEBUG Compile in all possible debugging. +# CAM_DEBUG_COMPILE Debug levels to compile in. +# CAM_DEBUG_FLAGS Debug levels to enable on boot. +# CAM_DEBUG_BUS Limit debugging to the given bus. +# CAM_DEBUG_TARGET Limit debugging to the given target. +# CAM_DEBUG_LUN Limit debugging to the given lun. +# CAM_DEBUG_DELAY Delay in us after printing each debug line. # # CAM_MAX_HIGHPOWER: Maximum number of concurrent high power (start unit) cmds # SCSI_NO_SENSE_STRINGS: When defined disables sense descriptions @@ -1323,10 +1322,12 @@ device ctl #CAM Target Layer # can be changed at boot and runtime with the # kern.cam.scsi_delay tunable/sysctl. options CAMDEBUG +options CAM_DEBUG_COMPILE=-1 +options CAM_DEBUG_FLAGS=(CAM_DEBUG_INFO|CAM_DEBUG_PROBE|CAM_DEBUG_PERIPH) options CAM_DEBUG_BUS=-1 options CAM_DEBUG_TARGET=-1 options CAM_DEBUG_LUN=-1 -options CAM_DEBUG_FLAGS=(CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB) +options CAM_DEBUG_DELAY=1 options CAM_MAX_HIGHPOWER=4 options SCSI_NO_SENSE_STRINGS options SCSI_NO_OP_STRINGS diff --git a/sys/conf/options b/sys/conf/options index 8f810f4bf89c..ba678e1a0b3b 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -306,6 +306,7 @@ MAXSSIZ opt_param.h # Generic SCSI options. CAM_MAX_HIGHPOWER opt_cam.h CAMDEBUG opt_cam.h +CAM_DEBUG_COMPILE opt_cam.h CAM_DEBUG_DELAY opt_cam.h CAM_DEBUG_BUS opt_cam.h CAM_DEBUG_TARGET opt_cam.h