|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
dbg.c
Abstract:
Debug logging code and other debug services
Environment:
kernel mode only
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
Revision History:
5-4-96 : created jdunn
--*/
#include "openhci.h"
//
// other debug functions
//
#if DBG
VOID OpenHCI_Assert( IN PVOID FailedAssertion, IN PVOID FileName, IN ULONG LineNumber, IN PCHAR Message ) /*++
Routine Description:
Debug Assert function.
Arguments:
DeviceObject - pointer to a device object
Irp - pointer to an I/O Request Packet
Return Value:
--*/ { #ifdef NTKERN
// this makes the compiler generate a ret
ULONG stop = 1; assert_loop: #endif
// just call the NT assert function and stop
// in the debugger.
RtlAssert( FailedAssertion, FileName, LineNumber, Message );
// loop here to prevent users from going past
// are assert before we can look at it
#ifdef NTKERN
TRAP(); if (stop) { goto assert_loop; } #endif
return; }
ULONG _cdecl OHCI_KdPrint2( PCH Format, ... ) { va_list list; int i; int arg[5]; ULONG l=2; if (OHCI_Debug_Trace_Level >= l) { if (l <= 1) { DbgPrint("OPENHCI.SYS: "); *Format = ' '; } else { DbgPrint("'OPENHCI.SYS: "); } va_start(list, Format); for (i=0; i<4; i++) { arg[i] = va_arg(list, int); } DbgPrint(Format, arg[0], arg[1], arg[2], arg[3]); }
return 0; }
ULONG _cdecl OHCI_KdPrintX( ULONG l, PCH Format, ... ) { va_list list; int i; int arg[5]; if (OHCI_Debug_Trace_Level >= l) { if (l <= 1) { DbgPrint("OPENHCI.SYS: "); #ifdef NTKERN
*Format = ' '; #endif
} else { DbgPrint("'OPENHCI.SYS: "); } va_start(list, Format); for (i=0; i<4; i++) { arg[i] = va_arg(list, int); } DbgPrint(Format, arg[0], arg[1], arg[2], arg[3]); }
return 0; }
#endif // DBG
#ifdef DEBUG_LOG
KSPIN_LOCK OHCILogSpinLock;
struct UHCD_LOG_ENTRY { ULONG le_sig; // Identifying string
ULONG_PTR le_info1; // entry specific info
ULONG_PTR le_info2; // entry specific info
ULONG_PTR le_info3; // entry specific info
}; /* USBD_LOG_ENTRY */
struct UHCD_LOG_ENTRY *OHCILStart = NULL; // No log yet
struct UHCD_LOG_ENTRY *OHCILPtr; struct UHCD_LOG_ENTRY *OHCILEnd;
#ifdef IRP_LOG
ULONG IrpLogSize = 4096*4; //4 page of log entries
#endif
#ifdef IRP_LOG
PULONG OHCIIrpLog; #endif
ULONG OHCI_LogMask = 0xffffffff;
VOID OHCI_Debug_LogEntry( IN ULONG Mask, IN ULONG Sig, IN ULONG_PTR Info1, IN ULONG_PTR Info2, IN ULONG_PTR Info3 ) /*++
Routine Description:
Adds an Entry to USBD log.
Arguments:
Return Value:
None.
--*/ { KIRQL irql; typedef union _SIG { struct { UCHAR Byte0; UCHAR Byte1; UCHAR Byte2; UCHAR Byte3; } b; ULONG l; } SIG, *PSIG;
SIG sig, rsig;
if (OHCILStart == NULL) { return; }
if ((OHCI_LogMask & Mask) == 0) { return; }
irql = KeGetCurrentIrql(); if (irql < DISPATCH_LEVEL) { KeAcquireSpinLock(&OHCILogSpinLock, &irql); } else { KeAcquireSpinLockAtDpcLevel(&OHCILogSpinLock); } if (OHCILPtr > OHCILStart) { OHCILPtr -= 1; // Decrement to next entry
} else { OHCILPtr = OHCILEnd; }
// RtlCopyMemory(OHCILPtr->le_name, Name, 4);
// LPtr->le_ret = (stk[1] & 0x00ffffff) | (CurVMID()<<24);
sig.l = Sig; rsig.b.Byte0 = sig.b.Byte3; rsig.b.Byte1 = sig.b.Byte2; rsig.b.Byte2 = sig.b.Byte1; rsig.b.Byte3 = sig.b.Byte0; OHCILPtr->le_sig = rsig.l; OHCILPtr->le_info1 = Info1; OHCILPtr->le_info2 = Info2; OHCILPtr->le_info3 = Info3;
ASSERT(OHCILPtr >= OHCILStart);
if (irql < DISPATCH_LEVEL) { KeReleaseSpinLock(&OHCILogSpinLock, irql); } else { KeReleaseSpinLockFromDpcLevel(&OHCILogSpinLock); }
return; }
VOID OHCI_LogInit( VOID ) /*++
Routine Description:
Init the debug log - remember interesting information in a circular buffer
Arguments: Return Value:
None.
--*/ { #ifdef MAX_DEBUG
ULONG logSize = 4096*4; //4 page of log entries
#else
ULONG logSize = 4096*8; #endif
if (OHCILStart != NULL) { return; }
#ifdef IRP_LOG
if (OHCIIrpLog == NULL) { OHCIIrpLog = ExAllocatePoolWithTag(NonPagedPool, IrpLogSize, OpenHCI_TAG); if (OHCIIrpLog) { RtlZeroMemory(OHCIIrpLog, IrpLogSize); } } #endif
KeInitializeSpinLock(&OHCILogSpinLock);
OHCILStart = ExAllocatePoolWithTag(NonPagedPool, logSize, OpenHCI_TAG);
if (OHCILStart) { OHCILPtr = OHCILStart;
// Point the end (and first entry) 1 entry from the end of
// the segment
OHCILEnd = OHCILStart + (logSize / sizeof(struct UHCD_LOG_ENTRY)) - 1; } else { TRAP(); }
return; }
VOID OHCI_LogFree( VOID ) /*++
Routine Description:
Init the debug log - remember interesting information in a circular buffer
Arguments: Return Value:
None.
--*/ { if (OHCILStart) { ExFreePool(OHCILStart); OHCILStart = NULL; }
#ifdef IRP_LOG
if (OHCIIrpLog) { ExFreePool(OHCIIrpLog); OHCIIrpLog = NULL; } #endif
return; }
#ifdef IRP_LOG
VOID OHCI_LogIrp( PIRP Irp, ULONG Add ) /*++
Routine Description:
Arguments: Return Value:
None.
--*/ { PULONG p; PUCHAR end;
p = OHCIIrpLog; end = (PUCHAR) OHCIIrpLog; end+=IrpLogSize;
if (Add) { while (*p) { p++; }
if ((PUCHAR) p > end) { // no room
TEST_TRAP(); } else { *p = (ULONG) Irp; } } else { while (*p != (ULONG) Irp) { p++; }
if ((PUCHAR) p > end) { // no room
TEST_TRAP(); } else { *p = 0; } }
return; }
#endif
#endif /* DEBUG_LOG */
|