Synchronize with trunk revision 59636 (just before Alex's CreateProcess revamp).
[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 UNREFERENCED_PARAMETER(Irp);
83 UNREFERENCED_PARAMETER(IoStackLocation);
84 UNREFERENCED_PARAMETER(DeviceExtension);
85
86 UNIMPLEMENTED_DBGBREAK();
87 return STATUS_NOT_SUPPORTED;
88 }
89
90 NTSTATUS
91 NTAPI
92 PciPdoSetPowerState(IN PIRP Irp,
93 IN PIO_STACK_LOCATION IoStackLocation,
94 IN PPCI_PDO_EXTENSION DeviceExtension)
95 {
96 UNREFERENCED_PARAMETER(Irp);
97 UNREFERENCED_PARAMETER(IoStackLocation);
98 UNREFERENCED_PARAMETER(DeviceExtension);
99
100 UNIMPLEMENTED;
101 return STATUS_NOT_SUPPORTED;
102 }
103
104 NTSTATUS
105 NTAPI
106 PciPdoIrpQueryPower(IN PIRP Irp,
107 IN PIO_STACK_LOCATION IoStackLocation,
108 IN PPCI_PDO_EXTENSION DeviceExtension)
109 {
110 UNREFERENCED_PARAMETER(Irp);
111 UNREFERENCED_PARAMETER(IoStackLocation);
112 UNREFERENCED_PARAMETER(DeviceExtension);
113
114 UNIMPLEMENTED_DBGBREAK();
115 return STATUS_NOT_SUPPORTED;
116 }
117
118 NTSTATUS
119 NTAPI
120 PciPdoIrpStartDevice(IN PIRP Irp,
121 IN PIO_STACK_LOCATION IoStackLocation,
122 IN PPCI_PDO_EXTENSION DeviceExtension)
123 {
124 NTSTATUS Status;
125 BOOLEAN Changed, DoReset;
126 POWER_STATE PowerState;
127 PAGED_CODE();
128
129 UNREFERENCED_PARAMETER(Irp);
130
131 DoReset = FALSE;
132
133 /* Begin entering the start phase */
134 Status = PciBeginStateTransition((PVOID)DeviceExtension, PciStarted);
135 if (!NT_SUCCESS(Status)) return Status;
136
137 /* Check if this is a VGA device */
138 if (((DeviceExtension->BaseClass == PCI_CLASS_PRE_20) &&
139 (DeviceExtension->SubClass == PCI_SUBCLASS_PRE_20_VGA)) ||
140 ((DeviceExtension->BaseClass == PCI_CLASS_DISPLAY_CTLR) &&
141 (DeviceExtension->SubClass == PCI_SUBCLASS_VID_VGA_CTLR)))
142 {
143 /* Always force it on */
144 DeviceExtension->CommandEnables |= (PCI_ENABLE_IO_SPACE |
145 PCI_ENABLE_MEMORY_SPACE);
146 }
147
148 /* Check if native IDE is enabled and it owns the I/O ports */
149 if (DeviceExtension->IoSpaceUnderNativeIdeControl)
150 {
151 /* Then don't allow I/O access */
152 DeviceExtension->CommandEnables &= ~PCI_ENABLE_IO_SPACE;
153 }
154
155 /* Always enable bus mastering */
156 DeviceExtension->CommandEnables |= PCI_ENABLE_BUS_MASTER;
157
158 /* Check if the OS assigned resources differ from the PCI configuration */
159 Changed = PciComputeNewCurrentSettings(DeviceExtension,
160 IoStackLocation->Parameters.
161 StartDevice.AllocatedResources);
162 if (Changed)
163 {
164 /* Remember this for later */
165 DeviceExtension->MovedDevice = TRUE;
166 }
167 else
168 {
169 /* All good */
170 DPRINT1("PCI - START not changing resource settings.\n");
171 }
172
173 /* Check if the device was sleeping */
174 if (DeviceExtension->PowerState.CurrentDeviceState != PowerDeviceD0)
175 {
176 /* Power it up */
177 Status = PciSetPowerManagedDevicePowerState(DeviceExtension,
178 PowerDeviceD0,
179 FALSE);
180 if (!NT_SUCCESS(Status))
181 {
182 /* Powerup fail, fail the request */
183 PciCancelStateTransition((PVOID)DeviceExtension, PciStarted);
184 return STATUS_DEVICE_POWER_FAILURE;
185 }
186
187 /* Tell the power manager that the device is powered up */
188 PowerState.DeviceState = PowerDeviceD0;
189 PoSetPowerState(DeviceExtension->PhysicalDeviceObject,
190 DevicePowerState,
191 PowerState);
192
193 /* Update internal state */
194 DeviceExtension->PowerState.CurrentDeviceState = PowerDeviceD0;
195
196 /* This device's resources and decodes will need to be reset */
197 DoReset = TRUE;
198 }
199
200 /* Update resource information now that the device is powered up and active */
201 Status = PciSetResources(DeviceExtension, DoReset, TRUE);
202 if (!NT_SUCCESS(Status))
203 {
204 /* That failed, so cancel the transition */
205 PciCancelStateTransition((PVOID)DeviceExtension, PciStarted);
206 }
207 else
208 {
209 /* Fully commit, as the device is now started up and ready to go */
210 PciCommitStateTransition((PVOID)DeviceExtension, PciStarted);
211 }
212
213 /* Return the result of the start request */
214 return Status;
215 }
216
217 NTSTATUS
218 NTAPI
219 PciPdoIrpQueryRemoveDevice(IN PIRP Irp,
220 IN PIO_STACK_LOCATION IoStackLocation,
221 IN PPCI_PDO_EXTENSION DeviceExtension)
222 {
223 UNREFERENCED_PARAMETER(Irp);
224 UNREFERENCED_PARAMETER(IoStackLocation);
225 UNREFERENCED_PARAMETER(DeviceExtension);
226
227 UNIMPLEMENTED;
228 return STATUS_NOT_SUPPORTED;
229 }
230
231 NTSTATUS
232 NTAPI
233 PciPdoIrpRemoveDevice(IN PIRP Irp,
234 IN PIO_STACK_LOCATION IoStackLocation,
235 IN PPCI_PDO_EXTENSION DeviceExtension)
236 {
237 UNREFERENCED_PARAMETER(Irp);
238 UNREFERENCED_PARAMETER(IoStackLocation);
239 UNREFERENCED_PARAMETER(DeviceExtension);
240
241 UNIMPLEMENTED_DBGBREAK();
242 return STATUS_NOT_SUPPORTED;
243 }
244
245 NTSTATUS
246 NTAPI
247 PciPdoIrpCancelRemoveDevice(IN PIRP Irp,
248 IN PIO_STACK_LOCATION IoStackLocation,
249 IN PPCI_PDO_EXTENSION DeviceExtension)
250 {
251 UNREFERENCED_PARAMETER(Irp);
252 UNREFERENCED_PARAMETER(IoStackLocation);
253 UNREFERENCED_PARAMETER(DeviceExtension);
254
255 UNIMPLEMENTED_DBGBREAK();
256 return STATUS_NOT_SUPPORTED;
257 }
258
259 NTSTATUS
260 NTAPI
261 PciPdoIrpStopDevice(IN PIRP Irp,
262 IN PIO_STACK_LOCATION IoStackLocation,
263 IN PPCI_PDO_EXTENSION DeviceExtension)
264 {
265 UNREFERENCED_PARAMETER(Irp);
266 UNREFERENCED_PARAMETER(IoStackLocation);
267 UNREFERENCED_PARAMETER(DeviceExtension);
268
269 UNIMPLEMENTED_DBGBREAK();
270 return STATUS_NOT_SUPPORTED;
271 }
272
273 NTSTATUS
274 NTAPI
275 PciPdoIrpQueryStopDevice(IN PIRP Irp,
276 IN PIO_STACK_LOCATION IoStackLocation,
277 IN PPCI_PDO_EXTENSION DeviceExtension)
278 {
279 UNREFERENCED_PARAMETER(Irp);
280 UNREFERENCED_PARAMETER(IoStackLocation);
281 UNREFERENCED_PARAMETER(DeviceExtension);
282
283 UNIMPLEMENTED_DBGBREAK();
284 return STATUS_NOT_SUPPORTED;
285 }
286
287 NTSTATUS
288 NTAPI
289 PciPdoIrpCancelStopDevice(IN PIRP Irp,
290 IN PIO_STACK_LOCATION IoStackLocation,
291 IN PPCI_PDO_EXTENSION DeviceExtension)
292 {
293 UNREFERENCED_PARAMETER(Irp);
294 UNREFERENCED_PARAMETER(IoStackLocation);
295 UNREFERENCED_PARAMETER(DeviceExtension);
296
297 UNIMPLEMENTED_DBGBREAK();
298 return STATUS_NOT_SUPPORTED;
299 }
300
301 NTSTATUS
302 NTAPI
303 PciPdoIrpQueryInterface(IN PIRP Irp,
304 IN PIO_STACK_LOCATION IoStackLocation,
305 IN PPCI_PDO_EXTENSION DeviceExtension)
306 {
307 UNREFERENCED_PARAMETER(Irp);
308 UNREFERENCED_PARAMETER(IoStackLocation);
309 UNREFERENCED_PARAMETER(DeviceExtension);
310
311 UNIMPLEMENTED_DBGBREAK();
312 return STATUS_NOT_SUPPORTED;
313 }
314
315 NTSTATUS
316 NTAPI
317 PciPdoIrpQueryDeviceRelations(IN PIRP Irp,
318 IN PIO_STACK_LOCATION IoStackLocation,
319 IN PPCI_PDO_EXTENSION DeviceExtension)
320 {
321 NTSTATUS Status;
322 PAGED_CODE();
323
324 /* Are ejection relations being queried? */
325 if (IoStackLocation->Parameters.QueryDeviceRelations.Type == EjectionRelations)
326 {
327 /* Call the worker function */
328 Status = PciQueryEjectionRelations(DeviceExtension,
329 (PDEVICE_RELATIONS*)&Irp->
330 IoStatus.Information);
331 }
332 else if (IoStackLocation->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
333 {
334 /* The only other relation supported is the target device relation */
335 Status = PciQueryTargetDeviceRelations(DeviceExtension,
336 (PDEVICE_RELATIONS*)&Irp->
337 IoStatus.Information);
338 }
339 else
340 {
341 /* All other relations are unsupported */
342 Status = STATUS_NOT_SUPPORTED;
343 }
344
345 /* Return either the result of the worker function, or unsupported status */
346 return Status;
347 }
348
349 NTSTATUS
350 NTAPI
351 PciPdoIrpQueryCapabilities(IN PIRP Irp,
352 IN PIO_STACK_LOCATION IoStackLocation,
353 IN PPCI_PDO_EXTENSION DeviceExtension)
354 {
355 PAGED_CODE();
356
357 UNREFERENCED_PARAMETER(Irp);
358
359 /* Call the worker function */
360 return PciQueryCapabilities(DeviceExtension,
361 IoStackLocation->
362 Parameters.DeviceCapabilities.Capabilities);
363 }
364
365 NTSTATUS
366 NTAPI
367 PciPdoIrpQueryResources(IN PIRP Irp,
368 IN PIO_STACK_LOCATION IoStackLocation,
369 IN PPCI_PDO_EXTENSION DeviceExtension)
370 {
371 PAGED_CODE();
372
373 UNREFERENCED_PARAMETER(IoStackLocation);
374
375 /* Call the worker function */
376 return PciQueryResources(DeviceExtension,
377 (PCM_RESOURCE_LIST*)&Irp->IoStatus.Information);
378 }
379
380 NTSTATUS
381 NTAPI
382 PciPdoIrpQueryResourceRequirements(IN PIRP Irp,
383 IN PIO_STACK_LOCATION IoStackLocation,
384 IN PPCI_PDO_EXTENSION DeviceExtension)
385 {
386 PAGED_CODE();
387
388 UNREFERENCED_PARAMETER(IoStackLocation);
389
390 /* Call the worker function */
391 return PciQueryRequirements(DeviceExtension,
392 (PIO_RESOURCE_REQUIREMENTS_LIST*)&Irp->
393 IoStatus.Information);
394 }
395
396 NTSTATUS
397 NTAPI
398 PciPdoIrpQueryDeviceText(IN PIRP Irp,
399 IN PIO_STACK_LOCATION IoStackLocation,
400 IN PPCI_PDO_EXTENSION DeviceExtension)
401 {
402 PAGED_CODE();
403
404 /* Call the worker function */
405 return PciQueryDeviceText(DeviceExtension,
406 IoStackLocation->
407 Parameters.QueryDeviceText.DeviceTextType,
408 IoStackLocation->
409 Parameters.QueryDeviceText.LocaleId,
410 (PWCHAR*)&Irp->IoStatus.Information);
411 }
412
413 NTSTATUS
414 NTAPI
415 PciPdoIrpQueryId(IN PIRP Irp,
416 IN PIO_STACK_LOCATION IoStackLocation,
417 IN PPCI_PDO_EXTENSION DeviceExtension)
418 {
419 PAGED_CODE();
420
421 /* Call the worker function */
422 return PciQueryId(DeviceExtension,
423 IoStackLocation->Parameters.QueryId.IdType,
424 (PWCHAR*)&Irp->IoStatus.Information);
425 }
426
427 NTSTATUS
428 NTAPI
429 PciPdoIrpQueryBusInformation(IN PIRP Irp,
430 IN PIO_STACK_LOCATION IoStackLocation,
431 IN PPCI_PDO_EXTENSION DeviceExtension)
432 {
433 PAGED_CODE();
434
435 UNREFERENCED_PARAMETER(IoStackLocation);
436
437 /* Call the worker function */
438 return PciQueryBusInformation(DeviceExtension,
439 (PPNP_BUS_INFORMATION*)&Irp->
440 IoStatus.Information);
441 }
442
443 NTSTATUS
444 NTAPI
445 PciPdoIrpReadConfig(IN PIRP Irp,
446 IN PIO_STACK_LOCATION IoStackLocation,
447 IN PPCI_PDO_EXTENSION DeviceExtension)
448 {
449 UNREFERENCED_PARAMETER(Irp);
450 UNREFERENCED_PARAMETER(IoStackLocation);
451 UNREFERENCED_PARAMETER(DeviceExtension);
452
453 UNIMPLEMENTED_DBGBREAK();
454 return STATUS_NOT_SUPPORTED;
455 }
456
457 NTSTATUS
458 NTAPI
459 PciPdoIrpWriteConfig(IN PIRP Irp,
460 IN PIO_STACK_LOCATION IoStackLocation,
461 IN PPCI_PDO_EXTENSION DeviceExtension)
462 {
463 UNREFERENCED_PARAMETER(Irp);
464 UNREFERENCED_PARAMETER(IoStackLocation);
465 UNREFERENCED_PARAMETER(DeviceExtension);
466
467 UNIMPLEMENTED_DBGBREAK();
468 return STATUS_NOT_SUPPORTED;
469 }
470
471 NTSTATUS
472 NTAPI
473 PciPdoIrpQueryDeviceState(IN PIRP Irp,
474 IN PIO_STACK_LOCATION IoStackLocation,
475 IN PPCI_PDO_EXTENSION DeviceExtension)
476 {
477 UNREFERENCED_PARAMETER(Irp);
478 UNREFERENCED_PARAMETER(IoStackLocation);
479 UNREFERENCED_PARAMETER(DeviceExtension);
480
481 UNIMPLEMENTED;
482 return STATUS_NOT_SUPPORTED;
483 }
484
485 NTSTATUS
486 NTAPI
487 PciPdoIrpDeviceUsageNotification(IN PIRP Irp,
488 IN PIO_STACK_LOCATION IoStackLocation,
489 IN PPCI_PDO_EXTENSION DeviceExtension)
490 {
491 UNREFERENCED_PARAMETER(Irp);
492 UNREFERENCED_PARAMETER(IoStackLocation);
493 UNREFERENCED_PARAMETER(DeviceExtension);
494
495 UNIMPLEMENTED_DBGBREAK();
496 return STATUS_NOT_SUPPORTED;
497 }
498
499 NTSTATUS
500 NTAPI
501 PciPdoIrpSurpriseRemoval(IN PIRP Irp,
502 IN PIO_STACK_LOCATION IoStackLocation,
503 IN PPCI_PDO_EXTENSION DeviceExtension)
504 {
505 UNREFERENCED_PARAMETER(Irp);
506 UNREFERENCED_PARAMETER(IoStackLocation);
507 UNREFERENCED_PARAMETER(DeviceExtension);
508
509 UNIMPLEMENTED_DBGBREAK();
510 return STATUS_NOT_SUPPORTED;
511 }
512
513 NTSTATUS
514 NTAPI
515 PciPdoIrpQueryLegacyBusInformation(IN PIRP Irp,
516 IN PIO_STACK_LOCATION IoStackLocation,
517 IN PPCI_PDO_EXTENSION DeviceExtension)
518 {
519 UNREFERENCED_PARAMETER(Irp);
520 UNREFERENCED_PARAMETER(IoStackLocation);
521 UNREFERENCED_PARAMETER(DeviceExtension);
522
523 UNIMPLEMENTED_DBGBREAK();
524 return STATUS_NOT_SUPPORTED;
525 }
526
527 NTSTATUS
528 NTAPI
529 PciPdoCreate(IN PPCI_FDO_EXTENSION DeviceExtension,
530 IN PCI_SLOT_NUMBER Slot,
531 OUT PDEVICE_OBJECT *PdoDeviceObject)
532 {
533 WCHAR DeviceName[32];
534 UNICODE_STRING DeviceString;
535 NTSTATUS Status;
536 PDEVICE_OBJECT DeviceObject;
537 PPCI_PDO_EXTENSION PdoExtension;
538 ULONG SequenceNumber;
539 PAGED_CODE();
540
541 /* Pick an atomically unique sequence number for this device */
542 SequenceNumber = InterlockedIncrement(&PciPdoSequenceNumber);
543
544 /* Create the standard PCI device name for a PDO */
545 swprintf(DeviceName, L"\\Device\\NTPNP_PCI%04d", SequenceNumber);
546 RtlInitUnicodeString(&DeviceString, DeviceName);
547
548 /* Create the actual device now */
549 Status = IoCreateDevice(DeviceExtension->FunctionalDeviceObject->DriverObject,
550 sizeof(PCI_PDO_EXTENSION),
551 &DeviceString,
552 FILE_DEVICE_BUS_EXTENDER,
553 0,
554 0,
555 &DeviceObject);
556 ASSERT(NT_SUCCESS(Status));
557
558 /* Get the extension for it */
559 PdoExtension = (PPCI_PDO_EXTENSION)DeviceObject->DeviceExtension;
560 DPRINT1("PCI: New PDO (b=0x%x, d=0x%x, f=0x%x) @ %p, ext @ %p\n",
561 DeviceExtension->BaseBus,
562 Slot.u.bits.DeviceNumber,
563 Slot.u.bits.FunctionNumber,
564 DeviceObject,
565 DeviceObject->DeviceExtension);
566
567 /* Configure the extension */
568 PdoExtension->ExtensionType = PciPdoExtensionType;
569 PdoExtension->IrpDispatchTable = &PciPdoDispatchTable;
570 PdoExtension->PhysicalDeviceObject = DeviceObject;
571 PdoExtension->Slot = Slot;
572 PdoExtension->PowerState.CurrentSystemState = PowerDeviceD0;
573 PdoExtension->PowerState.CurrentDeviceState = PowerDeviceD0;
574 PdoExtension->ParentFdoExtension = DeviceExtension;
575
576 /* Initialize the lock for arbiters and other interfaces */
577 KeInitializeEvent(&PdoExtension->SecondaryExtLock, SynchronizationEvent, TRUE);
578
579 /* Initialize the state machine */
580 PciInitializeState((PPCI_FDO_EXTENSION)PdoExtension);
581
582 /* Add the PDO to the parent's list */
583 PdoExtension->Next = NULL;
584 PciInsertEntryAtTail((PSINGLE_LIST_ENTRY)&DeviceExtension->ChildPdoList,
585 (PPCI_FDO_EXTENSION)PdoExtension,
586 &DeviceExtension->ChildListLock);
587
588 /* And finally return it to the caller */
589 *PdoDeviceObject = DeviceObject;
590 return STATUS_SUCCESS;
591 }
592
593 /* EOF */