IRP_MN_START_DEVICE implement for ROOT FDO (PciFdoStartDevice)

PciInitializeArbiterRanges implement to scan arbiter   not yet construct since Arb library missing
Add PCI state machine (PciBeginStateTransition, PciCancelStateTransition, PciCommitStateTransition) andtransition array (PnpStateTransitionArray) to check if valid
Now IRP_MN_QUERY_DEVICE_RELATIONS sent to ROOT FDO means time to enumerate bus!

svn path=/trunk/; revision=48075
This commit is contained in:
evb 2010-07-16 01:14:52 +00:00
parent add164dcfa
commit 2261af5265
5 changed files with 344 additions and 4 deletions

View file

@ -121,4 +121,83 @@ PciInitializeArbiters(IN PPCI_FDO_EXTENSION FdoExtension)
/* Return to caller */
return Status;
}
NTSTATUS
NTAPI
PciInitializeArbiterRanges(IN PPCI_FDO_EXTENSION DeviceExtension,
IN PCM_RESOURCE_LIST Resources)
{
//PPCI_PDO_EXTENSION PdoExtension;
CM_RESOURCE_TYPE DesiredType;
PVOID Instance;
PCI_SIGNATURE ArbiterType;
/* Arbiters should not already be initialized */
if (DeviceExtension->ArbitersInitialized)
{
/* Duplicated start request, fail initialization */
DPRINT1("PCI Warning hot start FDOx %08x, resource ranges not checked.\n", DeviceExtension);
return STATUS_INVALID_DEVICE_REQUEST;
}
/* Check for non-root FDO */
if (!PCI_IS_ROOT_FDO(DeviceExtension))
{
/* Grab the PDO */
#if 0 // when pdo support
PdoExtension = (PPCI_PDO_EXTENSION)DeviceExtension->PhysicalDeviceObject->DeviceExtension;
ASSERT(PdoExtension->ExtensionType == PciPdoExtensionType);
#endif
/* Multiple FDOs are not yet supported */
UNIMPLEMENTED;
while (TRUE);
return STATUS_SUCCESS;
}
/* Loop all arbiters */
for (ArbiterType = PciArb_Io; ArbiterType <= PciArb_Memory; ArbiterType++)
{
/* Pick correct resource type for each arbiter */
if (ArbiterType == PciArb_Io)
{
/* I/O Port */
DesiredType = CmResourceTypePort;
}
else if (ArbiterType == PciArb_Memory)
{
/* Device RAM */
DesiredType = CmResourceTypeMemory;
}
else
{
/* Ignore anything else */
continue;
}
/* Find an arbiter of this type */
Instance = PciFindNextSecondaryExtension(&DeviceExtension->SecondaryExtension,
ArbiterType);
if (Instance)
{
/*
* Now we should initialize it, not yet implemented because Arb
* library isn't yet implemented, not even the headers.
*/
UNIMPLEMENTED;
//while (TRUE);
}
else
{
/* The arbiter was not found, this is an error! */
DPRINT1("PCI - FDO ext 0x%08x %s arbiter (REQUIRED) is missing.\n",
DeviceExtension,
PciArbiterNames[ArbiterType - PciArb_Io]);
}
}
/* Arbiters are now initialized */
DeviceExtension->ArbitersInitialized = TRUE;
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -76,9 +76,49 @@ PciFdoIrpStartDevice(IN PIRP Irp,
IN PIO_STACK_LOCATION IoStackLocation,
IN PPCI_FDO_EXTENSION DeviceExtension)
{
UNIMPLEMENTED;
while (TRUE);
return STATUS_NOT_SUPPORTED;
NTSTATUS Status;
PCM_RESOURCE_LIST Resources;
PAGED_CODE();
/* The device stack must be starting the FDO in a success path */
if (!NT_SUCCESS(Irp->IoStatus.Status)) return STATUS_NOT_SUPPORTED;
/* Attempt to switch the state machine to the started state */
Status = PciBeginStateTransition(DeviceExtension, PciStarted);
if (!NT_SUCCESS(Status)) return Status;
/* Check for any boot-provided resources */
Resources = IoStackLocation->Parameters.StartDevice.AllocatedResources;
DPRINT1("Resources: %p\n", Resources);
if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension)))
{
/* These resources would only be for non-root FDOs, unhandled for now */
ASSERT(Resources->Count == 1);
UNIMPLEMENTED;
while (TRUE);
}
/* Initialize the arbiter for this FDO */
Status = PciInitializeArbiterRanges(DeviceExtension, Resources);
if (!NT_SUCCESS(Status))
{
/* Cancel the transition if this failed */
PciCancelStateTransition(DeviceExtension, PciStarted);
return Status;
}
/* Again, check for boot-provided resources for non-root FDO */
if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension)))
{
/* Unhandled for now */
ASSERT(Resources->Count == 1);
UNIMPLEMENTED;
while (TRUE);
}
/* Commit the transition to the started state */
PciCommitStateTransition(DeviceExtension, PciStarted);
return STATUS_SUCCESS;
}
NTSTATUS

