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
15 /*** PRIVATE *****************************************************************/
19 IN PDEVICE_OBJECT DeviceObject
,
21 PIO_STACK_LOCATION IrpSp
)
23 PPDO_DEVICE_EXTENSION DeviceExtension
;
28 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
30 Status
= STATUS_SUCCESS
;
32 switch (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
)
34 case DeviceTextDescription
:
35 DPRINT("DeviceTextDescription\n");
36 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceExtension
->DeviceDescription
.Buffer
;
39 case DeviceTextLocationInformation
:
40 DPRINT("DeviceTextLocationInformation\n");
41 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceExtension
->DeviceLocation
.Buffer
;
45 Irp
->IoStatus
.Information
= 0;
46 Status
= STATUS_INVALID_PARAMETER
;
55 IN PDEVICE_OBJECT DeviceObject
,
57 PIO_STACK_LOCATION IrpSp
)
59 PPDO_DEVICE_EXTENSION DeviceExtension
;
60 UNICODE_STRING String
;
65 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
67 // Irp->IoStatus.Information = 0;
69 Status
= STATUS_SUCCESS
;
71 RtlInitUnicodeString(&String
, NULL
);
73 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
74 case BusQueryDeviceID
:
75 Status
= RtlDuplicateUnicodeString(
76 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
77 &DeviceExtension
->DeviceID
,
80 DPRINT("DeviceID: %S\n", String
.Buffer
);
82 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
85 case BusQueryHardwareIDs
:
86 Status
= RtlDuplicateUnicodeString(
87 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
88 &DeviceExtension
->HardwareIDs
,
91 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
94 case BusQueryCompatibleIDs
:
95 Status
= RtlDuplicateUnicodeString(
96 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
97 &DeviceExtension
->CompatibleIDs
,
100 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
103 case BusQueryInstanceID
:
104 Status
= RtlDuplicateUnicodeString(
105 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
106 &DeviceExtension
->InstanceID
,
109 DPRINT("InstanceID: %S\n", String
.Buffer
);
111 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
114 case BusQueryDeviceSerialNumber
:
116 Status
= STATUS_NOT_IMPLEMENTED
;
124 PdoQueryBusInformation(
125 IN PDEVICE_OBJECT DeviceObject
,
127 PIO_STACK_LOCATION IrpSp
)
129 PPDO_DEVICE_EXTENSION DeviceExtension
;
130 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
131 PPNP_BUS_INFORMATION BusInformation
;
135 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
136 FdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
137 BusInformation
= ExAllocatePool(PagedPool
, sizeof(PNP_BUS_INFORMATION
));
138 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
139 if (BusInformation
!= NULL
)
141 BusInformation
->BusTypeGuid
= GUID_BUS_TYPE_PCI
;
142 BusInformation
->LegacyBusType
= PCIBus
;
143 BusInformation
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
145 return STATUS_SUCCESS
;
148 return STATUS_INSUFFICIENT_RESOURCES
;
153 PdoQueryCapabilities(
154 IN PDEVICE_OBJECT DeviceObject
,
156 PIO_STACK_LOCATION IrpSp
)
158 PPDO_DEVICE_EXTENSION DeviceExtension
;
159 PDEVICE_CAPABILITIES DeviceCapabilities
;
163 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
164 DeviceCapabilities
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
166 if (DeviceCapabilities
->Version
!= 1)
167 return STATUS_UNSUCCESSFUL
;
169 DeviceCapabilities
->UniqueID
= FALSE
;
170 DeviceCapabilities
->Address
= DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
;
171 DeviceCapabilities
->UINumber
= (ULONG
)-1; /* FIXME */
173 return STATUS_SUCCESS
;
178 PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension
,
190 /* Save original value */
191 Size
= HalGetBusDataByOffset(PCIConfiguration
,
192 DeviceExtension
->PciDevice
->BusNumber
,
193 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
197 if (Size
!= sizeof(ULONG
))
199 DPRINT1("Wrong size %lu\n", Size
);
203 BaseValue
= (OrigValue
& 0x00000001) ? (OrigValue
& ~0x3) : (OrigValue
& ~0xF);
207 /* Set magic value */
208 NewValue
= (ULONG
)-1;
209 Size
= HalSetBusDataByOffset(PCIConfiguration
,
210 DeviceExtension
->PciDevice
->BusNumber
,
211 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
215 if (Size
!= sizeof(ULONG
))
217 DPRINT1("Wrong size %lu\n", Size
);
221 /* Get the range length */
222 Size
= HalGetBusDataByOffset(PCIConfiguration
,
223 DeviceExtension
->PciDevice
->BusNumber
,
224 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
228 if (Size
!= sizeof(ULONG
))
230 DPRINT1("Wrong size %lu\n", Size
);
234 /* Restore original value */
235 Size
= HalSetBusDataByOffset(PCIConfiguration
,
236 DeviceExtension
->PciDevice
->BusNumber
,
237 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
241 if (Size
!= sizeof(ULONG
))
243 DPRINT1("Wrong size %lu\n", Size
);
249 DPRINT("Unused address register\n");
256 XLength
= ~((NewValue
& 0x00000001) ? (NewValue
& ~0x3) : (NewValue
& ~0xF)) + 1;
259 DbgPrint("BaseAddress 0x%08lx Length 0x%08lx",
262 if (NewValue
& 0x00000001)
264 DbgPrint(" IO range");
268 DbgPrint(" Memory range");
269 if ((NewValue
& 0x00000006) == 0)
271 DbgPrint(" in 32-Bit address space");
273 else if ((NewValue
& 0x00000006) == 2)
275 DbgPrint(" below 1BM ");
277 else if ((NewValue
& 0x00000006) == 4)
279 DbgPrint(" in 64-Bit address space");
282 if (NewValue
& 0x00000008)
284 DbgPrint(" prefetchable");
292 *Flags
= (NewValue
& 0x00000001) ? (NewValue
& 0x3) : (NewValue
& 0xF);
299 PdoQueryResourceRequirements(
300 IN PDEVICE_OBJECT DeviceObject
,
302 PIO_STACK_LOCATION IrpSp
)
304 PPDO_DEVICE_EXTENSION DeviceExtension
;
305 PCI_COMMON_CONFIG PciConfig
;
306 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
307 PIO_RESOURCE_DESCRIPTOR Descriptor
;
316 DPRINT("PdoQueryResourceRequirements() called\n");
318 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
320 /* Get PCI configuration space */
321 Size
= HalGetBusData(PCIConfiguration
,
322 DeviceExtension
->PciDevice
->BusNumber
,
323 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
325 PCI_COMMON_HDR_LENGTH
);
326 DPRINT("Size %lu\n", Size
);
327 if (Size
< PCI_COMMON_HDR_LENGTH
)
329 Irp
->IoStatus
.Information
= 0;
330 return STATUS_UNSUCCESSFUL
;
333 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
335 /* Count required resource descriptors */
337 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
339 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
341 if (!PdoGetRangeLength(DeviceExtension
,
352 /* FIXME: Check ROM address */
354 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
357 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
359 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
361 if (!PdoGetRangeLength(DeviceExtension
,
371 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
374 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
376 /* FIXME: Count Cardbus bridge resources */
380 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
385 Irp
->IoStatus
.Information
= 0;
386 return STATUS_SUCCESS
;
389 /* Calculate the resource list size */
390 ListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
->Descriptors
)
391 + ResCount
* sizeof(IO_RESOURCE_DESCRIPTOR
);
393 DPRINT("ListSize %lu (0x%lx)\n", ListSize
, ListSize
);
395 /* Allocate the resource requirements list */
396 ResourceList
= ExAllocatePool(PagedPool
,
398 if (ResourceList
== NULL
)
400 Irp
->IoStatus
.Information
= 0;
401 return STATUS_INSUFFICIENT_RESOURCES
;
404 RtlZeroMemory(ResourceList
, ListSize
);
405 ResourceList
->ListSize
= ListSize
;
406 ResourceList
->InterfaceType
= PCIBus
;
407 ResourceList
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
408 ResourceList
->SlotNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
;
409 ResourceList
->AlternativeLists
= 1;
411 ResourceList
->List
[0].Version
= 1;
412 ResourceList
->List
[0].Revision
= 1;
413 ResourceList
->List
[0].Count
= ResCount
;
415 Descriptor
= &ResourceList
->List
[0].Descriptors
[0];
416 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
418 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
420 if (!PdoGetRangeLength(DeviceExtension
,
426 DPRINT1("PdoGetRangeLength() failed\n");
432 DPRINT("Unused address register\n");
436 /* Set preferred descriptor */
437 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
438 if (Flags
& PCI_ADDRESS_IO_SPACE
)
440 Descriptor
->Type
= CmResourceTypePort
;
441 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
442 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
443 CM_RESOURCE_PORT_16_BIT_DECODE
|
444 CM_RESOURCE_PORT_POSITIVE_DECODE
;
446 Descriptor
->u
.Port
.Length
= Length
;
447 Descriptor
->u
.Port
.Alignment
= 1;
448 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
449 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
453 Descriptor
->Type
= CmResourceTypeMemory
;
454 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
455 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
457 Descriptor
->u
.Memory
.Length
= Length
;
458 Descriptor
->u
.Memory
.Alignment
= 1;
459 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
460 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
464 /* Set alternative descriptor */
465 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
466 if (Flags
& PCI_ADDRESS_IO_SPACE
)
468 Descriptor
->Type
= CmResourceTypePort
;
469 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
470 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
471 CM_RESOURCE_PORT_16_BIT_DECODE
|
472 CM_RESOURCE_PORT_POSITIVE_DECODE
;
474 Descriptor
->u
.Port
.Length
= Length
;
475 Descriptor
->u
.Port
.Alignment
= Length
;
476 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
477 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
481 Descriptor
->Type
= CmResourceTypeMemory
;
482 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
483 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
485 Descriptor
->u
.Memory
.Length
= Length
;
486 Descriptor
->u
.Memory
.Alignment
= Length
;
487 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
488 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
493 /* FIXME: Check ROM address */
495 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
497 Descriptor
->Option
= 0; /* Required */
498 Descriptor
->Type
= CmResourceTypeInterrupt
;
499 Descriptor
->ShareDisposition
= CmResourceShareShared
;
500 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
502 Descriptor
->u
.Interrupt
.MinimumVector
= 0;
503 Descriptor
->u
.Interrupt
.MaximumVector
= 0xFF;
506 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
508 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
510 if (!PdoGetRangeLength(DeviceExtension
,
516 DPRINT1("PdoGetRangeLength() failed\n");
522 DPRINT("Unused address register\n");
526 /* Set preferred descriptor */
527 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
528 if (Flags
& PCI_ADDRESS_IO_SPACE
)
530 Descriptor
->Type
= CmResourceTypePort
;
531 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
532 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
533 CM_RESOURCE_PORT_16_BIT_DECODE
|
534 CM_RESOURCE_PORT_POSITIVE_DECODE
;
536 Descriptor
->u
.Port
.Length
= Length
;
537 Descriptor
->u
.Port
.Alignment
= 1;
538 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
539 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
543 Descriptor
->Type
= CmResourceTypeMemory
;
544 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
545 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
547 Descriptor
->u
.Memory
.Length
= Length
;
548 Descriptor
->u
.Memory
.Alignment
= 1;
549 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
550 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
554 /* Set alternative descriptor */
555 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
556 if (Flags
& PCI_ADDRESS_IO_SPACE
)
558 Descriptor
->Type
= CmResourceTypePort
;
559 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
560 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
561 CM_RESOURCE_PORT_16_BIT_DECODE
|
562 CM_RESOURCE_PORT_POSITIVE_DECODE
;
564 Descriptor
->u
.Port
.Length
= Length
;
565 Descriptor
->u
.Port
.Alignment
= Length
;
566 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
567 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
571 Descriptor
->Type
= CmResourceTypeMemory
;
572 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
573 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
575 Descriptor
->u
.Memory
.Length
= Length
;
576 Descriptor
->u
.Memory
.Alignment
= Length
;
577 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
578 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
582 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
584 Descriptor
->Option
= 0; /* Required */
585 Descriptor
->Type
= CmResourceTypeBusNumber
;
586 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
588 Descriptor
->u
.BusNumber
.MinBusNumber
=
589 Descriptor
->u
.BusNumber
.MaxBusNumber
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
590 Descriptor
->u
.BusNumber
.Length
= 1;
591 Descriptor
->u
.BusNumber
.Reserved
= 0;
594 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
596 /* FIXME: Add Cardbus bridge resources */
599 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
601 return STATUS_SUCCESS
;
607 IN PDEVICE_OBJECT DeviceObject
,
609 PIO_STACK_LOCATION IrpSp
)
611 PPDO_DEVICE_EXTENSION DeviceExtension
;
612 PCI_COMMON_CONFIG PciConfig
;
613 PCM_RESOURCE_LIST ResourceList
;
614 PCM_PARTIAL_RESOURCE_LIST PartialList
;
615 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
624 DPRINT("PdoQueryResources() called\n");
626 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
628 /* Get PCI configuration space */
629 Size
= HalGetBusData(PCIConfiguration
,
630 DeviceExtension
->PciDevice
->BusNumber
,
631 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
633 PCI_COMMON_HDR_LENGTH
);
634 DPRINT("Size %lu\n", Size
);
635 if (Size
< PCI_COMMON_HDR_LENGTH
)
637 Irp
->IoStatus
.Information
= 0;
638 return STATUS_UNSUCCESSFUL
;
641 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
643 /* Count required resource descriptors */
645 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
647 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
649 if (!PdoGetRangeLength(DeviceExtension
,
660 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
661 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
664 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
666 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
668 if (!PdoGetRangeLength(DeviceExtension
,
678 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
681 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
683 /* FIXME: Count Cardbus bridge resources */
687 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
692 Irp
->IoStatus
.Information
= 0;
693 return STATUS_SUCCESS
;
696 /* Calculate the resource list size */
697 ListSize
= FIELD_OFFSET(CM_RESOURCE_LIST
, List
->PartialResourceList
.PartialDescriptors
)
698 + ResCount
* sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
700 /* Allocate the resource list */
701 ResourceList
= ExAllocatePool(PagedPool
,
703 if (ResourceList
== NULL
)
704 return STATUS_INSUFFICIENT_RESOURCES
;
706 RtlZeroMemory(ResourceList
, ListSize
);
707 ResourceList
->Count
= 1;
708 ResourceList
->List
[0].InterfaceType
= PCIConfiguration
;
709 ResourceList
->List
[0].BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
711 PartialList
= &ResourceList
->List
[0].PartialResourceList
;
712 PartialList
->Version
= 1;
713 PartialList
->Revision
= 1;
714 PartialList
->Count
= ResCount
;
716 Descriptor
= &PartialList
->PartialDescriptors
[0];
717 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
719 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
721 if (!PdoGetRangeLength(DeviceExtension
,
727 DPRINT1("PdoGetRangeLength() failed\n");
733 DPRINT("Unused address register\n");
737 if (Flags
& PCI_ADDRESS_IO_SPACE
)
739 Descriptor
->Type
= CmResourceTypePort
;
740 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
741 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
742 Descriptor
->u
.Port
.Start
.QuadPart
=
744 Descriptor
->u
.Port
.Length
= Length
;
748 Descriptor
->Type
= CmResourceTypeMemory
;
749 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
750 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
751 Descriptor
->u
.Memory
.Start
.QuadPart
=
753 Descriptor
->u
.Memory
.Length
= Length
;
759 /* Add interrupt resource */
760 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
761 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
763 Descriptor
->Type
= CmResourceTypeInterrupt
;
764 Descriptor
->ShareDisposition
= CmResourceShareShared
;
765 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
766 Descriptor
->u
.Interrupt
.Level
= PciConfig
.u
.type0
.InterruptLine
;
767 Descriptor
->u
.Interrupt
.Vector
= PciConfig
.u
.type0
.InterruptLine
;
768 Descriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
771 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
773 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
775 if (!PdoGetRangeLength(DeviceExtension
,
781 DPRINT1("PdoGetRangeLength() failed\n");
787 DPRINT("Unused address register\n");
791 if (Flags
& PCI_ADDRESS_IO_SPACE
)
793 Descriptor
->Type
= CmResourceTypePort
;
794 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
795 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
796 Descriptor
->u
.Port
.Start
.QuadPart
=
798 Descriptor
->u
.Port
.Length
= Length
;
802 Descriptor
->Type
= CmResourceTypeMemory
;
803 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
804 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
805 Descriptor
->u
.Memory
.Start
.QuadPart
=
807 Descriptor
->u
.Memory
.Length
= Length
;
812 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
814 Descriptor
->Type
= CmResourceTypeBusNumber
;
815 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
817 Descriptor
->u
.BusNumber
.Start
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
818 Descriptor
->u
.BusNumber
.Length
= 1;
819 Descriptor
->u
.BusNumber
.Reserved
= 0;
822 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
824 /* FIXME: Add Cardbus bridge resources */
827 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
829 return STATUS_SUCCESS
;
837 PPDO_DEVICE_EXTENSION DeviceExtension
;
839 DPRINT("InterfaceReference(%p)\n", Context
);
841 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
842 InterlockedIncrement(&DeviceExtension
->References
);
847 InterfaceDereference(
850 PPDO_DEVICE_EXTENSION DeviceExtension
;
852 DPRINT("InterfaceDereference(%p)\n", Context
);
854 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
855 InterlockedDecrement(&DeviceExtension
->References
);
860 InterfaceBusTranslateBusAddress(
862 IN PHYSICAL_ADDRESS BusAddress
,
864 IN OUT PULONG AddressSpace
,
865 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
867 PPDO_DEVICE_EXTENSION DeviceExtension
;
869 DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
870 Context
, BusAddress
, Length
, AddressSpace
, TranslatedAddress
);
872 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
874 return HalTranslateBusAddress(
875 PCIBus
, DeviceExtension
->PciDevice
->BusNumber
,
876 BusAddress
, AddressSpace
, TranslatedAddress
);
880 static PDMA_ADAPTER NTAPI
881 InterfaceBusGetDmaAdapter(
883 IN PDEVICE_DESCRIPTION DeviceDescription
,
884 OUT PULONG NumberOfMapRegisters
)
886 DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
887 Context
, DeviceDescription
, NumberOfMapRegisters
);
888 return (PDMA_ADAPTER
)HalGetAdapter(DeviceDescription
, NumberOfMapRegisters
);
893 InterfaceBusSetBusData(
900 PPDO_DEVICE_EXTENSION DeviceExtension
;
903 DPRINT("InterfaceBusSetBusData(%p 0x%lx %p 0x%lx 0x%lx)\n",
904 Context
, DataType
, Buffer
, Offset
, Length
);
906 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
908 DPRINT("Unknown DataType %lu\n", DataType
);
912 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
914 /* Get PCI configuration space */
915 Size
= HalSetBusDataByOffset(PCIConfiguration
,
916 DeviceExtension
->PciDevice
->BusNumber
,
917 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
926 InterfaceBusGetBusData(
933 PPDO_DEVICE_EXTENSION DeviceExtension
;
936 DPRINT("InterfaceBusGetBusData(%p 0x%lx %p 0x%lx 0x%lx) called\n",
937 Context
, DataType
, Buffer
, Offset
, Length
);
939 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
941 DPRINT("Unknown DataType %lu\n", DataType
);
945 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
947 /* Get PCI configuration space */
948 Size
= HalGetBusDataByOffset(PCIConfiguration
,
949 DeviceExtension
->PciDevice
->BusNumber
,
950 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
959 InterfacePciDevicePresent(
963 IN USHORT SubVendorID
,
964 IN USHORT SubSystemID
,
967 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
968 PPCI_DEVICE PciDevice
;
969 PLIST_ENTRY CurrentBus
, CurrentEntry
;
971 BOOLEAN Found
= FALSE
;
973 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
974 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
975 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
977 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
979 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
980 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
981 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
983 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
984 if (PciDevice
->PciConfig
.VendorID
== VendorID
&&
985 PciDevice
->PciConfig
.DeviceID
== DeviceID
)
987 if (!(Flags
& PCI_USE_SUBSYSTEM_IDS
) || (
988 PciDevice
->PciConfig
.u
.type0
.SubVendorID
== SubVendorID
&&
989 PciDevice
->PciConfig
.u
.type0
.SubSystemID
== SubSystemID
))
991 if (!(Flags
& PCI_USE_REVISION
) ||
992 PciDevice
->PciConfig
.RevisionID
== RevisionID
)
994 DPRINT("Found the PCI device\n");
1000 CurrentEntry
= CurrentEntry
->Flink
;
1003 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1004 CurrentBus
= CurrentBus
->Flink
;
1006 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1014 IN PPCI_COMMON_CONFIG PciConfig
,
1015 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1017 if ((Parameters
->Flags
& PCI_USE_VENDEV_IDS
) && (
1018 PciConfig
->VendorID
!= Parameters
->VendorID
||
1019 PciConfig
->DeviceID
!= Parameters
->DeviceID
))
1023 if ((Parameters
->Flags
& PCI_USE_CLASS_SUBCLASS
) && (
1024 PciConfig
->BaseClass
!= Parameters
->BaseClass
||
1025 PciConfig
->SubClass
!= Parameters
->SubClass
))
1029 if ((Parameters
->Flags
& PCI_USE_PROGIF
) &&
1030 PciConfig
->ProgIf
!= Parameters
->ProgIf
)
1034 if ((Parameters
->Flags
& PCI_USE_SUBSYSTEM_IDS
) && (
1035 PciConfig
->u
.type0
.SubVendorID
!= Parameters
->SubVendorID
||
1036 PciConfig
->u
.type0
.SubSystemID
!= Parameters
->SubSystemID
))
1040 if ((Parameters
->Flags
& PCI_USE_REVISION
) &&
1041 PciConfig
->RevisionID
!= Parameters
->RevisionID
)
1049 static BOOLEAN NTAPI
1050 InterfacePciDevicePresentEx(
1052 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1054 PPDO_DEVICE_EXTENSION DeviceExtension
;
1055 PFDO_DEVICE_EXTENSION MyFdoDeviceExtension
;
1056 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1057 PPCI_DEVICE PciDevice
;
1058 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1060 BOOLEAN Found
= FALSE
;
1062 DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
1063 Context
, Parameters
);
1065 if (!Parameters
|| Parameters
->Size
!= sizeof(PCI_DEVICE_PRESENCE_PARAMETERS
))
1068 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1069 MyFdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
1071 if (Parameters
->Flags
& PCI_USE_LOCAL_DEVICE
)
1073 return CheckPciDevice(&DeviceExtension
->PciDevice
->PciConfig
, Parameters
);
1076 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1077 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1078 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1080 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1081 if (!(Parameters
->Flags
& PCI_USE_LOCAL_BUS
) || FdoDeviceExtension
== MyFdoDeviceExtension
)
1083 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1084 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1085 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1087 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1089 if (CheckPciDevice(&PciDevice
->PciConfig
, Parameters
))
1091 DPRINT("Found the PCI device\n");
1095 CurrentEntry
= CurrentEntry
->Flink
;
1098 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1100 CurrentBus
= CurrentBus
->Flink
;
1102 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1110 IN PDEVICE_OBJECT DeviceObject
,
1112 PIO_STACK_LOCATION IrpSp
)
1116 if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1117 &GUID_BUS_INTERFACE_STANDARD
, sizeof(GUID
)) == sizeof(GUID
))
1119 /* BUS_INTERFACE_STANDARD */
1120 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1121 Status
= STATUS_NOT_SUPPORTED
;
1122 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(BUS_INTERFACE_STANDARD
))
1123 Status
= STATUS_BUFFER_TOO_SMALL
;
1126 PBUS_INTERFACE_STANDARD BusInterface
;
1127 BusInterface
= (PBUS_INTERFACE_STANDARD
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1128 BusInterface
->Size
= sizeof(BUS_INTERFACE_STANDARD
);
1129 BusInterface
->Version
= 1;
1130 BusInterface
->TranslateBusAddress
= InterfaceBusTranslateBusAddress
;
1131 BusInterface
->GetDmaAdapter
= InterfaceBusGetDmaAdapter
;
1132 BusInterface
->SetBusData
= InterfaceBusSetBusData
;
1133 BusInterface
->GetBusData
= InterfaceBusGetBusData
;
1134 Status
= STATUS_SUCCESS
;
1137 else if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1138 &GUID_PCI_DEVICE_PRESENT_INTERFACE
, sizeof(GUID
)) == sizeof(GUID
))
1140 /* PCI_DEVICE_PRESENT_INTERFACE */
1141 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1142 Status
= STATUS_NOT_SUPPORTED
;
1143 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(PCI_DEVICE_PRESENT_INTERFACE
))
1144 Status
= STATUS_BUFFER_TOO_SMALL
;
1147 PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface
;
1148 PciDevicePresentInterface
= (PPCI_DEVICE_PRESENT_INTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1149 PciDevicePresentInterface
->Size
= sizeof(PCI_DEVICE_PRESENT_INTERFACE
);
1150 PciDevicePresentInterface
->Version
= 1;
1151 PciDevicePresentInterface
->IsDevicePresent
= InterfacePciDevicePresent
;
1152 PciDevicePresentInterface
->IsDevicePresentEx
= InterfacePciDevicePresentEx
;
1153 Status
= STATUS_SUCCESS
;
1158 /* Not a supported interface */
1159 return STATUS_NOT_SUPPORTED
;
1162 if (NT_SUCCESS(Status
))
1164 /* Add a reference for the returned interface */
1165 PINTERFACE Interface
;
1166 Interface
= (PINTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1167 Interface
->Context
= DeviceObject
;
1168 Interface
->InterfaceReference
= InterfaceReference
;
1169 Interface
->InterfaceDereference
= InterfaceDereference
;
1170 Interface
->InterfaceReference(Interface
->Context
);
1179 IN PDEVICE_OBJECT DeviceObject
,
1181 PIO_STACK_LOCATION IrpSp
)
1185 DPRINT("PdoReadConfig() called\n");
1187 Size
= InterfaceBusGetBusData(
1189 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1190 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1191 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1192 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1194 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1196 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1197 Irp
->IoStatus
.Information
= 0;
1198 return STATUS_UNSUCCESSFUL
;
1201 Irp
->IoStatus
.Information
= Size
;
1203 return STATUS_SUCCESS
;
1209 IN PDEVICE_OBJECT DeviceObject
,
1211 PIO_STACK_LOCATION IrpSp
)
1215 DPRINT1("PdoWriteConfig() called\n");
1217 /* Get PCI configuration space */
1218 Size
= InterfaceBusSetBusData(
1220 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1221 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1222 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1223 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1225 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1227 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1228 Irp
->IoStatus
.Information
= 0;
1229 return STATUS_UNSUCCESSFUL
;
1232 Irp
->IoStatus
.Information
= Size
;
1234 return STATUS_SUCCESS
;
1240 IN PDEVICE_OBJECT DeviceObject
,
1242 PIO_STACK_LOCATION IrpSp
)
1244 PPDO_DEVICE_EXTENSION DeviceExtension
;
1249 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1251 if (IrpSp
->Parameters
.Power
.Type
== DevicePowerState
) {
1252 Status
= STATUS_SUCCESS
;
1253 switch (IrpSp
->Parameters
.Power
.State
.SystemState
) {
1255 Status
= STATUS_UNSUCCESSFUL
;
1258 Status
= STATUS_UNSUCCESSFUL
;
1265 /*** PUBLIC ******************************************************************/
1269 PDEVICE_OBJECT DeviceObject
,
1272 * FUNCTION: Handle Plug and Play IRPs for the child device
1274 * DeviceObject = Pointer to physical device object of the child device
1275 * Irp = Pointer to IRP that should be handled
1280 PIO_STACK_LOCATION IrpSp
;
1285 Status
= Irp
->IoStatus
.Status
;
1287 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1289 switch (IrpSp
->MinorFunction
) {
1291 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1298 case IRP_MN_QUERY_BUS_INFORMATION
:
1299 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
1302 case IRP_MN_QUERY_CAPABILITIES
:
1303 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
1307 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1308 /* FIXME: Possibly handle for RemovalRelations */
1312 case IRP_MN_QUERY_DEVICE_TEXT
:
1313 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
1314 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
1317 case IRP_MN_QUERY_ID
:
1318 DPRINT("IRP_MN_QUERY_ID received\n");
1319 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
1323 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1327 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1328 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
1329 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
1332 case IRP_MN_QUERY_RESOURCES
:
1333 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
1334 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
1338 case IRP_MN_SET_LOCK
:
1342 case IRP_MN_START_DEVICE
:
1343 case IRP_MN_QUERY_STOP_DEVICE
:
1344 case IRP_MN_CANCEL_STOP_DEVICE
:
1345 case IRP_MN_STOP_DEVICE
:
1346 case IRP_MN_QUERY_REMOVE_DEVICE
:
1347 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1348 case IRP_MN_REMOVE_DEVICE
:
1349 case IRP_MN_SURPRISE_REMOVAL
:
1350 Status
= STATUS_SUCCESS
;
1353 case IRP_MN_QUERY_INTERFACE
:
1354 DPRINT("IRP_MN_QUERY_INTERFACE received\n");
1355 Status
= PdoQueryInterface(DeviceObject
, Irp
, IrpSp
);
1358 case IRP_MN_READ_CONFIG
:
1359 DPRINT("IRP_MN_READ_CONFIG received\n");
1360 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1363 case IRP_MN_WRITE_CONFIG
:
1364 DPRINT("IRP_MN_WRITE_CONFIG received\n");
1365 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1369 DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp
->MinorFunction
);
1373 if (Status
!= STATUS_PENDING
) {
1374 Irp
->IoStatus
.Status
= Status
;
1375 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1378 DPRINT("Leaving. Status 0x%X\n", Status
);
1385 PDEVICE_OBJECT DeviceObject
,
1388 * FUNCTION: Handle power management IRPs for the child device
1390 * DeviceObject = Pointer to physical device object of the child device
1391 * Irp = Pointer to IRP that should be handled
1396 PIO_STACK_LOCATION IrpSp
;
1401 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1403 switch (IrpSp
->MinorFunction
) {
1404 case IRP_MN_SET_POWER
:
1405 Status
= PdoSetPower(DeviceObject
, Irp
, IrpSp
);
1409 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1410 Status
= STATUS_NOT_IMPLEMENTED
;
1414 if (Status
!= STATUS_PENDING
) {
1415 Irp
->IoStatus
.Status
= Status
;
1416 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1419 DPRINT("Leaving. Status 0x%X\n", Status
);