📄 pnputils.c
字号:
case CmResourceTypeDma:
// we don't do anything with DMA - fall through to default case
default:
break;
} // end switch( PartialResourceDescriptor->Type )
} // end for(... ; i < PartialResourceList->Count ; ...)
} // end if( FullResourceDescriptor )
return status;
}
BOOLEAN PptIsPci(
PFDO_EXTENSION Fdx,
PIRP Irp
)
/*++
Does this look like a PCI card? Return TRUE if yes, FALSE otherwise
--*/
{
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
PCM_RESOURCE_LIST ResourceList;
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
ULONG i;
ULONG portResourceDescriptorCount = 0;
BOOLEAN largePortRangeFound = FALSE;
ULONG rangeLength;
//
// If there are more than 2 IO resource descriptors, or if any IO resource
// descriptor has a range > 8 bytes, then assume that this is a PCI device
// and requires non-traditional handling.
//
ResourceList = irpStack->Parameters.StartDevice.AllocatedResourcesTranslated;
if (ResourceList == NULL) {
// we weren't given any resources
return FALSE;
}
FullResourceDescriptor = &ResourceList->List[0];
if (FullResourceDescriptor) {
PartialResourceList = &FullResourceDescriptor->PartialResourceList;
for (i = 0; i < PartialResourceList->Count; i++) {
PartialResourceDescriptor = &PartialResourceList->PartialDescriptors[i];
switch (PartialResourceDescriptor->Type) {
case CmResourceTypePort:
rangeLength = PartialResourceDescriptor->u.Port.Length;
DD((PCE)Fdx,DDT,"pnp::PptIsPCI - CmResourceTypePort - Start= %I64x, Length= %x , \n",
PartialResourceDescriptor->u.Port.Start.QuadPart, rangeLength);
++portResourceDescriptorCount;
if( rangeLength > 8 ) {
largePortRangeFound = TRUE;
}
break;
default:
;
} // end switch( PartialResourceDescriptor->Type )
} // end for(... ; i < PartialResourceList->Count ; ...)
} // end if( FullResourceDescriptor )
if( (portResourceDescriptorCount > 2) || (TRUE == largePortRangeFound) ) {
// looks like PCI
return TRUE;
} else {
// does not look like PCI
return FALSE;
}
}
NTSTATUS
PptPnpStartScanCmResourceList(
IN PFDO_EXTENSION Fdx,
IN PIRP Irp,
OUT PBOOLEAN FoundPort,
OUT PBOOLEAN FoundIrq,
OUT PBOOLEAN FoundDma
)
/*++dvdf3
Routine Description:
This function is a helper function called by PptPnpStartDevice().
This function scans the CM_RESOURCE_LIST supplied with the Pnp
IRP_MN_START_DEVICE IRP, extracts the resources from the list,
and saves them in the device Fdx.
Arguments:
Fdx - The device extension of the target of the START IRP
Irp - The IRP
FoundPort - Did we find a Port resource?
FoundIrq - Did we find an IRQ resource?
FoundDma - Did we find a DMA resource?
Return Value:
STATUS_SUCCESS - if we were given a resource list,
STATUS_INSUFFICIENT_RESOURCES - otherwise
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
PCM_RESOURCE_LIST ResourceList;
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
ULONG i;
PHYSICAL_ADDRESS start;
ULONG length;
BOOLEAN isPci = FALSE;
*FoundPort = FALSE;
*FoundIrq = FALSE;
*FoundDma = FALSE;
ResourceList = irpStack->Parameters.StartDevice.AllocatedResourcesTranslated;
if (ResourceList == NULL) {
// we weren't given any resources, bail out
DD((PCE)Fdx,DDT,"START - FAIL - No Resources - AllocatedResourcesTranslated == NULL\n");
status = STATUS_INSUFFICIENT_RESOURCES;
goto targetExit;
}
if( TRUE == PptIsPci( Fdx, Irp ) ) {
// This appears to be a PCI card
status = PptPnpStartScanPciCardCmResourceList(Fdx, Irp, FoundPort, FoundIrq, FoundDma);
isPci=TRUE;
goto targetExit;
}
//
// Device appears to be traditional / non-PCI card parallel port
//
FullResourceDescriptor = &ResourceList->List[0];
if (FullResourceDescriptor) {
Fdx->InterfaceType = FullResourceDescriptor->InterfaceType;
PartialResourceList = &FullResourceDescriptor->PartialResourceList;
for (i = 0; i < PartialResourceList->Count; i++) {
PartialResourceDescriptor = &PartialResourceList->PartialDescriptors[i];
switch (PartialResourceDescriptor->Type) {
case CmResourceTypePort:
start = PartialResourceDescriptor->u.Port.Start;
length = PartialResourceDescriptor->u.Port.Length;
DD((PCE)Fdx,DDT,"pnp::PptPnpStartScanCmResourceList - start= %I64x , length=%x\n",start, length);
*FoundPort = TRUE;
if ((Fdx->PortInfo.OriginalController.LowPart == 0) &&
(Fdx->PortInfo.OriginalController.HighPart == 0)) {
DD((PCE)Fdx,DDT,"pnp::PptPnpStartScanCmResourceList - assuming Controller\n");
Fdx->PortInfo.OriginalController = PartialResourceDescriptor->u.Port.Start;
Fdx->PortInfo.SpanOfController = PartialResourceDescriptor->u.Port.Length;
Fdx->PortInfo.Controller = (PUCHAR)(ULONG_PTR)Fdx->PortInfo.OriginalController.QuadPart;
Fdx->AddressSpace = PartialResourceDescriptor->Flags;
} else if ((Fdx->PnpInfo.OriginalEcpController.LowPart == 0) &&
(Fdx->PnpInfo.OriginalEcpController.HighPart == 0) &&
(IsNotNEC_98)) {
if ((PartialResourceDescriptor->u.Port.Start.LowPart < Fdx->PortInfo.OriginalController.LowPart) &&
(PartialResourceDescriptor->u.Port.Start.HighPart < Fdx->PortInfo.OriginalController.HighPart)) {
//
// Swapping address spaces
//
DD((PCE)Fdx,DDT,"pnp::PptPnpStartScanCmResourceList - assuming Controller - Swapping Controller/EcpController\n");
Fdx->PnpInfo.OriginalEcpController = Fdx->PortInfo.OriginalController;
Fdx->PnpInfo.SpanOfEcpController = Fdx->PortInfo.SpanOfController;
Fdx->PnpInfo.EcpController = Fdx->PortInfo.Controller;
Fdx->EcpAddressSpace = Fdx->AddressSpace;
Fdx->PortInfo.OriginalController = PartialResourceDescriptor->u.Port.Start;
Fdx->PortInfo.SpanOfController = PartialResourceDescriptor->u.Port.Length;
Fdx->PortInfo.Controller = (PUCHAR)(ULONG_PTR)Fdx->PortInfo.OriginalController.QuadPart;
Fdx->AddressSpace = PartialResourceDescriptor->Flags;
} else {
DD((PCE)Fdx,DDT,"pnp::PptPnpStartScanCmResourceList - assuming EcpController\n");
Fdx->PnpInfo.OriginalEcpController = PartialResourceDescriptor->u.Port.Start;
Fdx->PnpInfo.SpanOfEcpController = PartialResourceDescriptor->u.Port.Length;
Fdx->PnpInfo.EcpController = (PUCHAR)(ULONG_PTR)Fdx->PnpInfo.OriginalEcpController.QuadPart;
Fdx->EcpAddressSpace = PartialResourceDescriptor->Flags;
}
}
break;
case CmResourceTypeBusNumber:
Fdx->BusNumber = PartialResourceDescriptor->u.BusNumber.Start;
break;
case CmResourceTypeInterrupt:
*FoundIrq = TRUE;
Fdx->FoundInterrupt = TRUE;
Fdx->InterruptLevel = (KIRQL)PartialResourceDescriptor->u.Interrupt.Level;
Fdx->InterruptVector = PartialResourceDescriptor->u.Interrupt.Vector;
Fdx->InterruptAffinity = PartialResourceDescriptor->u.Interrupt.Affinity;
if (PartialResourceDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED) {
Fdx->InterruptMode = Latched;
} else {
Fdx->InterruptMode = LevelSensitive;
}
break;
case CmResourceTypeDma:
// we don't do anything with DMA - fall through to default case
default:
break;
} // end switch( PartialResourceDescriptor->Type )
} // end for(... ; i < PartialResourceList->Count ; ...)
} // end if( FullResourceDescriptor )
targetExit:
if( FALSE == isPci ) {
// we scanned the resources - dump what we found
DD((PCE)Fdx,DDT,"pnp::PptPnpStartScanCmResourceList - done, found:\n");
DD((PCE)Fdx,DDT," OriginalEcpController= %I64x\n", Fdx->PnpInfo.OriginalEcpController);
DD((PCE)Fdx,DDT," EcpController = %p\n", Fdx->PnpInfo.EcpController);
DD((PCE)Fdx,DDT," SpanOfEcpController = %x\n", Fdx->PnpInfo.SpanOfEcpController);
}
return status;
}
NTSTATUS
PptPnpStartValidateResources(
IN PDEVICE_OBJECT DeviceObject,
IN BOOLEAN FoundPort,
IN BOOLEAN FoundIrq,
IN BOOLEAN FoundDma
)
/*++dvdf3
Routine Description:
This function is a helper function called by PptPnpStartDevice().
This function does a sanity check of the resources saved in our
extension by PptPnpStartScanCmResourceList() to determine
if those resources appear to be valid. Checks for for Irq
and Dma resource validity are anticipated in a future version.
Arguments:
DeviceObject - The target of the START IRP
FoundPort - Did we find a Port resource?
FoundIrq - Did we find an IRQ resource?
FoundDma - Did we find a DMA resource?
Return Value:
STATUS_SUCCESS - on success,
STATUS_NO_SUCH_DEVICE - if we weren't given a port resource,
STATUS_NONE_MAPPED - if we were given a port resource but our
port address is NULL
--*/
{
PFDO_EXTENSION fdx = DeviceObject->DeviceExtension;
NTSTATUS status = STATUS_SUCCESS;
UNREFERENCED_PARAMETER( FoundIrq ); // future use
UNREFERENCED_PARAMETER( FoundDma ); // future use
if( !FoundPort ) {
status = STATUS_NO_SUCH_DEVICE;
} else {
// fdx->PortInfo.Controller = (PUCHAR)(ULONG_PTR)fdx->PortInfo.OriginalController.LowPart;
fdx->PortInfo.Controller = (PUCHAR)(ULONG_PTR)fdx->PortInfo.OriginalController.QuadPart;
if(!fdx->PortInfo.Controller) {
// ( Controller == NULL ) is invalid
PptLogError(DeviceObject->DriverObject, DeviceObject,
fdx->PortInfo.OriginalController, PhysicalZero, 0, 0, 0, 10,
STATUS_SUCCESS, PAR_REGISTERS_NOT_MAPPED);
status = STATUS_NONE_MAPPED;
}
}
return status;
}
BOOLEAN
PptPnpFilterExistsNonIrqResourceList(
IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
)
/*++dvdf8
Routine Description:
This function is a helper function called by
PptPnpFilterResourceRequirements().
This function scans the IO_RESOURCE_REQUIREMENTS_LIST to determine
whether there exists any resource alternatives that do NOT contain
an IRQ resource descriptor. The method used to filter out IRQ
resources may differ based on whether or not there exists a
resource alternative that does not contain an IRQ resource
descriptor.
Arguments:
ResourceRequirementsList - The list to scan.
Return Value:
TRUE - There exists at least one resource alternative in the list that
does not contain an IRQ resource descriptor.
FALSE - Otherwise.
--*/
{
ULONG listCount = ResourceRequirementsList->AlternativeLists;
PIO_RESOURCE_LIST curList;
ULONG i;
i=0;
curList = ResourceRequirementsList->List;
while( i < listCount ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -