/*++
*******************************************************************************
* 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_

#include "sraddk.h"

// Registry Value names
#define DEBUGTYPE       L"DebugType"
#define DEBUGLEVEL      L"DebugLevel"
#define DEBUGFLAGS      L"DebugFlags"

// Default values
#define DEFAULT_DEBUGLEVEL      0
#define DEFAULT_DEBUGTYPE       0
#define DEFAULT_DEBUGFLAGS      (DBGFLAG_TIME|DBGFLAG_THREAD|DBGFLAG_IRQL)

///////////////////////////////////////////////////////////////////////////////
//
// 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;

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

VOID DigiDebugInitEx( PUNICODE_STRING pRegistryPath OPTIONAL,
                      ULONG           defMask, 
                      ULONG           defMode,
                      PCHAR           Prefix,
                      PWCHAR          Version);

VOID __inline DigiDebugInit( PUNICODE_STRING pRegistryPath OPTIONAL,
                           ULONG           defMask, 
                           ULONG           defMode ) {
    DigiDebugInitEx(pRegistryPath,defMask,defMode,"digiXXXX",NULL);
}


#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) ) )


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

#ifdef STRATUS_DEVICE

// Debug level for the sradxb driver will either be off (0) or on 
// (DBG_NORMAL). Still, need to test for vendor trace being enabled

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

#else

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

#endif



#define DigiDumpData( Flags, pData, cbData )/*                  \
{                                                               \
        if (SRAGETLEVEL())                                              \
                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 DigiDbgBreakOnEntryEnabled()                    FALSE
#define DigiDump( Flags, String )                               {}
#define DigiDumpData( Flags, pData, cbData )    {}

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

#endif

#endif
