2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/bus/pci/pci/state.c
5 * PURPOSE: Bus/Device State Support
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
16 /* GLOBALS ********************************************************************/
18 PCHAR PciTransitionText
[PciMaxObjectState
+ 1] =
25 "PciSynchronizedOperation",
29 NTSTATUS PnpStateCancelArray
[PciMaxObjectState
] =
31 STATUS_INVALID_DEVICE_REQUEST
,
33 STATUS_INVALID_DEVICE_STATE
,
34 STATUS_INVALID_DEVICE_STATE
,
39 NTSTATUS PnpStateTransitionArray
[PciMaxObjectState
* PciMaxObjectState
] =
41 STATUS_SUCCESS
, // Not Started -> Not Started
42 STATUS_SUCCESS
, // Started -> Not Started
43 STATUS_FAIL_CHECK
, // Deleted -> Not Started
44 STATUS_SUCCESS
, // Stopped -> Not Started
45 STATUS_FAIL_CHECK
, // Surprise Removed -> Not Started
46 STATUS_FAIL_CHECK
, // Synchronized Operation -> Not Started
48 STATUS_SUCCESS
, // Not Started -> Started
49 STATUS_FAIL_CHECK
, // Started -> Started
50 STATUS_FAIL_CHECK
, // Deleted -> Started
51 STATUS_SUCCESS
, // Stopped -> Started
52 STATUS_FAIL_CHECK
, // Surprise Removed -> Started
53 STATUS_FAIL_CHECK
, // Synchronized Operation -> Started
55 STATUS_SUCCESS
, // Not Started -> Deleted
56 STATUS_SUCCESS
, // Started -> Deleted
57 STATUS_FAIL_CHECK
, // Deleted -> Deleted
58 STATUS_FAIL_CHECK
, // Stopped -> Deleted
59 STATUS_SUCCESS
, // Surprise Removed -> Deleted
60 STATUS_FAIL_CHECK
, // Synchronized Operation -> Deleted
62 STATUS_INVALID_DEVICE_REQUEST
, // Not Started -> Stopped
63 STATUS_SUCCESS
, // Started -> Stopped
64 STATUS_FAIL_CHECK
, // Deleted -> Stopped
65 STATUS_FAIL_CHECK
, // Stopped -> Stopped
66 STATUS_FAIL_CHECK
, // Surprise Removed -> Stopped
67 STATUS_FAIL_CHECK
, // Synchronized Operation -> Stopped
69 STATUS_SUCCESS
, // Not Started -> Surprise Removed
70 STATUS_SUCCESS
, // Started -> Surprise Removed
71 STATUS_FAIL_CHECK
, // Deleted -> Surprise Removed
72 STATUS_SUCCESS
, // Stopped -> Surprise Removed
73 STATUS_FAIL_CHECK
, // Surprise Removed -> Surprise Removed
74 STATUS_FAIL_CHECK
, // Synchronized Operation -> Surprise Removed
76 STATUS_SUCCESS
, // Not Started -> Synchronized Operation
77 STATUS_SUCCESS
, // Started -> Synchronized Operation
78 STATUS_INVALID_DEVICE_STATE
, // Deleted -> Synchronized Operation
79 STATUS_SUCCESS
, // Stopped -> Synchronized Operation
80 STATUS_INVALID_DEVICE_STATE
, // Surprise Removed -> Synchronized Operation
81 STATUS_FAIL_CHECK
// Synchronized Operation -> Synchronized Operation
84 /* FUNCTIONS ******************************************************************/
88 PciInitializeState(IN PPCI_FDO_EXTENSION DeviceExtension
)
90 /* Set the initial state */
91 DeviceExtension
->DeviceState
= PciNotStarted
;
92 DeviceExtension
->TentativeNextState
= PciNotStarted
;
97 PciBeginStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension
,
98 IN PCI_STATE NewState
)
100 PCI_STATE CurrentState
;
102 DPRINT1("PCI Request to begin transition of Extension %p to %s ->",
104 PciTransitionText
[NewState
]);
106 /* Assert the device isn't already in a pending transition */
107 ASSERT(DeviceExtension
->TentativeNextState
== DeviceExtension
->DeviceState
);
109 /* Assert this is a valid state */
110 CurrentState
= DeviceExtension
->DeviceState
;
111 ASSERT(CurrentState
< PciMaxObjectState
);
112 ASSERT(NewState
< PciMaxObjectState
);
114 /* Lookup if this state transition is valid */
115 Status
= PnpStateTransitionArray
[CurrentState
+ 6 * NewState
];
116 if (Status
== STATUS_FAIL_CHECK
)
118 /* Invalid transition (logical fault) */
119 DPRINT1("ERROR\nPCI: Error trying to enter state \"%s\" "
120 "from state \"%s\"\n",
121 PciTransitionText
[NewState
],
122 PciTransitionText
[CurrentState
]);
125 else if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
127 /* Invalid transition (illegal request) */
128 DPRINT1("ERROR\nPCI: Illegal request to try to enter state \"%s\" "
129 "from state \"%s\", rejecting",
130 PciTransitionText
[NewState
],
131 PciTransitionText
[CurrentState
]);
134 /* New state must be different from current, unless request is at fault */
135 ASSERT((NewState
!= DeviceExtension
->DeviceState
) || (!NT_SUCCESS(Status
)));
137 /* Enter the new state if successful, and return state status */
138 if (NT_SUCCESS(Status
)) DeviceExtension
->TentativeNextState
= NewState
;
139 DbgPrint("%x\n", Status
);
145 PciCancelStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension
,
146 IN PCI_STATE StateNotEntered
)
149 DPRINT1("PCI Request to cancel transition of Extension %p to %s ->",
151 PciTransitionText
[StateNotEntered
]);
153 /* The next state can't be the state the device is already in */
154 if (DeviceExtension
->TentativeNextState
== DeviceExtension
->DeviceState
)
156 /* It's too late since the state was already committed */
157 ASSERT(StateNotEntered
< PciMaxObjectState
);
158 ASSERT(PnpStateCancelArray
[StateNotEntered
] != STATUS_FAIL_CHECK
);
161 Status
= STATUS_INVALID_DEVICE_STATE
;
162 DbgPrint("%x\n", Status
);
166 /* The device hasn't yet entered the state, so it's still possible to cancel */
167 ASSERT(DeviceExtension
->TentativeNextState
== StateNotEntered
);
168 DeviceExtension
->TentativeNextState
= DeviceExtension
->DeviceState
;
171 Status
= STATUS_SUCCESS
;
172 DbgPrint("%x\n", Status
);
175 /* Return the cancel state */
181 PciCommitStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension
,
182 IN PCI_STATE NewState
)
184 DPRINT1("PCI Commit transition of Extension %p to %s\n",
185 DeviceExtension
, PciTransitionText
[NewState
]);
187 /* Make sure this is a valid commit */
188 ASSERT(NewState
!= PciSynchronizedOperation
);
189 ASSERT(DeviceExtension
->TentativeNextState
== NewState
);
191 /* Enter the new state */
192 DeviceExtension
->DeviceState
= NewState
;