2 * PROJECT: ReactOS PCI bus driver
4 * PURPOSE: Child device object dispatch routines
5 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * 10-09-2001 CSH Created
17 /*** PRIVATE *****************************************************************/
21 IN PDEVICE_OBJECT DeviceObject
,
23 PIO_STACK_LOCATION IrpSp
)
25 PPDO_DEVICE_EXTENSION DeviceExtension
;
26 UNICODE_STRING String
;
31 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
33 switch (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
)
35 case DeviceTextDescription
:
36 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
37 &DeviceExtension
->DeviceDescription
,
40 DPRINT("DeviceTextDescription\n");
41 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
44 case DeviceTextLocationInformation
:
45 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
46 &DeviceExtension
->DeviceLocation
,
49 DPRINT("DeviceTextLocationInformation\n");
50 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
54 Irp
->IoStatus
.Information
= 0;
55 Status
= STATUS_INVALID_PARAMETER
;
65 IN PDEVICE_OBJECT DeviceObject
,
67 PIO_STACK_LOCATION IrpSp
)
69 PPDO_DEVICE_EXTENSION DeviceExtension
;
70 UNICODE_STRING String
;
75 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
77 // Irp->IoStatus.Information = 0;
79 Status
= STATUS_SUCCESS
;
81 RtlInitUnicodeString(&String
, NULL
);
83 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
84 case BusQueryDeviceID
:
85 Status
= PciDuplicateUnicodeString(
86 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
87 &DeviceExtension
->DeviceID
,
90 DPRINT("DeviceID: %S\n", String
.Buffer
);
92 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
95 case BusQueryHardwareIDs
:
96 Status
= PciDuplicateUnicodeString(
97 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
98 &DeviceExtension
->HardwareIDs
,
101 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
104 case BusQueryCompatibleIDs
:
105 Status
= PciDuplicateUnicodeString(
106 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
107 &DeviceExtension
->CompatibleIDs
,
110 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
113 case BusQueryInstanceID
:
114 Status
= PciDuplicateUnicodeString(
115 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
116 &DeviceExtension
->InstanceID
,
119 DPRINT("InstanceID: %S\n", String
.Buffer
);
121 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
124 case BusQueryDeviceSerialNumber
:
126 Status
= STATUS_NOT_IMPLEMENTED
;
134 PdoQueryBusInformation(
135 IN PDEVICE_OBJECT DeviceObject
,
137 PIO_STACK_LOCATION IrpSp
)
139 PPDO_DEVICE_EXTENSION DeviceExtension
;
140 PPNP_BUS_INFORMATION BusInformation
;
142 UNREFERENCED_PARAMETER(IrpSp
);
145 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
146 BusInformation
= ExAllocatePool(PagedPool
, sizeof(PNP_BUS_INFORMATION
));
147 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
148 if (BusInformation
!= NULL
)
150 BusInformation
->BusTypeGuid
= GUID_BUS_TYPE_PCI
;
151 BusInformation
->LegacyBusType
= PCIBus
;
152 BusInformation
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
154 return STATUS_SUCCESS
;
157 return STATUS_INSUFFICIENT_RESOURCES
;
162 PdoQueryCapabilities(
163 IN PDEVICE_OBJECT DeviceObject
,
165 PIO_STACK_LOCATION IrpSp
)
167 PPDO_DEVICE_EXTENSION DeviceExtension
;
168 PDEVICE_CAPABILITIES DeviceCapabilities
;
169 ULONG DeviceNumber
, FunctionNumber
;
171 UNREFERENCED_PARAMETER(Irp
);
174 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
175 DeviceCapabilities
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
177 if (DeviceCapabilities
->Version
!= 1)
178 return STATUS_UNSUCCESSFUL
;
180 DeviceNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.DeviceNumber
;
181 FunctionNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.FunctionNumber
;
183 DeviceCapabilities
->UniqueID
= FALSE
;
184 DeviceCapabilities
->Address
= ((DeviceNumber
<< 16) & 0xFFFF0000) + (FunctionNumber
& 0xFFFF);
185 DeviceCapabilities
->UINumber
= MAXULONG
; /* FIXME */
187 return STATUS_SUCCESS
;
192 PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension
,
204 /* Save original value */
205 Size
= HalGetBusDataByOffset(PCIConfiguration
,
206 DeviceExtension
->PciDevice
->BusNumber
,
207 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
211 if (Size
!= sizeof(ULONG
))
213 DPRINT1("Wrong size %lu\n", Size
);
217 BaseValue
= (OrigValue
& PCI_ADDRESS_IO_SPACE
)
218 ? (OrigValue
& PCI_ADDRESS_IO_ADDRESS_MASK
)
219 : (OrigValue
& PCI_ADDRESS_MEMORY_ADDRESS_MASK
);
223 /* Set magic value */
225 Size
= HalSetBusDataByOffset(PCIConfiguration
,
226 DeviceExtension
->PciDevice
->BusNumber
,
227 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
231 if (Size
!= sizeof(ULONG
))
233 DPRINT1("Wrong size %lu\n", Size
);
237 /* Get the range length */
238 Size
= HalGetBusDataByOffset(PCIConfiguration
,
239 DeviceExtension
->PciDevice
->BusNumber
,
240 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
244 if (Size
!= sizeof(ULONG
))
246 DPRINT1("Wrong size %lu\n", Size
);
250 /* Restore original value */
251 Size
= HalSetBusDataByOffset(PCIConfiguration
,
252 DeviceExtension
->PciDevice
->BusNumber
,
253 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
257 if (Size
!= sizeof(ULONG
))
259 DPRINT1("Wrong size %lu\n", Size
);
265 DPRINT("Unused address register\n");
272 XLength
= ~((NewValue
& PCI_ADDRESS_IO_SPACE
)
273 ? (NewValue
& PCI_ADDRESS_IO_ADDRESS_MASK
)
274 : (NewValue
& PCI_ADDRESS_MEMORY_ADDRESS_MASK
)) + 1;
277 DbgPrint("BaseAddress 0x%08lx Length 0x%08lx",
280 if (NewValue
& PCI_ADDRESS_IO_SPACE
)
282 DbgPrint(" IO range");
286 DbgPrint(" Memory range");
287 if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 0)
289 DbgPrint(" in 32-Bit address space");
291 else if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 2)
293 DbgPrint(" below 1BM ");
295 else if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 4)
297 DbgPrint(" in 64-Bit address space");
300 if (NewValue
& PCI_ADDRESS_MEMORY_PREFETCHABLE
)
302 DbgPrint(" prefetchable");
310 *Flags
= (NewValue
& PCI_ADDRESS_IO_SPACE
)
311 ? (NewValue
& ~PCI_ADDRESS_IO_ADDRESS_MASK
)
312 : (NewValue
& ~PCI_ADDRESS_MEMORY_ADDRESS_MASK
);
319 PdoQueryResourceRequirements(
320 IN PDEVICE_OBJECT DeviceObject
,
322 PIO_STACK_LOCATION IrpSp
)
324 PPDO_DEVICE_EXTENSION DeviceExtension
;
325 PCI_COMMON_CONFIG PciConfig
;
326 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
327 PIO_RESOURCE_DESCRIPTOR Descriptor
;
336 UNREFERENCED_PARAMETER(IrpSp
);
337 DPRINT("PdoQueryResourceRequirements() called\n");
339 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
341 /* Get PCI configuration space */
342 Size
= HalGetBusData(PCIConfiguration
,
343 DeviceExtension
->PciDevice
->BusNumber
,
344 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
346 PCI_COMMON_HDR_LENGTH
);
347 DPRINT("Size %lu\n", Size
);
348 if (Size
< PCI_COMMON_HDR_LENGTH
)
350 Irp
->IoStatus
.Information
= 0;
351 return STATUS_UNSUCCESSFUL
;
354 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
356 /* Count required resource descriptors */
358 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
360 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
362 if (!PdoGetRangeLength(DeviceExtension
,
373 /* FIXME: Check ROM address */
375 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
378 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
380 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
382 if (!PdoGetRangeLength(DeviceExtension
,
392 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
395 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
397 /* FIXME: Count Cardbus bridge resources */
401 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
406 Irp
->IoStatus
.Information
= 0;
407 return STATUS_SUCCESS
;
410 /* Calculate the resource list size */
411 ListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
[0].Descriptors
)
412 + ResCount
* sizeof(IO_RESOURCE_DESCRIPTOR
);
414 DPRINT("ListSize %lu (0x%lx)\n", ListSize
, ListSize
);
416 /* Allocate the resource requirements list */
417 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
419 if (ResourceList
== NULL
)
421 Irp
->IoStatus
.Information
= 0;
422 return STATUS_INSUFFICIENT_RESOURCES
;
425 RtlZeroMemory(ResourceList
, ListSize
);
426 ResourceList
->ListSize
= ListSize
;
427 ResourceList
->InterfaceType
= PCIBus
;
428 ResourceList
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
429 ResourceList
->SlotNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
;
430 ResourceList
->AlternativeLists
= 1;
432 ResourceList
->List
[0].Version
= 1;
433 ResourceList
->List
[0].Revision
= 1;
434 ResourceList
->List
[0].Count
= ResCount
;
436 Descriptor
= &ResourceList
->List
[0].Descriptors
[0];
437 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
439 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
441 if (!PdoGetRangeLength(DeviceExtension
,
447 DPRINT1("PdoGetRangeLength() failed\n");
453 DPRINT("Unused address register\n");
457 /* Set preferred descriptor */
458 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
459 if (Flags
& PCI_ADDRESS_IO_SPACE
)
461 Descriptor
->Type
= CmResourceTypePort
;
462 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
463 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
464 CM_RESOURCE_PORT_16_BIT_DECODE
|
465 CM_RESOURCE_PORT_POSITIVE_DECODE
;
467 Descriptor
->u
.Port
.Length
= Length
;
468 Descriptor
->u
.Port
.Alignment
= 1;
469 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
470 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
474 Descriptor
->Type
= CmResourceTypeMemory
;
475 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
476 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
478 Descriptor
->u
.Memory
.Length
= Length
;
479 Descriptor
->u
.Memory
.Alignment
= 1;
480 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
481 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
485 /* Set alternative descriptor */
486 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
487 if (Flags
& PCI_ADDRESS_IO_SPACE
)
489 Descriptor
->Type
= CmResourceTypePort
;
490 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
491 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
492 CM_RESOURCE_PORT_16_BIT_DECODE
|
493 CM_RESOURCE_PORT_POSITIVE_DECODE
;
495 Descriptor
->u
.Port
.Length
= Length
;
496 Descriptor
->u
.Port
.Alignment
= Length
;
497 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
498 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
502 Descriptor
->Type
= CmResourceTypeMemory
;
503 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
504 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
506 Descriptor
->u
.Memory
.Length
= Length
;
507 Descriptor
->u
.Memory
.Alignment
= Length
;
508 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
509 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
514 /* FIXME: Check ROM address */
516 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
518 Descriptor
->Option
= 0; /* Required */
519 Descriptor
->Type
= CmResourceTypeInterrupt
;
520 Descriptor
->ShareDisposition
= CmResourceShareShared
;
521 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
523 Descriptor
->u
.Interrupt
.MinimumVector
= 0;
524 Descriptor
->u
.Interrupt
.MaximumVector
= 0xFF;
527 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
529 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
531 if (!PdoGetRangeLength(DeviceExtension
,
537 DPRINT1("PdoGetRangeLength() failed\n");
543 DPRINT("Unused address register\n");
547 /* Set preferred descriptor */
548 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
549 if (Flags
& PCI_ADDRESS_IO_SPACE
)
551 Descriptor
->Type
= CmResourceTypePort
;
552 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
553 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
554 CM_RESOURCE_PORT_16_BIT_DECODE
|
555 CM_RESOURCE_PORT_POSITIVE_DECODE
;
557 Descriptor
->u
.Port
.Length
= Length
;
558 Descriptor
->u
.Port
.Alignment
= 1;
559 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
560 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
564 Descriptor
->Type
= CmResourceTypeMemory
;
565 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
566 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
568 Descriptor
->u
.Memory
.Length
= Length
;
569 Descriptor
->u
.Memory
.Alignment
= 1;
570 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
571 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
575 /* Set alternative descriptor */
576 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
577 if (Flags
& PCI_ADDRESS_IO_SPACE
)
579 Descriptor
->Type
= CmResourceTypePort
;
580 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
581 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
582 CM_RESOURCE_PORT_16_BIT_DECODE
|
583 CM_RESOURCE_PORT_POSITIVE_DECODE
;
585 Descriptor
->u
.Port
.Length
= Length
;
586 Descriptor
->u
.Port
.Alignment
= Length
;
587 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
588 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
592 Descriptor
->Type
= CmResourceTypeMemory
;
593 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
594 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
596 Descriptor
->u
.Memory
.Length
= Length
;
597 Descriptor
->u
.Memory
.Alignment
= Length
;
598 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
599 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
603 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
605 Descriptor
->Option
= 0; /* Required */
606 Descriptor
->Type
= CmResourceTypeBusNumber
;
607 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
609 ResourceList
->BusNumber
=
610 Descriptor
->u
.BusNumber
.MinBusNumber
=
611 Descriptor
->u
.BusNumber
.MaxBusNumber
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
612 Descriptor
->u
.BusNumber
.Length
= 1;
613 Descriptor
->u
.BusNumber
.Reserved
= 0;
616 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
618 /* FIXME: Add Cardbus bridge resources */
621 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
623 return STATUS_SUCCESS
;
629 IN PDEVICE_OBJECT DeviceObject
,
631 PIO_STACK_LOCATION IrpSp
)
633 PPDO_DEVICE_EXTENSION DeviceExtension
;
634 PCI_COMMON_CONFIG PciConfig
;
635 PCM_RESOURCE_LIST ResourceList
;
636 PCM_PARTIAL_RESOURCE_LIST PartialList
;
637 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
646 DPRINT("PdoQueryResources() called\n");
648 UNREFERENCED_PARAMETER(IrpSp
);
649 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
651 /* Get PCI configuration space */
652 Size
= HalGetBusData(PCIConfiguration
,
653 DeviceExtension
->PciDevice
->BusNumber
,
654 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
656 PCI_COMMON_HDR_LENGTH
);
657 DPRINT("Size %lu\n", Size
);
658 if (Size
< PCI_COMMON_HDR_LENGTH
)
660 Irp
->IoStatus
.Information
= 0;
661 return STATUS_UNSUCCESSFUL
;
664 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
666 /* Count required resource descriptors */
668 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
670 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
672 if (!PdoGetRangeLength(DeviceExtension
,
683 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
684 (PciConfig
.u
.type0
.InterruptLine
!= 0) &&
685 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
688 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
690 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
692 if (!PdoGetRangeLength(DeviceExtension
,
702 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
705 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
707 /* FIXME: Count Cardbus bridge resources */
711 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
716 Irp
->IoStatus
.Information
= 0;
717 return STATUS_SUCCESS
;
720 /* Calculate the resource list size */
721 ListSize
= FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.PartialDescriptors
)
722 + ResCount
* sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
724 /* Allocate the resource list */
725 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
727 if (ResourceList
== NULL
)
728 return STATUS_INSUFFICIENT_RESOURCES
;
730 RtlZeroMemory(ResourceList
, ListSize
);
731 ResourceList
->Count
= 1;
732 ResourceList
->List
[0].InterfaceType
= PCIBus
;
733 ResourceList
->List
[0].BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
735 PartialList
= &ResourceList
->List
[0].PartialResourceList
;
736 PartialList
->Version
= 1;
737 PartialList
->Revision
= 1;
738 PartialList
->Count
= ResCount
;
740 Descriptor
= &PartialList
->PartialDescriptors
[0];
741 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
743 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
745 if (!PdoGetRangeLength(DeviceExtension
,
751 DPRINT1("PdoGetRangeLength() failed\n");
757 DPRINT("Unused address register\n");
761 if (Flags
& PCI_ADDRESS_IO_SPACE
)
763 Descriptor
->Type
= CmResourceTypePort
;
764 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
765 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
766 Descriptor
->u
.Port
.Start
.QuadPart
=
768 Descriptor
->u
.Port
.Length
= Length
;
772 Descriptor
->Type
= CmResourceTypeMemory
;
773 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
774 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
775 Descriptor
->u
.Memory
.Start
.QuadPart
=
777 Descriptor
->u
.Memory
.Length
= Length
;
783 /* Add interrupt resource */
784 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
785 (PciConfig
.u
.type0
.InterruptLine
!= 0) &&
786 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
788 Descriptor
->Type
= CmResourceTypeInterrupt
;
789 Descriptor
->ShareDisposition
= CmResourceShareShared
;
790 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
791 Descriptor
->u
.Interrupt
.Level
= PciConfig
.u
.type0
.InterruptLine
;
792 Descriptor
->u
.Interrupt
.Vector
= PciConfig
.u
.type0
.InterruptLine
;
793 Descriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
796 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
798 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
800 if (!PdoGetRangeLength(DeviceExtension
,
806 DPRINT1("PdoGetRangeLength() failed\n");
812 DPRINT("Unused address register\n");
816 if (Flags
& PCI_ADDRESS_IO_SPACE
)
818 Descriptor
->Type
= CmResourceTypePort
;
819 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
820 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
821 Descriptor
->u
.Port
.Start
.QuadPart
=
823 Descriptor
->u
.Port
.Length
= Length
;
827 Descriptor
->Type
= CmResourceTypeMemory
;
828 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
829 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
830 Descriptor
->u
.Memory
.Start
.QuadPart
=
832 Descriptor
->u
.Memory
.Length
= Length
;
837 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
839 Descriptor
->Type
= CmResourceTypeBusNumber
;
840 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
842 ResourceList
->List
[0].BusNumber
=
843 Descriptor
->u
.BusNumber
.Start
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
844 Descriptor
->u
.BusNumber
.Length
= 1;
845 Descriptor
->u
.BusNumber
.Reserved
= 0;
848 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
850 /* FIXME: Add Cardbus bridge resources */
853 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
855 return STATUS_SUCCESS
;
863 PPDO_DEVICE_EXTENSION DeviceExtension
;
865 DPRINT("InterfaceReference(%p)\n", Context
);
867 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
868 InterlockedIncrement(&DeviceExtension
->References
);
873 InterfaceDereference(
876 PPDO_DEVICE_EXTENSION DeviceExtension
;
878 DPRINT("InterfaceDereference(%p)\n", Context
);
880 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
881 InterlockedDecrement(&DeviceExtension
->References
);
886 InterfaceBusTranslateBusAddress(
888 IN PHYSICAL_ADDRESS BusAddress
,
890 IN OUT PULONG AddressSpace
,
891 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
893 PPDO_DEVICE_EXTENSION DeviceExtension
;
895 DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
896 Context
, BusAddress
, Length
, AddressSpace
, TranslatedAddress
);
898 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
900 return HalTranslateBusAddress(
901 PCIBus
, DeviceExtension
->PciDevice
->BusNumber
,
902 BusAddress
, AddressSpace
, TranslatedAddress
);
906 static PDMA_ADAPTER NTAPI
907 InterfaceBusGetDmaAdapter(
909 IN PDEVICE_DESCRIPTION DeviceDescription
,
910 OUT PULONG NumberOfMapRegisters
)
912 DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
913 Context
, DeviceDescription
, NumberOfMapRegisters
);
914 return (PDMA_ADAPTER
)HalGetAdapter(DeviceDescription
, NumberOfMapRegisters
);
919 InterfaceBusSetBusData(
926 PPDO_DEVICE_EXTENSION DeviceExtension
;
929 DPRINT("InterfaceBusSetBusData(%p 0x%lx %p 0x%lx 0x%lx)\n",
930 Context
, DataType
, Buffer
, Offset
, Length
);
932 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
934 DPRINT("Unknown DataType %lu\n", DataType
);
938 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
940 /* Get PCI configuration space */
941 Size
= HalSetBusDataByOffset(PCIConfiguration
,
942 DeviceExtension
->PciDevice
->BusNumber
,
943 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
952 InterfaceBusGetBusData(
959 PPDO_DEVICE_EXTENSION DeviceExtension
;
962 DPRINT("InterfaceBusGetBusData(%p 0x%lx %p 0x%lx 0x%lx) called\n",
963 Context
, DataType
, Buffer
, Offset
, Length
);
965 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
967 DPRINT("Unknown DataType %lu\n", DataType
);
971 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
973 /* Get PCI configuration space */
974 Size
= HalGetBusDataByOffset(PCIConfiguration
,
975 DeviceExtension
->PciDevice
->BusNumber
,
976 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
985 InterfacePciDevicePresent(
989 IN USHORT SubVendorID
,
990 IN USHORT SubSystemID
,
993 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
994 PPCI_DEVICE PciDevice
;
995 PLIST_ENTRY CurrentBus
, CurrentEntry
;
997 BOOLEAN Found
= FALSE
;
999 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1000 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1001 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1003 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1005 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1006 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1007 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1009 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1010 if (PciDevice
->PciConfig
.VendorID
== VendorID
&&
1011 PciDevice
->PciConfig
.DeviceID
== DeviceID
)
1013 if (!(Flags
& PCI_USE_SUBSYSTEM_IDS
) || (
1014 PciDevice
->PciConfig
.u
.type0
.SubVendorID
== SubVendorID
&&
1015 PciDevice
->PciConfig
.u
.type0
.SubSystemID
== SubSystemID
))
1017 if (!(Flags
& PCI_USE_REVISION
) ||
1018 PciDevice
->PciConfig
.RevisionID
== RevisionID
)
1020 DPRINT("Found the PCI device\n");
1026 CurrentEntry
= CurrentEntry
->Flink
;
1029 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1030 CurrentBus
= CurrentBus
->Flink
;
1032 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1040 IN PPCI_COMMON_CONFIG PciConfig
,
1041 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1043 if ((Parameters
->Flags
& PCI_USE_VENDEV_IDS
) && (
1044 PciConfig
->VendorID
!= Parameters
->VendorID
||
1045 PciConfig
->DeviceID
!= Parameters
->DeviceID
))
1049 if ((Parameters
->Flags
& PCI_USE_CLASS_SUBCLASS
) && (
1050 PciConfig
->BaseClass
!= Parameters
->BaseClass
||
1051 PciConfig
->SubClass
!= Parameters
->SubClass
))
1055 if ((Parameters
->Flags
& PCI_USE_PROGIF
) &&
1056 PciConfig
->ProgIf
!= Parameters
->ProgIf
)
1060 if ((Parameters
->Flags
& PCI_USE_SUBSYSTEM_IDS
) && (
1061 PciConfig
->u
.type0
.SubVendorID
!= Parameters
->SubVendorID
||
1062 PciConfig
->u
.type0
.SubSystemID
!= Parameters
->SubSystemID
))
1066 if ((Parameters
->Flags
& PCI_USE_REVISION
) &&
1067 PciConfig
->RevisionID
!= Parameters
->RevisionID
)
1075 static BOOLEAN NTAPI
1076 InterfacePciDevicePresentEx(
1078 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1080 PPDO_DEVICE_EXTENSION DeviceExtension
;
1081 PFDO_DEVICE_EXTENSION MyFdoDeviceExtension
;
1082 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1083 PPCI_DEVICE PciDevice
;
1084 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1086 BOOLEAN Found
= FALSE
;
1088 DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
1089 Context
, Parameters
);
1091 if (!Parameters
|| Parameters
->Size
!= sizeof(PCI_DEVICE_PRESENCE_PARAMETERS
))
1094 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1095 MyFdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
1097 if (Parameters
->Flags
& PCI_USE_LOCAL_DEVICE
)
1099 return CheckPciDevice(&DeviceExtension
->PciDevice
->PciConfig
, Parameters
);
1102 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1103 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1104 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1106 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1107 if (!(Parameters
->Flags
& PCI_USE_LOCAL_BUS
) || FdoDeviceExtension
== MyFdoDeviceExtension
)
1109 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1110 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1111 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1113 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1115 if (CheckPciDevice(&PciDevice
->PciConfig
, Parameters
))
1117 DPRINT("Found the PCI device\n");
1121 CurrentEntry
= CurrentEntry
->Flink
;
1124 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1126 CurrentBus
= CurrentBus
->Flink
;
1128 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1136 IN PDEVICE_OBJECT DeviceObject
,
1138 PIO_STACK_LOCATION IrpSp
)
1142 UNREFERENCED_PARAMETER(Irp
);
1143 if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1144 &GUID_BUS_INTERFACE_STANDARD
, sizeof(GUID
)) == sizeof(GUID
))
1146 /* BUS_INTERFACE_STANDARD */
1147 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1148 Status
= STATUS_NOT_SUPPORTED
;
1149 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(BUS_INTERFACE_STANDARD
))
1150 Status
= STATUS_BUFFER_TOO_SMALL
;
1153 PBUS_INTERFACE_STANDARD BusInterface
;
1154 BusInterface
= (PBUS_INTERFACE_STANDARD
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1155 BusInterface
->Size
= sizeof(BUS_INTERFACE_STANDARD
);
1156 BusInterface
->Version
= 1;
1157 BusInterface
->TranslateBusAddress
= InterfaceBusTranslateBusAddress
;
1158 BusInterface
->GetDmaAdapter
= InterfaceBusGetDmaAdapter
;
1159 BusInterface
->SetBusData
= InterfaceBusSetBusData
;
1160 BusInterface
->GetBusData
= InterfaceBusGetBusData
;
1161 Status
= STATUS_SUCCESS
;
1164 else if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1165 &GUID_PCI_DEVICE_PRESENT_INTERFACE
, sizeof(GUID
)) == sizeof(GUID
))
1167 /* PCI_DEVICE_PRESENT_INTERFACE */
1168 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1169 Status
= STATUS_NOT_SUPPORTED
;
1170 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(PCI_DEVICE_PRESENT_INTERFACE
))
1171 Status
= STATUS_BUFFER_TOO_SMALL
;
1174 PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface
;
1175 PciDevicePresentInterface
= (PPCI_DEVICE_PRESENT_INTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1176 PciDevicePresentInterface
->Size
= sizeof(PCI_DEVICE_PRESENT_INTERFACE
);
1177 PciDevicePresentInterface
->Version
= 1;
1178 PciDevicePresentInterface
->IsDevicePresent
= InterfacePciDevicePresent
;
1179 PciDevicePresentInterface
->IsDevicePresentEx
= InterfacePciDevicePresentEx
;
1180 Status
= STATUS_SUCCESS
;
1185 /* Not a supported interface */
1186 return STATUS_NOT_SUPPORTED
;
1189 if (NT_SUCCESS(Status
))
1191 /* Add a reference for the returned interface */
1192 PINTERFACE Interface
;
1193 Interface
= (PINTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1194 Interface
->Context
= DeviceObject
;
1195 Interface
->InterfaceReference
= InterfaceReference
;
1196 Interface
->InterfaceDereference
= InterfaceDereference
;
1197 Interface
->InterfaceReference(Interface
->Context
);
1205 IN PDEVICE_OBJECT DeviceObject
,
1207 PIO_STACK_LOCATION IrpSp
)
1209 PCM_RESOURCE_LIST RawResList
= IrpSp
->Parameters
.StartDevice
.AllocatedResources
;
1210 PCM_FULL_RESOURCE_DESCRIPTOR RawFullDesc
;
1211 PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDesc
;
1213 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1217 return STATUS_SUCCESS
;
1219 /* TODO: Assign the other resources we get to the card */
1221 for (i
= 0; i
< RawResList
->Count
; i
++)
1223 RawFullDesc
= &RawResList
->List
[i
];
1225 for (ii
= 0; ii
< RawFullDesc
->PartialResourceList
.Count
; ii
++)
1227 RawPartialDesc
= &RawFullDesc
->PartialResourceList
.PartialDescriptors
[ii
];
1229 if (RawPartialDesc
->Type
== CmResourceTypeInterrupt
)
1231 DPRINT1("Assigning IRQ %x to PCI device (%x, %x)\n",
1232 RawPartialDesc
->u
.Interrupt
.Vector
,
1233 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1234 DeviceExtension
->PciDevice
->BusNumber
);
1236 Irq
= (UCHAR
)RawPartialDesc
->u
.Interrupt
.Vector
;
1237 HalSetBusDataByOffset(PCIConfiguration
,
1238 DeviceExtension
->PciDevice
->BusNumber
,
1239 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1241 0x3c /* PCI_INTERRUPT_LINE */,
1247 return STATUS_SUCCESS
;
1252 IN PDEVICE_OBJECT DeviceObject
,
1254 PIO_STACK_LOCATION IrpSp
)
1258 DPRINT("PdoReadConfig() called\n");
1260 Size
= InterfaceBusGetBusData(
1262 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1263 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1264 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1265 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1267 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1269 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1270 Irp
->IoStatus
.Information
= 0;
1271 return STATUS_UNSUCCESSFUL
;
1274 Irp
->IoStatus
.Information
= Size
;
1276 return STATUS_SUCCESS
;
1282 IN PDEVICE_OBJECT DeviceObject
,
1284 PIO_STACK_LOCATION IrpSp
)
1288 DPRINT1("PdoWriteConfig() called\n");
1290 /* Get PCI configuration space */
1291 Size
= InterfaceBusSetBusData(
1293 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1294 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1295 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1296 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1298 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1300 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1301 Irp
->IoStatus
.Information
= 0;
1302 return STATUS_UNSUCCESSFUL
;
1305 Irp
->IoStatus
.Information
= Size
;
1307 return STATUS_SUCCESS
;
1311 PdoQueryDeviceRelations(
1312 IN PDEVICE_OBJECT DeviceObject
,
1314 PIO_STACK_LOCATION IrpSp
)
1316 PDEVICE_RELATIONS DeviceRelations
;
1318 /* We only support TargetDeviceRelation for child PDOs */
1319 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
1320 return Irp
->IoStatus
.Status
;
1322 /* We can do this because we only return 1 PDO for TargetDeviceRelation */
1323 DeviceRelations
= ExAllocatePool(PagedPool
, sizeof(*DeviceRelations
));
1324 if (!DeviceRelations
)
1325 return STATUS_INSUFFICIENT_RESOURCES
;
1327 DeviceRelations
->Count
= 1;
1328 DeviceRelations
->Objects
[0] = DeviceObject
;
1330 /* The PnP manager will remove this when it is done with the PDO */
1331 ObReferenceObject(DeviceObject
);
1333 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1335 return STATUS_SUCCESS
;
1340 IN PDEVICE_OBJECT DeviceObject
,
1342 PIO_STACK_LOCATION IrpSp
)
1346 UNREFERENCED_PARAMETER(Irp
);
1349 if (IrpSp
->Parameters
.Power
.Type
== DevicePowerState
) {
1350 Status
= STATUS_SUCCESS
;
1351 switch (IrpSp
->Parameters
.Power
.State
.SystemState
) {
1353 Status
= STATUS_UNSUCCESSFUL
;
1356 Status
= STATUS_UNSUCCESSFUL
;
1363 /*** PUBLIC ******************************************************************/
1367 PDEVICE_OBJECT DeviceObject
,
1370 * FUNCTION: Handle Plug and Play IRPs for the child device
1372 * DeviceObject = Pointer to physical device object of the child device
1373 * Irp = Pointer to IRP that should be handled
1378 PIO_STACK_LOCATION IrpSp
;
1383 Status
= Irp
->IoStatus
.Status
;
1385 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1387 switch (IrpSp
->MinorFunction
) {
1389 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1390 DPRINT("Unimplemented IRP_MN_DEVICE_USAGE_NOTIFICATION received\n");
1394 DPRINT("Unimplemented IRP_MN_EJECT received\n");
1397 case IRP_MN_QUERY_BUS_INFORMATION
:
1398 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
1401 case IRP_MN_QUERY_CAPABILITIES
:
1402 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
1405 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1406 Status
= PdoQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
1409 case IRP_MN_QUERY_DEVICE_TEXT
:
1410 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
1411 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
1414 case IRP_MN_QUERY_ID
:
1415 DPRINT("IRP_MN_QUERY_ID received\n");
1416 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
1419 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1420 DPRINT("Unimplemented IRP_MN_QUERY_ID received\n");
1423 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1424 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
1425 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
1428 case IRP_MN_QUERY_RESOURCES
:
1429 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
1430 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
1433 case IRP_MN_SET_LOCK
:
1434 DPRINT("Unimplemented IRP_MN_SET_LOCK received\n");
1437 case IRP_MN_START_DEVICE
:
1438 Status
= PdoStartDevice(DeviceObject
, Irp
, IrpSp
);
1441 case IRP_MN_QUERY_STOP_DEVICE
:
1442 case IRP_MN_CANCEL_STOP_DEVICE
:
1443 case IRP_MN_STOP_DEVICE
:
1444 case IRP_MN_QUERY_REMOVE_DEVICE
:
1445 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1446 case IRP_MN_SURPRISE_REMOVAL
:
1447 Status
= STATUS_SUCCESS
;
1450 case IRP_MN_REMOVE_DEVICE
:
1452 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1453 PFDO_DEVICE_EXTENSION FdoDeviceExtension
= DeviceExtension
->Fdo
->DeviceExtension
;
1456 /* Remove it from the device list */
1457 KeAcquireSpinLock(&FdoDeviceExtension
->DeviceListLock
, &OldIrql
);
1458 RemoveEntryList(&DeviceExtension
->PciDevice
->ListEntry
);
1459 FdoDeviceExtension
->DeviceListCount
--;
1460 KeReleaseSpinLock(&FdoDeviceExtension
->DeviceListLock
, OldIrql
);
1462 /* Free the device */
1463 ExFreePool(DeviceExtension
->PciDevice
);
1465 /* Complete the IRP */
1466 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1467 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1470 IoDeleteDevice(DeviceObject
);
1471 return STATUS_SUCCESS
;
1474 case IRP_MN_QUERY_INTERFACE
:
1475 DPRINT("IRP_MN_QUERY_INTERFACE received\n");
1476 Status
= PdoQueryInterface(DeviceObject
, Irp
, IrpSp
);
1479 case IRP_MN_READ_CONFIG
:
1480 DPRINT("IRP_MN_READ_CONFIG received\n");
1481 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1484 case IRP_MN_WRITE_CONFIG
:
1485 DPRINT("IRP_MN_WRITE_CONFIG received\n");
1486 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1489 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1490 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS received\n");
1492 Irp
->IoStatus
.Status
= Status
;
1496 DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp
->MinorFunction
);
1500 if (Status
!= STATUS_PENDING
) {
1501 Irp
->IoStatus
.Status
= Status
;
1502 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1505 DPRINT("Leaving. Status 0x%X\n", Status
);
1512 PDEVICE_OBJECT DeviceObject
,
1515 * FUNCTION: Handle power management IRPs for the child device
1517 * DeviceObject = Pointer to physical device object of the child device
1518 * Irp = Pointer to IRP that should be handled
1523 PIO_STACK_LOCATION IrpSp
;
1528 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1530 switch (IrpSp
->MinorFunction
) {
1531 case IRP_MN_SET_POWER
:
1532 Status
= PdoSetPower(DeviceObject
, Irp
, IrpSp
);
1536 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1537 Status
= STATUS_NOT_IMPLEMENTED
;
1541 if (Status
!= STATUS_PENDING
) {
1542 Irp
->IoStatus
.Status
= Status
;
1543 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1546 DPRINT("Leaving. Status 0x%X\n", Status
);