1 /* $Id: pdo.c,v 1.11 2004/10/24 09:14:03 navaraf Exp $
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
,
357 /* FIXME: Check ROM address */
359 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
362 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
364 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
366 if (!PdoGetRangeLength(DeviceExtension
,
376 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
381 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
386 Irp
->IoStatus
.Information
= 0;
387 return STATUS_SUCCESS
;
390 /* Calculate the resource list size */
391 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
);
394 ListSize
+= ((ResCount
- 1) * sizeof(IO_RESOURCE_DESCRIPTOR
));
397 DPRINT("ListSize %lu (0x%lx)\n", ListSize
, ListSize
);
399 /* Allocate the resource requirements list */
400 ResourceList
= ExAllocatePool(PagedPool
,
402 if (ResourceList
== NULL
)
404 Irp
->IoStatus
.Information
= 0;
405 return STATUS_INSUFFICIENT_RESOURCES
;
408 ResourceList
->ListSize
= ListSize
;
409 ResourceList
->InterfaceType
= PCIBus
;
410 ResourceList
->AlternativeLists
= 1;
412 ResourceList
->List
[0].Version
= 1;
413 ResourceList
->List
[0].Revision
= 1;
414 ResourceList
->List
[0].Count
= ResCount
;
416 Descriptor
= &ResourceList
->List
[0].Descriptors
[0];
417 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 0)
419 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
421 if (!PdoGetRangeLength(DeviceExtension
,
427 DPRINT1("PdoGetRangeLength() failed\n");
433 DPRINT("Unused address register\n");
437 /* Set preferred descriptor */
438 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
439 if (Flags
& PCI_ADDRESS_IO_SPACE
)
441 Descriptor
->Type
= CmResourceTypePort
;
442 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
443 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
444 CM_RESOURCE_PORT_16_BIT_DECODE
|
445 CM_RESOURCE_PORT_POSITIVE_DECODE
;
447 Descriptor
->u
.Port
.Length
= Length
;
448 Descriptor
->u
.Port
.Alignment
= 1;
449 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
450 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
454 Descriptor
->Type
= CmResourceTypeMemory
;
455 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
456 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
458 Descriptor
->u
.Memory
.Length
= Length
;
459 Descriptor
->u
.Memory
.Alignment
= 1;
460 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
461 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
465 /* Set alternative descriptor */
466 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
467 if (Flags
& PCI_ADDRESS_IO_SPACE
)
469 Descriptor
->Type
= CmResourceTypePort
;
470 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
471 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
472 CM_RESOURCE_PORT_16_BIT_DECODE
|
473 CM_RESOURCE_PORT_POSITIVE_DECODE
;
475 Descriptor
->u
.Port
.Length
= Length
;
476 Descriptor
->u
.Port
.Alignment
= Length
;
477 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
478 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
482 Descriptor
->Type
= CmResourceTypeMemory
;
483 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
484 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
486 Descriptor
->u
.Memory
.Length
= Length
;
487 Descriptor
->u
.Memory
.Alignment
= Length
;
488 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
489 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
494 /* FIXME: Check ROM address */
496 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
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
) == 1)
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;
583 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 2)
585 /* FIXME: Add Cardbus bridge resources */
588 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
590 return STATUS_SUCCESS
;
596 IN PDEVICE_OBJECT DeviceObject
,
598 PIO_STACK_LOCATION IrpSp
)
600 PPDO_DEVICE_EXTENSION DeviceExtension
;
601 PCI_COMMON_CONFIG PciConfig
;
602 PCM_RESOURCE_LIST ResourceList
;
603 PCM_PARTIAL_RESOURCE_LIST PartialList
;
604 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
613 DPRINT("PdoQueryResources() called\n");
615 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
617 /* Get PCI configuration space */
618 Size
= HalGetBusData(PCIConfiguration
,
619 DeviceExtension
->BusNumber
,
620 DeviceExtension
->SlotNumber
.u
.AsULONG
,
622 sizeof(PCI_COMMON_CONFIG
));
623 DPRINT("Size %lu\n", Size
);
624 if (Size
< sizeof(PCI_COMMON_CONFIG
))
626 Irp
->IoStatus
.Information
= 0;
627 return STATUS_UNSUCCESSFUL
;
630 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
632 /* Count required resource descriptors */
634 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 0)
636 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
638 if (!PdoGetRangeLength(DeviceExtension
,
648 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
649 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
652 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 1)
654 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
656 if (!PdoGetRangeLength(DeviceExtension
,
666 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 2)
672 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
677 Irp
->IoStatus
.Information
= 0;
678 return STATUS_SUCCESS
;
681 /* Calculate the resource list size */
682 ListSize
= sizeof(CM_RESOURCE_LIST
);
685 ListSize
+= ((ResCount
- 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
688 /* Allocate the resource list */
689 ResourceList
= ExAllocatePool(PagedPool
,
691 if (ResourceList
== NULL
)
692 return STATUS_INSUFFICIENT_RESOURCES
;
694 ResourceList
->Count
= 1;
695 ResourceList
->List
[0].InterfaceType
= PCIConfiguration
;
696 ResourceList
->List
[0].BusNumber
= DeviceExtension
->BusNumber
;
698 PartialList
= &ResourceList
->List
[0].PartialResourceList
;
699 PartialList
->Version
= 0;
700 PartialList
->Revision
= 0;
701 PartialList
->Count
= ResCount
;
703 Descriptor
= &PartialList
->PartialDescriptors
[0];
704 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 0)
706 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
708 if (!PdoGetRangeLength(DeviceExtension
,
714 DPRINT1("PdoGetRangeLength() failed\n");
720 DPRINT("Unused address register\n");
724 if (Flags
& PCI_ADDRESS_IO_SPACE
)
726 Descriptor
->Type
= CmResourceTypePort
;
727 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
728 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
729 Descriptor
->u
.Port
.Start
.QuadPart
=
731 Descriptor
->u
.Port
.Length
= Length
;
735 Descriptor
->Type
= CmResourceTypeMemory
;
736 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
737 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
738 Descriptor
->u
.Memory
.Start
.QuadPart
=
740 Descriptor
->u
.Memory
.Length
= Length
;
746 /* Add interrupt resource */
747 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
748 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
750 Descriptor
->Type
= CmResourceTypeInterrupt
;
751 Descriptor
->ShareDisposition
= CmResourceShareShared
;
752 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
753 Descriptor
->u
.Interrupt
.Level
= PciConfig
.u
.type0
.InterruptLine
;
754 Descriptor
->u
.Interrupt
.Vector
= PciConfig
.u
.type0
.InterruptLine
;
755 Descriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
758 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 1)
760 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
762 if (!PdoGetRangeLength(DeviceExtension
,
768 DPRINT1("PdoGetRangeLength() failed\n");
774 DPRINT("Unused address register\n");
778 if (Flags
& PCI_ADDRESS_IO_SPACE
)
780 Descriptor
->Type
= CmResourceTypePort
;
781 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
782 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
783 Descriptor
->u
.Port
.Start
.QuadPart
=
785 Descriptor
->u
.Port
.Length
= Length
;
789 Descriptor
->Type
= CmResourceTypeMemory
;
790 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
791 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
792 Descriptor
->u
.Memory
.Start
.QuadPart
=
794 Descriptor
->u
.Memory
.Length
= Length
;
800 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == 2)
805 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
807 return STATUS_SUCCESS
;
813 IN PDEVICE_OBJECT DeviceObject
,
815 PIO_STACK_LOCATION IrpSp
)
817 PPDO_DEVICE_EXTENSION DeviceExtension
;
820 DPRINT1("PdoReadConfig() called\n");
822 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
825 if (IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
!= PCI_WHICHSPACE_CONFIG
)
826 return STATUS_NOT_SUPPORTED
;
829 /* Get PCI configuration space */
830 Size
= HalGetBusDataByOffset(PCIConfiguration
,
831 DeviceExtension
->BusNumber
,
832 DeviceExtension
->SlotNumber
.u
.AsULONG
,
833 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
834 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
835 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
836 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
838 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
839 Irp
->IoStatus
.Information
= 0;
840 return STATUS_UNSUCCESSFUL
;
843 Irp
->IoStatus
.Information
= Size
;
845 return STATUS_SUCCESS
;
851 IN PDEVICE_OBJECT DeviceObject
,
853 PIO_STACK_LOCATION IrpSp
)
855 PPDO_DEVICE_EXTENSION DeviceExtension
;
858 DPRINT1("PdoWriteConfig() called\n");
860 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
863 if (IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
!= PCI_WHICHSPACE_CONFIG
)
864 return STATUS_NOT_SUPPORTED
;
867 /* Get PCI configuration space */
868 Size
= HalSetBusDataByOffset(PCIConfiguration
,
869 DeviceExtension
->BusNumber
,
870 DeviceExtension
->SlotNumber
.u
.AsULONG
,
871 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
872 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
873 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
874 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
876 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
877 Irp
->IoStatus
.Information
= 0;
878 return STATUS_UNSUCCESSFUL
;
881 Irp
->IoStatus
.Information
= Size
;
883 return STATUS_SUCCESS
;
889 IN PDEVICE_OBJECT DeviceObject
,
891 PIO_STACK_LOCATION IrpSp
)
893 PPDO_DEVICE_EXTENSION DeviceExtension
;
898 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
900 if (IrpSp
->Parameters
.Power
.Type
== DevicePowerState
) {
901 Status
= STATUS_SUCCESS
;
902 switch (IrpSp
->Parameters
.Power
.State
.SystemState
) {
904 Status
= STATUS_UNSUCCESSFUL
;
907 Status
= STATUS_UNSUCCESSFUL
;
914 /*** PUBLIC ******************************************************************/
918 PDEVICE_OBJECT DeviceObject
,
921 * FUNCTION: Handle Plug and Play IRPs for the child device
923 * DeviceObject = Pointer to physical device object of the child device
924 * Irp = Pointer to IRP that should be handled
929 PIO_STACK_LOCATION IrpSp
;
934 Status
= Irp
->IoStatus
.Status
;
936 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
938 switch (IrpSp
->MinorFunction
) {
940 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
947 case IRP_MN_QUERY_BUS_INFORMATION
:
948 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
951 case IRP_MN_QUERY_CAPABILITIES
:
952 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
956 case IRP_MN_QUERY_DEVICE_RELATIONS
:
957 /* FIXME: Possibly handle for RemovalRelations */
961 case IRP_MN_QUERY_DEVICE_TEXT
:
962 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
963 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
966 case IRP_MN_QUERY_ID
:
967 DPRINT("IRP_MN_QUERY_ID received\n");
968 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
972 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
976 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
977 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
978 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
981 case IRP_MN_QUERY_RESOURCES
:
982 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
983 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
987 case IRP_MN_SET_LOCK
:
991 case IRP_MN_START_DEVICE
:
992 case IRP_MN_QUERY_STOP_DEVICE
:
993 case IRP_MN_CANCEL_STOP_DEVICE
:
994 case IRP_MN_STOP_DEVICE
:
995 case IRP_MN_QUERY_REMOVE_DEVICE
:
996 case IRP_MN_CANCEL_REMOVE_DEVICE
:
997 case IRP_MN_REMOVE_DEVICE
:
998 case IRP_MN_SURPRISE_REMOVAL
:
999 Status
= STATUS_SUCCESS
;
1002 case IRP_MN_READ_CONFIG
:
1003 DPRINT1("IRP_MN_READ_CONFIG received\n");
1004 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1007 case IRP_MN_WRITE_CONFIG
:
1008 DPRINT1("IRP_MN_WRITE_CONFIG received\n");
1009 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1013 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1017 if (Status
!= STATUS_PENDING
) {
1018 Irp
->IoStatus
.Status
= Status
;
1019 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1022 DPRINT("Leaving. Status 0x%X\n", Status
);
1029 PDEVICE_OBJECT DeviceObject
,
1032 * FUNCTION: Handle power management IRPs for the child device
1034 * DeviceObject = Pointer to physical device object of the child device
1035 * Irp = Pointer to IRP that should be handled
1040 PIO_STACK_LOCATION IrpSp
;
1045 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1047 switch (IrpSp
->MinorFunction
) {
1048 case IRP_MN_SET_POWER
:
1049 Status
= PdoSetPower(DeviceObject
, Irp
, IrpSp
);
1053 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1054 Status
= STATUS_NOT_IMPLEMENTED
;
1058 if (Status
!= STATUS_PENDING
) {
1059 Irp
->IoStatus
.Status
= Status
;
1060 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1063 DPRINT("Leaving. Status 0x%X\n", Status
);