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.
This commit is contained in:
Alexander Motin 2012-06-07 10:05:51 +00:00
parent 2a4989cd1c
commit f0f25b9c80
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=236712
8 changed files with 90 additions and 117 deletions

View File

@ -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.

View File

@ -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 */

View File

@ -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();

View File

@ -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);

View File

@ -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;
}

View File

@ -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:

View File

@ -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

View File

@ -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