📄 driver.c
字号:
case CmResourceTypeDma:
DebugPrintf_NoInfo((" Type: DMA (unsupported)\n"));
break;
case CmResourceTypeDeviceSpecific:
DebugPrintf_NoInfo((" Type: Device Specific (unsupported)\n"));
break;
case CmResourceTypeBusNumber:
DebugPrintf_NoInfo((" Type: Bus Number (unsupported)\n"));
break;
// NonArbitrated & ConfigData are currently #defined as the same number
case CmResourceTypeConfigData:
DebugPrintf_NoInfo((" Type: Non-Arbitrated or Config Data (unsupported)\n"));
break;
case CmResourceTypeDevicePrivate:
DebugPrintf_NoInfo((" Type: Device Private Data (unsupported)\n"));
break;
case CmResourceTypePcCardConfig:
DebugPrintf_NoInfo((" Type: PC Card Configuration (unsupported)\n"));
break;
case CmResourceTypeMfCardConfig:
DebugPrintf_NoInfo((" Type: Multi-function Card Configuration (unsupported)\n"));
break;
default:
DebugPrintf_NoInfo((" Type: ?Unknown Resource Type?\n"));
break;
}
}
// Make sure BAR 0 exists or the device can't be started
if (pdx->PciBar[0].pVa == NULL)
{
ErrorPrintf(("ERROR - BAR 0 address not configured, unable to load driver\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
// Record the Vendor and Device ID
pdx->Device.VendorId = PciRegs.VendorID;
pdx->Device.DeviceId = PciRegs.DeviceID;
// Get bus and slot numbers of the device
status =
GetBusSlotNumber(
pdx->pPhysicalDeviceObject,
pdx,
PciRegs.u.type0.BaseAddresses[0]
);
if (!NT_SUCCESS(status))
{
DebugPrintf(("WARNING - Unable to get bus and slot number\n"));
}
if (bIntPresent)
{
// Disable the PCI interrupt
PlxChipPciInterruptDisable(
pdx
);
status =
IoConnectInterrupt(
&pdx->pInterruptObject,
OnInterrupt,
pdx,
NULL,
vector,
IrqL,
IrqL,
mode,
TRUE,
affinity,
FALSE
);
if ( !NT_SUCCESS(status) )
{
ErrorPrintf((
"ERROR - IoConnectInterrupt() failed, status = 0x%08x\n",
status
));
pdx->pInterruptObject = NULL;
}
else
{
DebugPrintf(("Connected to interrupt vector\n"));
// Re-enable the PCI Interrupt
KeSynchronizeExecution(
pdx->pInterruptObject,
PlxChipPciInterruptEnable,
pdx
);
}
}
else
{
DebugPrintf(("No interrupt found\n"));
pdx->pInterruptObject = NULL;
}
// Allocate a DMA adapter object for physical memory allocations
PlxDmaAdapterAllocate(
pdx
);
// If this is the first device, allocate buffers
if (Gbl_DeviceCount == 0)
{
if (Gbl_CommonBufferSize != 0)
{
DebugPrintf((
"Allocating common buffer...\n"
));
// Set requested size
PciMem.Size = Gbl_CommonBufferSize;
// Allocate common buffer
PlxPciPhysicalMemoryAllocate(
pdx,
&PciMem,
TRUE, // Smaller buffer is ok
pdx // Assign owner as the device
);
}
/********************************************************
* Since this is the first device, make sure to invalidate
* its removal relations. This forces the PnP Manager
* to eventually query for removal relations before
* attempting to remove the device. Devices added after
* this one rely on it for the Common DMA and SGL buffers;
* therefore, it can only be removed last.
*******************************************************/
IoInvalidateDeviceRelations(
pdx->pPhysicalDeviceObject,
RemovalRelations
);
}
// Relay Common buffer properties to device
if (pGbl_CommonBuffer != NULL)
{
PlxChipPostCommonBufferProperties(
pdx,
(U32)pGbl_CommonBuffer->BusPhysical,
pGbl_CommonBuffer->Size
);
}
// Increment our device count
InterlockedIncrement(
&Gbl_DeviceCount
);
return STATUS_SUCCESS;
}
/******************************************************************************
*
* Function : StopDevice
*
* Description: Stop a device
*
******************************************************************************/
VOID
StopDevice(
PDEVICE_OBJECT fdo
)
{
PLX_PHYSICAL_MEM PciMem;
DEVICE_EXTENSION *pdx;
pdx = fdo->DeviceExtension;
// Free all interrupt resources
if (pdx->pInterruptObject != NULL)
{
// Disable the PCI interrupt
KeSynchronizeExecution(
pdx->pInterruptObject,
(PKSYNCHRONIZE_ROUTINE)PlxChipPciInterruptDisable,
(PVOID)pdx
);
// Remove the ISR
IoDisconnectInterrupt(
pdx->pInterruptObject
);
pdx->pInterruptObject = NULL;
}
// Release the common buffer if this device owns it
if (pGbl_CommonBuffer != NULL)
{
if (pGbl_CommonBuffer->pOwner == pdx)
{
// Release common buffer
DebugPrintf((
"De-allocating Common Buffer...\n"
));
// Prepare buffer properties for parameter
PciMem.PhysicalAddr = pGbl_CommonBuffer->BusPhysical;
PciMem.Size = pGbl_CommonBuffer->Size;
// Release the buffer
PlxPciPhysicalMemoryFree(
pdx,
&PciMem
);
// Mark buffer as released
pGbl_CommonBuffer = NULL;
}
}
// Remove relayed Common buffer properties
PlxChipPostCommonBufferProperties(
pdx,
0,
0
);
// Release the DMA adapter object
PlxDmaAdapterFree(
pdx
);
// Unmap I/O regions from kernel space (No local register access after this)
PlxPciBarResourcesUnmap(
pdx
);
// Decrement our device count
InterlockedDecrement(
&Gbl_DeviceCount
);
}
/******************************************************************************
*
* Function : PlxDmaAdapterAllocate
*
* Description: Allocate a DMA adapter object which will provide support for
* later allocation of physically contiguous page-locked memory.
*
******************************************************************************/
NTSTATUS
PlxDmaAdapterAllocate(
DEVICE_EXTENSION *pdx
)
{
ULONG NumMapRegisters;
DEVICE_DESCRIPTION DeviceDescription;
DebugPrintf((
"Allocating DMA Adapter object...\n"
));
// Verify object not already created
if (pdx->pDmaAdapter != NULL)
{
DebugPrintf(("ERROR - DMA Adapter object already exist, unable to allocate\n"));
return STATUS_OBJECT_NAME_EXISTS;
}
// Clear device description
RtlZeroMemory(
&DeviceDescription,
sizeof(DEVICE_DESCRIPTION)
);
// Set device DMA properties
DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
DeviceDescription.Master = TRUE; // Device is bus master
DeviceDescription.ScatterGather = TRUE; // Device supports SGL
DeviceDescription.Dma32BitAddresses = TRUE; // Device supports 32-bit addressing
DeviceDescription.Reserved1 = FALSE; // For future use, must be FALSE
DeviceDescription.Dma64BitAddresses = FALSE; // Don't use 64-bit addressing
DeviceDescription.InterfaceType = PCIBus; // Device is PCI
DeviceDescription.MaximumLength = PHYS_MEM_MAX_SIZE_ALL;
// OS will assign map register count
NumMapRegisters = 0;
// Allocate a DMA adapter object
pdx->pDmaAdapter =
IoGetDmaAdapter(
pdx->pPhysicalDeviceObject,
&DeviceDescription,
&NumMapRegisters
);
if (pdx->pDmaAdapter == NULL)
{
DebugPrintf(("ERROR - DMA Adapter allocation failed\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
return STATUS_SUCCESS;
}
/******************************************************************************
*
* Function : PlxDmaAdapterFree
*
* Description: Frees the device DMA adapter object
*
******************************************************************************/
NTSTATUS
PlxDmaAdapterFree(
DEVICE_EXTENSION *pdx
)
{
DebugPrintf((
"Releasing DMA Adapter object...\n"
));
// Verify DMA Adapter was created
if (pdx->pDmaAdapter == NULL)
{
DebugPrintf(("ERROR - DMA Adapter object doesn't exist, unable to free object\n"));
return STATUS_RESOURCE_TYPE_NOT_FOUND;
}
// Delete the DMA Adapter
pdx->pDmaAdapter->DmaOperations->PutDmaAdapter(
pdx->pDmaAdapter
);
// DMA adapter object deleted, no longer available
pdx->pDmaAdapter = NULL;
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -