📄 driver.c
字号:
InitializeListHead(
&(pdx->List_PhysicalMem)
);
KeInitializeSpinLock(
&(pdx->Lock_PhysicalMemList)
);
InitializeListHead(
&(pdx->List_BarMappings)
);
KeInitializeSpinLock(
&(pdx->Lock_BarMappingsList)
);
// Initialize the interrupt DPC
KeInitializeDpc(
&(pdx->DpcForIsr),
DpcForIsr,
pdx
);
#if defined(DMA_SUPPORT)
// Initialize DMA management variables
for (i = 0 ; i < NUMBER_OF_DMA_CHANNELS; i++)
{
pdx->DmaInfo[i].state = DmaStateClosed;
pdx->DmaInfo[i].bLocalAddrConstant = FALSE;
}
KeInitializeSpinLock(
&(pdx->Lock_DmaChannel)
);
#endif // DMA_SUPPORT
KeInitializeEvent(
&pdx->evRemove,
NotificationEvent,
FALSE
);
/*
* Since we must pass PNP requests down to the next device object in the
* chain (namely the physical device object created by the bus enumerator),
* we have to remember what that device is. That's why we defined the
* LowerDeviceObject member in our device extension.
*/
pdx->pLowerDeviceObject =
IoAttachDeviceToDeviceStack(
fdo,
pdo
);
DebugPrintf((
"Attached device to stack\n"
" Functional DevObj: 0x%p\n"
" Lower DevObj: 0x%p\n"
" Physical DevObj: 0x%p\n",
fdo, pdx->pLowerDeviceObject, pdo
));
// Notify the power manager of the initial power state
pdx->PowerState = PowerDeviceD0; // Start device in full power state
PowerState.DeviceState = PowerDeviceD0;
PoSetPowerState(
fdo,
DevicePowerState,
PowerState
);
// Indicate the I/O Manager buffer management method
fdo->Flags |= DO_BUFFERED_IO;
// Manually clear the Device Initialzing flag
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}
/******************************************************************************
*
* Function : RemoveDevice
*
* Description: Remove a functional device object
*
******************************************************************************/
VOID
RemoveDevice(
PDEVICE_OBJECT fdo
)
{
NTSTATUS status;
UNICODE_STRING DeviceLinkName_Unicode;
DEVICE_EXTENSION *pdx;
pdx = fdo->DeviceExtension;
// Remove Win32 link name
if (wcslen(pdx->LinkName) != 0)
{
DebugPrintf((
"Removing Win32 link (%ws)\n",
pdx->LinkName
));
RtlInitUnicodeString(
&DeviceLinkName_Unicode,
pdx->LinkName
);
status =
IoDeleteSymbolicLink(
&DeviceLinkName_Unicode
);
if ( !NT_SUCCESS(status) )
DebugPrintf(("WARNING - Unable to remove Win32 link\n"));
}
// Detach device from the device object stack
if (pdx->pLowerDeviceObject)
{
IoDetachDevice(
pdx->pLowerDeviceObject
);
}
DebugPrintf(("Deleting device object...\n"));
// Delete the functional device object
IoDeleteDevice(
fdo
);
}
/******************************************************************************
*
* Function : StartDevice
*
* Description: Start a device
*
******************************************************************************/
NTSTATUS
StartDevice(
PDEVICE_OBJECT fdo,
PCM_PARTIAL_RESOURCE_LIST ResourceListRaw,
PCM_PARTIAL_RESOURCE_LIST ResourceList
)
{
U8 i;
U8 BarIndex;
U32 vector;
KIRQL IrqL;
BOOLEAN bIntPresent;
NTSTATUS status;
KAFFINITY affinity;
KINTERRUPT_MODE mode;
PLX_PHYSICAL_MEM PciMem;
DEVICE_EXTENSION *pdx;
PCI_COMMON_CONFIG PciRegs;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceRaw;
PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource;
pdx = fdo->DeviceExtension;
bIntPresent = FALSE;
ResourceRaw = ResourceListRaw->PartialDescriptors;
Resource = ResourceList->PartialDescriptors;
// Get the PCI base addresses
PciRegisterBufferRead(
fdo,
0,
&PciRegs,
sizeof(PCI_COMMON_CONFIG)
);
DebugPrintf((
"Resource list contains %d descriptors\n",
ResourceListRaw->Count
));
for (i = 0; i < ResourceListRaw->Count; ++i, ++Resource, ++ResourceRaw)
{
DebugPrintf_NoInfo((" Resource %02d\n", i));
switch (ResourceRaw->Type)
{
case CmResourceTypeInterrupt:
bIntPresent = TRUE;
IrqL = (KIRQL) Resource->u.Interrupt.Level;
vector = Resource->u.Interrupt.Vector;
affinity = Resource->u.Interrupt.Affinity;
DebugPrintf_NoInfo((
" Type : Interrupt\n"
" Vector : 0x%02x (Translated = 0x%02x)\n"
" IRQL : 0x%02x (Translated = 0x%02x)\n"
" Affinity : 0x%08x\n",
ResourceRaw->u.Interrupt.Vector, vector,
ResourceRaw->u.Interrupt.Level, IrqL,
ResourceRaw->u.Interrupt.Affinity
));
if (ResourceRaw->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
{
mode = Latched;
DebugPrintf_NoInfo((" Mode : Latched\n"));
}
else
{
mode = LevelSensitive;
DebugPrintf_NoInfo((" Mode : Level Sensitive\n"));
}
break;
case CmResourceTypePort:
DebugPrintf_NoInfo((
" Type : I/O Port\n"
" Address : 0x%08lx (Translated = 0x%08lx)\n"
" Size : 0x%08x ",
ResourceRaw->u.Port.Start,
Resource->u.Port.Start,
ResourceRaw->u.Port.Length
));
if (ResourceRaw->u.Port.Length >= (1 << 10))
{
DebugPrintf_NoInfo((
"(%d Kb)\n",
ResourceRaw->u.Port.Length >> 10
));
}
else
{
DebugPrintf_NoInfo((
"(%d Bytes)\n",
ResourceRaw->u.Port.Length
));
}
BarIndex =
GetBarIndex(
ResourceRaw->u.Port.Start,
&PciRegs
);
DebugPrintf_NoInfo((
" PCI BAR : "
));
if (BarIndex != (U8)-1)
{
DebugPrintf_NoInfo((
"%d\n",
BarIndex
));
pdx->PciBar[BarIndex].Physical = ResourceRaw->u.Port.Start;
pdx->PciBar[BarIndex].Size = ResourceRaw->u.Port.Length;
pdx->PciBar[BarIndex].pVa = NULL;
pdx->PciBar[BarIndex].bIsIoSpace = TRUE;
}
else
{
DebugPrintf_NoInfo((
"??\n"
));
}
break;
case CmResourceTypeMemory:
DebugPrintf_NoInfo((
" Type : Memory Space\n"
" Address : 0x%08lx (Translated = 0x%08lx)\n"
" Size : 0x%08x ",
ResourceRaw->u.Memory.Start,
Resource->u.Memory.Start,
ResourceRaw->u.Memory.Length
));
if (ResourceRaw->u.Memory.Length >= (1 << 10))
{
DebugPrintf_NoInfo((
"(%d Kb)\n",
ResourceRaw->u.Memory.Length >> 10
));
}
else
{
DebugPrintf_NoInfo((
"(%d Bytes)\n",
ResourceRaw->u.Memory.Length
));
}
BarIndex =
GetBarIndex(
ResourceRaw->u.Memory.Start,
&PciRegs
);
DebugPrintf_NoInfo((
" PCI BAR : "
));
if (BarIndex != (U8)-1)
{
DebugPrintf_NoInfo((
"%d\n",
BarIndex
));
DebugPrintf_NoInfo((" Kernel VA: "));
// Record resources
pdx->PciBar[BarIndex].Physical = ResourceRaw->u.Memory.Start;
pdx->PciBar[BarIndex].Size = ResourceRaw->u.Memory.Length;
pdx->PciBar[BarIndex].bIsIoSpace = FALSE;
status =
PlxPciBarResourceMap(
pdx,
BarIndex
);
if ( NT_SUCCESS(status) )
{
DebugPrintf_NoInfo((
"0x%p\n",
pdx->PciBar[BarIndex].pVa
));
}
else
{
DebugPrintf_NoInfo((
"ERROR - Unable to map 0x%08lx ==> Kernel VA\n",
ResourceRaw->u.Memory.Start
));
}
}
else
{
DebugPrintf_NoInfo((
"??\n"
));
}
break;
case CmResourceTypeNull:
DebugPrintf_NoInfo((" Type: Null (unsupported)\n"));
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -