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
;
770 /* Enable IO space access */
771 DeviceExtension
->PciDevice
->EnableIoSpace
= TRUE
;
775 Descriptor
->Type
= CmResourceTypeMemory
;
776 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
777 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
778 Descriptor
->u
.Memory
.Start
.QuadPart
=
780 Descriptor
->u
.Memory
.Length
= Length
;
782 /* Enable memory space access */
783 DeviceExtension
->PciDevice
->EnableMemorySpace
= TRUE
;
789 /* Add interrupt resource */
790 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
791 (PciConfig
.u
.type0
.InterruptLine
!= 0) &&
792 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
794 Descriptor
->Type
= CmResourceTypeInterrupt
;
795 Descriptor
->ShareDisposition
= CmResourceShareShared
;
796 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
797 Descriptor
->u
.Interrupt
.Level
= PciConfig
.u
.type0
.InterruptLine
;
798 Descriptor
->u
.Interrupt
.Vector
= PciConfig
.u
.type0
.InterruptLine
;
799 Descriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
802 /* Allow bus master mode */
803 DeviceExtension
->PciDevice
->EnableBusMaster
= TRUE
;
805 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
807 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
809 if (!PdoGetRangeLength(DeviceExtension
,
815 DPRINT1("PdoGetRangeLength() failed\n");
821 DPRINT("Unused address register\n");
825 if (Flags
& PCI_ADDRESS_IO_SPACE
)
827 Descriptor
->Type
= CmResourceTypePort
;
828 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
829 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
830 Descriptor
->u
.Port
.Start
.QuadPart
=
832 Descriptor
->u
.Port
.Length
= Length
;
834 /* Enable IO space access */
835 DeviceExtension
->PciDevice
->EnableIoSpace
= TRUE
;
839 Descriptor
->Type
= CmResourceTypeMemory
;
840 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
841 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
842 Descriptor
->u
.Memory
.Start
.QuadPart
=
844 Descriptor
->u
.Memory
.Length
= Length
;
846 /* Enable memory space access */
847 DeviceExtension
->PciDevice
->EnableMemorySpace
= TRUE
;
852 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
854 Descriptor
->Type
= CmResourceTypeBusNumber
;
855 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
857 ResourceList
->List
[0].BusNumber
=
858 Descriptor
->u
.BusNumber
.Start
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
859 Descriptor
->u
.BusNumber
.Length
= 1;
860 Descriptor
->u
.BusNumber
.Reserved
= 0;
863 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
865 /* FIXME: Add Cardbus bridge resources */
868 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
870 return STATUS_SUCCESS
;
878 PPDO_DEVICE_EXTENSION DeviceExtension
;
880 DPRINT("InterfaceReference(%p)\n", Context
);
882 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
883 InterlockedIncrement(&DeviceExtension
->References
);
888 InterfaceDereference(
891 PPDO_DEVICE_EXTENSION DeviceExtension
;
893 DPRINT("InterfaceDereference(%p)\n", Context
);
895 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
896 InterlockedDecrement(&DeviceExtension
->References
);
901 InterfaceBusTranslateBusAddress(
903 IN PHYSICAL_ADDRESS BusAddress
,
905 IN OUT PULONG AddressSpace
,
906 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
908 PPDO_DEVICE_EXTENSION DeviceExtension
;
910 DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
911 Context
, BusAddress
, Length
, AddressSpace
, TranslatedAddress
);
913 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
915 return HalTranslateBusAddress(
916 PCIBus
, DeviceExtension
->PciDevice
->BusNumber
,
917 BusAddress
, AddressSpace
, TranslatedAddress
);
921 static PDMA_ADAPTER NTAPI
922 InterfaceBusGetDmaAdapter(
924 IN PDEVICE_DESCRIPTION DeviceDescription
,
925 OUT PULONG NumberOfMapRegisters
)
927 DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
928 Context
, DeviceDescription
, NumberOfMapRegisters
);
929 return (PDMA_ADAPTER
)HalGetAdapter(DeviceDescription
, NumberOfMapRegisters
);
934 InterfaceBusSetBusData(
941 PPDO_DEVICE_EXTENSION DeviceExtension
;
944 DPRINT("InterfaceBusSetBusData(%p 0x%lx %p 0x%lx 0x%lx)\n",
945 Context
, DataType
, Buffer
, Offset
, Length
);
947 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
949 DPRINT("Unknown DataType %lu\n", DataType
);
953 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
955 /* Get PCI configuration space */
956 Size
= HalSetBusDataByOffset(PCIConfiguration
,
957 DeviceExtension
->PciDevice
->BusNumber
,
958 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
967 InterfaceBusGetBusData(
974 PPDO_DEVICE_EXTENSION DeviceExtension
;
977 DPRINT("InterfaceBusGetBusData(%p 0x%lx %p 0x%lx 0x%lx) called\n",
978 Context
, DataType
, Buffer
, Offset
, Length
);
980 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
982 DPRINT("Unknown DataType %lu\n", DataType
);
986 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
988 /* Get PCI configuration space */
989 Size
= HalGetBusDataByOffset(PCIConfiguration
,
990 DeviceExtension
->PciDevice
->BusNumber
,
991 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1000 InterfacePciDevicePresent(
1003 IN UCHAR RevisionID
,
1004 IN USHORT SubVendorID
,
1005 IN USHORT SubSystemID
,
1008 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1009 PPCI_DEVICE PciDevice
;
1010 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1012 BOOLEAN Found
= FALSE
;
1014 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1015 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1016 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1018 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1020 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1021 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1022 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1024 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1025 if (PciDevice
->PciConfig
.VendorID
== VendorID
&&
1026 PciDevice
->PciConfig
.DeviceID
== DeviceID
)
1028 if (!(Flags
& PCI_USE_SUBSYSTEM_IDS
) || (
1029 PciDevice
->PciConfig
.u
.type0
.SubVendorID
== SubVendorID
&&
1030 PciDevice
->PciConfig
.u
.type0
.SubSystemID
== SubSystemID
))
1032 if (!(Flags
& PCI_USE_REVISION
) ||
1033 PciDevice
->PciConfig
.RevisionID
== RevisionID
)
1035 DPRINT("Found the PCI device\n");
1041 CurrentEntry
= CurrentEntry
->Flink
;
1044 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1045 CurrentBus
= CurrentBus
->Flink
;
1047 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1055 IN PPCI_COMMON_CONFIG PciConfig
,
1056 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1058 if ((Parameters
->Flags
& PCI_USE_VENDEV_IDS
) && (
1059 PciConfig
->VendorID
!= Parameters
->VendorID
||
1060 PciConfig
->DeviceID
!= Parameters
->DeviceID
))
1064 if ((Parameters
->Flags
& PCI_USE_CLASS_SUBCLASS
) && (
1065 PciConfig
->BaseClass
!= Parameters
->BaseClass
||
1066 PciConfig
->SubClass
!= Parameters
->SubClass
))
1070 if ((Parameters
->Flags
& PCI_USE_PROGIF
) &&
1071 PciConfig
->ProgIf
!= Parameters
->ProgIf
)
1075 if ((Parameters
->Flags
& PCI_USE_SUBSYSTEM_IDS
) && (
1076 PciConfig
->u
.type0
.SubVendorID
!= Parameters
->SubVendorID
||
1077 PciConfig
->u
.type0
.SubSystemID
!= Parameters
->SubSystemID
))
1081 if ((Parameters
->Flags
& PCI_USE_REVISION
) &&
1082 PciConfig
->RevisionID
!= Parameters
->RevisionID
)
1090 static BOOLEAN NTAPI
1091 InterfacePciDevicePresentEx(
1093 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1095 PPDO_DEVICE_EXTENSION DeviceExtension
;
1096 PFDO_DEVICE_EXTENSION MyFdoDeviceExtension
;
1097 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1098 PPCI_DEVICE PciDevice
;
1099 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1101 BOOLEAN Found
= FALSE
;
1103 DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
1104 Context
, Parameters
);
1106 if (!Parameters
|| Parameters
->Size
!= sizeof(PCI_DEVICE_PRESENCE_PARAMETERS
))
1109 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1110 MyFdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
1112 if (Parameters
->Flags
& PCI_USE_LOCAL_DEVICE
)
1114 return CheckPciDevice(&DeviceExtension
->PciDevice
->PciConfig
, Parameters
);
1117 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1118 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1119 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1121 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1122 if (!(Parameters
->Flags
& PCI_USE_LOCAL_BUS
) || FdoDeviceExtension
== MyFdoDeviceExtension
)
1124 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1125 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1126 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1128 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1130 if (CheckPciDevice(&PciDevice
->PciConfig
, Parameters
))
1132 DPRINT("Found the PCI device\n");
1136 CurrentEntry
= CurrentEntry
->Flink
;
1139 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1141 CurrentBus
= CurrentBus
->Flink
;
1143 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1151 IN PDEVICE_OBJECT DeviceObject
,
1153 PIO_STACK_LOCATION IrpSp
)
1157 UNREFERENCED_PARAMETER(Irp
);
1158 if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1159 &GUID_BUS_INTERFACE_STANDARD
, sizeof(GUID
)) == sizeof(GUID
))
1161 /* BUS_INTERFACE_STANDARD */
1162 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1163 Status
= STATUS_NOT_SUPPORTED
;
1164 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(BUS_INTERFACE_STANDARD
))
1165 Status
= STATUS_BUFFER_TOO_SMALL
;
1168 PBUS_INTERFACE_STANDARD BusInterface
;
1169 BusInterface
= (PBUS_INTERFACE_STANDARD
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1170 BusInterface
->Size
= sizeof(BUS_INTERFACE_STANDARD
);
1171 BusInterface
->Version
= 1;
1172 BusInterface
->TranslateBusAddress
= InterfaceBusTranslateBusAddress
;
1173 BusInterface
->GetDmaAdapter
= InterfaceBusGetDmaAdapter
;
1174 BusInterface
->SetBusData
= InterfaceBusSetBusData
;
1175 BusInterface
->GetBusData
= InterfaceBusGetBusData
;
1176 Status
= STATUS_SUCCESS
;
1179 else if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1180 &GUID_PCI_DEVICE_PRESENT_INTERFACE
, sizeof(GUID
)) == sizeof(GUID
))
1182 /* PCI_DEVICE_PRESENT_INTERFACE */
1183 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1184 Status
= STATUS_NOT_SUPPORTED
;
1185 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(PCI_DEVICE_PRESENT_INTERFACE
))
1186 Status
= STATUS_BUFFER_TOO_SMALL
;
1189 PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface
;
1190 PciDevicePresentInterface
= (PPCI_DEVICE_PRESENT_INTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1191 PciDevicePresentInterface
->Size
= sizeof(PCI_DEVICE_PRESENT_INTERFACE
);
1192 PciDevicePresentInterface
->Version
= 1;
1193 PciDevicePresentInterface
->IsDevicePresent
= InterfacePciDevicePresent
;
1194 PciDevicePresentInterface
->IsDevicePresentEx
= InterfacePciDevicePresentEx
;
1195 Status
= STATUS_SUCCESS
;
1200 /* Not a supported interface */
1201 return STATUS_NOT_SUPPORTED
;
1204 if (NT_SUCCESS(Status
))
1206 /* Add a reference for the returned interface */
1207 PINTERFACE Interface
;
1208 Interface
= (PINTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1209 Interface
->Context
= DeviceObject
;
1210 Interface
->InterfaceReference
= InterfaceReference
;
1211 Interface
->InterfaceDereference
= InterfaceDereference
;
1212 Interface
->InterfaceReference(Interface
->Context
);
1220 IN PDEVICE_OBJECT DeviceObject
,
1222 PIO_STACK_LOCATION IrpSp
)
1224 PCM_RESOURCE_LIST RawResList
= IrpSp
->Parameters
.StartDevice
.AllocatedResources
;
1225 PCM_FULL_RESOURCE_DESCRIPTOR RawFullDesc
;
1226 PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDesc
;
1228 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1233 return STATUS_SUCCESS
;
1235 /* TODO: Assign the other resources we get to the card */
1237 for (i
= 0; i
< RawResList
->Count
; i
++)
1239 RawFullDesc
= &RawResList
->List
[i
];
1241 for (ii
= 0; ii
< RawFullDesc
->PartialResourceList
.Count
; ii
++)
1243 RawPartialDesc
= &RawFullDesc
->PartialResourceList
.PartialDescriptors
[ii
];
1245 if (RawPartialDesc
->Type
== CmResourceTypeInterrupt
)
1247 DPRINT1("Assigning IRQ %d to PCI device 0x%x on bus 0x%x\n",
1248 RawPartialDesc
->u
.Interrupt
.Vector
,
1249 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1250 DeviceExtension
->PciDevice
->BusNumber
);
1252 Irq
= (UCHAR
)RawPartialDesc
->u
.Interrupt
.Vector
;
1253 HalSetBusDataByOffset(PCIConfiguration
,
1254 DeviceExtension
->PciDevice
->BusNumber
,
1255 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1257 0x3c /* PCI_INTERRUPT_LINE */,
1265 DPRINT1("Enabling command flags for PCI device 0x%x on bus 0x%x: ",
1266 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1267 DeviceExtension
->PciDevice
->BusNumber
);
1268 if (DeviceExtension
->PciDevice
->EnableBusMaster
)
1270 Command
|= PCI_ENABLE_BUS_MASTER
;
1271 DbgPrint("[Bus master] ");
1274 if (DeviceExtension
->PciDevice
->EnableMemorySpace
)
1276 Command
|= PCI_ENABLE_MEMORY_SPACE
;
1277 DbgPrint("[Memory space enable] ");
1280 if (DeviceExtension
->PciDevice
->EnableIoSpace
)
1282 Command
|= PCI_ENABLE_IO_SPACE
;
1283 DbgPrint("[I/O space enable] ");
1290 /* OR with the previous value */
1291 Command
|= DeviceExtension
->PciDevice
->PciConfig
.Command
;
1293 HalSetBusDataByOffset(PCIConfiguration
,
1294 DeviceExtension
->PciDevice
->BusNumber
,
1295 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1297 FIELD_OFFSET(PCI_COMMON_CONFIG
, Command
),
1305 return STATUS_SUCCESS
;
1310 IN PDEVICE_OBJECT DeviceObject
,
1312 PIO_STACK_LOCATION IrpSp
)
1316 DPRINT("PdoReadConfig() called\n");
1318 Size
= InterfaceBusGetBusData(
1320 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1321 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1322 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1323 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1325 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1327 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1328 Irp
->IoStatus
.Information
= 0;
1329 return STATUS_UNSUCCESSFUL
;
1332 Irp
->IoStatus
.Information
= Size
;
1334 return STATUS_SUCCESS
;
1340 IN PDEVICE_OBJECT DeviceObject
,
1342 PIO_STACK_LOCATION IrpSp
)
1346 DPRINT1("PdoWriteConfig() called\n");
1348 /* Get PCI configuration space */
1349 Size
= InterfaceBusSetBusData(
1351 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1352 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1353 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1354 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1356 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1358 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1359 Irp
->IoStatus
.Information
= 0;
1360 return STATUS_UNSUCCESSFUL
;
1363 Irp
->IoStatus
.Information
= Size
;
1365 return STATUS_SUCCESS
;
1369 PdoQueryDeviceRelations(
1370 IN PDEVICE_OBJECT DeviceObject
,
1372 PIO_STACK_LOCATION IrpSp
)
1374 PDEVICE_RELATIONS DeviceRelations
;
1376 /* We only support TargetDeviceRelation for child PDOs */
1377 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
1378 return Irp
->IoStatus
.Status
;
1380 /* We can do this because we only return 1 PDO for TargetDeviceRelation */
1381 DeviceRelations
= ExAllocatePool(PagedPool
, sizeof(*DeviceRelations
));
1382 if (!DeviceRelations
)
1383 return STATUS_INSUFFICIENT_RESOURCES
;
1385 DeviceRelations
->Count
= 1;
1386 DeviceRelations
->Objects
[0] = DeviceObject
;
1388 /* The PnP manager will remove this when it is done with the PDO */
1389 ObReferenceObject(DeviceObject
);
1391 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1393 return STATUS_SUCCESS
;
1398 IN PDEVICE_OBJECT DeviceObject
,
1400 PIO_STACK_LOCATION IrpSp
)
1404 UNREFERENCED_PARAMETER(Irp
);
1407 if (IrpSp
->Parameters
.Power
.Type
== DevicePowerState
) {
1408 Status
= STATUS_SUCCESS
;
1409 switch (IrpSp
->Parameters
.Power
.State
.SystemState
) {
1411 Status
= STATUS_UNSUCCESSFUL
;
1414 Status
= STATUS_UNSUCCESSFUL
;
1421 /*** PUBLIC ******************************************************************/
1425 PDEVICE_OBJECT DeviceObject
,
1428 * FUNCTION: Handle Plug and Play IRPs for the child device
1430 * DeviceObject = Pointer to physical device object of the child device
1431 * Irp = Pointer to IRP that should be handled
1436 PIO_STACK_LOCATION IrpSp
;
1441 Status
= Irp
->IoStatus
.Status
;
1443 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1445 switch (IrpSp
->MinorFunction
) {
1447 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1448 DPRINT("Unimplemented IRP_MN_DEVICE_USAGE_NOTIFICATION received\n");
1452 DPRINT("Unimplemented IRP_MN_EJECT received\n");
1455 case IRP_MN_QUERY_BUS_INFORMATION
:
1456 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
1459 case IRP_MN_QUERY_CAPABILITIES
:
1460 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
1463 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1464 Status
= PdoQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
1467 case IRP_MN_QUERY_DEVICE_TEXT
:
1468 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
1469 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
1472 case IRP_MN_QUERY_ID
:
1473 DPRINT("IRP_MN_QUERY_ID received\n");
1474 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
1477 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1478 DPRINT("Unimplemented IRP_MN_QUERY_ID received\n");
1481 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1482 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
1483 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
1486 case IRP_MN_QUERY_RESOURCES
:
1487 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
1488 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
1491 case IRP_MN_SET_LOCK
:
1492 DPRINT("Unimplemented IRP_MN_SET_LOCK received\n");
1495 case IRP_MN_START_DEVICE
:
1496 Status
= PdoStartDevice(DeviceObject
, Irp
, IrpSp
);
1499 case IRP_MN_QUERY_STOP_DEVICE
:
1500 case IRP_MN_CANCEL_STOP_DEVICE
:
1501 case IRP_MN_STOP_DEVICE
:
1502 case IRP_MN_QUERY_REMOVE_DEVICE
:
1503 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1504 case IRP_MN_SURPRISE_REMOVAL
:
1505 Status
= STATUS_SUCCESS
;
1508 case IRP_MN_REMOVE_DEVICE
:
1510 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1511 PFDO_DEVICE_EXTENSION FdoDeviceExtension
= DeviceExtension
->Fdo
->DeviceExtension
;
1514 /* Remove it from the device list */
1515 KeAcquireSpinLock(&FdoDeviceExtension
->DeviceListLock
, &OldIrql
);
1516 RemoveEntryList(&DeviceExtension
->PciDevice
->ListEntry
);
1517 FdoDeviceExtension
->DeviceListCount
--;
1518 KeReleaseSpinLock(&FdoDeviceExtension
->DeviceListLock
, OldIrql
);
1520 /* Free the device */
1521 ExFreePool(DeviceExtension
->PciDevice
);
1523 /* Complete the IRP */
1524 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1525 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1528 IoDeleteDevice(DeviceObject
);
1529 return STATUS_SUCCESS
;
1532 case IRP_MN_QUERY_INTERFACE
:
1533 DPRINT("IRP_MN_QUERY_INTERFACE received\n");
1534 Status
= PdoQueryInterface(DeviceObject
, Irp
, IrpSp
);
1537 case IRP_MN_READ_CONFIG
:
1538 DPRINT("IRP_MN_READ_CONFIG received\n");
1539 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1542 case IRP_MN_WRITE_CONFIG
:
1543 DPRINT("IRP_MN_WRITE_CONFIG received\n");
1544 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1547 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1548 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS received\n");
1550 Irp
->IoStatus
.Status
= Status
;
1554 DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp
->MinorFunction
);
1558 if (Status
!= STATUS_PENDING
) {
1559 Irp
->IoStatus
.Status
= Status
;
1560 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1563 DPRINT("Leaving. Status 0x%X\n", Status
);
1570 PDEVICE_OBJECT DeviceObject
,
1573 * FUNCTION: Handle power management IRPs for the child device
1575 * DeviceObject = Pointer to physical device object of the child device
1576 * Irp = Pointer to IRP that should be handled
1581 PIO_STACK_LOCATION IrpSp
;
1586 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1588 switch (IrpSp
->MinorFunction
) {
1589 case IRP_MN_SET_POWER
:
1590 Status
= PdoSetPower(DeviceObject
, Irp
, IrpSp
);
1594 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1595 Status
= STATUS_NOT_IMPLEMENTED
;
1599 if (Status
!= STATUS_PENDING
) {
1600 Irp
->IoStatus
.Status
= Status
;
1601 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1604 DPRINT("Leaving. Status 0x%X\n", Status
);