View file

@ -309,7 +309,6 @@ PciCallDownIrpStack(
IN PIRP Irp
);
//
// Power Routines
//
@ -564,6 +563,13 @@ PcipLinkSecondaryExtension(
IN PVOID Destructor
);
PPCI_SECONDARY_EXTENSION
NTAPI
PciFindNextSecondaryExtension(
IN PSINGLE_LIST_ENTRY ListHead,
IN PCI_SIGNATURE ExtensionType
);
//
// Configuration Routines
//
@ -582,6 +588,28 @@ PciInitializeState(
IN PPCI_FDO_EXTENSION DeviceExtension
);
NTSTATUS
NTAPI
PciBeginStateTransition(
IN PPCI_FDO_EXTENSION DeviceExtension,
IN PCI_STATE NewState
);
NTSTATUS
NTAPI
PciCancelStateTransition(
IN PPCI_FDO_EXTENSION DeviceExtension,
IN PCI_STATE NewState
);
VOID
NTAPI
PciCommitStateTransition(
IN PPCI_FDO_EXTENSION DeviceExtension,
IN PCI_STATE NewState
);
//
// Arbiter Support
//
@ -591,6 +619,13 @@ PciInitializeArbiters(
IN PPCI_FDO_EXTENSION FdoExtension
);
NTSTATUS
NTAPI
PciInitializeArbiterRanges(
IN PPCI_FDO_EXTENSION DeviceExtension,
IN PCM_RESOURCE_LIST Resources
);
//
// Debug Helpers
//

View file

