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