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
27 /* PRIVATE FUNCTIONS **********************************************************/
30 IntVideoPortGetLegacyResources(
31 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
,
32 IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
33 OUT PVIDEO_ACCESS_RANGE
*AccessRanges
,
34 OUT PULONG AccessRangeCount
)
36 PCI_COMMON_CONFIG PciConfig
;
39 if (!DriverExtension
->InitializationData
.HwGetLegacyResources
&&
40 !DriverExtension
->InitializationData
.HwLegacyResourceCount
)
42 /* No legacy resources to report */
43 *AccessRangeCount
= 0;
44 return STATUS_SUCCESS
;
47 if (DriverExtension
->InitializationData
.HwGetLegacyResources
)
49 ReadLength
= HalGetBusData(PCIConfiguration
,
50 DeviceExtension
->SystemIoBusNumber
,
51 DeviceExtension
->SystemIoSlotNumber
,
54 if (ReadLength
!= sizeof(PciConfig
))
56 /* This device doesn't exist */
57 return STATUS_NO_SUCH_DEVICE
;
60 DriverExtension
->InitializationData
.HwGetLegacyResources(PciConfig
.VendorID
,
67 *AccessRanges
= DriverExtension
->InitializationData
.HwLegacyResourceList
;
68 *AccessRangeCount
= DriverExtension
->InitializationData
.HwLegacyResourceCount
;
71 INFO_(VIDEOPRT
, "Got %d legacy access ranges\n", *AccessRangeCount
);
73 return STATUS_SUCCESS
;
77 IntVideoPortFilterResourceRequirements(
78 IN PDEVICE_OBJECT DeviceObject
,
81 PDRIVER_OBJECT DriverObject
;
82 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
83 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
84 PVIDEO_ACCESS_RANGE AccessRanges
;
85 ULONG AccessRangeCount
, ListSize
, i
;
86 PIO_RESOURCE_REQUIREMENTS_LIST ResList
, OldResList
= (PVOID
)Irp
->IoStatus
.Information
;
87 PIO_RESOURCE_DESCRIPTOR CurrentDescriptor
;
90 DriverObject
= DeviceObject
->DriverObject
;
91 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
92 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
94 Status
= IntVideoPortGetLegacyResources(DriverExtension
, DeviceExtension
, &AccessRanges
, &AccessRangeCount
);
95 if (!NT_SUCCESS(Status
))
97 if (!AccessRangeCount
)
99 /* No legacy resources to report */
100 return Irp
->IoStatus
.Information
;
103 /* OK, we've got the access ranges now. Let's set up the resource requirements list */
107 /* Already one there so let's add to it */
108 ListSize
= OldResList
->ListSize
+ sizeof(IO_RESOURCE_DESCRIPTOR
) * AccessRangeCount
;
109 ResList
= ExAllocatePool(NonPagedPool
,
111 if (!ResList
) return STATUS_NO_MEMORY
;
113 RtlCopyMemory(ResList
, OldResList
, OldResList
->ListSize
);
115 ASSERT(ResList
->AlternativeLists
== 1);
117 ResList
->ListSize
= ListSize
;
118 ResList
->List
[0].Count
+= AccessRangeCount
;
120 CurrentDescriptor
= (PIO_RESOURCE_DESCRIPTOR
)((PUCHAR
)ResList
+ OldResList
->ListSize
);
122 ExFreePool(OldResList
);
123 Irp
->IoStatus
.Information
= 0;
127 /* We need to make a new one */
128 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + sizeof(IO_RESOURCE_DESCRIPTOR
) * (AccessRangeCount
- 1);
129 ResList
= ExAllocatePool(NonPagedPool
,
131 if (!ResList
) return STATUS_NO_MEMORY
;
133 RtlZeroMemory(ResList
, ListSize
);
135 /* We need to initialize some fields */
136 ResList
->ListSize
= ListSize
;
137 ResList
->InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
138 ResList
->BusNumber
= DeviceExtension
->SystemIoBusNumber
;
139 ResList
->SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
140 ResList
->AlternativeLists
= 1;
141 ResList
->List
[0].Version
= 1;
142 ResList
->List
[0].Revision
= 1;
143 ResList
->List
[0].Count
= AccessRangeCount
;
145 CurrentDescriptor
= ResList
->List
[0].Descriptors
;
148 for (i
= 0; i
< AccessRangeCount
; i
++)
150 /* This is a required resource */
151 CurrentDescriptor
->Option
= 0;
153 if (AccessRanges
[i
].RangeInIoSpace
)
154 CurrentDescriptor
->Type
= CmResourceTypePort
;
156 CurrentDescriptor
->Type
= CmResourceTypeMemory
;
158 CurrentDescriptor
->ShareDisposition
=
159 (AccessRanges
[i
].RangeShareable
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
161 CurrentDescriptor
->Flags
= 0;
163 if (CurrentDescriptor
->Type
== CmResourceTypePort
)
165 CurrentDescriptor
->u
.Port
.Length
= AccessRanges
[i
].RangeLength
;
166 CurrentDescriptor
->u
.Port
.MinimumAddress
=
167 CurrentDescriptor
->u
.Port
.MaximumAddress
= AccessRanges
[i
].RangeStart
;
168 CurrentDescriptor
->u
.Port
.Alignment
= 1;
169 if (AccessRanges
[i
].RangePassive
& VIDEO_RANGE_PASSIVE_DECODE
)
170 CurrentDescriptor
->Flags
|= CM_RESOURCE_PORT_PASSIVE_DECODE
;
171 if (AccessRanges
[i
].RangePassive
& VIDEO_RANGE_10_BIT_DECODE
)
172 CurrentDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
176 CurrentDescriptor
->u
.Memory
.Length
= AccessRanges
[i
].RangeLength
;
177 CurrentDescriptor
->u
.Memory
.MinimumAddress
=
178 CurrentDescriptor
->u
.Memory
.MaximumAddress
= AccessRanges
[i
].RangeStart
;
179 CurrentDescriptor
->u
.Memory
.Alignment
= 1;
180 CurrentDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
186 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResList
;
188 return STATUS_SUCCESS
;
192 IntVideoPortMapPhysicalMemory(
194 IN PHYSICAL_ADDRESS PhysicalAddress
,
195 IN ULONG SizeInBytes
,
197 IN OUT PVOID
*VirtualAddress OPTIONAL
)
199 OBJECT_ATTRIBUTES ObjAttribs
;
200 UNICODE_STRING UnicodeString
;
205 /* Initialize object attribs */
206 RtlInitUnicodeString(&UnicodeString
, L
"\\Device\\PhysicalMemory");
207 InitializeObjectAttributes(&ObjAttribs
,
209 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
212 /* Open physical memory section */
213 Status
= ZwOpenSection(&hMemObj
, SECTION_ALL_ACCESS
, &ObjAttribs
);
214 if (!NT_SUCCESS(Status
))
216 WARN_(VIDEOPRT
, "ZwOpenSection() failed! (0x%x)\n", Status
);
220 /* Map view of section */
222 Status
= ZwMapViewOfSection(hMemObj
,
227 (PLARGE_INTEGER
)(&PhysicalAddress
),
233 if (!NT_SUCCESS(Status
))
235 WARN_(VIDEOPRT
, "ZwMapViewOfSection() failed! (0x%x)\n", Status
);
243 IntVideoPortMapMemory(
244 IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
245 IN PHYSICAL_ADDRESS IoAddress
,
246 IN ULONG NumberOfUchars
,
248 IN HANDLE ProcessHandle
,
249 OUT VP_STATUS
*Status
)
251 PHYSICAL_ADDRESS TranslatedAddress
;
252 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
257 INFO_(VIDEOPRT
, "- IoAddress: %lx\n", IoAddress
.u
.LowPart
);
258 INFO_(VIDEOPRT
, "- NumberOfUchars: %lx\n", NumberOfUchars
);
259 INFO_(VIDEOPRT
, "- InIoSpace: %x\n", InIoSpace
);
261 InIoSpace
&= ~VIDEO_MEMORY_SPACE_DENSE
;
262 if ((InIoSpace
& VIDEO_MEMORY_SPACE_P6CACHE
) != 0)
264 INFO_(VIDEOPRT
, "VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
265 InIoSpace
&= ~VIDEO_MEMORY_SPACE_P6CACHE
;
268 if (ProcessHandle
!= NULL
&& (InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) == 0)
270 INFO_(VIDEOPRT
, "ProcessHandle is not NULL (0x%x) but InIoSpace does not have "
271 "VIDEO_MEMORY_SPACE_USER_MODE set! Setting "
272 "VIDEO_MEMORY_SPACE_USER_MODE.\n",
274 InIoSpace
|= VIDEO_MEMORY_SPACE_USER_MODE
;
276 else if (ProcessHandle
== NULL
&& (InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) != 0)
278 INFO_(VIDEOPRT
, "ProcessHandle is NULL (0x%x) but InIoSpace does have "
279 "VIDEO_MEMORY_SPACE_USER_MODE set! Setting ProcessHandle "
280 "to NtCurrentProcess()\n",
282 ProcessHandle
= NtCurrentProcess();
285 if ((InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) == 0 &&
286 !IsListEmpty(&DeviceExtension
->AddressMappingListHead
))
288 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
289 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
291 AddressMapping
= CONTAINING_RECORD(
293 VIDEO_PORT_ADDRESS_MAPPING
,
295 if (IoAddress
.QuadPart
== AddressMapping
->IoAddress
.QuadPart
&&
296 NumberOfUchars
<= AddressMapping
->NumberOfUchars
)
299 AddressMapping
->MappingCount
++;
302 return AddressMapping
->MappedAddress
;
305 Entry
= Entry
->Flink
;
309 AddressSpace
= (ULONG
)InIoSpace
;
310 AddressSpace
&= ~VIDEO_MEMORY_SPACE_USER_MODE
;
311 if (HalTranslateBusAddress(
312 DeviceExtension
->AdapterInterfaceType
,
313 DeviceExtension
->SystemIoBusNumber
,
316 &TranslatedAddress
) == FALSE
)
319 *Status
= ERROR_NOT_ENOUGH_MEMORY
;
325 if (AddressSpace
!= 0)
327 ASSERT(0 == TranslatedAddress
.u
.HighPart
);
331 return (PVOID
)(ULONG_PTR
)TranslatedAddress
.u
.LowPart
;
335 if ((InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) != 0)
338 MappedAddress
= NULL
;
339 NtStatus
= IntVideoPortMapPhysicalMemory(ProcessHandle
,
342 PAGE_READWRITE
/* | PAGE_WRITECOMBINE*/,
344 if (!NT_SUCCESS(NtStatus
))
346 WARN_(VIDEOPRT
, "IntVideoPortMapPhysicalMemory() failed! (0x%x)\n", NtStatus
);
351 INFO_(VIDEOPRT
, "Mapped user address = 0x%08x\n", MappedAddress
);
353 else /* kernel space */
355 MappedAddress
= MmMapIoSpace(
361 if (MappedAddress
!= NULL
)
367 if ((InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) == 0)
369 AddressMapping
= ExAllocatePoolWithTag(
371 sizeof(VIDEO_PORT_ADDRESS_MAPPING
),
374 if (AddressMapping
== NULL
)
375 return MappedAddress
;
377 RtlZeroMemory(AddressMapping
, sizeof(VIDEO_PORT_ADDRESS_MAPPING
));
378 AddressMapping
->NumberOfUchars
= NumberOfUchars
;
379 AddressMapping
->IoAddress
= IoAddress
;
380 AddressMapping
->SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
381 AddressMapping
->MappedAddress
= MappedAddress
;
382 AddressMapping
->MappingCount
= 1;
384 &DeviceExtension
->AddressMappingListHead
,
385 &AddressMapping
->List
);
388 return MappedAddress
;
398 IntVideoPortUnmapMemory(
399 IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
400 IN PVOID MappedAddress
)
402 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
406 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
407 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
409 AddressMapping
= CONTAINING_RECORD(
411 VIDEO_PORT_ADDRESS_MAPPING
,
413 if (AddressMapping
->MappedAddress
== MappedAddress
)
415 ASSERT(AddressMapping
->MappingCount
> 0);
416 AddressMapping
->MappingCount
--;
417 if (AddressMapping
->MappingCount
== 0)
420 AddressMapping
->MappedAddress
,
421 AddressMapping
->NumberOfUchars
);
422 RemoveEntryList(Entry
);
423 ExFreePool(AddressMapping
);
428 Entry
= Entry
->Flink
;
431 /* If there was no kernelmode mapping for the given address found we assume
432 * that the given address is a usermode mapping and try to unmap it.
434 * FIXME: Is it ok to use NtCurrentProcess?
436 Status
= ZwUnmapViewOfSection(NtCurrentProcess(), MappedAddress
);
437 if (!NT_SUCCESS(Status
))
439 WARN_(VIDEOPRT
, "Warning: Mapping for address 0x%p not found!\n", MappedAddress
);
443 /* PUBLIC FUNCTIONS ***********************************************************/
450 VideoPortGetDeviceBase(
451 IN PVOID HwDeviceExtension
,
452 IN PHYSICAL_ADDRESS IoAddress
,
453 IN ULONG NumberOfUchars
,
456 TRACE_(VIDEOPRT
, "VideoPortGetDeviceBase\n");
457 return IntVideoPortMapMemory(
458 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
),
471 VideoPortFreeDeviceBase(
472 IN PVOID HwDeviceExtension
,
473 IN PVOID MappedAddress
)
475 TRACE_(VIDEOPRT
, "VideoPortFreeDeviceBase\n");
476 IntVideoPortUnmapMemory(
477 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
),
486 VideoPortMapBankedMemory(
487 IN PVOID HwDeviceExtension
,
488 IN PHYSICAL_ADDRESS PhysicalAddress
,
491 OUT PVOID
*VirtualAddress
,
493 IN UCHAR ReadWriteBank
,
494 IN PBANKED_SECTION_ROUTINE BankRoutine
,
497 TRACE_(VIDEOPRT
, "VideoPortMapBankedMemory\n");
499 return ERROR_INVALID_FUNCTION
;
509 IN PVOID HwDeviceExtension
,
510 IN PHYSICAL_ADDRESS PhysicalAddress
,
513 OUT PVOID
*VirtualAddress
)
515 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
518 TRACE_(VIDEOPRT
, "VideoPortMapMemory\n");
519 INFO_(VIDEOPRT
, "- *VirtualAddress: 0x%x\n", *VirtualAddress
);
521 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
522 *VirtualAddress
= IntVideoPortMapMemory(
527 (HANDLE
)*VirtualAddress
,
538 VideoPortUnmapMemory(
539 IN PVOID HwDeviceExtension
,
540 IN PVOID VirtualAddress
,
541 IN HANDLE ProcessHandle
)
543 TRACE_(VIDEOPRT
, "VideoPortFreeDeviceBase\n");
545 IntVideoPortUnmapMemory(
546 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
),
557 VideoPortGetAccessRanges(
558 IN PVOID HwDeviceExtension
,
559 IN ULONG NumRequestedResources
,
560 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL
,
561 IN ULONG NumAccessRanges
,
562 IN PVIDEO_ACCESS_RANGE AccessRanges
,
567 PCI_SLOT_NUMBER PciSlotNumber
;
569 ULONG FunctionNumber
;
570 PCI_COMMON_CONFIG Config
;
571 PCM_RESOURCE_LIST AllocatedResources
;
573 UINT AssignedCount
= 0;
574 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
575 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
576 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
577 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
578 USHORT VendorIdToFind
;
579 USHORT DeviceIdToFind
;
580 ULONG ReturnedLength
;
581 PVIDEO_ACCESS_RANGE LegacyAccessRanges
;
582 ULONG LegacyAccessRangeCount
;
583 PDRIVER_OBJECT DriverObject
;
585 PIO_RESOURCE_REQUIREMENTS_LIST ResReqList
;
586 BOOLEAN DeviceAndVendorFound
= FALSE
;
588 TRACE_(VIDEOPRT
, "VideoPortGetAccessRanges(%d, %p, %d, %p)\n", NumRequestedResources
, RequestedResources
, NumAccessRanges
, AccessRanges
);
590 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
591 DriverObject
= DeviceExtension
->DriverObject
;
592 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
594 if (NumRequestedResources
== 0)
596 AllocatedResources
= DeviceExtension
->AllocatedResources
;
597 if (AllocatedResources
== NULL
&&
598 DeviceExtension
->AdapterInterfaceType
== PCIBus
)
600 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
602 PciSlotNumber
.u
.AsULONG
= DeviceExtension
->SystemIoSlotNumber
;
604 ReturnedLength
= HalGetBusData(PCIConfiguration
,
605 DeviceExtension
->SystemIoBusNumber
,
606 PciSlotNumber
.u
.AsULONG
,
608 sizeof(PCI_COMMON_CONFIG
));
610 if (ReturnedLength
!= sizeof(PCI_COMMON_CONFIG
))
612 return ERROR_NOT_ENOUGH_MEMORY
;
617 VendorIdToFind
= VendorId
!= NULL
? *(PUSHORT
)VendorId
: 0;
618 DeviceIdToFind
= DeviceId
!= NULL
? *(PUSHORT
)DeviceId
: 0;
620 if (VendorIdToFind
== 0 && DeviceIdToFind
== 0)
623 return ERROR_DEV_NOT_EXIST
;
626 INFO_(VIDEOPRT
, "Looking for VendorId 0x%04x DeviceId 0x%04x\n",
627 VendorIdToFind
, DeviceIdToFind
);
630 * Search for the device id and vendor id on this bus.
632 for (DeviceNumber
= 0; DeviceNumber
< PCI_MAX_DEVICES
; DeviceNumber
++)
634 PciSlotNumber
.u
.bits
.DeviceNumber
= DeviceNumber
;
635 for (FunctionNumber
= 0; FunctionNumber
< PCI_MAX_FUNCTION
; FunctionNumber
++)
637 INFO_(VIDEOPRT
, "- Function number: %d\n", FunctionNumber
);
638 PciSlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
639 ReturnedLength
= HalGetBusData(PCIConfiguration
,
640 DeviceExtension
->SystemIoBusNumber
,
641 PciSlotNumber
.u
.AsULONG
,
643 sizeof(PCI_COMMON_CONFIG
));
644 INFO_(VIDEOPRT
, "- Length of data: %x\n", ReturnedLength
);
645 if (ReturnedLength
== sizeof(PCI_COMMON_CONFIG
))
647 INFO_(VIDEOPRT
, "- Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
649 PciSlotNumber
.u
.AsULONG
,
650 PciSlotNumber
.u
.bits
.DeviceNumber
,
651 PciSlotNumber
.u
.bits
.FunctionNumber
,
655 if ((VendorIdToFind
== 0 || Config
.VendorID
== VendorIdToFind
) &&
656 (DeviceIdToFind
== 0 || Config
.DeviceID
== DeviceIdToFind
))
658 DeviceAndVendorFound
= TRUE
;
663 if (DeviceAndVendorFound
) break;
665 if (FunctionNumber
== PCI_MAX_FUNCTION
)
667 WARN_(VIDEOPRT
, "Didn't find device.\n");
668 return ERROR_DEV_NOT_EXIST
;
672 Status
= HalAssignSlotResources(&DeviceExtension
->RegistryPath
,
674 DeviceExtension
->DriverObject
,
675 DeviceExtension
->DriverObject
->DeviceObject
,
676 DeviceExtension
->AdapterInterfaceType
,
677 DeviceExtension
->SystemIoBusNumber
,
678 PciSlotNumber
.u
.AsULONG
,
679 &AllocatedResources
);
681 if (!NT_SUCCESS(Status
))
683 WARN_(VIDEOPRT
, "HalAssignSlotResources failed with status %x.\n",Status
);
686 DeviceExtension
->AllocatedResources
= AllocatedResources
;
687 DeviceExtension
->SystemIoSlotNumber
= PciSlotNumber
.u
.AsULONG
;
689 /* Add legacy resources to the resources from HAL */
690 Status
= IntVideoPortGetLegacyResources(DriverExtension
, DeviceExtension
,
691 &LegacyAccessRanges
, &LegacyAccessRangeCount
);
692 if (!NT_SUCCESS(Status
))
693 return ERROR_DEV_NOT_EXIST
;
695 if (NumAccessRanges
< LegacyAccessRangeCount
)
697 ERR_(VIDEOPRT
, "Too many legacy access ranges found\n");
698 return ERROR_NOT_ENOUGH_MEMORY
;
701 RtlCopyMemory(AccessRanges
, LegacyAccessRanges
, LegacyAccessRangeCount
* sizeof(VIDEO_ACCESS_RANGE
));
702 AssignedCount
= LegacyAccessRangeCount
;
707 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + (NumRequestedResources
- 1) * sizeof(IO_RESOURCE_DESCRIPTOR
);
708 ResReqList
= ExAllocatePool(NonPagedPool
, ListSize
);
709 if (!ResReqList
) return ERROR_NOT_ENOUGH_MEMORY
;
711 ResReqList
->ListSize
= ListSize
;
712 ResReqList
->InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
713 ResReqList
->BusNumber
= DeviceExtension
->SystemIoBusNumber
;
714 ResReqList
->SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
715 ResReqList
->AlternativeLists
= 1;
716 ResReqList
->List
[0].Version
= 1;
717 ResReqList
->List
[0].Revision
= 1;
718 ResReqList
->List
[0].Count
= NumRequestedResources
;
720 /* Copy in the caller's resource list */
721 RtlCopyMemory(ResReqList
->List
[0].Descriptors
,
723 NumRequestedResources
* sizeof(IO_RESOURCE_DESCRIPTOR
));
725 Status
= IoAssignResources(&DeviceExtension
->RegistryPath
,
727 DeviceExtension
->DriverObject
,
728 DeviceExtension
->PhysicalDeviceObject
?
729 DeviceExtension
->PhysicalDeviceObject
:
730 DeviceExtension
->DriverObject
->DeviceObject
,
732 &AllocatedResources
);
734 if (!NT_SUCCESS(Status
))
737 if (!DeviceExtension
->AllocatedResources
)
738 DeviceExtension
->AllocatedResources
= AllocatedResources
;
741 if (AllocatedResources
== NULL
)
742 return ERROR_NOT_ENOUGH_MEMORY
;
744 /* Return the slot number if the caller wants it */
745 if (Slot
!= NULL
) *Slot
= DeviceExtension
->SystemIoBusNumber
;
747 for (FullList
= AllocatedResources
->List
;
748 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
751 INFO_(VIDEOPRT
, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n",
752 FullList
->InterfaceType
, FullList
->BusNumber
, DeviceExtension
->SystemIoBusNumber
, FullList
->PartialResourceList
.Version
, FullList
->PartialResourceList
.Revision
);
754 ASSERT(FullList
->InterfaceType
== PCIBus
);
755 ASSERT(FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
);
756 ASSERT(1 == FullList
->PartialResourceList
.Version
);
757 ASSERT(1 == FullList
->PartialResourceList
.Revision
);
758 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
759 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
762 if ((Descriptor
->Type
== CmResourceTypeMemory
||
763 Descriptor
->Type
== CmResourceTypePort
) &&
764 AssignedCount
>= NumAccessRanges
)
766 ERR_(VIDEOPRT
, "Too many access ranges found\n");
767 return ERROR_NOT_ENOUGH_MEMORY
;
769 if (Descriptor
->Type
== CmResourceTypeMemory
)
771 INFO_(VIDEOPRT
, "Memory range starting at 0x%08x length 0x%08x\n",
772 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
773 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Memory
.Start
;
774 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Memory
.Length
;
775 AccessRanges
[AssignedCount
].RangeInIoSpace
= 0;
776 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
777 AccessRanges
[AssignedCount
].RangeShareable
=
778 (Descriptor
->ShareDisposition
== CmResourceShareShared
);
779 AccessRanges
[AssignedCount
].RangePassive
= 0;
782 else if (Descriptor
->Type
== CmResourceTypePort
)
784 INFO_(VIDEOPRT
, "Port range starting at 0x%04x length %d\n",
785 Descriptor
->u
.Port
.Start
.u
.LowPart
, Descriptor
->u
.Port
.Length
);
786 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Port
.Start
;
787 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Port
.Length
;
788 AccessRanges
[AssignedCount
].RangeInIoSpace
= 1;
789 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
790 AccessRanges
[AssignedCount
].RangeShareable
=
791 (Descriptor
->ShareDisposition
== CmResourceShareShared
);
792 AccessRanges
[AssignedCount
].RangePassive
= 0;
793 if (Descriptor
->Flags
& CM_RESOURCE_PORT_10_BIT_DECODE
)
794 AccessRanges
[AssignedCount
].RangePassive
|= VIDEO_RANGE_10_BIT_DECODE
;
795 if (Descriptor
->Flags
& CM_RESOURCE_PORT_PASSIVE_DECODE
)
796 AccessRanges
[AssignedCount
].RangePassive
|= VIDEO_RANGE_PASSIVE_DECODE
;
799 else if (Descriptor
->Type
== CmResourceTypeInterrupt
)
801 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
802 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
803 if (Descriptor
->ShareDisposition
== CmResourceShareShared
)
804 DeviceExtension
->InterruptShared
= TRUE
;
806 DeviceExtension
->InterruptShared
= FALSE
;
819 VideoPortVerifyAccessRanges(
820 IN PVOID HwDeviceExtension
,
821 IN ULONG NumAccessRanges
,
822 IN PVIDEO_ACCESS_RANGE AccessRanges
)
824 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
825 BOOLEAN ConflictDetected
;
827 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
828 PCM_RESOURCE_LIST ResourceList
;
829 ULONG ResourceListSize
;
832 TRACE_(VIDEOPRT
, "VideoPortVerifyAccessRanges\n");
834 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
836 /* Create the resource list */
837 ResourceListSize
= sizeof(CM_RESOURCE_LIST
)
838 + (NumAccessRanges
- 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
839 ResourceList
= ExAllocatePool(PagedPool
, ResourceListSize
);
842 WARN_(VIDEOPRT
, "ExAllocatePool() failed\n");
843 return ERROR_INVALID_PARAMETER
;
846 /* Fill resource list */
847 ResourceList
->Count
= 1;
848 ResourceList
->List
[0].InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
849 ResourceList
->List
[0].BusNumber
= DeviceExtension
->SystemIoBusNumber
;
850 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
851 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
852 ResourceList
->List
[0].PartialResourceList
.Count
= NumAccessRanges
;
853 for (i
= 0; i
< NumAccessRanges
; i
++, AccessRanges
++)
855 PartialDescriptor
= &ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
856 if (AccessRanges
->RangeInIoSpace
)
858 PartialDescriptor
->Type
= CmResourceTypePort
;
859 PartialDescriptor
->u
.Port
.Start
= AccessRanges
->RangeStart
;
860 PartialDescriptor
->u
.Port
.Length
= AccessRanges
->RangeLength
;
864 PartialDescriptor
->Type
= CmResourceTypeMemory
;
865 PartialDescriptor
->u
.Memory
.Start
= AccessRanges
->RangeStart
;
866 PartialDescriptor
->u
.Memory
.Length
= AccessRanges
->RangeLength
;
868 if (AccessRanges
->RangeShareable
)
869 PartialDescriptor
->ShareDisposition
= CmResourceShareShared
;
871 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
872 PartialDescriptor
->Flags
= 0;
873 if (AccessRanges
->RangePassive
& VIDEO_RANGE_PASSIVE_DECODE
)
874 PartialDescriptor
->Flags
|= CM_RESOURCE_PORT_PASSIVE_DECODE
;
875 if (AccessRanges
->RangePassive
& VIDEO_RANGE_10_BIT_DECODE
)
876 PartialDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
879 /* Try to acquire all resource ranges */
880 Status
= IoReportResourceForDetection(
881 DeviceExtension
->DriverObject
,
882 NULL
, 0, /* Driver List */
883 DeviceExtension
->PhysicalDeviceObject
,
884 ResourceList
, ResourceListSize
,
886 ExFreePool(ResourceList
);
888 if (!NT_SUCCESS(Status
) || ConflictDetected
)
889 return ERROR_INVALID_PARAMETER
;
899 VideoPortGetDeviceData(
900 IN PVOID HwDeviceExtension
,
901 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType
,
902 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine
,
905 TRACE_(VIDEOPRT
, "VideoPortGetDeviceData\n");
907 return ERROR_INVALID_FUNCTION
;
915 VideoPortAllocatePool(
916 IN PVOID HwDeviceExtension
,
917 IN VP_POOL_TYPE PoolType
,
918 IN SIZE_T NumberOfBytes
,
921 TRACE_(VIDEOPRT
, "VideoPortAllocatePool\n");
922 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
931 IN PVOID HwDeviceExtension
,
942 VideoPortAllocateBuffer(
943 IN PVOID HwDeviceExtension
,
947 TRACE_(VIDEOPRT
, "VideoPortAllocateBuffer\n");
948 *Buffer
= ExAllocatePoolWithTag ( PagedPool
, Size
, TAG_VIDEO_PORT_BUFFER
) ;
949 return *Buffer
== NULL
? ERROR_NOT_ENOUGH_MEMORY
: NO_ERROR
;
957 VideoPortReleaseBuffer(
958 IN PVOID HwDeviceExtension
,
961 TRACE_(VIDEOPRT
, "VideoPortReleaseBuffer\n");
971 IN PVOID HwDeviceExtension
,
972 IN PVOID BaseAddress
,
974 IN VP_LOCK_OPERATION Operation
)
978 Mdl
= IoAllocateMdl(BaseAddress
, Length
, FALSE
, FALSE
, NULL
);
984 MmProbeAndLockPages(Mdl
, KernelMode
,Operation
);
995 IN PVOID HwDeviceExtension
,
996 IN OUT PVIDEO_REQUEST_PACKET pVrp
,
998 IN PEVENT pDisplayEvent
,
999 IN DMA_FLAGS DmaFlags
)
1003 /* clear output buffer */
1004 pVrp
->OutputBuffer
= NULL
;
1006 if (DmaFlags
!= VideoPortDmaInitOnly
)
1008 /* VideoPortKeepPagesLocked / VideoPortUnlockAfterDma is no-op */
1012 /* lock the buffer */
1013 Buffer
= VideoPortLockBuffer(HwDeviceExtension
, pVrp
->InputBuffer
, pVrp
->InputBufferLength
, IoModifyAccess
);
1017 /* store result buffer & length */
1018 pVrp
->OutputBuffer
= Buffer
;
1019 pVrp
->OutputBufferLength
= pVrp
->InputBufferLength
;
1021 /* operation succeeded */
1025 /* operation failed */
1035 VideoPortUnlockBuffer(
1036 IN PVOID HwDeviceExtension
,
1041 MmUnlockPages((PMDL
)Mdl
);
1051 VideoPortSetTrappedEmulatorPorts(
1052 IN PVOID HwDeviceExtension
,
1053 IN ULONG NumAccessRanges
,
1054 IN PVIDEO_ACCESS_RANGE AccessRange
)
1057 /* Should store the ranges in the device extension for use by ntvdm. */
1066 VideoPortGetBusData(
1067 IN PVOID HwDeviceExtension
,
1068 IN BUS_DATA_TYPE BusDataType
,
1069 IN ULONG SlotNumber
,
1074 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1076 TRACE_(VIDEOPRT
, "VideoPortGetBusData\n");
1078 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1080 if (BusDataType
!= Cmos
)
1082 /* Legacy vs. PnP behaviour */
1083 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
1084 SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
1087 return HalGetBusDataByOffset(
1089 DeviceExtension
->SystemIoBusNumber
,
1101 VideoPortSetBusData(
1102 IN PVOID HwDeviceExtension
,
1103 IN BUS_DATA_TYPE BusDataType
,
1104 IN ULONG SlotNumber
,
1109 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1111 TRACE_(VIDEOPRT
, "VideoPortSetBusData\n");
1113 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1115 if (BusDataType
!= Cmos
)
1117 /* Legacy vs. PnP behaviour */
1118 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
1119 SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
1122 return HalSetBusDataByOffset(
1124 DeviceExtension
->SystemIoBusNumber
,