2010-04-01 19:07:40 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS PCI Bus Driver
|
|
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
|
|
* FILE: drivers/bus/pci/pci/state.c
|
|
|
|
* PURPOSE: Bus/Device State Support
|
|
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
|
|
|
#include <pci.h>
|
2014-01-04 12:05:02 +00:00
|
|
|
|
2010-04-01 19:07:40 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
|
2010-07-16 01:14:52 +00:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2010-04-01 19:07:40 +00:00
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
|
Implement Root Bus FDO AddDevice codes, get boot config, connect to HAL or ACPI config handlers (PciQueryForPciBusInterface, PciGetConfigHandlers), read BUS FDO hack flag, get _HPP HotPlug PCI ACPI data and initialize arbiter support.
PciGetHotPlugParameters work but no PCI HotPlug support on my machines, so cannot test ACPI data, that part stub now
Add PciFdoDispatchTable, PciFdoDispatchPnpTable, PciFdoDispatchPowerTable but all stub to PciIrpNotSupported however set correct IRP Dispatch Style for the IRPS
Arbiter support in PciInitializeARbiters done, but PciInterfaces array is NULL (stub) at moment
Add PCI_SIGNATURE, PCI_STATE, PCI_DISAPTCH_STYLE type, add PciInitializeState to begin the state support
Add structure for PCI_FDO_EXTENSION, PCI_SECONDARY_EXTENSION, PCI_INTERFACE, PCI_ARBITER_INSTANCE, PCI_DISPATCH_TABLE
PCI utility functions added: PciFindParentPciFdoExtension, PciInsertEntryAtTail, PciInsertEntryAtHead, PcipLinkSecondaryExtension, PciGetDeviceProperty, PciSendIoctl
Need sir_richard to add arbiter.h header to define ARBITER_INSTANCE for finish support
This 1000 more codes done now~
svn path=/trunk/; revision=47898
2010-06-28 17:30:35 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
PciInitializeState(IN PPCI_FDO_EXTENSION DeviceExtension)
|
|
|
|
{
|
|
|
|
/* Set the initial state */
|
|
|
|
DeviceExtension->DeviceState = PciNotStarted;
|
|
|
|
DeviceExtension->TentativeNextState = PciNotStarted;
|
|
|
|
}
|
|
|
|
|
2010-07-16 01:14:52 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-04-01 19:07:40 +00:00
|
|
|
/* EOF */
|