325 lines
8.1 KiB
C
325 lines
8.1 KiB
C
/*--------------------------------------------------------------------------
|
||
*
|
||
* Copyright (C) Cyclades Corporation, 1999-2001.
|
||
* All rights reserved.
|
||
*
|
||
* Cyclom-Y Enumerator Driver
|
||
*
|
||
* This file: log.c
|
||
*
|
||
* Description: This module contains contains the entry points
|
||
* for a standard bus PNP / WDM driver.
|
||
*
|
||
* Notes: This code supports Windows 2000 and Windows XP,
|
||
* x86 and ia64 processors.
|
||
*
|
||
* Complies with Cyclades SW Coding Standard rev 1.3.
|
||
*
|
||
*--------------------------------------------------------------------------
|
||
*/
|
||
|
||
/*-------------------------------------------------------------------------
|
||
*
|
||
* Change History
|
||
*
|
||
*--------------------------------------------------------------------------
|
||
*
|
||
*
|
||
*--------------------------------------------------------------------------
|
||
*/
|
||
|
||
|
||
#include "pch.h"
|
||
|
||
typedef enum _CYY_MEM_COMPARES {
|
||
AddressesAreEqual,
|
||
AddressesOverlap,
|
||
AddressesAreDisjoint
|
||
} CYY_MEM_COMPARES,*PCYY_MEM_COMPARES;
|
||
|
||
static const PHYSICAL_ADDRESS CyyPhysicalZero = {0};
|
||
|
||
CYY_MEM_COMPARES
|
||
CyyMemCompare(
|
||
IN PHYSICAL_ADDRESS A,
|
||
IN ULONG SpanOfA,
|
||
IN PHYSICAL_ADDRESS B,
|
||
IN ULONG SpanOfB
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Compare two phsical address.
|
||
|
||
Arguments:
|
||
|
||
A - One half of the comparison.
|
||
|
||
SpanOfA - In units of bytes, the span of A.
|
||
|
||
B - One half of the comparison.
|
||
|
||
SpanOfB - In units of bytes, the span of B.
|
||
|
||
|
||
Return Value:
|
||
|
||
The result of the comparison.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
LARGE_INTEGER a;
|
||
LARGE_INTEGER b;
|
||
|
||
LARGE_INTEGER lower;
|
||
ULONG lowerSpan;
|
||
LARGE_INTEGER higher;
|
||
|
||
//PAGED_CODE(); Non paged because it can be called during CyyLogError, which is no paged now.
|
||
|
||
a = A;
|
||
b = B;
|
||
|
||
if (a.QuadPart == b.QuadPart) {
|
||
|
||
return AddressesAreEqual;
|
||
|
||
}
|
||
|
||
if (a.QuadPart > b.QuadPart) {
|
||
|
||
higher = a;
|
||
lower = b;
|
||
lowerSpan = SpanOfB;
|
||
|
||
} else {
|
||
|
||
higher = b;
|
||
lower = a;
|
||
lowerSpan = SpanOfA;
|
||
|
||
}
|
||
|
||
if ((higher.QuadPart - lower.QuadPart) >= lowerSpan) {
|
||
|
||
return AddressesAreDisjoint;
|
||
|
||
}
|
||
|
||
return AddressesOverlap;
|
||
|
||
}
|
||
|
||
|
||
VOID
|
||
CyyLogError(
|
||
IN PDRIVER_OBJECT DriverObject,
|
||
IN PDEVICE_OBJECT DeviceObject OPTIONAL,
|
||
IN PHYSICAL_ADDRESS P1,
|
||
IN PHYSICAL_ADDRESS P2,
|
||
IN ULONG SequenceNumber,
|
||
IN UCHAR MajorFunctionCode,
|
||
IN UCHAR RetryCount,
|
||
IN ULONG UniqueErrorValue,
|
||
IN NTSTATUS FinalStatus,
|
||
IN NTSTATUS SpecificIOStatus,
|
||
IN ULONG LengthOfInsert1,
|
||
IN PWCHAR Insert1,
|
||
IN ULONG LengthOfInsert2,
|
||
IN PWCHAR Insert2
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine allocates an error log entry, copies the supplied data
|
||
to it, and requests that it be written to the error log file.
|
||
|
||
Arguments:
|
||
|
||
DriverObject - A pointer to the driver object for the device.
|
||
|
||
DeviceObject - A pointer to the device object associated with the
|
||
device that had the error, early in initialization, one may not
|
||
yet exist.
|
||
|
||
P1,P2 - If phyical addresses for the controller ports involved
|
||
with the error are available, put them through as dump data.
|
||
|
||
SequenceNumber - A ulong value that is unique to an IRP over the
|
||
life of the irp in this driver - 0 generally means an error not
|
||
associated with an irp.
|
||
|
||
MajorFunctionCode - If there is an error associated with the irp,
|
||
this is the major function code of that irp.
|
||
|
||
RetryCount - The number of times a particular operation has been
|
||
retried.
|
||
|
||
UniqueErrorValue - A unique long word that identifies the particular
|
||
call to this function.
|
||
|
||
FinalStatus - The final status given to the irp that was associated
|
||
with this error. If this log entry is being made during one of
|
||
the retries this value will be STATUS_SUCCESS.
|
||
|
||
SpecificIOStatus - The IO status for a particular error.
|
||
|
||
LengthOfInsert1 - The length in bytes (including the terminating NULL)
|
||
of the first insertion string.
|
||
|
||
Insert1 - The first insertion string.
|
||
|
||
LengthOfInsert2 - The length in bytes (including the terminating NULL)
|
||
of the second insertion string. NOTE, there must
|
||
be a first insertion string for their to be
|
||
a second insertion string.
|
||
|
||
Insert2 - The second insertion string.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
PIO_ERROR_LOG_PACKET errorLogEntry;
|
||
|
||
PVOID objectToUse;
|
||
SHORT dumpToAllocate = 0;
|
||
PUCHAR ptrToFirstInsert;
|
||
PUCHAR ptrToSecondInsert;
|
||
|
||
//PAGED_CODE(); It can be called at raised IRQL.
|
||
|
||
if (Insert1 == NULL) {
|
||
LengthOfInsert1 = 0;
|
||
}
|
||
|
||
if (Insert2 == NULL) {
|
||
LengthOfInsert2 = 0;
|
||
}
|
||
|
||
|
||
if (ARGUMENT_PRESENT(DeviceObject)) {
|
||
|
||
objectToUse = DeviceObject;
|
||
|
||
} else {
|
||
|
||
objectToUse = DriverObject;
|
||
|
||
}
|
||
|
||
if (CyyMemCompare(
|
||
P1,
|
||
(ULONG)1,
|
||
CyyPhysicalZero,
|
||
(ULONG)1
|
||
) != AddressesAreEqual) {
|
||
|
||
dumpToAllocate = (SHORT)sizeof(PHYSICAL_ADDRESS);
|
||
|
||
}
|
||
|
||
if (CyyMemCompare(
|
||
P2,
|
||
(ULONG)1,
|
||
CyyPhysicalZero,
|
||
(ULONG)1
|
||
) != AddressesAreEqual) {
|
||
|
||
dumpToAllocate += (SHORT)sizeof(PHYSICAL_ADDRESS);
|
||
|
||
}
|
||
|
||
errorLogEntry = IoAllocateErrorLogEntry(
|
||
objectToUse,
|
||
(UCHAR)(sizeof(IO_ERROR_LOG_PACKET) +
|
||
dumpToAllocate
|
||
+ LengthOfInsert1 +
|
||
LengthOfInsert2)
|
||
);
|
||
|
||
if ( errorLogEntry != NULL ) {
|
||
|
||
errorLogEntry->ErrorCode = SpecificIOStatus;
|
||
errorLogEntry->SequenceNumber = SequenceNumber;
|
||
errorLogEntry->MajorFunctionCode = MajorFunctionCode;
|
||
errorLogEntry->RetryCount = RetryCount;
|
||
errorLogEntry->UniqueErrorValue = UniqueErrorValue;
|
||
errorLogEntry->FinalStatus = FinalStatus;
|
||
errorLogEntry->DumpDataSize = dumpToAllocate;
|
||
|
||
if (dumpToAllocate) {
|
||
|
||
RtlCopyMemory(
|
||
&errorLogEntry->DumpData[0],
|
||
&P1,
|
||
sizeof(PHYSICAL_ADDRESS)
|
||
);
|
||
|
||
if (dumpToAllocate > sizeof(PHYSICAL_ADDRESS)) {
|
||
|
||
RtlCopyMemory(
|
||
((PUCHAR)&errorLogEntry->DumpData[0])
|
||
+sizeof(PHYSICAL_ADDRESS),
|
||
&P2,
|
||
sizeof(PHYSICAL_ADDRESS)
|
||
);
|
||
|
||
ptrToFirstInsert =
|
||
((PUCHAR)&errorLogEntry->DumpData[0])+(2*sizeof(PHYSICAL_ADDRESS));
|
||
|
||
} else {
|
||
|
||
ptrToFirstInsert =
|
||
((PUCHAR)&errorLogEntry->DumpData[0])+sizeof(PHYSICAL_ADDRESS);
|
||
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
ptrToFirstInsert = (PUCHAR)&errorLogEntry->DumpData[0];
|
||
|
||
}
|
||
|
||
ptrToSecondInsert = ptrToFirstInsert + LengthOfInsert1;
|
||
|
||
if (LengthOfInsert1) {
|
||
|
||
errorLogEntry->NumberOfStrings = 1;
|
||
errorLogEntry->StringOffset = (USHORT)(ptrToFirstInsert -
|
||
(PUCHAR)errorLogEntry);
|
||
RtlCopyMemory(
|
||
ptrToFirstInsert,
|
||
Insert1,
|
||
LengthOfInsert1
|
||
);
|
||
|
||
if (LengthOfInsert2) {
|
||
|
||
errorLogEntry->NumberOfStrings = 2;
|
||
RtlCopyMemory(
|
||
ptrToSecondInsert,
|
||
Insert2,
|
||
LengthOfInsert2
|
||
);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
IoWriteErrorLogEntry(errorLogEntry);
|
||
|
||
}
|
||
|
||
}
|