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
)
85 case BusQueryDeviceID
:
86 Status
= PciDuplicateUnicodeString(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(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
97 &DeviceExtension
->HardwareIDs
,
100 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
103 case BusQueryCompatibleIDs
:
104 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
105 &DeviceExtension
->CompatibleIDs
,
108 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
111 case BusQueryInstanceID
:
112 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
113 &DeviceExtension
->InstanceID
,
116 DPRINT("InstanceID: %S\n", String
.Buffer
);
118 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
121 case BusQueryDeviceSerialNumber
:
123 Status
= STATUS_NOT_IMPLEMENTED
;
131 PdoQueryBusInformation(
132 IN PDEVICE_OBJECT DeviceObject
,
134 PIO_STACK_LOCATION IrpSp
)
136 PPDO_DEVICE_EXTENSION DeviceExtension
;
137 PPNP_BUS_INFORMATION BusInformation
;
139 UNREFERENCED_PARAMETER(IrpSp
);
142 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
143 BusInformation
= ExAllocatePool(PagedPool
, sizeof(PNP_BUS_INFORMATION
));
144 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
145 if (BusInformation
!= NULL
)
147 BusInformation
->BusTypeGuid
= GUID_BUS_TYPE_PCI
;
148 BusInformation
->LegacyBusType
= PCIBus
;
149 BusInformation
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
151 return STATUS_SUCCESS
;
154 return STATUS_INSUFFICIENT_RESOURCES
;
159 PdoQueryCapabilities(
160 IN PDEVICE_OBJECT DeviceObject
,
162 PIO_STACK_LOCATION IrpSp
)
164 PPDO_DEVICE_EXTENSION DeviceExtension
;
165 PDEVICE_CAPABILITIES DeviceCapabilities
;
166 ULONG DeviceNumber
, FunctionNumber
;
168 UNREFERENCED_PARAMETER(Irp
);
171 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
172 DeviceCapabilities
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
174 if (DeviceCapabilities
->Version
!= 1)
175 return STATUS_UNSUCCESSFUL
;
177 DeviceNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.DeviceNumber
;
178 FunctionNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.FunctionNumber
;
180 DeviceCapabilities
->UniqueID
= FALSE
;
181 DeviceCapabilities
->Address
= ((DeviceNumber
<< 16) & 0xFFFF0000) + (FunctionNumber
& 0xFFFF);
182 DeviceCapabilities
->UINumber
= MAXULONG
; /* FIXME */
184 return STATUS_SUCCESS
;
189 PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension
,
201 /* Save original value */
202 Size
= HalGetBusDataByOffset(PCIConfiguration
,
203 DeviceExtension
->PciDevice
->BusNumber
,
204 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
208 if (Size
!= sizeof(ULONG
))
210 DPRINT1("Wrong size %lu\n", Size
);
214 BaseValue
= (OrigValue
& PCI_ADDRESS_IO_SPACE
)
215 ? (OrigValue
& PCI_ADDRESS_IO_ADDRESS_MASK
)
216 : (OrigValue
& PCI_ADDRESS_MEMORY_ADDRESS_MASK
);
220 /* Set magic value */
222 Size
= HalSetBusDataByOffset(PCIConfiguration
,
223 DeviceExtension
->PciDevice
->BusNumber
,
224 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
228 if (Size
!= sizeof(ULONG
))
230 DPRINT1("Wrong size %lu\n", Size
);
234 /* Get the range length */
235 Size
= HalGetBusDataByOffset(PCIConfiguration
,
236 DeviceExtension
->PciDevice
->BusNumber
,
237 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
241 if (Size
!= sizeof(ULONG
))
243 DPRINT1("Wrong size %lu\n", Size
);
247 /* Restore original value */
248 Size
= HalSetBusDataByOffset(PCIConfiguration
,
249 DeviceExtension
->PciDevice
->BusNumber
,
250 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
254 if (Size
!= sizeof(ULONG
))
256 DPRINT1("Wrong size %lu\n", Size
);
262 DPRINT("Unused address register\n");
269 XLength
= ~((NewValue
& PCI_ADDRESS_IO_SPACE
)
270 ? (NewValue
& PCI_ADDRESS_IO_ADDRESS_MASK
)
271 : (NewValue
& PCI_ADDRESS_MEMORY_ADDRESS_MASK
)) + 1;
274 DbgPrint("BaseAddress 0x%08lx Length 0x%08lx",
277 if (NewValue
& PCI_ADDRESS_IO_SPACE
)
279 DbgPrint(" IO range");
283 DbgPrint(" Memory range");
284 if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 0)
286 DbgPrint(" in 32-Bit address space");
288 else if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 2)
290 DbgPrint(" below 1BM ");
292 else if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 4)
294 DbgPrint(" in 64-Bit address space");
297 if (NewValue
& PCI_ADDRESS_MEMORY_PREFETCHABLE
)
299 DbgPrint(" prefetchable");
307 *Flags
= (NewValue
& PCI_ADDRESS_IO_SPACE
)
308 ? (NewValue
& ~PCI_ADDRESS_IO_ADDRESS_MASK
)
309 : (NewValue
& ~PCI_ADDRESS_MEMORY_ADDRESS_MASK
);
316 PdoQueryResourceRequirements(
317 IN PDEVICE_OBJECT DeviceObject
,
319 PIO_STACK_LOCATION IrpSp
)
321 PPDO_DEVICE_EXTENSION DeviceExtension
;
322 PCI_COMMON_CONFIG PciConfig
;
323 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
324 PIO_RESOURCE_DESCRIPTOR Descriptor
;
333 UNREFERENCED_PARAMETER(IrpSp
);
334 DPRINT("PdoQueryResourceRequirements() called\n");
336 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
338 /* Get PCI configuration space */
339 Size
= HalGetBusData(PCIConfiguration
,
340 DeviceExtension
->PciDevice
->BusNumber
,
341 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
343 PCI_COMMON_HDR_LENGTH
);
344 DPRINT("Size %lu\n", Size
);
345 if (Size
< PCI_COMMON_HDR_LENGTH
)
347 Irp
->IoStatus
.Information
= 0;
348 return STATUS_UNSUCCESSFUL
;
351 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
353 /* Count required resource descriptors */
355 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
357 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
359 if (!PdoGetRangeLength(DeviceExtension
,
370 /* FIXME: Check ROM address */
372 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
375 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
377 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
379 if (!PdoGetRangeLength(DeviceExtension
,
390 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
393 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
395 /* FIXME: Count Cardbus bridge resources */
399 DPRINT1("Unsupported header type %d\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
404 Irp
->IoStatus
.Information
= 0;
405 return STATUS_SUCCESS
;
408 /* Calculate the resource list size */
409 ListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
[0].Descriptors
) +
410 ResCount
* sizeof(IO_RESOURCE_DESCRIPTOR
);
412 DPRINT("ListSize %lu (0x%lx)\n", ListSize
, ListSize
);
414 /* Allocate the resource requirements list */
415 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
418 if (ResourceList
== NULL
)
420 Irp
->IoStatus
.Information
= 0;
421 return STATUS_INSUFFICIENT_RESOURCES
;
424 RtlZeroMemory(ResourceList
, ListSize
);
425 ResourceList
->ListSize
= ListSize
;
426 ResourceList
->InterfaceType
= PCIBus
;
427 ResourceList
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
428 ResourceList
->SlotNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
;
429 ResourceList
->AlternativeLists
= 1;
431 ResourceList
->List
[0].Version
= 1;
432 ResourceList
->List
[0].Revision
= 1;
433 ResourceList
->List
[0].Count
= ResCount
;
435 Descriptor
= &ResourceList
->List
[0].Descriptors
[0];
436 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
438 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
440 if (!PdoGetRangeLength(DeviceExtension
,
446 DPRINT1("PdoGetRangeLength() failed\n");
452 DPRINT("Unused address register\n");
456 /* Set preferred descriptor */
457 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
458 if (Flags
& PCI_ADDRESS_IO_SPACE
)
460 Descriptor
->Type
= CmResourceTypePort
;
461 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
462 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
463 CM_RESOURCE_PORT_16_BIT_DECODE
|
464 CM_RESOURCE_PORT_POSITIVE_DECODE
;
466 Descriptor
->u
.Port
.Length
= Length
;
467 Descriptor
->u
.Port
.Alignment
= 1;
468 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
469 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
473 Descriptor
->Type
= CmResourceTypeMemory
;
474 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
475 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
477 Descriptor
->u
.Memory
.Length
= Length
;
478 Descriptor
->u
.Memory
.Alignment
= 1;
479 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
480 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
484 /* Set alternative descriptor */
485 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
486 if (Flags
& PCI_ADDRESS_IO_SPACE
)
488 Descriptor
->Type
= CmResourceTypePort
;
489 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
490 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
491 CM_RESOURCE_PORT_16_BIT_DECODE
|
492 CM_RESOURCE_PORT_POSITIVE_DECODE
;
494 Descriptor
->u
.Port
.Length
= Length
;
495 Descriptor
->u
.Port
.Alignment
= Length
;
496 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
497 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
501 Descriptor
->Type
= CmResourceTypeMemory
;
502 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
503 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
505 Descriptor
->u
.Memory
.Length
= Length
;
506 Descriptor
->u
.Memory
.Alignment
= Length
;
507 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
508 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
513 /* FIXME: Check ROM address */
515 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
517 Descriptor
->Option
= 0; /* Required */
518 Descriptor
->Type
= CmResourceTypeInterrupt
;
519 Descriptor
->ShareDisposition
= CmResourceShareShared
;
520 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
522 Descriptor
->u
.Interrupt
.MinimumVector
= 0;
523 Descriptor
->u
.Interrupt
.MaximumVector
= 0xFF;
526 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
528 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
530 if (!PdoGetRangeLength(DeviceExtension
,
536 DPRINT1("PdoGetRangeLength() failed\n");
542 DPRINT("Unused address register\n");
546 /* Set preferred descriptor */
547 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
548 if (Flags
& PCI_ADDRESS_IO_SPACE
)
550 Descriptor
->Type
= CmResourceTypePort
;
551 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
552 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
553 CM_RESOURCE_PORT_16_BIT_DECODE
|
554 CM_RESOURCE_PORT_POSITIVE_DECODE
;
556 Descriptor
->u
.Port
.Length
= Length
;
557 Descriptor
->u
.Port
.Alignment
= 1;
558 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
559 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
563 Descriptor
->Type
= CmResourceTypeMemory
;
564 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
565 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
567 Descriptor
->u
.Memory
.Length
= Length
;
568 Descriptor
->u
.Memory
.Alignment
= 1;
569 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
570 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
574 /* Set alternative descriptor */
575 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
576 if (Flags
& PCI_ADDRESS_IO_SPACE
)
578 Descriptor
->Type
= CmResourceTypePort
;
579 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
580 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
581 CM_RESOURCE_PORT_16_BIT_DECODE
|
582 CM_RESOURCE_PORT_POSITIVE_DECODE
;
584 Descriptor
->u
.Port
.Length
= Length
;
585 Descriptor
->u
.Port
.Alignment
= Length
;
586 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
587 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
591 Descriptor
->Type
= CmResourceTypeMemory
;
592 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
593 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
595 Descriptor
->u
.Memory
.Length
= Length
;
596 Descriptor
->u
.Memory
.Alignment
= Length
;
597 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
598 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
,
703 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
706 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
708 /* FIXME: Count Cardbus bridge resources */
712 DPRINT1("Unsupported header type %d\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
717 Irp
->IoStatus
.Information
= 0;
718 return STATUS_SUCCESS
;
721 /* Calculate the resource list size */
722 ListSize
= FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.PartialDescriptors
) +
723 ResCount
* sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
725 /* Allocate the resource list */
726 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
729 if (ResourceList
== NULL
)
730 return STATUS_INSUFFICIENT_RESOURCES
;
732 RtlZeroMemory(ResourceList
, ListSize
);
733 ResourceList
->Count
= 1;
734 ResourceList
->List
[0].InterfaceType
= PCIBus
;
735 ResourceList
->List
[0].BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
737 PartialList
= &ResourceList
->List
[0].PartialResourceList
;
738 PartialList
->Version
= 1;
739 PartialList
->Revision
= 1;
740 PartialList
->Count
= ResCount
;
742 Descriptor
= &PartialList
->PartialDescriptors
[0];
743 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
745 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
747 if (!PdoGetRangeLength(DeviceExtension
,
753 DPRINT1("PdoGetRangeLength() failed\n");
759 DPRINT("Unused address register\n");
763 if (Flags
& PCI_ADDRESS_IO_SPACE
)
765 Descriptor
->Type
= CmResourceTypePort
;
766 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
767 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
768 Descriptor
->u
.Port
.Start
.QuadPart
= (ULONGLONG
)Base
;
769 Descriptor
->u
.Port
.Length
= Length
;
771 /* Enable IO space access */
772 DeviceExtension
->PciDevice
->EnableIoSpace
= TRUE
;
776 Descriptor
->Type
= CmResourceTypeMemory
;
777 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
778 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
779 Descriptor
->u
.Memory
.Start
.QuadPart
= (ULONGLONG
)Base
;
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
= (ULONGLONG
)Base
;
831 Descriptor
->u
.Port
.Length
= Length
;
833 /* Enable IO space access */
834 DeviceExtension
->PciDevice
->EnableIoSpace
= TRUE
;
838 Descriptor
->Type
= CmResourceTypeMemory
;
839 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
840 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
841 Descriptor
->u
.Memory
.Start
.QuadPart
= (ULONGLONG
)Base
;
842 Descriptor
->u
.Memory
.Length
= Length
;
844 /* Enable memory space access */
845 DeviceExtension
->PciDevice
->EnableMemorySpace
= TRUE
;
851 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
853 Descriptor
->Type
= CmResourceTypeBusNumber
;
854 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
856 ResourceList
->List
[0].BusNumber
=
857 Descriptor
->u
.BusNumber
.Start
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
858 Descriptor
->u
.BusNumber
.Length
= 1;
859 Descriptor
->u
.BusNumber
.Reserved
= 0;
862 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
864 /* FIXME: Add Cardbus bridge resources */
867 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
869 return STATUS_SUCCESS
;
877 PPDO_DEVICE_EXTENSION DeviceExtension
;
879 DPRINT("InterfaceReference(%p)\n", Context
);
881 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
882 InterlockedIncrement(&DeviceExtension
->References
);
887 InterfaceDereference(
890 PPDO_DEVICE_EXTENSION DeviceExtension
;
892 DPRINT("InterfaceDereference(%p)\n", Context
);
894 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
895 InterlockedDecrement(&DeviceExtension
->References
);
898 static TRANSLATE_BUS_ADDRESS InterfaceBusTranslateBusAddress
;
903 InterfaceBusTranslateBusAddress(
905 IN PHYSICAL_ADDRESS BusAddress
,
907 IN OUT PULONG AddressSpace
,
908 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
910 PPDO_DEVICE_EXTENSION DeviceExtension
;
912 DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
913 Context
, BusAddress
, Length
, AddressSpace
, TranslatedAddress
);
915 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
917 return HalTranslateBusAddress(PCIBus
,
918 DeviceExtension
->PciDevice
->BusNumber
,
924 static GET_DMA_ADAPTER InterfaceBusGetDmaAdapter
;
929 InterfaceBusGetDmaAdapter(
931 IN PDEVICE_DESCRIPTION DeviceDescription
,
932 OUT PULONG NumberOfMapRegisters
)
934 DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
935 Context
, DeviceDescription
, NumberOfMapRegisters
);
936 return (PDMA_ADAPTER
)HalGetAdapter(DeviceDescription
, NumberOfMapRegisters
);
939 static GET_SET_DEVICE_DATA InterfaceBusSetBusData
;
944 InterfaceBusSetBusData(
951 PPDO_DEVICE_EXTENSION DeviceExtension
;
954 DPRINT("InterfaceBusSetBusData(%p 0x%lx %p 0x%lx 0x%lx)\n",
955 Context
, DataType
, Buffer
, Offset
, Length
);
957 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
959 DPRINT("Unknown DataType %lu\n", DataType
);
963 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
965 /* Get PCI configuration space */
966 Size
= HalSetBusDataByOffset(PCIConfiguration
,
967 DeviceExtension
->PciDevice
->BusNumber
,
968 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
975 static GET_SET_DEVICE_DATA InterfaceBusGetBusData
;
980 InterfaceBusGetBusData(
987 PPDO_DEVICE_EXTENSION DeviceExtension
;
990 DPRINT("InterfaceBusGetBusData(%p 0x%lx %p 0x%lx 0x%lx) called\n",
991 Context
, DataType
, Buffer
, Offset
, Length
);
993 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
995 DPRINT("Unknown DataType %lu\n", DataType
);
999 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1001 /* Get PCI configuration space */
1002 Size
= HalGetBusDataByOffset(PCIConfiguration
,
1003 DeviceExtension
->PciDevice
->BusNumber
,
1004 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1012 static BOOLEAN NTAPI
1013 InterfacePciDevicePresent(
1016 IN UCHAR RevisionID
,
1017 IN USHORT SubVendorID
,
1018 IN USHORT SubSystemID
,
1021 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1022 PPCI_DEVICE PciDevice
;
1023 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1025 BOOLEAN Found
= FALSE
;
1027 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1028 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1029 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1031 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1033 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1034 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1035 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1037 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1038 if (PciDevice
->PciConfig
.VendorID
== VendorID
&&
1039 PciDevice
->PciConfig
.DeviceID
== DeviceID
)
1041 if (!(Flags
& PCI_USE_SUBSYSTEM_IDS
) ||
1042 (PciDevice
->PciConfig
.u
.type0
.SubVendorID
== SubVendorID
&&
1043 PciDevice
->PciConfig
.u
.type0
.SubSystemID
== SubSystemID
))
1045 if (!(Flags
& PCI_USE_REVISION
) ||
1046 PciDevice
->PciConfig
.RevisionID
== RevisionID
)
1048 DPRINT("Found the PCI device\n");
1054 CurrentEntry
= CurrentEntry
->Flink
;
1057 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1058 CurrentBus
= CurrentBus
->Flink
;
1060 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1068 IN PPCI_COMMON_CONFIG PciConfig
,
1069 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1071 if ((Parameters
->Flags
& PCI_USE_VENDEV_IDS
) &&
1072 (PciConfig
->VendorID
!= Parameters
->VendorID
||
1073 PciConfig
->DeviceID
!= Parameters
->DeviceID
))
1078 if ((Parameters
->Flags
& PCI_USE_CLASS_SUBCLASS
) &&
1079 (PciConfig
->BaseClass
!= Parameters
->BaseClass
||
1080 PciConfig
->SubClass
!= Parameters
->SubClass
))
1085 if ((Parameters
->Flags
& PCI_USE_PROGIF
) &&
1086 PciConfig
->ProgIf
!= Parameters
->ProgIf
)
1091 if ((Parameters
->Flags
& PCI_USE_SUBSYSTEM_IDS
) &&
1092 (PciConfig
->u
.type0
.SubVendorID
!= Parameters
->SubVendorID
||
1093 PciConfig
->u
.type0
.SubSystemID
!= Parameters
->SubSystemID
))
1098 if ((Parameters
->Flags
& PCI_USE_REVISION
) &&
1099 PciConfig
->RevisionID
!= Parameters
->RevisionID
)
1108 static BOOLEAN NTAPI
1109 InterfacePciDevicePresentEx(
1111 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1113 PPDO_DEVICE_EXTENSION DeviceExtension
;
1114 PFDO_DEVICE_EXTENSION MyFdoDeviceExtension
;
1115 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1116 PPCI_DEVICE PciDevice
;
1117 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1119 BOOLEAN Found
= FALSE
;
1121 DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
1122 Context
, Parameters
);
1124 if (!Parameters
|| Parameters
->Size
!= sizeof(PCI_DEVICE_PRESENCE_PARAMETERS
))
1127 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1128 MyFdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
1130 if (Parameters
->Flags
& PCI_USE_LOCAL_DEVICE
)
1132 return CheckPciDevice(&DeviceExtension
->PciDevice
->PciConfig
, Parameters
);
1135 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1136 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1137 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1139 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1140 if (!(Parameters
->Flags
& PCI_USE_LOCAL_BUS
) || FdoDeviceExtension
== MyFdoDeviceExtension
)
1142 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1143 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1144 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1146 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1148 if (CheckPciDevice(&PciDevice
->PciConfig
, Parameters
))
1150 DPRINT("Found the PCI device\n");
1154 CurrentEntry
= CurrentEntry
->Flink
;
1157 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1159 CurrentBus
= CurrentBus
->Flink
;
1161 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1169 IN PDEVICE_OBJECT DeviceObject
,
1171 PIO_STACK_LOCATION IrpSp
)
1175 UNREFERENCED_PARAMETER(Irp
);
1177 if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1178 &GUID_BUS_INTERFACE_STANDARD
, sizeof(GUID
)) == sizeof(GUID
))
1180 /* BUS_INTERFACE_STANDARD */
1181 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1182 Status
= STATUS_NOT_SUPPORTED
;
1183 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(BUS_INTERFACE_STANDARD
))
1184 Status
= STATUS_BUFFER_TOO_SMALL
;
1187 PBUS_INTERFACE_STANDARD BusInterface
;
1188 BusInterface
= (PBUS_INTERFACE_STANDARD
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1189 BusInterface
->Size
= sizeof(BUS_INTERFACE_STANDARD
);
1190 BusInterface
->Version
= 1;
1191 BusInterface
->TranslateBusAddress
= InterfaceBusTranslateBusAddress
;
1192 BusInterface
->GetDmaAdapter
= InterfaceBusGetDmaAdapter
;
1193 BusInterface
->SetBusData
= InterfaceBusSetBusData
;
1194 BusInterface
->GetBusData
= InterfaceBusGetBusData
;
1195 Status
= STATUS_SUCCESS
;
1198 else if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1199 &GUID_PCI_DEVICE_PRESENT_INTERFACE
, sizeof(GUID
)) == sizeof(GUID
))
1201 /* PCI_DEVICE_PRESENT_INTERFACE */
1202 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1203 Status
= STATUS_NOT_SUPPORTED
;
1204 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(PCI_DEVICE_PRESENT_INTERFACE
))
1205 Status
= STATUS_BUFFER_TOO_SMALL
;
1208 PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface
;
1209 PciDevicePresentInterface
= (PPCI_DEVICE_PRESENT_INTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1210 PciDevicePresentInterface
->Size
= sizeof(PCI_DEVICE_PRESENT_INTERFACE
);
1211 PciDevicePresentInterface
->Version
= 1;
1212 PciDevicePresentInterface
->IsDevicePresent
= InterfacePciDevicePresent
;
1213 PciDevicePresentInterface
->IsDevicePresentEx
= InterfacePciDevicePresentEx
;
1214 Status
= STATUS_SUCCESS
;
1219 /* Not a supported interface */
1220 return STATUS_NOT_SUPPORTED
;
1223 if (NT_SUCCESS(Status
))
1225 /* Add a reference for the returned interface */
1226 PINTERFACE Interface
;
1227 Interface
= (PINTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1228 Interface
->Context
= DeviceObject
;
1229 Interface
->InterfaceReference
= InterfaceReference
;
1230 Interface
->InterfaceDereference
= InterfaceDereference
;
1231 Interface
->InterfaceReference(Interface
->Context
);
1239 IN PDEVICE_OBJECT DeviceObject
,
1241 PIO_STACK_LOCATION IrpSp
)
1243 PCM_RESOURCE_LIST RawResList
= IrpSp
->Parameters
.StartDevice
.AllocatedResources
;
1244 PCM_FULL_RESOURCE_DESCRIPTOR RawFullDesc
;
1245 PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDesc
;
1247 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1251 UNREFERENCED_PARAMETER(Irp
);
1254 return STATUS_SUCCESS
;
1256 /* TODO: Assign the other resources we get to the card */
1258 for (i
= 0; i
< RawResList
->Count
; i
++)
1260 RawFullDesc
= &RawResList
->List
[i
];
1262 for (ii
= 0; ii
< RawFullDesc
->PartialResourceList
.Count
; ii
++)
1264 RawPartialDesc
= &RawFullDesc
->PartialResourceList
.PartialDescriptors
[ii
];
1266 if (RawPartialDesc
->Type
== CmResourceTypeInterrupt
)
1268 DPRINT1("Assigning IRQ %u to PCI device 0x%x on bus 0x%x\n",
1269 RawPartialDesc
->u
.Interrupt
.Vector
,
1270 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1271 DeviceExtension
->PciDevice
->BusNumber
);
1273 Irq
= (UCHAR
)RawPartialDesc
->u
.Interrupt
.Vector
;
1274 HalSetBusDataByOffset(PCIConfiguration
,
1275 DeviceExtension
->PciDevice
->BusNumber
,
1276 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1278 0x3c /* PCI_INTERRUPT_LINE */,
1286 DPRINT1("Enabling command flags for PCI device 0x%x on bus 0x%x: ",
1287 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1288 DeviceExtension
->PciDevice
->BusNumber
);
1289 if (DeviceExtension
->PciDevice
->EnableBusMaster
)
1291 Command
|= PCI_ENABLE_BUS_MASTER
;
1292 DbgPrint("[Bus master] ");
1295 if (DeviceExtension
->PciDevice
->EnableMemorySpace
)
1297 Command
|= PCI_ENABLE_MEMORY_SPACE
;
1298 DbgPrint("[Memory space enable] ");
1301 if (DeviceExtension
->PciDevice
->EnableIoSpace
)
1303 Command
|= PCI_ENABLE_IO_SPACE
;
1304 DbgPrint("[I/O space enable] ");
1311 /* OR with the previous value */
1312 Command
|= DeviceExtension
->PciDevice
->PciConfig
.Command
;
1314 HalSetBusDataByOffset(PCIConfiguration
,
1315 DeviceExtension
->PciDevice
->BusNumber
,
1316 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1318 FIELD_OFFSET(PCI_COMMON_CONFIG
, Command
),
1326 return STATUS_SUCCESS
;
1331 IN PDEVICE_OBJECT DeviceObject
,
1333 PIO_STACK_LOCATION IrpSp
)
1337 DPRINT("PdoReadConfig() called\n");
1339 Size
= InterfaceBusGetBusData(DeviceObject
,
1340 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1341 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1342 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1343 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1345 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1347 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1348 Irp
->IoStatus
.Information
= 0;
1349 return STATUS_UNSUCCESSFUL
;
1352 Irp
->IoStatus
.Information
= Size
;
1354 return STATUS_SUCCESS
;
1360 IN PDEVICE_OBJECT DeviceObject
,
1362 PIO_STACK_LOCATION IrpSp
)
1366 DPRINT1("PdoWriteConfig() called\n");
1368 /* Get PCI configuration space */
1369 Size
= InterfaceBusSetBusData(DeviceObject
,
1370 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1371 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1372 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1373 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1375 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1377 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1378 Irp
->IoStatus
.Information
= 0;
1379 return STATUS_UNSUCCESSFUL
;
1382 Irp
->IoStatus
.Information
= Size
;
1384 return STATUS_SUCCESS
;
1388 PdoQueryDeviceRelations(
1389 IN PDEVICE_OBJECT DeviceObject
,
1391 PIO_STACK_LOCATION IrpSp
)
1393 PDEVICE_RELATIONS DeviceRelations
;
1395 /* We only support TargetDeviceRelation for child PDOs */
1396 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
1397 return Irp
->IoStatus
.Status
;
1399 /* We can do this because we only return 1 PDO for TargetDeviceRelation */
1400 DeviceRelations
= ExAllocatePool(PagedPool
, sizeof(*DeviceRelations
));
1401 if (!DeviceRelations
)
1402 return STATUS_INSUFFICIENT_RESOURCES
;
1404 DeviceRelations
->Count
= 1;
1405 DeviceRelations
->Objects
[0] = DeviceObject
;
1407 /* The PnP manager will remove this when it is done with the PDO */
1408 ObReferenceObject(DeviceObject
);
1410 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1412 return STATUS_SUCCESS
;
1417 IN PDEVICE_OBJECT DeviceObject
,
1419 PIO_STACK_LOCATION IrpSp
)
1423 UNREFERENCED_PARAMETER(DeviceObject
);
1424 UNREFERENCED_PARAMETER(Irp
);
1427 if (IrpSp
->Parameters
.Power
.Type
== DevicePowerState
)
1429 Status
= STATUS_SUCCESS
;
1431 switch (IrpSp
->Parameters
.Power
.State
.SystemState
)
1434 Status
= STATUS_UNSUCCESSFUL
;
1439 Status
= STATUS_UNSUCCESSFUL
;
1446 /*** PUBLIC ******************************************************************/
1450 PDEVICE_OBJECT DeviceObject
,
1453 * FUNCTION: Handle Plug and Play IRPs for the child device
1455 * DeviceObject = Pointer to physical device object of the child device
1456 * Irp = Pointer to IRP that should be handled
1461 PIO_STACK_LOCATION IrpSp
;
1466 Status
= Irp
->IoStatus
.Status
;
1468 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1470 switch (IrpSp
->MinorFunction
)
1472 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1473 DPRINT("Unimplemented IRP_MN_DEVICE_USAGE_NOTIFICATION received\n");
1477 DPRINT("Unimplemented IRP_MN_EJECT received\n");
1480 case IRP_MN_QUERY_BUS_INFORMATION
:
1481 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
1484 case IRP_MN_QUERY_CAPABILITIES
:
1485 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
1488 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1489 Status
= PdoQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
1492 case IRP_MN_QUERY_DEVICE_TEXT
:
1493 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
1494 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
1497 case IRP_MN_QUERY_ID
:
1498 DPRINT("IRP_MN_QUERY_ID received\n");
1499 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
1502 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1503 DPRINT("Unimplemented IRP_MN_QUERY_ID received\n");
1506 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1507 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
1508 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
1511 case IRP_MN_QUERY_RESOURCES
:
1512 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
1513 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
1516 case IRP_MN_SET_LOCK
:
1517 DPRINT("Unimplemented IRP_MN_SET_LOCK received\n");
1520 case IRP_MN_START_DEVICE
:
1521 Status
= PdoStartDevice(DeviceObject
, Irp
, IrpSp
);
1524 case IRP_MN_QUERY_STOP_DEVICE
:
1525 case IRP_MN_CANCEL_STOP_DEVICE
:
1526 case IRP_MN_STOP_DEVICE
:
1527 case IRP_MN_QUERY_REMOVE_DEVICE
:
1528 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1529 case IRP_MN_SURPRISE_REMOVAL
:
1530 Status
= STATUS_SUCCESS
;
1533 case IRP_MN_REMOVE_DEVICE
:
1535 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1536 PFDO_DEVICE_EXTENSION FdoDeviceExtension
= DeviceExtension
->Fdo
->DeviceExtension
;
1539 /* Remove it from the device list */
1540 KeAcquireSpinLock(&FdoDeviceExtension
->DeviceListLock
, &OldIrql
);
1541 RemoveEntryList(&DeviceExtension
->PciDevice
->ListEntry
);
1542 FdoDeviceExtension
->DeviceListCount
--;
1543 KeReleaseSpinLock(&FdoDeviceExtension
->DeviceListLock
, OldIrql
);
1545 /* Free the device */
1546 ExFreePool(DeviceExtension
->PciDevice
);
1548 /* Complete the IRP */
1549 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1550 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1553 IoDeleteDevice(DeviceObject
);
1554 return STATUS_SUCCESS
;
1557 case IRP_MN_QUERY_INTERFACE
:
1558 DPRINT("IRP_MN_QUERY_INTERFACE received\n");
1559 Status
= PdoQueryInterface(DeviceObject
, Irp
, IrpSp
);
1562 case IRP_MN_READ_CONFIG
:
1563 DPRINT("IRP_MN_READ_CONFIG received\n");
1564 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1567 case IRP_MN_WRITE_CONFIG
:
1568 DPRINT("IRP_MN_WRITE_CONFIG received\n");
1569 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1572 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1573 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS received\n");
1575 Irp
->IoStatus
.Status
= Status
;
1579 DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp
->MinorFunction
);
1583 if (Status
!= STATUS_PENDING
)
1585 Irp
->IoStatus
.Status
= Status
;
1586 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1589 DPRINT("Leaving. Status 0x%X\n", Status
);
1596 PDEVICE_OBJECT DeviceObject
,
1599 * FUNCTION: Handle power management IRPs for the child device
1601 * DeviceObject = Pointer to physical device object of the child device
1602 * Irp = Pointer to IRP that should be handled
1607 PIO_STACK_LOCATION IrpSp
;
1612 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1614 switch (IrpSp
->MinorFunction
)
1616 case IRP_MN_SET_POWER
:
1617 Status
= PdoSetPower(DeviceObject
, Irp
, IrpSp
);
1621 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1622 Status
= STATUS_NOT_IMPLEMENTED
;
1626 if (Status
!= STATUS_PENDING
)
1628 Irp
->IoStatus
.Status
= Status
;
1629 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1632 DPRINT("Leaving. Status 0x%X\n", Status
);