@ -14,6 +14,72 @@
/* GLOBALS ********************************************************************/
PCHAR PciTransitionText[PciMaxObjectState + 1] =
{
"PciNotStarted",
"PciStarted",
"PciDeleted",
"PciStopped",
"PciSurpriseRemoved",
"PciSynchronizedOperation",
"PciMaxObjectState"
};
NTSTATUS PnpStateCancelArray[PciMaxObjectState] =
{
STATUS_INVALID_DEVICE_REQUEST,
STATUS_FAIL_CHECK,
STATUS_INVALID_DEVICE_STATE,
STATUS_INVALID_DEVICE_STATE,
STATUS_FAIL_CHECK,
STATUS_FAIL_CHECK
};
NTSTATUS PnpStateTransitionArray[PciMaxObjectState * PciMaxObjectState] =
{
STATUS_SUCCESS, // Not Started -> Not Started
STATUS_SUCCESS, // Started -> Not Started
STATUS_FAIL_CHECK, // Deleted -> Not Started
STATUS_SUCCESS, // Stopped -> Not Started
STATUS_FAIL_CHECK, // Surprise Removed -> Not Started
STATUS_FAIL_CHECK, // Synchronized Operation -> Not Started
STATUS_SUCCESS, // Not Started -> Started
STATUS_FAIL_CHECK, // Started -> Started
STATUS_FAIL_CHECK, // Deleted -> Started
STATUS_SUCCESS, // Stopped -> Started
STATUS_FAIL_CHECK, // Surprise Removed -> Started
STATUS_FAIL_CHECK, // Synchronized Operation -> Started
STATUS_SUCCESS, // Not Started -> Deleted
STATUS_SUCCESS, // Started -> Deleted
STATUS_FAIL_CHECK, // Deleted -> Deleted
STATUS_FAIL_CHECK, // Stopped -> Deleted
STATUS_SUCCESS, // Surprise Removed -> Deleted
STATUS_FAIL_CHECK, // Synchronized Operation -> Deleted
STATUS_INVALID_DEVICE_REQUEST, // Not Started -> Stopped
STATUS_SUCCESS, // Started -> Stopped
STATUS_FAIL_CHECK, // Deleted -> Stopped
STATUS_FAIL_CHECK, // Stopped -> Stopped
STATUS_FAIL_CHECK, // Surprise Removed -> Stopped
STATUS_FAIL_CHECK, // Synchronized Operation -> Stopped
STATUS_SUCCESS, // Not Started -> Surprise Removed
STATUS_SUCCESS, // Started -> Surprise Removed
STATUS_FAIL_CHECK, // Deleted -> Surprise Removed
STATUS_SUCCESS, // Stopped -> Surprise Removed
STATUS_FAIL_CHECK, // Surprise Removed -> Surprise Removed
STATUS_FAIL_CHECK, // Synchronized Operation -> Surprise Removed
STATUS_SUCCESS, // Not Started -> Synchronized Operation
STATUS_SUCCESS, // Started -> Synchronized Operation
STATUS_INVALID_DEVICE_STATE, // Deleted -> Synchronized Operation
STATUS_SUCCESS, // Stopped -> Synchronized Operation
STATUS_INVALID_DEVICE_STATE, // Surprise Removed -> Synchronized Operation
STATUS_FAIL_CHECK // Synchronized Operation -> Synchronized Operation
};
/* FUNCTIONS ******************************************************************/
VOID
@ -25,4 +91,104 @@ PciInitializeState(IN PPCI_FDO_EXTENSION DeviceExtension)
DeviceExtension->TentativeNextState = PciNotStarted;
}
NTSTATUS
NTAPI
PciBeginStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension,
IN PCI_STATE NewState)
{
PCI_STATE CurrentState;
NTSTATUS Status;
DPRINT1("PCI Request to begin transition of Extension %p to %s ->",
DeviceExtension,
PciTransitionText[NewState]);
/* Assert the device isn't already in a pending transition */
ASSERT(DeviceExtension->TentativeNextState == DeviceExtension->DeviceState);
/* Assert this is a valid state */
CurrentState = DeviceExtension->DeviceState;
ASSERT(CurrentState < PciMaxObjectState);
ASSERT(NewState < PciMaxObjectState);
/* Lookup if this state transition is valid */
Status = PnpStateTransitionArray[CurrentState + 6 * NewState];
if (Status == STATUS_FAIL_CHECK)
{
/* Invalid transition (logical fault) */
DPRINT1("ERROR\nPCI: Error trying to enter state \"%s\" "
"from state \"%s\"\n",
PciTransitionText[NewState],
PciTransitionText[CurrentState]);
DbgBreakPoint();
}
else if (Status == STATUS_INVALID_DEVICE_REQUEST)
{
/* Invalid transition (illegal request) */
DPRINT1("ERROR\nPCI: Illegal request to try to enter state \"%s\" "
"from state \"%s\", rejecting",
PciTransitionText[NewState],
PciTransitionText[CurrentState]);
}
/* New state must be different from current, unless request is at fault */
ASSERT((NewState != DeviceExtension->DeviceState) || (!NT_SUCCESS(Status)));
/* Enter the new state if successful, and return state status */
if (NT_SUCCESS(Status)) DeviceExtension->TentativeNextState = NewState;
DbgPrint("%x\n", Status);
return Status;
}
NTSTATUS
NTAPI
PciCancelStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension,
IN PCI_STATE StateNotEntered)
{
NTSTATUS Status;
DPRINT1("PCI Request to cancel transition of Extension %p to %s ->",
DeviceExtension,
PciTransitionText[StateNotEntered]);
/* The next state can't be the state the device is already in */
if (DeviceExtension->TentativeNextState == DeviceExtension->DeviceState)
{
/* It's too late since the state was already committed */
ASSERT(StateNotEntered < PciMaxObjectState);
ASSERT(PnpStateCancelArray[StateNotEntered] != STATUS_FAIL_CHECK);
/* Return failure */
Status = STATUS_INVALID_DEVICE_STATE;
DbgPrint("%x\n", Status);
}
else
{
/* The device hasn't yet entered the state, so it's still possible to cancel */
ASSERT(DeviceExtension->TentativeNextState == StateNotEntered);
DeviceExtension->TentativeNextState = DeviceExtension->DeviceState;
/* Return success */
Status = STATUS_SUCCESS;
DbgPrint("%x\n", Status);
}
/* Return the cancel state */
return Status;
}
VOID
NTAPI
PciCommitStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension,
IN PCI_STATE NewState)
{
DPRINT1("PCI Commit transition of Extension %p to %s\n",
DeviceExtension, PciTransitionText[NewState]);
/* Make sure this is a valid commit */
ASSERT(NewState != PciSynchronizedOperation);
ASSERT(DeviceExtension->TentativeNextState == NewState);
/* Enter the new state */
DeviceExtension->DeviceState = NewState;
}
/* EOF */

View file

@ -555,4 +555,24 @@ PciSendIoctl(IN PDEVICE_OBJECT DeviceObject,
return Status;
}
PPCI_SECONDARY_EXTENSION
NTAPI
PciFindNextSecondaryExtension(IN PSINGLE_LIST_ENTRY ListHead,
IN PCI_SIGNATURE ExtensionType)
{
PSINGLE_LIST_ENTRY NextEntry;
PPCI_SECONDARY_EXTENSION Extension;
/* Scan the list */
for (NextEntry = ListHead; NextEntry; NextEntry = NextEntry->Next)
{
/* Grab each extension and check if it's the one requested */
Extension = CONTAINING_RECORD(NextEntry, PCI_SECONDARY_EXTENSION, List);
if (Extension->ExtensionType == ExtensionType) return Extension;
}
/* Nothing was found */
return NULL;
}
/* EOF */