413 lines
6.8 KiB
C
413 lines
6.8 KiB
C
|
/*++
|
||
|
|
||
|
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 */
|