Last code in PciScanBus: call to PciGetfunctionLimits now implement (call PcipGetfunctionLimits if PciSkipThisFunction say no)

PcipGetfunctionLimits support PCI_HACK_CRITICAL_DEVICE and PCI Debug Device by use IPI code (PciExecuteCriticalSystemRoutine implement)
PciConfigurators table define for Device, PCI-to-PCI (PP) Bridge plus CardBus Bridge but all configurator stub now
Configurator chain: Init (Massage) -> [WRITE INIT] (PciWriteLimitsAndRestoreCurrent) -> Restore -> SaveLimit -> SaveCurrent
Support ExpectedWritebackFailure
Fix bug in PciApplyHacks (found by me testing sir_richard code)
Now pass 7000 SLOC ^_^;~ Good night!

svn path=/trunk/; revision=48118
This commit is contained in:
evb 2010-07-19 16:35:52 +00:00
parent c4c9522794
commit 0b09093a76
6 changed files with 686 additions and 5 deletions

View file

@ -16,4 +16,62 @@
/* FUNCTIONS ******************************************************************/
VOID
NTAPI
Device_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Device_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Device_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Device_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Device_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context,
IN PPCI_COMMON_HEADER PciData,
IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Device_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Device_ChangeResourceSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
/* EOF */

View file

