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.4 2004/02/25 05:38:33 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 VideoPortDisableInterrupt(IN PVOID HwDeviceExtension
)
86 DPRINT("VideoPortDisableInterrupt\n");
88 return STATUS_NOT_IMPLEMENTED
;
97 VideoPortEnableInterrupt(IN PVOID HwDeviceExtension
)
99 DPRINT("VideoPortEnableInterrupt\n");
101 return STATUS_NOT_IMPLEMENTED
;
110 VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension
,
111 IN PVOID MappedAddress
)
113 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
115 DPRINT("VideoPortFreeDeviceBase\n");
117 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
118 VIDEO_PORT_DEVICE_EXTENSION
,
119 MiniPortDeviceExtension
);
121 InternalUnmapMemory(DeviceExtension
, MappedAddress
);
130 VideoPortGetBusData(IN PVOID HwDeviceExtension
,
131 IN BUS_DATA_TYPE BusDataType
,
137 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
139 DPRINT("VideoPortGetBusData\n");
141 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
142 VIDEO_PORT_DEVICE_EXTENSION
,
143 MiniPortDeviceExtension
);
145 return HalGetBusDataByOffset(BusDataType
,
146 DeviceExtension
->SystemIoBusNumber
,
159 VideoPortGetCurrentIrql(VOID
)
161 DPRINT("VideoPortGetCurrentIrql\n");
162 return KeGetCurrentIrql();
171 VideoPortGetDeviceBase(IN PVOID HwDeviceExtension
,
172 IN PHYSICAL_ADDRESS IoAddress
,
173 IN ULONG NumberOfUchars
,
176 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
178 DPRINT("VideoPortGetDeviceBase\n");
180 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
181 VIDEO_PORT_DEVICE_EXTENSION
,
182 MiniPortDeviceExtension
);
184 return InternalMapMemory(DeviceExtension
, IoAddress
, NumberOfUchars
, InIoSpace
);
193 VideoPortGetDeviceData(IN PVOID HwDeviceExtension
,
194 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType
,
195 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine
,
198 DPRINT("VideoPortGetDeviceData\n");
200 return STATUS_NOT_IMPLEMENTED
;
209 VideoPortGetAccessRanges(IN PVOID HwDeviceExtension
,
210 IN ULONG NumRequestedResources
,
211 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL
,
212 IN ULONG NumAccessRanges
,
213 IN PVIDEO_ACCESS_RANGE AccessRanges
,
218 PCI_SLOT_NUMBER PciSlotNumber
;
220 ULONG FunctionNumber
;
221 PCI_COMMON_CONFIG Config
;
222 PCM_RESOURCE_LIST AllocatedResources
;
225 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
226 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
227 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
229 DPRINT("VideoPortGetAccessRanges\n");
231 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
232 VIDEO_PORT_DEVICE_EXTENSION
,
233 MiniPortDeviceExtension
);
235 if (0 == NumRequestedResources
&& PCIBus
== DeviceExtension
->AdapterInterfaceType
)
237 DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n", (int)*((USHORT
*) VendorId
),
238 (int)*((USHORT
*) DeviceId
));
240 PciSlotNumber
.u
.AsULONG
= *Slot
;
241 for (FunctionNumber
= 0; ! FoundDevice
&& FunctionNumber
< 8; FunctionNumber
++)
243 PciSlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
244 if (sizeof(PCI_COMMON_CONFIG
) ==
245 HalGetBusDataByOffset(PCIConfiguration
, DeviceExtension
->SystemIoBusNumber
,
246 PciSlotNumber
.u
.AsULONG
,&Config
, 0,
247 sizeof(PCI_COMMON_CONFIG
)))
249 DPRINT("Slot 0x%02x (Device %d Function %d) VendorId 0x%04x DeviceId 0x%04x\n",
250 PciSlotNumber
.u
.AsULONG
, PciSlotNumber
.u
.bits
.DeviceNumber
,
251 PciSlotNumber
.u
.bits
.FunctionNumber
, Config
.VendorID
, Config
.DeviceID
);
252 FoundDevice
= (Config
.VendorID
== *((USHORT
*) VendorId
) &&
253 Config
.DeviceID
== *((USHORT
*) DeviceId
));
258 return STATUS_UNSUCCESSFUL
;
260 Status
= HalAssignSlotResources(NULL
, NULL
, NULL
, NULL
,
261 DeviceExtension
->AdapterInterfaceType
,
262 DeviceExtension
->SystemIoBusNumber
,
263 PciSlotNumber
.u
.AsULONG
, &AllocatedResources
);
264 if (! NT_SUCCESS(Status
))
269 for (FullList
= AllocatedResources
->List
;
270 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
273 assert(FullList
->InterfaceType
== PCIBus
&&
274 FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
&&
275 1 == FullList
->PartialResourceList
.Version
&&
276 1 == FullList
->PartialResourceList
.Revision
);
277 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
278 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
281 if ((CmResourceTypeMemory
== Descriptor
->Type
282 || CmResourceTypePort
== Descriptor
->Type
)
283 && NumAccessRanges
<= AssignedCount
)
285 DPRINT1("Too many access ranges found\n");
286 ExFreePool(AllocatedResources
);
287 return STATUS_UNSUCCESSFUL
;
289 if (CmResourceTypeMemory
== Descriptor
->Type
)
291 if (NumAccessRanges
<= AssignedCount
)
293 DPRINT1("Too many access ranges found\n");
294 ExFreePool(AllocatedResources
);
295 return STATUS_UNSUCCESSFUL
;
297 DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
298 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
299 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Memory
.Start
;
300 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Memory
.Length
;
301 AccessRanges
[AssignedCount
].RangeInIoSpace
= 0;
302 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
303 AccessRanges
[AssignedCount
].RangeShareable
=
304 (CmResourceShareShared
== Descriptor
->ShareDisposition
);
307 else if (CmResourceTypePort
== Descriptor
->Type
)
309 DPRINT("Port range starting at 0x%04x length %d\n",
310 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
311 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Port
.Start
;
312 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Port
.Length
;
313 AccessRanges
[AssignedCount
].RangeInIoSpace
= 1;
314 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
315 AccessRanges
[AssignedCount
].RangeShareable
= 0;
318 else if (CmResourceTypeInterrupt
== Descriptor
->Type
)
320 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
321 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
325 ExFreePool(AllocatedResources
);
332 return STATUS_SUCCESS
;
335 typedef struct QueryRegistryCallbackContext
337 PVOID HwDeviceExtension
;
339 PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine
;
340 } QUERY_REGISTRY_CALLBACK_CONTEXT
, *PQUERY_REGISTRY_CALLBACK_CONTEXT
;
342 static NTSTATUS STDCALL
343 QueryRegistryCallback(IN PWSTR ValueName
,
346 IN ULONG ValueLength
,
348 IN PVOID EntryContext
)
350 PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext
= (PQUERY_REGISTRY_CALLBACK_CONTEXT
) Context
;
352 DPRINT("Found registry value for name %S: type %d, length %d\n",
353 ValueName
, ValueType
, ValueLength
);
354 return (*(CallbackContext
->HwGetRegistryRoutine
))(CallbackContext
->HwDeviceExtension
,
355 CallbackContext
->HwContext
,
366 VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension
,
367 IN PWSTR ParameterName
,
368 IN UCHAR IsParameterFileName
,
369 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine
,
372 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
373 QUERY_REGISTRY_CALLBACK_CONTEXT Context
;
374 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
376 DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName
);
378 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
379 VIDEO_PORT_DEVICE_EXTENSION
,
380 MiniPortDeviceExtension
);
382 if (IsParameterFileName
)
387 DPRINT("ParameterName %S\n", ParameterName
);
389 Context
.HwDeviceExtension
= HwDeviceExtension
;
390 Context
.HwContext
= HwContext
;
391 Context
.HwGetRegistryRoutine
= GetRegistryRoutine
;
393 QueryTable
[0].QueryRoutine
= QueryRegistryCallback
;
394 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
;
395 QueryTable
[0].Name
= ParameterName
;
396 QueryTable
[0].EntryContext
= NULL
;
397 QueryTable
[0].DefaultType
= REG_NONE
;
398 QueryTable
[0].DefaultData
= NULL
;
399 QueryTable
[0].DefaultLength
= 0;
401 QueryTable
[1].QueryRoutine
= NULL
;
402 QueryTable
[1].Name
= NULL
;
404 return NT_SUCCESS(RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
405 DeviceExtension
->RegistryPath
.Buffer
,
406 QueryTable
, &Context
, NULL
))
407 ? ERROR_SUCCESS
: ERROR_INVALID_PARAMETER
;
416 VideoPortGetVgaStatus(IN PVOID HwDeviceExtension
,
417 OUT PULONG VgaStatus
)
419 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
421 DPRINT("VideoPortGetVgaStatus = %S \n", VgaStatus
);
423 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
424 VIDEO_PORT_DEVICE_EXTENSION
,
425 MiniPortDeviceExtension
);
427 if(KeGetCurrentIrql() == PASSIVE_LEVEL
)
429 if ( PCIBus
== DeviceExtension
->AdapterInterfaceType
)
432 VgaStatus 0 == VGA not enabled, 1 == VGA enabled.
435 /* Assumed for now */
437 VgaStatus
= (PULONG
) 1;
439 return STATUS_SUCCESS
;
442 return ERROR_INVALID_FUNCTION
;
446 VPInterruptRoutine(IN
struct _KINTERRUPT
*Interrupt
,
447 IN PVOID ServiceContext
)
449 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
451 DeviceExtension
= ServiceContext
;
452 assert(NULL
!= DeviceExtension
->HwInterrupt
);
454 return DeviceExtension
->HwInterrupt(&DeviceExtension
->MiniPortDeviceExtension
);
458 VPTimerRoutine(IN PDEVICE_OBJECT DeviceObject
,
461 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
463 DeviceExtension
= Context
;
464 assert(DeviceExtension
== DeviceObject
->DeviceExtension
465 && NULL
!= DeviceExtension
->HwTimer
);
467 DeviceExtension
->HwTimer(&DeviceExtension
->MiniPortDeviceExtension
);
474 VideoPortInitialize(IN PVOID Context1
,
476 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData
,
479 PUNICODE_STRING RegistryPath
;
481 WCHAR DeviceBuffer
[20];
482 WCHAR SymlinkBuffer
[20];
483 WCHAR DeviceVideoBuffer
[20];
485 PDRIVER_OBJECT MPDriverObject
= (PDRIVER_OBJECT
) Context1
;
486 PDEVICE_OBJECT MPDeviceObject
;
487 VIDEO_PORT_CONFIG_INFO ConfigInfo
;
488 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
489 ULONG DeviceNumber
= 0;
490 UNICODE_STRING DeviceName
;
491 UNICODE_STRING SymlinkName
;
496 ULONG InterruptVector
;
498 DPRINT("VideoPortInitialize\n");
500 RegistryPath
= (PUNICODE_STRING
) Context2
;
502 /* Build Dispatch table from passed data */
503 MPDriverObject
->DriverStartIo
= (PDRIVER_STARTIO
) HwInitializationData
->HwStartIO
;
505 /* Create a unicode device name */
509 swprintf(DeviceBuffer
, L
"\\Device\\Video%lu", DeviceNumber
);
510 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
512 /* Create the device */
513 Status
= IoCreateDevice(MPDriverObject
,
514 HwInitializationData
->HwDeviceExtensionSize
+
515 sizeof(VIDEO_PORT_DEVICE_EXTENSION
),
521 if (!NT_SUCCESS(Status
))
523 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status
);
527 MPDriverObject
->DeviceObject
= MPDeviceObject
;
529 /* Initialize the miniport drivers dispatch table */
530 MPDriverObject
->MajorFunction
[IRP_MJ_CREATE
] = VidDispatchOpen
;
531 MPDriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = VidDispatchClose
;
532 MPDriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = VidDispatchDeviceControl
;
534 /* Initialize our device extension */
536 (PVIDEO_PORT_DEVICE_EXTENSION
) MPDeviceObject
->DeviceExtension
;
537 DeviceExtension
->DeviceObject
= MPDeviceObject
;
538 DeviceExtension
->HwInitialize
= HwInitializationData
->HwInitialize
;
539 DeviceExtension
->HwResetHw
= HwInitializationData
->HwResetHw
;
540 DeviceExtension
->AdapterInterfaceType
= HwInitializationData
->AdapterInterfaceType
;
541 DeviceExtension
->SystemIoBusNumber
= 0;
542 MaxLen
= (wcslen(RegistryPath
->Buffer
) + 10) * sizeof(WCHAR
);
543 DeviceExtension
->RegistryPath
.MaximumLength
= MaxLen
;
544 DeviceExtension
->RegistryPath
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
547 swprintf(DeviceExtension
->RegistryPath
.Buffer
, L
"%s\\Device%d",
548 RegistryPath
->Buffer
, DeviceNumber
);
549 DeviceExtension
->RegistryPath
.Length
= wcslen(DeviceExtension
->RegistryPath
.Buffer
) *
552 MaxBus
= (DeviceExtension
->AdapterInterfaceType
== PCIBus
) ? 8 : 1;
553 DPRINT("MaxBus: %lu\n", MaxBus
);
554 InitializeListHead(&DeviceExtension
->AddressMappingListHead
);
556 /* Set the buffering strategy here... */
557 /* If you change this, remember to change VidDispatchDeviceControl too */
558 MPDeviceObject
->Flags
|= DO_BUFFERED_IO
;
562 RtlZeroMemory(&DeviceExtension
->MiniPortDeviceExtension
,
563 HwInitializationData
->HwDeviceExtensionSize
);
564 DPRINT("Searching on bus %d\n", DeviceExtension
->SystemIoBusNumber
);
565 /* Setup configuration info */
566 RtlZeroMemory(&ConfigInfo
, sizeof(VIDEO_PORT_CONFIG_INFO
));
567 ConfigInfo
.Length
= sizeof(VIDEO_PORT_CONFIG_INFO
);
568 ConfigInfo
.AdapterInterfaceType
= DeviceExtension
->AdapterInterfaceType
;
569 ConfigInfo
.SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
570 ConfigInfo
.InterruptMode
= (PCIBus
== DeviceExtension
->AdapterInterfaceType
) ?
571 LevelSensitive
: Latched
;
573 /* Call HwFindAdapter entry point */
574 /* FIXME: Need to figure out what string to pass as param 3 */
575 Status
= HwInitializationData
->HwFindAdapter(&DeviceExtension
->MiniPortDeviceExtension
,
580 if (NO_ERROR
!= Status
)
582 DPRINT("HwFindAdapter call failed with error %d\n", Status
);
583 DeviceExtension
->SystemIoBusNumber
++;
586 while (NO_ERROR
!= Status
&& DeviceExtension
->SystemIoBusNumber
< MaxBus
);
588 if (NO_ERROR
!= Status
)
590 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
591 IoDeleteDevice(MPDeviceObject
);
595 DPRINT("Found adapter\n");
597 /* create symbolic link "\??\DISPLAYx" */
598 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DeviceNumber
+1);
599 RtlInitUnicodeString (&SymlinkName
,
601 IoCreateSymbolicLink (&SymlinkName
,
604 /* Add entry to DEVICEMAP\VIDEO key in registry */
605 swprintf(DeviceVideoBuffer
, L
"\\Device\\Video%d", DeviceNumber
);
606 RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP
,
610 DeviceExtension
->RegistryPath
.Buffer
,
611 DeviceExtension
->RegistryPath
.Length
+ sizeof(WCHAR
));
613 /* FIXME: Allocate hardware resources for device */
615 /* Allocate interrupt for device */
616 DeviceExtension
->HwInterrupt
= HwInitializationData
->HwInterrupt
;
617 if (0 == ConfigInfo
.BusInterruptVector
)
619 ConfigInfo
.BusInterruptVector
= DeviceExtension
->InterruptVector
;
621 if (0 == ConfigInfo
.BusInterruptLevel
)
623 ConfigInfo
.BusInterruptLevel
= DeviceExtension
->InterruptLevel
;
625 if (NULL
!= HwInitializationData
->HwInterrupt
)
628 HalGetInterruptVector(ConfigInfo
.AdapterInterfaceType
,
629 ConfigInfo
.SystemIoBusNumber
,
630 ConfigInfo
.BusInterruptLevel
,
631 ConfigInfo
.BusInterruptVector
,
634 if (0 == InterruptVector
)
636 DPRINT1("HalGetInterruptVector failed\n");
637 IoDeleteDevice(MPDeviceObject
);
639 return STATUS_INSUFFICIENT_RESOURCES
;
641 KeInitializeSpinLock(&DeviceExtension
->InterruptSpinLock
);
642 Status
= IoConnectInterrupt(&DeviceExtension
->InterruptObject
,
645 &DeviceExtension
->InterruptSpinLock
,
649 ConfigInfo
.InterruptMode
,
653 if (!NT_SUCCESS(Status
))
655 DPRINT1("IoConnectInterrupt failed with status 0x%08x\n", Status
);
656 IoDeleteDevice(MPDeviceObject
);
665 DeviceExtension
->HwTimer
= HwInitializationData
->HwTimer
;
666 if (HwInitializationData
->HwTimer
!= NULL
)
668 DPRINT("Initializing timer\n");
669 Status
= IoInitializeTimer(MPDeviceObject
,
672 if (!NT_SUCCESS(Status
))
674 DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status
);
676 if (HwInitializationData
->HwInterrupt
!= NULL
)
678 IoDisconnectInterrupt(DeviceExtension
->InterruptObject
);
680 IoDeleteDevice(MPDeviceObject
);
686 return STATUS_SUCCESS
;
694 VideoPortLogError(IN PVOID HwDeviceExtension
,
695 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL
,
696 IN VP_STATUS ErrorCode
,
699 DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
700 ErrorCode
, ErrorCode
, UniqueId
, UniqueId
);
703 DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp
->IoControlCode
, Vrp
->IoControlCode
);
713 VideoPortMapBankedMemory(IN PVOID HwDeviceExtension
,
714 IN PHYSICAL_ADDRESS PhysicalAddress
,
717 OUT PVOID
*VirtualAddress
,
719 IN UCHAR ReadWriteBank
,
720 IN PBANKED_SECTION_ROUTINE BankRoutine
,
723 DPRINT("VideoPortMapBankedMemory\n");
725 return STATUS_NOT_IMPLEMENTED
;
734 VideoPortMapMemory(IN PVOID HwDeviceExtension
,
735 IN PHYSICAL_ADDRESS PhysicalAddress
,
738 OUT PVOID
*VirtualAddress
)
740 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
742 DPRINT("VideoPortMapMemory\n");
744 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
745 VIDEO_PORT_DEVICE_EXTENSION
,
746 MiniPortDeviceExtension
);
747 *VirtualAddress
= InternalMapMemory(DeviceExtension
, PhysicalAddress
,
748 *Length
, *InIoSpace
);
750 return NULL
== *VirtualAddress
? STATUS_NO_MEMORY
: STATUS_SUCCESS
;
759 VideoPortScanRom(IN PVOID HwDeviceExtension
,
766 PUCHAR SearchLocation
;
768 DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase
, RomLength
, String
);
770 StringLength
= strlen(String
);
772 SearchLocation
= RomBase
;
773 for (SearchLocation
= RomBase
;
774 ! Found
&& SearchLocation
< RomBase
+ RomLength
- StringLength
;
777 Found
= (RtlCompareMemory(SearchLocation
, String
, StringLength
) == StringLength
);
780 DPRINT("Match found at %p\n", SearchLocation
);
793 VideoPortSetBusData(IN PVOID HwDeviceExtension
,
794 IN BUS_DATA_TYPE BusDataType
,
800 DPRINT("VideoPortSetBusData\n");
801 return HalSetBusDataByOffset(BusDataType
,
815 VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension
,
818 IN ULONG ValueLength
)
820 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
822 DPRINT("VideoSetRegistryParameters\n");
824 assert_irql(PASSIVE_LEVEL
);
826 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
827 VIDEO_PORT_DEVICE_EXTENSION
,
828 MiniPortDeviceExtension
);
829 return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
830 DeviceExtension
->RegistryPath
.Buffer
,
843 VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension
,
844 IN ULONG NumAccessRanges
,
845 IN PVIDEO_ACCESS_RANGE AccessRange
)
847 DPRINT("VideoPortSetTrappedEmulatorPorts\n");
849 return STATUS_NOT_IMPLEMENTED
;
858 VideoPortStartTimer(IN PVOID HwDeviceExtension
)
860 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
862 DPRINT("VideoPortStartTimer\n");
864 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
865 VIDEO_PORT_DEVICE_EXTENSION
,
866 MiniPortDeviceExtension
);
867 IoStartTimer(DeviceExtension
->DeviceObject
);
876 VideoPortStopTimer(IN PVOID HwDeviceExtension
)
878 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
880 DPRINT("VideoPortStopTimer\n");
882 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
883 VIDEO_PORT_DEVICE_EXTENSION
,
884 MiniPortDeviceExtension
);
885 IoStopTimer(DeviceExtension
->DeviceObject
);
894 VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension
,
895 IN VIDEO_SYNCHRONIZE_PRIORITY Priority
,
896 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine
,
900 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
903 DPRINT("VideoPortSynchronizeExecution\n");
908 Ret
= (*SynchronizeRoutine
)(Context
);
910 case VpMediumPriority
:
911 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
912 VIDEO_PORT_DEVICE_EXTENSION
,
913 MiniPortDeviceExtension
);
914 if (NULL
== DeviceExtension
->InterruptObject
)
916 Ret
= (*SynchronizeRoutine
)(Context
);
920 Ret
= KeSynchronizeExecution(DeviceExtension
->InterruptObject
,
926 OldIrql
= KeGetCurrentIrql();
927 if (OldIrql
< SYNCH_LEVEL
)
929 OldIrql
= KfRaiseIrql(SYNCH_LEVEL
);
931 Ret
= (*SynchronizeRoutine
)(Context
);
932 if (OldIrql
< SYNCH_LEVEL
)
934 KfLowerIrql(OldIrql
);
950 VideoPortUnmapMemory(IN PVOID HwDeviceExtension
,
951 IN PVOID VirtualAddress
,
952 IN HANDLE ProcessHandle
)
954 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
956 DPRINT("VideoPortFreeDeviceBase\n");
958 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
959 VIDEO_PORT_DEVICE_EXTENSION
,
960 MiniPortDeviceExtension
);
962 InternalUnmapMemory(DeviceExtension
, VirtualAddress
);
964 return STATUS_SUCCESS
;
973 VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension
,
974 IN ULONG NumAccessRanges
,
975 IN PVIDEO_ACCESS_RANGE AccessRanges
)
977 DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
983 * Reset display to blue screen
985 static BOOLEAN STDCALL
986 VideoPortResetDisplayParameters(Columns
, Rows
)
988 if (NULL
== ResetDisplayParametersDeviceExtension
)
992 if (NULL
== ResetDisplayParametersDeviceExtension
->HwResetHw
)
996 if (!ResetDisplayParametersDeviceExtension
->HwResetHw(&ResetDisplayParametersDeviceExtension
->MiniPortDeviceExtension
,
1002 ResetDisplayParametersDeviceExtension
= NULL
;
1013 VideoPortAllocatePool(
1014 IN PVOID HwDeviceExtension
,
1015 IN VP_POOL_TYPE PoolType
,
1016 IN SIZE_T NumberOfBytes
,
1019 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
1029 IN PVOID HwDeviceExtension
,
1038 // Answer requests for Open calls
1044 // Standard dispatch arguments
1051 VidDispatchOpen(IN PDEVICE_OBJECT pDO
,
1054 PIO_STACK_LOCATION IrpStack
;
1055 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1057 DPRINT("VidDispatchOpen() called\n");
1059 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1061 if (! CsrssInitialized
)
1063 DPRINT("Referencing CSRSS\n");
1064 Csrss
= PsGetCurrentProcess();
1065 DPRINT("Csrss %p\n", Csrss
);
1069 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
) pDO
->DeviceExtension
;
1070 if (DeviceExtension
->HwInitialize(&DeviceExtension
->MiniPortDeviceExtension
))
1072 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1073 /* Storing the device extension pointer in a static variable is an ugly
1074 * hack. Unfortunately, we need it in VideoPortResetDisplayParameters
1075 * and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
1076 * parameter. On the bright side, the DISPLAY device is opened
1077 * exclusively, so there can be only one device extension active at
1078 * any point in time. */
1079 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
1080 HalAcquireDisplayOwnership(VideoPortResetDisplayParameters
);
1084 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1088 Irp
->IoStatus
.Information
= FILE_OPENED
;
1089 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1091 return STATUS_SUCCESS
;
1097 // Answer requests for Close calls
1103 // Standard dispatch arguments
1110 VidDispatchClose(IN PDEVICE_OBJECT pDO
,
1113 PIO_STACK_LOCATION IrpStack
;
1115 DPRINT("VidDispatchClose() called\n");
1117 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1119 if (! CsrssInitialized
)
1121 CsrssInitialized
= TRUE
;
1125 HalReleaseDisplayOwnership();
1128 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1129 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1131 return STATUS_SUCCESS
;
1134 // VidDispatchDeviceControl
1137 // Answer requests for device control calls
1143 // Standard dispatch arguments
1150 VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject
,
1153 PIO_STACK_LOCATION IrpStack
;
1154 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1155 PVIDEO_REQUEST_PACKET vrp
;
1157 DPRINT("VidDispatchDeviceControl\n");
1158 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1159 DeviceExtension
= DeviceObject
->DeviceExtension
;
1161 /* Translate the IRP to a VRP */
1162 vrp
= ExAllocatePool(PagedPool
, sizeof(VIDEO_REQUEST_PACKET
));
1165 return STATUS_NO_MEMORY
;
1167 vrp
->StatusBlock
= (PSTATUS_BLOCK
) &(Irp
->IoStatus
);
1168 vrp
->IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
1170 /* We're assuming METHOD_BUFFERED */
1171 vrp
->InputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
1172 vrp
->InputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
1173 vrp
->OutputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
1174 vrp
->OutputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1176 /* Call the Miniport Driver with the VRP */
1177 ((PDRIVER_STARTIO
)DeviceObject
->DriverObject
->DriverStartIo
)((PVOID
) &DeviceExtension
->MiniPortDeviceExtension
, (PIRP
)vrp
);
1182 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1184 return STATUS_SUCCESS
;
1188 InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
1189 IN PHYSICAL_ADDRESS IoAddress
,
1190 IN ULONG NumberOfUchars
,
1193 PHYSICAL_ADDRESS TranslatedAddress
;
1194 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
1196 PVOID MappedAddress
;
1199 if (0 != (InIoSpace
& VIDEO_MEMORY_SPACE_P6CACHE
))
1201 DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
1202 InIoSpace
&= ~VIDEO_MEMORY_SPACE_P6CACHE
;
1204 if (! IsListEmpty(&DeviceExtension
->AddressMappingListHead
))
1206 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
1207 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
1209 AddressMapping
= CONTAINING_RECORD(Entry
,
1210 VIDEO_PORT_ADDRESS_MAPPING
,
1212 if (IoAddress
.QuadPart
== AddressMapping
->IoAddress
.QuadPart
&&
1213 NumberOfUchars
<= AddressMapping
->NumberOfUchars
)
1215 AddressMapping
->MappingCount
++;
1216 return AddressMapping
->MappedAddress
;
1218 Entry
= Entry
->Flink
;
1222 AddressSpace
= (ULONG
)InIoSpace
;
1223 if (HalTranslateBusAddress(DeviceExtension
->AdapterInterfaceType
,
1224 DeviceExtension
->SystemIoBusNumber
,
1227 &TranslatedAddress
) == FALSE
)
1231 if (AddressSpace
!= 0)
1233 assert(0 == TranslatedAddress
.u
.HighPart
);
1234 return (PVOID
) TranslatedAddress
.u
.LowPart
;
1237 MappedAddress
= MmMapIoSpace(TranslatedAddress
,
1241 AddressMapping
= ExAllocatePoolWithTag(PagedPool
,
1242 sizeof(VIDEO_PORT_ADDRESS_MAPPING
),
1244 if (AddressMapping
== NULL
)
1245 return MappedAddress
;
1247 AddressMapping
->MappedAddress
= MappedAddress
;
1248 AddressMapping
->NumberOfUchars
= NumberOfUchars
;
1249 AddressMapping
->IoAddress
= IoAddress
;
1250 AddressMapping
->SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
1251 AddressMapping
->MappingCount
= 1;
1253 InsertHeadList(&DeviceExtension
->AddressMappingListHead
,
1254 &AddressMapping
->List
);
1256 return MappedAddress
;
1260 InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
1261 IN PVOID MappedAddress
)
1263 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
1266 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
1267 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
1269 AddressMapping
= CONTAINING_RECORD(Entry
,
1270 VIDEO_PORT_ADDRESS_MAPPING
,
1272 if (AddressMapping
->MappedAddress
== MappedAddress
)
1274 assert(0 <= AddressMapping
->MappingCount
);
1275 AddressMapping
->MappingCount
--;
1276 if (0 == AddressMapping
->MappingCount
)
1278 MmUnmapIoSpace(AddressMapping
->MappedAddress
,
1279 AddressMapping
->NumberOfUchars
);
1280 RemoveEntryList(Entry
);
1281 ExFreePool(AddressMapping
);
1287 Entry
= Entry
->Flink
;