[PCIX]
[reactos.git] / reactos / drivers / bus / pcix / pci / state.c
1 /*
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
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <pci.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* GLOBALS ********************************************************************/
17
18 PCHAR PciTransitionText[PciMaxObjectState + 1] =
19 {
20 "PciNotStarted",
21 "PciStarted",
22 "PciDeleted",
23 "PciStopped",
24 "PciSurpriseRemoved",
25 "PciSynchronizedOperation",
26 "PciMaxObjectState"
27 };
28
29 NTSTATUS PnpStateCancelArray[PciMaxObjectState] =
30 {
31 STATUS_INVALID_DEVICE_REQUEST,
32 STATUS_FAIL_CHECK,
33 STATUS_INVALID_DEVICE_STATE,
34 STATUS_INVALID_DEVICE_STATE,
35 STATUS_FAIL_CHECK,
36 STATUS_FAIL_CHECK
37 };
38
39 NTSTATUS PnpStateTransitionArray[PciMaxObjectState * PciMaxObjectState] =
40 {
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
47
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
54
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
61
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
68
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
75
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
82 };
83
84 /* FUNCTIONS ******************************************************************/
85
86 VOID
87 NTAPI
88 PciInitializeState(IN PPCI_FDO_EXTENSION DeviceExtension)
89 {
90 /* Set the initial state */
91 DeviceExtension->DeviceState = PciNotStarted;
92 DeviceExtension->TentativeNextState = PciNotStarted;
93 }
94
95 NTSTATUS
96 NTAPI
97 PciBeginStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension,
98 IN PCI_STATE NewState)
99 {
100 PCI_STATE CurrentState;
101 NTSTATUS Status;
102 DPRINT1("PCI Request to begin transition of Extension %p to %s ->",
103 DeviceExtension,
104 PciTransitionText[NewState]);
105
106 /* Assert the device isn't already in a pending transition */
107 ASSERT(DeviceExtension->TentativeNextState == DeviceExtension->DeviceState);
108
109 /* Assert this is a valid state */
110 CurrentState = DeviceExtension->DeviceState;
111 ASSERT(CurrentState < PciMaxObjectState);
112 ASSERT(NewState < PciMaxObjectState);
113
114 /* Lookup if this state transition is valid */
115 Status = PnpStateTransitionArray[CurrentState + 6 * NewState];
116 if (Status == STATUS_FAIL_CHECK)
117 {
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]);
123 DbgBreakPoint();
124 }
125 else if (Status == STATUS_INVALID_DEVICE_REQUEST)
126 {
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]);
132 }
133
134 /* New state must be different from current, unless request is at fault */
135 ASSERT((NewState != DeviceExtension->DeviceState) || (!NT_SUCCESS(Status)));
136
137 /* Enter the new state if successful, and return state status */
138 if (NT_SUCCESS(Status)) DeviceExtension->TentativeNextState = NewState;
139 DbgPrint("%x\n", Status);
140 return Status;
141 }
142
143 NTSTATUS
144 NTAPI
145 PciCancelStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension,
146 IN PCI_STATE StateNotEntered)
147 {
148 NTSTATUS Status;
149 DPRINT1("PCI Request to cancel transition of Extension %p to %s ->",
150 DeviceExtension,
151 PciTransitionText[StateNotEntered]);
152
153 /* The next state can't be the state the device is already in */
154 if (DeviceExtension->TentativeNextState == DeviceExtension->DeviceState)
155 {
156 /* It's too late since the state was already committed */
157 ASSERT(StateNotEntered < PciMaxObjectState);
158 ASSERT(PnpStateCancelArray[StateNotEntered] != STATUS_FAIL_CHECK);
159
160 /* Return failure */
161 Status = STATUS_INVALID_DEVICE_STATE;
162 DbgPrint("%x\n", Status);
163 }
164 else
165 {
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;
169
170 /* Return success */
171 Status = STATUS_SUCCESS;
172 DbgPrint("%x\n", Status);
173 }
174
175 /* Return the cancel state */
176 return Status;
177 }
178
179 VOID
180 NTAPI
181 PciCommitStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension,
182 IN PCI_STATE NewState)
183 {
184 DPRINT1("PCI Commit transition of Extension %p to %s\n",
185 DeviceExtension, PciTransitionText[NewState]);
186
187 /* Make sure this is a valid commit */
188 ASSERT(NewState != PciSynchronizedOperation);
189 ASSERT(DeviceExtension->TentativeNextState == NewState);
190
191 /* Enter the new state */
192 DeviceExtension->DeviceState = NewState;
193 }
194
195 /* EOF */