Fix a memory leak if VideoPortInitialize is called more than once from the same miniport.
[reactos.git] / reactos / drivers / video / videoprt / resource.c
1 /*
2 * VideoPort driver
3 *
4 * Copyright (C) 2002 - 2005 ReactOS Team
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
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 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; see the file COPYING.LIB.
18 * If not, write to the Free Software Foundation,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * $Id$
22 */
23
24 #include "videoprt.h"
25
26 /* PRIVATE FUNCTIONS **********************************************************/
27
28 NTSTATUS NTAPI
29 IntVideoPortMapPhysicalMemory(
30 IN HANDLE Process,
31 IN PHYSICAL_ADDRESS PhysicalAddress,
32 IN ULONG SizeInBytes,
33 IN ULONG Protect,
34 IN OUT PVOID *VirtualAddress OPTIONAL)
35 {
36 OBJECT_ATTRIBUTES ObjAttribs;
37 UNICODE_STRING UnicodeString;
38 HANDLE hMemObj;
39 NTSTATUS Status;
40 SIZE_T Size;
41
42 /* Initialize object attribs */
43 RtlInitUnicodeString(&UnicodeString, L"\\Device\\PhysicalMemory");
44 InitializeObjectAttributes(&ObjAttribs,
45 &UnicodeString,
46 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
47 NULL, NULL);
48
49 /* Open physical memory section */
50 Status = ZwOpenSection(&hMemObj, SECTION_ALL_ACCESS, &ObjAttribs);
51 if (!NT_SUCCESS(Status))
52 {
53 DPRINT("ZwOpenSection() failed! (0x%x)\n", Status);
54 return Status;
55 }
56
57 /* Map view of section */
58 Size = SizeInBytes;
59 Status = ZwMapViewOfSection(hMemObj,
60 Process,
61 VirtualAddress,
62 0,
63 Size,
64 (PLARGE_INTEGER)(&PhysicalAddress),
65 &Size,
66 ViewUnmap,
67 0,
68 Protect);
69 ZwClose(hMemObj);
70 if (!NT_SUCCESS(Status))
71 {
72 DPRINT("ZwMapViewOfSection() failed! (0x%x)\n", Status);
73 }
74
75 return Status;
76 }
77
78
79 PVOID NTAPI
80 IntVideoPortMapMemory(
81 IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
82 IN PHYSICAL_ADDRESS IoAddress,
83 IN ULONG NumberOfUchars,
84 IN UCHAR InIoSpace,
85 IN HANDLE ProcessHandle,
86 OUT VP_STATUS *Status)
87 {
88 PHYSICAL_ADDRESS TranslatedAddress;
89 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
90 ULONG AddressSpace;
91 PVOID MappedAddress;
92 PLIST_ENTRY Entry;
93
94 DPRINT("- IoAddress: %lx\n", IoAddress.u.LowPart);
95 DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars);
96 DPRINT("- InIoSpace: %x\n", InIoSpace);
97
98 InIoSpace &= ~VIDEO_MEMORY_SPACE_DENSE;
99 if ((InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE) != 0)
100 {
101 DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
102 InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE;
103 }
104
105 if (ProcessHandle != NULL && (InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0)
106 {
107 DPRINT("ProcessHandle is not NULL (0x%x) but InIoSpace does not have "
108 "VIDEO_MEMORY_SPACE_USER_MODE set! Setting "
109 "VIDEO_MEMORY_SPACE_USER_MODE.\n",
110 ProcessHandle);
111 InIoSpace |= VIDEO_MEMORY_SPACE_USER_MODE;
112 }
113 else if (ProcessHandle == NULL && (InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
114 {
115 DPRINT("ProcessHandle is NULL (0x%x) but InIoSpace does have "
116 "VIDEO_MEMORY_SPACE_USER_MODE set! Setting ProcessHandle "
117 "to NtCurrentProcess()\n",
118 ProcessHandle);
119 ProcessHandle = NtCurrentProcess();
120 }
121
122 if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0 &&
123 !IsListEmpty(&DeviceExtension->AddressMappingListHead))
124 {
125 Entry = DeviceExtension->AddressMappingListHead.Flink;
126 while (Entry != &DeviceExtension->AddressMappingListHead)
127 {
128 AddressMapping = CONTAINING_RECORD(
129 Entry,
130 VIDEO_PORT_ADDRESS_MAPPING,
131 List);
132 if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart &&
133 NumberOfUchars <= AddressMapping->NumberOfUchars)
134 {
135 {
136 AddressMapping->MappingCount++;
137 if (Status)
138 *Status = NO_ERROR;
139 return AddressMapping->MappedAddress;
140 }
141 }
142 Entry = Entry->Flink;
143 }
144 }
145
146 AddressSpace = (ULONG)InIoSpace;
147 AddressSpace &= ~VIDEO_MEMORY_SPACE_USER_MODE;
148 if (HalTranslateBusAddress(
149 DeviceExtension->AdapterInterfaceType,
150 DeviceExtension->SystemIoBusNumber,
151 IoAddress,
152 &AddressSpace,
153 &TranslatedAddress) == FALSE)
154 {
155 if (Status)
156 *Status = ERROR_NOT_ENOUGH_MEMORY;
157
158 return NULL;
159 }
160
161 /* I/O space */
162 if (AddressSpace != 0)
163 {
164 ASSERT(0 == TranslatedAddress.u.HighPart);
165 if (Status)
166 *Status = NO_ERROR;
167
168 return (PVOID)TranslatedAddress.u.LowPart;
169 }
170
171 /* user space */
172 if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
173 {
174 NTSTATUS NtStatus;
175 MappedAddress = NULL;
176 NtStatus = IntVideoPortMapPhysicalMemory(ProcessHandle,
177 TranslatedAddress,
178 NumberOfUchars,
179 PAGE_READWRITE/* | PAGE_WRITECOMBINE*/,
180 &MappedAddress);
181 if (!NT_SUCCESS(NtStatus))
182 {
183 DPRINT("IntVideoPortMapPhysicalMemory() failed! (0x%x)\n", NtStatus);
184 if (Status)
185 *Status = NO_ERROR;
186 return NULL;
187 }
188 DPRINT("Mapped user address = 0x%08x\n", MappedAddress);
189 }
190 else /* kernel space */
191 {
192 MappedAddress = MmMapIoSpace(
193 TranslatedAddress,
194 NumberOfUchars,
195 MmNonCached);
196 }
197
198 if (MappedAddress != NULL)
199 {
200 if (Status)
201 {
202 *Status = NO_ERROR;
203 }
204 if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0)
205 {
206 AddressMapping = ExAllocatePoolWithTag(
207 PagedPool,
208 sizeof(VIDEO_PORT_ADDRESS_MAPPING),
209 TAG_VIDEO_PORT);
210
211 if (AddressMapping == NULL)
212 return MappedAddress;
213
214 RtlZeroMemory(AddressMapping, sizeof(VIDEO_PORT_ADDRESS_MAPPING));
215 AddressMapping->NumberOfUchars = NumberOfUchars;
216 AddressMapping->IoAddress = IoAddress;
217 AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
218 AddressMapping->MappedAddress = MappedAddress;
219 AddressMapping->MappingCount = 1;
220 InsertHeadList(
221 &DeviceExtension->AddressMappingListHead,
222 &AddressMapping->List);
223 }
224
225 return MappedAddress;
226 }
227
228 if (Status)
229 *Status = NO_ERROR;
230
231 return NULL;
232 }
233
234 VOID NTAPI
235 IntVideoPortUnmapMemory(
236 IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
237 IN PVOID MappedAddress)
238 {
239 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
240 PLIST_ENTRY Entry;
241 NTSTATUS Status;
242
243 Entry = DeviceExtension->AddressMappingListHead.Flink;
244 while (Entry != &DeviceExtension->AddressMappingListHead)
245 {
246 AddressMapping = CONTAINING_RECORD(
247 Entry,
248 VIDEO_PORT_ADDRESS_MAPPING,
249 List);
250 if (AddressMapping->MappedAddress == MappedAddress)
251 {
252 ASSERT(AddressMapping->MappingCount > 0);
253 AddressMapping->MappingCount--;
254 if (AddressMapping->MappingCount == 0)
255 {
256 MmUnmapIoSpace(
257 AddressMapping->MappedAddress,
258 AddressMapping->NumberOfUchars);
259 RemoveEntryList(Entry);
260 ExFreePool(AddressMapping);
261 }
262 return;
263 }
264
265 Entry = Entry->Flink;
266 }
267
268 /* If there was no kernelmode mapping for the given address found we assume
269 * that the given address is a usermode mapping and try to unmap it.
270 *
271 * FIXME: Is it ok to use NtCurrentProcess?
272 */
273 Status = ZwUnmapViewOfSection(NtCurrentProcess(), MappedAddress);
274 if (!NT_SUCCESS(Status))
275 {
276 DPRINT1("Warning: Mapping for address 0x%x not found!\n", (ULONG)MappedAddress);
277 }
278 }
279
280 /* PUBLIC FUNCTIONS ***********************************************************/
281
282 /*
283 * @implemented
284 */
285
286 PVOID NTAPI
287 VideoPortGetDeviceBase(
288 IN PVOID HwDeviceExtension,
289 IN PHYSICAL_ADDRESS IoAddress,
290 IN ULONG NumberOfUchars,
291 IN UCHAR InIoSpace)
292 {
293 DPRINT("VideoPortGetDeviceBase\n");
294 return IntVideoPortMapMemory(
295 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
296 IoAddress,
297 NumberOfUchars,
298 InIoSpace,
299 NULL,
300 NULL);
301 }
302
303 /*
304 * @implemented
305 */
306
307 VOID NTAPI
308 VideoPortFreeDeviceBase(
309 IN PVOID HwDeviceExtension,
310 IN PVOID MappedAddress)
311 {
312 DPRINT("VideoPortFreeDeviceBase\n");
313 IntVideoPortUnmapMemory(
314 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
315 MappedAddress);
316 }
317
318 /*
319 * @unimplemented
320 */
321
322 VP_STATUS NTAPI
323 VideoPortMapBankedMemory(
324 IN PVOID HwDeviceExtension,
325 IN PHYSICAL_ADDRESS PhysicalAddress,
326 IN PULONG Length,
327 IN PULONG InIoSpace,
328 OUT PVOID *VirtualAddress,
329 IN ULONG BankLength,
330 IN UCHAR ReadWriteBank,
331 IN PBANKED_SECTION_ROUTINE BankRoutine,
332 IN PVOID Context)
333 {
334 DPRINT("VideoPortMapBankedMemory\n");
335 UNIMPLEMENTED;
336 return ERROR_CALL_NOT_IMPLEMENTED;
337 }
338
339
340 /*
341 * @implemented
342 */
343
344 VP_STATUS NTAPI
345 VideoPortMapMemory(
346 IN PVOID HwDeviceExtension,
347 IN PHYSICAL_ADDRESS PhysicalAddress,
348 IN PULONG Length,
349 IN PULONG InIoSpace,
350 OUT PVOID *VirtualAddress)
351 {
352 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
353 NTSTATUS Status;
354
355 DPRINT("VideoPortMapMemory\n");
356 DPRINT("- *VirtualAddress: 0x%x\n", *VirtualAddress);
357
358 DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
359 *VirtualAddress = IntVideoPortMapMemory(
360 DeviceExtension,
361 PhysicalAddress,
362 *Length,
363 *InIoSpace,
364 (HANDLE)*VirtualAddress,
365 &Status);
366
367 return Status;
368 }
369
370 /*
371 * @implemented
372 */
373
374 VP_STATUS NTAPI
375 VideoPortUnmapMemory(
376 IN PVOID HwDeviceExtension,
377 IN PVOID VirtualAddress,
378 IN HANDLE ProcessHandle)
379 {
380 DPRINT("VideoPortFreeDeviceBase\n");
381
382 IntVideoPortUnmapMemory(
383 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
384 VirtualAddress);
385
386 return NO_ERROR;
387 }
388
389 /*
390 * @implemented
391 */
392
393 VP_STATUS NTAPI
394 VideoPortGetAccessRanges(
395 IN PVOID HwDeviceExtension,
396 IN ULONG NumRequestedResources,
397 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL,
398 IN ULONG NumAccessRanges,
399 IN PVIDEO_ACCESS_RANGE AccessRanges,
400 IN PVOID VendorId,
401 IN PVOID DeviceId,
402 IN PULONG Slot)
403 {
404 PCI_SLOT_NUMBER PciSlotNumber;
405 ULONG FunctionNumber;
406 PCI_COMMON_CONFIG Config;
407 PCM_RESOURCE_LIST AllocatedResources;
408 NTSTATUS Status;
409 UINT AssignedCount;
410 CM_FULL_RESOURCE_DESCRIPTOR *FullList;
411 CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
412 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
413 USHORT VendorIdToFind;
414 USHORT DeviceIdToFind;
415 ULONG SlotIdToFind;
416 ULONG ReturnedLength;
417
418 DPRINT("VideoPortGetAccessRanges\n");
419
420 DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
421
422 if (NumRequestedResources == 0)
423 {
424 AllocatedResources = DeviceExtension->AllocatedResources;
425 if (AllocatedResources == NULL &&
426 DeviceExtension->AdapterInterfaceType == PCIBus)
427 {
428 if (DeviceExtension->PhysicalDeviceObject != NULL)
429 {
430 PciSlotNumber.u.AsULONG = DeviceExtension->SystemIoSlotNumber;
431
432 ReturnedLength = HalGetBusData(
433 PCIConfiguration,
434 DeviceExtension->SystemIoBusNumber,
435 PciSlotNumber.u.AsULONG,
436 &Config,
437 sizeof(PCI_COMMON_CONFIG));
438
439 if (ReturnedLength != sizeof(PCI_COMMON_CONFIG))
440 {
441 return ERROR_NO_SYSTEM_RESOURCES;
442 }
443 }
444 else
445 {
446 VendorIdToFind = VendorId != NULL ? *(PUSHORT)VendorId : 0;
447 DeviceIdToFind = DeviceId != NULL ? *(PUSHORT)DeviceId : 0;
448 SlotIdToFind = Slot != NULL ? *Slot : 0;
449 PciSlotNumber.u.AsULONG = SlotIdToFind;
450
451 DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n",
452 VendorIdToFind, DeviceIdToFind);
453
454 /*
455 * Search for the device id and vendor id on this bus.
456 */
457
458 for (FunctionNumber = 0; FunctionNumber < 8; FunctionNumber++)
459 {
460 DPRINT("- Function number: %d\n", FunctionNumber);
461 PciSlotNumber.u.bits.FunctionNumber = FunctionNumber;
462 ReturnedLength = HalGetBusData(
463 PCIConfiguration,
464 DeviceExtension->SystemIoBusNumber,
465 PciSlotNumber.u.AsULONG,
466 &Config,
467 sizeof(PCI_COMMON_CONFIG));
468 DPRINT("- Length of data: %x\n", ReturnedLength);
469 if (ReturnedLength == sizeof(PCI_COMMON_CONFIG))
470 {
471 DPRINT("- Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
472 "DeviceId 0x%04x\n",
473 PciSlotNumber.u.AsULONG,
474 PciSlotNumber.u.bits.DeviceNumber,
475 PciSlotNumber.u.bits.FunctionNumber,
476 Config.VendorID,
477 Config.DeviceID);
478
479 if ((VendorIdToFind == 0 || Config.VendorID == VendorIdToFind) &&
480 (DeviceIdToFind == 0 || Config.DeviceID == DeviceIdToFind))
481 {
482 break;
483 }
484 }
485 }
486
487 if (FunctionNumber == 8)
488 {
489 DPRINT("Didn't find device.\n");
490 return ERROR_DEV_NOT_EXIST;
491 }
492 }
493
494 Status = HalAssignSlotResources(
495 NULL, NULL, NULL, NULL,
496 DeviceExtension->AdapterInterfaceType,
497 DeviceExtension->SystemIoBusNumber,
498 PciSlotNumber.u.AsULONG,
499 &AllocatedResources);
500
501 if (!NT_SUCCESS(Status))
502 {
503 return Status;
504 }
505 DeviceExtension->AllocatedResources = AllocatedResources;
506 }
507 if (AllocatedResources == NULL)
508 return ERROR_NO_SYSTEM_RESOURCES;
509
510 AssignedCount = 0;
511 for (FullList = AllocatedResources->List;
512 FullList < AllocatedResources->List + AllocatedResources->Count;
513 FullList++)
514 {
515 ASSERT(FullList->InterfaceType == PCIBus &&
516 FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
517 1 == FullList->PartialResourceList.Version &&
518 1 == FullList->PartialResourceList.Revision);
519 for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
520 Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
521 Descriptor++)
522 {
523 if ((Descriptor->Type == CmResourceTypeMemory ||
524 Descriptor->Type == CmResourceTypePort) &&
525 AssignedCount >= NumAccessRanges)
526 {
527 DPRINT1("Too many access ranges found\n");
528 return ERROR_NO_SYSTEM_RESOURCES;
529 }
530 if (Descriptor->Type == CmResourceTypeMemory)
531 {
532 if (NumAccessRanges <= AssignedCount)
533 {
534 DPRINT1("Too many access ranges found\n");
535 return ERROR_NO_SYSTEM_RESOURCES;
536 }
537 DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
538 Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
539 AccessRanges[AssignedCount].RangeStart = Descriptor->u.Memory.Start;
540 AccessRanges[AssignedCount].RangeLength = Descriptor->u.Memory.Length;
541 AccessRanges[AssignedCount].RangeInIoSpace = 0;
542 AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
543 AccessRanges[AssignedCount].RangeShareable =
544 (Descriptor->ShareDisposition == CmResourceShareShared);
545 AssignedCount++;
546 }
547 else if (Descriptor->Type == CmResourceTypePort)
548 {
549 DPRINT("Port range starting at 0x%04x length %d\n",
550 Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
551 AccessRanges[AssignedCount].RangeStart = Descriptor->u.Port.Start;
552 AccessRanges[AssignedCount].RangeLength = Descriptor->u.Port.Length;
553 AccessRanges[AssignedCount].RangeInIoSpace = 1;
554 AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
555 AccessRanges[AssignedCount].RangeShareable = 0;
556 AssignedCount++;
557 }
558 else if (Descriptor->Type == CmResourceTypeInterrupt)
559 {
560 DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
561 DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
562 if (Descriptor->ShareDisposition == CmResourceShareShared)
563 DeviceExtension->InterruptShared = TRUE;
564 else
565 DeviceExtension->InterruptShared = FALSE;
566 }
567 }
568 }
569 }
570 else
571 {
572 UNIMPLEMENTED
573 }
574
575 return NO_ERROR;
576 }
577
578 /*
579 * @implemented
580 */
581
582 VP_STATUS NTAPI
583 VideoPortVerifyAccessRanges(
584 IN PVOID HwDeviceExtension,
585 IN ULONG NumAccessRanges,
586 IN PVIDEO_ACCESS_RANGE AccessRanges)
587 {
588 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
589 BOOLEAN ConflictDetected;
590 ULONG i;
591 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
592 PCM_RESOURCE_LIST ResourceList;
593 ULONG ResourceListSize;
594 NTSTATUS Status;
595
596 DPRINT("VideoPortVerifyAccessRanges\n");
597
598 DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
599
600 /* Create the resource list */
601 ResourceListSize = sizeof(CM_RESOURCE_LIST)
602 + (NumAccessRanges - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
603 ResourceList = ExAllocatePool(PagedPool, ResourceListSize);
604 if (!ResourceList)
605 {
606 DPRINT("ExAllocatePool() failed\n");
607 return ERROR_INVALID_PARAMETER;
608 }
609
610 /* Fill resource list */
611 ResourceList->Count = 1;
612 ResourceList->List[0].InterfaceType = DeviceExtension->AdapterInterfaceType;
613 ResourceList->List[0].BusNumber = DeviceExtension->SystemIoBusNumber;
614 ResourceList->List[0].PartialResourceList.Version = 1;
615 ResourceList->List[0].PartialResourceList.Revision = 1;
616 ResourceList->List[0].PartialResourceList.Count = NumAccessRanges;
617 for (i = 0; i < NumAccessRanges; i++, AccessRanges++)
618 {
619 PartialDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[i];
620 if (AccessRanges->RangeInIoSpace)
621 {
622 PartialDescriptor->Type = CmResourceTypePort;
623 PartialDescriptor->u.Port.Start = AccessRanges->RangeStart;
624 PartialDescriptor->u.Port.Length = AccessRanges->RangeLength;
625 }
626 else
627 {
628 PartialDescriptor->Type = CmResourceTypeMemory;
629 PartialDescriptor->u.Memory.Start = AccessRanges->RangeStart;
630 PartialDescriptor->u.Memory.Length = AccessRanges->RangeLength;
631 }
632 if (AccessRanges->RangeShareable)
633 PartialDescriptor->ShareDisposition = CmResourceShareShared;
634 else
635 PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
636 PartialDescriptor->Flags = 0;
637 if (AccessRanges->RangePassive & VIDEO_RANGE_PASSIVE_DECODE)
638 PartialDescriptor->Flags |= CM_RESOURCE_PORT_PASSIVE_DECODE;
639 if (AccessRanges->RangePassive & VIDEO_RANGE_10_BIT_DECODE)
640 PartialDescriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE;
641 }
642
643 /* Try to acquire all resource ranges */
644 Status = IoReportResourceForDetection(
645 DeviceExtension->DriverObject,
646 NULL, 0, /* Driver List */
647 DeviceExtension->PhysicalDeviceObject,
648 ResourceList, ResourceListSize,
649 &ConflictDetected);
650 ExFreePool(ResourceList);
651
652 if (!NT_SUCCESS(Status) || ConflictDetected)
653 return ERROR_INVALID_PARAMETER;
654 else
655 return NO_ERROR;
656 }
657
658 /*
659 * @unimplemented
660 */
661
662 VP_STATUS NTAPI
663 VideoPortGetDeviceData(
664 IN PVOID HwDeviceExtension,
665 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType,
666 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine,
667 IN PVOID Context)
668 {
669 DPRINT("VideoPortGetDeviceData\n");
670 UNIMPLEMENTED;
671 return ERROR_CALL_NOT_IMPLEMENTED;
672 }
673
674 /*
675 * @implemented
676 */
677
678 PVOID NTAPI
679 VideoPortAllocatePool(
680 IN PVOID HwDeviceExtension,
681 IN VP_POOL_TYPE PoolType,
682 IN SIZE_T NumberOfBytes,
683 IN ULONG Tag)
684 {
685 DPRINT("VideoPortAllocatePool\n");
686 return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
687 }
688
689 /*
690 * @implemented
691 */
692
693 VOID NTAPI
694 VideoPortFreePool(
695 IN PVOID HwDeviceExtension,
696 IN PVOID Ptr)
697 {
698 ExFreePool(Ptr);
699 }
700
701 /*
702 * @implemented
703 */
704
705 VP_STATUS NTAPI
706 VideoPortAllocateBuffer(
707 IN PVOID HwDeviceExtension,
708 IN ULONG Size,
709 OUT PVOID *Buffer)
710 {
711 DPRINT("VideoPortAllocateBuffer\n");
712 *Buffer = ExAllocatePool(PagedPool, Size);
713 return *Buffer == NULL ? ERROR_NOT_ENOUGH_MEMORY : NO_ERROR;
714 }
715
716 /*
717 * @implemented
718 */
719
720 VOID NTAPI
721 VideoPortReleaseBuffer(
722 IN PVOID HwDeviceExtension,
723 IN PVOID Ptr)
724 {
725 DPRINT("VideoPortReleaseBuffer\n");
726 ExFreePool(Ptr);
727 }
728
729 /*
730 * @unimplemented
731 */
732
733 PVOID NTAPI
734 VideoPortLockBuffer(
735 IN PVOID HwDeviceExtension,
736 IN PVOID BaseAddress,
737 IN ULONG Length,
738 IN VP_LOCK_OPERATION Operation)
739 {
740 DPRINT1("VideoPortLockBuffer: Unimplemented.\n");
741 return NULL;
742 }
743
744 /*
745 * @unimplemented
746 */
747
748 VOID NTAPI
749 VideoPortUnlockBuffer(
750 IN PVOID HwDeviceExtension,
751 IN PVOID Mdl)
752 {
753 DPRINT1("VideoPortUnlockBuffer: Unimplemented.\n");
754 }
755
756 /*
757 * @unimplemented
758 */
759
760 VP_STATUS NTAPI
761 VideoPortSetTrappedEmulatorPorts(
762 IN PVOID HwDeviceExtension,
763 IN ULONG NumAccessRanges,
764 IN PVIDEO_ACCESS_RANGE AccessRange)
765 {
766 DPRINT("VideoPortSetTrappedEmulatorPorts\n");
767 /* Should store the ranges in the device extension for use by ntvdm. */
768 return NO_ERROR;
769 }
770
771 /*
772 * @implemented
773 */
774
775 ULONG NTAPI
776 VideoPortGetBusData(
777 IN PVOID HwDeviceExtension,
778 IN BUS_DATA_TYPE BusDataType,
779 IN ULONG SlotNumber,
780 OUT PVOID Buffer,
781 IN ULONG Offset,
782 IN ULONG Length)
783 {
784 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
785
786 DPRINT("VideoPortGetBusData\n");
787
788 DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
789
790 if (BusDataType != Cmos)
791 {
792 /* Legacy vs. PnP behaviour */
793 if (DeviceExtension->PhysicalDeviceObject != NULL)
794 SlotNumber = DeviceExtension->SystemIoSlotNumber;
795 }
796
797 return HalGetBusDataByOffset(
798 BusDataType,
799 DeviceExtension->SystemIoBusNumber,
800 SlotNumber,
801 Buffer,
802 Offset,
803 Length);
804 }
805
806 /*
807 * @implemented
808 */
809
810 ULONG NTAPI
811 VideoPortSetBusData(
812 IN PVOID HwDeviceExtension,
813 IN BUS_DATA_TYPE BusDataType,
814 IN ULONG SlotNumber,
815 IN PVOID Buffer,
816 IN ULONG Offset,
817 IN ULONG Length)
818 {
819 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
820
821 DPRINT("VideoPortSetBusData\n");
822
823 DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
824
825 if (BusDataType != Cmos)
826 {
827 /* Legacy vs. PnP behaviour */
828 if (DeviceExtension->PhysicalDeviceObject != NULL)
829 SlotNumber = DeviceExtension->SystemIoSlotNumber;
830 }
831
832 return HalSetBusDataByOffset(
833 BusDataType,
834 DeviceExtension->SystemIoBusNumber,
835 SlotNumber,
836 Buffer,
837 Offset,
838 Length);
839 }