Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

295 lines
8.8 KiB

/*++
Copyright (c) 1991 - 2001 Microsoft Corporation
Module Name:
### ## # ## ## # ## ##### #### ##### #####
## # ## ### ## ## ### ## ## ## ## # ## ## ## ##
### ## ### ## ## ### ## ## ## ## ## ## ## ##
### ## # # ## ## # # ## ## ## ## ## ## ## ##
### ### ### ### ### ## ## ## ##### #####
# ## ### ### ### ### ## ## ## ## # ## ##
### ## ## ## ## ##### ## #### ## ##
Abstract:
This module contains the entire implementation of
the watchdog miniport for the ServerWorks
CSB5 server chip set.
Author:
Wesley Witt (wesw) 1-Oct-2001
Environment:
Kernel mode only.
Notes:
--*/
#include "swwd.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,DriverEntry)
#endif
NTSTATUS
SaWdDeviceIoctl(
IN PVOID DeviceExtensionIn,
IN PIRP Irp,
IN PVOID FsContext,
IN ULONG FunctionCode,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
IN PVOID OutputBuffer,
IN ULONG OutputBufferLength
)
/*++
Routine Description:
This function is called by the SAPORT driver so that
the mini-port driver can service an IOCTL call.
Arguments:
DeviceExtensionIn - A pointer to the mini-port's device extension
Irp - IO request packet pointer
FsContext - Context pointer
FunctionCode - The IOCTL function code
InputBuffer - Pointer to the input buffer, contains the data sent down by the I/O
InputBufferLength - Length in bytes of the InputBuffer
OutputBuffer - Pointer to the output buffer, contains the data generated by this call
OutputBufferLength - Length in bytes of the OutputBuffer
Context:
IRQL: IRQL PASSIVE_LEVEL, arbitrary thread context
Return Value:
If the function succeeds, it must return STATUS_SUCCESS.
Otherwise, it must return one of the error status values defined in ntstatus.h.
--*/
{
PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceExtensionIn;
NTSTATUS Status = STATUS_SUCCESS;
PSA_WD_CAPS WdCaps = NULL;
UCHAR Control;
ULONG TimerValue;
switch (FunctionCode) {
case FUNC_SA_GET_VERSION:
*((PULONG)OutputBuffer) = SA_INTERFACE_VERSION;
break;
case FUNC_SA_GET_CAPABILITIES:
WdCaps = (PSA_WD_CAPS)OutputBuffer;
WdCaps->SizeOfStruct = sizeof(SA_WD_CAPS);
WdCaps->Minimum = 1;
WdCaps->Maximum = 512;
break;
case FUNC_SAWD_DISABLE:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
Control = READ_REGISTER_UCHAR( DeviceExtension->WdMemBase );
if (*((PULONG)InputBuffer) == 1) {
SETBITS( Control, WATCHDOG_CONTROL_ENABLE );
SETBITS( Control, WATCHDOG_CONTROL_TRIGGER );
} else {
CLEARBITS( Control, WATCHDOG_CONTROL_ENABLE );
}
WRITE_REGISTER_UCHAR( DeviceExtension->WdMemBase, Control );
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
case FUNC_SAWD_QUERY_EXPIRE_BEHAVIOR:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
Control = READ_REGISTER_UCHAR( DeviceExtension->WdMemBase );
if (Control & WATCHDOG_CONTROL_TIMER_MODE) {
*((PULONG)OutputBuffer) = 1;
} else {
*((PULONG)OutputBuffer) = 0;
}
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
case FUNC_SAWD_SET_EXPIRE_BEHAVIOR:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
Control = READ_REGISTER_UCHAR( DeviceExtension->WdMemBase );
if (*((PULONG)InputBuffer) == 1) {
SETBITS( Control, WATCHDOG_CONTROL_TIMER_MODE );
} else {
CLEARBITS( Control, WATCHDOG_CONTROL_TIMER_MODE );
}
WRITE_REGISTER_UCHAR( DeviceExtension->WdMemBase, Control );
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
case FUNC_SAWD_PING:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
Control = READ_REGISTER_UCHAR( DeviceExtension->WdMemBase );
SETBITS( Control, WATCHDOG_CONTROL_TRIGGER );
WRITE_REGISTER_UCHAR( DeviceExtension->WdMemBase, Control );
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
case FUNC_SAWD_QUERY_TIMER:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
TimerValue = READ_REGISTER_ULONG( (PULONG)(DeviceExtension->WdMemBase+4) );
*((PULONG)OutputBuffer) = TimerValue & 0x1ff;
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
case FUNC_SAWD_SET_TIMER:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
TimerValue = *((PULONG)InputBuffer) & 0x1ff;
WRITE_REGISTER_ULONG( (PULONG)(DeviceExtension->WdMemBase+4), TimerValue );
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
default:
Status = STATUS_NOT_SUPPORTED;
REPORT_ERROR( SA_DEVICE_WATCHDOG, "Unsupported device control", Status );
break;
}
return Status;
}
NTSTATUS
SaWdHwInitialize(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID DeviceExtensionIn,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResources,
IN ULONG PartialResourceCount
)
/*++
Routine Description:
This function is called by the SAPORT driver so that
the mini-port driver can initialize it's hardware
resources.
Arguments:
DeviceObject - Pointer to the target device object.
Irp - Pointer to an IRP structure that describes the requested I/O operation.
DeviceExtension - A pointer to the mini-port's device extension.
PartialResources - Pointer to the translated resources alloacted by the system.
PartialResourceCount - The number of resources in the PartialResources array.
Context:
IRQL: IRQL PASSIVE_LEVEL, system thread context
Return Value:
If the function succeeds, it must return STATUS_SUCCESS.
Otherwise, it must return one of the error status values defined in ntstatus.h.
--*/
{
PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceExtensionIn;
NTSTATUS Status;
ULONG i;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceMemory = NULL;
for (i=0; i<PartialResourceCount; i++) {
if (PartialResources[i].Type == CmResourceTypeMemory) {
ResourceMemory = &PartialResources[i];
}
}
if (ResourceMemory == NULL) {
REPORT_ERROR( SA_DEVICE_WATCHDOG, "Missing memory resource", STATUS_UNSUCCESSFUL );
return STATUS_UNSUCCESSFUL;
}
//
// Setup the memory base address
//
DeviceExtension->WdMemBase = (PUCHAR) SaPortGetVirtualAddress(
DeviceExtension,
ResourceMemory->u.Memory.Start,
ResourceMemory->u.Memory.Length
);
if (DeviceExtension->WdMemBase == NULL) {
REPORT_ERROR( SA_DEVICE_WATCHDOG, "SaPortGetVirtualAddress failed", STATUS_NO_MEMORY );
return STATUS_NO_MEMORY;
}
ExInitializeFastMutex( &DeviceExtension->WdIoLock );
return STATUS_SUCCESS;
}
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
This routine is the driver's entry point, called by the I/O system
to load the driver. The driver's entry points are initialized and
a mutex to control paging is initialized.
In DBG mode, this routine also examines the registry for special
debug parameters.
Arguments:
DriverObject - a pointer to the object that represents this device driver.
RegistryPath - a pointer to this driver's key in the Services tree.
Return Value:
STATUS_SUCCESS
--*/
{
NTSTATUS Status;
SAPORT_INITIALIZATION_DATA SaPortInitData;
RtlZeroMemory( &SaPortInitData, sizeof(SAPORT_INITIALIZATION_DATA) );
SaPortInitData.StructSize = sizeof(SAPORT_INITIALIZATION_DATA);
SaPortInitData.DeviceType = SA_DEVICE_WATCHDOG;
SaPortInitData.HwInitialize = SaWdHwInitialize;
SaPortInitData.DeviceIoctl = SaWdDeviceIoctl;
SaPortInitData.DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
Status = SaPortInitialize( DriverObject, RegistryPath, &SaPortInitData );
if (!NT_SUCCESS(Status)) {
REPORT_ERROR( SA_DEVICE_WATCHDOG, "SaPortInitialize failed\n", Status );
return Status;
}
return STATUS_SUCCESS;
}