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
19 #define DBGPRINT(...) DbgPrint(__VA_ARGS__)
24 #define PCI_ADDRESS_MEMORY_ADDRESS_MASK_64 0xfffffffffffffff0ull
25 #define PCI_ADDRESS_IO_ADDRESS_MASK_64 0xfffffffffffffffcull
27 /*** PRIVATE *****************************************************************/
31 IN PDEVICE_OBJECT DeviceObject
,
33 PIO_STACK_LOCATION IrpSp
)
35 PPDO_DEVICE_EXTENSION DeviceExtension
;
36 UNICODE_STRING String
;
41 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
43 switch (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
)
45 case DeviceTextDescription
:
46 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
47 &DeviceExtension
->DeviceDescription
,
50 DPRINT("DeviceTextDescription\n");
51 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
54 case DeviceTextLocationInformation
:
55 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
56 &DeviceExtension
->DeviceLocation
,
59 DPRINT("DeviceTextLocationInformation\n");
60 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
64 Irp
->IoStatus
.Information
= 0;
65 Status
= STATUS_INVALID_PARAMETER
;
75 IN PDEVICE_OBJECT DeviceObject
,
77 PIO_STACK_LOCATION IrpSp
)
79 PPDO_DEVICE_EXTENSION DeviceExtension
;
80 UNICODE_STRING String
;
85 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
87 // Irp->IoStatus.Information = 0;
89 Status
= STATUS_SUCCESS
;
91 RtlInitUnicodeString(&String
, NULL
);
93 switch (IrpSp
->Parameters
.QueryId
.IdType
)
95 case BusQueryDeviceID
:
96 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
97 &DeviceExtension
->DeviceID
,
100 DPRINT("DeviceID: %S\n", String
.Buffer
);
102 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
105 case BusQueryHardwareIDs
:
106 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
107 &DeviceExtension
->HardwareIDs
,
110 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
113 case BusQueryCompatibleIDs
:
114 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
115 &DeviceExtension
->CompatibleIDs
,
118 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
121 case BusQueryInstanceID
:
122 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
123 &DeviceExtension
->InstanceID
,
126 DPRINT("InstanceID: %S\n", String
.Buffer
);
128 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
131 case BusQueryDeviceSerialNumber
:
133 Status
= STATUS_NOT_IMPLEMENTED
;
141 PdoQueryBusInformation(
142 IN PDEVICE_OBJECT DeviceObject
,
144 PIO_STACK_LOCATION IrpSp
)
146 PPDO_DEVICE_EXTENSION DeviceExtension
;
147 PPNP_BUS_INFORMATION BusInformation
;
149 UNREFERENCED_PARAMETER(IrpSp
);
152 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
153 BusInformation
= ExAllocatePoolWithTag(PagedPool
, sizeof(PNP_BUS_INFORMATION
), TAG_PCI
);
154 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
155 if (BusInformation
!= NULL
)
157 BusInformation
->BusTypeGuid
= GUID_BUS_TYPE_PCI
;
158 BusInformation
->LegacyBusType
= PCIBus
;
159 BusInformation
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
161 return STATUS_SUCCESS
;
164 return STATUS_INSUFFICIENT_RESOURCES
;
169 PdoQueryCapabilities(
170 IN PDEVICE_OBJECT DeviceObject
,
172 PIO_STACK_LOCATION IrpSp
)
174 PPDO_DEVICE_EXTENSION DeviceExtension
;
175 PDEVICE_CAPABILITIES DeviceCapabilities
;
176 ULONG DeviceNumber
, FunctionNumber
;
178 UNREFERENCED_PARAMETER(Irp
);
181 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
182 DeviceCapabilities
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
184 if (DeviceCapabilities
->Version
!= 1)
185 return STATUS_UNSUCCESSFUL
;
187 DeviceNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.DeviceNumber
;
188 FunctionNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.FunctionNumber
;
190 DeviceCapabilities
->UniqueID
= FALSE
;
191 DeviceCapabilities
->Address
= ((DeviceNumber
<< 16) & 0xFFFF0000) + (FunctionNumber
& 0xFFFF);
192 DeviceCapabilities
->UINumber
= MAXULONG
; /* FIXME */
194 return STATUS_SUCCESS
;
198 PdoReadPciBar(PPDO_DEVICE_EXTENSION DeviceExtension
,
200 PULONG OriginalValue
,
206 /* Read the original value */
207 Size
= HalGetBusDataByOffset(PCIConfiguration
,
208 DeviceExtension
->PciDevice
->BusNumber
,
209 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
213 if (Size
!= sizeof(ULONG
))
215 DPRINT1("Wrong size %lu\n", Size
);
219 /* Write all ones to determine which bits are held to zero */
221 Size
= HalSetBusDataByOffset(PCIConfiguration
,
222 DeviceExtension
->PciDevice
->BusNumber
,
223 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
227 if (Size
!= sizeof(ULONG
))
229 DPRINT1("Wrong size %lu\n", Size
);
233 /* Get the range length */
234 Size
= HalGetBusDataByOffset(PCIConfiguration
,
235 DeviceExtension
->PciDevice
->BusNumber
,
236 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
240 if (Size
!= sizeof(ULONG
))
242 DPRINT1("Wrong size %lu\n", Size
);
246 /* Restore original value */
247 Size
= HalSetBusDataByOffset(PCIConfiguration
,
248 DeviceExtension
->PciDevice
->BusNumber
,
249 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
253 if (Size
!= sizeof(ULONG
))
255 DPRINT1("Wrong size %lu\n", Size
);
263 PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension
,
269 PULONGLONG MaximumAddress
)
287 /* Compute the offset of this BAR in PCI config space */
288 Offset
= 0x10 + Bar
* 4;
290 /* Assume this is a 32-bit BAR until we find wrong */
293 /* Initialize BAR values to zero */
294 OriginalValue
.Bar
= 0ULL;
297 /* Read the first BAR */
298 if (!PdoReadPciBar(DeviceExtension
, Offset
,
299 &OriginalValue
.Bars
.Bar0
,
300 &NewValue
.Bars
.Bar0
))
305 /* Check if this is a memory BAR */
306 if (!(OriginalValue
.Bars
.Bar0
& PCI_ADDRESS_IO_SPACE
))
308 /* Write the maximum address if the caller asked for it */
309 if (MaximumAddress
!= NULL
)
311 if ((OriginalValue
.Bars
.Bar0
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == PCI_TYPE_32BIT
)
313 *MaximumAddress
= 0x00000000FFFFFFFFULL
;
315 else if ((OriginalValue
.Bars
.Bar0
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == PCI_TYPE_20BIT
)
317 *MaximumAddress
= 0x00000000000FFFFFULL
;
319 else if ((OriginalValue
.Bars
.Bar0
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == PCI_TYPE_64BIT
)
321 *MaximumAddress
= 0xFFFFFFFFFFFFFFFFULL
;
325 /* Check if this is a 64-bit BAR */
326 if ((OriginalValue
.Bars
.Bar0
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == PCI_TYPE_64BIT
)
328 /* We've now consumed the next BAR too */
331 /* Read the next BAR */
332 if (!PdoReadPciBar(DeviceExtension
, Offset
+ 4,
333 &OriginalValue
.Bars
.Bar1
,
334 &NewValue
.Bars
.Bar1
))
342 /* Write the maximum I/O port address */
343 if (MaximumAddress
!= NULL
)
345 *MaximumAddress
= 0x00000000FFFFFFFFULL
;
349 if (NewValue
.Bar
== 0)
351 DPRINT("Unused address register\n");
358 *Base
= OriginalValue
.Bar
& PCI_ADDRESS_MEMORY_ADDRESS_MASK_64
;
360 *Length
= ~((NewValue
.Bar
& PCI_ADDRESS_IO_SPACE
)
361 ? (NewValue
.Bar
& PCI_ADDRESS_IO_ADDRESS_MASK_64
)
362 : (NewValue
.Bar
& PCI_ADDRESS_MEMORY_ADDRESS_MASK_64
)) + 1;
364 *Flags
= (NewValue
.Bar
& PCI_ADDRESS_IO_SPACE
)
365 ? (NewValue
.Bar
& ~PCI_ADDRESS_IO_ADDRESS_MASK_64
)
366 : (NewValue
.Bar
& ~PCI_ADDRESS_MEMORY_ADDRESS_MASK_64
);
373 PdoQueryResourceRequirements(
374 IN PDEVICE_OBJECT DeviceObject
,
376 PIO_STACK_LOCATION IrpSp
)
378 PPDO_DEVICE_EXTENSION DeviceExtension
;
379 PCI_COMMON_CONFIG PciConfig
;
380 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
381 PIO_RESOURCE_DESCRIPTOR Descriptor
;
389 ULONGLONG MaximumAddress
;
391 UNREFERENCED_PARAMETER(IrpSp
);
392 DPRINT("PdoQueryResourceRequirements() called\n");
394 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
396 /* Get PCI configuration space */
397 Size
= HalGetBusData(PCIConfiguration
,
398 DeviceExtension
->PciDevice
->BusNumber
,
399 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
401 PCI_COMMON_HDR_LENGTH
);
402 DPRINT("Size %lu\n", Size
);
403 if (Size
< PCI_COMMON_HDR_LENGTH
)
405 Irp
->IoStatus
.Information
= 0;
406 return STATUS_UNSUCCESSFUL
;
409 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
411 /* Count required resource descriptors */
413 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
415 for (Bar
= 0; Bar
< PCI_TYPE0_ADDRESSES
;)
417 if (!PdoGetRangeLength(DeviceExtension
,
430 /* FIXME: Check ROM address */
432 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
435 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
437 for (Bar
= 0; Bar
< PCI_TYPE1_ADDRESSES
;)
439 if (!PdoGetRangeLength(DeviceExtension
,
452 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
455 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
457 /* FIXME: Count Cardbus bridge resources */
461 DPRINT1("Unsupported header type %d\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
466 Irp
->IoStatus
.Information
= 0;
467 return STATUS_SUCCESS
;
470 /* Calculate the resource list size */
471 ListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
[0].Descriptors
) +
472 ResCount
* sizeof(IO_RESOURCE_DESCRIPTOR
);
474 DPRINT("ListSize %lu (0x%lx)\n", ListSize
, ListSize
);
476 /* Allocate the resource requirements list */
477 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
480 if (ResourceList
== NULL
)
482 Irp
->IoStatus
.Information
= 0;
483 return STATUS_INSUFFICIENT_RESOURCES
;
486 RtlZeroMemory(ResourceList
, ListSize
);
487 ResourceList
->ListSize
= ListSize
;
488 ResourceList
->InterfaceType
= PCIBus
;
489 ResourceList
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
490 ResourceList
->SlotNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
;
491 ResourceList
->AlternativeLists
= 1;
493 ResourceList
->List
[0].Version
= 1;
494 ResourceList
->List
[0].Revision
= 1;
495 ResourceList
->List
[0].Count
= ResCount
;
497 Descriptor
= &ResourceList
->List
[0].Descriptors
[0];
498 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
500 for (Bar
= 0; Bar
< PCI_TYPE0_ADDRESSES
;)
502 if (!PdoGetRangeLength(DeviceExtension
,
510 DPRINT1("PdoGetRangeLength() failed\n");
516 DPRINT("Unused address register\n");
520 /* Set preferred descriptor */
521 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
522 if (Flags
& PCI_ADDRESS_IO_SPACE
)
524 Descriptor
->Type
= CmResourceTypePort
;
525 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
526 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
527 CM_RESOURCE_PORT_16_BIT_DECODE
|
528 CM_RESOURCE_PORT_POSITIVE_DECODE
;
530 Descriptor
->u
.Port
.Length
= Length
;
531 Descriptor
->u
.Port
.Alignment
= 1;
532 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= Base
;
533 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= Base
+ Length
- 1;
537 Descriptor
->Type
= CmResourceTypeMemory
;
538 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
539 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
|
540 (Flags
& PCI_ADDRESS_MEMORY_PREFETCHABLE
) ? CM_RESOURCE_MEMORY_PREFETCHABLE
: 0;
542 Descriptor
->u
.Memory
.Length
= Length
;
543 Descriptor
->u
.Memory
.Alignment
= 1;
544 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= Base
;
545 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= Base
+ Length
- 1;
549 /* Set alternative descriptor */
550 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
551 if (Flags
& PCI_ADDRESS_IO_SPACE
)
553 Descriptor
->Type
= CmResourceTypePort
;
554 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
555 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
556 CM_RESOURCE_PORT_16_BIT_DECODE
|
557 CM_RESOURCE_PORT_POSITIVE_DECODE
;
559 Descriptor
->u
.Port
.Length
= Length
;
560 Descriptor
->u
.Port
.Alignment
= Length
;
561 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= 0;
562 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= MaximumAddress
;
566 Descriptor
->Type
= CmResourceTypeMemory
;
567 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
568 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
|
569 (Flags
& PCI_ADDRESS_MEMORY_PREFETCHABLE
) ? CM_RESOURCE_MEMORY_PREFETCHABLE
: 0;
571 Descriptor
->u
.Memory
.Length
= Length
;
572 Descriptor
->u
.Memory
.Alignment
= Length
;
573 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= 0;
574 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= MaximumAddress
;
579 /* FIXME: Check ROM address */
581 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
583 Descriptor
->Option
= 0; /* Required */
584 Descriptor
->Type
= CmResourceTypeInterrupt
;
585 Descriptor
->ShareDisposition
= CmResourceShareShared
;
586 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
588 Descriptor
->u
.Interrupt
.MinimumVector
= 0;
589 Descriptor
->u
.Interrupt
.MaximumVector
= 0xFF;
592 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
594 for (Bar
= 0; Bar
< PCI_TYPE1_ADDRESSES
;)
596 if (!PdoGetRangeLength(DeviceExtension
,
604 DPRINT1("PdoGetRangeLength() failed\n");
610 DPRINT("Unused address register\n");
614 /* Set preferred descriptor */
615 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
616 if (Flags
& PCI_ADDRESS_IO_SPACE
)
618 Descriptor
->Type
= CmResourceTypePort
;
619 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
620 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
621 CM_RESOURCE_PORT_16_BIT_DECODE
|
622 CM_RESOURCE_PORT_POSITIVE_DECODE
;
624 Descriptor
->u
.Port
.Length
= Length
;
625 Descriptor
->u
.Port
.Alignment
= 1;
626 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= Base
;
627 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= Base
+ Length
- 1;
631 Descriptor
->Type
= CmResourceTypeMemory
;
632 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
633 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
|
634 (Flags
& PCI_ADDRESS_MEMORY_PREFETCHABLE
) ? CM_RESOURCE_MEMORY_PREFETCHABLE
: 0;
636 Descriptor
->u
.Memory
.Length
= Length
;
637 Descriptor
->u
.Memory
.Alignment
= 1;
638 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= Base
;
639 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= Base
+ Length
- 1;
643 /* Set alternative descriptor */
644 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
645 if (Flags
& PCI_ADDRESS_IO_SPACE
)
647 Descriptor
->Type
= CmResourceTypePort
;
648 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
649 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
650 CM_RESOURCE_PORT_16_BIT_DECODE
|
651 CM_RESOURCE_PORT_POSITIVE_DECODE
;
653 Descriptor
->u
.Port
.Length
= Length
;
654 Descriptor
->u
.Port
.Alignment
= Length
;
655 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= 0;
656 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= MaximumAddress
;
660 Descriptor
->Type
= CmResourceTypeMemory
;
661 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
662 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
|
663 (Flags
& PCI_ADDRESS_MEMORY_PREFETCHABLE
) ? CM_RESOURCE_MEMORY_PREFETCHABLE
: 0;
665 Descriptor
->u
.Memory
.Length
= Length
;
666 Descriptor
->u
.Memory
.Alignment
= Length
;
667 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= 0;
668 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= MaximumAddress
;
673 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
675 Descriptor
->Option
= 0; /* Required */
676 Descriptor
->Type
= CmResourceTypeBusNumber
;
677 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
679 ResourceList
->BusNumber
=
680 Descriptor
->u
.BusNumber
.MinBusNumber
=
681 Descriptor
->u
.BusNumber
.MaxBusNumber
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
682 Descriptor
->u
.BusNumber
.Length
= 1;
683 Descriptor
->u
.BusNumber
.Reserved
= 0;
686 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
688 /* FIXME: Add Cardbus bridge resources */
691 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
693 return STATUS_SUCCESS
;
699 IN PDEVICE_OBJECT DeviceObject
,
701 PIO_STACK_LOCATION IrpSp
)
703 PPDO_DEVICE_EXTENSION DeviceExtension
;
704 PCI_COMMON_CONFIG PciConfig
;
705 PCM_RESOURCE_LIST ResourceList
;
706 PCM_PARTIAL_RESOURCE_LIST PartialList
;
707 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
716 DPRINT("PdoQueryResources() called\n");
718 UNREFERENCED_PARAMETER(IrpSp
);
719 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
721 /* Get PCI configuration space */
722 Size
= HalGetBusData(PCIConfiguration
,
723 DeviceExtension
->PciDevice
->BusNumber
,
724 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
726 PCI_COMMON_HDR_LENGTH
);
727 DPRINT("Size %lu\n", Size
);
728 if (Size
< PCI_COMMON_HDR_LENGTH
)
730 Irp
->IoStatus
.Information
= 0;
731 return STATUS_UNSUCCESSFUL
;
734 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
736 /* Count required resource descriptors */
738 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
740 for (Bar
= 0; Bar
< PCI_TYPE0_ADDRESSES
;)
742 if (!PdoGetRangeLength(DeviceExtension
,
755 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
756 (PciConfig
.u
.type0
.InterruptLine
!= 0) &&
757 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
760 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
762 for (Bar
= 0; Bar
< PCI_TYPE1_ADDRESSES
;)
764 if (!PdoGetRangeLength(DeviceExtension
,
777 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
780 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
782 /* FIXME: Count Cardbus bridge resources */
786 DPRINT1("Unsupported header type %d\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
791 Irp
->IoStatus
.Information
= 0;
792 return STATUS_SUCCESS
;
795 /* Calculate the resource list size */
796 ListSize
= FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.PartialDescriptors
) +
797 ResCount
* sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
799 /* Allocate the resource list */
800 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
803 if (ResourceList
== NULL
)
804 return STATUS_INSUFFICIENT_RESOURCES
;
806 RtlZeroMemory(ResourceList
, ListSize
);
807 ResourceList
->Count
= 1;
808 ResourceList
->List
[0].InterfaceType
= PCIBus
;
809 ResourceList
->List
[0].BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
811 PartialList
= &ResourceList
->List
[0].PartialResourceList
;
812 PartialList
->Version
= 1;
813 PartialList
->Revision
= 1;
814 PartialList
->Count
= ResCount
;
816 Descriptor
= &PartialList
->PartialDescriptors
[0];
817 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
819 for (Bar
= 0; Bar
< PCI_TYPE0_ADDRESSES
;)
821 if (!PdoGetRangeLength(DeviceExtension
,
832 DPRINT("Unused address register\n");
836 if (Flags
& PCI_ADDRESS_IO_SPACE
)
838 Descriptor
->Type
= CmResourceTypePort
;
839 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
840 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
841 CM_RESOURCE_PORT_16_BIT_DECODE
|
842 CM_RESOURCE_PORT_POSITIVE_DECODE
;
843 Descriptor
->u
.Port
.Start
.QuadPart
= (ULONGLONG
)Base
;
844 Descriptor
->u
.Port
.Length
= Length
;
846 /* Enable IO space access */
847 DeviceExtension
->PciDevice
->EnableIoSpace
= TRUE
;
851 Descriptor
->Type
= CmResourceTypeMemory
;
852 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
853 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
|
854 (Flags
& PCI_ADDRESS_MEMORY_PREFETCHABLE
) ? CM_RESOURCE_MEMORY_PREFETCHABLE
: 0;
855 Descriptor
->u
.Memory
.Start
.QuadPart
= (ULONGLONG
)Base
;
856 Descriptor
->u
.Memory
.Length
= Length
;
858 /* Enable memory space access */
859 DeviceExtension
->PciDevice
->EnableMemorySpace
= TRUE
;
865 /* Add interrupt resource */
866 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
867 (PciConfig
.u
.type0
.InterruptLine
!= 0) &&
868 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
870 Descriptor
->Type
= CmResourceTypeInterrupt
;
871 Descriptor
->ShareDisposition
= CmResourceShareShared
;
872 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
873 Descriptor
->u
.Interrupt
.Level
= PciConfig
.u
.type0
.InterruptLine
;
874 Descriptor
->u
.Interrupt
.Vector
= PciConfig
.u
.type0
.InterruptLine
;
875 Descriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
878 /* Allow bus master mode */
879 DeviceExtension
->PciDevice
->EnableBusMaster
= TRUE
;
881 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
883 for (Bar
= 0; Bar
< PCI_TYPE1_ADDRESSES
;)
885 if (!PdoGetRangeLength(DeviceExtension
,
896 DPRINT("Unused address register\n");
900 if (Flags
& PCI_ADDRESS_IO_SPACE
)
902 Descriptor
->Type
= CmResourceTypePort
;
903 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
904 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
905 CM_RESOURCE_PORT_16_BIT_DECODE
|
906 CM_RESOURCE_PORT_POSITIVE_DECODE
;
907 Descriptor
->u
.Port
.Start
.QuadPart
= (ULONGLONG
)Base
;
908 Descriptor
->u
.Port
.Length
= Length
;
910 /* Enable IO space access */
911 DeviceExtension
->PciDevice
->EnableIoSpace
= TRUE
;
915 Descriptor
->Type
= CmResourceTypeMemory
;
916 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
917 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
|
918 (Flags
& PCI_ADDRESS_MEMORY_PREFETCHABLE
) ? CM_RESOURCE_MEMORY_PREFETCHABLE
: 0;
919 Descriptor
->u
.Memory
.Start
.QuadPart
= (ULONGLONG
)Base
;
920 Descriptor
->u
.Memory
.Length
= Length
;
922 /* Enable memory space access */
923 DeviceExtension
->PciDevice
->EnableMemorySpace
= TRUE
;
929 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
931 Descriptor
->Type
= CmResourceTypeBusNumber
;
932 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
934 ResourceList
->List
[0].BusNumber
=
935 Descriptor
->u
.BusNumber
.Start
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
936 Descriptor
->u
.BusNumber
.Length
= 1;
937 Descriptor
->u
.BusNumber
.Reserved
= 0;
940 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
942 /* FIXME: Add Cardbus bridge resources */
945 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
947 return STATUS_SUCCESS
;
955 PPDO_DEVICE_EXTENSION DeviceExtension
;
957 DPRINT("InterfaceReference(%p)\n", Context
);
959 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
960 InterlockedIncrement(&DeviceExtension
->References
);
965 InterfaceDereference(
968 PPDO_DEVICE_EXTENSION DeviceExtension
;
970 DPRINT("InterfaceDereference(%p)\n", Context
);
972 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
973 InterlockedDecrement(&DeviceExtension
->References
);
976 static TRANSLATE_BUS_ADDRESS InterfaceBusTranslateBusAddress
;
981 InterfaceBusTranslateBusAddress(
983 IN PHYSICAL_ADDRESS BusAddress
,
985 IN OUT PULONG AddressSpace
,
986 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
988 PPDO_DEVICE_EXTENSION DeviceExtension
;
990 DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
991 Context
, BusAddress
, Length
, AddressSpace
, TranslatedAddress
);
993 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
995 return HalTranslateBusAddress(PCIBus
,
996 DeviceExtension
->PciDevice
->BusNumber
,
1002 static GET_DMA_ADAPTER InterfaceBusGetDmaAdapter
;
1007 InterfaceBusGetDmaAdapter(
1009 IN PDEVICE_DESCRIPTION DeviceDescription
,
1010 OUT PULONG NumberOfMapRegisters
)
1012 DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
1013 Context
, DeviceDescription
, NumberOfMapRegisters
);
1014 return (PDMA_ADAPTER
)HalGetAdapter(DeviceDescription
, NumberOfMapRegisters
);
1017 static GET_SET_DEVICE_DATA InterfaceBusSetBusData
;
1022 InterfaceBusSetBusData(
1029 PPDO_DEVICE_EXTENSION DeviceExtension
;
1032 DPRINT("InterfaceBusSetBusData(%p 0x%lx %p 0x%lx 0x%lx)\n",
1033 Context
, DataType
, Buffer
, Offset
, Length
);
1035 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
1037 DPRINT("Unknown DataType %lu\n", DataType
);
1041 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1043 /* Get PCI configuration space */
1044 Size
= HalSetBusDataByOffset(PCIConfiguration
,
1045 DeviceExtension
->PciDevice
->BusNumber
,
1046 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1053 static GET_SET_DEVICE_DATA InterfaceBusGetBusData
;
1058 InterfaceBusGetBusData(
1065 PPDO_DEVICE_EXTENSION DeviceExtension
;
1068 DPRINT("InterfaceBusGetBusData(%p 0x%lx %p 0x%lx 0x%lx) called\n",
1069 Context
, DataType
, Buffer
, Offset
, Length
);
1071 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
1073 DPRINT("Unknown DataType %lu\n", DataType
);
1077 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1079 /* Get PCI configuration space */
1080 Size
= HalGetBusDataByOffset(PCIConfiguration
,
1081 DeviceExtension
->PciDevice
->BusNumber
,
1082 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1090 static BOOLEAN NTAPI
1091 InterfacePciDevicePresent(
1094 IN UCHAR RevisionID
,
1095 IN USHORT SubVendorID
,
1096 IN USHORT SubSystemID
,
1099 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1100 PPCI_DEVICE PciDevice
;
1101 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1103 BOOLEAN Found
= FALSE
;
1105 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1106 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1107 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1109 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1111 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1112 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1113 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1115 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1116 if (PciDevice
->PciConfig
.VendorID
== VendorID
&&
1117 PciDevice
->PciConfig
.DeviceID
== DeviceID
)
1119 if (!(Flags
& PCI_USE_SUBSYSTEM_IDS
) ||
1120 (PciDevice
->PciConfig
.u
.type0
.SubVendorID
== SubVendorID
&&
1121 PciDevice
->PciConfig
.u
.type0
.SubSystemID
== SubSystemID
))
1123 if (!(Flags
& PCI_USE_REVISION
) ||
1124 PciDevice
->PciConfig
.RevisionID
== RevisionID
)
1126 DPRINT("Found the PCI device\n");
1132 CurrentEntry
= CurrentEntry
->Flink
;
1135 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1136 CurrentBus
= CurrentBus
->Flink
;
1138 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1146 IN PPCI_COMMON_CONFIG PciConfig
,
1147 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1149 if ((Parameters
->Flags
& PCI_USE_VENDEV_IDS
) &&
1150 (PciConfig
->VendorID
!= Parameters
->VendorID
||
1151 PciConfig
->DeviceID
!= Parameters
->DeviceID
))
1156 if ((Parameters
->Flags
& PCI_USE_CLASS_SUBCLASS
) &&
1157 (PciConfig
->BaseClass
!= Parameters
->BaseClass
||
1158 PciConfig
->SubClass
!= Parameters
->SubClass
))
1163 if ((Parameters
->Flags
& PCI_USE_PROGIF
) &&
1164 PciConfig
->ProgIf
!= Parameters
->ProgIf
)
1169 if ((Parameters
->Flags
& PCI_USE_SUBSYSTEM_IDS
) &&
1170 (PciConfig
->u
.type0
.SubVendorID
!= Parameters
->SubVendorID
||
1171 PciConfig
->u
.type0
.SubSystemID
!= Parameters
->SubSystemID
))
1176 if ((Parameters
->Flags
& PCI_USE_REVISION
) &&
1177 PciConfig
->RevisionID
!= Parameters
->RevisionID
)
1186 static BOOLEAN NTAPI
1187 InterfacePciDevicePresentEx(
1189 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1191 PPDO_DEVICE_EXTENSION DeviceExtension
;
1192 PFDO_DEVICE_EXTENSION MyFdoDeviceExtension
;
1193 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1194 PPCI_DEVICE PciDevice
;
1195 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1197 BOOLEAN Found
= FALSE
;
1199 DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
1200 Context
, Parameters
);
1202 if (!Parameters
|| Parameters
->Size
!= sizeof(PCI_DEVICE_PRESENCE_PARAMETERS
))
1205 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1206 MyFdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
1208 if (Parameters
->Flags
& PCI_USE_LOCAL_DEVICE
)
1210 return CheckPciDevice(&DeviceExtension
->PciDevice
->PciConfig
, Parameters
);
1213 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1214 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1215 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1217 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1218 if (!(Parameters
->Flags
& PCI_USE_LOCAL_BUS
) || FdoDeviceExtension
== MyFdoDeviceExtension
)
1220 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1221 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1222 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1224 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1226 if (CheckPciDevice(&PciDevice
->PciConfig
, Parameters
))
1228 DPRINT("Found the PCI device\n");
1232 CurrentEntry
= CurrentEntry
->Flink
;
1235 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1237 CurrentBus
= CurrentBus
->Flink
;
1239 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1247 IN PDEVICE_OBJECT DeviceObject
,
1249 PIO_STACK_LOCATION IrpSp
)
1253 UNREFERENCED_PARAMETER(Irp
);
1255 if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1256 &GUID_BUS_INTERFACE_STANDARD
, sizeof(GUID
)) == sizeof(GUID
))
1258 /* BUS_INTERFACE_STANDARD */
1259 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1260 Status
= STATUS_NOT_SUPPORTED
;
1261 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(BUS_INTERFACE_STANDARD
))
1262 Status
= STATUS_BUFFER_TOO_SMALL
;
1265 PBUS_INTERFACE_STANDARD BusInterface
;
1266 BusInterface
= (PBUS_INTERFACE_STANDARD
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1267 BusInterface
->Size
= sizeof(BUS_INTERFACE_STANDARD
);
1268 BusInterface
->Version
= 1;
1269 BusInterface
->TranslateBusAddress
= InterfaceBusTranslateBusAddress
;
1270 BusInterface
->GetDmaAdapter
= InterfaceBusGetDmaAdapter
;
1271 BusInterface
->SetBusData
= InterfaceBusSetBusData
;
1272 BusInterface
->GetBusData
= InterfaceBusGetBusData
;
1273 Status
= STATUS_SUCCESS
;
1276 else if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1277 &GUID_PCI_DEVICE_PRESENT_INTERFACE
, sizeof(GUID
)) == sizeof(GUID
))
1279 /* PCI_DEVICE_PRESENT_INTERFACE */
1280 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1281 Status
= STATUS_NOT_SUPPORTED
;
1282 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(PCI_DEVICE_PRESENT_INTERFACE
))
1283 Status
= STATUS_BUFFER_TOO_SMALL
;
1286 PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface
;
1287 PciDevicePresentInterface
= (PPCI_DEVICE_PRESENT_INTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1288 PciDevicePresentInterface
->Size
= sizeof(PCI_DEVICE_PRESENT_INTERFACE
);
1289 PciDevicePresentInterface
->Version
= 1;
1290 PciDevicePresentInterface
->IsDevicePresent
= InterfacePciDevicePresent
;
1291 PciDevicePresentInterface
->IsDevicePresentEx
= InterfacePciDevicePresentEx
;
1292 Status
= STATUS_SUCCESS
;
1297 /* Not a supported interface */
1298 return STATUS_NOT_SUPPORTED
;
1301 if (NT_SUCCESS(Status
))
1303 /* Add a reference for the returned interface */
1304 PINTERFACE Interface
;
1305 Interface
= (PINTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1306 Interface
->Context
= DeviceObject
;
1307 Interface
->InterfaceReference
= InterfaceReference
;
1308 Interface
->InterfaceDereference
= InterfaceDereference
;
1309 Interface
->InterfaceReference(Interface
->Context
);
1317 IN PDEVICE_OBJECT DeviceObject
,
1319 PIO_STACK_LOCATION IrpSp
)
1321 PCM_RESOURCE_LIST RawResList
= IrpSp
->Parameters
.StartDevice
.AllocatedResources
;
1322 PCM_FULL_RESOURCE_DESCRIPTOR RawFullDesc
;
1323 PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDesc
;
1325 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1329 UNREFERENCED_PARAMETER(Irp
);
1332 return STATUS_SUCCESS
;
1334 /* TODO: Assign the other resources we get to the card */
1336 for (i
= 0; i
< RawResList
->Count
; i
++)
1338 RawFullDesc
= &RawResList
->List
[i
];
1340 for (ii
= 0; ii
< RawFullDesc
->PartialResourceList
.Count
; ii
++)
1342 RawPartialDesc
= &RawFullDesc
->PartialResourceList
.PartialDescriptors
[ii
];
1344 if (RawPartialDesc
->Type
== CmResourceTypeInterrupt
)
1346 DPRINT("Assigning IRQ %u to PCI device 0x%x on bus 0x%x\n",
1347 RawPartialDesc
->u
.Interrupt
.Vector
,
1348 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1349 DeviceExtension
->PciDevice
->BusNumber
);
1351 Irq
= (UCHAR
)RawPartialDesc
->u
.Interrupt
.Vector
;
1352 HalSetBusDataByOffset(PCIConfiguration
,
1353 DeviceExtension
->PciDevice
->BusNumber
,
1354 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1356 0x3c /* PCI_INTERRUPT_LINE */,
1364 DBGPRINT("pci!PdoStartDevice: Enabling command flags for PCI device 0x%x on bus 0x%x: ",
1365 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1366 DeviceExtension
->PciDevice
->BusNumber
);
1367 if (DeviceExtension
->PciDevice
->EnableBusMaster
)
1369 Command
|= PCI_ENABLE_BUS_MASTER
;
1370 DBGPRINT("[Bus master] ");
1373 if (DeviceExtension
->PciDevice
->EnableMemorySpace
)
1375 Command
|= PCI_ENABLE_MEMORY_SPACE
;
1376 DBGPRINT("[Memory space enable] ");
1379 if (DeviceExtension
->PciDevice
->EnableIoSpace
)
1381 Command
|= PCI_ENABLE_IO_SPACE
;
1382 DBGPRINT("[I/O space enable] ");
1389 /* OR with the previous value */
1390 Command
|= DeviceExtension
->PciDevice
->PciConfig
.Command
;
1392 HalSetBusDataByOffset(PCIConfiguration
,
1393 DeviceExtension
->PciDevice
->BusNumber
,
1394 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1396 FIELD_OFFSET(PCI_COMMON_CONFIG
, Command
),
1404 return STATUS_SUCCESS
;
1409 IN PDEVICE_OBJECT DeviceObject
,
1411 PIO_STACK_LOCATION IrpSp
)
1415 DPRINT("PdoReadConfig() called\n");
1417 Size
= InterfaceBusGetBusData(DeviceObject
,
1418 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1419 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1420 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1421 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1423 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1425 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1426 Irp
->IoStatus
.Information
= 0;
1427 return STATUS_UNSUCCESSFUL
;
1430 Irp
->IoStatus
.Information
= Size
;
1432 return STATUS_SUCCESS
;
1438 IN PDEVICE_OBJECT DeviceObject
,
1440 PIO_STACK_LOCATION IrpSp
)
1444 DPRINT1("PdoWriteConfig() called\n");
1446 /* Get PCI configuration space */
1447 Size
= InterfaceBusSetBusData(DeviceObject
,
1448 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1449 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1450 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1451 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1453 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1455 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1456 Irp
->IoStatus
.Information
= 0;
1457 return STATUS_UNSUCCESSFUL
;
1460 Irp
->IoStatus
.Information
= Size
;
1462 return STATUS_SUCCESS
;
1466 PdoQueryDeviceRelations(
1467 IN PDEVICE_OBJECT DeviceObject
,
1469 PIO_STACK_LOCATION IrpSp
)
1471 PDEVICE_RELATIONS DeviceRelations
;
1473 /* We only support TargetDeviceRelation for child PDOs */
1474 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
1475 return Irp
->IoStatus
.Status
;
1477 /* We can do this because we only return 1 PDO for TargetDeviceRelation */
1478 DeviceRelations
= ExAllocatePoolWithTag(PagedPool
, sizeof(*DeviceRelations
), TAG_PCI
);
1479 if (!DeviceRelations
)
1480 return STATUS_INSUFFICIENT_RESOURCES
;
1482 DeviceRelations
->Count
= 1;
1483 DeviceRelations
->Objects
[0] = DeviceObject
;
1485 /* The PnP manager will remove this when it is done with the PDO */
1486 ObReferenceObject(DeviceObject
);
1488 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1490 return STATUS_SUCCESS
;
1494 /*** PUBLIC ******************************************************************/
1498 PDEVICE_OBJECT DeviceObject
,
1501 * FUNCTION: Handle Plug and Play IRPs for the child device
1503 * DeviceObject = Pointer to physical device object of the child device
1504 * Irp = Pointer to IRP that should be handled
1509 PIO_STACK_LOCATION IrpSp
;
1514 Status
= Irp
->IoStatus
.Status
;
1516 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1518 switch (IrpSp
->MinorFunction
)
1520 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1521 DPRINT("Unimplemented IRP_MN_DEVICE_USAGE_NOTIFICATION received\n");
1525 DPRINT("Unimplemented IRP_MN_EJECT received\n");
1528 case IRP_MN_QUERY_BUS_INFORMATION
:
1529 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
1532 case IRP_MN_QUERY_CAPABILITIES
:
1533 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
1536 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1537 Status
= PdoQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
1540 case IRP_MN_QUERY_DEVICE_TEXT
:
1541 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
1542 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
1545 case IRP_MN_QUERY_ID
:
1546 DPRINT("IRP_MN_QUERY_ID received\n");
1547 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
1550 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1551 DPRINT("Unimplemented IRP_MN_QUERY_ID received\n");
1554 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1555 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
1556 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
1559 case IRP_MN_QUERY_RESOURCES
:
1560 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
1561 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
1564 case IRP_MN_SET_LOCK
:
1565 DPRINT("Unimplemented IRP_MN_SET_LOCK received\n");
1568 case IRP_MN_START_DEVICE
:
1569 Status
= PdoStartDevice(DeviceObject
, Irp
, IrpSp
);
1572 case IRP_MN_QUERY_STOP_DEVICE
:
1573 case IRP_MN_CANCEL_STOP_DEVICE
:
1574 case IRP_MN_STOP_DEVICE
:
1575 case IRP_MN_QUERY_REMOVE_DEVICE
:
1576 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1577 case IRP_MN_SURPRISE_REMOVAL
:
1578 Status
= STATUS_SUCCESS
;
1581 case IRP_MN_REMOVE_DEVICE
:
1583 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1584 PFDO_DEVICE_EXTENSION FdoDeviceExtension
= DeviceExtension
->Fdo
->DeviceExtension
;
1587 /* Remove it from the device list */
1588 KeAcquireSpinLock(&FdoDeviceExtension
->DeviceListLock
, &OldIrql
);
1589 RemoveEntryList(&DeviceExtension
->PciDevice
->ListEntry
);
1590 FdoDeviceExtension
->DeviceListCount
--;
1591 KeReleaseSpinLock(&FdoDeviceExtension
->DeviceListLock
, OldIrql
);
1593 /* Free the device */
1594 ExFreePoolWithTag(DeviceExtension
->PciDevice
, TAG_PCI
);
1596 /* Complete the IRP */
1597 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1598 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1601 IoDeleteDevice(DeviceObject
);
1602 return STATUS_SUCCESS
;
1605 case IRP_MN_QUERY_INTERFACE
:
1606 DPRINT("IRP_MN_QUERY_INTERFACE received\n");
1607 Status
= PdoQueryInterface(DeviceObject
, Irp
, IrpSp
);
1610 case IRP_MN_READ_CONFIG
:
1611 DPRINT("IRP_MN_READ_CONFIG received\n");
1612 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1615 case IRP_MN_WRITE_CONFIG
:
1616 DPRINT("IRP_MN_WRITE_CONFIG received\n");
1617 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1620 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1621 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS received\n");
1623 Irp
->IoStatus
.Status
= Status
;
1627 DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp
->MinorFunction
);
1631 if (Status
!= STATUS_PENDING
)
1633 Irp
->IoStatus
.Status
= Status
;
1634 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1637 DPRINT("Leaving. Status 0x%X\n", Status
);
1644 PDEVICE_OBJECT DeviceObject
,
1647 * FUNCTION: Handle power management IRPs for the child device
1649 * DeviceObject = Pointer to physical device object of the child device
1650 * Irp = Pointer to IRP that should be handled
1655 PIO_STACK_LOCATION IrpSp
;
1656 NTSTATUS Status
= Irp
->IoStatus
.Status
;
1660 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1662 switch (IrpSp
->MinorFunction
)
1664 case IRP_MN_QUERY_POWER
:
1665 case IRP_MN_SET_POWER
:
1666 Status
= STATUS_SUCCESS
;
1670 PoStartNextPowerIrp(Irp
);
1671 Irp
->IoStatus
.Status
= Status
;
1672 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1674 DPRINT("Leaving. Status 0x%X\n", Status
);