📄 pcie.c
字号:
ResourcesTranslated - The translated PnP resources associated with the
device. This is what is important to a PCI device.
Return Value:
NT status code - failure will result in the device stack being torn down
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION devExt;
UNREFERENCED_PARAMETER(Resources);
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
"--> PCIEEvtDevicePrepareHardware");
devExt = PCIEGetDeviceContext(Device);
status = PCIEPrepareHardware(devExt, ResourcesTranslated);
if (!NT_SUCCESS (status)){
return status;
}
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
"<-- PCIEEvtDevicePrepareHardware, status %!STATUS!", status);
return status;
}
NTSTATUS
PCIEEvtDeviceReleaseHardware(
IN WDFDEVICE Device,
IN WDFCMRESLIST ResourcesTranslated
)
/*++
Routine Description:
Unmap the resources that were mapped in PCIEEvtDevicePrepareHardware.
This will only be called when the device stopped for resource rebalance,
surprise-removed or query-removed.
Arguments:
Device - A handle to the WDFDEVICE
ResourcesTranslated - The translated PnP resources associated with the
device. This is what is important to a PCI device.
Return Value:
NT status code - failure will result in the device stack being torn down
--*/
{
PDEVICE_EXTENSION devExt;
NTSTATUS status = STATUS_SUCCESS;
UNREFERENCED_PARAMETER(ResourcesTranslated);
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
"--> PCIEEvtDeviceReleaseHardware");
devExt = PCIEGetDeviceContext(Device);
if (devExt->RegsBase)
{
// Free logical address of REG memory on card
MmUnmapIoSpace(devExt->RegsBase, devExt->RegsLength);
devExt->RegsBase = NULL;
}
if (devExt->BufferLogicalAddress)
{
// Free DMA buffer for device-to-host
MmFreeContiguousMemory(devExt->BufferLogicalAddress);
devExt->BufferLogicalAddress = NULL;
devExt->BufferPhysicalAddress = NULL;
devExt->BufferSize = 0;
}
if (devExt->Buffer2LogicalAddress)
{
// Free DMA buffer for host-to-device
MmFreeContiguousMemory(devExt->Buffer2LogicalAddress);
devExt->Buffer2LogicalAddress = NULL;
devExt->Buffer2PhysicalAddress = NULL;
devExt->Buffer2Size = 0;
}
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- PCIEEvtDeviceReleaseHardware");
return status;
}
NTSTATUS
PCIEEvtDeviceD0Entry(
IN WDFDEVICE Device,
IN WDF_POWER_DEVICE_STATE PreviousState
)
/*++
Routine Description:
This routine prepares the device for use. It is called whenever the device
enters the D0 state, which happens when the device is started, when it is
restarted, and when it has been powered off.
Note that interrupts will not be enabled at the time that this is called.
They will be enabled after this callback completes.
This function is not marked pageable because this function is in the
device power up path. When a function is marked pagable and the code
section is paged out, it will generate a page fault which could impact
the fast resume behavior because the client driver will have to wait
until the system drivers can service this page fault.
Arguments:
Device - The handle to the WDF device object
PreviousState - The state the device was in before this callback was invoked.
Return Value:
NTSTATUS
Success implies that the device can be used.
Failure will result in the device stack being torn down.
--*/
{
PDEVICE_EXTENSION devExt;
NTSTATUS status;
UNREFERENCED_PARAMETER(PreviousState);
return STATUS_SUCCESS;
}
NTSTATUS
PCIEEvtDeviceD0Exit(
IN WDFDEVICE Device,
IN WDF_POWER_DEVICE_STATE TargetState
)
/*++
Routine Description:
This routine undoes anything done in PCIEEvtDeviceD0Entry. It is called
whenever the device leaves the D0 state, which happens when the device
is stopped, when it is removed, and when it is powered off.
The device is still in D0 when this callback is invoked, which means that
the driver can still touch hardware in this routine.
Note that interrupts have already been disabled by the time that this
callback is invoked.
Arguments:
Device - The handle to the WDF device object
TargetState - The state the device will go to when this callback completes.
Return Value:
Success implies that the device can be used. Failure will result in the
device stack being torn down.
--*/
{
PDEVICE_EXTENSION devExt;
PAGED_CODE();
devExt = PCIEGetDeviceContext(Device);
switch (TargetState) {
case WdfPowerDeviceD1:
case WdfPowerDeviceD2:
case WdfPowerDeviceD3:
//
// Fill in any code to save hardware state here.
//
//
// Fill in any code to put the device in a low-power state here.
//
break;
case WdfPowerDevicePrepareForHibernation:
//
// Fill in any code to save hardware state here. Do not put in any
// code to shut the device off. If this device cannot support being
// in the paging path (or being a parent or grandparent of a paging
// path device) then this whole case can be deleted.
//
break;
case WdfPowerDeviceD3Final:
default:
//
// Reset the hardware, as we're shutting down for the last time.
//
PCIEShutdown(devExt);
break;
}
return STATUS_SUCCESS;
}
VOID
PCIEEvtDriverContextCleanup(
IN WDFDRIVER Driver
)
/*++
Routine Description:
Free all the resources allocated in DriverEntry.
Arguments:
Driver - handle to a WDF Driver object.
Return Value:
VOID.
--*/
{
PAGED_CODE ();
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
"PCIEEvtDriverContextCleanup: enter");
WPP_CLEANUP( WdfDriverWdmGetDriverObject( Driver ) );
}
NTSTATUS
PCIESetIdleAndWakeSettings(
IN PDEVICE_EXTENSION FdoData
)
/*++
Routine Description:
Called by EvtDeviceAdd to set the idle and wait-wake policy. Registering this policy
causes Power Management Tab to show up in the device manager. By default these
options are enabled and the user is provided control to change the settings.
Return Value:
NTSTATUS - Failure status is returned if the device is not capable of suspending
or wait-waking the machine by an external event. Framework checks the
capability information reported by the bus driver to decide whether the device is
capable of waking the machine.
--*/
{
WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings;
WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS wakeSettings;
NTSTATUS status = STATUS_SUCCESS;
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> PCIESetIdleAndWakeSettings");
PAGED_CODE();
//
// Init the idle policy structure.
//
WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, IdleCanWakeFromS0);
idleSettings.IdleTimeout = 10000; // 10-sec
status = WdfDeviceAssignS0IdleSettings(FdoData->Device, &idleSettings);
if ( !NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"DeviceSetPowerPolicyS0IdlePolicy failed %!STATUS!", status);
return status;
}
//
// Init wait-wake policy structure.
//
WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings);
status = WdfDeviceAssignSxWakeSettings(FdoData->Device, &wakeSettings);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"DeviceAssignSxWakeSettings failed %!STATUS!", status);
return status;
}
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- PCIESetIdleAndWakeSettings");
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -