windows-nt/Source/XPSP1/NT/drivers/wdm/usb/hcd/openhci/dbg.c
2020-09-26 16:20:57 +08:00

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