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.7 2004/03/06 08:39:06 jimtabor Exp $
26 BOOLEAN CsrssInitialized
= FALSE
;
27 PEPROCESS Csrss
= NULL
;
28 PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension
= NULL
;
30 // ------------------------------------------------------- Public Interface
35 // This function initializes the driver.
41 // IN PDRIVER_OBJECT DriverObject System allocated Driver Object
43 // IN PUNICODE_STRING RegistryPath Name of registry driver service
50 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
51 IN PUNICODE_STRING RegistryPath
)
53 DPRINT("DriverEntry()\n");
54 return(STATUS_SUCCESS
);
61 VideoPortDebugPrint(IN VIDEO_DEBUG_LEVEL DebugPrintLevel
,
62 IN PCHAR DebugMessage
, ...)
68 if (DebugPrintLevel > InternalDebugLevel)
71 va_start (ap
, DebugMessage
);
72 vsprintf (Buffer
, DebugMessage
, ap
);
84 VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension
,
85 IN PVOID MappedAddress
)
87 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
89 DPRINT("VideoPortFreeDeviceBase\n");
91 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
92 VIDEO_PORT_DEVICE_EXTENSION
,
93 MiniPortDeviceExtension
);
95 InternalUnmapMemory(DeviceExtension
, MappedAddress
);
104 VideoPortGetBusData(IN PVOID HwDeviceExtension
,
105 IN BUS_DATA_TYPE BusDataType
,
111 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
113 DPRINT("VideoPortGetBusData\n");
115 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
116 VIDEO_PORT_DEVICE_EXTENSION
,
117 MiniPortDeviceExtension
);
119 return HalGetBusDataByOffset(BusDataType
,
120 DeviceExtension
->SystemIoBusNumber
,
133 VideoPortGetCurrentIrql(VOID
)
135 DPRINT("VideoPortGetCurrentIrql\n");
136 return KeGetCurrentIrql();
145 VideoPortGetDeviceBase(IN PVOID HwDeviceExtension
,
146 IN PHYSICAL_ADDRESS IoAddress
,
147 IN ULONG NumberOfUchars
,
150 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
152 DPRINT("VideoPortGetDeviceBase\n");
154 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
155 VIDEO_PORT_DEVICE_EXTENSION
,
156 MiniPortDeviceExtension
);
158 return InternalMapMemory(DeviceExtension
, IoAddress
, NumberOfUchars
, InIoSpace
, NULL
);
167 VideoPortGetDeviceData(IN PVOID HwDeviceExtension
,
168 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType
,
169 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine
,
172 DPRINT("VideoPortGetDeviceData\n");
174 return STATUS_NOT_IMPLEMENTED
;
183 VideoPortGetAccessRanges(IN PVOID HwDeviceExtension
,
184 IN ULONG NumRequestedResources
,
185 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL
,
186 IN ULONG NumAccessRanges
,
187 IN PVIDEO_ACCESS_RANGE AccessRanges
,
192 PCI_SLOT_NUMBER PciSlotNumber
;
194 ULONG FunctionNumber
;
195 PCI_COMMON_CONFIG Config
;
196 PCM_RESOURCE_LIST AllocatedResources
;
199 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
200 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
201 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
203 DPRINT("VideoPortGetAccessRanges\n");
205 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
206 VIDEO_PORT_DEVICE_EXTENSION
,
207 MiniPortDeviceExtension
);
209 if (0 == NumRequestedResources
&& PCIBus
== DeviceExtension
->AdapterInterfaceType
)
211 if (DeviceId
!= NULL
&& VendorId
!= NULL
)
213 DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n", (int)*((USHORT
*) VendorId
),
214 (int)*((USHORT
*) DeviceId
));
217 PciSlotNumber
.u
.AsULONG
= *Slot
;
218 for (FunctionNumber
= 0; ! FoundDevice
&& FunctionNumber
< 8; FunctionNumber
++)
220 PciSlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
221 if (sizeof(PCI_COMMON_CONFIG
) ==
222 HalGetBusDataByOffset(PCIConfiguration
, DeviceExtension
->SystemIoBusNumber
,
223 PciSlotNumber
.u
.AsULONG
,&Config
, 0,
224 sizeof(PCI_COMMON_CONFIG
)))
226 if (DeviceId
!= NULL
&& VendorId
!= NULL
)
228 DPRINT("Slot 0x%02x (Device %d Function %d) VendorId 0x%04x DeviceId 0x%04x\n",
229 PciSlotNumber
.u
.AsULONG
, PciSlotNumber
.u
.bits
.DeviceNumber
,
230 PciSlotNumber
.u
.bits
.FunctionNumber
, Config
.VendorID
, Config
.DeviceID
);
233 FoundDevice
= (VendorId
== NULL
|| Config
.VendorID
== *((USHORT
*) VendorId
)) &&
234 (DeviceId
== NULL
|| Config
.DeviceID
== *((USHORT
*) DeviceId
));
239 return STATUS_UNSUCCESSFUL
;
241 Status
= HalAssignSlotResources(NULL
, NULL
, NULL
, NULL
,
242 DeviceExtension
->AdapterInterfaceType
,
243 DeviceExtension
->SystemIoBusNumber
,
244 PciSlotNumber
.u
.AsULONG
, &AllocatedResources
);
245 if (! NT_SUCCESS(Status
))
250 for (FullList
= AllocatedResources
->List
;
251 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
254 assert(FullList
->InterfaceType
== PCIBus
&&
255 FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
&&
256 1 == FullList
->PartialResourceList
.Version
&&
257 1 == FullList
->PartialResourceList
.Revision
);
258 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
259 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
262 if ((CmResourceTypeMemory
== Descriptor
->Type
263 || CmResourceTypePort
== Descriptor
->Type
)
264 && NumAccessRanges
<= AssignedCount
)
266 DPRINT1("Too many access ranges found\n");
267 ExFreePool(AllocatedResources
);
268 return STATUS_UNSUCCESSFUL
;
270 if (CmResourceTypeMemory
== Descriptor
->Type
)
272 if (NumAccessRanges
<= AssignedCount
)
274 DPRINT1("Too many access ranges found\n");
275 ExFreePool(AllocatedResources
);
276 return STATUS_UNSUCCESSFUL
;
278 DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
279 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
280 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Memory
.Start
;
281 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Memory
.Length
;
282 AccessRanges
[AssignedCount
].RangeInIoSpace
= 0;
283 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
284 AccessRanges
[AssignedCount
].RangeShareable
=
285 (CmResourceShareShared
== Descriptor
->ShareDisposition
);
288 else if (CmResourceTypePort
== Descriptor
->Type
)
290 DPRINT("Port range starting at 0x%04x length %d\n",
291 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
292 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Port
.Start
;
293 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Port
.Length
;
294 AccessRanges
[AssignedCount
].RangeInIoSpace
= 1;
295 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
296 AccessRanges
[AssignedCount
].RangeShareable
= 0;
299 else if (CmResourceTypeInterrupt
== Descriptor
->Type
)
301 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
302 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
306 ExFreePool(AllocatedResources
);
313 return STATUS_SUCCESS
;
316 typedef struct QueryRegistryCallbackContext
318 PVOID HwDeviceExtension
;
320 PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine
;
321 } QUERY_REGISTRY_CALLBACK_CONTEXT
, *PQUERY_REGISTRY_CALLBACK_CONTEXT
;
323 static NTSTATUS STDCALL
324 QueryRegistryCallback(IN PWSTR ValueName
,
327 IN ULONG ValueLength
,
329 IN PVOID EntryContext
)
331 PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext
= (PQUERY_REGISTRY_CALLBACK_CONTEXT
) Context
;
333 DPRINT("Found registry value for name %S: type %d, length %d\n",
334 ValueName
, ValueType
, ValueLength
);
335 return (*(CallbackContext
->HwGetRegistryRoutine
))(CallbackContext
->HwDeviceExtension
,
336 CallbackContext
->HwContext
,
347 VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension
,
348 IN PWSTR ParameterName
,
349 IN UCHAR IsParameterFileName
,
350 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine
,
353 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
354 QUERY_REGISTRY_CALLBACK_CONTEXT Context
;
355 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
357 DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName
);
359 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
360 VIDEO_PORT_DEVICE_EXTENSION
,
361 MiniPortDeviceExtension
);
363 if (IsParameterFileName
)
368 DPRINT("ParameterName %S\n", ParameterName
);
370 Context
.HwDeviceExtension
= HwDeviceExtension
;
371 Context
.HwContext
= HwContext
;
372 Context
.HwGetRegistryRoutine
= GetRegistryRoutine
;
374 QueryTable
[0].QueryRoutine
= QueryRegistryCallback
;
375 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
;
376 QueryTable
[0].Name
= ParameterName
;
377 QueryTable
[0].EntryContext
= NULL
;
378 QueryTable
[0].DefaultType
= REG_NONE
;
379 QueryTable
[0].DefaultData
= NULL
;
380 QueryTable
[0].DefaultLength
= 0;
382 QueryTable
[1].QueryRoutine
= NULL
;
383 QueryTable
[1].Name
= NULL
;
385 return NT_SUCCESS(RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
386 DeviceExtension
->RegistryPath
.Buffer
,
387 QueryTable
, &Context
, NULL
))
388 ? ERROR_SUCCESS
: ERROR_INVALID_PARAMETER
;
397 VideoPortGetVgaStatus(IN PVOID HwDeviceExtension
,
398 OUT PULONG VgaStatus
)
400 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
402 DPRINT1("VideoPortGetVgaStatus = %S \n", VgaStatus
);
404 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
405 VIDEO_PORT_DEVICE_EXTENSION
,
406 MiniPortDeviceExtension
);
408 if(KeGetCurrentIrql() == PASSIVE_LEVEL
)
410 DPRINT1("VideoPortGetVgaStatus1 = %S \n", VgaStatus
);
412 if ( PCIBus
== DeviceExtension
->AdapterInterfaceType
)
415 VgaStatus 0 == VGA not enabled, 1 == VGA enabled.
417 DPRINT1("VideoPortGetVgaStatus2 = %S \n", VgaStatus
);
419 /* Assumed for now */
421 VgaStatus
= (PULONG
) 1;
423 return STATUS_SUCCESS
;
426 DPRINT1("VideoPortGetVgaStatus3 = %S \n", VgaStatus
);
428 return ERROR_INVALID_FUNCTION
;
432 VPInterruptRoutine(IN
struct _KINTERRUPT
*Interrupt
,
433 IN PVOID ServiceContext
)
435 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
437 DeviceExtension
= ServiceContext
;
438 assert(NULL
!= DeviceExtension
->HwInterrupt
);
440 return DeviceExtension
->HwInterrupt(&DeviceExtension
->MiniPortDeviceExtension
);
444 VPTimerRoutine(IN PDEVICE_OBJECT DeviceObject
,
447 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
449 DeviceExtension
= Context
;
450 assert(DeviceExtension
== DeviceObject
->DeviceExtension
451 && NULL
!= DeviceExtension
->HwTimer
);
453 DeviceExtension
->HwTimer(&DeviceExtension
->MiniPortDeviceExtension
);
460 VideoPortInitialize(IN PVOID Context1
,
462 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData
,
465 PUNICODE_STRING RegistryPath
;
467 WCHAR DeviceBuffer
[20];
468 WCHAR SymlinkBuffer
[20];
469 WCHAR DeviceVideoBuffer
[20];
471 PDRIVER_OBJECT MPDriverObject
= (PDRIVER_OBJECT
) Context1
;
472 PDEVICE_OBJECT MPDeviceObject
;
473 VIDEO_PORT_CONFIG_INFO ConfigInfo
;
474 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
476 UNICODE_STRING DeviceName
;
477 UNICODE_STRING SymlinkName
;
482 ULONG InterruptVector
;
483 OBJECT_ATTRIBUTES Obj
;
486 DPRINT("VideoPortInitialize\n");
488 RegistryPath
= (PUNICODE_STRING
) Context2
;
490 /* Build Dispatch table from passed data */
491 MPDriverObject
->DriverStartIo
= (PDRIVER_STARTIO
) HwInitializationData
->HwStartIO
;
493 /* Find the first free device number */
494 for (DisplayNumber
= 0;;)
496 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DisplayNumber
+ 1);
497 RtlInitUnicodeString(&SymlinkName
, SymlinkBuffer
);
498 InitializeObjectAttributes(&Obj
, &SymlinkName
, 0, NULL
, NULL
);
499 Status
= ZwOpenSymbolicLinkObject(&ObjHandle
, GENERIC_READ
, &Obj
);
500 if (NT_SUCCESS(Status
))
506 else if (Status
== STATUS_NOT_FOUND
|| Status
== STATUS_UNSUCCESSFUL
)
516 DPRINT("- DisplayNumber: %d\n", DisplayNumber
);
522 /* Create a unicode device name. */
523 swprintf(DeviceBuffer
, L
"\\Device\\Video%lu", DisplayNumber
);
524 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
526 /* Create the device. */
527 Status
= IoCreateDevice(
529 HwInitializationData
->HwDeviceExtensionSize
+
530 sizeof(VIDEO_PORT_DEVICE_EXTENSION
),
536 if (!NT_SUCCESS(Status
))
538 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status
);
542 MPDriverObject
->DeviceObject
= MPDeviceObject
;
544 /* Initialize the miniport drivers dispatch table */
545 MPDriverObject
->MajorFunction
[IRP_MJ_CREATE
] = VidDispatchOpen
;
546 MPDriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = VidDispatchClose
;
547 MPDriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = VidDispatchDeviceControl
;
549 /* Initialize our device extension */
551 (PVIDEO_PORT_DEVICE_EXTENSION
) MPDeviceObject
->DeviceExtension
;
552 DeviceExtension
->DeviceObject
= MPDeviceObject
;
553 DeviceExtension
->HwInitialize
= HwInitializationData
->HwInitialize
;
554 DeviceExtension
->HwResetHw
= HwInitializationData
->HwResetHw
;
555 DeviceExtension
->AdapterInterfaceType
= HwInitializationData
->AdapterInterfaceType
;
556 DeviceExtension
->SystemIoBusNumber
= 0;
557 MaxLen
= (wcslen(RegistryPath
->Buffer
) + 10) * sizeof(WCHAR
);
558 DeviceExtension
->RegistryPath
.MaximumLength
= MaxLen
;
559 DeviceExtension
->RegistryPath
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
562 swprintf(DeviceExtension
->RegistryPath
.Buffer
, L
"%s\\Device0",
563 RegistryPath
->Buffer
);
564 DeviceExtension
->RegistryPath
.Length
= wcslen(DeviceExtension
->RegistryPath
.Buffer
) *
567 MaxBus
= (DeviceExtension
->AdapterInterfaceType
== PCIBus
) ? 8 : 1;
568 DPRINT("MaxBus: %lu\n", MaxBus
);
569 InitializeListHead(&DeviceExtension
->AddressMappingListHead
);
571 /* Set the buffering strategy here... */
572 /* If you change this, remember to change VidDispatchDeviceControl too */
573 MPDeviceObject
->Flags
|= DO_BUFFERED_IO
;
577 RtlZeroMemory(&DeviceExtension
->MiniPortDeviceExtension
,
578 HwInitializationData
->HwDeviceExtensionSize
);
579 DPRINT("Searching on bus %d\n", DeviceExtension
->SystemIoBusNumber
);
580 /* Setup configuration info */
581 RtlZeroMemory(&ConfigInfo
, sizeof(VIDEO_PORT_CONFIG_INFO
));
582 ConfigInfo
.Length
= sizeof(VIDEO_PORT_CONFIG_INFO
);
583 ConfigInfo
.AdapterInterfaceType
= DeviceExtension
->AdapterInterfaceType
;
584 ConfigInfo
.SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
585 ConfigInfo
.InterruptMode
= (PCIBus
== DeviceExtension
->AdapterInterfaceType
) ?
586 LevelSensitive
: Latched
;
588 /* Call HwFindAdapter entry point */
589 /* FIXME: Need to figure out what string to pass as param 3 */
590 Status
= HwInitializationData
->HwFindAdapter(&DeviceExtension
->MiniPortDeviceExtension
,
595 if (NO_ERROR
!= Status
)
597 DPRINT("HwFindAdapter call failed with error %d\n", Status
);
598 DeviceExtension
->SystemIoBusNumber
++;
601 while (NO_ERROR
!= Status
&& DeviceExtension
->SystemIoBusNumber
< MaxBus
);
603 if (NO_ERROR
!= Status
)
605 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
606 IoDeleteDevice(MPDeviceObject
);
610 DPRINT("Found adapter\n");
612 /* create symbolic link "\??\DISPLAYx" */
613 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DisplayNumber
+ 1);
614 RtlInitUnicodeString (&SymlinkName
,
616 IoCreateSymbolicLink (&SymlinkName
,
619 /* Add entry to DEVICEMAP\VIDEO key in registry */
620 swprintf(DeviceVideoBuffer
, L
"\\Device\\Video%d", DisplayNumber
);
621 RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP
,
625 DeviceExtension
->RegistryPath
.Buffer
,
626 DeviceExtension
->RegistryPath
.Length
+ sizeof(WCHAR
));
628 /* FIXME: Allocate hardware resources for device */
630 /* Allocate interrupt for device */
631 DeviceExtension
->HwInterrupt
= HwInitializationData
->HwInterrupt
;
632 if (0 == ConfigInfo
.BusInterruptVector
)
634 ConfigInfo
.BusInterruptVector
= DeviceExtension
->InterruptVector
;
636 if (0 == ConfigInfo
.BusInterruptLevel
)
638 ConfigInfo
.BusInterruptLevel
= DeviceExtension
->InterruptLevel
;
640 if (NULL
!= HwInitializationData
->HwInterrupt
)
643 HalGetInterruptVector(ConfigInfo
.AdapterInterfaceType
,
644 ConfigInfo
.SystemIoBusNumber
,
645 ConfigInfo
.BusInterruptLevel
,
646 ConfigInfo
.BusInterruptVector
,
649 if (0 == InterruptVector
)
651 DPRINT1("HalGetInterruptVector failed\n");
652 IoDeleteDevice(MPDeviceObject
);
654 return STATUS_INSUFFICIENT_RESOURCES
;
656 KeInitializeSpinLock(&DeviceExtension
->InterruptSpinLock
);
657 Status
= IoConnectInterrupt(&DeviceExtension
->InterruptObject
,
660 &DeviceExtension
->InterruptSpinLock
,
664 ConfigInfo
.InterruptMode
,
668 if (!NT_SUCCESS(Status
))
670 DPRINT1("IoConnectInterrupt failed with status 0x%08x\n", Status
);
671 IoDeleteDevice(MPDeviceObject
);
680 DeviceExtension
->HwTimer
= HwInitializationData
->HwTimer
;
681 if (HwInitializationData
->HwTimer
!= NULL
)
683 DPRINT("Initializing timer\n");
684 Status
= IoInitializeTimer(MPDeviceObject
,
687 if (!NT_SUCCESS(Status
))
689 DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status
);
691 if (HwInitializationData
->HwInterrupt
!= NULL
)
693 IoDisconnectInterrupt(DeviceExtension
->InterruptObject
);
695 IoDeleteDevice(MPDeviceObject
);
701 return STATUS_SUCCESS
;
709 VideoPortLogError(IN PVOID HwDeviceExtension
,
710 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL
,
711 IN VP_STATUS ErrorCode
,
714 DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
715 ErrorCode
, ErrorCode
, UniqueId
, UniqueId
);
718 DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp
->IoControlCode
, Vrp
->IoControlCode
);
728 VideoPortMapBankedMemory(IN PVOID HwDeviceExtension
,
729 IN PHYSICAL_ADDRESS PhysicalAddress
,
732 OUT PVOID
*VirtualAddress
,
734 IN UCHAR ReadWriteBank
,
735 IN PBANKED_SECTION_ROUTINE BankRoutine
,
738 DPRINT("VideoPortMapBankedMemory\n");
740 return STATUS_NOT_IMPLEMENTED
;
749 VideoPortMapMemory(IN PVOID HwDeviceExtension
,
750 IN PHYSICAL_ADDRESS PhysicalAddress
,
753 OUT PVOID
*VirtualAddress
)
755 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
758 DPRINT("VideoPortMapMemory\n");
760 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
761 VIDEO_PORT_DEVICE_EXTENSION
,
762 MiniPortDeviceExtension
);
763 *VirtualAddress
= InternalMapMemory(DeviceExtension
, PhysicalAddress
,
764 *Length
, *InIoSpace
, &Status
);
775 VideoPortScanRom(IN PVOID HwDeviceExtension
,
782 PUCHAR SearchLocation
;
784 DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase
, RomLength
, String
);
786 StringLength
= strlen(String
);
788 SearchLocation
= RomBase
;
789 for (SearchLocation
= RomBase
;
790 ! Found
&& SearchLocation
< RomBase
+ RomLength
- StringLength
;
793 Found
= (RtlCompareMemory(SearchLocation
, String
, StringLength
) == StringLength
);
796 DPRINT("Match found at %p\n", SearchLocation
);
809 VideoPortSetBusData(IN PVOID HwDeviceExtension
,
810 IN BUS_DATA_TYPE BusDataType
,
816 DPRINT("VideoPortSetBusData\n");
817 return HalSetBusDataByOffset(BusDataType
,
831 VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension
,
834 IN ULONG ValueLength
)
836 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
838 DPRINT("VideoSetRegistryParameters\n");
840 assert_irql(PASSIVE_LEVEL
);
842 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
843 VIDEO_PORT_DEVICE_EXTENSION
,
844 MiniPortDeviceExtension
);
845 return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
846 DeviceExtension
->RegistryPath
.Buffer
,
859 VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension
,
860 IN ULONG NumAccessRanges
,
861 IN PVIDEO_ACCESS_RANGE AccessRange
)
863 DPRINT("VideoPortSetTrappedEmulatorPorts\n");
865 return STATUS_NOT_IMPLEMENTED
;
874 VideoPortStartTimer(IN PVOID HwDeviceExtension
)
876 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
878 DPRINT("VideoPortStartTimer\n");
880 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
881 VIDEO_PORT_DEVICE_EXTENSION
,
882 MiniPortDeviceExtension
);
883 IoStartTimer(DeviceExtension
->DeviceObject
);
892 VideoPortStopTimer(IN PVOID HwDeviceExtension
)
894 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
896 DPRINT("VideoPortStopTimer\n");
898 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
899 VIDEO_PORT_DEVICE_EXTENSION
,
900 MiniPortDeviceExtension
);
901 IoStopTimer(DeviceExtension
->DeviceObject
);
910 VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension
,
911 IN VIDEO_SYNCHRONIZE_PRIORITY Priority
,
912 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine
,
916 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
919 DPRINT("VideoPortSynchronizeExecution\n");
924 Ret
= (*SynchronizeRoutine
)(Context
);
926 case VpMediumPriority
:
927 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
928 VIDEO_PORT_DEVICE_EXTENSION
,
929 MiniPortDeviceExtension
);
930 if (NULL
== DeviceExtension
->InterruptObject
)
932 Ret
= (*SynchronizeRoutine
)(Context
);
936 Ret
= KeSynchronizeExecution(DeviceExtension
->InterruptObject
,
942 OldIrql
= KeGetCurrentIrql();
943 if (OldIrql
< SYNCH_LEVEL
)
945 OldIrql
= KfRaiseIrql(SYNCH_LEVEL
);
947 Ret
= (*SynchronizeRoutine
)(Context
);
948 if (OldIrql
< SYNCH_LEVEL
)
950 KfLowerIrql(OldIrql
);
966 VideoPortUnmapMemory(IN PVOID HwDeviceExtension
,
967 IN PVOID VirtualAddress
,
968 IN HANDLE ProcessHandle
)
970 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
972 DPRINT("VideoPortFreeDeviceBase\n");
974 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
975 VIDEO_PORT_DEVICE_EXTENSION
,
976 MiniPortDeviceExtension
);
978 InternalUnmapMemory(DeviceExtension
, VirtualAddress
);
980 return STATUS_SUCCESS
;
989 VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension
,
990 IN ULONG NumAccessRanges
,
991 IN PVIDEO_ACCESS_RANGE AccessRanges
)
993 DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
999 * Reset display to blue screen
1001 static BOOLEAN STDCALL
1002 VideoPortResetDisplayParameters(Columns
, Rows
)
1004 if (NULL
== ResetDisplayParametersDeviceExtension
)
1008 if (NULL
== ResetDisplayParametersDeviceExtension
->HwResetHw
)
1012 if (!ResetDisplayParametersDeviceExtension
->HwResetHw(&ResetDisplayParametersDeviceExtension
->MiniPortDeviceExtension
,
1018 ResetDisplayParametersDeviceExtension
= NULL
;
1029 VideoPortAllocatePool(
1030 IN PVOID HwDeviceExtension
,
1031 IN VP_POOL_TYPE PoolType
,
1032 IN SIZE_T NumberOfBytes
,
1035 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
1045 IN PVOID HwDeviceExtension
,
1054 // Answer requests for Open calls
1060 // Standard dispatch arguments
1067 VidDispatchOpen(IN PDEVICE_OBJECT pDO
,
1070 PIO_STACK_LOCATION IrpStack
;
1071 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1073 DPRINT("VidDispatchOpen() called\n");
1075 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1077 if (! CsrssInitialized
)
1079 DPRINT("Referencing CSRSS\n");
1080 Csrss
= PsGetCurrentProcess();
1081 DPRINT("Csrss %p\n", Csrss
);
1085 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
) pDO
->DeviceExtension
;
1086 if (DeviceExtension
->HwInitialize(&DeviceExtension
->MiniPortDeviceExtension
))
1088 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1089 /* Storing the device extension pointer in a static variable is an ugly
1090 * hack. Unfortunately, we need it in VideoPortResetDisplayParameters
1091 * and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
1092 * parameter. On the bright side, the DISPLAY device is opened
1093 * exclusively, so there can be only one device extension active at
1094 * any point in time. */
1095 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
1096 HalAcquireDisplayOwnership(VideoPortResetDisplayParameters
);
1100 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1104 Irp
->IoStatus
.Information
= FILE_OPENED
;
1105 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1107 return STATUS_SUCCESS
;
1113 // Answer requests for Close calls
1119 // Standard dispatch arguments
1126 VidDispatchClose(IN PDEVICE_OBJECT pDO
,
1129 PIO_STACK_LOCATION IrpStack
;
1131 DPRINT("VidDispatchClose() called\n");
1133 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1135 if (! CsrssInitialized
)
1137 CsrssInitialized
= TRUE
;
1141 HalReleaseDisplayOwnership();
1144 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1145 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1147 return STATUS_SUCCESS
;
1150 // VidDispatchDeviceControl
1153 // Answer requests for device control calls
1159 // Standard dispatch arguments
1166 VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject
,
1169 PIO_STACK_LOCATION IrpStack
;
1170 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1171 PVIDEO_REQUEST_PACKET vrp
;
1173 DPRINT("VidDispatchDeviceControl\n");
1174 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1175 DeviceExtension
= DeviceObject
->DeviceExtension
;
1177 /* Translate the IRP to a VRP */
1178 vrp
= ExAllocatePool(NonPagedPool
, sizeof(VIDEO_REQUEST_PACKET
));
1181 return STATUS_NO_MEMORY
;
1183 vrp
->StatusBlock
= (PSTATUS_BLOCK
) &(Irp
->IoStatus
);
1184 vrp
->IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
1186 DPRINT("- IoControlCode: %x\n", vrp
->IoControlCode
);
1188 /* We're assuming METHOD_BUFFERED */
1189 vrp
->InputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
1190 vrp
->InputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
1191 vrp
->OutputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
1192 vrp
->OutputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1194 /* Call the Miniport Driver with the VRP */
1195 ((PDRIVER_STARTIO
)DeviceObject
->DriverObject
->DriverStartIo
)((PVOID
) &DeviceExtension
->MiniPortDeviceExtension
, (PIRP
)vrp
);
1200 DPRINT("- Returned status: %x\n", Irp
->IoStatus
.Status
);
1202 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1204 return STATUS_SUCCESS
;
1208 InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
1209 IN PHYSICAL_ADDRESS IoAddress
,
1210 IN ULONG NumberOfUchars
,
1212 OUT NTSTATUS
*Status
)
1214 PHYSICAL_ADDRESS TranslatedAddress
;
1215 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
1217 PVOID MappedAddress
;
1220 if (0 != (InIoSpace
& VIDEO_MEMORY_SPACE_P6CACHE
))
1222 DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
1223 InIoSpace
&= ~VIDEO_MEMORY_SPACE_P6CACHE
;
1225 if (! IsListEmpty(&DeviceExtension
->AddressMappingListHead
))
1227 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
1228 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
1230 AddressMapping
= CONTAINING_RECORD(Entry
,
1231 VIDEO_PORT_ADDRESS_MAPPING
,
1233 if (IoAddress
.QuadPart
== AddressMapping
->IoAddress
.QuadPart
&&
1234 NumberOfUchars
<= AddressMapping
->NumberOfUchars
)
1236 AddressMapping
->MappingCount
++;
1239 *Status
= STATUS_SUCCESS
;
1241 return AddressMapping
->MappedAddress
;
1243 Entry
= Entry
->Flink
;
1247 AddressSpace
= (ULONG
)InIoSpace
;
1248 if (HalTranslateBusAddress(DeviceExtension
->AdapterInterfaceType
,
1249 DeviceExtension
->SystemIoBusNumber
,
1252 &TranslatedAddress
) == FALSE
)
1256 *Status
= STATUS_NO_MEMORY
;
1262 if (AddressSpace
!= 0)
1264 assert(0 == TranslatedAddress
.u
.HighPart
);
1267 *Status
= STATUS_SUCCESS
;
1269 return (PVOID
) TranslatedAddress
.u
.LowPart
;
1272 MappedAddress
= MmMapIoSpace(TranslatedAddress
,
1280 *Status
= STATUS_SUCCESS
;
1283 AddressMapping
= ExAllocatePoolWithTag(PagedPool
,
1284 sizeof(VIDEO_PORT_ADDRESS_MAPPING
),
1286 if (AddressMapping
== NULL
)
1287 return MappedAddress
;
1289 AddressMapping
->MappedAddress
= MappedAddress
;
1290 AddressMapping
->NumberOfUchars
= NumberOfUchars
;
1291 AddressMapping
->IoAddress
= IoAddress
;
1292 AddressMapping
->SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
1293 AddressMapping
->MappingCount
= 1;
1295 InsertHeadList(&DeviceExtension
->AddressMappingListHead
,
1296 &AddressMapping
->List
);
1298 return MappedAddress
;
1304 *Status
= STATUS_NO_MEMORY
;
1312 InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
1313 IN PVOID MappedAddress
)
1315 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
1318 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
1319 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
1321 AddressMapping
= CONTAINING_RECORD(Entry
,
1322 VIDEO_PORT_ADDRESS_MAPPING
,
1324 if (AddressMapping
->MappedAddress
== MappedAddress
)
1326 assert(0 <= AddressMapping
->MappingCount
);
1327 AddressMapping
->MappingCount
--;
1328 if (0 == AddressMapping
->MappingCount
)
1330 MmUnmapIoSpace(AddressMapping
->MappedAddress
,
1331 AddressMapping
->NumberOfUchars
);
1332 RemoveEntryList(Entry
);
1333 ExFreePool(AddressMapping
);
1339 Entry
= Entry
->Flink
;
1344 VideoPortDDCMonitorHelper(
1345 PVOID HwDeviceExtension
,
1346 /*PI2C_FNC_TABLE*/PVOID I2CFunctions
,
1348 ULONG EdidBufferSize
1357 VideoPortAllocateBuffer(IN PVOID HwDeviceExtension
,
1361 DPRINT("VideoPortAllocateBuffer\n");
1363 Buffer
= ExAllocatePool (PagedPool
, Size
) ;
1364 return STATUS_SUCCESS
;
1370 VideoPortReleaseBuffer( IN PVOID HwDeviceExtension
,
1373 DPRINT("VideoPortReleaseBuffer\n");