@ -14,6 +14,37 @@
/* GLOBALS ********************************************************************/
PCI_CONFIGURATOR PciConfigurators[] =
{
{
Device_MassageHeaderForLimitsDetermination,
Device_RestoreCurrent,
Device_SaveLimits,
Device_SaveCurrentSettings,
Device_ChangeResourceSettings,
Device_GetAdditionalResourceDescriptors,
Device_ResetDevice
},
{
PPBridge_MassageHeaderForLimitsDetermination,
PPBridge_RestoreCurrent,
PPBridge_SaveLimits,
PPBridge_SaveCurrentSettings,
PPBridge_ChangeResourceSettings,
PPBridge_GetAdditionalResourceDescriptors,
PPBridge_ResetDevice
},
{
Cardbus_MassageHeaderForLimitsDetermination,
Cardbus_RestoreCurrent,
Cardbus_SaveLimits,
Cardbus_SaveCurrentSettings,
Cardbus_ChangeResourceSettings,
Cardbus_GetAdditionalResourceDescriptors,
Cardbus_ResetDevice
}
};
/* FUNCTIONS ******************************************************************/
/*
@ -186,9 +217,6 @@ PciApplyHacks(IN PPCI_FDO_EXTENSION DeviceExtension,
USHORT Command;
UCHAR RegValue;
/* There should always be a PDO extension passed in */
ASSERT(PdoExtension);
/* Check what kind of hack operation this is */
switch (OperationType)
{
@ -229,6 +257,9 @@ PciApplyHacks(IN PPCI_FDO_EXTENSION DeviceExtension,
*/
case PCI_HACK_FIXUP_AFTER_CONFIGURATION:
/* There should always be a PDO extension passed in */
ASSERT(PdoExtension);
/*
* On the OPTi Viper-M IDE controller, Linux doesn't support IDE-DMA
* and FreeBSD bug reports indicate that the system crashes when the
@ -346,6 +377,9 @@ PciApplyHacks(IN PPCI_FDO_EXTENSION DeviceExtension,
*/
case PCI_HACK_FIXUP_BEFORE_UPDATE:
/* There should always be a PDO extension passed in */
ASSERT(PdoExtension);
/* Is this an IBM 20H2999 PCI Docking Bridge, used on Thinkpads? */
if ((PdoExtension->VendorId == 0x1014) &&
(PdoExtension->DeviceId == 0x95))
@ -438,7 +472,6 @@ PciApplyHacks(IN PPCI_FDO_EXTENSION DeviceExtension,
}
}
BOOLEAN
NTAPI
PcipIsSameDevice(IN PPCI_PDO_EXTENSION DeviceExtension,
@ -667,6 +700,223 @@ PciGetEnhancedCapabilities(IN PPCI_PDO_EXTENSION PdoExtension,
}
}
VOID
NTAPI
PciWriteLimitsAndRestoreCurrent(IN PVOID Reserved,
IN PPCI_CONFIGURATOR_CONTEXT Context)
{
PPCI_COMMON_HEADER PciData, Current;
PPCI_PDO_EXTENSION PdoExtension;
/* Grab all parameters from the context */
PdoExtension = Context->PdoExtension;
Current = Context->Current;
PciData = Context->PciData;
/* Write the limit discovery header */
PciWriteDeviceConfig(PdoExtension, PciData, 0, PCI_COMMON_HDR_LENGTH);
/* Now read what the device indicated the limits are */
PciReadDeviceConfig(PdoExtension, PciData, 0, PCI_COMMON_HDR_LENGTH);
/* Then write back the original configuration header */
PciWriteDeviceConfig(PdoExtension, Current, 0, PCI_COMMON_HDR_LENGTH);
/* Copy back the original command that was saved in the context */
Current->Command = Context->Command;
if (Context->Command)
{
/* Program it back into the device */
PciWriteDeviceConfig(PdoExtension,
&Context->Command,
FIELD_OFFSET(PCI_COMMON_HEADER, Command),
sizeof(USHORT));
}
/* Copy back the original status that was saved as well */
Current->Status = Context->Status;
/* Call the configurator to restore any other data that might've changed */
Context->Configurator->RestoreCurrent(Context);
}
NTSTATUS
NTAPI
PcipGetFunctionLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
PPCI_CONFIGURATOR Configurator;
PPCI_COMMON_HEADER PciData, Current;
PPCI_PDO_EXTENSION PdoExtension;
PCI_IPI_CONTEXT IpiContext;
PIO_RESOURCE_DESCRIPTOR IoDescriptor;
ULONG Offset;
PAGED_CODE();
/* Grab all parameters from the context */
PdoExtension = Context->PdoExtension;
Current = Context->Current;
PciData = Context->PciData;
/* Save the current PCI Command and Status word */
Context->Status = Current->Status;
Context->Command = Current->Command;
/* Now that they're saved, clear the status, and disable all decodes */
Current->Status = 0;
Current->Command &= ~(PCI_ENABLE_IO_SPACE |
PCI_ENABLE_MEMORY_SPACE |
PCI_ENABLE_BUS_MASTER);
/* Make a copy of the current PCI configuration header (with decodes off) */
RtlCopyMemory(PciData, Current, PCI_COMMON_HDR_LENGTH);
/* Locate the correct resource configurator for this type of device */
Configurator = &PciConfigurators[PdoExtension->HeaderType];
Context->Configurator = Configurator;
/* Initialize it, which will typically setup the BARs for limit discovery */
Configurator->Initialize(Context);
/* Check for critical devices and PCI Debugging devices */
if ((PdoExtension->HackFlags & PCI_HACK_CRITICAL_DEVICE) ||
(PdoExtension->OnDebugPath))
{
/* Specifically check for a PCI Debugging device */
if (PdoExtension->OnDebugPath)
{
/* Was it enabled for bus mastering? */
if (Context->Command & PCI_ENABLE_BUS_MASTER)
{
/* This decode needs to be re-enabled so debugging can work */
PciData->Command |= PCI_ENABLE_BUS_MASTER;
Current->Command |= PCI_ENABLE_BUS_MASTER;
}
/* Disable the debugger while the discovery is happening */
KdDisableDebugger();
}
/* For these devices, an IPI must be sent to force high-IRQL discovery */
IpiContext.Barrier = 1;
IpiContext.RunCount = 1;
IpiContext.PdoExtension = PdoExtension;
IpiContext.Function = PciWriteLimitsAndRestoreCurrent;
IpiContext.Context = Context;
KeIpiGenericCall(PciExecuteCriticalSystemRoutine, (ULONG_PTR)&IpiContext);
/* Re-enable the debugger if this was a PCI Debugging Device */
if (PdoExtension->OnDebugPath) KdEnableDebugger();
}
else
{
/* Otherwise, it's safe to do this in-line at low IRQL */
PciWriteLimitsAndRestoreCurrent(PdoExtension, Context);
}
/*
* Check if it's valid to compare the headers to see if limit discovery mode
* has properly exited (the expected case is that the PCI header would now
* be equal to what it was before). In some cases, it is known that this will
* fail, because during PciApplyHacks (among other places), software hacks
* had to be applied to the header, which the hardware-side will not see, and
* thus the headers would appear "different".
*/
if (!PdoExtension->ExpectedWritebackFailure)
{
/* Read the current PCI header now, after discovery has completed */
PciReadDeviceConfig(PdoExtension, PciData + 1, 0, PCI_COMMON_HDR_LENGTH);
/* Check if the current header at entry, is equal to the header now */
Offset = RtlCompareMemory(PciData + 1, Current, PCI_COMMON_HDR_LENGTH);
if (Offset != PCI_COMMON_HDR_LENGTH)
{
/* It's not, which means configuration somehow changed, dump this */
DPRINT1("PCI - CFG space write verify failed at offset 0x%x\n", Offset);
PciDebugDumpCommonConfig(PciData + 1);
DPRINT1("----------\n");
PciDebugDumpCommonConfig(Current);
}
}
/* This PDO should not already have resources, since this is only done once */
ASSERT(PdoExtension->Resources == NULL);
/* Allocate the structure that will hold the discovered resources and limits */
PdoExtension->Resources = ExAllocatePoolWithTag(NonPagedPool,
sizeof(PCI_FUNCTION_RESOURCES),
'BicP');
if (!PdoExtension->Resources) return STATUS_INSUFFICIENT_RESOURCES;
/* Clear it out for now */
RtlZeroMemory(PdoExtension->Resources, sizeof(PCI_FUNCTION_RESOURCES));
/* Now call the configurator, which will first store the limits... */
Configurator->SaveLimits(Context);
/* ...and then store the current resources being used */
Configurator->SaveCurrentSettings(Context);
/* Loop all the limit descriptors backwards */
IoDescriptor = &PdoExtension->Resources->Limit[PCI_TYPE0_ADDRESSES + 1];
while (TRUE)
{
/* Keep going until a non-null descriptor is found */
IoDescriptor--;
if (IoDescriptor->Type != CmResourceTypeNull) break;
/* This is a null descriptor, is it the last one? */
if (IoDescriptor == &PdoExtension->Resources->Limit[PCI_TYPE0_ADDRESSES + 1])
{
/* This means the descriptor is NULL, which means discovery failed */
DPRINT1("PCI Resources fail!\n");
/* No resources will be assigned for the device */
ExFreePoolWithTag(PdoExtension->Resources, 0);
PdoExtension->Resources = NULL;
break;
}
}
/* Return success here, even if the device has no assigned resources */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
PciGetFunctionLimits(IN PPCI_PDO_EXTENSION PdoExtension,
IN PPCI_COMMON_HEADER Current,
IN ULONGLONG HackFlags)
{
NTSTATUS Status;
PPCI_COMMON_HEADER PciData;
PCI_CONFIGURATOR_CONTEXT Context;
PAGED_CODE();
/* Do the hackflags indicate this device should be skipped? */
if (PciSkipThisFunction(Current,
PdoExtension->Slot,
PCI_SKIP_RESOURCE_ENUMERATION,
HackFlags))
{
/* Do not process its resources */
return STATUS_SUCCESS;
}
/* Allocate a buffer to hold two PCI configuration headers */
PciData = ExAllocatePoolWithTag(0, 2 * PCI_COMMON_HDR_LENGTH, 'BicP');
if (!PciData) return STATUS_INSUFFICIENT_RESOURCES;
/* Set up the context for the resource enumeration, and do it */
Context.Current = Current;
Context.PciData = PciData;
Context.PdoExtension = PdoExtension;
Status = PcipGetFunctionLimits(&Context);
/* Enumeration is completed, free the PCI headers and return the status */
ExFreePoolWithTag(PciData, 0);
return Status;
}
NTSTATUS
NTAPI
PciScanBus(IN PPCI_FDO_EXTENSION DeviceExtension)
@ -937,6 +1187,9 @@ PciScanBus(IN PPCI_FDO_EXTENSION DeviceExtension)
/* Get power, AGP, and other capability data */
PciGetEnhancedCapabilities(NewExtension, PciData);
/* Now configure the BARs */
Status = PciGetFunctionLimits(NewExtension, PciData, HackFlags);
/* Power up the device */
PciSetPowerManagedDevicePowerState(NewExtension, PowerDeviceD0, FALSE);

View file

@ -29,6 +29,64 @@ PCI_INTERFACE PciCardbusPrivateInterface =
/* FUNCTIONS ******************************************************************/
VOID
NTAPI
Cardbus_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Cardbus_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Cardbus_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Cardbus_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Cardbus_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context,
IN PPCI_COMMON_HEADER PciData,
IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Cardbus_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
Cardbus_ChangeResourceSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
NTSTATUS
NTAPI
pcicbintrf_Initializer(IN PVOID Instance)

View file

@ -398,6 +398,89 @@ typedef struct _PCI_VERIFIER_DATA
PCHAR DebuggerMessageText;
} PCI_VERIFIER_DATA, *PPCI_VERIFIER_DATA;
//
// PCI Configuration Callbacks
//
struct _PCI_CONFIGURATOR_CONTEXT;
typedef VOID (NTAPI *PCI_CONFIGURATOR_INITIALIZE)(
IN struct _PCI_CONFIGURATOR_CONTEXT* Context
);
typedef VOID (NTAPI *PCI_CONFIGURATOR_RESTORE_CURRENT)(
IN struct _PCI_CONFIGURATOR_CONTEXT* Context
);
typedef VOID (NTAPI *PCI_CONFIGURATOR_SAVE_LIMITS)(
IN struct _PCI_CONFIGURATOR_CONTEXT* Context
);
typedef VOID (NTAPI *PCI_CONFIGURATOR_SAVE_CURRENT_SETTINGS)(
IN struct _PCI_CONFIGURATOR_CONTEXT* Context
);
typedef VOID (NTAPI *PCI_CONFIGURATOR_CHANGE_RESOURCE_SETTINGS)(
IN struct _PCI_CONFIGURATOR_CONTEXT* Context
);
typedef VOID (NTAPI *PCI_CONFIGURATOR_GET_ADDITIONAL_RESOURCE_DESCRIPTORS)(
IN struct _PCI_CONFIGURATOR_CONTEXT* Context,
IN PPCI_COMMON_HEADER PciData,
IN PIO_RESOURCE_DESCRIPTOR IoDescriptor
);
typedef VOID (NTAPI *PCI_CONFIGURATOR_RESET_DEVICE)(
IN struct _PCI_CONFIGURATOR_CONTEXT* Context
);
//
// PCI Configurator
//
typedef struct _PCI_CONFIGURATOR
{
PCI_CONFIGURATOR_INITIALIZE Initialize;
PCI_CONFIGURATOR_RESTORE_CURRENT RestoreCurrent;
PCI_CONFIGURATOR_SAVE_LIMITS SaveLimits;
PCI_CONFIGURATOR_SAVE_CURRENT_SETTINGS SaveCurrentSettings;
PCI_CONFIGURATOR_CHANGE_RESOURCE_SETTINGS ChangeResourceSettings;
PCI_CONFIGURATOR_GET_ADDITIONAL_RESOURCE_DESCRIPTORS GetAdditionalResourceDescriptors;
PCI_CONFIGURATOR_RESET_DEVICE ResetDevice;
} PCI_CONFIGURATOR, *PPCI_CONFIGURATOR;
//
// PCI Configurator Context
//
typedef struct _PCI_CONFIGURATOR_CONTEXT
{
PPCI_PDO_EXTENSION PdoExtension;
PPCI_COMMON_HEADER Current;
PPCI_COMMON_HEADER PciData;
PPCI_CONFIGURATOR Configurator;
USHORT SecondaryStatus;
USHORT Status;
USHORT Command;
} PCI_CONFIGURATOR_CONTEXT, *PPCI_CONFIGURATOR_CONTEXT;
//
// PCI IPI Function
//
typedef VOID (NTAPI *PCI_IPI_FUNCTION)(
IN PVOID Reserved,
IN PPCI_CONFIGURATOR_CONTEXT Context
);
//
// PCI IPI Context
//
typedef struct _PCI_IPI_CONTEXT
{
LONG RunCount;
ULONG Barrier;
PPCI_PDO_EXTENSION PdoExtension;
PCI_IPI_FUNCTION Function;
PVOID Context;
} PCI_IPI_CONTEXT, *PPCI_IPI_CONTEXT;
//
// IRP Dispatch Routines
//
@ -981,6 +1064,12 @@ PciCanDisableDecodes(
IN BOOLEAN ForPowerDown
);
ULONG_PTR
NTAPI
PciExecuteCriticalSystemRoutine(
IN ULONG_PTR IpiContext
);
BOOLEAN
NTAPI
PciIsSlotPresentInParentMethod(
@ -1069,7 +1158,6 @@ PciCommitStateTransition(
IN PCI_STATE NewState
);
//
// Arbiter Support
//
@ -1348,6 +1436,147 @@ PciGetDeviceDescriptionMessage(
IN UCHAR SubClass
);
//
// CardBUS Support
//
VOID
NTAPI
Cardbus_MassageHeaderForLimitsDetermination(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
Cardbus_SaveCurrentSettings(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
Cardbus_SaveLimits(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
Cardbus_RestoreCurrent(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
Cardbus_GetAdditionalResourceDescriptors(
IN PPCI_CONFIGURATOR_CONTEXT Context,
IN PPCI_COMMON_HEADER PciData,
IN PIO_RESOURCE_DESCRIPTOR IoDescriptor
);
VOID
NTAPI
Cardbus_ResetDevice(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
Cardbus_ChangeResourceSettings(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
//
// PCI Device Support
//
VOID
NTAPI
Device_MassageHeaderForLimitsDetermination(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
Device_SaveCurrentSettings(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
Device_SaveLimits(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
Device_RestoreCurrent(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
Device_GetAdditionalResourceDescriptors(
IN PPCI_CONFIGURATOR_CONTEXT Context,
IN PPCI_COMMON_HEADER PciData,
IN PIO_RESOURCE_DESCRIPTOR IoDescriptor
);
VOID
NTAPI
Device_ResetDevice(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
Device_ChangeResourceSettings(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
//
// PCI-to-PCI Bridge Device Support
//
VOID
NTAPI
PPBridge_MassageHeaderForLimitsDetermination(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
PPBridge_SaveCurrentSettings(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
PPBridge_SaveLimits(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
PPBridge_RestoreCurrent(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
PPBridge_GetAdditionalResourceDescriptors(
IN PPCI_CONFIGURATOR_CONTEXT Context,
IN PPCI_COMMON_HEADER PciData,
IN PIO_RESOURCE_DESCRIPTOR IoDescriptor
);
VOID
NTAPI
PPBridge_ResetDevice(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
VOID
NTAPI
PPBridge_ChangeResourceSettings(
IN PPCI_CONFIGURATOR_CONTEXT Context
);
//
// External Resources
//

View file

@ -16,4 +16,62 @@
/* FUNCTIONS ******************************************************************/
VOID
NTAPI
PPBridge_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
PPBridge_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
PPBridge_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
PPBridge_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
PPBridge_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context,
IN PPCI_COMMON_HEADER PciData,
IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
PPBridge_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
VOID
NTAPI
PPBridge_ChangeResourceSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
UNIMPLEMENTED;
while (TRUE);
}
/* EOF */

View file

@ -1041,6 +1041,31 @@ PciCanDisableDecodes(IN PPCI_PDO_EXTENSION DeviceExtension,
return !(HackFlags & PCI_HACK_NO_PM_CAPS);
}
ULONG_PTR
NTAPI
PciExecuteCriticalSystemRoutine(IN ULONG_PTR IpiContext)
{
PPCI_IPI_CONTEXT Context = (PPCI_IPI_CONTEXT)IpiContext;
/* Check if the IPI is already running */
if (!InterlockedDecrement(&Context->RunCount))
{
/* Nope, this is the first instance, so execute the IPI function */
Context->Function(Context->PdoExtension, Context->Context);
/* Notify anyone that was spinning that they can stop now */
Context->Barrier = 0;
}
else
{
/* Spin until it has finished running */
while (Context->Barrier);
}
/* Done */
return 0;
}
BOOLEAN
NTAPI
PciIsSlotPresentInParentMethod(IN PPCI_PDO_EXTENSION PdoExtension,