📄 pnp.c
字号:
//
RtlZeroMemory(deviceDescription, sizeof(DEVICE_DESCRIPTION));
deviceDescription->Version = DEVICE_DESCRIPTION_VERSION;
deviceDescription->Master = TRUE;
deviceDescription->ScatterGather = FALSE;
deviceDescription->Dma32BitAddresses = TRUE;
deviceDescription->InterfaceType = PCIBus;
//
// Maximum size of transfer that we support on this device. Choose
// anything you like, really.
//
deviceDescription->MaximumLength = OSR_PCI_MAX_TXFER;
//
// Allocate one Adapter for WRITE
//
DevExt->WriteAdapter = IoGetDmaAdapter(DevExt->PhysicalDeviceObject,
deviceDescription,
&DevExt->WriteMapRegsGot);
if(!DevExt->WriteAdapter) {
#if DBG
DbgPrint("IoGetDmaAdapter for WRITE FAILED!!\n");
#endif
//
// Clean up the mess
//
ExFreePool(deviceDescription);
//OsrUnload(DriverObj);
return(STATUS_UNSUCCESSFUL);
}
#if DBG
DbgPrint("Max Map Regs for WRITE = %d.\n", DevExt->WriteMapRegsGot);
#endif
//
// And then another for READ
//
DevExt->ReadAdapter = IoGetDmaAdapter(DevExt->PhysicalDeviceObject,
deviceDescription,
&DevExt->ReadMapRegsGot);
if(!DevExt->ReadAdapter) {
#if DBG
DbgPrint("IoGetDmaAdapter for READ FAILED!!\n");
#endif
//
// Clean up the mess
//
ExFreePool(deviceDescription);
//OsrUnload(DriverObj);
return(STATUS_UNSUCCESSFUL);
}
#if DBG
DbgPrint("Max Map Regs for READ = %d.\n", DevExt->ReadMapRegsGot);
#endif
//
// Return the memory allocated from pool during initialization
//
ExFreePool(deviceDescription);
return STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrCanStopDevice
//
// This routine determines if the device cab be safely stopped. In
// our case we'll assume you can always stop the device. A device
// might not be able to be stopped, for example, if it doesn't have
// a queue for incoming requests or if it was notified that it is
// in the paging path.
//
// INPUTS:
//
// devExt - Address of our device extension.
// Irp - Address of the input IRP.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS;
//
// IRQL:
//
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS OsrCanStopDevice(POSR_DEVICE_EXT devExt, PIRP Irp)
{
UNREFERENCED_PARAMETER(devExt);
UNREFERENCED_PARAMETER(Irp);
return STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrCanRemoveDevice
//
// This routine determines if the device cab be safely removed. In our case
// we'll assume you can always remove the device. A device might note be able to
// be removed, for example, if it has opened handles or removing the device would
// result in the lost of data.
//
// INPUTS:
//
// devExt - Address of our device extension.
// Irp - Address of the input IRP.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS;
//
// IRQL:
//
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS OsrCanRemoveDevice(POSR_DEVICE_EXT devExt, PIRP Irp)
{
UNREFERENCED_PARAMETER(devExt);
UNREFERENCED_PARAMETER(Irp);
return STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrReturnResources
//
// This function is called to return any hardware resources which
// have been allocated for the device. In our case, these are
// the Interrupt Object, and any ports we might have mapped through
// memory. Note that we do NOT return our Device Object here.
//
// INPUTS:
//
// devExt - Address of our device extension.
// Irp - Address of the input IRP.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// VOID
//
// IRQL:
//
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID
OsrReturnResources(POSR_DEVICE_EXT devExt)
{
//
// Disconnect from any interrupts
//
if (devExt->InterruptObject) {
//
// Disconnect from the interrupt
//
IoDisconnectInterrupt(devExt->InterruptObject);
devExt->InterruptObject = NULL;
}
//
// Unmap any ports that were mapped
//
if (devExt->MappedPorts) {
MmUnmapIoSpace(devExt->AmccBaseRegisterAddress, 0x40);
devExt->MappedPorts = FALSE;
devExt->AmccBaseRegisterAddress = 0;
}
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrRequestIncrement
// OsrRequestDecrement
//
// These functions are used to track the number of requests that
// are presently queued the device indicated by the passed
// Device Extension.
//
// This code is based heavily on the PnP Sample Driver in the
// \General directory of the NTDDK.
//
// INPUTS:
//
// devExt - Address of our device extension.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS;
//
// IRQL:
//
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID
OsrRequestIncrement(POSR_DEVICE_EXT devExt)
{
LONG result;
result = InterlockedIncrement(&devExt->OutstandingIO);
ASSERT(result >= 0);
//
// Need to clear Remove
//
if (result == 1) {
//
// The remove event is cleared when the first request is
// added to the queue.
//
KeClearEvent(&devExt->RemoveEvent);
}
return;
}
VOID
OsrRequestDecrement(POSR_DEVICE_EXT devExt)
{
LONG result;
result = InterlockedDecrement(&devExt->OutstandingIO);
ASSERT(result >= 0);
if (result == 0) {
//
// The remove event is set when the queue is totally EMPTY.
//
KeSetEvent(&devExt->RemoveEvent,
IO_NO_INCREMENT,
FALSE);
}
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrWaitForStop
//
// Using the event set by the OsrRequestIncrement() and
// OsrRequestDecrement() functions, this function waits until
// the device can be stopped.
//
// On our device, STOP implies there are no active requests on
// the device, even though there are queued requests.
//
// INPUTS:
//
// devExt - Address of our device extension.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS;
//
// IRQL:
//
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID
OsrWaitForStop(POSR_DEVICE_EXT devExt)
{
devExt->HoldNewRequests = TRUE;
ASSERT(devExt->State != STATE_STARTED);
KeWaitForSingleObject(&devExt->StopEvent,
Executive,
KernelMode,
FALSE,
NULL);
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrWaitForRemove
//
// Using the event set by the OsrRequestIncrement() and
// OsrRequestDecrement() functions, this function waits until
// the device can be removed.
//
// On our device, REMOVE implies there are no active or queued
// requests on the device.
//
// INPUTS:
//
// devExt - Address of our device extension.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS;
//
// IRQL:
//
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID
OsrWaitForRemove(POSR_DEVICE_EXT devExt)
{
#if DBG
LARGE_INTEGER timeout;
NTSTATUS status;
timeout.QuadPart = -5*10*1000*1000; // 5 seconds
#endif
devExt->Removed = TRUE;
ASSERT(devExt->State < STATE_ALL_BELOW_FAIL);
#if DBG
wait_again:
status = KeWaitForSingleObject(&devExt->RemoveEvent,
Executive,
KernelMode,
FALSE,
&timeout);
if(status == STATUS_TIMEOUT) {
DbgPrint("OsrPci: *** Still Waiting for activity to stop on device?? %d. requests reamin\n", devExt->OutstandingIO);
goto wait_again;
}
if(status != STATUS_SUCCESS) {
DbgPrint("OsrPci: *** Wait not ended with success, and not with timeout?? Status = 0x%0x\n", status);
}
#else
KeWaitForSingleObject(&devExt->RemoveEvent,
Executive,
KernelMode,
FALSE,
NULL);
#endif
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrSystemControl
//
// This dispatch entry point is used to pass any WMI IRPs that we
// receive on to the underlying bus driver.
//
// INPUTS:
//
/// DriverObject - Pointer to driver object.
// Irp - Address of the input IRP.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// VOID
//
// IRQL:
//
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS
OsrSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
//
// Since we don't play WMI, pass this request on down to the
// driver below us...
//
IoSkipCurrentIrpStackLocation(Irp);
return(IoCallDriver(((POSR_DEVICE_EXT)(DeviceObject->DeviceExtension))->DeviceToSendIrpsTo, Irp));
}
#if DBG
VOID
OsrPrintState(POSR_DEVICE_EXT devExt)
{
if(devExt->State == STATE_REMOVED) {
DbgPrint("STATE_REMOVED\n");
return;
}
if(devExt->State == STATE_STARTED) {
DbgPrint("STATE_STARTED\n");
return;
}
if(devExt->State == STATE_REMOVE_PENDING) {
DbgPrint("STATE_REMOVE_PENDING\n");
return;
}
if(devExt->State == STATE_SURPRISE_REMOVED) {
DbgPrint("STATE_SURPRISE_REMOVED\n");
return;
}
if(devExt->State == STATE_STOP_PENDING) {
DbgPrint("STATE_STOP_PENDING\n");
return;
}
if(devExt->State == STATE_STOPPED) {
DbgPrint("STATE_STOPPED\n");
return;
}
if(devExt->State == STATE_NEVER_STARTED) {
DbgPrint("STATE_NEVER_STARTED\n");
return;
}
DbgPrint("*********UNKNOWN STATE Value 0x%0x\n", devExt->State);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -