/*++
*******************************************************************************
* Copyright (c) 1990-98 Digi International Inc., All Rights Reserved				*
* 																										*
* This software contains proprietary and confidential information of Digi		*
* International Inc.  By accepting transfer of this copy, Recipient agrees		*
* to retain this software in confidence, to prevent disclosure to others,		*
* and to make no use of this software other than that for which it was			*
* delivered.  This is an unpublished copyrighted work of Digi International	*
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly	*
* prohibited.																						*
* 																										*
* Restricted Rights Legend																		*
*																										*
* Use, duplication, or disclosure by the Government is subject to					*
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in			*
* Technical Data and Computer Software clause at DFARS 252.227-7031 or			*
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -				*
* Restricted Rights at 48 CFR 52.227-19, as applicable.								*
*																										*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343				*
*																										*
*******************************************************************************

Module Name:

   digidebug.h

Abstract:

   Routines to display debug messages to the kernel debug console or to a logfile using
	memprint support.  Also contains ASSERT macro.

Author:

   Michael Zarns

--*/

#ifndef _DIGIDEBUG_
#define _DIGIDEBUG_

///////////////////////////////////////////////////////////////////////////////
//
// gDebugMask Flags.  This replaces the older DigiDebugLevel variable.  
//
// The *User* flags values are for you to define and use as you wish.  For example,
// 	#define DIGIINIT DEBUG_00000000 
// 	DigiDump( DIGIINIT, "..." )
// 
// 
// The *Predefined* values should be used as specified.  For example, DEBUG_ERROR
// should always be used to print errors.
//

// User flags
#define DEBUG_00000001		(ULONG)0x00000001
#define DEBUG_00000002		(ULONG)0x00000002
#define DEBUG_00000004		(ULONG)0x00000004
#define DEBUG_00000008		(ULONG)0x00000008
#define DEBUG_00000010		(ULONG)0x00000010
#define DEBUG_00000020		(ULONG)0x00000020
#define DEBUG_00000040		(ULONG)0x00000040
#define DEBUG_00000080		(ULONG)0x00000080
#define DEBUG_00000100		(ULONG)0x00000100
#define DEBUG_00000200		(ULONG)0x00000200
#define DEBUG_00000400		(ULONG)0x00000400
#define DEBUG_00000800		(ULONG)0x00000800
#define DEBUG_00001000		(ULONG)0x00001000
#define DEBUG_00002000		(ULONG)0x00002000
#define DEBUG_00004000		(ULONG)0x00004000
#define DEBUG_00008000		(ULONG)0x00008000
#define DEBUG_00010000		(ULONG)0x00010000
#define DEBUG_00020000		(ULONG)0x00020000
#define DEBUG_00040000		(ULONG)0x00040000
#define DEBUG_00080000		(ULONG)0x00080000
#define DEBUG_00100000		(ULONG)0x00100000
#define DEBUG_00200000		(ULONG)0x00200000
#define DEBUG_00400000		(ULONG)0x00400000
#define DEBUG_00800000		(ULONG)0x00800000
#define DEBUG_01000000		(ULONG)0x01000000
#define DEBUG_02000000		(ULONG)0x02000000

// Predefined flags
#define DEBUG_DIGIPNP		(ULONG)0x04000000
#define DEBUG_DSAPILIB		(ULONG)0x08000000
#define DEBUG_DIGILIB		(ULONG)0x10000000
#define DEBUG_WARN			(ULONG)0x20000000
#define DEBUG_ERROR			(ULONG)0x40000000
#define DEBUG_BREAK			(ULONG)0x80000000


///////////////////////////////////////////////////////////////////////////////
//
// gDebugMode Flags.  This replaces the older DigiPrintFlags variable.  
//
// The mode setting defines where DigiDump text is printed.  Console prints to the
// kernel debug console.  File prints to a logfile, defined by your driver by calling
// DebugInit.
//

#define DEBUGMODE_NONE		(ULONG)0x00000000
#define DEBUGMODE_CONSOLE	(ULONG)0x00000001
#define DEBUGMODE_FILE     (ULONG)0x00000002
#define DEBUGMODE_ANY      (DEBUGMODE_CONSOLE|DEBUGMODE_FILE)


extern ULONG gDebugMask;
extern ULONG gDebugMode;


#if DBG || DIGIDEBUG_ENABLE

VOID DigiDbgDump( IN PCSZ pszFormat, ... );

VOID DigiDbgDumpData( IN VOID const * pData, 
                      IN ULONG        cbData );

#define ShouldBreak( Flags )						( (Flags) & (DEBUG_BREAK) )
#define ConsoleModeEnabled( Mode )				( (Mode) & (DEBUGMODE_CONSOLE) )
#define FileModeEnabled( Mode )					( (Mode) & (DEBUGMODE_FILE) )
#define DisplayEnabled( Mode )					( ConsoleModeEnabled(Mode) || FileModeEnabled(Mode) )
#define FlagEnabled( Mask, Flags )				( (Mask) & (Flags) )
#define ShouldDisplay( Mode, Mask, Flags )	( DisplayEnabled(Mode) && ( FlagEnabled(Mask, Flags) || ShouldBreak(Flags) ) )


///////////////////////////////////////////////////////////////////////////////
//
// Initialization.  Call this from DriverEntry!  Gathers debug settings from registry.
//

VOID DigiDebugInit( PUNICODE_STRING pRegistryPath OPTIONAL,
                    ULONG           defMask, 
                    ULONG           defMode );


// Optional.  Call this from DriverEntry to see if registry flag was set to tell
// us to break.  This routine does not break, it simply checks the flag.  Requires
// previous call to DigiDebugInit to actually gather settings from registry.
BOOLEAN DigiDbgBreakOnEntryEnabled( VOID );


///////////////////////////////////////////////////////////////////////////////
//
// Dump macros.  Use these macros to display debug text.
//

#define DigiDump( Flags, String )								\
{																			\
	if ( ShouldDisplay( gDebugMode, gDebugMask, Flags ) )	\
		DigiDbgDump String;											\
	if ( ShouldBreak( Flags ) )									\
		DbgBreakPoint();												\
}


#define DigiDumpData( Flags, pData, cbData )					\
{																			\
	if ( ShouldDisplay( gDebugMode, gDebugMask, Flags ) )	\
		DigiDbgDumpData( pData, cbData );						\
	if ( ShouldBreak( Flags ) )									\
		DbgBreakPoint();												\
}

#ifdef ASSERT
#undef ASSERT
#endif
#define ASSERT( Condition )																\
{																									\
	if( !( Condition ) )																		\
	{																								\
		(void)DbgPrint( "ASSERT failed: " #Condition "\nfile: %s, line %d\n",\
		             __FILE__, __LINE__ );												\
		DbgBreakPoint();																		\
	}																								\
}

#else

#define DigiDebugInit( X, Y, Z )					{}
#define DigiDbgBreakOnEntryEnabled()			FALSE
#define DigiDump( Flags, String )				{}
#define DigiDumpData( Flags, pData, cbData )	{}

#ifdef ASSERT
#undef ASSERT
#endif
#define ASSERT( Condition )						{}

#endif

#endif