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 /*** PRIVATE *****************************************************************/
28 IN PDEVICE_OBJECT DeviceObject
,
30 PIO_STACK_LOCATION IrpSp
)
32 PPDO_DEVICE_EXTENSION DeviceExtension
;
33 UNICODE_STRING String
;
38 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
40 switch (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
)
42 case DeviceTextDescription
:
43 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
44 &DeviceExtension
->DeviceDescription
,
47 DPRINT("DeviceTextDescription\n");
48 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
51 case DeviceTextLocationInformation
:
52 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
53 &DeviceExtension
->DeviceLocation
,
56 DPRINT("DeviceTextLocationInformation\n");
57 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
61 Irp
->IoStatus
.Information
= 0;
62 Status
= STATUS_INVALID_PARAMETER
;
72 IN PDEVICE_OBJECT DeviceObject
,
74 PIO_STACK_LOCATION IrpSp
)
76 PPDO_DEVICE_EXTENSION DeviceExtension
;
77 UNICODE_STRING String
;
82 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
84 // Irp->IoStatus.Information = 0;
86 Status
= STATUS_SUCCESS
;
88 RtlInitUnicodeString(&String
, NULL
);
90 switch (IrpSp
->Parameters
.QueryId
.IdType
)
92 case BusQueryDeviceID
:
93 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
94 &DeviceExtension
->DeviceID
,
97 DPRINT("DeviceID: %S\n", String
.Buffer
);
99 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
102 case BusQueryHardwareIDs
:
103 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
104 &DeviceExtension
->HardwareIDs
,
107 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
110 case BusQueryCompatibleIDs
:
111 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
112 &DeviceExtension
->CompatibleIDs
,
115 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
118 case BusQueryInstanceID
:
119 Status
= PciDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
120 &DeviceExtension
->InstanceID
,
123 DPRINT("InstanceID: %S\n", String
.Buffer
);
125 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
128 case BusQueryDeviceSerialNumber
:
130 Status
= STATUS_NOT_IMPLEMENTED
;
138 PdoQueryBusInformation(
139 IN PDEVICE_OBJECT DeviceObject
,
141 PIO_STACK_LOCATION IrpSp
)
143 PPDO_DEVICE_EXTENSION DeviceExtension
;
144 PPNP_BUS_INFORMATION BusInformation
;
146 UNREFERENCED_PARAMETER(IrpSp
);
149 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
150 BusInformation
= ExAllocatePool(PagedPool
, sizeof(PNP_BUS_INFORMATION
));
151 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
152 if (BusInformation
!= NULL
)
154 BusInformation
->BusTypeGuid
= GUID_BUS_TYPE_PCI
;
155 BusInformation
->LegacyBusType
= PCIBus
;
156 BusInformation
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
158 return STATUS_SUCCESS
;
161 return STATUS_INSUFFICIENT_RESOURCES
;
166 PdoQueryCapabilities(
167 IN PDEVICE_OBJECT DeviceObject
,
169 PIO_STACK_LOCATION IrpSp
)
171 PPDO_DEVICE_EXTENSION DeviceExtension
;
172 PDEVICE_CAPABILITIES DeviceCapabilities
;
173 ULONG DeviceNumber
, FunctionNumber
;
175 UNREFERENCED_PARAMETER(Irp
);
178 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
179 DeviceCapabilities
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
181 if (DeviceCapabilities
->Version
!= 1)
182 return STATUS_UNSUCCESSFUL
;
184 DeviceNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.DeviceNumber
;
185 FunctionNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.FunctionNumber
;
187 DeviceCapabilities
->UniqueID
= FALSE
;
188 DeviceCapabilities
->Address
= ((DeviceNumber
<< 16) & 0xFFFF0000) + (FunctionNumber
& 0xFFFF);
189 DeviceCapabilities
->UINumber
= MAXULONG
; /* FIXME */
191 return STATUS_SUCCESS
;
196 PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension
,
208 /* Save original value */
209 Size
= HalGetBusDataByOffset(PCIConfiguration
,
210 DeviceExtension
->PciDevice
->BusNumber
,
211 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
215 if (Size
!= sizeof(ULONG
))
217 DPRINT1("Wrong size %lu\n", Size
);
221 BaseValue
= (OrigValue
& PCI_ADDRESS_IO_SPACE
)
222 ? (OrigValue
& PCI_ADDRESS_IO_ADDRESS_MASK
)
223 : (OrigValue
& PCI_ADDRESS_MEMORY_ADDRESS_MASK
);
227 /* Set magic value */
229 Size
= HalSetBusDataByOffset(PCIConfiguration
,
230 DeviceExtension
->PciDevice
->BusNumber
,
231 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
235 if (Size
!= sizeof(ULONG
))
237 DPRINT1("Wrong size %lu\n", Size
);
241 /* Get the range length */
242 Size
= HalGetBusDataByOffset(PCIConfiguration
,
243 DeviceExtension
->PciDevice
->BusNumber
,
244 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
248 if (Size
!= sizeof(ULONG
))
250 DPRINT1("Wrong size %lu\n", Size
);
254 /* Restore original value */
255 Size
= HalSetBusDataByOffset(PCIConfiguration
,
256 DeviceExtension
->PciDevice
->BusNumber
,
257 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
261 if (Size
!= sizeof(ULONG
))
263 DPRINT1("Wrong size %lu\n", Size
);
269 DPRINT("Unused address register\n");
276 XLength
= ~((NewValue
& PCI_ADDRESS_IO_SPACE
)
277 ? (NewValue
& PCI_ADDRESS_IO_ADDRESS_MASK
)
278 : (NewValue
& PCI_ADDRESS_MEMORY_ADDRESS_MASK
)) + 1;
281 DbgPrint("BaseAddress 0x%08lx Length 0x%08lx",
284 if (NewValue
& PCI_ADDRESS_IO_SPACE
)
286 DbgPrint(" IO range");
290 DbgPrint(" Memory range");
291 if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 0)
293 DbgPrint(" in 32-Bit address space");
295 else if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 2)
297 DbgPrint(" below 1BM ");
299 else if ((NewValue
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == 4)
301 DbgPrint(" in 64-Bit address space");
304 if (NewValue
& PCI_ADDRESS_MEMORY_PREFETCHABLE
)
306 DbgPrint(" prefetchable");
314 *Flags
= (NewValue
& PCI_ADDRESS_IO_SPACE
)
315 ? (NewValue
& ~PCI_ADDRESS_IO_ADDRESS_MASK
)
316 : (NewValue
& ~PCI_ADDRESS_MEMORY_ADDRESS_MASK
);
323 PdoQueryResourceRequirements(
324 IN PDEVICE_OBJECT DeviceObject
,
326 PIO_STACK_LOCATION IrpSp
)
328 PPDO_DEVICE_EXTENSION DeviceExtension
;
329 PCI_COMMON_CONFIG PciConfig
;
330 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList
;
331 PIO_RESOURCE_DESCRIPTOR Descriptor
;
340 UNREFERENCED_PARAMETER(IrpSp
);
341 DPRINT("PdoQueryResourceRequirements() called\n");
343 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
345 /* Get PCI configuration space */
346 Size
= HalGetBusData(PCIConfiguration
,
347 DeviceExtension
->PciDevice
->BusNumber
,
348 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
350 PCI_COMMON_HDR_LENGTH
);
351 DPRINT("Size %lu\n", Size
);
352 if (Size
< PCI_COMMON_HDR_LENGTH
)
354 Irp
->IoStatus
.Information
= 0;
355 return STATUS_UNSUCCESSFUL
;
358 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
360 /* Count required resource descriptors */
362 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
364 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
366 if (!PdoGetRangeLength(DeviceExtension
,
377 /* FIXME: Check ROM address */
379 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
382 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
384 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
386 if (!PdoGetRangeLength(DeviceExtension
,
397 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
400 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
402 /* FIXME: Count Cardbus bridge resources */
406 DPRINT1("Unsupported header type %d\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
411 Irp
->IoStatus
.Information
= 0;
412 return STATUS_SUCCESS
;
415 /* Calculate the resource list size */
416 ListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
[0].Descriptors
) +
417 ResCount
* sizeof(IO_RESOURCE_DESCRIPTOR
);
419 DPRINT("ListSize %lu (0x%lx)\n", ListSize
, ListSize
);
421 /* Allocate the resource requirements list */
422 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
425 if (ResourceList
== NULL
)
427 Irp
->IoStatus
.Information
= 0;
428 return STATUS_INSUFFICIENT_RESOURCES
;
431 RtlZeroMemory(ResourceList
, ListSize
);
432 ResourceList
->ListSize
= ListSize
;
433 ResourceList
->InterfaceType
= PCIBus
;
434 ResourceList
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
435 ResourceList
->SlotNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
;
436 ResourceList
->AlternativeLists
= 1;
438 ResourceList
->List
[0].Version
= 1;
439 ResourceList
->List
[0].Revision
= 1;
440 ResourceList
->List
[0].Count
= ResCount
;
442 Descriptor
= &ResourceList
->List
[0].Descriptors
[0];
443 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
445 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
447 if (!PdoGetRangeLength(DeviceExtension
,
453 DPRINT1("PdoGetRangeLength() failed\n");
459 DPRINT("Unused address register\n");
463 /* Set preferred descriptor */
464 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
465 if (Flags
& PCI_ADDRESS_IO_SPACE
)
467 Descriptor
->Type
= CmResourceTypePort
;
468 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
469 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
470 CM_RESOURCE_PORT_16_BIT_DECODE
|
471 CM_RESOURCE_PORT_POSITIVE_DECODE
;
473 Descriptor
->u
.Port
.Length
= Length
;
474 Descriptor
->u
.Port
.Alignment
= 1;
475 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
476 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
480 Descriptor
->Type
= CmResourceTypeMemory
;
481 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
482 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
484 Descriptor
->u
.Memory
.Length
= Length
;
485 Descriptor
->u
.Memory
.Alignment
= 1;
486 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
487 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
491 /* Set alternative descriptor */
492 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
493 if (Flags
& PCI_ADDRESS_IO_SPACE
)
495 Descriptor
->Type
= CmResourceTypePort
;
496 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
497 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
498 CM_RESOURCE_PORT_16_BIT_DECODE
|
499 CM_RESOURCE_PORT_POSITIVE_DECODE
;
501 Descriptor
->u
.Port
.Length
= Length
;
502 Descriptor
->u
.Port
.Alignment
= Length
;
503 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
504 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
508 Descriptor
->Type
= CmResourceTypeMemory
;
509 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
510 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
512 Descriptor
->u
.Memory
.Length
= Length
;
513 Descriptor
->u
.Memory
.Alignment
= Length
;
514 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
515 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
520 /* FIXME: Check ROM address */
522 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
524 Descriptor
->Option
= 0; /* Required */
525 Descriptor
->Type
= CmResourceTypeInterrupt
;
526 Descriptor
->ShareDisposition
= CmResourceShareShared
;
527 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
529 Descriptor
->u
.Interrupt
.MinimumVector
= 0;
530 Descriptor
->u
.Interrupt
.MaximumVector
= 0xFF;
533 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
535 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
537 if (!PdoGetRangeLength(DeviceExtension
,
543 DPRINT1("PdoGetRangeLength() failed\n");
549 DPRINT("Unused address register\n");
553 /* Set preferred descriptor */
554 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
555 if (Flags
& PCI_ADDRESS_IO_SPACE
)
557 Descriptor
->Type
= CmResourceTypePort
;
558 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
559 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
560 CM_RESOURCE_PORT_16_BIT_DECODE
|
561 CM_RESOURCE_PORT_POSITIVE_DECODE
;
563 Descriptor
->u
.Port
.Length
= Length
;
564 Descriptor
->u
.Port
.Alignment
= 1;
565 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
566 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
570 Descriptor
->Type
= CmResourceTypeMemory
;
571 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
572 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
574 Descriptor
->u
.Memory
.Length
= Length
;
575 Descriptor
->u
.Memory
.Alignment
= 1;
576 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
577 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
581 /* Set alternative descriptor */
582 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
583 if (Flags
& PCI_ADDRESS_IO_SPACE
)
585 Descriptor
->Type
= CmResourceTypePort
;
586 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
587 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
588 CM_RESOURCE_PORT_16_BIT_DECODE
|
589 CM_RESOURCE_PORT_POSITIVE_DECODE
;
591 Descriptor
->u
.Port
.Length
= Length
;
592 Descriptor
->u
.Port
.Alignment
= Length
;
593 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
594 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
598 Descriptor
->Type
= CmResourceTypeMemory
;
599 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
600 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
602 Descriptor
->u
.Memory
.Length
= Length
;
603 Descriptor
->u
.Memory
.Alignment
= Length
;
604 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
605 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
610 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
612 Descriptor
->Option
= 0; /* Required */
613 Descriptor
->Type
= CmResourceTypeBusNumber
;
614 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
616 ResourceList
->BusNumber
=
617 Descriptor
->u
.BusNumber
.MinBusNumber
=
618 Descriptor
->u
.BusNumber
.MaxBusNumber
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
619 Descriptor
->u
.BusNumber
.Length
= 1;
620 Descriptor
->u
.BusNumber
.Reserved
= 0;
623 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
625 /* FIXME: Add Cardbus bridge resources */
628 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
630 return STATUS_SUCCESS
;
636 IN PDEVICE_OBJECT DeviceObject
,
638 PIO_STACK_LOCATION IrpSp
)
640 PPDO_DEVICE_EXTENSION DeviceExtension
;
641 PCI_COMMON_CONFIG PciConfig
;
642 PCM_RESOURCE_LIST ResourceList
;
643 PCM_PARTIAL_RESOURCE_LIST PartialList
;
644 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
653 DPRINT("PdoQueryResources() called\n");
655 UNREFERENCED_PARAMETER(IrpSp
);
656 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
658 /* Get PCI configuration space */
659 Size
= HalGetBusData(PCIConfiguration
,
660 DeviceExtension
->PciDevice
->BusNumber
,
661 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
663 PCI_COMMON_HDR_LENGTH
);
664 DPRINT("Size %lu\n", Size
);
665 if (Size
< PCI_COMMON_HDR_LENGTH
)
667 Irp
->IoStatus
.Information
= 0;
668 return STATUS_UNSUCCESSFUL
;
671 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
673 /* Count required resource descriptors */
675 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
677 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
679 if (!PdoGetRangeLength(DeviceExtension
,
690 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
691 (PciConfig
.u
.type0
.InterruptLine
!= 0) &&
692 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
695 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
697 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
699 if (!PdoGetRangeLength(DeviceExtension
,
710 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
713 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
715 /* FIXME: Count Cardbus bridge resources */
719 DPRINT1("Unsupported header type %d\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
724 Irp
->IoStatus
.Information
= 0;
725 return STATUS_SUCCESS
;
728 /* Calculate the resource list size */
729 ListSize
= FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.PartialDescriptors
) +
730 ResCount
* sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
732 /* Allocate the resource list */
733 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
736 if (ResourceList
== NULL
)
737 return STATUS_INSUFFICIENT_RESOURCES
;
739 RtlZeroMemory(ResourceList
, ListSize
);
740 ResourceList
->Count
= 1;
741 ResourceList
->List
[0].InterfaceType
= PCIBus
;
742 ResourceList
->List
[0].BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
744 PartialList
= &ResourceList
->List
[0].PartialResourceList
;
745 PartialList
->Version
= 1;
746 PartialList
->Revision
= 1;
747 PartialList
->Count
= ResCount
;
749 Descriptor
= &PartialList
->PartialDescriptors
[0];
750 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
752 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
754 if (!PdoGetRangeLength(DeviceExtension
,
760 DPRINT1("PdoGetRangeLength() failed\n");
766 DPRINT("Unused address register\n");
770 if (Flags
& PCI_ADDRESS_IO_SPACE
)
772 Descriptor
->Type
= CmResourceTypePort
;
773 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
774 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
775 Descriptor
->u
.Port
.Start
.QuadPart
= (ULONGLONG
)Base
;
776 Descriptor
->u
.Port
.Length
= Length
;
778 /* Enable IO space access */
779 DeviceExtension
->PciDevice
->EnableIoSpace
= TRUE
;
783 Descriptor
->Type
= CmResourceTypeMemory
;
784 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
785 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
786 Descriptor
->u
.Memory
.Start
.QuadPart
= (ULONGLONG
)Base
;
787 Descriptor
->u
.Memory
.Length
= Length
;
789 /* Enable memory space access */
790 DeviceExtension
->PciDevice
->EnableMemorySpace
= TRUE
;
796 /* Add interrupt resource */
797 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
798 (PciConfig
.u
.type0
.InterruptLine
!= 0) &&
799 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
801 Descriptor
->Type
= CmResourceTypeInterrupt
;
802 Descriptor
->ShareDisposition
= CmResourceShareShared
;
803 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
804 Descriptor
->u
.Interrupt
.Level
= PciConfig
.u
.type0
.InterruptLine
;
805 Descriptor
->u
.Interrupt
.Vector
= PciConfig
.u
.type0
.InterruptLine
;
806 Descriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
809 /* Allow bus master mode */
810 DeviceExtension
->PciDevice
->EnableBusMaster
= TRUE
;
812 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
814 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
816 if (!PdoGetRangeLength(DeviceExtension
,
822 DPRINT1("PdoGetRangeLength() failed\n");
828 DPRINT("Unused address register\n");
832 if (Flags
& PCI_ADDRESS_IO_SPACE
)
834 Descriptor
->Type
= CmResourceTypePort
;
835 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
836 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
837 Descriptor
->u
.Port
.Start
.QuadPart
= (ULONGLONG
)Base
;
838 Descriptor
->u
.Port
.Length
= Length
;
840 /* Enable IO space access */
841 DeviceExtension
->PciDevice
->EnableIoSpace
= TRUE
;
845 Descriptor
->Type
= CmResourceTypeMemory
;
846 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
847 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
848 Descriptor
->u
.Memory
.Start
.QuadPart
= (ULONGLONG
)Base
;
849 Descriptor
->u
.Memory
.Length
= Length
;
851 /* Enable memory space access */
852 DeviceExtension
->PciDevice
->EnableMemorySpace
= TRUE
;
858 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
860 Descriptor
->Type
= CmResourceTypeBusNumber
;
861 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
863 ResourceList
->List
[0].BusNumber
=
864 Descriptor
->u
.BusNumber
.Start
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
865 Descriptor
->u
.BusNumber
.Length
= 1;
866 Descriptor
->u
.BusNumber
.Reserved
= 0;
869 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
871 /* FIXME: Add Cardbus bridge resources */
874 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
876 return STATUS_SUCCESS
;
884 PPDO_DEVICE_EXTENSION DeviceExtension
;
886 DPRINT("InterfaceReference(%p)\n", Context
);
888 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
889 InterlockedIncrement(&DeviceExtension
->References
);
894 InterfaceDereference(
897 PPDO_DEVICE_EXTENSION DeviceExtension
;
899 DPRINT("InterfaceDereference(%p)\n", Context
);
901 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
902 InterlockedDecrement(&DeviceExtension
->References
);
905 static TRANSLATE_BUS_ADDRESS InterfaceBusTranslateBusAddress
;
910 InterfaceBusTranslateBusAddress(
912 IN PHYSICAL_ADDRESS BusAddress
,
914 IN OUT PULONG AddressSpace
,
915 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
917 PPDO_DEVICE_EXTENSION DeviceExtension
;
919 DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
920 Context
, BusAddress
, Length
, AddressSpace
, TranslatedAddress
);
922 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
924 return HalTranslateBusAddress(PCIBus
,
925 DeviceExtension
->PciDevice
->BusNumber
,
931 static GET_DMA_ADAPTER InterfaceBusGetDmaAdapter
;
936 InterfaceBusGetDmaAdapter(
938 IN PDEVICE_DESCRIPTION DeviceDescription
,
939 OUT PULONG NumberOfMapRegisters
)
941 DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
942 Context
, DeviceDescription
, NumberOfMapRegisters
);
943 return (PDMA_ADAPTER
)HalGetAdapter(DeviceDescription
, NumberOfMapRegisters
);
946 static GET_SET_DEVICE_DATA InterfaceBusSetBusData
;
951 InterfaceBusSetBusData(
958 PPDO_DEVICE_EXTENSION DeviceExtension
;
961 DPRINT("InterfaceBusSetBusData(%p 0x%lx %p 0x%lx 0x%lx)\n",
962 Context
, DataType
, Buffer
, Offset
, Length
);
964 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
966 DPRINT("Unknown DataType %lu\n", DataType
);
970 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
972 /* Get PCI configuration space */
973 Size
= HalSetBusDataByOffset(PCIConfiguration
,
974 DeviceExtension
->PciDevice
->BusNumber
,
975 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
982 static GET_SET_DEVICE_DATA InterfaceBusGetBusData
;
987 InterfaceBusGetBusData(
994 PPDO_DEVICE_EXTENSION DeviceExtension
;
997 DPRINT("InterfaceBusGetBusData(%p 0x%lx %p 0x%lx 0x%lx) called\n",
998 Context
, DataType
, Buffer
, Offset
, Length
);
1000 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
1002 DPRINT("Unknown DataType %lu\n", DataType
);
1006 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1008 /* Get PCI configuration space */
1009 Size
= HalGetBusDataByOffset(PCIConfiguration
,
1010 DeviceExtension
->PciDevice
->BusNumber
,
1011 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1019 static BOOLEAN NTAPI
1020 InterfacePciDevicePresent(
1023 IN UCHAR RevisionID
,
1024 IN USHORT SubVendorID
,
1025 IN USHORT SubSystemID
,
1028 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1029 PPCI_DEVICE PciDevice
;
1030 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1032 BOOLEAN Found
= FALSE
;
1034 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1035 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1036 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1038 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1040 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1041 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1042 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1044 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1045 if (PciDevice
->PciConfig
.VendorID
== VendorID
&&
1046 PciDevice
->PciConfig
.DeviceID
== DeviceID
)
1048 if (!(Flags
& PCI_USE_SUBSYSTEM_IDS
) ||
1049 (PciDevice
->PciConfig
.u
.type0
.SubVendorID
== SubVendorID
&&
1050 PciDevice
->PciConfig
.u
.type0
.SubSystemID
== SubSystemID
))
1052 if (!(Flags
& PCI_USE_REVISION
) ||
1053 PciDevice
->PciConfig
.RevisionID
== RevisionID
)
1055 DPRINT("Found the PCI device\n");
1061 CurrentEntry
= CurrentEntry
->Flink
;
1064 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1065 CurrentBus
= CurrentBus
->Flink
;
1067 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1075 IN PPCI_COMMON_CONFIG PciConfig
,
1076 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1078 if ((Parameters
->Flags
& PCI_USE_VENDEV_IDS
) &&
1079 (PciConfig
->VendorID
!= Parameters
->VendorID
||
1080 PciConfig
->DeviceID
!= Parameters
->DeviceID
))
1085 if ((Parameters
->Flags
& PCI_USE_CLASS_SUBCLASS
) &&
1086 (PciConfig
->BaseClass
!= Parameters
->BaseClass
||
1087 PciConfig
->SubClass
!= Parameters
->SubClass
))
1092 if ((Parameters
->Flags
& PCI_USE_PROGIF
) &&
1093 PciConfig
->ProgIf
!= Parameters
->ProgIf
)
1098 if ((Parameters
->Flags
& PCI_USE_SUBSYSTEM_IDS
) &&
1099 (PciConfig
->u
.type0
.SubVendorID
!= Parameters
->SubVendorID
||
1100 PciConfig
->u
.type0
.SubSystemID
!= Parameters
->SubSystemID
))
1105 if ((Parameters
->Flags
& PCI_USE_REVISION
) &&
1106 PciConfig
->RevisionID
!= Parameters
->RevisionID
)
1115 static BOOLEAN NTAPI
1116 InterfacePciDevicePresentEx(
1118 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1120 PPDO_DEVICE_EXTENSION DeviceExtension
;
1121 PFDO_DEVICE_EXTENSION MyFdoDeviceExtension
;
1122 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1123 PPCI_DEVICE PciDevice
;
1124 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1126 BOOLEAN Found
= FALSE
;
1128 DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
1129 Context
, Parameters
);
1131 if (!Parameters
|| Parameters
->Size
!= sizeof(PCI_DEVICE_PRESENCE_PARAMETERS
))
1134 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1135 MyFdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
1137 if (Parameters
->Flags
& PCI_USE_LOCAL_DEVICE
)
1139 return CheckPciDevice(&DeviceExtension
->PciDevice
->PciConfig
, Parameters
);
1142 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1143 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1144 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1146 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1147 if (!(Parameters
->Flags
& PCI_USE_LOCAL_BUS
) || FdoDeviceExtension
== MyFdoDeviceExtension
)
1149 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1150 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1151 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1153 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1155 if (CheckPciDevice(&PciDevice
->PciConfig
, Parameters
))
1157 DPRINT("Found the PCI device\n");
1161 CurrentEntry
= CurrentEntry
->Flink
;
1164 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1166 CurrentBus
= CurrentBus
->Flink
;
1168 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1176 IN PDEVICE_OBJECT DeviceObject
,
1178 PIO_STACK_LOCATION IrpSp
)
1182 UNREFERENCED_PARAMETER(Irp
);
1184 if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1185 &GUID_BUS_INTERFACE_STANDARD
, sizeof(GUID
)) == sizeof(GUID
))
1187 /* BUS_INTERFACE_STANDARD */
1188 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1189 Status
= STATUS_NOT_SUPPORTED
;
1190 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(BUS_INTERFACE_STANDARD
))
1191 Status
= STATUS_BUFFER_TOO_SMALL
;
1194 PBUS_INTERFACE_STANDARD BusInterface
;
1195 BusInterface
= (PBUS_INTERFACE_STANDARD
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1196 BusInterface
->Size
= sizeof(BUS_INTERFACE_STANDARD
);
1197 BusInterface
->Version
= 1;
1198 BusInterface
->TranslateBusAddress
= InterfaceBusTranslateBusAddress
;
1199 BusInterface
->GetDmaAdapter
= InterfaceBusGetDmaAdapter
;
1200 BusInterface
->SetBusData
= InterfaceBusSetBusData
;
1201 BusInterface
->GetBusData
= InterfaceBusGetBusData
;
1202 Status
= STATUS_SUCCESS
;
1205 else if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1206 &GUID_PCI_DEVICE_PRESENT_INTERFACE
, sizeof(GUID
)) == sizeof(GUID
))
1208 /* PCI_DEVICE_PRESENT_INTERFACE */
1209 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1210 Status
= STATUS_NOT_SUPPORTED
;
1211 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(PCI_DEVICE_PRESENT_INTERFACE
))
1212 Status
= STATUS_BUFFER_TOO_SMALL
;
1215 PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface
;
1216 PciDevicePresentInterface
= (PPCI_DEVICE_PRESENT_INTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1217 PciDevicePresentInterface
->Size
= sizeof(PCI_DEVICE_PRESENT_INTERFACE
);
1218 PciDevicePresentInterface
->Version
= 1;
1219 PciDevicePresentInterface
->IsDevicePresent
= InterfacePciDevicePresent
;
1220 PciDevicePresentInterface
->IsDevicePresentEx
= InterfacePciDevicePresentEx
;
1221 Status
= STATUS_SUCCESS
;
1226 /* Not a supported interface */
1227 return STATUS_NOT_SUPPORTED
;
1230 if (NT_SUCCESS(Status
))
1232 /* Add a reference for the returned interface */
1233 PINTERFACE Interface
;
1234 Interface
= (PINTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1235 Interface
->Context
= DeviceObject
;
1236 Interface
->InterfaceReference
= InterfaceReference
;
1237 Interface
->InterfaceDereference
= InterfaceDereference
;
1238 Interface
->InterfaceReference(Interface
->Context
);
1246 IN PDEVICE_OBJECT DeviceObject
,
1248 PIO_STACK_LOCATION IrpSp
)
1250 PCM_RESOURCE_LIST RawResList
= IrpSp
->Parameters
.StartDevice
.AllocatedResources
;
1251 PCM_FULL_RESOURCE_DESCRIPTOR RawFullDesc
;
1252 PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDesc
;
1254 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1258 UNREFERENCED_PARAMETER(Irp
);
1261 return STATUS_SUCCESS
;
1263 /* TODO: Assign the other resources we get to the card */
1265 for (i
= 0; i
< RawResList
->Count
; i
++)
1267 RawFullDesc
= &RawResList
->List
[i
];
1269 for (ii
= 0; ii
< RawFullDesc
->PartialResourceList
.Count
; ii
++)
1271 RawPartialDesc
= &RawFullDesc
->PartialResourceList
.PartialDescriptors
[ii
];
1273 if (RawPartialDesc
->Type
== CmResourceTypeInterrupt
)
1275 DPRINT("Assigning IRQ %u to PCI device 0x%x on bus 0x%x\n",
1276 RawPartialDesc
->u
.Interrupt
.Vector
,
1277 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1278 DeviceExtension
->PciDevice
->BusNumber
);
1280 Irq
= (UCHAR
)RawPartialDesc
->u
.Interrupt
.Vector
;
1281 HalSetBusDataByOffset(PCIConfiguration
,
1282 DeviceExtension
->PciDevice
->BusNumber
,
1283 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1285 0x3c /* PCI_INTERRUPT_LINE */,
1293 DBGPRINT("pci!PdoStartDevice: Enabling command flags for PCI device 0x%x on bus 0x%x: ",
1294 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1295 DeviceExtension
->PciDevice
->BusNumber
);
1296 if (DeviceExtension
->PciDevice
->EnableBusMaster
)
1298 Command
|= PCI_ENABLE_BUS_MASTER
;
1299 DBGPRINT("[Bus master] ");
1302 if (DeviceExtension
->PciDevice
->EnableMemorySpace
)
1304 Command
|= PCI_ENABLE_MEMORY_SPACE
;
1305 DBGPRINT("[Memory space enable] ");
1308 if (DeviceExtension
->PciDevice
->EnableIoSpace
)
1310 Command
|= PCI_ENABLE_IO_SPACE
;
1311 DBGPRINT("[I/O space enable] ");
1318 /* OR with the previous value */
1319 Command
|= DeviceExtension
->PciDevice
->PciConfig
.Command
;
1321 HalSetBusDataByOffset(PCIConfiguration
,
1322 DeviceExtension
->PciDevice
->BusNumber
,
1323 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
1325 FIELD_OFFSET(PCI_COMMON_CONFIG
, Command
),
1333 return STATUS_SUCCESS
;
1338 IN PDEVICE_OBJECT DeviceObject
,
1340 PIO_STACK_LOCATION IrpSp
)
1344 DPRINT("PdoReadConfig() called\n");
1346 Size
= InterfaceBusGetBusData(DeviceObject
,
1347 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1348 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1349 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1350 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1352 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1354 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1355 Irp
->IoStatus
.Information
= 0;
1356 return STATUS_UNSUCCESSFUL
;
1359 Irp
->IoStatus
.Information
= Size
;
1361 return STATUS_SUCCESS
;
1367 IN PDEVICE_OBJECT DeviceObject
,
1369 PIO_STACK_LOCATION IrpSp
)
1373 DPRINT1("PdoWriteConfig() called\n");
1375 /* Get PCI configuration space */
1376 Size
= InterfaceBusSetBusData(DeviceObject
,
1377 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1378 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1379 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1380 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1382 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1384 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1385 Irp
->IoStatus
.Information
= 0;
1386 return STATUS_UNSUCCESSFUL
;
1389 Irp
->IoStatus
.Information
= Size
;
1391 return STATUS_SUCCESS
;
1395 PdoQueryDeviceRelations(
1396 IN PDEVICE_OBJECT DeviceObject
,
1398 PIO_STACK_LOCATION IrpSp
)
1400 PDEVICE_RELATIONS DeviceRelations
;
1402 /* We only support TargetDeviceRelation for child PDOs */
1403 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
1404 return Irp
->IoStatus
.Status
;
1406 /* We can do this because we only return 1 PDO for TargetDeviceRelation */
1407 DeviceRelations
= ExAllocatePool(PagedPool
, sizeof(*DeviceRelations
));
1408 if (!DeviceRelations
)
1409 return STATUS_INSUFFICIENT_RESOURCES
;
1411 DeviceRelations
->Count
= 1;
1412 DeviceRelations
->Objects
[0] = DeviceObject
;
1414 /* The PnP manager will remove this when it is done with the PDO */
1415 ObReferenceObject(DeviceObject
);
1417 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1419 return STATUS_SUCCESS
;
1424 IN PDEVICE_OBJECT DeviceObject
,
1426 PIO_STACK_LOCATION IrpSp
)
1430 UNREFERENCED_PARAMETER(DeviceObject
);
1431 UNREFERENCED_PARAMETER(Irp
);
1434 if (IrpSp
->Parameters
.Power
.Type
== DevicePowerState
)
1436 Status
= STATUS_SUCCESS
;
1438 switch (IrpSp
->Parameters
.Power
.State
.SystemState
)
1441 Status
= STATUS_UNSUCCESSFUL
;
1446 Status
= STATUS_UNSUCCESSFUL
;
1453 /*** PUBLIC ******************************************************************/
1457 PDEVICE_OBJECT DeviceObject
,
1460 * FUNCTION: Handle Plug and Play IRPs for the child device
1462 * DeviceObject = Pointer to physical device object of the child device
1463 * Irp = Pointer to IRP that should be handled
1468 PIO_STACK_LOCATION IrpSp
;
1473 Status
= Irp
->IoStatus
.Status
;
1475 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1477 switch (IrpSp
->MinorFunction
)
1479 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1480 DPRINT("Unimplemented IRP_MN_DEVICE_USAGE_NOTIFICATION received\n");
1484 DPRINT("Unimplemented IRP_MN_EJECT received\n");
1487 case IRP_MN_QUERY_BUS_INFORMATION
:
1488 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
1491 case IRP_MN_QUERY_CAPABILITIES
:
1492 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
1495 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1496 Status
= PdoQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
1499 case IRP_MN_QUERY_DEVICE_TEXT
:
1500 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
1501 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
1504 case IRP_MN_QUERY_ID
:
1505 DPRINT("IRP_MN_QUERY_ID received\n");
1506 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
1509 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1510 DPRINT("Unimplemented IRP_MN_QUERY_ID received\n");
1513 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1514 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
1515 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
1518 case IRP_MN_QUERY_RESOURCES
:
1519 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
1520 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
1523 case IRP_MN_SET_LOCK
:
1524 DPRINT("Unimplemented IRP_MN_SET_LOCK received\n");
1527 case IRP_MN_START_DEVICE
:
1528 Status
= PdoStartDevice(DeviceObject
, Irp
, IrpSp
);
1531 case IRP_MN_QUERY_STOP_DEVICE
:
1532 case IRP_MN_CANCEL_STOP_DEVICE
:
1533 case IRP_MN_STOP_DEVICE
:
1534 case IRP_MN_QUERY_REMOVE_DEVICE
:
1535 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1536 case IRP_MN_SURPRISE_REMOVAL
:
1537 Status
= STATUS_SUCCESS
;
1540 case IRP_MN_REMOVE_DEVICE
:
1542 PPDO_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
1543 PFDO_DEVICE_EXTENSION FdoDeviceExtension
= DeviceExtension
->Fdo
->DeviceExtension
;
1546 /* Remove it from the device list */
1547 KeAcquireSpinLock(&FdoDeviceExtension
->DeviceListLock
, &OldIrql
);
1548 RemoveEntryList(&DeviceExtension
->PciDevice
->ListEntry
);
1549 FdoDeviceExtension
->DeviceListCount
--;
1550 KeReleaseSpinLock(&FdoDeviceExtension
->DeviceListLock
, OldIrql
);
1552 /* Free the device */
1553 ExFreePool(DeviceExtension
->PciDevice
);
1555 /* Complete the IRP */
1556 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1557 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1560 IoDeleteDevice(DeviceObject
);
1561 return STATUS_SUCCESS
;
1564 case IRP_MN_QUERY_INTERFACE
:
1565 DPRINT("IRP_MN_QUERY_INTERFACE received\n");
1566 Status
= PdoQueryInterface(DeviceObject
, Irp
, IrpSp
);
1569 case IRP_MN_READ_CONFIG
:
1570 DPRINT("IRP_MN_READ_CONFIG received\n");
1571 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1574 case IRP_MN_WRITE_CONFIG
:
1575 DPRINT("IRP_MN_WRITE_CONFIG received\n");
1576 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1579 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1580 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS received\n");
1582 Irp
->IoStatus
.Status
= Status
;
1586 DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp
->MinorFunction
);
1590 if (Status
!= STATUS_PENDING
)
1592 Irp
->IoStatus
.Status
= Status
;
1593 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1596 DPRINT("Leaving. Status 0x%X\n", Status
);
1603 PDEVICE_OBJECT DeviceObject
,
1606 * FUNCTION: Handle power management IRPs for the child device
1608 * DeviceObject = Pointer to physical device object of the child device
1609 * Irp = Pointer to IRP that should be handled
1614 PIO_STACK_LOCATION IrpSp
;
1619 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1621 switch (IrpSp
->MinorFunction
)
1623 case IRP_MN_SET_POWER
:
1624 Status
= PdoSetPower(DeviceObject
, Irp
, IrpSp
);
1628 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1629 Status
= STATUS_NOT_IMPLEMENTED
;
1633 if (Status
!= STATUS_PENDING
)
1635 Irp
->IoStatus
.Status
= Status
;
1636 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1639 DPRINT("Leaving. Status 0x%X\n", Status
);