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
18 /*** PRIVATE *****************************************************************/
22 IN PDEVICE_OBJECT DeviceObject
,
24 PIO_STACK_LOCATION IrpSp
)
26 PPDO_DEVICE_EXTENSION DeviceExtension
;
27 UNICODE_STRING String
;
32 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
34 switch (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
)
36 case DeviceTextDescription
:
37 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
38 &DeviceExtension
->DeviceDescription
,
41 DPRINT("DeviceTextDescription\n");
42 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
45 case DeviceTextLocationInformation
:
46 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
47 &DeviceExtension
->DeviceLocation
,
50 DPRINT("DeviceTextLocationInformation\n");
51 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
55 Irp
->IoStatus
.Information
= 0;
56 Status
= STATUS_INVALID_PARAMETER
;
66 IN PDEVICE_OBJECT DeviceObject
,
68 PIO_STACK_LOCATION IrpSp
)
70 PPDO_DEVICE_EXTENSION DeviceExtension
;
71 UNICODE_STRING String
;
76 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
78 // Irp->IoStatus.Information = 0;
80 Status
= STATUS_SUCCESS
;
82 RtlInitUnicodeString(&String
, NULL
);
84 switch (IrpSp
->Parameters
.QueryId
.IdType
)
86 case BusQueryDeviceID
:
87 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
88 &DeviceExtension
->DeviceID
,
91 DPRINT("DeviceID: %S\n", String
.Buffer
);
93 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
96 case BusQueryHardwareIDs
:
97 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
98 &DeviceExtension
->HardwareIDs
,
101 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
104 case BusQueryCompatibleIDs
:
105 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
106 &DeviceExtension
->CompatibleIDs
,
109 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
112 case BusQueryInstanceID
:
113 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
114 &DeviceExtension
->InstanceID
,
117 DPRINT("InstanceID: %S\n", String
.Buffer
);
119 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
122 case BusQueryDeviceSerialNumber
:
124 Status
= STATUS_NOT_IMPLEMENTED
;
132 PdoQueryBusInformation(
133 IN PDEVICE_OBJECT DeviceObject
,
135 PIO_STACK_LOCATION IrpSp
)
137 PPDO_DEVICE_EXTENSION DeviceExtension
;
138 PPNP_BUS_INFORMATION BusInformation
;
140 UNREFERENCED_PARAMETER(IrpSp
);
143 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
144 BusInformation
= ExAllocatePool(PagedPool
, sizeof(PNP_BUS_INFORMATION
));
145 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
146 if (BusInformation
!= NULL
)
148 BusInformation
->BusTypeGuid
= GUID_BUS_TYPE_PCI
;
149 BusInformation
->LegacyBusType
= PCIBus
;
150 BusInformation
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
152 return STATUS_SUCCESS
;
155 return STATUS_INSUFFICIENT_RESOURCES
;
160 PdoQueryCapabilities(
161 IN PDEVICE_OBJECT DeviceObject
,
163 PIO_STACK_LOCATION IrpSp
)
165 PPDO_DEVICE_EXTENSION DeviceExtension
;
166 PDEVICE_CAPABILITIES DeviceCapabilities
;
167 ULONG DeviceNumber
, FunctionNumber
;
169 UNREFERENCED_PARAMETER(Irp
);
172 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
173 DeviceCapabilities
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
175 if (DeviceCapabilities
->Version
!= 1)
176 return STATUS_UNSUCCESSFUL
;
178 DeviceNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.DeviceNumber
;
179 FunctionNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.FunctionNumber
;
181 DeviceCapabilities
->UniqueID
= FALSE
;
182 DeviceCapabilities
->Address
= ((DeviceNumber
<< 16) & 0xFFFF0000) + (FunctionNumber
& 0xFFFF);
183 DeviceCapabilities
->UINumber
= MAXULONG
; /* FIXME */
185 return STATUS_SUCCESS
;
190 PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension
,
202 /* Save original value */
203 Size
= HalGetBusDataByOffset(PCIConfiguration
,
204 DeviceExtension
->PciDevice
->BusNumber
,
205 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
209 if (Size
!= sizeof(ULONG
))
211 DPRINT1("Wrong size %lu\n", Size
);
215 BaseValue
= (OrigValue
& PCI_ADDRESS_IO_SPACE
)
216 ? (OrigValue
& PCI_ADDRESS_IO_ADDRESS_MASK
)
217 : (OrigValue
& PCI_ADDRESS_MEMORY_ADDRESS_MASK
);
221 /* Set magic value */
223 Size
= HalSetBusDataByOffset(PCIConfiguration
,
224 DeviceExtension
->PciDevice
->BusNumber
,
225 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
229 if (Size
!= sizeof(ULONG
))
231 DPRINT1("Wrong size %lu\n", Size
);
235 /* Get the range length */
236 Size
= HalGetBusDataByOffset(PCIConfiguration
,
237 DeviceExtension
->PciDevice
->BusNumber
,
238 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
242 if (Size
!= sizeof(ULONG
))
244 DPRINT1("Wrong size %lu\n", Size
);
248 /* Restore original value */
249 Size
= HalSetBusDataByOffset(PCIConfiguration
,
250 DeviceExtension
->PciDevice
->BusNumber
,
251 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
255 if (Size
!= sizeof(ULONG
))
257 DPRINT1("Wrong size %lu\n", Size
);
263 DPRINT("Unused address register\n");
270 XLength
= ~((NewValue
& PCI_ADDRESS_IO_SPACE
)
271 ? (NewValue
& PCI_ADDRESS_IO_ADDRESS_MASK
)
272 : (NewValue
& PCI_ADDRESS_MEMORY_ADDRESS_MASK
)) + 1;
275 DbgPrint("BaseAddress 0x%08lx Length 0x%08lx",
278 if (NewValue
& PCI_ADDRESS_IO_SPACE
)
280 DbgPrint(" IO range");
284 DbgPrint(" Memory range");
285 if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 0)
287 DbgPrint(" in 32-Bit address space");
289 else if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 2)
291 DbgPrint(" below 1BM ");
293 else if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 4)
295 DbgPrint(" in 64-Bit address space");
298 if (NewValue
& PCI_ADDRESS_MEMORY_PREFETCHABLE
)
300 DbgPrint(" prefetchable");
308 *Flags
= (NewValue
& PCI_ADDRESS_IO_SPACE
)
309 ? (NewValue
& ~PCI_ADDRESS_IO_ADDRESS_MASK
)
310 : (NewValue
& ~PCI_ADDRESS_MEMORY_ADDRESS_MASK
);
317 PdoQueryResourceRequirements(
318 IN PDEVICE_OBJECT DeviceObject
,
320 PIO_STACK_LOCATION IrpSp
)
322 PPDO_DEVICE_EXTENSION DeviceExtension
;
323 PCI_COMMON_CONFIG PciConfig
;
324 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
325 PIO_RESOURCE_DESCRIPTOR Descriptor
;
334 UNREFERENCED_PARAMETER(IrpSp
);
335 DPRINT("PdoQueryResourceRequirements() called\n");
337 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
339 /* Get PCI configuration space */
340 Size
= HalGetBusData(PCIConfiguration
,
341 DeviceExtension
->PciDevice
->BusNumber
,
342 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
344 PCI_COMMON_HDR_LENGTH
);
345 DPRINT("Size %lu\n", Size
);
346 if (Size
< PCI_COMMON_HDR_LENGTH
)
348 Irp
->IoStatus
.Information
= 0;
349 return STATUS_UNSUCCESSFUL
;
352 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
354 /* Count required resource descriptors */
356 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
358 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
360 if (!PdoGetRangeLength(DeviceExtension
,
371 /* FIXME: Check ROM address */
373 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
376 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
378 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
380 if (!PdoGetRangeLength(DeviceExtension
,
391 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
394 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
396 /* FIXME: Count Cardbus bridge resources */
400 DPRINT1("Unsupported header type %d\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
405 Irp
->IoStatus
.Information
= 0;
406 return STATUS_SUCCESS
;
409 /* Calculate the resource list size */
410 ListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
[0].Descriptors
) +
411 ResCount
* sizeof(IO_RESOURCE_DESCRIPTOR
);
413 DPRINT("ListSize %lu (0x%lx)\n", ListSize
, ListSize
);
415 /* Allocate the resource requirements list */
416 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;
604 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
606 Descriptor
->Option
= 0; /* Required */
607 Descriptor
->Type
= CmResourceTypeBusNumber
;
608 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
610 ResourceList
->BusNumber
=
611 Descriptor
->u
.BusNumber
.MinBusNumber
=
612 Descriptor
->u
.BusNumber
.MaxBusNumber
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
613 Descriptor
->u
.BusNumber
.Length
= 1;
614 Descriptor
->u
.BusNumber
.Reserved
= 0;
617 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
619 /* FIXME: Add Cardbus bridge resources */
622 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
624 return STATUS_SUCCESS
;
630 IN PDEVICE_OBJECT DeviceObject
,
632 PIO_STACK_LOCATION IrpSp
)
634 PPDO_DEVICE_EXTENSION DeviceExtension
;
635 PCI_COMMON_CONFIG PciConfig
;
636 PCM_RESOURCE_LIST ResourceList
;
637 PCM_PARTIAL_RESOURCE_LIST PartialList
;
638 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
647 DPRINT("PdoQueryResources() called\n");
649 UNREFERENCED_PARAMETER(IrpSp
);
650 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
652 /* Get PCI configuration space */
653 Size
= HalGetBusData(PCIConfiguration
,
654 DeviceExtension
->PciDevice
->BusNumber
,
655 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
657 PCI_COMMON_HDR_LENGTH
);
658 DPRINT("Size %lu\n", Size
);
659 if (Size
< PCI_COMMON_HDR_LENGTH
)
661 Irp
->IoStatus
.Information
= 0;
662 return STATUS_UNSUCCESSFUL
;
665 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
667 /* Count required resource descriptors */
669 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
671 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
673 if (!PdoGetRangeLength(DeviceExtension
,
684 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
685 (PciConfig
.u
.type0
.InterruptLine
!= 0) &&
686 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
689 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
691 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
693 if (!PdoGetRangeLength(DeviceExtension
,
704 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
707 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
709 /* FIXME: Count Cardbus bridge resources */
713 DPRINT1("Unsupported header type %d\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
718 Irp
->IoStatus
.Information
= 0;
719 return STATUS_SUCCESS
;
722 /* Calculate the resource list size */
723 ListSize
= FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.PartialDescriptors
) +
724 ResCount
* sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
726 /* Allocate the resource list */
727 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
730 if (ResourceList
== NULL
)
731 return STATUS_INSUFFICIENT_RESOURCES
;
733 RtlZeroMemory(ResourceList
, ListSize
);
734 ResourceList
->Count
= 1;
735 ResourceList
->List
[0].InterfaceType
= PCIBus
;
736 ResourceList
->List
[0].BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
738 PartialList
= &ResourceList
->List
[0].PartialResourceList
;
739 PartialList
->Version
= 1;
740 PartialList
->Revision
= 1;
741 PartialList
->Count
= ResCount
;
743 Descriptor
= &PartialList
->PartialDescriptors
[0];
744 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
746 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
748 if (!PdoGetRangeLength(DeviceExtension
,
754 DPRINT1("PdoGetRangeLength() failed\n");
760 DPRINT("Unused address register\n");
764 if (Flags
& PCI_ADDRESS_IO_SPACE
)
766 Descriptor
->Type
= CmResourceTypePort
;
767 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
768 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
769 Descriptor
->u
.Port
.Start
.QuadPart
= (ULONGLONG
)Base
;
770 Descriptor
->u
.Port
.Length
= Length
;
772 /* Enable IO space access */
773 DeviceExtension
->PciDevice
->EnableIoSpace
= TRUE
;
777 Descriptor
->Type
= CmResourceTypeMemory
;
778 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
779 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
780 Descriptor
->u
.Memory
.Start
.QuadPart
= (ULONGLONG
)Base
;
781 Descriptor
->u
.Memory
.Length
= Length
;
783 /* Enable memory space access */
784 DeviceExtension
->PciDevice
->EnableMemorySpace
= TRUE
;
790 /* Add interrupt resource */
791 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
792 (PciConfig
.u
.type0
.InterruptLine
!= 0) &&
793 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
795 Descriptor
->Type
= CmResourceTypeInterrupt
;
796 Descriptor
->ShareDisposition
= CmResourceShareShared
;
797 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
798 Descriptor
->u
.Interrupt
.Level
= PciConfig
.u
.type0
.InterruptLine
;
799 Descriptor
->u
.Interrupt
.Vector
= PciConfig
.u
.type0
.InterruptLine
;
800 Descriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
803 /* Allow bus master mode */
804 DeviceExtension
->PciDevice
->EnableBusMaster
= TRUE
;
806 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
808 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
810 if (!PdoGetRangeLength(DeviceExtension
,
816 DPRINT1("PdoGetRangeLength() failed\n");
822 DPRINT("Unused address register\n");
826 if (Flags
& PCI_ADDRESS_IO_SPACE
)
828 Descriptor
->Type
= CmResourceTypePort
;
829 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
830 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
831 Descriptor
->u
.Port
.Start
.QuadPart
= (ULONGLONG
)Base
;
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
= (ULONGLONG
)Base
;
843 Descriptor
->u
.Memory
.Length
= Length
;
845 /* Enable memory space access */
846 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
);
899 static TRANSLATE_BUS_ADDRESS InterfaceBusTranslateBusAddress
;
904 InterfaceBusTranslateBusAddress(
906 IN PHYSICAL_ADDRESS BusAddress
,
908 IN OUT PULONG AddressSpace
,
909 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
911 PPDO_DEVICE_EXTENSION DeviceExtension
;
913 DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
914 Context
, BusAddress
, Length
, AddressSpace
, TranslatedAddress
);
916 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
918 return HalTranslateBusAddress(PCIBus
,
919 DeviceExtension
->PciDevice
->BusNumber
,
925 static GET_DMA_ADAPTER InterfaceBusGetDmaAdapter
;
930 InterfaceBusGetDmaAdapter(
932 IN PDEVICE_DESCRIPTION DeviceDescription
,
933 OUT PULONG NumberOfMapRegisters
)
935 DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
936 Context
, DeviceDescription
, NumberOfMapRegisters
);
937 return (PDMA_ADAPTER
)HalGetAdapter(DeviceDescription
, NumberOfMapRegisters
);
940 static GET_SET_DEVICE_DATA InterfaceBusSetBusData
;
945 InterfaceBusSetBusData(
952 PPDO_DEVICE_EXTENSION DeviceExtension
;
955 DPRINT("InterfaceBusSetBusData(%p 0x%lx %p 0x%lx 0x%lx)\n",
956 Context
, DataType
, Buffer
, Offset
, Length
);
958 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
960 DPRINT("Unknown DataType %lu\n", DataType
);
964 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
966 /* Get PCI configuration space */
967 Size
= HalSetBusDataByOffset(PCIConfiguration
,
968 DeviceExtension
->PciDevice
->BusNumber
,
969 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
976 static GET_SET_DEVICE_DATA InterfaceBusGetBusData
;
981 InterfaceBusGetBusData(
988 PPDO_DEVICE_EXTENSION DeviceExtension
;
991 DPRINT("InterfaceBusGetBusData(%p 0x%lx %p 0x%lx 0x%lx) called\n",
992 Context
, DataType
, Buffer
, Offset
, Length
);
994 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
996 DPRINT("Unknown DataType %lu\n", DataType
);
1000 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1002 /* Get PCI configuration space */
1003 Size
= HalGetBusDataByOffset(PCIConfiguration
,
1004 DeviceExtension
->PciDevice
->BusNumber
,
1005 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1013 static BOOLEAN NTAPI
1014 InterfacePciDevicePresent(
1017 IN UCHAR RevisionID
,
1018 IN USHORT SubVendorID
,
1019 IN USHORT SubSystemID
,
1022 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1023 PPCI_DEVICE PciDevice
;
1024 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1026 BOOLEAN Found
= FALSE
;
1028 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1029 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1030 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1032 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1034 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1035 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1036 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1038 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1039 if (PciDevice
->PciConfig
.VendorID
== VendorID
&&
1040 PciDevice
->PciConfig
.DeviceID
== DeviceID
)
1042 if (!(Flags
& PCI_USE_SUBSYSTEM_IDS
) ||
1043 (PciDevice
->PciConfig
.u
.type0
.SubVendorID
== SubVendorID
&&
1044 PciDevice
->PciConfig
.u
.type0
.SubSystemID
== SubSystemID
))
1046 if (!(Flags
& PCI_USE_REVISION
) ||
1047 PciDevice
->PciConfig
.RevisionID
== RevisionID
)
1049 DPRINT("Found the PCI device\n");
1055 CurrentEntry
= CurrentEntry
->Flink
;
1058 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1059 CurrentBus
= CurrentBus
->Flink
;
1061 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1069 IN PPCI_COMMON_CONFIG PciConfig
,
1070 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1072 if ((Parameters
->Flags
& PCI_USE_VENDEV_IDS
) &&
1073 (PciConfig
->VendorID
!= Parameters
->VendorID
||
1074 PciConfig
->DeviceID
!= Parameters
->DeviceID
))
1079 if ((Parameters
->Flags
& PCI_USE_CLASS_SUBCLASS
) &&
1080 (PciConfig
->BaseClass
!= Parameters
->BaseClass
||
1081 PciConfig
->SubClass
!= Parameters
->SubClass
))
1086 if ((Parameters
->Flags
& PCI_USE_PROGIF
) &&
1087 PciConfig
->ProgIf
!= Parameters
->ProgIf
)
1092 if ((Parameters
->Flags
& PCI_USE_SUBSYSTEM_IDS
) &&
1093 (PciConfig
->u
.type0
.SubVendorID
!= Parameters
->SubVendorID
||
1094 PciConfig
->u
.type0
.SubSystemID
!= Parameters
->SubSystemID
))
1099 if ((Parameters
->Flags
& PCI_USE_REVISION
) &&
1100 PciConfig
->RevisionID
!= Parameters
->RevisionID
)
1109 static BOOLEAN NTAPI
1110 InterfacePciDevicePresentEx(
1112 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1114 PPDO_DEVICE_EXTENSION DeviceExtension
;
1115 PFDO_DEVICE_EXTENSION MyFdoDeviceExtension
;
1116 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1117 PPCI_DEVICE PciDevice
;
1118 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1120 BOOLEAN Found
= FALSE
;
1122 DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
1123 Context
, Parameters
);
1125 if (!Parameters
|| Parameters
->Size
!= sizeof(PCI_DEVICE_PRESENCE_PARAMETERS
))
1128 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1129 MyFdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
1131 if (Parameters
->Flags
& PCI_USE_LOCAL_DEVICE
)
1133 return CheckPciDevice(&DeviceExtension
->PciDevice
->PciConfig
, Parameters
);
1136 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1137 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1138 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1140 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1141 if (!(Parameters
->Flags
& PCI_USE_LOCAL_BUS
) || FdoDeviceExtension
== MyFdoDeviceExtension
)
1143 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1144 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1145 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1147 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1149 if (CheckPciDevice(&PciDevice
->PciConfig
, Parameters
))
1151 DPRINT("Found the PCI device\n");
1155 CurrentEntry
= CurrentEntry
->Flink
;
1158 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1160 CurrentBus
= CurrentBus
->Flink
;
1162 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1170 IN PDEVICE_OBJECT DeviceObject
,
1172 PIO_STACK_LOCATION IrpSp
)
1176 UNREFERENCED_PARAMETER(Irp
);
1178 if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1179 &GUID_BUS_INTERFACE_STANDARD
, sizeof(GUID
)) == sizeof(GUID
))
1181 /* BUS_INTERFACE_STANDARD */
1182 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1183 Status
= STATUS_NOT_SUPPORTED
;
1184 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(BUS_INTERFACE_STANDARD
))
1185 Status
= STATUS_BUFFER_TOO_SMALL
;
1188 PBUS_INTERFACE_STANDARD BusInterface
;
1189 BusInterface
= (PBUS_INTERFACE_STANDARD
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1190 BusInterface
->Size
= sizeof(BUS_INTERFACE_STANDARD
);
1191 BusInterface
->Version
= 1;
1192 BusInterface
->TranslateBusAddress
= InterfaceBusTranslateBusAddress
;
1193 BusInterface
->GetDmaAdapter
= InterfaceBusGetDmaAdapter
;
1194 BusInterface
->SetBusData
= InterfaceBusSetBusData
;
1195 BusInterface
->GetBusData
= InterfaceBusGetBusData
;
1196 Status
= STATUS_SUCCESS
;
1199 else if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1200 &GUID_PCI_DEVICE_PRESENT_INTERFACE
, sizeof(GUID
)) == sizeof(GUID
))
1202 /* PCI_DEVICE_PRESENT_INTERFACE */
1203 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1204 Status
= STATUS_NOT_SUPPORTED
;
1205 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(PCI_DEVICE_PRESENT_INTERFACE
))
1206 Status
= STATUS_BUFFER_TOO_SMALL
;
1209 PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface
;
1210 PciDevicePresentInterface
= (PPCI_DEVICE_PRESENT_INTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1211 PciDevicePresentInterface
->Size
= sizeof(PCI_DEVICE_PRESENT_INTERFACE
);
1212 PciDevicePresentInterface
->Version
= 1;
1213 PciDevicePresentInterface
->IsDevicePresent
= InterfacePciDevicePresent
;
1214 PciDevicePresentInterface
->IsDevicePresentEx
= InterfacePciDevicePresentEx
;
1215 Status
= STATUS_SUCCESS
;
1220 /* Not a supported interface */
1221 return STATUS_NOT_SUPPORTED
;
1224 if (NT_SUCCESS(Status
))
1226 /* Add a reference for the returned interface */
1227 PINTERFACE Interface
;
1228 Interface
= (PINTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1229 Interface
->Context
= DeviceObject
;
1230 Interface
->InterfaceReference
= InterfaceReference
;
1231 Interface
->InterfaceDereference
= InterfaceDereference
;
1232 Interface
->InterfaceReference(Interface
->Context
);
1240 IN PDEVICE_OBJECT DeviceObject
,
1242 PIO_STACK_LOCATION IrpSp
)
1244 PCM_RESOURCE_LIST RawResList
= IrpSp
->Parameters
.StartDevice
.AllocatedResources
;
1245 PCM_FULL_RESOURCE_DESCRIPTOR RawFullDesc
;
1246 PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDesc
;
1248 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1252 UNREFERENCED_PARAMETER(Irp
);
1255 return STATUS_SUCCESS
;
1257 /* TODO: Assign the other resources we get to the card */
1259 for (i
= 0; i
< RawResList
->Count
; i
++)
1261 RawFullDesc
= &RawResList
->List
[i
];
1263 for (ii
= 0; ii
< RawFullDesc
->PartialResourceList
.Count
; ii
++)
1265 RawPartialDesc
= &RawFullDesc
->PartialResourceList
.PartialDescriptors
[ii
];
1267 if (RawPartialDesc
->Type
== CmResourceTypeInterrupt
)
1269 DPRINT1("Assigning IRQ %u to PCI device 0x%x on bus 0x%x\n",
1270 RawPartialDesc
->u
.Interrupt
.Vector
,
1271 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1272 DeviceExtension
->PciDevice
->BusNumber
);
1274 Irq
= (UCHAR
)RawPartialDesc
->u
.Interrupt
.Vector
;
1275 HalSetBusDataByOffset(PCIConfiguration
,
1276 DeviceExtension
->PciDevice
->BusNumber
,
1277 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1279 0x3c /* PCI_INTERRUPT_LINE */,
1287 DPRINT1("Enabling command flags for PCI device 0x%x on bus 0x%x: ",
1288 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1289 DeviceExtension
->PciDevice
->BusNumber
);
1290 if (DeviceExtension
->PciDevice
->EnableBusMaster
)
1292 Command
|= PCI_ENABLE_BUS_MASTER
;
1293 DbgPrint("[Bus master] ");
1296 if (DeviceExtension
->PciDevice
->EnableMemorySpace
)
1298 Command
|= PCI_ENABLE_MEMORY_SPACE
;
1299 DbgPrint("[Memory space enable] ");
1302 if (DeviceExtension
->PciDevice
->EnableIoSpace
)
1304 Command
|= PCI_ENABLE_IO_SPACE
;
1305 DbgPrint("[I/O space enable] ");
1312 /* OR with the previous value */
1313 Command
|= DeviceExtension
->PciDevice
->PciConfig
.Command
;
1315 HalSetBusDataByOffset(PCIConfiguration
,
1316 DeviceExtension
->PciDevice
->BusNumber
,
1317 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1319 FIELD_OFFSET(PCI_COMMON_CONFIG
, Command
),
1327 return STATUS_SUCCESS
;
1332 IN PDEVICE_OBJECT DeviceObject
,
1334 PIO_STACK_LOCATION IrpSp
)
1338 DPRINT("PdoReadConfig() called\n");
1340 Size
= InterfaceBusGetBusData(DeviceObject
,
1341 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1342 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1343 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1344 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1346 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1348 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1349 Irp
->IoStatus
.Information
= 0;
1350 return STATUS_UNSUCCESSFUL
;
1353 Irp
->IoStatus
.Information
= Size
;
1355 return STATUS_SUCCESS
;
1361 IN PDEVICE_OBJECT DeviceObject
,
1363 PIO_STACK_LOCATION IrpSp
)
1367 DPRINT1("PdoWriteConfig() called\n");
1369 /* Get PCI configuration space */
1370 Size
= InterfaceBusSetBusData(DeviceObject
,
1371 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1372 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1373 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1374 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1376 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1378 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1379 Irp
->IoStatus
.Information
= 0;
1380 return STATUS_UNSUCCESSFUL
;
1383 Irp
->IoStatus
.Information
= Size
;
1385 return STATUS_SUCCESS
;
1389 PdoQueryDeviceRelations(
1390 IN PDEVICE_OBJECT DeviceObject
,
1392 PIO_STACK_LOCATION IrpSp
)
1394 PDEVICE_RELATIONS DeviceRelations
;
1396 /* We only support TargetDeviceRelation for child PDOs */
1397 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
1398 return Irp
->IoStatus
.Status
;
1400 /* We can do this because we only return 1 PDO for TargetDeviceRelation */
1401 DeviceRelations
= ExAllocatePool(PagedPool
, sizeof(*DeviceRelations
));
1402 if (!DeviceRelations
)
1403 return STATUS_INSUFFICIENT_RESOURCES
;
1405 DeviceRelations
->Count
= 1;
1406 DeviceRelations
->Objects
[0] = DeviceObject
;
1408 /* The PnP manager will remove this when it is done with the PDO */
1409 ObReferenceObject(DeviceObject
);
1411 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1413 return STATUS_SUCCESS
;
1418 IN PDEVICE_OBJECT DeviceObject
,
1420 PIO_STACK_LOCATION IrpSp
)
1424 UNREFERENCED_PARAMETER(DeviceObject
);
1425 UNREFERENCED_PARAMETER(Irp
);
1428 if (IrpSp
->Parameters
.Power
.Type
== DevicePowerState
)
1430 Status
= STATUS_SUCCESS
;
1432 switch (IrpSp
->Parameters
.Power
.State
.SystemState
)
1435 Status
= STATUS_UNSUCCESSFUL
;
1440 Status
= STATUS_UNSUCCESSFUL
;
1447 /*** PUBLIC ******************************************************************/
1451 PDEVICE_OBJECT DeviceObject
,
1454 * FUNCTION: Handle Plug and Play IRPs for the child device
1456 * DeviceObject = Pointer to physical device object of the child device
1457 * Irp = Pointer to IRP that should be handled
1462 PIO_STACK_LOCATION IrpSp
;
1467 Status
= Irp
->IoStatus
.Status
;
1469 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1471 switch (IrpSp
->MinorFunction
)
1473 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1474 DPRINT("Unimplemented IRP_MN_DEVICE_USAGE_NOTIFICATION received\n");
1478 DPRINT("Unimplemented IRP_MN_EJECT received\n");
1481 case IRP_MN_QUERY_BUS_INFORMATION
:
1482 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
1485 case IRP_MN_QUERY_CAPABILITIES
:
1486 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
1489 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1490 Status
= PdoQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
1493 case IRP_MN_QUERY_DEVICE_TEXT
:
1494 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
1495 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
1498 case IRP_MN_QUERY_ID
:
1499 DPRINT("IRP_MN_QUERY_ID received\n");
1500 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
1503 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1504 DPRINT("Unimplemented IRP_MN_QUERY_ID received\n");
1507 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1508 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
1509 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
1512 case IRP_MN_QUERY_RESOURCES
:
1513 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
1514 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
1517 case IRP_MN_SET_LOCK
:
1518 DPRINT("Unimplemented IRP_MN_SET_LOCK received\n");
1521 case IRP_MN_START_DEVICE
:
1522 Status
= PdoStartDevice(DeviceObject
, Irp
, IrpSp
);
1525 case IRP_MN_QUERY_STOP_DEVICE
:
1526 case IRP_MN_CANCEL_STOP_DEVICE
:
1527 case IRP_MN_STOP_DEVICE
:
1528 case IRP_MN_QUERY_REMOVE_DEVICE
:
1529 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1530 case IRP_MN_SURPRISE_REMOVAL
:
1531 Status
= STATUS_SUCCESS
;
1534 case IRP_MN_REMOVE_DEVICE
:
1536 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1537 PFDO_DEVICE_EXTENSION FdoDeviceExtension
= DeviceExtension
->Fdo
->DeviceExtension
;
1540 /* Remove it from the device list */
1541 KeAcquireSpinLock(&FdoDeviceExtension
->DeviceListLock
, &OldIrql
);
1542 RemoveEntryList(&DeviceExtension
->PciDevice
->ListEntry
);
1543 FdoDeviceExtension
->DeviceListCount
--;
1544 KeReleaseSpinLock(&FdoDeviceExtension
->DeviceListLock
, OldIrql
);
1546 /* Free the device */
1547 ExFreePool(DeviceExtension
->PciDevice
);
1549 /* Complete the IRP */
1550 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1551 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1554 IoDeleteDevice(DeviceObject
);
1555 return STATUS_SUCCESS
;
1558 case IRP_MN_QUERY_INTERFACE
:
1559 DPRINT("IRP_MN_QUERY_INTERFACE received\n");
1560 Status
= PdoQueryInterface(DeviceObject
, Irp
, IrpSp
);
1563 case IRP_MN_READ_CONFIG
:
1564 DPRINT("IRP_MN_READ_CONFIG received\n");
1565 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1568 case IRP_MN_WRITE_CONFIG
:
1569 DPRINT("IRP_MN_WRITE_CONFIG received\n");
1570 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1573 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1574 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS received\n");
1576 Irp
->IoStatus
.Status
= Status
;
1580 DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp
->MinorFunction
);
1584 if (Status
!= STATUS_PENDING
)
1586 Irp
->IoStatus
.Status
= Status
;
1587 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1590 DPRINT("Leaving. Status 0x%X\n", Status
);
1597 PDEVICE_OBJECT DeviceObject
,
1600 * FUNCTION: Handle power management IRPs for the child device
1602 * DeviceObject = Pointer to physical device object of the child device
1603 * Irp = Pointer to IRP that should be handled
1608 PIO_STACK_LOCATION IrpSp
;
1613 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1615 switch (IrpSp
->MinorFunction
)
1617 case IRP_MN_SET_POWER
:
1618 Status
= PdoSetPower(DeviceObject
, Irp
, IrpSp
);
1622 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1623 Status
= STATUS_NOT_IMPLEMENTED
;
1627 if (Status
!= STATUS_PENDING
)
1629 Irp
->IoStatus
.Status
= Status
;
1630 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1633 DPRINT("Leaving. Status 0x%X\n", Status
);