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
17 /*** PRIVATE *****************************************************************/
21 IN PDEVICE_OBJECT DeviceObject
,
23 PIO_STACK_LOCATION IrpSp
)
25 PPDO_DEVICE_EXTENSION DeviceExtension
;
30 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
32 Status
= STATUS_SUCCESS
;
34 switch (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
)
36 case DeviceTextDescription
:
37 DPRINT("DeviceTextDescription\n");
38 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceExtension
->DeviceDescription
.Buffer
;
41 case DeviceTextLocationInformation
:
42 DPRINT("DeviceTextLocationInformation\n");
43 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceExtension
->DeviceLocation
.Buffer
;
47 Irp
->IoStatus
.Information
= 0;
48 Status
= STATUS_INVALID_PARAMETER
;
57 IN PDEVICE_OBJECT DeviceObject
,
59 PIO_STACK_LOCATION IrpSp
)
61 PPDO_DEVICE_EXTENSION DeviceExtension
;
62 UNICODE_STRING String
;
67 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
69 // Irp->IoStatus.Information = 0;
71 Status
= STATUS_SUCCESS
;
73 RtlInitUnicodeString(&String
, NULL
);
75 switch (IrpSp
->Parameters
.QueryId
.IdType
) {
76 case BusQueryDeviceID
:
77 Status
= PciDuplicateUnicodeString(
78 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
79 &DeviceExtension
->DeviceID
,
82 DPRINT("DeviceID: %S\n", String
.Buffer
);
84 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
87 case BusQueryHardwareIDs
:
88 Status
= PciDuplicateUnicodeString(
89 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
90 &DeviceExtension
->HardwareIDs
,
93 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
96 case BusQueryCompatibleIDs
:
97 Status
= PciDuplicateUnicodeString(
98 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
99 &DeviceExtension
->CompatibleIDs
,
102 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
105 case BusQueryInstanceID
:
106 Status
= PciDuplicateUnicodeString(
107 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
108 &DeviceExtension
->InstanceID
,
111 DPRINT("InstanceID: %S\n", String
.Buffer
);
113 Irp
->IoStatus
.Information
= (ULONG_PTR
)String
.Buffer
;
116 case BusQueryDeviceSerialNumber
:
118 Status
= STATUS_NOT_IMPLEMENTED
;
126 PdoQueryBusInformation(
127 IN PDEVICE_OBJECT DeviceObject
,
129 PIO_STACK_LOCATION IrpSp
)
131 PPDO_DEVICE_EXTENSION DeviceExtension
;
132 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
133 PPNP_BUS_INFORMATION BusInformation
;
137 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
138 FdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
139 BusInformation
= ExAllocatePool(PagedPool
, sizeof(PNP_BUS_INFORMATION
));
140 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInformation
;
141 if (BusInformation
!= NULL
)
143 BusInformation
->BusTypeGuid
= GUID_BUS_TYPE_PCI
;
144 BusInformation
->LegacyBusType
= PCIBus
;
145 BusInformation
->BusNumber
= DeviceExtension
->PciDevice
->BusNumber
;
147 return STATUS_SUCCESS
;
150 return STATUS_INSUFFICIENT_RESOURCES
;
155 PdoQueryCapabilities(
156 IN PDEVICE_OBJECT DeviceObject
,
158 PIO_STACK_LOCATION IrpSp
)
160 PPDO_DEVICE_EXTENSION DeviceExtension
;
161 PDEVICE_CAPABILITIES DeviceCapabilities
;
162 ULONG DeviceNumber
, FunctionNumber
;
166 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
167 DeviceCapabilities
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
169 if (DeviceCapabilities
->Version
!= 1)
170 return STATUS_UNSUCCESSFUL
;
172 DeviceNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.DeviceNumber
;
173 FunctionNumber
= DeviceExtension
->PciDevice
->SlotNumber
.u
.bits
.FunctionNumber
;
175 DeviceCapabilities
->UniqueID
= FALSE
;
176 DeviceCapabilities
->Address
= ((DeviceNumber
<< 16) & 0xFFFF0000) + (FunctionNumber
& 0xFFFF);
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
->PciDevice
->BusNumber
,
199 DeviceExtension
->PciDevice
->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
->PciDevice
->BusNumber
,
217 DeviceExtension
->PciDevice
->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
->PciDevice
->BusNumber
,
230 DeviceExtension
->PciDevice
->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
->PciDevice
->BusNumber
,
243 DeviceExtension
->PciDevice
->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
->PciDevice
->BusNumber
,
329 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
331 PCI_COMMON_HDR_LENGTH
);
332 DPRINT("Size %lu\n", Size
);
333 if (Size
< PCI_COMMON_HDR_LENGTH
)
335 Irp
->IoStatus
.Information
= 0;
336 return STATUS_UNSUCCESSFUL
;
339 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
341 /* Count required resource descriptors */
343 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
345 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
347 if (!PdoGetRangeLength(DeviceExtension
,
358 /* FIXME: Check ROM address */
360 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
363 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
365 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
367 if (!PdoGetRangeLength(DeviceExtension
,
377 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
380 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
382 /* FIXME: Count Cardbus bridge resources */
386 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
391 Irp
->IoStatus
.Information
= 0;
392 return STATUS_SUCCESS
;
395 /* Calculate the resource list size */
396 ListSize
= FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST
, List
->Descriptors
)
397 + ResCount
* sizeof(IO_RESOURCE_DESCRIPTOR
);
399 DPRINT("ListSize %lu (0x%lx)\n", ListSize
, ListSize
);
401 /* Allocate the resource requirements list */
402 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
404 if (ResourceList
== NULL
)
406 Irp
->IoStatus
.Information
= 0;
407 return STATUS_INSUFFICIENT_RESOURCES
;
410 RtlZeroMemory(ResourceList
, ListSize
);
411 ResourceList
->ListSize
= ListSize
;
412 ResourceList
->InterfaceType
= PCIBus
;
413 ResourceList
->BusNumber
= 0;
414 ResourceList
->SlotNumber
= 0;
415 ResourceList
->AlternativeLists
= 1;
417 ResourceList
->List
[0].Version
= 1;
418 ResourceList
->List
[0].Revision
= 1;
419 ResourceList
->List
[0].Count
= ResCount
;
421 Descriptor
= &ResourceList
->List
[0].Descriptors
[0];
422 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
424 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
426 if (!PdoGetRangeLength(DeviceExtension
,
432 DPRINT1("PdoGetRangeLength() failed\n");
438 DPRINT("Unused address register\n");
442 /* Set preferred descriptor */
443 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
444 if (Flags
& PCI_ADDRESS_IO_SPACE
)
446 Descriptor
->Type
= CmResourceTypePort
;
447 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
448 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
449 CM_RESOURCE_PORT_16_BIT_DECODE
|
450 CM_RESOURCE_PORT_POSITIVE_DECODE
;
452 Descriptor
->u
.Port
.Length
= Length
;
453 Descriptor
->u
.Port
.Alignment
= 1;
454 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
455 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
459 Descriptor
->Type
= CmResourceTypeMemory
;
460 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
461 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
463 Descriptor
->u
.Memory
.Length
= Length
;
464 Descriptor
->u
.Memory
.Alignment
= 1;
465 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
466 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
470 /* Set alternative descriptor */
471 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
472 if (Flags
& PCI_ADDRESS_IO_SPACE
)
474 Descriptor
->Type
= CmResourceTypePort
;
475 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
476 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
477 CM_RESOURCE_PORT_16_BIT_DECODE
|
478 CM_RESOURCE_PORT_POSITIVE_DECODE
;
480 Descriptor
->u
.Port
.Length
= Length
;
481 Descriptor
->u
.Port
.Alignment
= Length
;
482 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
483 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
487 Descriptor
->Type
= CmResourceTypeMemory
;
488 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
489 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
491 Descriptor
->u
.Memory
.Length
= Length
;
492 Descriptor
->u
.Memory
.Alignment
= Length
;
493 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
494 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
499 /* FIXME: Check ROM address */
501 if (PciConfig
.u
.type0
.InterruptPin
!= 0)
503 Descriptor
->Option
= 0; /* Required */
504 Descriptor
->Type
= CmResourceTypeInterrupt
;
505 Descriptor
->ShareDisposition
= CmResourceShareShared
;
506 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
508 Descriptor
->u
.Interrupt
.MinimumVector
= 0;
509 Descriptor
->u
.Interrupt
.MaximumVector
= 0xFF;
512 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
514 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
516 if (!PdoGetRangeLength(DeviceExtension
,
522 DPRINT1("PdoGetRangeLength() failed\n");
528 DPRINT("Unused address register\n");
532 /* Set preferred descriptor */
533 Descriptor
->Option
= IO_RESOURCE_PREFERRED
;
534 if (Flags
& PCI_ADDRESS_IO_SPACE
)
536 Descriptor
->Type
= CmResourceTypePort
;
537 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
538 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
539 CM_RESOURCE_PORT_16_BIT_DECODE
|
540 CM_RESOURCE_PORT_POSITIVE_DECODE
;
542 Descriptor
->u
.Port
.Length
= Length
;
543 Descriptor
->u
.Port
.Alignment
= 1;
544 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
545 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
549 Descriptor
->Type
= CmResourceTypeMemory
;
550 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
551 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
553 Descriptor
->u
.Memory
.Length
= Length
;
554 Descriptor
->u
.Memory
.Alignment
= 1;
555 Descriptor
->u
.Memory
.MinimumAddress
.QuadPart
= (ULONGLONG
)Base
;
556 Descriptor
->u
.Memory
.MaximumAddress
.QuadPart
= (ULONGLONG
)(Base
+ Length
- 1);
560 /* Set alternative descriptor */
561 Descriptor
->Option
= IO_RESOURCE_ALTERNATIVE
;
562 if (Flags
& PCI_ADDRESS_IO_SPACE
)
564 Descriptor
->Type
= CmResourceTypePort
;
565 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
566 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
|
567 CM_RESOURCE_PORT_16_BIT_DECODE
|
568 CM_RESOURCE_PORT_POSITIVE_DECODE
;
570 Descriptor
->u
.Port
.Length
= Length
;
571 Descriptor
->u
.Port
.Alignment
= Length
;
572 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
573 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
577 Descriptor
->Type
= CmResourceTypeMemory
;
578 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
579 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
581 Descriptor
->u
.Memory
.Length
= Length
;
582 Descriptor
->u
.Memory
.Alignment
= Length
;
583 Descriptor
->u
.Port
.MinimumAddress
.QuadPart
= (ULONGLONG
)0;
584 Descriptor
->u
.Port
.MaximumAddress
.QuadPart
= (ULONGLONG
)0x00000000FFFFFFFF;
588 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
590 Descriptor
->Option
= 0; /* Required */
591 Descriptor
->Type
= CmResourceTypeBusNumber
;
592 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
594 ResourceList
->BusNumber
=
595 Descriptor
->u
.BusNumber
.MinBusNumber
=
596 Descriptor
->u
.BusNumber
.MaxBusNumber
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
597 Descriptor
->u
.BusNumber
.Length
= 1;
598 Descriptor
->u
.BusNumber
.Reserved
= 0;
601 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
603 /* FIXME: Add Cardbus bridge resources */
606 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
608 return STATUS_SUCCESS
;
614 IN PDEVICE_OBJECT DeviceObject
,
616 PIO_STACK_LOCATION IrpSp
)
618 PPDO_DEVICE_EXTENSION DeviceExtension
;
619 PCI_COMMON_CONFIG PciConfig
;
620 PCM_RESOURCE_LIST ResourceList
;
621 PCM_PARTIAL_RESOURCE_LIST PartialList
;
622 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
631 DPRINT("PdoQueryResources() called\n");
633 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
635 /* Get PCI configuration space */
636 Size
= HalGetBusData(PCIConfiguration
,
637 DeviceExtension
->PciDevice
->BusNumber
,
638 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
640 PCI_COMMON_HDR_LENGTH
);
641 DPRINT("Size %lu\n", Size
);
642 if (Size
< PCI_COMMON_HDR_LENGTH
)
644 Irp
->IoStatus
.Information
= 0;
645 return STATUS_UNSUCCESSFUL
;
648 DPRINT("Command register: 0x%04hx\n", PciConfig
.Command
);
650 /* Count required resource descriptors */
652 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
654 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
656 if (!PdoGetRangeLength(DeviceExtension
,
667 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
668 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
671 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
673 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
675 if (!PdoGetRangeLength(DeviceExtension
,
685 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
688 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
690 /* FIXME: Count Cardbus bridge resources */
694 DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig
));
699 Irp
->IoStatus
.Information
= 0;
700 return STATUS_SUCCESS
;
703 /* Calculate the resource list size */
704 ListSize
= FIELD_OFFSET(CM_RESOURCE_LIST
, List
->PartialResourceList
.PartialDescriptors
)
705 + ResCount
* sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
707 /* Allocate the resource list */
708 ResourceList
= ExAllocatePoolWithTag(PagedPool
,
710 if (ResourceList
== NULL
)
711 return STATUS_INSUFFICIENT_RESOURCES
;
713 RtlZeroMemory(ResourceList
, ListSize
);
714 ResourceList
->Count
= 1;
715 ResourceList
->List
[0].InterfaceType
= PCIBus
;
716 ResourceList
->List
[0].BusNumber
= 0;
718 PartialList
= &ResourceList
->List
[0].PartialResourceList
;
719 PartialList
->Version
= 1;
720 PartialList
->Revision
= 1;
721 PartialList
->Count
= ResCount
;
723 Descriptor
= &PartialList
->PartialDescriptors
[0];
724 if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_DEVICE_TYPE
)
726 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
728 if (!PdoGetRangeLength(DeviceExtension
,
734 DPRINT1("PdoGetRangeLength() failed\n");
740 DPRINT("Unused address register\n");
744 if (Flags
& PCI_ADDRESS_IO_SPACE
)
746 Descriptor
->Type
= CmResourceTypePort
;
747 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
748 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
749 Descriptor
->u
.Port
.Start
.QuadPart
=
751 Descriptor
->u
.Port
.Length
= Length
;
755 Descriptor
->Type
= CmResourceTypeMemory
;
756 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
757 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
758 Descriptor
->u
.Memory
.Start
.QuadPart
=
760 Descriptor
->u
.Memory
.Length
= Length
;
766 /* Add interrupt resource */
767 if ((PciConfig
.u
.type0
.InterruptPin
!= 0) &&
768 (PciConfig
.u
.type0
.InterruptLine
!= 0xFF))
770 Descriptor
->Type
= CmResourceTypeInterrupt
;
771 Descriptor
->ShareDisposition
= CmResourceShareShared
;
772 Descriptor
->Flags
= CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
;
773 Descriptor
->u
.Interrupt
.Level
= PciConfig
.u
.type0
.InterruptLine
;
774 Descriptor
->u
.Interrupt
.Vector
= 0;
775 Descriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
778 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_BRIDGE_TYPE
)
780 for (i
= 0; i
< PCI_TYPE1_ADDRESSES
; i
++)
782 if (!PdoGetRangeLength(DeviceExtension
,
788 DPRINT1("PdoGetRangeLength() failed\n");
794 DPRINT("Unused address register\n");
798 if (Flags
& PCI_ADDRESS_IO_SPACE
)
800 Descriptor
->Type
= CmResourceTypePort
;
801 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
802 Descriptor
->Flags
= CM_RESOURCE_PORT_IO
;
803 Descriptor
->u
.Port
.Start
.QuadPart
=
805 Descriptor
->u
.Port
.Length
= Length
;
809 Descriptor
->Type
= CmResourceTypeMemory
;
810 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
811 Descriptor
->Flags
= CM_RESOURCE_MEMORY_READ_WRITE
;
812 Descriptor
->u
.Memory
.Start
.QuadPart
=
814 Descriptor
->u
.Memory
.Length
= Length
;
819 if (DeviceExtension
->PciDevice
->PciConfig
.BaseClass
== PCI_CLASS_BRIDGE_DEV
)
821 Descriptor
->Type
= CmResourceTypeBusNumber
;
822 Descriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
824 ResourceList
->List
[0].BusNumber
=
825 Descriptor
->u
.BusNumber
.Start
= DeviceExtension
->PciDevice
->PciConfig
.u
.type1
.SecondaryBus
;
826 Descriptor
->u
.BusNumber
.Length
= 1;
827 Descriptor
->u
.BusNumber
.Reserved
= 0;
830 else if (PCI_CONFIGURATION_TYPE(&PciConfig
) == PCI_CARDBUS_BRIDGE_TYPE
)
832 /* FIXME: Add Cardbus bridge resources */
835 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
837 return STATUS_SUCCESS
;
845 PPDO_DEVICE_EXTENSION DeviceExtension
;
847 DPRINT("InterfaceReference(%p)\n", Context
);
849 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
850 InterlockedIncrement(&DeviceExtension
->References
);
855 InterfaceDereference(
858 PPDO_DEVICE_EXTENSION DeviceExtension
;
860 DPRINT("InterfaceDereference(%p)\n", Context
);
862 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
863 InterlockedDecrement(&DeviceExtension
->References
);
868 InterfaceBusTranslateBusAddress(
870 IN PHYSICAL_ADDRESS BusAddress
,
872 IN OUT PULONG AddressSpace
,
873 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
875 PPDO_DEVICE_EXTENSION DeviceExtension
;
877 DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
878 Context
, BusAddress
, Length
, AddressSpace
, TranslatedAddress
);
880 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
882 return HalTranslateBusAddress(
883 PCIBus
, DeviceExtension
->PciDevice
->BusNumber
,
884 BusAddress
, AddressSpace
, TranslatedAddress
);
888 static PDMA_ADAPTER NTAPI
889 InterfaceBusGetDmaAdapter(
891 IN PDEVICE_DESCRIPTION DeviceDescription
,
892 OUT PULONG NumberOfMapRegisters
)
894 DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
895 Context
, DeviceDescription
, NumberOfMapRegisters
);
896 return (PDMA_ADAPTER
)HalGetAdapter(DeviceDescription
, NumberOfMapRegisters
);
901 InterfaceBusSetBusData(
908 PPDO_DEVICE_EXTENSION DeviceExtension
;
911 DPRINT("InterfaceBusSetBusData(%p 0x%lx %p 0x%lx 0x%lx)\n",
912 Context
, DataType
, Buffer
, Offset
, Length
);
914 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
916 DPRINT("Unknown DataType %lu\n", DataType
);
920 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
922 /* Get PCI configuration space */
923 Size
= HalSetBusDataByOffset(PCIConfiguration
,
924 DeviceExtension
->PciDevice
->BusNumber
,
925 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
934 InterfaceBusGetBusData(
941 PPDO_DEVICE_EXTENSION DeviceExtension
;
944 DPRINT("InterfaceBusGetBusData(%p 0x%lx %p 0x%lx 0x%lx) called\n",
945 Context
, DataType
, Buffer
, Offset
, Length
);
947 if (DataType
!= PCI_WHICHSPACE_CONFIG
)
949 DPRINT("Unknown DataType %lu\n", DataType
);
953 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
955 /* Get PCI configuration space */
956 Size
= HalGetBusDataByOffset(PCIConfiguration
,
957 DeviceExtension
->PciDevice
->BusNumber
,
958 DeviceExtension
->PciDevice
->SlotNumber
.u
.AsULONG
,
967 InterfacePciDevicePresent(
971 IN USHORT SubVendorID
,
972 IN USHORT SubSystemID
,
975 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
976 PPCI_DEVICE PciDevice
;
977 PLIST_ENTRY CurrentBus
, CurrentEntry
;
979 BOOLEAN Found
= FALSE
;
981 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
982 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
983 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
985 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
987 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
988 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
989 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
991 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
992 if (PciDevice
->PciConfig
.VendorID
== VendorID
&&
993 PciDevice
->PciConfig
.DeviceID
== DeviceID
)
995 if (!(Flags
& PCI_USE_SUBSYSTEM_IDS
) || (
996 PciDevice
->PciConfig
.u
.type0
.SubVendorID
== SubVendorID
&&
997 PciDevice
->PciConfig
.u
.type0
.SubSystemID
== SubSystemID
))
999 if (!(Flags
& PCI_USE_REVISION
) ||
1000 PciDevice
->PciConfig
.RevisionID
== RevisionID
)
1002 DPRINT("Found the PCI device\n");
1008 CurrentEntry
= CurrentEntry
->Flink
;
1011 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1012 CurrentBus
= CurrentBus
->Flink
;
1014 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1022 IN PPCI_COMMON_CONFIG PciConfig
,
1023 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1025 if ((Parameters
->Flags
& PCI_USE_VENDEV_IDS
) && (
1026 PciConfig
->VendorID
!= Parameters
->VendorID
||
1027 PciConfig
->DeviceID
!= Parameters
->DeviceID
))
1031 if ((Parameters
->Flags
& PCI_USE_CLASS_SUBCLASS
) && (
1032 PciConfig
->BaseClass
!= Parameters
->BaseClass
||
1033 PciConfig
->SubClass
!= Parameters
->SubClass
))
1037 if ((Parameters
->Flags
& PCI_USE_PROGIF
) &&
1038 PciConfig
->ProgIf
!= Parameters
->ProgIf
)
1042 if ((Parameters
->Flags
& PCI_USE_SUBSYSTEM_IDS
) && (
1043 PciConfig
->u
.type0
.SubVendorID
!= Parameters
->SubVendorID
||
1044 PciConfig
->u
.type0
.SubSystemID
!= Parameters
->SubSystemID
))
1048 if ((Parameters
->Flags
& PCI_USE_REVISION
) &&
1049 PciConfig
->RevisionID
!= Parameters
->RevisionID
)
1057 static BOOLEAN NTAPI
1058 InterfacePciDevicePresentEx(
1060 IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
)
1062 PPDO_DEVICE_EXTENSION DeviceExtension
;
1063 PFDO_DEVICE_EXTENSION MyFdoDeviceExtension
;
1064 PFDO_DEVICE_EXTENSION FdoDeviceExtension
;
1065 PPCI_DEVICE PciDevice
;
1066 PLIST_ENTRY CurrentBus
, CurrentEntry
;
1068 BOOLEAN Found
= FALSE
;
1070 DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
1071 Context
, Parameters
);
1073 if (!Parameters
|| Parameters
->Size
!= sizeof(PCI_DEVICE_PRESENCE_PARAMETERS
))
1076 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
1077 MyFdoDeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceExtension
->Fdo
->DeviceExtension
;
1079 if (Parameters
->Flags
& PCI_USE_LOCAL_DEVICE
)
1081 return CheckPciDevice(&DeviceExtension
->PciDevice
->PciConfig
, Parameters
);
1084 KeAcquireSpinLock(&DriverExtension
->BusListLock
, &OldIrql
);
1085 CurrentBus
= DriverExtension
->BusListHead
.Flink
;
1086 while (!Found
&& CurrentBus
!= &DriverExtension
->BusListHead
)
1088 FdoDeviceExtension
= CONTAINING_RECORD(CurrentBus
, FDO_DEVICE_EXTENSION
, ListEntry
);
1089 if (!(Parameters
->Flags
& PCI_USE_LOCAL_BUS
) || FdoDeviceExtension
== MyFdoDeviceExtension
)
1091 KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1092 CurrentEntry
= FdoDeviceExtension
->DeviceListHead
.Flink
;
1093 while (!Found
&& CurrentEntry
!= &FdoDeviceExtension
->DeviceListHead
)
1095 PciDevice
= CONTAINING_RECORD(CurrentEntry
, PCI_DEVICE
, ListEntry
);
1097 if (CheckPciDevice(&PciDevice
->PciConfig
, Parameters
))
1099 DPRINT("Found the PCI device\n");
1103 CurrentEntry
= CurrentEntry
->Flink
;
1106 KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension
->DeviceListLock
);
1108 CurrentBus
= CurrentBus
->Flink
;
1110 KeReleaseSpinLock(&DriverExtension
->BusListLock
, OldIrql
);
1118 IN PDEVICE_OBJECT DeviceObject
,
1120 PIO_STACK_LOCATION IrpSp
)
1124 if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1125 &GUID_BUS_INTERFACE_STANDARD
, sizeof(GUID
)) == sizeof(GUID
))
1127 /* BUS_INTERFACE_STANDARD */
1128 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1129 Status
= STATUS_NOT_SUPPORTED
;
1130 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(BUS_INTERFACE_STANDARD
))
1131 Status
= STATUS_BUFFER_TOO_SMALL
;
1134 PBUS_INTERFACE_STANDARD BusInterface
;
1135 BusInterface
= (PBUS_INTERFACE_STANDARD
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1136 BusInterface
->Size
= sizeof(BUS_INTERFACE_STANDARD
);
1137 BusInterface
->Version
= 1;
1138 BusInterface
->TranslateBusAddress
= InterfaceBusTranslateBusAddress
;
1139 BusInterface
->GetDmaAdapter
= InterfaceBusGetDmaAdapter
;
1140 BusInterface
->SetBusData
= InterfaceBusSetBusData
;
1141 BusInterface
->GetBusData
= InterfaceBusGetBusData
;
1142 Status
= STATUS_SUCCESS
;
1145 else if (RtlCompareMemory(IrpSp
->Parameters
.QueryInterface
.InterfaceType
,
1146 &GUID_PCI_DEVICE_PRESENT_INTERFACE
, sizeof(GUID
)) == sizeof(GUID
))
1148 /* PCI_DEVICE_PRESENT_INTERFACE */
1149 if (IrpSp
->Parameters
.QueryInterface
.Version
< 1)
1150 Status
= STATUS_NOT_SUPPORTED
;
1151 else if (IrpSp
->Parameters
.QueryInterface
.Size
< sizeof(PCI_DEVICE_PRESENT_INTERFACE
))
1152 Status
= STATUS_BUFFER_TOO_SMALL
;
1155 PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface
;
1156 PciDevicePresentInterface
= (PPCI_DEVICE_PRESENT_INTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1157 PciDevicePresentInterface
->Size
= sizeof(PCI_DEVICE_PRESENT_INTERFACE
);
1158 PciDevicePresentInterface
->Version
= 1;
1159 PciDevicePresentInterface
->IsDevicePresent
= InterfacePciDevicePresent
;
1160 PciDevicePresentInterface
->IsDevicePresentEx
= InterfacePciDevicePresentEx
;
1161 Status
= STATUS_SUCCESS
;
1166 /* Not a supported interface */
1167 return STATUS_NOT_SUPPORTED
;
1170 if (NT_SUCCESS(Status
))
1172 /* Add a reference for the returned interface */
1173 PINTERFACE Interface
;
1174 Interface
= (PINTERFACE
)IrpSp
->Parameters
.QueryInterface
.Interface
;
1175 Interface
->Context
= DeviceObject
;
1176 Interface
->InterfaceReference
= InterfaceReference
;
1177 Interface
->InterfaceDereference
= InterfaceDereference
;
1178 Interface
->InterfaceReference(Interface
->Context
);
1187 IN PDEVICE_OBJECT DeviceObject
,
1189 PIO_STACK_LOCATION IrpSp
)
1193 DPRINT("PdoReadConfig() called\n");
1195 Size
= InterfaceBusGetBusData(
1197 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1198 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1199 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1200 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1202 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1204 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1205 Irp
->IoStatus
.Information
= 0;
1206 return STATUS_UNSUCCESSFUL
;
1209 Irp
->IoStatus
.Information
= Size
;
1211 return STATUS_SUCCESS
;
1217 IN PDEVICE_OBJECT DeviceObject
,
1219 PIO_STACK_LOCATION IrpSp
)
1223 DPRINT1("PdoWriteConfig() called\n");
1225 /* Get PCI configuration space */
1226 Size
= InterfaceBusSetBusData(
1228 IrpSp
->Parameters
.ReadWriteConfig
.WhichSpace
,
1229 IrpSp
->Parameters
.ReadWriteConfig
.Buffer
,
1230 IrpSp
->Parameters
.ReadWriteConfig
.Offset
,
1231 IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1233 if (Size
!= IrpSp
->Parameters
.ReadWriteConfig
.Length
)
1235 DPRINT1("Size %lu Length %lu\n", Size
, IrpSp
->Parameters
.ReadWriteConfig
.Length
);
1236 Irp
->IoStatus
.Information
= 0;
1237 return STATUS_UNSUCCESSFUL
;
1240 Irp
->IoStatus
.Information
= Size
;
1242 return STATUS_SUCCESS
;
1248 IN PDEVICE_OBJECT DeviceObject
,
1250 PIO_STACK_LOCATION IrpSp
)
1252 PPDO_DEVICE_EXTENSION DeviceExtension
;
1257 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1259 if (IrpSp
->Parameters
.Power
.Type
== DevicePowerState
) {
1260 Status
= STATUS_SUCCESS
;
1261 switch (IrpSp
->Parameters
.Power
.State
.SystemState
) {
1263 Status
= STATUS_UNSUCCESSFUL
;
1266 Status
= STATUS_UNSUCCESSFUL
;
1273 /*** PUBLIC ******************************************************************/
1277 PDEVICE_OBJECT DeviceObject
,
1280 * FUNCTION: Handle Plug and Play IRPs for the child device
1282 * DeviceObject = Pointer to physical device object of the child device
1283 * Irp = Pointer to IRP that should be handled
1288 PIO_STACK_LOCATION IrpSp
;
1293 Status
= Irp
->IoStatus
.Status
;
1295 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1297 switch (IrpSp
->MinorFunction
) {
1299 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
1306 case IRP_MN_QUERY_BUS_INFORMATION
:
1307 Status
= PdoQueryBusInformation(DeviceObject
, Irp
, IrpSp
);
1310 case IRP_MN_QUERY_CAPABILITIES
:
1311 Status
= PdoQueryCapabilities(DeviceObject
, Irp
, IrpSp
);
1315 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1316 /* FIXME: Possibly handle for RemovalRelations */
1320 case IRP_MN_QUERY_DEVICE_TEXT
:
1321 DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
1322 Status
= PdoQueryDeviceText(DeviceObject
, Irp
, IrpSp
);
1325 case IRP_MN_QUERY_ID
:
1326 DPRINT("IRP_MN_QUERY_ID received\n");
1327 Status
= PdoQueryId(DeviceObject
, Irp
, IrpSp
);
1331 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1335 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
1336 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
1337 Status
= PdoQueryResourceRequirements(DeviceObject
, Irp
, IrpSp
);
1340 case IRP_MN_QUERY_RESOURCES
:
1341 DPRINT("IRP_MN_QUERY_RESOURCES received\n");
1342 Status
= PdoQueryResources(DeviceObject
, Irp
, IrpSp
);
1346 case IRP_MN_SET_LOCK
:
1350 case IRP_MN_START_DEVICE
:
1351 case IRP_MN_QUERY_STOP_DEVICE
:
1352 case IRP_MN_CANCEL_STOP_DEVICE
:
1353 case IRP_MN_STOP_DEVICE
:
1354 case IRP_MN_QUERY_REMOVE_DEVICE
:
1355 case IRP_MN_CANCEL_REMOVE_DEVICE
:
1356 case IRP_MN_REMOVE_DEVICE
:
1357 case IRP_MN_SURPRISE_REMOVAL
:
1358 Status
= STATUS_SUCCESS
;
1361 case IRP_MN_QUERY_INTERFACE
:
1362 DPRINT("IRP_MN_QUERY_INTERFACE received\n");
1363 Status
= PdoQueryInterface(DeviceObject
, Irp
, IrpSp
);
1366 case IRP_MN_READ_CONFIG
:
1367 DPRINT("IRP_MN_READ_CONFIG received\n");
1368 Status
= PdoReadConfig(DeviceObject
, Irp
, IrpSp
);
1371 case IRP_MN_WRITE_CONFIG
:
1372 DPRINT("IRP_MN_WRITE_CONFIG received\n");
1373 Status
= PdoWriteConfig(DeviceObject
, Irp
, IrpSp
);
1376 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1377 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS received\n");
1379 Irp
->IoStatus
.Status
= Status
;
1383 DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp
->MinorFunction
);
1387 if (Status
!= STATUS_PENDING
) {
1388 Irp
->IoStatus
.Status
= Status
;
1389 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1392 DPRINT("Leaving. Status 0x%X\n", Status
);
1399 PDEVICE_OBJECT DeviceObject
,
1402 * FUNCTION: Handle power management IRPs for the child device
1404 * DeviceObject = Pointer to physical device object of the child device
1405 * Irp = Pointer to IRP that should be handled
1410 PIO_STACK_LOCATION IrpSp
;
1415 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1417 switch (IrpSp
->MinorFunction
) {
1418 case IRP_MN_SET_POWER
:
1419 Status
= PdoSetPower(DeviceObject
, Irp
, IrpSp
);
1423 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1424 Status
= STATUS_NOT_IMPLEMENTED
;
1428 if (Status
!= STATUS_PENDING
) {
1429 Irp
->IoStatus
.Status
= Status
;
1430 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1433 DPRINT("Leaving. Status 0x%X\n", Status
);