4 * Copyright (C) 2002 - 2005 ReactOS Team
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 /* PRIVATE FUNCTIONS **********************************************************/
27 IntVideoPortGetLegacyResources(
28 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
,
29 IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
30 OUT PVIDEO_ACCESS_RANGE
*AccessRanges
,
31 OUT PULONG AccessRangeCount
)
33 PCI_COMMON_CONFIG PciConfig
;
36 if (!DriverExtension
->InitializationData
.HwGetLegacyResources
&&
37 !DriverExtension
->InitializationData
.HwLegacyResourceCount
)
39 /* No legacy resources to report */
40 *AccessRangeCount
= 0;
41 return STATUS_SUCCESS
;
44 if (DriverExtension
->InitializationData
.HwGetLegacyResources
)
46 ReadLength
= HalGetBusData(PCIConfiguration
,
47 DeviceExtension
->SystemIoBusNumber
,
48 DeviceExtension
->SystemIoSlotNumber
,
51 if (ReadLength
!= sizeof(PciConfig
))
53 /* This device doesn't exist */
54 return STATUS_NO_SUCH_DEVICE
;
57 DriverExtension
->InitializationData
.HwGetLegacyResources(PciConfig
.VendorID
,
64 *AccessRanges
= DriverExtension
->InitializationData
.HwLegacyResourceList
;
65 *AccessRangeCount
= DriverExtension
->InitializationData
.HwLegacyResourceCount
;
68 INFO_(VIDEOPRT
, "Got %d legacy access ranges\n", *AccessRangeCount
);
70 return STATUS_SUCCESS
;
74 IntVideoPortFilterResourceRequirements(
75 IN PDEVICE_OBJECT DeviceObject
,
78 PDRIVER_OBJECT DriverObject
;
79 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
80 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
81 PVIDEO_ACCESS_RANGE AccessRanges
;
82 ULONG AccessRangeCount
, ListSize
, i
;
83 PIO_RESOURCE_REQUIREMENTS_LIST ResList
, OldResList
= (PVOID
)Irp
->IoStatus
.Information
;
84 PIO_RESOURCE_DESCRIPTOR CurrentDescriptor
;
87 DriverObject
= DeviceObject
->DriverObject
;
88 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
89 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
91 Status
= IntVideoPortGetLegacyResources(DriverExtension
, DeviceExtension
, &AccessRanges
, &AccessRangeCount
);
92 if (!NT_SUCCESS(Status
))
94 if (!AccessRangeCount
)
96 /* No legacy resources to report */
97 return Irp
->IoStatus
.Information
;
100 /* OK, we've got the access ranges now. Let's set up the resource requirements list */
104 /* Already one there so let's add to it */
105 ListSize
= OldResList
->ListSize
+ sizeof(IO_RESOURCE_DESCRIPTOR
) * AccessRangeCount
;
106 ResList
= ExAllocatePool(NonPagedPool
,
108 if (!ResList
) return STATUS_NO_MEMORY
;
110 RtlCopyMemory(ResList
, OldResList
, OldResList
->ListSize
);
112 ASSERT(ResList
->AlternativeLists
== 1);
114 ResList
->ListSize
= ListSize
;
115 ResList
->List
[0].Count
+= AccessRangeCount
;
117 CurrentDescriptor
= (PIO_RESOURCE_DESCRIPTOR
)((PUCHAR
)ResList
+ OldResList
->ListSize
);
119 ExFreePool(OldResList
);
120 Irp
->IoStatus
.Information
= 0;
124 /* We need to make a new one */
125 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + sizeof(IO_RESOURCE_DESCRIPTOR
) * (AccessRangeCount
- 1);
126 ResList
= ExAllocatePool(NonPagedPool
,
128 if (!ResList
) return STATUS_NO_MEMORY
;
130 RtlZeroMemory(ResList
, ListSize
);
132 /* We need to initialize some fields */
133 ResList
->ListSize
= ListSize
;
134 ResList
->InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
135 ResList
->BusNumber
= DeviceExtension
->SystemIoBusNumber
;
136 ResList
->SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
137 ResList
->AlternativeLists
= 1;
138 ResList
->List
[0].Version
= 1;
139 ResList
->List
[0].Revision
= 1;
140 ResList
->List
[0].Count
= AccessRangeCount
;
142 CurrentDescriptor
= ResList
->List
[0].Descriptors
;
145 for (i
= 0; i
< AccessRangeCount
; i
++)
147 /* This is a required resource */
148 CurrentDescriptor
->Option
= 0;
150 if (AccessRanges
[i
].RangeInIoSpace
)
151 CurrentDescriptor
->Type
= CmResourceTypePort
;
153 CurrentDescriptor
->Type
= CmResourceTypeMemory
;
155 CurrentDescriptor
->ShareDisposition
=
156 (AccessRanges
[i
].RangeShareable
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
158 CurrentDescriptor
->Flags
= 0;
160 if (CurrentDescriptor
->Type
== CmResourceTypePort
)
162 CurrentDescriptor
->u
.Port
.Length
= AccessRanges
[i
].RangeLength
;
163 CurrentDescriptor
->u
.Port
.MinimumAddress
=
164 CurrentDescriptor
->u
.Port
.MaximumAddress
= AccessRanges
[i
].RangeStart
;
165 CurrentDescriptor
->u
.Port
.Alignment
= 1;
166 if (AccessRanges
[i
].RangePassive
& VIDEO_RANGE_PASSIVE_DECODE
)
167 CurrentDescriptor
->Flags
|= CM_RESOURCE_PORT_PASSIVE_DECODE
;
168 if (AccessRanges
[i
].RangePassive
& VIDEO_RANGE_10_BIT_DECODE
)
169 CurrentDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
173 CurrentDescriptor
->u
.Memory
.Length
= AccessRanges
[i
].RangeLength
;
174 CurrentDescriptor
->u
.Memory
.MinimumAddress
=
175 CurrentDescriptor
->u
.Memory
.MaximumAddress
= AccessRanges
[i
].RangeStart
;
176 CurrentDescriptor
->u
.Memory
.Alignment
= 1;
177 CurrentDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
183 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResList
;
185 return STATUS_SUCCESS
;
189 IntVideoPortMapPhysicalMemory(
191 IN PHYSICAL_ADDRESS PhysicalAddress
,
192 IN ULONG SizeInBytes
,
194 IN OUT PVOID
*VirtualAddress OPTIONAL
)
196 OBJECT_ATTRIBUTES ObjAttribs
;
197 UNICODE_STRING UnicodeString
;
202 /* Initialize object attribs */
203 RtlInitUnicodeString(&UnicodeString
, L
"\\Device\\PhysicalMemory");
204 InitializeObjectAttributes(&ObjAttribs
,
206 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
209 /* Open physical memory section */
210 Status
= ZwOpenSection(&hMemObj
, SECTION_ALL_ACCESS
, &ObjAttribs
);
211 if (!NT_SUCCESS(Status
))
213 WARN_(VIDEOPRT
, "ZwOpenSection() failed! (0x%x)\n", Status
);
217 /* Map view of section */
219 Status
= ZwMapViewOfSection(hMemObj
,
224 (PLARGE_INTEGER
)(&PhysicalAddress
),
230 if (!NT_SUCCESS(Status
))
232 WARN_(VIDEOPRT
, "ZwMapViewOfSection() failed! (0x%x)\n", Status
);
240 IntVideoPortMapMemory(
241 IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
242 IN PHYSICAL_ADDRESS IoAddress
,
243 IN ULONG NumberOfUchars
,
245 IN HANDLE ProcessHandle
,
246 OUT VP_STATUS
*Status
)
248 PHYSICAL_ADDRESS TranslatedAddress
;
249 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
254 INFO_(VIDEOPRT
, "- IoAddress: %lx\n", IoAddress
.u
.LowPart
);
255 INFO_(VIDEOPRT
, "- NumberOfUchars: %lx\n", NumberOfUchars
);
256 INFO_(VIDEOPRT
, "- InIoSpace: %x\n", InIoSpace
);
258 InIoSpace
&= ~VIDEO_MEMORY_SPACE_DENSE
;
259 if ((InIoSpace
& VIDEO_MEMORY_SPACE_P6CACHE
) != 0)
261 INFO_(VIDEOPRT
, "VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
262 InIoSpace
&= ~VIDEO_MEMORY_SPACE_P6CACHE
;
265 if (ProcessHandle
!= NULL
&& (InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) == 0)
267 INFO_(VIDEOPRT
, "ProcessHandle is not NULL (0x%x) but InIoSpace does not have "
268 "VIDEO_MEMORY_SPACE_USER_MODE set! Setting "
269 "VIDEO_MEMORY_SPACE_USER_MODE.\n",
271 InIoSpace
|= VIDEO_MEMORY_SPACE_USER_MODE
;
273 else if (ProcessHandle
== NULL
&& (InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) != 0)
275 INFO_(VIDEOPRT
, "ProcessHandle is NULL (0x%x) but InIoSpace does have "
276 "VIDEO_MEMORY_SPACE_USER_MODE set! Setting ProcessHandle "
277 "to NtCurrentProcess()\n",
279 ProcessHandle
= NtCurrentProcess();
282 if ((InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) == 0 &&
283 !IsListEmpty(&DeviceExtension
->AddressMappingListHead
))
285 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
286 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
288 AddressMapping
= CONTAINING_RECORD(
290 VIDEO_PORT_ADDRESS_MAPPING
,
292 if (IoAddress
.QuadPart
== AddressMapping
->IoAddress
.QuadPart
&&
293 NumberOfUchars
<= AddressMapping
->NumberOfUchars
)
296 AddressMapping
->MappingCount
++;
299 return AddressMapping
->MappedAddress
;
302 Entry
= Entry
->Flink
;
306 AddressSpace
= (ULONG
)InIoSpace
;
307 AddressSpace
&= ~VIDEO_MEMORY_SPACE_USER_MODE
;
308 if (HalTranslateBusAddress(
309 DeviceExtension
->AdapterInterfaceType
,
310 DeviceExtension
->SystemIoBusNumber
,
313 &TranslatedAddress
) == FALSE
)
316 *Status
= ERROR_NOT_ENOUGH_MEMORY
;
322 if (AddressSpace
!= 0)
324 ASSERT(0 == TranslatedAddress
.u
.HighPart
);
328 return (PVOID
)(ULONG_PTR
)TranslatedAddress
.u
.LowPart
;
332 if ((InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) != 0)
335 MappedAddress
= NULL
;
336 NtStatus
= IntVideoPortMapPhysicalMemory(ProcessHandle
,
339 PAGE_READWRITE
/* | PAGE_WRITECOMBINE*/,
341 if (!NT_SUCCESS(NtStatus
))
343 WARN_(VIDEOPRT
, "IntVideoPortMapPhysicalMemory() failed! (0x%x)\n", NtStatus
);
348 INFO_(VIDEOPRT
, "Mapped user address = 0x%08x\n", MappedAddress
);
350 else /* kernel space */
352 MappedAddress
= MmMapIoSpace(
358 if (MappedAddress
!= NULL
)
364 if ((InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) == 0)
366 AddressMapping
= ExAllocatePoolWithTag(
368 sizeof(VIDEO_PORT_ADDRESS_MAPPING
),
371 if (AddressMapping
== NULL
)
372 return MappedAddress
;
374 RtlZeroMemory(AddressMapping
, sizeof(VIDEO_PORT_ADDRESS_MAPPING
));
375 AddressMapping
->NumberOfUchars
= NumberOfUchars
;
376 AddressMapping
->IoAddress
= IoAddress
;
377 AddressMapping
->SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
378 AddressMapping
->MappedAddress
= MappedAddress
;
379 AddressMapping
->MappingCount
= 1;
381 &DeviceExtension
->AddressMappingListHead
,
382 &AddressMapping
->List
);
385 return MappedAddress
;
395 IntVideoPortUnmapMemory(
396 IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
397 IN PVOID MappedAddress
)
399 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
403 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
404 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
406 AddressMapping
= CONTAINING_RECORD(
408 VIDEO_PORT_ADDRESS_MAPPING
,
410 if (AddressMapping
->MappedAddress
== MappedAddress
)
412 ASSERT(AddressMapping
->MappingCount
> 0);
413 AddressMapping
->MappingCount
--;
414 if (AddressMapping
->MappingCount
== 0)
417 AddressMapping
->MappedAddress
,
418 AddressMapping
->NumberOfUchars
);
419 RemoveEntryList(Entry
);
420 ExFreePool(AddressMapping
);
425 Entry
= Entry
->Flink
;
428 /* If there was no kernelmode mapping for the given address found we assume
429 * that the given address is a usermode mapping and try to unmap it.
431 * FIXME: Is it ok to use NtCurrentProcess?
433 Status
= ZwUnmapViewOfSection(NtCurrentProcess(), MappedAddress
);
434 if (!NT_SUCCESS(Status
))
436 WARN_(VIDEOPRT
, "Warning: Mapping for address 0x%p not found!\n", MappedAddress
);
440 /* PUBLIC FUNCTIONS ***********************************************************/
447 VideoPortGetDeviceBase(
448 IN PVOID HwDeviceExtension
,
449 IN PHYSICAL_ADDRESS IoAddress
,
450 IN ULONG NumberOfUchars
,
453 TRACE_(VIDEOPRT
, "VideoPortGetDeviceBase\n");
454 return IntVideoPortMapMemory(
455 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
),
468 VideoPortFreeDeviceBase(
469 IN PVOID HwDeviceExtension
,
470 IN PVOID MappedAddress
)
472 TRACE_(VIDEOPRT
, "VideoPortFreeDeviceBase\n");
473 IntVideoPortUnmapMemory(
474 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
),
483 VideoPortMapBankedMemory(
484 IN PVOID HwDeviceExtension
,
485 IN PHYSICAL_ADDRESS PhysicalAddress
,
488 OUT PVOID
*VirtualAddress
,
490 IN UCHAR ReadWriteBank
,
491 IN PBANKED_SECTION_ROUTINE BankRoutine
,
494 TRACE_(VIDEOPRT
, "VideoPortMapBankedMemory\n");
496 return ERROR_INVALID_FUNCTION
;
506 IN PVOID HwDeviceExtension
,
507 IN PHYSICAL_ADDRESS PhysicalAddress
,
510 OUT PVOID
*VirtualAddress
)
512 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
515 TRACE_(VIDEOPRT
, "VideoPortMapMemory\n");
516 INFO_(VIDEOPRT
, "- *VirtualAddress: 0x%x\n", *VirtualAddress
);
518 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
519 *VirtualAddress
= IntVideoPortMapMemory(
524 (HANDLE
)*VirtualAddress
,
535 VideoPortUnmapMemory(
536 IN PVOID HwDeviceExtension
,
537 IN PVOID VirtualAddress
,
538 IN HANDLE ProcessHandle
)
540 TRACE_(VIDEOPRT
, "VideoPortFreeDeviceBase\n");
542 IntVideoPortUnmapMemory(
543 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
),
554 VideoPortGetAccessRanges(
555 IN PVOID HwDeviceExtension
,
556 IN ULONG NumRequestedResources
,
557 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL
,
558 IN ULONG NumAccessRanges
,
559 IN PVIDEO_ACCESS_RANGE AccessRanges
,
564 PCI_SLOT_NUMBER PciSlotNumber
;
566 ULONG FunctionNumber
;
567 PCI_COMMON_CONFIG Config
;
568 PCM_RESOURCE_LIST AllocatedResources
;
570 UINT AssignedCount
= 0;
571 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
572 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
573 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
574 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
575 USHORT VendorIdToFind
;
576 USHORT DeviceIdToFind
;
577 ULONG ReturnedLength
;
578 PVIDEO_ACCESS_RANGE LegacyAccessRanges
;
579 ULONG LegacyAccessRangeCount
;
580 PDRIVER_OBJECT DriverObject
;
582 PIO_RESOURCE_REQUIREMENTS_LIST ResReqList
;
583 BOOLEAN DeviceAndVendorFound
= FALSE
;
585 TRACE_(VIDEOPRT
, "VideoPortGetAccessRanges(%d, %p, %d, %p)\n", NumRequestedResources
, RequestedResources
, NumAccessRanges
, AccessRanges
);
587 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
588 DriverObject
= DeviceExtension
->DriverObject
;
589 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
591 if (NumRequestedResources
== 0)
593 AllocatedResources
= DeviceExtension
->AllocatedResources
;
594 if (AllocatedResources
== NULL
&&
595 DeviceExtension
->AdapterInterfaceType
== PCIBus
)
597 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
599 PciSlotNumber
.u
.AsULONG
= DeviceExtension
->SystemIoSlotNumber
;
601 ReturnedLength
= HalGetBusData(PCIConfiguration
,
602 DeviceExtension
->SystemIoBusNumber
,
603 PciSlotNumber
.u
.AsULONG
,
605 sizeof(PCI_COMMON_CONFIG
));
607 if (ReturnedLength
!= sizeof(PCI_COMMON_CONFIG
))
609 return ERROR_NOT_ENOUGH_MEMORY
;
614 VendorIdToFind
= VendorId
!= NULL
? *(PUSHORT
)VendorId
: 0;
615 DeviceIdToFind
= DeviceId
!= NULL
? *(PUSHORT
)DeviceId
: 0;
617 if (VendorIdToFind
== 0 && DeviceIdToFind
== 0)
620 return ERROR_DEV_NOT_EXIST
;
623 INFO_(VIDEOPRT
, "Looking for VendorId 0x%04x DeviceId 0x%04x\n",
624 VendorIdToFind
, DeviceIdToFind
);
627 * Search for the device id and vendor id on this bus.
629 for (DeviceNumber
= 0; DeviceNumber
< PCI_MAX_DEVICES
; DeviceNumber
++)
631 PciSlotNumber
.u
.bits
.DeviceNumber
= DeviceNumber
;
632 for (FunctionNumber
= 0; FunctionNumber
< PCI_MAX_FUNCTION
; FunctionNumber
++)
634 INFO_(VIDEOPRT
, "- Function number: %d\n", FunctionNumber
);
635 PciSlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
636 ReturnedLength
= HalGetBusData(PCIConfiguration
,
637 DeviceExtension
->SystemIoBusNumber
,
638 PciSlotNumber
.u
.AsULONG
,
640 sizeof(PCI_COMMON_CONFIG
));
641 INFO_(VIDEOPRT
, "- Length of data: %x\n", ReturnedLength
);
642 if (ReturnedLength
== sizeof(PCI_COMMON_CONFIG
))
644 INFO_(VIDEOPRT
, "- Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
646 PciSlotNumber
.u
.AsULONG
,
647 PciSlotNumber
.u
.bits
.DeviceNumber
,
648 PciSlotNumber
.u
.bits
.FunctionNumber
,
652 if ((VendorIdToFind
== 0 || Config
.VendorID
== VendorIdToFind
) &&
653 (DeviceIdToFind
== 0 || Config
.DeviceID
== DeviceIdToFind
))
655 DeviceAndVendorFound
= TRUE
;
660 if (DeviceAndVendorFound
) break;
662 if (FunctionNumber
== PCI_MAX_FUNCTION
)
664 WARN_(VIDEOPRT
, "Didn't find device.\n");
665 return ERROR_DEV_NOT_EXIST
;
669 Status
= HalAssignSlotResources(&DeviceExtension
->RegistryPath
,
671 DeviceExtension
->DriverObject
,
672 DeviceExtension
->DriverObject
->DeviceObject
,
673 DeviceExtension
->AdapterInterfaceType
,
674 DeviceExtension
->SystemIoBusNumber
,
675 PciSlotNumber
.u
.AsULONG
,
676 &AllocatedResources
);
678 if (!NT_SUCCESS(Status
))
680 WARN_(VIDEOPRT
, "HalAssignSlotResources failed with status %x.\n",Status
);
683 DeviceExtension
->AllocatedResources
= AllocatedResources
;
684 DeviceExtension
->SystemIoSlotNumber
= PciSlotNumber
.u
.AsULONG
;
686 /* Add legacy resources to the resources from HAL */
687 Status
= IntVideoPortGetLegacyResources(DriverExtension
, DeviceExtension
,
688 &LegacyAccessRanges
, &LegacyAccessRangeCount
);
689 if (!NT_SUCCESS(Status
))
690 return ERROR_DEV_NOT_EXIST
;
692 if (NumAccessRanges
< LegacyAccessRangeCount
)
694 ERR_(VIDEOPRT
, "Too many legacy access ranges found\n");
695 return ERROR_NOT_ENOUGH_MEMORY
;
698 RtlCopyMemory(AccessRanges
, LegacyAccessRanges
, LegacyAccessRangeCount
* sizeof(VIDEO_ACCESS_RANGE
));
699 AssignedCount
= LegacyAccessRangeCount
;
704 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + (NumRequestedResources
- 1) * sizeof(IO_RESOURCE_DESCRIPTOR
);
705 ResReqList
= ExAllocatePool(NonPagedPool
, ListSize
);
706 if (!ResReqList
) return ERROR_NOT_ENOUGH_MEMORY
;
708 ResReqList
->ListSize
= ListSize
;
709 ResReqList
->InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
710 ResReqList
->BusNumber
= DeviceExtension
->SystemIoBusNumber
;
711 ResReqList
->SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
712 ResReqList
->AlternativeLists
= 1;
713 ResReqList
->List
[0].Version
= 1;
714 ResReqList
->List
[0].Revision
= 1;
715 ResReqList
->List
[0].Count
= NumRequestedResources
;
717 /* Copy in the caller's resource list */
718 RtlCopyMemory(ResReqList
->List
[0].Descriptors
,
720 NumRequestedResources
* sizeof(IO_RESOURCE_DESCRIPTOR
));
722 Status
= IoAssignResources(&DeviceExtension
->RegistryPath
,
724 DeviceExtension
->DriverObject
,
725 DeviceExtension
->PhysicalDeviceObject
?
726 DeviceExtension
->PhysicalDeviceObject
:
727 DeviceExtension
->DriverObject
->DeviceObject
,
729 &AllocatedResources
);
731 if (!NT_SUCCESS(Status
))
734 if (!DeviceExtension
->AllocatedResources
)
735 DeviceExtension
->AllocatedResources
= AllocatedResources
;
738 if (AllocatedResources
== NULL
)
739 return ERROR_NOT_ENOUGH_MEMORY
;
741 /* Return the slot number if the caller wants it */
742 if (Slot
!= NULL
) *Slot
= DeviceExtension
->SystemIoBusNumber
;
744 for (FullList
= AllocatedResources
->List
;
745 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
748 INFO_(VIDEOPRT
, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n",
749 FullList
->InterfaceType
, FullList
->BusNumber
, DeviceExtension
->SystemIoBusNumber
, FullList
->PartialResourceList
.Version
, FullList
->PartialResourceList
.Revision
);
751 ASSERT(FullList
->InterfaceType
== PCIBus
);
752 ASSERT(FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
);
753 ASSERT(1 == FullList
->PartialResourceList
.Version
);
754 ASSERT(1 == FullList
->PartialResourceList
.Revision
);
755 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
756 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
759 if ((Descriptor
->Type
== CmResourceTypeMemory
||
760 Descriptor
->Type
== CmResourceTypePort
) &&
761 AssignedCount
>= NumAccessRanges
)
763 ERR_(VIDEOPRT
, "Too many access ranges found\n");
764 return ERROR_NOT_ENOUGH_MEMORY
;
766 if (Descriptor
->Type
== CmResourceTypeMemory
)
768 INFO_(VIDEOPRT
, "Memory range starting at 0x%08x length 0x%08x\n",
769 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
770 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Memory
.Start
;
771 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Memory
.Length
;
772 AccessRanges
[AssignedCount
].RangeInIoSpace
= 0;
773 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
774 AccessRanges
[AssignedCount
].RangeShareable
=
775 (Descriptor
->ShareDisposition
== CmResourceShareShared
);
776 AccessRanges
[AssignedCount
].RangePassive
= 0;
779 else if (Descriptor
->Type
== CmResourceTypePort
)
781 INFO_(VIDEOPRT
, "Port range starting at 0x%04x length %d\n",
782 Descriptor
->u
.Port
.Start
.u
.LowPart
, Descriptor
->u
.Port
.Length
);
783 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Port
.Start
;
784 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Port
.Length
;
785 AccessRanges
[AssignedCount
].RangeInIoSpace
= 1;
786 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
787 AccessRanges
[AssignedCount
].RangeShareable
=
788 (Descriptor
->ShareDisposition
== CmResourceShareShared
);
789 AccessRanges
[AssignedCount
].RangePassive
= 0;
790 if (Descriptor
->Flags
& CM_RESOURCE_PORT_10_BIT_DECODE
)
791 AccessRanges
[AssignedCount
].RangePassive
|= VIDEO_RANGE_10_BIT_DECODE
;
792 if (Descriptor
->Flags
& CM_RESOURCE_PORT_PASSIVE_DECODE
)
793 AccessRanges
[AssignedCount
].RangePassive
|= VIDEO_RANGE_PASSIVE_DECODE
;
796 else if (Descriptor
->Type
== CmResourceTypeInterrupt
)
798 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
799 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
800 if (Descriptor
->ShareDisposition
== CmResourceShareShared
)
801 DeviceExtension
->InterruptShared
= TRUE
;
803 DeviceExtension
->InterruptShared
= FALSE
;
816 VideoPortVerifyAccessRanges(
817 IN PVOID HwDeviceExtension
,
818 IN ULONG NumAccessRanges
,
819 IN PVIDEO_ACCESS_RANGE AccessRanges
)
821 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
822 BOOLEAN ConflictDetected
;
824 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
825 PCM_RESOURCE_LIST ResourceList
;
826 ULONG ResourceListSize
;
829 TRACE_(VIDEOPRT
, "VideoPortVerifyAccessRanges\n");
831 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
833 /* Create the resource list */
834 ResourceListSize
= sizeof(CM_RESOURCE_LIST
)
835 + (NumAccessRanges
- 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
836 ResourceList
= ExAllocatePool(PagedPool
, ResourceListSize
);
839 WARN_(VIDEOPRT
, "ExAllocatePool() failed\n");
840 return ERROR_INVALID_PARAMETER
;
843 /* Fill resource list */
844 ResourceList
->Count
= 1;
845 ResourceList
->List
[0].InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
846 ResourceList
->List
[0].BusNumber
= DeviceExtension
->SystemIoBusNumber
;
847 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
848 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
849 ResourceList
->List
[0].PartialResourceList
.Count
= NumAccessRanges
;
850 for (i
= 0; i
< NumAccessRanges
; i
++, AccessRanges
++)
852 PartialDescriptor
= &ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
853 if (AccessRanges
->RangeInIoSpace
)
855 PartialDescriptor
->Type
= CmResourceTypePort
;
856 PartialDescriptor
->u
.Port
.Start
= AccessRanges
->RangeStart
;
857 PartialDescriptor
->u
.Port
.Length
= AccessRanges
->RangeLength
;
861 PartialDescriptor
->Type
= CmResourceTypeMemory
;
862 PartialDescriptor
->u
.Memory
.Start
= AccessRanges
->RangeStart
;
863 PartialDescriptor
->u
.Memory
.Length
= AccessRanges
->RangeLength
;
865 if (AccessRanges
->RangeShareable
)
866 PartialDescriptor
->ShareDisposition
= CmResourceShareShared
;
868 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
869 PartialDescriptor
->Flags
= 0;
870 if (AccessRanges
->RangePassive
& VIDEO_RANGE_PASSIVE_DECODE
)
871 PartialDescriptor
->Flags
|= CM_RESOURCE_PORT_PASSIVE_DECODE
;
872 if (AccessRanges
->RangePassive
& VIDEO_RANGE_10_BIT_DECODE
)
873 PartialDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
876 /* Try to acquire all resource ranges */
877 Status
= IoReportResourceForDetection(
878 DeviceExtension
->DriverObject
,
879 NULL
, 0, /* Driver List */
880 DeviceExtension
->PhysicalDeviceObject
,
881 ResourceList
, ResourceListSize
,
883 ExFreePool(ResourceList
);
885 if (!NT_SUCCESS(Status
) || ConflictDetected
)
886 return ERROR_INVALID_PARAMETER
;
896 VideoPortGetDeviceData(
897 IN PVOID HwDeviceExtension
,
898 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType
,
899 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine
,
902 TRACE_(VIDEOPRT
, "VideoPortGetDeviceData\n");
904 return ERROR_INVALID_FUNCTION
;
912 VideoPortAllocatePool(
913 IN PVOID HwDeviceExtension
,
914 IN VP_POOL_TYPE PoolType
,
915 IN SIZE_T NumberOfBytes
,
918 TRACE_(VIDEOPRT
, "VideoPortAllocatePool\n");
919 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
928 IN PVOID HwDeviceExtension
,
939 VideoPortAllocateBuffer(
940 IN PVOID HwDeviceExtension
,
944 TRACE_(VIDEOPRT
, "VideoPortAllocateBuffer\n");
945 *Buffer
= ExAllocatePoolWithTag ( PagedPool
, Size
, TAG_VIDEO_PORT_BUFFER
) ;
946 return *Buffer
== NULL
? ERROR_NOT_ENOUGH_MEMORY
: NO_ERROR
;
954 VideoPortReleaseBuffer(
955 IN PVOID HwDeviceExtension
,
958 TRACE_(VIDEOPRT
, "VideoPortReleaseBuffer\n");
968 IN PVOID HwDeviceExtension
,
969 IN PVOID BaseAddress
,
971 IN VP_LOCK_OPERATION Operation
)
975 Mdl
= IoAllocateMdl(BaseAddress
, Length
, FALSE
, FALSE
, NULL
);
981 MmProbeAndLockPages(Mdl
, KernelMode
,Operation
);
992 IN PVOID HwDeviceExtension
,
993 IN OUT PVIDEO_REQUEST_PACKET pVrp
,
995 IN PEVENT pDisplayEvent
,
996 IN DMA_FLAGS DmaFlags
)
1000 /* clear output buffer */
1001 pVrp
->OutputBuffer
= NULL
;
1003 if (DmaFlags
!= VideoPortDmaInitOnly
)
1005 /* VideoPortKeepPagesLocked / VideoPortUnlockAfterDma is no-op */
1009 /* lock the buffer */
1010 Buffer
= VideoPortLockBuffer(HwDeviceExtension
, pVrp
->InputBuffer
, pVrp
->InputBufferLength
, IoModifyAccess
);
1014 /* store result buffer & length */
1015 pVrp
->OutputBuffer
= Buffer
;
1016 pVrp
->OutputBufferLength
= pVrp
->InputBufferLength
;
1018 /* operation succeeded */
1022 /* operation failed */
1032 VideoPortUnlockBuffer(
1033 IN PVOID HwDeviceExtension
,
1038 MmUnlockPages((PMDL
)Mdl
);
1048 VideoPortSetTrappedEmulatorPorts(
1049 IN PVOID HwDeviceExtension
,
1050 IN ULONG NumAccessRanges
,
1051 IN PVIDEO_ACCESS_RANGE AccessRange
)
1054 /* Should store the ranges in the device extension for use by ntvdm. */
1063 VideoPortGetBusData(
1064 IN PVOID HwDeviceExtension
,
1065 IN BUS_DATA_TYPE BusDataType
,
1066 IN ULONG SlotNumber
,
1071 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1073 TRACE_(VIDEOPRT
, "VideoPortGetBusData\n");
1075 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1077 if (BusDataType
!= Cmos
)
1079 /* Legacy vs. PnP behaviour */
1080 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
1081 SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
1084 return HalGetBusDataByOffset(
1086 DeviceExtension
->SystemIoBusNumber
,
1098 VideoPortSetBusData(
1099 IN PVOID HwDeviceExtension
,
1100 IN BUS_DATA_TYPE BusDataType
,
1101 IN ULONG SlotNumber
,
1106 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1108 TRACE_(VIDEOPRT
, "VideoPortSetBusData\n");
1110 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1112 if (BusDataType
!= Cmos
)
1114 /* Legacy vs. PnP behaviour */
1115 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
1116 SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
1119 return HalSetBusDataByOffset(
1121 DeviceExtension
->SystemIoBusNumber
,