[CMAKE]
[reactos.git] / drivers / bus / pcix / pdo.c
1 /*
2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/bus/pci/pdo.c
5 * PURPOSE: PDO Device Management
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <pci.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS ********************************************************************/
16
17 LONG PciPdoSequenceNumber;
18
19 C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, DeviceState) == FIELD_OFFSET(PCI_PDO_EXTENSION, DeviceState));
20 C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, TentativeNextState) == FIELD_OFFSET(PCI_PDO_EXTENSION, TentativeNextState));
21 C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, List) == FIELD_OFFSET(PCI_PDO_EXTENSION, Next));
22
23 PCI_MN_DISPATCH_TABLE PciPdoDispatchPowerTable[] =
24 {
25 {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciPdoWaitWake},
26 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
27 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoSetPowerState},
28 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryPower},
29 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}
30 };
31
32 PCI_MN_DISPATCH_TABLE PciPdoDispatchPnpTable[] =
33 {
34 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpStartDevice},
35 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryRemoveDevice},
36 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpRemoveDevice},
37 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpCancelRemoveDevice},
38 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpStopDevice},
39 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryStopDevice},
40 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpCancelStopDevice},
41 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceRelations},
42 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryInterface},
43 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryCapabilities},
44 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryResources},
45 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryResourceRequirements},
46 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceText},
47 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
48 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
49 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpReadConfig},
50 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpWriteConfig},
51 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
52 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
53 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryId},
54 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceState},
55 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryBusInformation},
56 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpDeviceUsageNotification},
57 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpSurpriseRemoval},
58 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryLegacyBusInformation},
59 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}
60 };
61
62 PCI_MJ_DISPATCH_TABLE PciPdoDispatchTable =
63 {
64 IRP_MN_QUERY_LEGACY_BUS_INFORMATION,
65 PciPdoDispatchPnpTable,
66 IRP_MN_QUERY_POWER,
67 PciPdoDispatchPowerTable,
68 IRP_COMPLETE,
69 (PCI_DISPATCH_FUNCTION)PciIrpNotSupported,
70 IRP_COMPLETE,
71 (PCI_DISPATCH_FUNCTION)PciIrpInvalidDeviceRequest
72 };
73
74 /* FUNCTIONS ******************************************************************/
75
76 NTSTATUS
77 NTAPI
78 PciPdoWaitWake(IN PIRP Irp,
79 IN PIO_STACK_LOCATION IoStackLocation,
80 IN PPCI_PDO_EXTENSION DeviceExtension)
81 {
82 UNIMPLEMENTED;
83 while (TRUE);
84 return STATUS_NOT_SUPPORTED;
85 }
86
87 NTSTATUS
88 NTAPI
89 PciPdoSetPowerState(IN PIRP Irp,
90 IN PIO_STACK_LOCATION IoStackLocation,
91 IN PPCI_PDO_EXTENSION DeviceExtension)
92 {
93 UNIMPLEMENTED;
94 while (TRUE);
95 return STATUS_NOT_SUPPORTED;
96 }
97
98 NTSTATUS
99 NTAPI
100 PciPdoIrpQueryPower(IN PIRP Irp,
101 IN PIO_STACK_LOCATION IoStackLocation,
102 IN PPCI_PDO_EXTENSION DeviceExtension)
103 {
104 UNIMPLEMENTED;
105 while (TRUE);
106 return STATUS_NOT_SUPPORTED;
107 }
108
109 NTSTATUS
110 NTAPI
111 PciPdoIrpStartDevice(IN PIRP Irp,
112 IN PIO_STACK_LOCATION IoStackLocation,
113 IN PPCI_PDO_EXTENSION DeviceExtension)
114 {
115 UNIMPLEMENTED;
116 while (TRUE);
117 return STATUS_NOT_SUPPORTED;
118 }
119
120 NTSTATUS
121 NTAPI
122 PciPdoIrpQueryRemoveDevice(IN PIRP Irp,
123 IN PIO_STACK_LOCATION IoStackLocation,
124 IN PPCI_PDO_EXTENSION DeviceExtension)
125 {
126 UNIMPLEMENTED;
127 while (TRUE);
128 return STATUS_NOT_SUPPORTED;
129 }
130
131 NTSTATUS
132 NTAPI
133 PciPdoIrpRemoveDevice(IN PIRP Irp,
134 IN PIO_STACK_LOCATION IoStackLocation,
135 IN PPCI_PDO_EXTENSION DeviceExtension)
136 {
137 UNIMPLEMENTED;
138 while (TRUE);
139 return STATUS_NOT_SUPPORTED;
140 }
141
142 NTSTATUS
143 NTAPI
144 PciPdoIrpCancelRemoveDevice(IN PIRP Irp,
145 IN PIO_STACK_LOCATION IoStackLocation,
146 IN PPCI_PDO_EXTENSION DeviceExtension)
147 {
148 UNIMPLEMENTED;
149 while (TRUE);
150 return STATUS_NOT_SUPPORTED;
151 }
152
153 NTSTATUS
154 NTAPI
155 PciPdoIrpStopDevice(IN PIRP Irp,
156 IN PIO_STACK_LOCATION IoStackLocation,
157 IN PPCI_PDO_EXTENSION DeviceExtension)
158 {
159 UNIMPLEMENTED;
160 while (TRUE);
161 return STATUS_NOT_SUPPORTED;
162 }
163
164 NTSTATUS
165 NTAPI
166 PciPdoIrpQueryStopDevice(IN PIRP Irp,
167 IN PIO_STACK_LOCATION IoStackLocation,
168 IN PPCI_PDO_EXTENSION DeviceExtension)
169 {
170 UNIMPLEMENTED;
171 while (TRUE);
172 return STATUS_NOT_SUPPORTED;
173 }
174
175 NTSTATUS
176 NTAPI
177 PciPdoIrpCancelStopDevice(IN PIRP Irp,
178 IN PIO_STACK_LOCATION IoStackLocation,
179 IN PPCI_PDO_EXTENSION DeviceExtension)
180 {
181 UNIMPLEMENTED;
182 while (TRUE);
183 return STATUS_NOT_SUPPORTED;
184 }
185
186 NTSTATUS
187 NTAPI
188 PciPdoIrpQueryInterface(IN PIRP Irp,
189 IN PIO_STACK_LOCATION IoStackLocation,
190 IN PPCI_PDO_EXTENSION DeviceExtension)
191 {
192 UNIMPLEMENTED;
193 while (TRUE);
194 return STATUS_NOT_SUPPORTED;
195 }
196
197 NTSTATUS
198 NTAPI
199 PciPdoIrpQueryDeviceRelations(IN PIRP Irp,
200 IN PIO_STACK_LOCATION IoStackLocation,
201 IN PPCI_PDO_EXTENSION DeviceExtension)
202 {
203 UNIMPLEMENTED;
204 while (TRUE);
205 return STATUS_NOT_SUPPORTED;
206 }
207
208 NTSTATUS
209 NTAPI
210 PciPdoIrpQueryCapabilities(IN PIRP Irp,
211 IN PIO_STACK_LOCATION IoStackLocation,
212 IN PPCI_PDO_EXTENSION DeviceExtension)
213 {
214 UNIMPLEMENTED;
215 while (TRUE);
216 return STATUS_NOT_SUPPORTED;
217 }
218
219 NTSTATUS
220 NTAPI
221 PciPdoIrpQueryResources(IN PIRP Irp,
222 IN PIO_STACK_LOCATION IoStackLocation,
223 IN PPCI_PDO_EXTENSION DeviceExtension)
224 {
225 UNIMPLEMENTED;
226 while (TRUE);
227 return STATUS_NOT_SUPPORTED;
228 }
229
230 NTSTATUS
231 NTAPI
232 PciPdoIrpQueryResourceRequirements(IN PIRP Irp,
233 IN PIO_STACK_LOCATION IoStackLocation,
234 IN PPCI_PDO_EXTENSION DeviceExtension)
235 {
236 UNIMPLEMENTED;
237 while (TRUE);
238 return STATUS_NOT_SUPPORTED;
239 }
240
241 NTSTATUS
242 NTAPI
243 PciPdoIrpQueryDeviceText(IN PIRP Irp,
244 IN PIO_STACK_LOCATION IoStackLocation,
245 IN PPCI_PDO_EXTENSION DeviceExtension)
246 {
247 UNIMPLEMENTED;
248 while (TRUE);
249 return STATUS_NOT_SUPPORTED;
250 }
251
252 NTSTATUS
253 NTAPI
254 PciPdoIrpQueryId(IN PIRP Irp,
255 IN PIO_STACK_LOCATION IoStackLocation,
256 IN PPCI_PDO_EXTENSION DeviceExtension)
257 {
258 UNIMPLEMENTED;
259 while (TRUE);
260 return STATUS_NOT_SUPPORTED;
261 }
262
263 NTSTATUS
264 NTAPI
265 PciPdoIrpQueryBusInformation(IN PIRP Irp,
266 IN PIO_STACK_LOCATION IoStackLocation,
267 IN PPCI_PDO_EXTENSION DeviceExtension)
268 {
269 UNIMPLEMENTED;
270 while (TRUE);
271 return STATUS_NOT_SUPPORTED;
272 }
273
274 NTSTATUS
275 NTAPI
276 PciPdoIrpReadConfig(IN PIRP Irp,
277 IN PIO_STACK_LOCATION IoStackLocation,
278 IN PPCI_PDO_EXTENSION DeviceExtension)
279 {
280 UNIMPLEMENTED;
281 while (TRUE);
282 return STATUS_NOT_SUPPORTED;
283 }
284
285 NTSTATUS
286 NTAPI
287 PciPdoIrpWriteConfig(IN PIRP Irp,
288 IN PIO_STACK_LOCATION IoStackLocation,
289 IN PPCI_PDO_EXTENSION DeviceExtension)
290 {
291 UNIMPLEMENTED;
292 while (TRUE);
293 return STATUS_NOT_SUPPORTED;
294 }
295
296 NTSTATUS
297 NTAPI
298 PciPdoIrpQueryDeviceState(IN PIRP Irp,
299 IN PIO_STACK_LOCATION IoStackLocation,
300 IN PPCI_PDO_EXTENSION DeviceExtension)
301 {
302 UNIMPLEMENTED;
303 while (TRUE);
304 return STATUS_NOT_SUPPORTED;
305 }
306
307 NTSTATUS
308 NTAPI
309 PciPdoIrpDeviceUsageNotification(IN PIRP Irp,
310 IN PIO_STACK_LOCATION IoStackLocation,
311 IN PPCI_PDO_EXTENSION DeviceExtension)
312 {
313 UNIMPLEMENTED;
314 while (TRUE);
315 return STATUS_NOT_SUPPORTED;
316 }
317
318 NTSTATUS
319 NTAPI
320 PciPdoIrpSurpriseRemoval(IN PIRP Irp,
321 IN PIO_STACK_LOCATION IoStackLocation,
322 IN PPCI_PDO_EXTENSION DeviceExtension)
323 {
324 UNIMPLEMENTED;
325 while (TRUE);
326 return STATUS_NOT_SUPPORTED;
327 }
328
329 NTSTATUS
330 NTAPI
331 PciPdoIrpQueryLegacyBusInformation(IN PIRP Irp,
332 IN PIO_STACK_LOCATION IoStackLocation,
333 IN PPCI_PDO_EXTENSION DeviceExtension)
334 {
335 UNIMPLEMENTED;
336 while (TRUE);
337 return STATUS_NOT_SUPPORTED;
338 }
339
340 NTSTATUS
341 NTAPI
342 PciPdoCreate(IN PPCI_FDO_EXTENSION DeviceExtension,
343 IN PCI_SLOT_NUMBER Slot,
344 OUT PDEVICE_OBJECT *PdoDeviceObject)
345 {
346 WCHAR DeviceName[32];
347 UNICODE_STRING DeviceString;
348 NTSTATUS Status;
349 PDEVICE_OBJECT DeviceObject;
350 PPCI_PDO_EXTENSION PdoExtension;
351 ULONG SequenceNumber;
352 PAGED_CODE();
353
354 /* Pick an atomically unique sequence number for this device */
355 SequenceNumber = InterlockedIncrement(&PciPdoSequenceNumber);
356
357 /* Create the standard PCI device name for a PDO */
358 swprintf(DeviceName, L"\\Device\\NTPNP_PCI%04d", SequenceNumber);
359 RtlInitUnicodeString(&DeviceString, DeviceName);
360
361 /* Create the actual device now */
362 Status = IoCreateDevice(DeviceExtension->FunctionalDeviceObject->DriverObject,
363 sizeof(PCI_PDO_EXTENSION),
364 &DeviceString,
365 FILE_DEVICE_BUS_EXTENDER,
366 0,
367 0,
368 &DeviceObject);
369 ASSERT(NT_SUCCESS(Status));
370
371 /* Get the extension for it */
372 PdoExtension = (PPCI_PDO_EXTENSION)DeviceObject->DeviceExtension;
373 DPRINT1("PCI: New PDO (b=0x%x, d=0x%x, f=0x%x) @ %p, ext @ %p\n",
374 DeviceExtension->BaseBus,
375 Slot.u.bits.DeviceNumber,
376 Slot.u.bits.FunctionNumber,
377 DeviceObject,
378 DeviceObject->DeviceExtension);
379
380 /* Configure the extension */
381 PdoExtension->ExtensionType = PciPdoExtensionType;
382 PdoExtension->IrpDispatchTable = &PciPdoDispatchTable;
383 PdoExtension->PhysicalDeviceObject = DeviceObject;
384 PdoExtension->Slot = Slot;
385 PdoExtension->PowerState.CurrentSystemState = PowerDeviceD0;
386 PdoExtension->PowerState.CurrentDeviceState = PowerDeviceD0;
387 PdoExtension->ParentFdoExtension = DeviceExtension;
388
389 /* Initialize the lock for arbiters and other interfaces */
390 KeInitializeEvent(&PdoExtension->SecondaryExtLock, SynchronizationEvent, TRUE);
391
392 /* Initialize the state machine */
393 PciInitializeState((PPCI_FDO_EXTENSION)PdoExtension);
394
395 /* Add the PDO to the parent's list */
396 PdoExtension->Next = NULL;
397 PciInsertEntryAtTail((PSINGLE_LIST_ENTRY)&DeviceExtension->ChildPdoList,
398 (PPCI_FDO_EXTENSION)PdoExtension,
399 &DeviceExtension->ChildListLock);
400
401 /* And finally return it to the caller */
402 *PdoDeviceObject = DeviceObject;
403 return STATUS_SUCCESS;
404 }
405
406 /* EOF */