3 * PROJECT: ReactOS PCI bus driver
5 * PURPOSE: Child device object dispatch routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * 10-09-2001 CSH Created
11 #include <ddk/ntddk.h>
19 DEFINE_GUID(GUID_BUS_TYPE_PCI
, 0xc8ebdfb0L
, 0xb510, 0x11d0, 0x80, 0xe5, 0x00, 0xa0, 0xc9, 0x25, 0x42, 0xe3);
21 /*** PRIVATE *****************************************************************/
25 IN PDEVICE_OBJECT DeviceObject
,
27 PIO_STACK_LOCATION IrpSp
)
29 PPDO_DEVICE_EXTENSION DeviceExtension
;
34 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
36 Status
= STATUS_SUCCESS
;
38 switch (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
)
40 case DeviceTextDescription
:
41 DPRINT("DeviceTextDescription\n");
42 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceExtension
->DeviceDescription
.Buffer
;
45 case DeviceTextLocationInformation
:
46 DPRINT("DeviceTextLocationInformation\n");
47 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceExtension
->DeviceLocation
.Buffer
;
51 Irp
->IoStatus
.Information
= 0;
52 Status
= STATUS_INVALID_PARAMETER
;
61 IN PDEVICE_OBJECT DeviceObject
,
63 PIO_STACK_LOCATION IrpSp
)
65 PPDO_DEVICE_EXTENSION DeviceExtension
;
66 UNICODE_STRING String
;
71 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
73 // Irp->IoStatus.Information = 0;
75 Status
= STATUS_SUCCESS
;
77 RtlInitUnicodeString(&String
, NULL
);
79 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
80 case BusQueryDeviceID
:
81 Status
= PciDuplicateUnicodeString(
83 &DeviceExtension
->DeviceID
,
86 DPRINT("DeviceID: %S\n", String
.Buffer
);
88 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
91 case BusQueryHardwareIDs
:
92 Status
= PciDuplicateUnicodeString(
94 &DeviceExtension
->HardwareIDs
,
97 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
100 case BusQueryCompatibleIDs
:
101 Status
= PciDuplicateUnicodeString(
103 &DeviceExtension
->CompatibleIDs
,
106 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
109 case BusQueryInstanceID
:
110 Status
= PciDuplicateUnicodeString(
112 &DeviceExtension
->InstanceID
,
115 DPRINT("InstanceID: %S\n", String
.Buffer
);
117 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
120 case BusQueryDeviceSerialNumber
:
122 Status
= STATUS_NOT_IMPLEMENTED
;
130 PdoQueryBusInformation(
131 IN PDEVICE_OBJECT DeviceObject
,
133 PIO_STACK_LOCATION IrpSp
)
135 PPDO_DEVICE_EXTENSION DeviceExtension
;
136 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
137 PPNP_BUS_INFORMATION BusInformation
;
141 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
142 FdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->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
->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
;
169 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
170 DeviceCapabilities
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
172 if (DeviceCapabilities
->Version
!= 1)
173 return STATUS_UNSUCCESSFUL
;
175 DeviceCapabilities
->UniqueID
= FALSE
;
176 DeviceCapabilities
->Address
= DeviceExtension
->SlotNumber
.u
.AsULONG
;
177 DeviceCapabilities
->UINumber
= (ULONG
)-1; /* FIXME */
179 return STATUS_SUCCESS
;
184 PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension
,
196 /* Save original value */
197 Size
= HalGetBusDataByOffset(PCIConfiguration
,
198 DeviceExtension
->BusNumber
,
199 DeviceExtension
->SlotNumber
.u
.AsULONG
,
203 if (Size
!= sizeof(ULONG
))
205 DPRINT1("Wrong size %lu\n", Size
);
209 BaseValue
= (OrigValue
& 0x00000001) ? (OrigValue
& ~0x3) : (OrigValue
& ~0xF);
213 /* Set magic value */
214 NewValue
= (ULONG
)-1;
215 Size
= HalSetBusDataByOffset(PCIConfiguration
,
216 DeviceExtension
->BusNumber
,
217 DeviceExtension
->SlotNumber
.u
.AsULONG
,
221 if (Size
!= sizeof(ULONG
))
223 DPRINT1("Wrong size %lu\n", Size
);
227 /* Get the range length */
228 Size
= HalGetBusDataByOffset(PCIConfiguration
,
229 DeviceExtension
->BusNumber
,
230 DeviceExtension
->SlotNumber
.u
.AsULONG
,
234 if (Size
!= sizeof(ULONG
))
236 DPRINT1("Wrong size %lu\n", Size
);
240 /* Restore original value */
241 Size
= HalSetBusDataByOffset(PCIConfiguration
,
242 DeviceExtension
->BusNumber
,
243 DeviceExtension
->SlotNumber
.u
.AsULONG
,
247 if (Size
!= sizeof(ULONG
))
249 DPRINT1("Wrong size %lu\n", Size
);
255 DPRINT("Unused address register\n");
262 XLength
= ~((NewValue
& 0x00000001) ? (NewValue
& ~0x3) : (NewValue
& ~0xF)) + 1;
265 DbgPrint("BaseAddress 0x%08lx Length 0x%08lx",
268 if (NewValue
& 0x00000001)
270 DbgPrint(" IO range");
274 DbgPrint(" Memory range");
275 if ((NewValue
& 0x00000006) == 0)
277 DbgPrint(" in 32-Bit address space");
279 else if ((NewValue
& 0x00000006) == 2)
281 DbgPrint(" below 1BM ");
283 else if ((NewValue
& 0x00000006) == 4)
285 DbgPrint(" in 64-Bit address space");
288 if (NewValue
& 0x00000008)
290 DbgPrint(" prefetchable");
298 *Flags
= (NewValue
& 0x00000001) ? (NewValue
& 0x3) : (NewValue
& 0xF);
305 PdoQueryResourceRequirements(
306 IN PDEVICE_OBJECT DeviceObject
,
308 PIO_STACK_LOCATION IrpSp
)
310 PPDO_DEVICE_EXTENSION DeviceExtension
;
311 PCI_COMMON_CONFIG PciConfig
;
312 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
313 PIO_RESOURCE_DESCRIPTOR Descriptor
;
322 DPRINT("PdoQueryResourceRequirements() called\n");
324 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
326 /* Get PCI configuration space */
327 Size
= HalGetBusData(PCIConfiguration
,
328 DeviceExtension
->BusNumber
,
329 DeviceExtension
->SlotNumber
.u
.AsULONG
,
331 sizeof(PCI_COMMON_CONFIG
));
332 DPRINT("Size %lu\n", Size
);
333 if (Size
< sizeof(PCI_COMMON_CONFIG
))
335 Irp
->IoStatus
.Information
= 0;
336 return STATUS_UNSUCCESSFUL
;
339 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
341 /* Count required resource descriptors */
343 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
345 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
347 if (!PdoGetRangeLength(DeviceExtension
,
358 /* FIXME: Check ROM address */
360 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
363 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
365 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
367 if (!PdoGetRangeLength(DeviceExtension
,
378 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
383 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
388 Irp
->IoStatus
.Information
= 0;
389 return STATUS_SUCCESS
;
392 /* Calculate the resource list size */
393 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
);
396 ListSize
+= ((ResCount
- 1) * sizeof(IO_RESOURCE_DESCRIPTOR
));
399 DPRINT("ListSize %lu (0x%lx)\n", ListSize
, ListSize
);
401 /* Allocate the resource requirements list */
402 ResourceList
= ExAllocatePool(PagedPool
,
404 if (ResourceList
== NULL
)
406 Irp
->IoStatus
.Information
= 0;
407 return STATUS_INSUFFICIENT_RESOURCES
;
410 ResourceList
->ListSize
= ListSize
;
411 ResourceList
->InterfaceType
= PCIBus
;
412 ResourceList
->AlternativeLists
= 1;
414 ResourceList
->List
[0].Version
= 1;
415 ResourceList
->List
[0].Revision
= 1;
416 ResourceList
->List
[0].Count
= ResCount
;
418 Descriptor
= &ResourceList
->List
[0].Descriptors
[0];
419 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 0)
421 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
423 if (!PdoGetRangeLength(DeviceExtension
,
429 DPRINT1("PdoGetRangeLength() failed\n");
435 DPRINT("Unused address register\n");
439 /* Set preferred descriptor */
440 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
441 if (Flags
& PCI_ADDRESS_IO_SPACE
)
443 Descriptor
->Type
= CmResourceTypePort
;
444 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
445 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
446 CM_RESOURCE_PORT_16_BIT_DECODE
|
447 CM_RESOURCE_PORT_POSITIVE_DECODE
;
449 Descriptor
->u
.Port
.Length
= Length
;
450 Descriptor
->u
.Port
.Alignment
= 1;
451 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
452 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
456 Descriptor
->Type
= CmResourceTypeMemory
;
457 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
458 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
460 Descriptor
->u
.Memory
.Length
= Length
;
461 Descriptor
->u
.Memory
.Alignment
= 1;
462 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
463 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
467 /* Set alternative descriptor */
468 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
469 if (Flags
& PCI_ADDRESS_IO_SPACE
)
471 Descriptor
->Type
= CmResourceTypePort
;
472 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
473 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
474 CM_RESOURCE_PORT_16_BIT_DECODE
|
475 CM_RESOURCE_PORT_POSITIVE_DECODE
;
477 Descriptor
->u
.Port
.Length
= Length
;
478 Descriptor
->u
.Port
.Alignment
= Length
;
479 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
480 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
484 Descriptor
->Type
= CmResourceTypeMemory
;
485 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
486 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
488 Descriptor
->u
.Memory
.Length
= Length
;
489 Descriptor
->u
.Memory
.Alignment
= Length
;
490 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
491 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
496 /* FIXME: Check ROM address */
498 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
500 Descriptor
->Option
= 0; /* Required */
501 Descriptor
->Type
= CmResourceTypeInterrupt
;
502 Descriptor
->ShareDisposition
= CmResourceShareShared
;
503 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
505 Descriptor
->u
.Interrupt
.MinimumVector
= 0;
506 Descriptor
->u
.Interrupt
.MaximumVector
= 0xFF;
509 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 1)
511 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
513 if (!PdoGetRangeLength(DeviceExtension
,
519 DPRINT1("PdoGetRangeLength() failed\n");
525 DPRINT("Unused address register\n");
529 /* Set preferred descriptor */
530 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
531 if (Flags
& PCI_ADDRESS_IO_SPACE
)
533 Descriptor
->Type
= CmResourceTypePort
;
534 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
535 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
536 CM_RESOURCE_PORT_16_BIT_DECODE
|
537 CM_RESOURCE_PORT_POSITIVE_DECODE
;
539 Descriptor
->u
.Port
.Length
= Length
;
540 Descriptor
->u
.Port
.Alignment
= 1;
541 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
542 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
546 Descriptor
->Type
= CmResourceTypeMemory
;
547 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
548 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
550 Descriptor
->u
.Memory
.Length
= Length
;
551 Descriptor
->u
.Memory
.Alignment
= 1;
552 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
553 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
557 /* Set alternative descriptor */
558 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
559 if (Flags
& PCI_ADDRESS_IO_SPACE
)
561 Descriptor
->Type
= CmResourceTypePort
;
562 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
563 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
564 CM_RESOURCE_PORT_16_BIT_DECODE
|
565 CM_RESOURCE_PORT_POSITIVE_DECODE
;
567 Descriptor
->u
.Port
.Length
= Length
;
568 Descriptor
->u
.Port
.Alignment
= Length
;
569 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
570 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
574 Descriptor
->Type
= CmResourceTypeMemory
;
575 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
576 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
578 Descriptor
->u
.Memory
.Length
= Length
;
579 Descriptor
->u
.Memory
.Alignment
= Length
;
580 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
581 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
586 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 2)
588 /* FIXME: Add Cardbus bridge resources */
591 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
593 return STATUS_SUCCESS
;
599 IN PDEVICE_OBJECT DeviceObject
,
601 PIO_STACK_LOCATION IrpSp
)
603 PPDO_DEVICE_EXTENSION DeviceExtension
;
604 PCI_COMMON_CONFIG PciConfig
;
605 PCM_RESOURCE_LIST ResourceList
;
606 PCM_PARTIAL_RESOURCE_LIST PartialList
;
607 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
616 DPRINT("PdoQueryResources() called\n");
618 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
620 /* Get PCI configuration space */
621 Size
= HalGetBusData(PCIConfiguration
,
622 DeviceExtension
->BusNumber
,
623 DeviceExtension
->SlotNumber
.u
.AsULONG
,
625 sizeof(PCI_COMMON_CONFIG
));
626 DPRINT("Size %lu\n", Size
);
627 if (Size
< sizeof(PCI_COMMON_CONFIG
))
629 Irp
->IoStatus
.Information
= 0;
630 return STATUS_UNSUCCESSFUL
;
633 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
635 /* Count required resource descriptors */
637 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 0)
639 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
641 if (!PdoGetRangeLength(DeviceExtension
,
652 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
653 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
656 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 1)
658 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
660 if (!PdoGetRangeLength(DeviceExtension
,
671 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 2)
677 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
682 Irp
->IoStatus
.Information
= 0;
683 return STATUS_SUCCESS
;
686 /* Calculate the resource list size */
687 ListSize
= sizeof(CM_RESOURCE_LIST
);
690 ListSize
+= ((ResCount
- 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
693 /* Allocate the resource list */
694 ResourceList
= ExAllocatePool(PagedPool
,
696 if (ResourceList
== NULL
)
697 return STATUS_INSUFFICIENT_RESOURCES
;
699 ResourceList
->Count
= 1;
700 ResourceList
->List
[0].InterfaceType
= PCIConfiguration
;
701 ResourceList
->List
[0].BusNumber
= DeviceExtension
->BusNumber
;
703 PartialList
= &ResourceList
->List
[0].PartialResourceList
;
704 PartialList
->Version
= 0;
705 PartialList
->Revision
= 0;
706 PartialList
->Count
= ResCount
;
708 Descriptor
= &PartialList
->PartialDescriptors
[0];
709 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 0)
711 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
713 if (!PdoGetRangeLength(DeviceExtension
,
719 DPRINT1("PdoGetRangeLength() failed\n");
725 DPRINT("Unused address register\n");
729 if (Flags
& PCI_ADDRESS_IO_SPACE
)
731 Descriptor
->Type
= CmResourceTypePort
;
732 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
733 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
734 Descriptor
->u
.Port
.Start
.QuadPart
=
736 Descriptor
->u
.Port
.Length
= Length
;
740 Descriptor
->Type
= CmResourceTypeMemory
;
741 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
742 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
743 Descriptor
->u
.Memory
.Start
.QuadPart
=
745 Descriptor
->u
.Memory
.Length
= Length
;
751 /* Add interrupt resource */
752 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
753 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
755 Descriptor
->Type
= CmResourceTypeInterrupt
;
756 Descriptor
->ShareDisposition
= CmResourceShareShared
;
757 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
758 Descriptor
->u
.Interrupt
.Level
= PciConfig
.u
.type0
.InterruptLine
;
759 Descriptor
->u
.Interrupt
.Vector
= PciConfig
.u
.type0
.InterruptLine
;
760 Descriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
763 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 1)
765 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
767 if (!PdoGetRangeLength(DeviceExtension
,
773 DPRINT1("PdoGetRangeLength() failed\n");
779 DPRINT("Unused address register\n");
783 if (Flags
& PCI_ADDRESS_IO_SPACE
)
785 Descriptor
->Type
= CmResourceTypePort
;
786 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
787 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
788 Descriptor
->u
.Port
.Start
.QuadPart
=
790 Descriptor
->u
.Port
.Length
= Length
;
794 Descriptor
->Type
= CmResourceTypeMemory
;
795 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
796 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
797 Descriptor
->u
.Memory
.Start
.QuadPart
=
799 Descriptor
->u
.Memory
.Length
= Length
;
805 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 2)
810 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
812 return STATUS_SUCCESS
;
818 IN PDEVICE_OBJECT DeviceObject
,
820 PIO_STACK_LOCATION IrpSp
)
822 PPDO_DEVICE_EXTENSION DeviceExtension
;
825 DPRINT1("PdoReadConfig() called\n");
827 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
830 if (IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
!= PCI_WHICHSPACE_CONFIG
)
831 return STATUS_NOT_SUPPORTED
;
834 /* Get PCI configuration space */
835 Size
= HalGetBusDataByOffset(PCIConfiguration
,
836 DeviceExtension
->BusNumber
,
837 DeviceExtension
->SlotNumber
.u
.AsULONG
,
838 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
839 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
840 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
841 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
843 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
844 Irp
->IoStatus
.Information
= 0;
845 return STATUS_UNSUCCESSFUL
;
848 Irp
->IoStatus
.Information
= Size
;
850 return STATUS_SUCCESS
;
856 IN PDEVICE_OBJECT DeviceObject
,
858 PIO_STACK_LOCATION IrpSp
)
860 PPDO_DEVICE_EXTENSION DeviceExtension
;
863 DPRINT1("PdoWriteConfig() called\n");
865 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
868 if (IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
!= PCI_WHICHSPACE_CONFIG
)
869 return STATUS_NOT_SUPPORTED
;
872 /* Get PCI configuration space */
873 Size
= HalSetBusDataByOffset(PCIConfiguration
,
874 DeviceExtension
->BusNumber
,
875 DeviceExtension
->SlotNumber
.u
.AsULONG
,
876 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
877 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
878 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
879 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
881 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
882 Irp
->IoStatus
.Information
= 0;
883 return STATUS_UNSUCCESSFUL
;
886 Irp
->IoStatus
.Information
= Size
;
888 return STATUS_SUCCESS
;
894 IN PDEVICE_OBJECT DeviceObject
,
896 PIO_STACK_LOCATION IrpSp
)
898 PPDO_DEVICE_EXTENSION DeviceExtension
;
903 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
905 if (IrpSp
->Parameters
.Power
.Type
== DevicePowerState
) {
906 Status
= STATUS_SUCCESS
;
907 switch (IrpSp
->Parameters
.Power
.State
.SystemState
) {
909 Status
= STATUS_UNSUCCESSFUL
;
912 Status
= STATUS_UNSUCCESSFUL
;
919 /*** PUBLIC ******************************************************************/
923 PDEVICE_OBJECT DeviceObject
,
926 * FUNCTION: Handle Plug and Play IRPs for the child device
928 * DeviceObject = Pointer to physical device object of the child device
929 * Irp = Pointer to IRP that should be handled
934 PIO_STACK_LOCATION IrpSp
;
939 Status
= Irp
->IoStatus
.Status
;
941 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
943 switch (IrpSp
->MinorFunction
) {
945 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
952 case IRP_MN_QUERY_BUS_INFORMATION
:
953 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
956 case IRP_MN_QUERY_CAPABILITIES
:
957 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
961 case IRP_MN_QUERY_DEVICE_RELATIONS
:
962 /* FIXME: Possibly handle for RemovalRelations */
966 case IRP_MN_QUERY_DEVICE_TEXT
:
967 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
968 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
971 case IRP_MN_QUERY_ID
:
972 DPRINT("IRP_MN_QUERY_ID received\n");
973 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
977 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
981 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
982 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
983 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
986 case IRP_MN_QUERY_RESOURCES
:
987 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
988 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
992 case IRP_MN_SET_LOCK
:
996 case IRP_MN_START_DEVICE
:
997 case IRP_MN_QUERY_STOP_DEVICE
:
998 case IRP_MN_CANCEL_STOP_DEVICE
:
999 case IRP_MN_STOP_DEVICE
:
1000 case IRP_MN_QUERY_REMOVE_DEVICE
:
1001 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1002 case IRP_MN_REMOVE_DEVICE
:
1003 case IRP_MN_SURPRISE_REMOVAL
:
1004 Status
= STATUS_SUCCESS
;
1007 case IRP_MN_READ_CONFIG
:
1008 DPRINT1("IRP_MN_READ_CONFIG received\n");
1009 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1012 case IRP_MN_WRITE_CONFIG
:
1013 DPRINT1("IRP_MN_WRITE_CONFIG received\n");
1014 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1018 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1022 if (Status
!= STATUS_PENDING
) {
1023 Irp
->IoStatus
.Status
= Status
;
1024 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1027 DPRINT("Leaving. Status 0x%X\n", Status
);
1034 PDEVICE_OBJECT DeviceObject
,
1037 * FUNCTION: Handle power management IRPs for the child device
1039 * DeviceObject = Pointer to physical device object of the child device
1040 * Irp = Pointer to IRP that should be handled
1045 PIO_STACK_LOCATION IrpSp
;
1050 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1052 switch (IrpSp
->MinorFunction
) {
1053 case IRP_MN_SET_POWER
:
1054 Status
= PdoSetPower(DeviceObject
, Irp
, IrpSp
);
1058 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1059 Status
= STATUS_NOT_IMPLEMENTED
;
1063 if (Status
!= STATUS_PENDING
) {
1064 Irp
->IoStatus
.Status
= Status
;
1065 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1068 DPRINT("Leaving. Status 0x%X\n", Status
);