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 PciSlotNumber
.u
.bits
.Reserved
= 0;
633 for (DeviceNumber
= 0; DeviceNumber
< PCI_MAX_DEVICES
; DeviceNumber
++)
635 PciSlotNumber
.u
.bits
.DeviceNumber
= DeviceNumber
;
636 for (FunctionNumber
= 0; FunctionNumber
< PCI_MAX_FUNCTION
; FunctionNumber
++)
638 INFO_(VIDEOPRT
, "- Function number: %d\n", FunctionNumber
);
639 PciSlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
640 ReturnedLength
= HalGetBusData(PCIConfiguration
,
641 DeviceExtension
->SystemIoBusNumber
,
642 PciSlotNumber
.u
.AsULONG
,
644 sizeof(PCI_COMMON_CONFIG
));
645 INFO_(VIDEOPRT
, "- Length of data: %x\n", ReturnedLength
);
646 if (ReturnedLength
== sizeof(PCI_COMMON_CONFIG
))
648 INFO_(VIDEOPRT
, "- Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
650 PciSlotNumber
.u
.AsULONG
,
651 PciSlotNumber
.u
.bits
.DeviceNumber
,
652 PciSlotNumber
.u
.bits
.FunctionNumber
,
656 if ((VendorIdToFind
== 0 || Config
.VendorID
== VendorIdToFind
) &&
657 (DeviceIdToFind
== 0 || Config
.DeviceID
== DeviceIdToFind
))
659 DeviceAndVendorFound
= TRUE
;
664 if (DeviceAndVendorFound
) break;
666 if (FunctionNumber
== PCI_MAX_FUNCTION
)
668 WARN_(VIDEOPRT
, "Didn't find device.\n");
669 return ERROR_DEV_NOT_EXIST
;
673 Status
= HalAssignSlotResources(&DeviceExtension
->RegistryPath
,
675 DeviceExtension
->DriverObject
,
676 DeviceExtension
->DriverObject
->DeviceObject
,
677 DeviceExtension
->AdapterInterfaceType
,
678 DeviceExtension
->SystemIoBusNumber
,
679 PciSlotNumber
.u
.AsULONG
,
680 &AllocatedResources
);
682 if (!NT_SUCCESS(Status
))
684 WARN_(VIDEOPRT
, "HalAssignSlotResources failed with status %x.\n",Status
);
687 DeviceExtension
->AllocatedResources
= AllocatedResources
;
688 DeviceExtension
->SystemIoSlotNumber
= PciSlotNumber
.u
.AsULONG
;
690 /* Add legacy resources to the resources from HAL */
691 Status
= IntVideoPortGetLegacyResources(DriverExtension
, DeviceExtension
,
692 &LegacyAccessRanges
, &LegacyAccessRangeCount
);
693 if (!NT_SUCCESS(Status
))
694 return ERROR_DEV_NOT_EXIST
;
696 if (NumAccessRanges
< LegacyAccessRangeCount
)
698 ERR_(VIDEOPRT
, "Too many legacy access ranges found\n");
699 return ERROR_NOT_ENOUGH_MEMORY
;
702 RtlCopyMemory(AccessRanges
, LegacyAccessRanges
, LegacyAccessRangeCount
* sizeof(VIDEO_ACCESS_RANGE
));
703 AssignedCount
= LegacyAccessRangeCount
;
708 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + (NumRequestedResources
- 1) * sizeof(IO_RESOURCE_DESCRIPTOR
);
709 ResReqList
= ExAllocatePool(NonPagedPool
, ListSize
);
710 if (!ResReqList
) return ERROR_NOT_ENOUGH_MEMORY
;
712 ResReqList
->ListSize
= ListSize
;
713 ResReqList
->InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
714 ResReqList
->BusNumber
= DeviceExtension
->SystemIoBusNumber
;
715 ResReqList
->SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
716 ResReqList
->AlternativeLists
= 1;
717 ResReqList
->List
[0].Version
= 1;
718 ResReqList
->List
[0].Revision
= 1;
719 ResReqList
->List
[0].Count
= NumRequestedResources
;
721 /* Copy in the caller's resource list */
722 RtlCopyMemory(ResReqList
->List
[0].Descriptors
,
724 NumRequestedResources
* sizeof(IO_RESOURCE_DESCRIPTOR
));
726 Status
= IoAssignResources(&DeviceExtension
->RegistryPath
,
728 DeviceExtension
->DriverObject
,
729 DeviceExtension
->PhysicalDeviceObject
?
730 DeviceExtension
->PhysicalDeviceObject
:
731 DeviceExtension
->DriverObject
->DeviceObject
,
733 &AllocatedResources
);
735 if (!NT_SUCCESS(Status
))
738 if (!DeviceExtension
->AllocatedResources
)
739 DeviceExtension
->AllocatedResources
= AllocatedResources
;
742 if (AllocatedResources
== NULL
)
743 return ERROR_NOT_ENOUGH_MEMORY
;
745 /* Return the slot number if the caller wants it */
746 if (Slot
!= NULL
) *Slot
= DeviceExtension
->SystemIoBusNumber
;
748 FullList
= AllocatedResources
->List
;
749 ASSERT(AllocatedResources
->Count
== 1);
750 INFO_(VIDEOPRT
, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n",
751 FullList
->InterfaceType
, FullList
->BusNumber
, DeviceExtension
->SystemIoBusNumber
, FullList
->PartialResourceList
.Version
, FullList
->PartialResourceList
.Revision
);
753 ASSERT(FullList
->InterfaceType
== PCIBus
);
754 ASSERT(FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
);
755 ASSERT(1 == FullList
->PartialResourceList
.Version
);
756 ASSERT(1 == FullList
->PartialResourceList
.Revision
);
757 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
758 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
761 if ((Descriptor
->Type
== CmResourceTypeMemory
||
762 Descriptor
->Type
== CmResourceTypePort
) &&
763 AssignedCount
>= NumAccessRanges
)
765 ERR_(VIDEOPRT
, "Too many access ranges found\n");
766 return ERROR_NOT_ENOUGH_MEMORY
;
768 if (Descriptor
->Type
== CmResourceTypeMemory
)
770 INFO_(VIDEOPRT
, "Memory range starting at 0x%08x length 0x%08x\n",
771 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
772 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Memory
.Start
;
773 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Memory
.Length
;
774 AccessRanges
[AssignedCount
].RangeInIoSpace
= 0;
775 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
776 AccessRanges
[AssignedCount
].RangeShareable
=
777 (Descriptor
->ShareDisposition
== CmResourceShareShared
);
778 AccessRanges
[AssignedCount
].RangePassive
= 0;
781 else if (Descriptor
->Type
== CmResourceTypePort
)
783 INFO_(VIDEOPRT
, "Port range starting at 0x%04x length %d\n",
784 Descriptor
->u
.Port
.Start
.u
.LowPart
, Descriptor
->u
.Port
.Length
);
785 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Port
.Start
;
786 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Port
.Length
;
787 AccessRanges
[AssignedCount
].RangeInIoSpace
= 1;
788 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
789 AccessRanges
[AssignedCount
].RangeShareable
=
790 (Descriptor
->ShareDisposition
== CmResourceShareShared
);
791 AccessRanges
[AssignedCount
].RangePassive
= 0;
792 if (Descriptor
->Flags
& CM_RESOURCE_PORT_10_BIT_DECODE
)
793 AccessRanges
[AssignedCount
].RangePassive
|= VIDEO_RANGE_10_BIT_DECODE
;
794 if (Descriptor
->Flags
& CM_RESOURCE_PORT_PASSIVE_DECODE
)
795 AccessRanges
[AssignedCount
].RangePassive
|= VIDEO_RANGE_PASSIVE_DECODE
;
798 else if (Descriptor
->Type
== CmResourceTypeInterrupt
)
800 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
801 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
802 if (Descriptor
->ShareDisposition
== CmResourceShareShared
)
803 DeviceExtension
->InterruptShared
= TRUE
;
805 DeviceExtension
->InterruptShared
= FALSE
;
817 VideoPortVerifyAccessRanges(
818 IN PVOID HwDeviceExtension
,
819 IN ULONG NumAccessRanges
,
820 IN PVIDEO_ACCESS_RANGE AccessRanges
)
822 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
823 BOOLEAN ConflictDetected
;
825 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
826 PCM_RESOURCE_LIST ResourceList
;
827 ULONG ResourceListSize
;
830 TRACE_(VIDEOPRT
, "VideoPortVerifyAccessRanges\n");
832 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
834 /* Create the resource list */
835 ResourceListSize
= sizeof(CM_RESOURCE_LIST
)
836 + (NumAccessRanges
- 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
837 ResourceList
= ExAllocatePool(PagedPool
, ResourceListSize
);
840 WARN_(VIDEOPRT
, "ExAllocatePool() failed\n");
841 return ERROR_INVALID_PARAMETER
;
844 /* Fill resource list */
845 ResourceList
->Count
= 1;
846 ResourceList
->List
[0].InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
847 ResourceList
->List
[0].BusNumber
= DeviceExtension
->SystemIoBusNumber
;
848 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
849 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
850 ResourceList
->List
[0].PartialResourceList
.Count
= NumAccessRanges
;
851 for (i
= 0; i
< NumAccessRanges
; i
++, AccessRanges
++)
853 PartialDescriptor
= &ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
854 if (AccessRanges
->RangeInIoSpace
)
856 PartialDescriptor
->Type
= CmResourceTypePort
;
857 PartialDescriptor
->u
.Port
.Start
= AccessRanges
->RangeStart
;
858 PartialDescriptor
->u
.Port
.Length
= AccessRanges
->RangeLength
;
862 PartialDescriptor
->Type
= CmResourceTypeMemory
;
863 PartialDescriptor
->u
.Memory
.Start
= AccessRanges
->RangeStart
;
864 PartialDescriptor
->u
.Memory
.Length
= AccessRanges
->RangeLength
;
866 if (AccessRanges
->RangeShareable
)
867 PartialDescriptor
->ShareDisposition
= CmResourceShareShared
;
869 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
870 PartialDescriptor
->Flags
= 0;
871 if (AccessRanges
->RangePassive
& VIDEO_RANGE_PASSIVE_DECODE
)
872 PartialDescriptor
->Flags
|= CM_RESOURCE_PORT_PASSIVE_DECODE
;
873 if (AccessRanges
->RangePassive
& VIDEO_RANGE_10_BIT_DECODE
)
874 PartialDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
877 /* Try to acquire all resource ranges */
878 Status
= IoReportResourceForDetection(
879 DeviceExtension
->DriverObject
,
880 NULL
, 0, /* Driver List */
881 DeviceExtension
->PhysicalDeviceObject
,
882 ResourceList
, ResourceListSize
,
884 ExFreePool(ResourceList
);
886 if (!NT_SUCCESS(Status
) || ConflictDetected
)
887 return ERROR_INVALID_PARAMETER
;
897 VideoPortGetDeviceData(
898 IN PVOID HwDeviceExtension
,
899 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType
,
900 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine
,
903 TRACE_(VIDEOPRT
, "VideoPortGetDeviceData\n");
905 return ERROR_INVALID_FUNCTION
;
913 VideoPortAllocatePool(
914 IN PVOID HwDeviceExtension
,
915 IN VP_POOL_TYPE PoolType
,
916 IN SIZE_T NumberOfBytes
,
919 TRACE_(VIDEOPRT
, "VideoPortAllocatePool\n");
920 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
929 IN PVOID HwDeviceExtension
,
940 VideoPortAllocateBuffer(
941 IN PVOID HwDeviceExtension
,
945 TRACE_(VIDEOPRT
, "VideoPortAllocateBuffer\n");
946 *Buffer
= ExAllocatePoolWithTag ( PagedPool
, Size
, TAG_VIDEO_PORT_BUFFER
) ;
947 return *Buffer
== NULL
? ERROR_NOT_ENOUGH_MEMORY
: NO_ERROR
;
955 VideoPortReleaseBuffer(
956 IN PVOID HwDeviceExtension
,
959 TRACE_(VIDEOPRT
, "VideoPortReleaseBuffer\n");
969 IN PVOID HwDeviceExtension
,
970 IN PVOID BaseAddress
,
972 IN VP_LOCK_OPERATION Operation
)
976 Mdl
= IoAllocateMdl(BaseAddress
, Length
, FALSE
, FALSE
, NULL
);
982 MmProbeAndLockPages(Mdl
, KernelMode
,Operation
);
993 IN PVOID HwDeviceExtension
,
994 IN OUT PVIDEO_REQUEST_PACKET pVrp
,
996 IN PEVENT pDisplayEvent
,
997 IN DMA_FLAGS DmaFlags
)
1001 /* clear output buffer */
1002 pVrp
->OutputBuffer
= NULL
;
1004 if (DmaFlags
!= VideoPortDmaInitOnly
)
1006 /* VideoPortKeepPagesLocked / VideoPortUnlockAfterDma is no-op */
1010 /* lock the buffer */
1011 Buffer
= VideoPortLockBuffer(HwDeviceExtension
, pVrp
->InputBuffer
, pVrp
->InputBufferLength
, IoModifyAccess
);
1015 /* store result buffer & length */
1016 pVrp
->OutputBuffer
= Buffer
;
1017 pVrp
->OutputBufferLength
= pVrp
->InputBufferLength
;
1019 /* operation succeeded */
1023 /* operation failed */
1033 VideoPortUnlockBuffer(
1034 IN PVOID HwDeviceExtension
,
1039 MmUnlockPages((PMDL
)Mdl
);
1049 VideoPortSetTrappedEmulatorPorts(
1050 IN PVOID HwDeviceExtension
,
1051 IN ULONG NumAccessRanges
,
1052 IN PVIDEO_ACCESS_RANGE AccessRange
)
1055 /* Should store the ranges in the device extension for use by ntvdm. */
1064 VideoPortGetBusData(
1065 IN PVOID HwDeviceExtension
,
1066 IN BUS_DATA_TYPE BusDataType
,
1067 IN ULONG SlotNumber
,
1072 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1074 TRACE_(VIDEOPRT
, "VideoPortGetBusData\n");
1076 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1078 if (BusDataType
!= Cmos
)
1080 /* Legacy vs. PnP behaviour */
1081 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
1082 SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
1085 return HalGetBusDataByOffset(
1087 DeviceExtension
->SystemIoBusNumber
,
1099 VideoPortSetBusData(
1100 IN PVOID HwDeviceExtension
,
1101 IN BUS_DATA_TYPE BusDataType
,
1102 IN ULONG SlotNumber
,
1107 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1109 TRACE_(VIDEOPRT
, "VideoPortSetBusData\n");
1111 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1113 if (BusDataType
!= Cmos
)
1115 /* Legacy vs. PnP behaviour */
1116 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
1117 SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
1120 return HalSetBusDataByOffset(
1122 DeviceExtension
->SystemIoBusNumber
,