4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
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.
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.
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.
21 * $Id: videoprt.c,v 1.18 2004/03/10 16:10:13 navaraf Exp $
26 BOOLEAN CsrssInitialized
= FALSE
;
27 PEPROCESS Csrss
= NULL
;
28 PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension
= NULL
;
29 static PVOID RomImageBuffer
= NULL
;
32 VideoPortDeferredRoutine(
34 IN PVOID DeferredContext
,
35 IN PVOID SystemArgument1
,
36 IN PVOID SystemArgument2
39 VideoPortGetProcAddress(IN PVOID HwDeviceExtension
,
40 IN PUCHAR FunctionName
);
42 // ------------------------------------------------------- Public Interface
47 // This function initializes the driver.
53 // IN PDRIVER_OBJECT DriverObject System allocated Driver Object
55 // IN PUNICODE_STRING RegistryPath Name of registry driver service
62 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
63 IN PUNICODE_STRING RegistryPath
)
65 DPRINT("DriverEntry()\n");
66 return(STATUS_SUCCESS
);
73 VideoPortDebugPrint(IN VIDEO_DEBUG_LEVEL DebugPrintLevel
,
74 IN PCHAR DebugMessage
, ...)
80 if (DebugPrintLevel > InternalDebugLevel)
83 va_start (ap
, DebugMessage
);
84 vsprintf (Buffer
, DebugMessage
, ap
);
96 VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension
,
97 IN PVOID MappedAddress
)
99 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
101 DPRINT("VideoPortFreeDeviceBase\n");
103 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
104 VIDEO_PORT_DEVICE_EXTENSION
,
105 MiniPortDeviceExtension
);
107 InternalUnmapMemory(DeviceExtension
, MappedAddress
);
116 VideoPortGetBusData(IN PVOID HwDeviceExtension
,
117 IN BUS_DATA_TYPE BusDataType
,
123 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
125 DPRINT("VideoPortGetBusData\n");
127 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
128 VIDEO_PORT_DEVICE_EXTENSION
,
129 MiniPortDeviceExtension
);
131 return HalGetBusDataByOffset(BusDataType
,
132 DeviceExtension
->SystemIoBusNumber
,
145 VideoPortGetCurrentIrql(VOID
)
147 return KeGetCurrentIrql();
156 VideoPortGetDeviceBase(IN PVOID HwDeviceExtension
,
157 IN PHYSICAL_ADDRESS IoAddress
,
158 IN ULONG NumberOfUchars
,
161 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
163 DPRINT("VideoPortGetDeviceBase\n");
165 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
166 VIDEO_PORT_DEVICE_EXTENSION
,
167 MiniPortDeviceExtension
);
169 return InternalMapMemory(DeviceExtension
, IoAddress
, NumberOfUchars
, InIoSpace
, NULL
);
178 VideoPortGetDeviceData(IN PVOID HwDeviceExtension
,
179 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType
,
180 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine
,
183 DPRINT("VideoPortGetDeviceData\n");
185 return STATUS_NOT_IMPLEMENTED
;
194 VideoPortGetAccessRanges(IN PVOID HwDeviceExtension
,
195 IN ULONG NumRequestedResources
,
196 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL
,
197 IN ULONG NumAccessRanges
,
198 IN PVIDEO_ACCESS_RANGE AccessRanges
,
203 PCI_SLOT_NUMBER PciSlotNumber
;
204 ULONG FunctionNumber
;
205 PCI_COMMON_CONFIG Config
;
206 PCM_RESOURCE_LIST AllocatedResources
;
209 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
210 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
211 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
212 USHORT VendorIdToFind
;
213 USHORT DeviceIdToFind
;
216 DPRINT("VideoPortGetAccessRanges\n");
218 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
219 VIDEO_PORT_DEVICE_EXTENSION
,
220 MiniPortDeviceExtension
);
222 if (0 == NumRequestedResources
&&
223 PCIBus
== DeviceExtension
->AdapterInterfaceType
)
225 VendorIdToFind
= VendorId
!= NULL
? *(PUSHORT
)VendorId
: 0;
226 DeviceIdToFind
= DeviceId
!= NULL
? *(PUSHORT
)DeviceId
: 0;
227 SlotIdToFind
= Slot
!= NULL
? *Slot
: 0;
229 DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x SlotId 0x%04x\n",
230 VendorIdToFind
, DeviceIdToFind
, SlotIdToFind
);
232 PciSlotNumber
.u
.AsULONG
= SlotIdToFind
;
235 Search for the device id and vendor id on this bus.
237 for (FunctionNumber
= 0; FunctionNumber
< 8; FunctionNumber
++)
239 ULONG ReturnedLength
;
240 DPRINT("- Function number: %d\n", FunctionNumber
);
241 PciSlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
242 ReturnedLength
= HalGetBusData(PCIConfiguration
,
243 DeviceExtension
->SystemIoBusNumber
,
244 PciSlotNumber
.u
.AsULONG
,
246 sizeof(PCI_COMMON_CONFIG
));
247 DPRINT("- Length of data: %x\n", ReturnedLength
);
248 if (sizeof(PCI_COMMON_CONFIG
) == ReturnedLength
)
250 DPRINT("- Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
252 PciSlotNumber
.u
.AsULONG
,
253 PciSlotNumber
.u
.bits
.DeviceNumber
,
254 PciSlotNumber
.u
.bits
.FunctionNumber
,
258 if ((VendorIdToFind
== 0 || Config
.VendorID
== VendorIdToFind
) &&
259 (DeviceIdToFind
== 0 || Config
.DeviceID
== DeviceIdToFind
))
265 if (FunctionNumber
== 8)
267 DPRINT("Didn't find device.\n");
268 return STATUS_UNSUCCESSFUL
;
271 Status
= HalAssignSlotResources(NULL
, NULL
, NULL
, NULL
,
272 DeviceExtension
->AdapterInterfaceType
,
273 DeviceExtension
->SystemIoBusNumber
,
274 PciSlotNumber
.u
.AsULONG
,
275 &AllocatedResources
);
276 if (! NT_SUCCESS(Status
))
281 for (FullList
= AllocatedResources
->List
;
282 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
285 assert(FullList
->InterfaceType
== PCIBus
&&
286 FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
&&
287 1 == FullList
->PartialResourceList
.Version
&&
288 1 == FullList
->PartialResourceList
.Revision
);
289 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
290 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
293 if ((CmResourceTypeMemory
== Descriptor
->Type
294 || CmResourceTypePort
== Descriptor
->Type
)
295 && NumAccessRanges
<= AssignedCount
)
297 DPRINT1("Too many access ranges found\n");
298 ExFreePool(AllocatedResources
);
299 return STATUS_UNSUCCESSFUL
;
301 if (CmResourceTypeMemory
== Descriptor
->Type
)
303 if (NumAccessRanges
<= AssignedCount
)
305 DPRINT1("Too many access ranges found\n");
306 ExFreePool(AllocatedResources
);
307 return STATUS_UNSUCCESSFUL
;
309 DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
310 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
311 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Memory
.Start
;
312 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Memory
.Length
;
313 AccessRanges
[AssignedCount
].RangeInIoSpace
= 0;
314 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
315 AccessRanges
[AssignedCount
].RangeShareable
=
316 (CmResourceShareShared
== Descriptor
->ShareDisposition
);
319 else if (CmResourceTypePort
== Descriptor
->Type
)
321 DPRINT("Port range starting at 0x%04x length %d\n",
322 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
323 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Port
.Start
;
324 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Port
.Length
;
325 AccessRanges
[AssignedCount
].RangeInIoSpace
= 1;
326 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
327 AccessRanges
[AssignedCount
].RangeShareable
= 0;
330 else if (CmResourceTypeInterrupt
== Descriptor
->Type
)
332 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
333 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
337 ExFreePool(AllocatedResources
);
344 return STATUS_SUCCESS
;
347 typedef struct QueryRegistryCallbackContext
349 PVOID HwDeviceExtension
;
351 PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine
;
352 } QUERY_REGISTRY_CALLBACK_CONTEXT
, *PQUERY_REGISTRY_CALLBACK_CONTEXT
;
354 static NTSTATUS STDCALL
355 QueryRegistryCallback(IN PWSTR ValueName
,
358 IN ULONG ValueLength
,
360 IN PVOID EntryContext
)
362 PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext
= (PQUERY_REGISTRY_CALLBACK_CONTEXT
) Context
;
364 DPRINT("Found registry value for name %S: type %d, length %d\n",
365 ValueName
, ValueType
, ValueLength
);
366 return (*(CallbackContext
->HwGetRegistryRoutine
))(CallbackContext
->HwDeviceExtension
,
367 CallbackContext
->HwContext
,
378 VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension
,
379 IN PWSTR ParameterName
,
380 IN UCHAR IsParameterFileName
,
381 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine
,
384 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
385 QUERY_REGISTRY_CALLBACK_CONTEXT Context
;
386 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
388 DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName
);
390 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
391 VIDEO_PORT_DEVICE_EXTENSION
,
392 MiniPortDeviceExtension
);
394 if (IsParameterFileName
)
399 Context
.HwDeviceExtension
= HwDeviceExtension
;
400 Context
.HwContext
= HwContext
;
401 Context
.HwGetRegistryRoutine
= GetRegistryRoutine
;
403 QueryTable
[0].QueryRoutine
= QueryRegistryCallback
;
404 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
;
405 QueryTable
[0].Name
= ParameterName
;
406 QueryTable
[0].EntryContext
= NULL
;
407 QueryTable
[0].DefaultType
= REG_NONE
;
408 QueryTable
[0].DefaultData
= NULL
;
409 QueryTable
[0].DefaultLength
= 0;
411 QueryTable
[1].QueryRoutine
= NULL
;
412 QueryTable
[1].Name
= NULL
;
414 return NT_SUCCESS(RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
415 DeviceExtension
->RegistryPath
.Buffer
,
416 QueryTable
, &Context
, NULL
))
417 ? ERROR_SUCCESS
: ERROR_INVALID_PARAMETER
;
426 VideoPortGetVgaStatus(IN PVOID HwDeviceExtension
,
427 OUT PULONG VgaStatus
)
429 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
431 DPRINT1("VideoPortGetVgaStatus = %S \n", VgaStatus
);
433 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
434 VIDEO_PORT_DEVICE_EXTENSION
,
435 MiniPortDeviceExtension
);
437 if(KeGetCurrentIrql() == PASSIVE_LEVEL
)
439 DPRINT1("VideoPortGetVgaStatus1 = %S \n", VgaStatus
);
441 if ( PCIBus
== DeviceExtension
->AdapterInterfaceType
)
444 VgaStatus 0 == VGA not enabled, 1 == VGA enabled.
446 DPRINT1("VideoPortGetVgaStatus2 = %S \n", VgaStatus
);
448 /* Assumed for now */
450 VgaStatus
= (PULONG
) 1;
452 return STATUS_SUCCESS
;
455 DPRINT1("VideoPortGetVgaStatus3 = %S \n", VgaStatus
);
457 return ERROR_INVALID_FUNCTION
;
461 VPInterruptRoutine(IN
struct _KINTERRUPT
*Interrupt
,
462 IN PVOID ServiceContext
)
464 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
466 DeviceExtension
= ServiceContext
;
467 assert(NULL
!= DeviceExtension
->HwInterrupt
);
469 return DeviceExtension
->HwInterrupt(&DeviceExtension
->MiniPortDeviceExtension
);
473 VPTimerRoutine(IN PDEVICE_OBJECT DeviceObject
,
476 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
478 DeviceExtension
= Context
;
479 assert(DeviceExtension
== DeviceObject
->DeviceExtension
480 && NULL
!= DeviceExtension
->HwTimer
);
482 DeviceExtension
->HwTimer(&DeviceExtension
->MiniPortDeviceExtension
);
489 VideoPortInitialize(IN PVOID Context1
,
491 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData
,
494 PUNICODE_STRING RegistryPath
;
496 WCHAR DeviceBuffer
[20];
497 WCHAR SymlinkBuffer
[20];
498 WCHAR DeviceVideoBuffer
[20];
500 PDRIVER_OBJECT MPDriverObject
= (PDRIVER_OBJECT
) Context1
;
501 PDEVICE_OBJECT MPDeviceObject
;
502 VIDEO_PORT_CONFIG_INFO ConfigInfo
;
503 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
505 UNICODE_STRING DeviceName
;
506 UNICODE_STRING SymlinkName
;
511 ULONG InterruptVector
;
512 OBJECT_ATTRIBUTES Obj
;
515 DPRINT("VideoPortInitialize\n");
517 RegistryPath
= (PUNICODE_STRING
) Context2
;
519 /* Build Dispatch table from passed data */
520 MPDriverObject
->DriverStartIo
= (PDRIVER_STARTIO
) HwInitializationData
->HwStartIO
;
522 /* Find the first free device number */
523 for (DisplayNumber
= 0;;)
525 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DisplayNumber
+ 1);
526 RtlInitUnicodeString(&SymlinkName
, SymlinkBuffer
);
527 InitializeObjectAttributes(&Obj
, &SymlinkName
, 0, NULL
, NULL
);
528 Status
= ZwOpenSymbolicLinkObject(&ObjHandle
, GENERIC_READ
, &Obj
);
529 if (NT_SUCCESS(Status
))
535 else if (Status
== STATUS_NOT_FOUND
|| Status
== STATUS_UNSUCCESSFUL
)
545 DPRINT("- DisplayNumber: %d\n", DisplayNumber
);
551 /* Create a unicode device name. */
552 swprintf(DeviceBuffer
, L
"\\Device\\Video%lu", DisplayNumber
);
553 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
555 /* Create the device. */
556 Status
= IoCreateDevice(
558 HwInitializationData
->HwDeviceExtensionSize
+
559 sizeof(VIDEO_PORT_DEVICE_EXTENSION
),
565 if (!NT_SUCCESS(Status
))
567 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status
);
571 MPDriverObject
->DeviceObject
= MPDeviceObject
;
573 /* Initialize the miniport drivers dispatch table */
574 MPDriverObject
->MajorFunction
[IRP_MJ_CREATE
] = VidDispatchOpen
;
575 MPDriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = VidDispatchClose
;
576 MPDriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = VidDispatchDeviceControl
;
578 /* Initialize our device extension */
580 (PVIDEO_PORT_DEVICE_EXTENSION
) MPDeviceObject
->DeviceExtension
;
581 DeviceExtension
->DeviceObject
= MPDeviceObject
;
582 DeviceExtension
->HwInitialize
= HwInitializationData
->HwInitialize
;
583 DeviceExtension
->HwResetHw
= HwInitializationData
->HwResetHw
;
584 DeviceExtension
->AdapterInterfaceType
= HwInitializationData
->AdapterInterfaceType
;
585 DeviceExtension
->SystemIoBusNumber
= 0;
586 KeInitializeDpc(&DeviceExtension
->DpcObject
, VideoPortDeferredRoutine
,
587 (PVOID
)DeviceExtension
);
588 MaxLen
= (wcslen(RegistryPath
->Buffer
) + 10) * sizeof(WCHAR
);
589 DeviceExtension
->RegistryPath
.MaximumLength
= MaxLen
;
590 DeviceExtension
->RegistryPath
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
593 swprintf(DeviceExtension
->RegistryPath
.Buffer
, L
"%s\\Device0",
594 RegistryPath
->Buffer
);
595 DeviceExtension
->RegistryPath
.Length
= wcslen(DeviceExtension
->RegistryPath
.Buffer
) *
598 MaxBus
= (DeviceExtension
->AdapterInterfaceType
== PCIBus
) ? 8 : 1;
599 DPRINT("MaxBus: %lu\n", MaxBus
);
600 InitializeListHead(&DeviceExtension
->AddressMappingListHead
);
602 /* Set the buffering strategy here... */
603 /* If you change this, remember to change VidDispatchDeviceControl too */
604 MPDeviceObject
->Flags
|= DO_BUFFERED_IO
;
608 RtlZeroMemory(&DeviceExtension
->MiniPortDeviceExtension
,
609 HwInitializationData
->HwDeviceExtensionSize
);
610 DPRINT("Searching on bus %d\n", DeviceExtension
->SystemIoBusNumber
);
611 /* Setup configuration info */
612 RtlZeroMemory(&ConfigInfo
, sizeof(VIDEO_PORT_CONFIG_INFO
));
613 ConfigInfo
.Length
= sizeof(VIDEO_PORT_CONFIG_INFO
);
614 ConfigInfo
.AdapterInterfaceType
= DeviceExtension
->AdapterInterfaceType
;
615 ConfigInfo
.SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
616 ConfigInfo
.InterruptMode
= (PCIBus
== DeviceExtension
->AdapterInterfaceType
) ?
617 LevelSensitive
: Latched
;
618 ConfigInfo
.DriverRegistryPath
= RegistryPath
->Buffer
;
619 ConfigInfo
.VideoPortGetProcAddress
= VideoPortGetProcAddress
;
621 /* Call HwFindAdapter entry point */
622 /* FIXME: Need to figure out what string to pass as param 3 */
623 DPRINT("FindAdapter %X\n", HwInitializationData
->HwFindAdapter
);
624 Status
= HwInitializationData
->HwFindAdapter(&DeviceExtension
->MiniPortDeviceExtension
,
629 if (NO_ERROR
!= Status
)
631 DPRINT("HwFindAdapter call failed with error %X\n", Status
);
632 DeviceExtension
->SystemIoBusNumber
++;
635 while (NO_ERROR
!= Status
&& DeviceExtension
->SystemIoBusNumber
< MaxBus
);
637 if (NO_ERROR
!= Status
)
639 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
640 IoDeleteDevice(MPDeviceObject
);
644 DPRINT("Found adapter\n");
646 /* create symbolic link "\??\DISPLAYx" */
647 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DisplayNumber
+ 1);
648 RtlInitUnicodeString (&SymlinkName
,
650 IoCreateSymbolicLink (&SymlinkName
,
653 /* Add entry to DEVICEMAP\VIDEO key in registry */
654 swprintf(DeviceVideoBuffer
, L
"\\Device\\Video%d", DisplayNumber
);
655 RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP
,
659 DeviceExtension
->RegistryPath
.Buffer
,
660 DeviceExtension
->RegistryPath
.Length
+ sizeof(WCHAR
));
662 /* FIXME: Allocate hardware resources for device */
664 /* Allocate interrupt for device */
665 DeviceExtension
->HwInterrupt
= HwInitializationData
->HwInterrupt
;
666 if (0 == ConfigInfo
.BusInterruptVector
)
668 ConfigInfo
.BusInterruptVector
= DeviceExtension
->InterruptVector
;
670 if (0 == ConfigInfo
.BusInterruptLevel
)
672 ConfigInfo
.BusInterruptLevel
= DeviceExtension
->InterruptLevel
;
674 if (NULL
!= HwInitializationData
->HwInterrupt
)
677 HalGetInterruptVector(ConfigInfo
.AdapterInterfaceType
,
678 ConfigInfo
.SystemIoBusNumber
,
679 ConfigInfo
.BusInterruptLevel
,
680 ConfigInfo
.BusInterruptVector
,
683 if (0 == InterruptVector
)
685 DPRINT1("HalGetInterruptVector failed\n");
686 IoDeleteDevice(MPDeviceObject
);
688 return STATUS_INSUFFICIENT_RESOURCES
;
690 KeInitializeSpinLock(&DeviceExtension
->InterruptSpinLock
);
691 Status
= IoConnectInterrupt(&DeviceExtension
->InterruptObject
,
694 &DeviceExtension
->InterruptSpinLock
,
698 ConfigInfo
.InterruptMode
,
702 if (!NT_SUCCESS(Status
))
704 DPRINT1("IoConnectInterrupt failed with status 0x%08x\n", Status
);
705 IoDeleteDevice(MPDeviceObject
);
714 DeviceExtension
->HwTimer
= HwInitializationData
->HwTimer
;
715 if (HwInitializationData
->HwTimer
!= NULL
)
717 DPRINT("Initializing timer\n");
718 Status
= IoInitializeTimer(MPDeviceObject
,
721 if (!NT_SUCCESS(Status
))
723 DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status
);
725 if (HwInitializationData
->HwInterrupt
!= NULL
)
727 IoDisconnectInterrupt(DeviceExtension
->InterruptObject
);
729 IoDeleteDevice(MPDeviceObject
);
735 return STATUS_SUCCESS
;
743 VideoPortLogError(IN PVOID HwDeviceExtension
,
744 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL
,
745 IN VP_STATUS ErrorCode
,
748 DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
749 ErrorCode
, ErrorCode
, UniqueId
, UniqueId
);
752 DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp
->IoControlCode
, Vrp
->IoControlCode
);
762 VideoPortMapBankedMemory(IN PVOID HwDeviceExtension
,
763 IN PHYSICAL_ADDRESS PhysicalAddress
,
766 OUT PVOID
*VirtualAddress
,
768 IN UCHAR ReadWriteBank
,
769 IN PBANKED_SECTION_ROUTINE BankRoutine
,
772 DPRINT("VideoPortMapBankedMemory\n");
774 return STATUS_NOT_IMPLEMENTED
;
783 VideoPortMapMemory(IN PVOID HwDeviceExtension
,
784 IN PHYSICAL_ADDRESS PhysicalAddress
,
787 OUT PVOID
*VirtualAddress
)
789 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
792 DPRINT("VideoPortMapMemory\n");
794 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
795 VIDEO_PORT_DEVICE_EXTENSION
,
796 MiniPortDeviceExtension
);
797 *VirtualAddress
= InternalMapMemory(DeviceExtension
, PhysicalAddress
,
798 *Length
, *InIoSpace
, &Status
);
809 VideoPortScanRom(IN PVOID HwDeviceExtension
,
816 PUCHAR SearchLocation
;
818 DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase
, RomLength
, String
);
820 StringLength
= strlen(String
);
822 SearchLocation
= RomBase
;
823 for (SearchLocation
= RomBase
;
824 ! Found
&& SearchLocation
< RomBase
+ RomLength
- StringLength
;
827 Found
= (RtlCompareMemory(SearchLocation
, String
, StringLength
) == StringLength
);
830 DPRINT("Match found at %p\n", SearchLocation
);
843 VideoPortSetBusData(IN PVOID HwDeviceExtension
,
844 IN BUS_DATA_TYPE BusDataType
,
850 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
852 DPRINT("VideoPortSetBusData\n");
854 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
855 VIDEO_PORT_DEVICE_EXTENSION
,
856 MiniPortDeviceExtension
);
858 return HalSetBusDataByOffset(BusDataType
,
859 DeviceExtension
->SystemIoBusNumber
,
872 VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension
,
875 IN ULONG ValueLength
)
877 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
879 DPRINT("VideoSetRegistryParameters\n");
881 assert_irql(PASSIVE_LEVEL
);
883 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
884 VIDEO_PORT_DEVICE_EXTENSION
,
885 MiniPortDeviceExtension
);
886 return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
887 DeviceExtension
->RegistryPath
.Buffer
,
900 VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension
,
901 IN ULONG NumAccessRanges
,
902 IN PVIDEO_ACCESS_RANGE AccessRange
)
904 DPRINT("VideoPortSetTrappedEmulatorPorts\n");
905 /* Should store the ranges in the device extension for use by ntvdm. */
906 return STATUS_SUCCESS
;
915 VideoPortStartTimer(IN PVOID HwDeviceExtension
)
917 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
919 DPRINT("VideoPortStartTimer\n");
921 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
922 VIDEO_PORT_DEVICE_EXTENSION
,
923 MiniPortDeviceExtension
);
924 IoStartTimer(DeviceExtension
->DeviceObject
);
933 VideoPortStopTimer(IN PVOID HwDeviceExtension
)
935 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
937 DPRINT("VideoPortStopTimer\n");
939 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
940 VIDEO_PORT_DEVICE_EXTENSION
,
941 MiniPortDeviceExtension
);
942 IoStopTimer(DeviceExtension
->DeviceObject
);
951 VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension
,
952 IN VIDEO_SYNCHRONIZE_PRIORITY Priority
,
953 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine
,
957 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
963 Ret
= (*SynchronizeRoutine
)(Context
);
965 case VpMediumPriority
:
966 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
967 VIDEO_PORT_DEVICE_EXTENSION
,
968 MiniPortDeviceExtension
);
969 if (NULL
== DeviceExtension
->InterruptObject
)
971 Ret
= (*SynchronizeRoutine
)(Context
);
975 Ret
= KeSynchronizeExecution(DeviceExtension
->InterruptObject
,
981 OldIrql
= KeGetCurrentIrql();
982 if (OldIrql
< SYNCH_LEVEL
)
984 OldIrql
= KfRaiseIrql(SYNCH_LEVEL
);
986 Ret
= (*SynchronizeRoutine
)(Context
);
987 if (OldIrql
< SYNCH_LEVEL
)
989 KfLowerIrql(OldIrql
);
1005 VideoPortUnmapMemory(IN PVOID HwDeviceExtension
,
1006 IN PVOID VirtualAddress
,
1007 IN HANDLE ProcessHandle
)
1009 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1011 DPRINT("VideoPortFreeDeviceBase\n");
1013 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
1014 VIDEO_PORT_DEVICE_EXTENSION
,
1015 MiniPortDeviceExtension
);
1017 InternalUnmapMemory(DeviceExtension
, VirtualAddress
);
1019 return STATUS_SUCCESS
;
1028 VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension
,
1029 IN ULONG NumAccessRanges
,
1030 IN PVIDEO_ACCESS_RANGE AccessRanges
)
1032 DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
1038 * Reset display to blue screen
1040 static BOOLEAN STDCALL
1041 VideoPortResetDisplayParameters(Columns
, Rows
)
1043 if (NULL
== ResetDisplayParametersDeviceExtension
)
1047 if (NULL
== ResetDisplayParametersDeviceExtension
->HwResetHw
)
1051 if (!ResetDisplayParametersDeviceExtension
->HwResetHw(&ResetDisplayParametersDeviceExtension
->MiniPortDeviceExtension
,
1057 ResetDisplayParametersDeviceExtension
= NULL
;
1068 VideoPortAllocatePool(
1069 IN PVOID HwDeviceExtension
,
1070 IN VP_POOL_TYPE PoolType
,
1071 IN SIZE_T NumberOfBytes
,
1074 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
1084 IN PVOID HwDeviceExtension
,
1093 // Answer requests for Open calls
1099 // Standard dispatch arguments
1106 VidDispatchOpen(IN PDEVICE_OBJECT pDO
,
1109 PIO_STACK_LOCATION IrpStack
;
1110 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1112 DPRINT("VidDispatchOpen() called\n");
1114 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1116 if (! CsrssInitialized
)
1118 DPRINT("Referencing CSRSS\n");
1119 Csrss
= PsGetCurrentProcess();
1120 DPRINT("Csrss %p\n", Csrss
);
1124 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
) pDO
->DeviceExtension
;
1125 if (DeviceExtension
->HwInitialize(&DeviceExtension
->MiniPortDeviceExtension
))
1127 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1128 /* Storing the device extension pointer in a static variable is an ugly
1129 * hack. Unfortunately, we need it in VideoPortResetDisplayParameters
1130 * and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
1131 * parameter. On the bright side, the DISPLAY device is opened
1132 * exclusively, so there can be only one device extension active at
1133 * any point in time. */
1134 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
1135 HalAcquireDisplayOwnership(VideoPortResetDisplayParameters
);
1139 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1143 Irp
->IoStatus
.Information
= FILE_OPENED
;
1144 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1146 return STATUS_SUCCESS
;
1152 // Answer requests for Close calls
1158 // Standard dispatch arguments
1165 VidDispatchClose(IN PDEVICE_OBJECT pDO
,
1168 PIO_STACK_LOCATION IrpStack
;
1170 DPRINT("VidDispatchClose() called\n");
1172 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1174 if (! CsrssInitialized
)
1176 CsrssInitialized
= TRUE
;
1180 HalReleaseDisplayOwnership();
1183 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1184 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1186 return STATUS_SUCCESS
;
1189 // VidDispatchDeviceControl
1192 // Answer requests for device control calls
1198 // Standard dispatch arguments
1205 VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject
,
1208 PIO_STACK_LOCATION IrpStack
;
1209 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1210 PVIDEO_REQUEST_PACKET vrp
;
1212 DPRINT("VidDispatchDeviceControl\n");
1213 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1214 DeviceExtension
= DeviceObject
->DeviceExtension
;
1216 /* Translate the IRP to a VRP */
1217 vrp
= ExAllocatePool(NonPagedPool
, sizeof(VIDEO_REQUEST_PACKET
));
1220 return STATUS_NO_MEMORY
;
1222 vrp
->StatusBlock
= (PSTATUS_BLOCK
) &(Irp
->IoStatus
);
1223 vrp
->IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
1225 DPRINT("- IoControlCode: %x\n", vrp
->IoControlCode
);
1227 /* We're assuming METHOD_BUFFERED */
1228 vrp
->InputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
1229 vrp
->InputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
1230 vrp
->OutputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
1231 vrp
->OutputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1233 /* Call the Miniport Driver with the VRP */
1234 ((PDRIVER_STARTIO
)DeviceObject
->DriverObject
->DriverStartIo
)((PVOID
) &DeviceExtension
->MiniPortDeviceExtension
, (PIRP
)vrp
);
1239 DPRINT("- Returned status: %x\n", Irp
->IoStatus
.Status
);
1241 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1243 return STATUS_SUCCESS
;
1247 InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
1248 IN PHYSICAL_ADDRESS IoAddress
,
1249 IN ULONG NumberOfUchars
,
1251 OUT NTSTATUS
*Status
)
1253 PHYSICAL_ADDRESS TranslatedAddress
;
1254 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
1256 PVOID MappedAddress
;
1259 DPRINT("- IoAddress: %lx\n", IoAddress
.u
.LowPart
);
1260 DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars
);
1261 DPRINT("- InIoSpace: %x\n", InIoSpace
);
1262 InIoSpace
&= ~VIDEO_MEMORY_SPACE_DENSE
;
1263 if (0 != (InIoSpace
& VIDEO_MEMORY_SPACE_P6CACHE
))
1265 DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
1266 InIoSpace
&= ~VIDEO_MEMORY_SPACE_P6CACHE
;
1268 if (! IsListEmpty(&DeviceExtension
->AddressMappingListHead
))
1270 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
1271 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
1273 AddressMapping
= CONTAINING_RECORD(Entry
,
1274 VIDEO_PORT_ADDRESS_MAPPING
,
1276 if (IoAddress
.QuadPart
== AddressMapping
->IoAddress
.QuadPart
&&
1277 NumberOfUchars
<= AddressMapping
->NumberOfUchars
)
1279 AddressMapping
->MappingCount
++;
1282 *Status
= STATUS_SUCCESS
;
1284 return AddressMapping
->MappedAddress
;
1286 Entry
= Entry
->Flink
;
1290 AddressSpace
= (ULONG
)InIoSpace
;
1291 if (HalTranslateBusAddress(DeviceExtension
->AdapterInterfaceType
,
1292 DeviceExtension
->SystemIoBusNumber
,
1295 &TranslatedAddress
) == FALSE
)
1299 *Status
= STATUS_NO_MEMORY
;
1305 if (AddressSpace
!= 0)
1307 assert(0 == TranslatedAddress
.u
.HighPart
);
1310 *Status
= STATUS_SUCCESS
;
1312 return (PVOID
) TranslatedAddress
.u
.LowPart
;
1315 MappedAddress
= MmMapIoSpace(TranslatedAddress
,
1323 *Status
= STATUS_SUCCESS
;
1326 AddressMapping
= ExAllocatePoolWithTag(PagedPool
,
1327 sizeof(VIDEO_PORT_ADDRESS_MAPPING
),
1329 if (AddressMapping
== NULL
)
1330 return MappedAddress
;
1332 AddressMapping
->MappedAddress
= MappedAddress
;
1333 AddressMapping
->NumberOfUchars
= NumberOfUchars
;
1334 AddressMapping
->IoAddress
= IoAddress
;
1335 AddressMapping
->SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
1336 AddressMapping
->MappingCount
= 1;
1338 InsertHeadList(&DeviceExtension
->AddressMappingListHead
,
1339 &AddressMapping
->List
);
1341 return MappedAddress
;
1347 *Status
= STATUS_NO_MEMORY
;
1355 InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
1356 IN PVOID MappedAddress
)
1358 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
1361 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
1362 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
1364 AddressMapping
= CONTAINING_RECORD(Entry
,
1365 VIDEO_PORT_ADDRESS_MAPPING
,
1367 if (AddressMapping
->MappedAddress
== MappedAddress
)
1369 assert(0 <= AddressMapping
->MappingCount
);
1370 AddressMapping
->MappingCount
--;
1371 if (0 == AddressMapping
->MappingCount
)
1373 MmUnmapIoSpace(AddressMapping
->MappedAddress
,
1374 AddressMapping
->NumberOfUchars
);
1375 RemoveEntryList(Entry
);
1376 ExFreePool(AddressMapping
);
1382 Entry
= Entry
->Flink
;
1387 VideoPortDDCMonitorHelper(
1388 PVOID HwDeviceExtension
,
1389 /*PI2C_FNC_TABLE*/PVOID I2CFunctions
,
1391 ULONG EdidBufferSize
1394 DPRINT1("VideoPortDDCMonitorHelper() - Unimplemented.\n");
1403 VideoPortAllocateBuffer(IN PVOID HwDeviceExtension
,
1407 DPRINT("VideoPortAllocateBuffer()\n");
1409 Buffer
= ExAllocatePool(PagedPool
, Size
);
1410 return STATUS_SUCCESS
;
1419 VideoPortReleaseBuffer( IN PVOID HwDeviceExtension
,
1422 DPRINT("VideoPortReleaseBuffer()\n");
1430 VideoPortEnumerateChildren ( IN PVOID HwDeviceExtension
,
1433 DPRINT1("VideoPortEnumerateChildren(): Unimplemented.\n");
1434 return STATUS_SUCCESS
;
1439 VideoPortGetRomImage ( IN PVOID HwDeviceExtension
,
1444 DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
1445 HwDeviceExtension
, Length
);
1447 /* If the length is zero then free the existing buffer. */
1450 if (RomImageBuffer
!= NULL
)
1452 ExFreePool(RomImageBuffer
);
1453 RomImageBuffer
= NULL
;
1459 PEPROCESS CallingProcess
, PrevAttachedProcess
;
1462 The DDK says we shouldn't use the legacy C000 method but get the
1463 rom base address from the corresponding pci or acpi register but
1464 lets ignore that and use C000 anyway. CSRSS has already mapped the
1465 bios area into memory so we'll copy from there.
1467 CallingProcess
= PsGetCurrentProcess();
1468 if (CallingProcess
!= Csrss
)
1470 if (NULL
!= PsGetCurrentThread()->OldProcess
)
1472 PrevAttachedProcess
= CallingProcess
;
1477 PrevAttachedProcess
= NULL
;
1479 KeAttachProcess(Csrss
);
1485 Length
= min(Length
, 0x10000);
1486 if (RomImageBuffer
!= NULL
)
1488 ExFreePool(RomImageBuffer
);
1490 RomImageBuffer
= ExAllocatePool(PagedPool
, Length
);
1491 if (RomImageBuffer
== NULL
)
1495 RtlCopyMemory(RomImageBuffer
, (PUCHAR
)0xC0000, Length
);
1498 Detach from csrss if we attached.
1500 if (CallingProcess
!= Csrss
)
1503 if (NULL
!= PrevAttachedProcess
)
1505 KeAttachProcess(PrevAttachedProcess
);
1509 return(RomImageBuffer
);
1516 VideoPortDeferredRoutine ( IN PKDPC Dpc
,
1517 IN PVOID DeferredContext
,
1518 IN PVOID SystemArgument1
,
1519 IN PVOID SystemArgument2
)
1521 PVOID HwDeviceExtension
=
1522 ((PVIDEO_PORT_DEVICE_EXTENSION
)DeferredContext
)->MiniPortDeviceExtension
;
1523 ((PMINIPORT_DPC_ROUTINE
)SystemArgument1
)(HwDeviceExtension
, SystemArgument2
);
1528 VideoPortQueueDpc ( IN PVOID HwDeviceExtension
,
1529 IN PMINIPORT_DPC_ROUTINE CallbackRoutine
,
1532 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1534 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
1535 VIDEO_PORT_DEVICE_EXTENSION
,
1536 MiniPortDeviceExtension
);
1537 return KeInsertQueueDpc(&DeviceExtension
->DpcObject
,
1538 (PVOID
)CallbackRoutine
,
1544 VideoPortGetAssociatedDeviceExtension ( IN PVOID DeviceObject
)
1546 DPRINT1("VideoPortGetAssociatedDeviceExtension(): Unimplemented.\n");
1552 VideoPortAllocateCommonBuffer ( IN PVOID HwDeviceExtension
,
1553 IN PVP_DMA_ADAPTER VpDmaAdapter
,
1554 IN ULONG DesiredLength
,
1555 OUT PPHYSICAL_ADDRESS LogicalAddress
,
1556 IN BOOLEAN CacheEnabled
,
1559 return HalAllocateCommonBuffer((PADAPTER_OBJECT
)VpDmaAdapter
,
1567 VideoPortReleaseCommonBuffer ( IN PVOID HwDeviceExtension
,
1568 IN PVP_DMA_ADAPTER VpDmaAdapter
,
1570 IN PHYSICAL_ADDRESS LogicalAddress
,
1571 IN PVOID VirtualAddress
,
1572 IN BOOLEAN CacheEnabled
)
1574 HalFreeCommonBuffer((PADAPTER_OBJECT
)VpDmaAdapter
,
1583 VideoPortCreateSecondaryDisplay ( IN PVOID HwDeviceExtension
,
1584 IN OUT PVOID
*SecondaryDeviceExtension
,
1587 DPRINT1("VideoPortCreateSecondaryDisplay(): Unimplemented.\n");
1588 return STATUS_UNSUCCESSFUL
;
1593 VideoPortPutDmaAdapter ( IN PVOID HwDeviceExtension
,
1594 IN PVP_DMA_ADAPTER VpDmaAdapter
)
1596 DPRINT("VideoPortPutDmaAdapter(): Unimplemented.\n");
1601 VideoPortGetDmaAdapter ( IN PVOID HwDeviceExtension
,
1602 IN PVP_DEVICE_DESCRIPTION VpDeviceExtension
)
1604 DEVICE_DESCRIPTION DeviceDescription
;
1605 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1606 ULONG NumberOfMapRegisters
;
1607 PVP_DMA_ADAPTER Adapter
;
1609 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
1610 VIDEO_PORT_DEVICE_EXTENSION
,
1611 MiniPortDeviceExtension
);
1613 DPRINT("VideoPortGetDmaAdapter()\n");
1615 DeviceDescription
.Version
= DEVICE_DESCRIPTION_VERSION
;
1616 DeviceDescription
.Master
= TRUE
/* ?? */;
1617 DeviceDescription
.ScatterGather
= VpDeviceExtension
->ScatterGather
;
1618 DeviceDescription
.DemandMode
= FALSE
/* ?? */;
1619 DeviceDescription
.AutoInitialize
= FALSE
/* ?? */;
1620 DeviceDescription
.Dma32BitAddresses
= VpDeviceExtension
->Dma32BitAddresses
;
1621 DeviceDescription
.IgnoreCount
= FALSE
/* ?? */;
1622 DeviceDescription
.Reserved1
= FALSE
;
1623 DeviceDescription
.BusNumber
= DeviceExtension
->SystemIoBusNumber
;
1624 DeviceDescription
.DmaChannel
= 0 /* ?? */;
1625 DeviceDescription
.InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
1626 DeviceDescription
.DmaWidth
= Width8Bits
;
1627 DeviceDescription
.DmaSpeed
= Compatible
;
1628 DeviceDescription
.MaximumLength
= VpDeviceExtension
->MaximumLength
;
1629 DeviceDescription
.DmaPort
= 0;
1632 (PVP_DMA_ADAPTER
)HalGetAdapter(&DeviceDescription
, &NumberOfMapRegisters
);
1633 DPRINT("Adapter %X\n", Adapter
);
1643 VideoPortGetVersion ( IN PVOID HwDeviceExtension
,
1644 IN OUT PVPOSVERSIONINFO VpOsVersionInfo
)
1646 RTL_OSVERSIONINFOEXW Version
;
1648 Version
.dwOSVersionInfoSize
= sizeof(RTL_OSVERSIONINFOEXW
);
1649 if (VpOsVersionInfo
->Size
>= sizeof(VPOSVERSIONINFO
))
1652 if (NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW
)&Version
)))
1654 VpOsVersionInfo
->MajorVersion
= Version
.dwMajorVersion
;
1655 VpOsVersionInfo
->MinorVersion
= Version
.dwMinorVersion
;
1656 VpOsVersionInfo
->BuildNumber
= Version
.dwBuildNumber
;
1657 VpOsVersionInfo
->ServicePackMajor
= Version
.wServicePackMajor
;
1658 VpOsVersionInfo
->ServicePackMinor
= Version
.wServicePackMinor
;
1659 return STATUS_SUCCESS
;
1661 return STATUS_UNSUCCESSFUL
;
1663 VpOsVersionInfo
->MajorVersion
= 5;
1664 VpOsVersionInfo
->MinorVersion
= 0;
1665 VpOsVersionInfo
->BuildNumber
= 2195;
1666 VpOsVersionInfo
->ServicePackMajor
= 4;
1667 VpOsVersionInfo
->ServicePackMinor
= 0;
1668 return(STATUS_SUCCESS
);
1672 return ERROR_INVALID_PARAMETER
;
1677 VideoPortLockBuffer ( IN PVOID HwDeviceExtension
,
1678 IN PVOID BaseAddress
,
1680 IN VP_LOCK_OPERATION Operation
)
1682 DPRINT1("VideoPortLockBuffer(): Unimplemented.\n");
1688 VideoPortUnlockBuffer ( IN PVOID HwDeviceExtension
,
1691 DPRINT1("VideoPortUnlockBuffer(): Unimplemented.\n");
1696 VideoPortCreateEvent ( IN PVOID HwDeviceExtension
,
1702 (*Event
) = ExAllocatePoolWithTag(NonPagedPool
, sizeof(KEVENT
),
1704 if ((*Event
) == NULL
)
1706 return STATUS_NO_MEMORY
;
1708 if (EventFlag
& NOTIFICATION_EVENT
)
1710 Type
= NotificationEvent
;
1714 Type
= SynchronizationEvent
;
1716 KeInitializeEvent((PKEVENT
)*Event
, Type
, EventFlag
& INITIAL_EVENT_SIGNALED
);
1717 return STATUS_SUCCESS
;
1722 VideoPortDeleteEvent ( IN PVOID HwDeviceExtension
,
1726 return STATUS_SUCCESS
;
1731 VideoPortSetEvent ( IN PVOID HwDeviceExtension
,
1734 return KeSetEvent((PKEVENT
)Event
, IO_NO_INCREMENT
, FALSE
);
1739 VideoPortClearEvent ( IN PVOID HwDeviceExtension
,
1742 KeClearEvent((PKEVENT
)Event
);
1747 VideoPortWaitForSingleObject ( IN PVOID HwDeviceExtension
,
1749 IN PLARGE_INTEGER Timeout OPTIONAL
)
1751 return KeWaitForSingleObject(Object
,
1760 VideoPortCheckForDeviceExistence ( IN PVOID HwDeviceExtension
,
1763 IN UCHAR RevisionId
,
1764 IN USHORT SubVendorId
,
1765 IN USHORT SubSystemId
,
1768 DPRINT1("VideoPortCheckForDeviceExistence(): Unimplemented.\n");
1774 VideoPortRegisterBugcheckCallback ( IN PVOID HwDeviceExtension
,
1775 IN ULONG BugcheckCode
,
1777 IN ULONG BugcheckDataSize
)
1779 DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
1780 return STATUS_UNSUCCESSFUL
;
1785 VideoPortImageDirectoryEntryToData ( PVOID BaseAddress
,
1788 PIMAGE_NT_HEADERS NtHeader
;
1791 NtHeader
= RtlImageNtHeader (BaseAddress
);
1792 if (NtHeader
== NULL
)
1795 if (Directory
>= NtHeader
->OptionalHeader
.NumberOfRvaAndSizes
)
1798 Va
= NtHeader
->OptionalHeader
.DataDirectory
[Directory
].VirtualAddress
;
1802 return (PVOID
)(BaseAddress
+ Va
);
1806 VideoPortGetProcAddress(IN PVOID HwDeviceExtension
,
1807 IN PUCHAR FunctionName
)
1809 SYSTEM_LOAD_IMAGE GdiDriverInfo
;
1811 PIMAGE_EXPORT_DIRECTORY ExportDir
;
1818 DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName
);
1820 RtlInitUnicodeString(&GdiDriverInfo
.ModuleName
, L
"videoprt");
1821 Status
= ZwSetSystemInformation(SystemLoadImage
, &GdiDriverInfo
,
1822 sizeof(SYSTEM_LOAD_IMAGE
));
1823 if (!NT_SUCCESS(Status
))
1825 DPRINT("Couldn't get our own module handle?\n");
1829 BaseAddress
= GdiDriverInfo
.ModuleBase
;
1831 /* Get the pointer to the export directory */
1832 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)
1833 VideoPortImageDirectoryEntryToData (BaseAddress
,
1834 IMAGE_DIRECTORY_ENTRY_EXPORT
);
1836 /* search by name */
1837 AddressPtr
= (PULONG
)
1838 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfFunctions
);
1839 OrdinalPtr
= (PUSHORT
)
1840 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfNameOrdinals
);
1842 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfNames
);
1843 for (i
= 0; i
< ExportDir
->NumberOfNames
; i
++, NamePtr
++, OrdinalPtr
++)
1845 if (!_strnicmp(FunctionName
, (char*)(BaseAddress
+ *NamePtr
),
1846 strlen(FunctionName
)))
1848 return (PVOID
)((ULONG_PTR
)BaseAddress
+
1849 (ULONG_PTR
)AddressPtr
[*OrdinalPtr
]);
1852 DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName
);
1857 VideoPortQueryPerformanceCounter(
1858 IN PVOID HwDeviceExtension
,
1859 OUT PLONGLONG PerformanceFrequency OPTIONAL
)
1861 LARGE_INTEGER Result
;
1863 DPRINT("VideoPortQueryPerformanceCounter\n");
1864 Result
= KeQueryPerformanceCounter((PLARGE_INTEGER
)PerformanceFrequency
);
1865 return Result
.QuadPart
;