📄 pci_sample.c
字号:
//
// Stop the watchdog timer
//
IoStopTimer(devObj);
//
// Delete the device object
//
IoDeleteDevice(devObj);
}
#if DBG
///////////////////////////////////////////////////////////////////////////////
//
// OsrPrintConfig
//
// This routine is called to print out the PCI configuration information for
// our device.
//
// INPUTS:
//
// configInfo - Address of the PCI_COMMON_CONFIG information for our device.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// None.
//
// IRQL:
//
// This routine is called at IRQL_PASSIVE_LEVEL.
//
// NOTES:
//
// We only use this for debugging purposes.
//
///////////////////////////////////////////////////////////////////////////////
static VOID
OsrPrintConfig(PPCI_COMMON_CONFIG configInfo)
{
ULONG index;
DbgPrint("Displaying PCI Configuration Information\n");
DbgPrint("\tRevisionID is 0x%x\n", (int)configInfo->RevisionID);
DbgPrint("\tProgIf is 0x%x\n", (int) configInfo->ProgIf);
DbgPrint("\tSubClass is 0x%x\n", (int) configInfo->SubClass);
DbgPrint("\tBaseClass is 0x%x\n", (int) configInfo->BaseClass);
DbgPrint("\tCacheLineSize is 0x%x\n", (int) configInfo->CacheLineSize);
DbgPrint("\tLatencyTimer is 0x%x\n", (int) configInfo->LatencyTimer);
DbgPrint("\tHeaderType is 0x%x\n", (int) configInfo->HeaderType);
DbgPrint("\tBIST is 0x%x\n", (int) configInfo->HeaderType);
for (index = 0; index < PCI_TYPE0_ADDRESSES; index++) {
DbgPrint("\tBaseAddresses[%d] is 0x%x\n",index, configInfo->u.type0.BaseAddresses[index]);
}
DbgPrint("\tROMBaseAddress is 0x%x\n", configInfo->u.type0.ROMBaseAddress);
DbgPrint("\tInterruptLine is 0x%x\n", configInfo->u.type0.InterruptLine);
DbgPrint("\tInterruptPin is 0x%x\n", configInfo->u.type0.InterruptPin);
DbgPrint("****************************\n");
}
//
// Some static string tables we use as part of debugging
//
static PSTR CmResourceTypeStrings[] =
{
"CmResourceTypeNull",
"CmResourceTypePort",
"CmResourceTypeInterrupt",
"CmResourceTypeMemory",
"CmResourceTypeDma",
"CmResourceTypeDeviceSpecific",
"CmResourceTypeMaximum"
};
static PSTR CmShareDispositionStrings[] =
{
"CmResourceShareUndetermined",
"CmResourceShareDeviceExclusive",
"CmResourceShareDriverExclusive",
"CmResourceShareShared"
};
///////////////////////////////////////////////////////////////////////////////
//
// OsrPrintResourceList
//
// This routine is called to print out the Resource descriptor list containing
// the resources allocated for our device by NT.
//
// INPUTS:
//
// Resources - Address of the CM_RESOURCE_LIST information for our device.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// None.
//
// IRQL:
//
// This routine is called at IRQL_PASSIVE_LEVEL.
//
// NOTES:
//
// We only use this for debugging purposes.
//
///////////////////////////////////////////////////////////////////////////////
static VOID
OsrPrintResourceList(PCM_RESOURCE_LIST Resources)
{
ULONG index, index2;
DbgPrint("%d. resource descriptor list(s) returned\n", Resources->Count);
for (index = 0; index < Resources->Count; index++) {
DbgPrint("\t[%d] Interface Type 0x%x\n",
index, Resources->List[index].InterfaceType);
DbgPrint("\t[%d] BusNumber 0x%x\n",
index, Resources->List[index].BusNumber);
DbgPrint("\t[%d] Version 0x%x\n",
index, Resources->List[index].PartialResourceList.Version);
DbgPrint("\t[%d] Revision 0x%x\n",
index, Resources->List[index].PartialResourceList.Revision);
DbgPrint("\t[%d] Partial Resource Descriptors %d.\n",
index, Resources->List[index].PartialResourceList.Count);
for (index2 = 0;
index2 < Resources->List[index].PartialResourceList.Count;
index2++) {
PCM_PARTIAL_RESOURCE_DESCRIPTOR prd; // Too much to type!
prd = &Resources->List[index].PartialResourceList.PartialDescriptors[index2];
DbgPrint("\t\t[%d] Type 0x%x (%s)\n",
index2, prd->Type, CmResourceTypeStrings[prd->Type]);
DbgPrint("\t\t[%d] Share Disposition 0x%x (%s)\n",
index2, prd->ShareDisposition,
CmShareDispositionStrings[prd->ShareDisposition]);
DbgPrint("\t\t[%d] Flags 0x%x\n", index2, prd->Flags);
DbgPrint("\t\t[%d] Raw 0x%x %x %x\n",
index2, prd->u.DeviceSpecificData.DataSize,
prd->u.DeviceSpecificData.Reserved1,
prd->u.DeviceSpecificData.Reserved2);
switch (prd->Type) {
case CmResourceTypePort:
if (prd->Flags == CM_RESOURCE_PORT_MEMORY)
DbgPrint("\t\t[%d] port memory starting at 0x%x length 0x%x\n",
index2, prd->u.Port.Start.LowPart,
prd->u.Port.Length);
if (prd->Flags == CM_RESOURCE_PORT_IO)
DbgPrint("\t\t[%d] port i/o starting at 0x%x length 0x%x\n",
index2, prd->u.Port.Start.LowPart,
prd->u.Port.Length);
break;
case CmResourceTypeInterrupt:
if (prd->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)
DbgPrint("\t\t[%d] level interrupt at lvl 0x%x vector 0x%x affinity 0x%x\n",
index2, prd->u.Interrupt.Level,
prd->u.Interrupt.Vector,
prd->u.Interrupt.Affinity);
if (prd->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
DbgPrint("\t\t[%d] latched interrupt at lvl 0x%x vector 0x%x affinity 0x%x\n",
index2, prd->u.Interrupt.Level,
prd->u.Interrupt.Vector,
prd->u.Interrupt.Affinity);
break;
case CmResourceTypeMemory:
if (prd->Flags == CM_RESOURCE_MEMORY_READ_WRITE)
DbgPrint("\t\t[%d] r/w memory starting at 0x%x length 0x%x\n",
index2, prd->u.Memory.Start.LowPart,
prd->u.Memory.Length);
if (prd->Flags & CM_RESOURCE_MEMORY_READ_ONLY)
DbgPrint("\t\t[%d] r/o memory starting at 0x%x length 0x%x\n",
index2, prd->u.Memory.Start.LowPart,
prd->u.Memory.Length);
if (prd->Flags & CM_RESOURCE_MEMORY_WRITE_ONLY)
DbgPrint("\t\t[%d] w/o memory starting at 0x%x length 0x%x\n",
index2, prd->u.Memory.Start.LowPart,
prd->u.Memory.Length);
break;
case CmResourceTypeDma:
DbgPrint("\t\t[%d] DMA on channel 0x%x\n",
index2, prd->u.Dma.Channel);
break;
case CmResourceTypeDeviceSpecific:
DbgPrint("\t\t[%d] Device specific data at 0x%x length 0x%x\n",
index2,
((ULONG) &prd->u.DeviceSpecificData.Reserved2) + (ULONG)sizeof(ULONG),
prd->u.DeviceSpecificData.DataSize);
break;
default:
//
// Say what?!! Unknown resource type. Something is pretty wierd here.
//
DbgPrint("Unknown resource type 0x%x\n", prd->Type);
break;
}
}
DbgPrint("\t[%d] ***** End dump ******\n", index);
}
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrPrintIntcsr
//
// This routine is called to print out a descriptive view of the bits set
// in the IntCsr register.
//
// INPUTS:
//
// Intcsr - Contents of the IntCsr register.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// None.
//
// IRQL:
//
// This routine is called at IRQL >= IRQL_PASSIVE_LEVEL.
//
// NOTES:
//
// We only use this for debugging purposes. It is called by the ISR as well
// as by the read and write paths.
//
///////////////////////////////////////////////////////////////////////////////
VOID
OsrPrintIntcsr(ULONG Intcsr)
{
if(Intcsr & AMCC_INT_OUT_FIFO_CTRL) {
DbgPrint("\tOut FIFO Ctrl\n");
}
if(Intcsr & AMCC_INT_IN_FIFO_CTRL) {
DbgPrint("\tIn FIFO Ctrl\n");
}
if(Intcsr & AMCC_INT_FIFO_ADVA_BYTE0) {
DbgPrint("\tADVA BYTE0\n");
}
if(Intcsr & AMCC_INT_FIFO_ADVA_BYTE1) {
DbgPrint("\tADVA BYTE1\n");
}
if(Intcsr & AMCC_INT_FIFO_ADVA_BYTE2) {
DbgPrint("\tADVA BYTE2\n");
}
if(Intcsr & AMCC_INT_FIFO_ADVA_BYTE3) {
DbgPrint("\tADVA BYTE3\n");
}
if(Intcsr & AMCC_INT_FIFO_ADVP_BYTE0) {
DbgPrint("\tADVP BYTE0\n");
}
if(Intcsr & AMCC_INT_FIFO_ADVP_BYTE1) {
DbgPrint("\tADVP BYTE1\n");
}
if(Intcsr & AMCC_INT_FIFO_ADVP_BYTE2) {
DbgPrint("\tADVP BYTE2\n");
}
if(Intcsr & AMCC_INT_FIFO_ADVP_BYTE3) {
DbgPrint("\tADVP BYTE3\n");
}
if(Intcsr & AMCC_INT_ENDIAN_16BIT) {
DbgPrint("\tENDIAN 16BIT\n");
}
if(Intcsr & AMCC_INT_ENDIAN_32BIT) {
DbgPrint("\tENDIAN 32BIT\n");
}
if(Intcsr & AMCC_INT_ENDIAN_64BIT) {
DbgPrint("\tENDIAN 64BIT\n");
}
if(Intcsr & AMCC_INT_INTERRUPTED) {
DbgPrint("\tINTERRUPTED\n");
}
if(Intcsr & AMCC_INT_RESERVED22) {
DbgPrint("\tRESERVED 22\n");
}
if(Intcsr & AMCC_INT_TARG_ABORT) {
DbgPrint("\tTARG_ABORT\n");
}
if(Intcsr & AMCC_INT_MAST_ABORT) {
DbgPrint("\tMAST_ABORT\n");
}
if(Intcsr & AMCC_INT_READ_COMP) {
DbgPrint("\tREAD_COMP\n");
}
if(Intcsr & AMCC_INT_WRITE_COMP) {
DbgPrint("\tWRITE_COMP\n");
}
if(Intcsr & AMCC_INT_INMBX_ACK) {
DbgPrint("\tINMBX_ACK\n");
}
if(Intcsr & AMCC_INT_OUTMBX_ACK) {
DbgPrint("\tOUTMBX_ACK\n");
}
if(Intcsr & AMCC_INT_INT_ON_READ) {
DbgPrint("\tINT_ON_READ\n");
}
if(Intcsr & AMCC_INT_INT_ON_WRITE) {
DbgPrint("\tINT_ON_WRITE\n");
}
if(Intcsr & AMCC_INT_RESERVED13) {
DbgPrint("\tRESERVED13\n");
}
if(Intcsr & AMCC_INT_ENABLE_OUTMBX_INT) {
DbgPrint("\tENABLE_OUTMBX_INT\n");
}
if(Intcsr & AMCC_INT_ENABLE_INMBX_INT) {
DbgPrint("\tENABLE_INMBX_INT\n");
}
}
#endif // DBG
///////////////////////////////////////////////////////////////////////////////
//
// OsrReturnPool
//
// This routine is called to delete the memory assiged to the Driver for
// configInfo, DeviceDescription and Resources.
//
// INPUTS:
//
// ConfigInfo - Address of the PCI_COMMON_CONFIG information to delete.
//
// DeviceDescription - Address of the DEVICE_DESCRIPTION information to delete.
//
// Resources - Address of the CM_RESOURCE_LIST to delete.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// None.
//
// IRQL:
//
// This routine is called at IRQL >= IRQL_PASSIVE_LEVEL.
//
// NOTES:
//
///////////////////////////////////////////////////////////////////////////////
static VOID OsrReturnPool(PPCI_COMMON_CONFIG ConfigInfo, PDEVICE_DESCRIPTION
DeviceDescription, PCM_RESOURCE_LIST Resources)
{
if(ConfigInfo)
ExFreePool(ConfigInfo);
if(DeviceDescription)
ExFreePool(DeviceDescription);
if(Resources)
ExFreePool(Resources);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -