Author: evb
Date: Fri Jul 16 01:14:52 2010
New Revision: 48075
URL:
http://svn.reactos.org/svn/reactos?rev=48075&view=rev
Log:
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!
Modified:
trunk/reactos/drivers/bus/pcix/arb/arb_comn.c
trunk/reactos/drivers/bus/pcix/fdo.c
trunk/reactos/drivers/bus/pcix/pci.h
trunk/reactos/drivers/bus/pcix/pci/state.c
trunk/reactos/drivers/bus/pcix/utils.c
Modified: trunk/reactos/drivers/bus/pcix/arb/arb_comn.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/pcix/arb/arb_c…
==============================================================================
--- trunk/reactos/drivers/bus/pcix/arb/arb_comn.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/pcix/arb/arb_comn.c [iso-8859-1] Fri Jul 16 01:14:52 2010
@@ -121,4 +121,83 @@
/* 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 */
Modified: trunk/reactos/drivers/bus/pcix/fdo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/pcix/fdo.c?rev…
==============================================================================
--- trunk/reactos/drivers/bus/pcix/fdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/pcix/fdo.c [iso-8859-1] Fri Jul 16 01:14:52 2010
@@ -76,9 +76,49 @@
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
Modified: trunk/reactos/drivers/bus/pcix/pci.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/pcix/pci.h?rev…
==============================================================================
--- trunk/reactos/drivers/bus/pcix/pci.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/pcix/pci.h [iso-8859-1] Fri Jul 16 01:14:52 2010
@@ -309,7 +309,6 @@
IN PIRP Irp
);
-
//
// Power Routines
//
@@ -564,6 +563,13 @@
IN PVOID Destructor
);
+PPCI_SECONDARY_EXTENSION
+NTAPI
+PciFindNextSecondaryExtension(
+ IN PSINGLE_LIST_ENTRY ListHead,
+ IN PCI_SIGNATURE ExtensionType
+);
+
//
// Configuration Routines
//
@@ -582,6 +588,28 @@
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
//
@@ -589,6 +617,13 @@
NTAPI
PciInitializeArbiters(
IN PPCI_FDO_EXTENSION FdoExtension
+);
+
+NTSTATUS
+NTAPI
+PciInitializeArbiterRanges(
+ IN PPCI_FDO_EXTENSION DeviceExtension,
+ IN PCM_RESOURCE_LIST Resources
);
//
Modified: trunk/reactos/drivers/bus/pcix/pci/state.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/pcix/pci/state…
==============================================================================
--- trunk/reactos/drivers/bus/pcix/pci/state.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/pcix/pci/state.c [iso-8859-1] Fri Jul 16 01:14:52 2010
@@ -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 @@
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 */
Modified: trunk/reactos/drivers/bus/pcix/utils.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/pcix/utils.c?r…
==============================================================================
--- trunk/reactos/drivers/bus/pcix/utils.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/pcix/utils.c [iso-8859-1] Fri Jul 16 01:14:52 2010
@@ -555,4 +555,24 @@
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 */