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