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
10 #include <ddk/ntddk.h>
11 #include <ddk/ntifs.h>
13 #include <ddk/wdmguid.h>
20 /*** PRIVATE *****************************************************************/
24 IN PDEVICE_OBJECT DeviceObject
,
26 PIO_STACK_LOCATION IrpSp
)
28 PPDO_DEVICE_EXTENSION DeviceExtension
;
33 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
35 Status
= STATUS_SUCCESS
;
37 switch (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
)
39 case DeviceTextDescription
:
40 DPRINT("DeviceTextDescription\n");
41 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceExtension
->DeviceDescription
.Buffer
;
44 case DeviceTextLocationInformation
:
45 DPRINT("DeviceTextLocationInformation\n");
46 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceExtension
->DeviceLocation
.Buffer
;
50 Irp
->IoStatus
.Information
= 0;
51 Status
= STATUS_INVALID_PARAMETER
;
60 IN PDEVICE_OBJECT DeviceObject
,
62 PIO_STACK_LOCATION IrpSp
)
64 PPDO_DEVICE_EXTENSION DeviceExtension
;
65 UNICODE_STRING String
;
70 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
72 // Irp->IoStatus.Information = 0;
74 Status
= STATUS_SUCCESS
;
76 RtlInitUnicodeString(&String
, NULL
);
78 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
79 case BusQueryDeviceID
:
80 Status
= RtlDuplicateUnicodeString(
81 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
82 &DeviceExtension
->DeviceID
,
85 DPRINT("DeviceID: %S\n", String
.Buffer
);
87 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
90 case BusQueryHardwareIDs
:
91 Status
= RtlDuplicateUnicodeString(
92 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
93 &DeviceExtension
->HardwareIDs
,
96 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
99 case BusQueryCompatibleIDs
:
100 Status
= RtlDuplicateUnicodeString(
101 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
102 &DeviceExtension
->CompatibleIDs
,
105 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
108 case BusQueryInstanceID
:
109 Status
= RtlDuplicateUnicodeString(
110 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
111 &DeviceExtension
->InstanceID
,
114 DPRINT("InstanceID: %S\n", String
.Buffer
);
116 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
119 case BusQueryDeviceSerialNumber
:
121 Status
= STATUS_NOT_IMPLEMENTED
;
129 PdoQueryBusInformation(
130 IN PDEVICE_OBJECT DeviceObject
,
132 PIO_STACK_LOCATION IrpSp
)
134 PPDO_DEVICE_EXTENSION DeviceExtension
;
135 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
136 PPNP_BUS_INFORMATION BusInformation
;
140 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
141 FdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
142 BusInformation
= ExAllocatePool(PagedPool
, sizeof(PNP_BUS_INFORMATION
));
143 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
144 if (BusInformation
!= NULL
)
146 BusInformation
->BusTypeGuid
= GUID_BUS_TYPE_PCI
;
147 BusInformation
->LegacyBusType
= PCIBus
;
148 BusInformation
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
150 return STATUS_SUCCESS
;
153 return STATUS_INSUFFICIENT_RESOURCES
;
158 PdoQueryCapabilities(
159 IN PDEVICE_OBJECT DeviceObject
,
161 PIO_STACK_LOCATION IrpSp
)
163 PPDO_DEVICE_EXTENSION DeviceExtension
;
164 PDEVICE_CAPABILITIES DeviceCapabilities
;
168 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
169 DeviceCapabilities
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
171 if (DeviceCapabilities
->Version
!= 1)
172 return STATUS_UNSUCCESSFUL
;
174 DeviceCapabilities
->UniqueID
= FALSE
;
175 DeviceCapabilities
->Address
= DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
;
176 DeviceCapabilities
->UINumber
= (ULONG
)-1; /* FIXME */
178 return STATUS_SUCCESS
;
183 PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension
,
195 /* Save original value */
196 Size
= HalGetBusDataByOffset(PCIConfiguration
,
197 DeviceExtension
->PciDevice
->BusNumber
,
198 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
202 if (Size
!= sizeof(ULONG
))
204 DPRINT1("Wrong size %lu\n", Size
);
208 BaseValue
= (OrigValue
& 0x00000001) ? (OrigValue
& ~0x3) : (OrigValue
& ~0xF);
212 /* Set magic value */
213 NewValue
= (ULONG
)-1;
214 Size
= HalSetBusDataByOffset(PCIConfiguration
,
215 DeviceExtension
->PciDevice
->BusNumber
,
216 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
220 if (Size
!= sizeof(ULONG
))
222 DPRINT1("Wrong size %lu\n", Size
);
226 /* Get the range length */
227 Size
= HalGetBusDataByOffset(PCIConfiguration
,
228 DeviceExtension
->PciDevice
->BusNumber
,
229 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
233 if (Size
!= sizeof(ULONG
))
235 DPRINT1("Wrong size %lu\n", Size
);
239 /* Restore original value */
240 Size
= HalSetBusDataByOffset(PCIConfiguration
,
241 DeviceExtension
->PciDevice
->BusNumber
,
242 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
246 if (Size
!= sizeof(ULONG
))
248 DPRINT1("Wrong size %lu\n", Size
);
254 DPRINT("Unused address register\n");
261 XLength
= ~((NewValue
& 0x00000001) ? (NewValue
& ~0x3) : (NewValue
& ~0xF)) + 1;
264 DbgPrint("BaseAddress 0x%08lx Length 0x%08lx",
267 if (NewValue
& 0x00000001)
269 DbgPrint(" IO range");
273 DbgPrint(" Memory range");
274 if ((NewValue
& 0x00000006) == 0)
276 DbgPrint(" in 32-Bit address space");
278 else if ((NewValue
& 0x00000006) == 2)
280 DbgPrint(" below 1BM ");
282 else if ((NewValue
& 0x00000006) == 4)
284 DbgPrint(" in 64-Bit address space");
287 if (NewValue
& 0x00000008)
289 DbgPrint(" prefetchable");
297 *Flags
= (NewValue
& 0x00000001) ? (NewValue
& 0x3) : (NewValue
& 0xF);
304 PdoQueryResourceRequirements(
305 IN PDEVICE_OBJECT DeviceObject
,
307 PIO_STACK_LOCATION IrpSp
)
309 PPDO_DEVICE_EXTENSION DeviceExtension
;
310 PCI_COMMON_CONFIG PciConfig
;
311 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
312 PIO_RESOURCE_DESCRIPTOR Descriptor
;
321 DPRINT("PdoQueryResourceRequirements() called\n");
323 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
325 /* Get PCI configuration space */
326 Size
= HalGetBusData(PCIConfiguration
,
327 DeviceExtension
->PciDevice
->BusNumber
,
328 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
330 PCI_COMMON_HDR_LENGTH
);
331 DPRINT("Size %lu\n", Size
);
332 if (Size
< PCI_COMMON_HDR_LENGTH
)
334 Irp
->IoStatus
.Information
= 0;
335 return STATUS_UNSUCCESSFUL
;
338 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
340 /* Count required resource descriptors */
342 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
344 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
346 if (!PdoGetRangeLength(DeviceExtension
,
357 /* FIXME: Check ROM address */
359 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
362 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
364 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
366 if (!PdoGetRangeLength(DeviceExtension
,
376 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
379 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
384 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
389 Irp
->IoStatus
.Information
= 0;
390 return STATUS_SUCCESS
;
393 /* Calculate the resource list size */
394 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
);
397 ListSize
+= ((ResCount
- 1) * sizeof(IO_RESOURCE_DESCRIPTOR
));
400 DPRINT("ListSize %lu (0x%lx)\n", ListSize
, ListSize
);
402 /* Allocate the resource requirements list */
403 ResourceList
= ExAllocatePool(PagedPool
,
405 if (ResourceList
== NULL
)
407 Irp
->IoStatus
.Information
= 0;
408 return STATUS_INSUFFICIENT_RESOURCES
;
411 ResourceList
->ListSize
= ListSize
;
412 ResourceList
->InterfaceType
= PCIBus
;
413 ResourceList
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
414 ResourceList
->SlotNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
;
415 ResourceList
->AlternativeLists
= 1;
417 ResourceList
->List
[0].Version
= 1;
418 ResourceList
->List
[0].Revision
= 1;
419 ResourceList
->List
[0].Count
= ResCount
;
421 Descriptor
= &ResourceList
->List
[0].Descriptors
[0];
422 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
424 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
426 if (!PdoGetRangeLength(DeviceExtension
,
432 DPRINT1("PdoGetRangeLength() failed\n");
438 DPRINT("Unused address register\n");
442 /* Set preferred descriptor */
443 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
444 if (Flags
& PCI_ADDRESS_IO_SPACE
)
446 Descriptor
->Type
= CmResourceTypePort
;
447 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
448 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
449 CM_RESOURCE_PORT_16_BIT_DECODE
|
450 CM_RESOURCE_PORT_POSITIVE_DECODE
;
452 Descriptor
->u
.Port
.Length
= Length
;
453 Descriptor
->u
.Port
.Alignment
= 1;
454 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
455 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
459 Descriptor
->Type
= CmResourceTypeMemory
;
460 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
461 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
463 Descriptor
->u
.Memory
.Length
= Length
;
464 Descriptor
->u
.Memory
.Alignment
= 1;
465 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
466 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
470 /* Set alternative descriptor */
471 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
472 if (Flags
& PCI_ADDRESS_IO_SPACE
)
474 Descriptor
->Type
= CmResourceTypePort
;
475 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
476 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
477 CM_RESOURCE_PORT_16_BIT_DECODE
|
478 CM_RESOURCE_PORT_POSITIVE_DECODE
;
480 Descriptor
->u
.Port
.Length
= Length
;
481 Descriptor
->u
.Port
.Alignment
= Length
;
482 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
483 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
487 Descriptor
->Type
= CmResourceTypeMemory
;
488 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
489 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
491 Descriptor
->u
.Memory
.Length
= Length
;
492 Descriptor
->u
.Memory
.Alignment
= Length
;
493 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
494 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
499 /* FIXME: Check ROM address */
501 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
503 Descriptor
->Option
= 0; /* Required */
504 Descriptor
->Type
= CmResourceTypeInterrupt
;
505 Descriptor
->ShareDisposition
= CmResourceShareShared
;
506 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
508 Descriptor
->u
.Interrupt
.MinimumVector
= 0;
509 Descriptor
->u
.Interrupt
.MaximumVector
= 0xFF;
512 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
514 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
516 if (!PdoGetRangeLength(DeviceExtension
,
522 DPRINT1("PdoGetRangeLength() failed\n");
528 DPRINT("Unused address register\n");
532 /* Set preferred descriptor */
533 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
534 if (Flags
& PCI_ADDRESS_IO_SPACE
)
536 Descriptor
->Type
= CmResourceTypePort
;
537 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
538 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
539 CM_RESOURCE_PORT_16_BIT_DECODE
|
540 CM_RESOURCE_PORT_POSITIVE_DECODE
;
542 Descriptor
->u
.Port
.Length
= Length
;
543 Descriptor
->u
.Port
.Alignment
= 1;
544 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
545 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
549 Descriptor
->Type
= CmResourceTypeMemory
;
550 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
551 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
553 Descriptor
->u
.Memory
.Length
= Length
;
554 Descriptor
->u
.Memory
.Alignment
= 1;
555 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
556 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
560 /* Set alternative descriptor */
561 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
562 if (Flags
& PCI_ADDRESS_IO_SPACE
)
564 Descriptor
->Type
= CmResourceTypePort
;
565 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
566 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
567 CM_RESOURCE_PORT_16_BIT_DECODE
|
568 CM_RESOURCE_PORT_POSITIVE_DECODE
;
570 Descriptor
->u
.Port
.Length
= Length
;
571 Descriptor
->u
.Port
.Alignment
= Length
;
572 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
573 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
577 Descriptor
->Type
= CmResourceTypeMemory
;
578 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
579 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
581 Descriptor
->u
.Memory
.Length
= Length
;
582 Descriptor
->u
.Memory
.Alignment
= Length
;
583 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
584 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
588 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
590 Descriptor
->Option
= 0; /* Required */
591 Descriptor
->Type
= CmResourceTypeBusNumber
;
592 Descriptor
->ShareDisposition
= CmResourceShareShared
;
593 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
595 Descriptor
->u
.BusNumber
.MinBusNumber
=
596 Descriptor
->u
.BusNumber
.MaxBusNumber
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SubordinateBus
;
597 Descriptor
->u
.BusNumber
.Length
= 1;
598 Descriptor
->u
.BusNumber
.Reserved
= 0;
601 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
603 /* FIXME: Add Cardbus bridge resources */
606 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
608 return STATUS_SUCCESS
;
614 IN PDEVICE_OBJECT DeviceObject
,
616 PIO_STACK_LOCATION IrpSp
)
618 PPDO_DEVICE_EXTENSION DeviceExtension
;
619 PCI_COMMON_CONFIG PciConfig
;
620 PCM_RESOURCE_LIST ResourceList
;
621 PCM_PARTIAL_RESOURCE_LIST PartialList
;
622 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
631 DPRINT("PdoQueryResources() called\n");
633 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
635 /* Get PCI configuration space */
636 Size
= HalGetBusData(PCIConfiguration
,
637 DeviceExtension
->PciDevice
->BusNumber
,
638 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
640 PCI_COMMON_HDR_LENGTH
);
641 DPRINT("Size %lu\n", Size
);
642 if (Size
< PCI_COMMON_HDR_LENGTH
)
644 Irp
->IoStatus
.Information
= 0;
645 return STATUS_UNSUCCESSFUL
;
648 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
650 /* Count required resource descriptors */
652 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
654 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
656 if (!PdoGetRangeLength(DeviceExtension
,
667 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
668 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
671 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
673 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
675 if (!PdoGetRangeLength(DeviceExtension
,
686 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
692 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
697 Irp
->IoStatus
.Information
= 0;
698 return STATUS_SUCCESS
;
701 /* Calculate the resource list size */
702 ListSize
= sizeof(CM_RESOURCE_LIST
);
705 ListSize
+= ((ResCount
- 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
708 /* Allocate the resource list */
709 ResourceList
= ExAllocatePool(PagedPool
,
711 if (ResourceList
== NULL
)
712 return STATUS_INSUFFICIENT_RESOURCES
;
714 ResourceList
->Count
= 1;
715 ResourceList
->List
[0].InterfaceType
= PCIConfiguration
;
716 ResourceList
->List
[0].BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
718 PartialList
= &ResourceList
->List
[0].PartialResourceList
;
719 PartialList
->Version
= 0;
720 PartialList
->Revision
= 0;
721 PartialList
->Count
= ResCount
;
723 Descriptor
= &PartialList
->PartialDescriptors
[0];
724 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
726 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
728 if (!PdoGetRangeLength(DeviceExtension
,
734 DPRINT1("PdoGetRangeLength() failed\n");
740 DPRINT("Unused address register\n");
744 if (Flags
& PCI_ADDRESS_IO_SPACE
)
746 Descriptor
->Type
= CmResourceTypePort
;
747 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
748 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
749 Descriptor
->u
.Port
.Start
.QuadPart
=
751 Descriptor
->u
.Port
.Length
= Length
;
755 Descriptor
->Type
= CmResourceTypeMemory
;
756 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
757 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
758 Descriptor
->u
.Memory
.Start
.QuadPart
=
760 Descriptor
->u
.Memory
.Length
= Length
;
766 /* Add interrupt resource */
767 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
768 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
770 Descriptor
->Type
= CmResourceTypeInterrupt
;
771 Descriptor
->ShareDisposition
= CmResourceShareShared
;
772 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
773 Descriptor
->u
.Interrupt
.Level
= PciConfig
.u
.type0
.InterruptLine
;
774 Descriptor
->u
.Interrupt
.Vector
= PciConfig
.u
.type0
.InterruptLine
;
775 Descriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
778 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
780 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
782 if (!PdoGetRangeLength(DeviceExtension
,
788 DPRINT1("PdoGetRangeLength() failed\n");
794 DPRINT("Unused address register\n");
798 if (Flags
& PCI_ADDRESS_IO_SPACE
)
800 Descriptor
->Type
= CmResourceTypePort
;
801 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
802 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
803 Descriptor
->u
.Port
.Start
.QuadPart
=
805 Descriptor
->u
.Port
.Length
= Length
;
809 Descriptor
->Type
= CmResourceTypeMemory
;
810 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
811 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
812 Descriptor
->u
.Memory
.Start
.QuadPart
=
814 Descriptor
->u
.Memory
.Length
= Length
;
820 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
825 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
827 return STATUS_SUCCESS
;
833 IN PDEVICE_OBJECT DeviceObject
,
835 PIO_STACK_LOCATION IrpSp
)
837 PPDO_DEVICE_EXTENSION DeviceExtension
;
840 DPRINT1("PdoReadConfig() called\n");
842 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
845 if (IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
!= PCI_WHICHSPACE_CONFIG
)
846 return STATUS_NOT_SUPPORTED
;
849 /* Get PCI configuration space */
850 Size
= HalGetBusDataByOffset(PCIConfiguration
,
851 DeviceExtension
->PciDevice
->BusNumber
,
852 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
853 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
854 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
855 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
856 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
858 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
859 Irp
->IoStatus
.Information
= 0;
860 return STATUS_UNSUCCESSFUL
;
863 Irp
->IoStatus
.Information
= Size
;
865 return STATUS_SUCCESS
;
871 IN PDEVICE_OBJECT DeviceObject
,
873 PIO_STACK_LOCATION IrpSp
)
875 PPDO_DEVICE_EXTENSION DeviceExtension
;
878 DPRINT1("PdoWriteConfig() called\n");
880 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
883 if (IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
!= PCI_WHICHSPACE_CONFIG
)
884 return STATUS_NOT_SUPPORTED
;
887 /* Get PCI configuration space */
888 Size
= HalSetBusDataByOffset(PCIConfiguration
,
889 DeviceExtension
->PciDevice
->BusNumber
,
890 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
891 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
892 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
893 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
894 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
896 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
897 Irp
->IoStatus
.Information
= 0;
898 return STATUS_UNSUCCESSFUL
;
901 Irp
->IoStatus
.Information
= Size
;
903 return STATUS_SUCCESS
;
909 IN PDEVICE_OBJECT DeviceObject
,
911 PIO_STACK_LOCATION IrpSp
)
913 PPDO_DEVICE_EXTENSION DeviceExtension
;
918 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
920 if (IrpSp
->Parameters
.Power
.Type
== DevicePowerState
) {
921 Status
= STATUS_SUCCESS
;
922 switch (IrpSp
->Parameters
.Power
.State
.SystemState
) {
924 Status
= STATUS_UNSUCCESSFUL
;
927 Status
= STATUS_UNSUCCESSFUL
;
934 /*** PUBLIC ******************************************************************/
938 PDEVICE_OBJECT DeviceObject
,
941 * FUNCTION: Handle Plug and Play IRPs for the child device
943 * DeviceObject = Pointer to physical device object of the child device
944 * Irp = Pointer to IRP that should be handled
949 PIO_STACK_LOCATION IrpSp
;
954 Status
= Irp
->IoStatus
.Status
;
956 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
958 switch (IrpSp
->MinorFunction
) {
960 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
967 case IRP_MN_QUERY_BUS_INFORMATION
:
968 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
971 case IRP_MN_QUERY_CAPABILITIES
:
972 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
976 case IRP_MN_QUERY_DEVICE_RELATIONS
:
977 /* FIXME: Possibly handle for RemovalRelations */
981 case IRP_MN_QUERY_DEVICE_TEXT
:
982 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
983 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
986 case IRP_MN_QUERY_ID
:
987 DPRINT("IRP_MN_QUERY_ID received\n");
988 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
992 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
996 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
997 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
998 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
1001 case IRP_MN_QUERY_RESOURCES
:
1002 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
1003 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
1007 case IRP_MN_SET_LOCK
:
1011 case IRP_MN_START_DEVICE
:
1012 case IRP_MN_QUERY_STOP_DEVICE
:
1013 case IRP_MN_CANCEL_STOP_DEVICE
:
1014 case IRP_MN_STOP_DEVICE
:
1015 case IRP_MN_QUERY_REMOVE_DEVICE
:
1016 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1017 case IRP_MN_REMOVE_DEVICE
:
1018 case IRP_MN_SURPRISE_REMOVAL
:
1019 Status
= STATUS_SUCCESS
;
1022 case IRP_MN_READ_CONFIG
:
1023 DPRINT1("IRP_MN_READ_CONFIG received\n");
1024 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1027 case IRP_MN_WRITE_CONFIG
:
1028 DPRINT1("IRP_MN_WRITE_CONFIG received\n");
1029 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1033 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1037 if (Status
!= STATUS_PENDING
) {
1038 Irp
->IoStatus
.Status
= Status
;
1039 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1042 DPRINT("Leaving. Status 0x%X\n", Status
);
1049 PDEVICE_OBJECT DeviceObject
,
1052 * FUNCTION: Handle power management IRPs for the child device
1054 * DeviceObject = Pointer to physical device object of the child device
1055 * Irp = Pointer to IRP that should be handled
1060 PIO_STACK_LOCATION IrpSp
;
1065 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1067 switch (IrpSp
->MinorFunction
) {
1068 case IRP_MN_SET_POWER
:
1069 Status
= PdoSetPower(DeviceObject
, Irp
, IrpSp
);
1073 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1074 Status
= STATUS_NOT_IMPLEMENTED
;
1078 if (Status
!= STATUS_PENDING
) {
1079 Irp
->IoStatus
.Status
= Status
;
1080 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1083 DPRINT("Leaving. Status 0x%X\n", Status
);