4 * Written by Rex Jolliff
10 #include <ddk/ntddvid.h>
12 #include "../../../ntoskrnl/include/internal/v86m.h"
17 #define VERSION "0.0.0"
19 #define TAG_VIDEO_PORT TAG('V', 'I', 'D', 'P')
21 typedef struct _VIDEO_PORT_ADDRESS_MAPPING
27 PHYSICAL_ADDRESS IoAddress;
28 ULONG SystemIoBusNumber;
30 } VIDEO_PORT_ADDRESS_MAPPING, *PVIDEO_PORT_ADDRESS_MAPPING;
32 typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
34 PDEVICE_OBJECT DeviceObject;
35 PKINTERRUPT InterruptObject;
36 KSPIN_LOCK InterruptSpinLock;
40 PVIDEO_HW_INITIALIZE HwInitialize;
41 PVIDEO_HW_RESET_HW HwResetHw;
42 LIST_ENTRY AddressMappingListHead;
43 INTERFACE_TYPE AdapterInterfaceType;
44 ULONG SystemIoBusNumber;
45 UNICODE_STRING RegistryPath;
47 UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */
48 } VIDEO_PORT_DEVICE_EXTENSION, *PVIDEO_PORT_DEVICE_EXTENSION;
51 static VOID STDCALL VidStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
52 static NTSTATUS STDCALL VidDispatchOpen(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
53 static NTSTATUS STDCALL VidDispatchClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
54 static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
55 static PVOID STDCALL InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
56 IN PHYSICAL_ADDRESS IoAddress,
57 IN ULONG NumberOfUchars,
59 static VOID STDCALL InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
60 IN PVOID MappedAddress);
62 static BOOLEAN CsrssInitialized = FALSE;
63 static PEPROCESS Csrss = NULL;
64 static PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
66 PBYTE ReturnCsrssAddress(void)
68 DPRINT("ReturnCsrssAddress()\n");
72 // ------------------------------------------------------- Public Interface
77 // This function initializes the driver.
83 // IN PDRIVER_OBJECT DriverObject System allocated Driver Object
85 // IN PUNICODE_STRING RegistryPath Name of registry driver service
92 DriverEntry(IN PDRIVER_OBJECT DriverObject,
93 IN PUNICODE_STRING RegistryPath)
95 DPRINT("DriverEntry()\n");
96 return(STATUS_SUCCESS);
103 VideoPortDebugPrint(IN ULONG DebugPrintLevel,
104 IN PCHAR DebugMessage, ...)
110 if (DebugPrintLevel > InternalDebugLevel)
113 va_start (ap, DebugMessage);
114 vsprintf (Buffer, DebugMessage, ap);
126 VideoPortDisableInterrupt(IN PVOID HwDeviceExtension)
128 DPRINT("VideoPortDisableInterrupt\n");
138 VideoPortEnableInterrupt(IN PVOID HwDeviceExtension)
140 DPRINT("VideoPortEnableInterrupt\n");
150 VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension,
151 IN PVOID MappedAddress)
153 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
155 DPRINT("VideoPortFreeDeviceBase\n");
157 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
158 VIDEO_PORT_DEVICE_EXTENSION,
159 MiniPortDeviceExtension);
161 InternalUnmapMemory(DeviceExtension, MappedAddress);
170 VideoPortGetBusData(IN PVOID HwDeviceExtension,
171 IN BUS_DATA_TYPE BusDataType,
177 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
179 DPRINT("VideoPortGetBusData\n");
181 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
182 VIDEO_PORT_DEVICE_EXTENSION,
183 MiniPortDeviceExtension);
185 return HalGetBusDataByOffset(BusDataType,
186 DeviceExtension->SystemIoBusNumber,
199 VideoPortGetCurrentIrql(VOID)
201 DPRINT("VideoPortGetCurrentIrql\n");
202 return KeGetCurrentIrql();
211 VideoPortGetDeviceBase(IN PVOID HwDeviceExtension,
212 IN PHYSICAL_ADDRESS IoAddress,
213 IN ULONG NumberOfUchars,
216 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
218 DPRINT("VideoPortGetDeviceBase\n");
220 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
221 VIDEO_PORT_DEVICE_EXTENSION,
222 MiniPortDeviceExtension);
224 return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace);
233 VideoPortGetDeviceData(IN PVOID HwDeviceExtension,
234 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType,
235 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine,
238 DPRINT("VideoPortGetDeviceData\n");
248 VideoPortGetAccessRanges(IN PVOID HwDeviceExtension,
249 IN ULONG NumRequestedResources,
250 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL,
251 IN ULONG NumAccessRanges,
252 IN PVIDEO_ACCESS_RANGE AccessRanges,
257 PCI_SLOT_NUMBER PciSlotNumber;
259 ULONG FunctionNumber;
260 PCI_COMMON_CONFIG Config;
261 PCM_RESOURCE_LIST AllocatedResources;
264 CM_FULL_RESOURCE_DESCRIPTOR *FullList;
265 CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
266 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
268 DPRINT("VideoPortGetAccessRanges\n");
270 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
271 VIDEO_PORT_DEVICE_EXTENSION,
272 MiniPortDeviceExtension);
274 if (0 == NumRequestedResources && PCIBus == DeviceExtension->AdapterInterfaceType)
276 DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n", (int)*((USHORT *) VendorId),
277 (int)*((USHORT *) DeviceId));
279 PciSlotNumber.u.AsULONG = *Slot;
280 for (FunctionNumber = 0; ! FoundDevice && FunctionNumber < 8; FunctionNumber++)
282 PciSlotNumber.u.bits.FunctionNumber = FunctionNumber;
283 if (sizeof(PCI_COMMON_CONFIG) ==
284 HalGetBusDataByOffset(PCIConfiguration, DeviceExtension->SystemIoBusNumber,
285 PciSlotNumber.u.AsULONG,&Config, 0,
286 sizeof(PCI_COMMON_CONFIG)))
288 DPRINT("Slot 0x%02x (Device %d Function %d) VendorId 0x%04x DeviceId 0x%04x\n",
289 PciSlotNumber.u.AsULONG, PciSlotNumber.u.bits.DeviceNumber,
290 PciSlotNumber.u.bits.FunctionNumber, Config.VendorID, Config.DeviceID);
291 FoundDevice = (Config.VendorID == *((USHORT *) VendorId) &&
292 Config.DeviceID == *((USHORT *) DeviceId));
297 return STATUS_UNSUCCESSFUL;
299 Status = HalAssignSlotResources(NULL, NULL, NULL, NULL,
300 DeviceExtension->AdapterInterfaceType,
301 DeviceExtension->SystemIoBusNumber,
302 PciSlotNumber.u.AsULONG, &AllocatedResources);
303 if (! NT_SUCCESS(Status))
308 for (FullList = AllocatedResources->List;
309 FullList < AllocatedResources->List + AllocatedResources->Count &&
310 AssignedCount < NumAccessRanges;
313 assert(FullList->InterfaceType == PCIBus &&
314 FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
315 1 == FullList->PartialResourceList.Version &&
316 1 == FullList->PartialResourceList.Revision);
317 for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
318 Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count &&
319 AssignedCount < NumAccessRanges;
322 if (CmResourceTypeMemory == Descriptor->Type)
324 DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
325 Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
326 AccessRanges[AssignedCount].RangeStart = Descriptor->u.Memory.Start;
327 AccessRanges[AssignedCount].RangeLength = Descriptor->u.Memory.Length;
328 AccessRanges[AssignedCount].RangeInIoSpace = 0;
329 AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
330 AccessRanges[AssignedCount].RangeShareable =
331 (CmResourceShareShared == Descriptor->ShareDisposition);
333 else if (CmResourceTypePort == Descriptor->Type)
335 DPRINT("Port range starting at 0x%04x length %d\n",
336 Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
337 AccessRanges[AssignedCount].RangeStart = Descriptor->u.Port.Start;
338 AccessRanges[AssignedCount].RangeLength = Descriptor->u.Port.Length;
339 AccessRanges[AssignedCount].RangeInIoSpace = 1;
340 AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
341 AccessRanges[AssignedCount].RangeShareable = 0;
345 ExFreePool(AllocatedResources);
346 return STATUS_UNSUCCESSFUL;
351 ExFreePool(AllocatedResources);
358 return STATUS_SUCCESS;
367 VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension,
368 IN PWSTR ParameterName,
369 IN UCHAR IsParameterFileName,
370 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine,
373 DPRINT("VideoPortGetRegistryParameters\n");
374 DPRINT("ParameterName %S\n", ParameterName);
375 return STATUS_OBJECT_NAME_NOT_FOUND;
386 VideoPortInitialize(IN PVOID Context1,
388 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData,
391 PUNICODE_STRING RegistryPath;
393 WCHAR DeviceBuffer[20];
394 WCHAR SymlinkBuffer[20];
395 WCHAR DeviceVideoBuffer[20];
397 PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1;
398 PDEVICE_OBJECT MPDeviceObject;
399 VIDEO_PORT_CONFIG_INFO ConfigInfo;
400 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
401 ULONG DeviceNumber = 0;
402 UNICODE_STRING DeviceName;
403 UNICODE_STRING SymlinkName;
407 DPRINT("VideoPortInitialize\n");
409 RegistryPath = (PUNICODE_STRING) Context2;
411 /* Build Dispatch table from passed data */
412 MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO;
414 /* Create a unicode device name */
418 swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber);
419 RtlInitUnicodeString(&DeviceName, DeviceBuffer);
421 /* Create the device */
422 Status = IoCreateDevice(MPDriverObject,
423 HwInitializationData->HwDeviceExtensionSize +
424 sizeof(VIDEO_PORT_DEVICE_EXTENSION),
430 if (!NT_SUCCESS(Status))
432 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
436 MPDriverObject->DeviceObject = MPDeviceObject;
438 /* Initialize the miniport drivers dispatch table */
439 MPDriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH) VidDispatchOpen;
440 MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH) VidDispatchClose;
441 MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH) VidDispatchDeviceControl;
443 /* Initialize our device extension */
445 (PVIDEO_PORT_DEVICE_EXTENSION) MPDeviceObject->DeviceExtension;
446 DeviceExtension->DeviceObject = MPDeviceObject;
447 DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
448 DeviceExtension->HwResetHw = HwInitializationData->HwResetHw;
449 DeviceExtension->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType;
450 DeviceExtension->SystemIoBusNumber = 0;
451 MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR);
452 DeviceExtension->RegistryPath.MaximumLength = MaxLen;
453 DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
456 swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device%d",
457 RegistryPath->Buffer, DeviceNumber);
458 DeviceExtension->RegistryPath.Length = wcslen(DeviceExtension->RegistryPath.Buffer) *
461 MaxBus = (DeviceExtension->AdapterInterfaceType == PCIBus) ? 8 : 1;
462 DPRINT("MaxBus: %lu\n", MaxBus);
463 InitializeListHead(&DeviceExtension->AddressMappingListHead);
465 /* Set the buffering strategy here... */
466 /* If you change this, remember to change VidDispatchDeviceControl too */
467 MPDeviceObject->Flags |= DO_BUFFERED_IO;
471 RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension,
472 HwInitializationData->HwDeviceExtensionSize);
473 DPRINT("Searching on bus %d\n", DeviceExtension->SystemIoBusNumber);
474 /* Setup configuration info */
475 RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
476 ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO);
477 ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType;
478 ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
479 ConfigInfo.InterruptMode = (PCIBus == DeviceExtension->AdapterInterfaceType) ?
480 LevelSensitive : Latched;
482 /* Call HwFindAdapter entry point */
483 /* FIXME: Need to figure out what string to pass as param 3 */
484 Status = HwInitializationData->HwFindAdapter(&DeviceExtension->MiniPortDeviceExtension,
489 if (NO_ERROR != Status)
491 DPRINT("HwFindAdapter call failed with error %d\n", Status);
492 DeviceExtension->SystemIoBusNumber++;
495 while (NO_ERROR != Status && DeviceExtension->SystemIoBusNumber < MaxBus);
497 if (NO_ERROR != Status)
499 RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
500 IoDeleteDevice(MPDeviceObject);
504 DPRINT("Found adapter\n");
506 /* create symbolic link "\??\DISPLAYx" */
507 swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber+1);
508 RtlInitUnicodeString (&SymlinkName,
510 IoCreateSymbolicLink (&SymlinkName,
513 /* Add entry to DEVICEMAP\VIDEO key in registry */
514 swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DeviceNumber);
515 RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
519 DeviceExtension->RegistryPath.Buffer,
520 DeviceExtension->RegistryPath.Length + sizeof(WCHAR));
522 /* FIXME: Allocate hardware resources for device */
524 /* Allocate interrupt for device */
525 if (HwInitializationData->HwInterrupt != NULL &&
526 !(ConfigInfo.BusInterruptLevel == 0 &&
527 ConfigInfo.BusInterruptVector == 0))
530 DeviceExtension->IRQL = ConfigInfo.BusInterruptLevel;
531 DeviceExtension->InterruptLevel =
532 HalGetInterruptVector(ConfigInfo.AdapterInterfaceType,
533 ConfigInfo.SystemIoBusNumber,
534 ConfigInfo.BusInterruptLevel,
535 ConfigInfo.BusInterruptVector,
536 &DeviceExtension->IRQL,
537 &DeviceExtension->Affinity);
538 KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock);
539 Status = IoConnectInterrupt(&DeviceExtension->InterruptObject,
541 HwInitializationData->HwInterrupt,
542 &DeviceExtension->MiniPortDeviceExtension,
543 &DeviceExtension->InterruptSpinLock,
544 DeviceExtension->InterruptLevel,
545 DeviceExtension->IRQL,
546 DeviceExtension->IRQL,
547 ConfigInfo.InterruptMode,
549 DeviceExtension->Affinity,
551 if (!NT_SUCCESS(Status))
553 DPRINT("IoConnectInterrupt failed with status 0x%08x\n", Status);
554 IoDeleteDevice(MPDeviceObject);
564 /* FIXME: initialize timer routine for MP Driver */
565 if (HwInitializationData->HwTimer != NULL)
567 Status = IoInitializeTimer(MPDeviceObject,
569 HwInitializationData->HwTimer,
570 &DeviceExtension->MiniPortDeviceExtension);
571 if (!NT_SUCCESS(Status))
573 DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status);
575 if (HwInitializationData->HwInterrupt != NULL)
577 IoDisconnectInterrupt(DeviceExtension->InterruptObject);
579 IoDeleteDevice(MPDeviceObject);
585 return STATUS_SUCCESS;
593 VideoPortInt10(IN PVOID HwDeviceExtension,
594 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
596 KV86M_REGISTERS Regs;
598 PEPROCESS CallingProcess;
600 DPRINT("VideoPortInt10\n");
602 CallingProcess = PsGetCurrentProcess();
603 if (CallingProcess != Csrss)
605 KeAttachProcess(Csrss);
608 memset(&Regs, 0, sizeof(Regs));
609 Regs.Eax = BiosArguments->Eax;
610 Regs.Ebx = BiosArguments->Ebx;
611 Regs.Ecx = BiosArguments->Ecx;
612 Regs.Edx = BiosArguments->Edx;
613 Regs.Esi = BiosArguments->Esi;
614 Regs.Edi = BiosArguments->Edi;
615 Regs.Ebp = BiosArguments->Ebp;
616 Status = Ke386CallBios(0x10, &Regs);
618 if (CallingProcess != Csrss)
632 VideoPortLogError(IN PVOID HwDeviceExtension,
633 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL,
634 IN VP_STATUS ErrorCode,
637 DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
638 ErrorCode, ErrorCode, UniqueId, UniqueId);
641 DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp->IoControlCode, Vrp->IoControlCode);
651 VideoPortMapBankedMemory(IN PVOID HwDeviceExtension,
652 IN PHYSICAL_ADDRESS PhysicalAddress,
655 OUT PVOID *VirtualAddress,
657 IN UCHAR ReadWriteBank,
658 IN PBANKED_SECTION_ROUTINE BankRoutine,
661 DPRINT("VideoPortMapBankedMemory\n");
671 VideoPortMapMemory(IN PVOID HwDeviceExtension,
672 IN PHYSICAL_ADDRESS PhysicalAddress,
675 OUT PVOID *VirtualAddress)
677 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
678 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
681 DPRINT("VideoPortMapMemory\n");
683 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
684 VIDEO_PORT_DEVICE_EXTENSION,
685 MiniPortDeviceExtension);
686 *VirtualAddress = InternalMapMemory(DeviceExtension, PhysicalAddress,
687 *Length, *InIoSpace);
689 return NULL == *VirtualAddress ? STATUS_NO_MEMORY : STATUS_SUCCESS;
698 VideoPortReadPortUchar(IN PUCHAR Port)
700 DPRINT("VideoPortReadPortUchar\n");
701 return READ_PORT_UCHAR(Port);
710 VideoPortReadPortUshort(IN PUSHORT Port)
712 DPRINT("VideoPortReadPortUshort\n");
713 return READ_PORT_USHORT(Port);
722 VideoPortReadPortUlong(IN PULONG Port)
724 DPRINT("VideoPortReadPortUlong\n");
725 return READ_PORT_ULONG(Port);
734 VideoPortReadPortBufferUchar(IN PUCHAR Port,
738 DPRINT("VideoPortReadPortBufferUchar\n");
739 READ_PORT_BUFFER_UCHAR(Port, Buffer, Count);
748 VideoPortReadPortBufferUshort(IN PUSHORT Port,
752 DPRINT("VideoPortReadPortBufferUshort\n");
753 READ_PORT_BUFFER_USHORT(Port, Buffer, Count);
762 VideoPortReadPortBufferUlong(IN PULONG Port,
766 DPRINT("VideoPortReadPortBufferUlong\n");
767 READ_PORT_BUFFER_ULONG(Port, Buffer, Count);
776 VideoPortReadRegisterUchar(IN PUCHAR Register)
778 DPRINT("VideoPortReadPortRegisterUchar\n");
779 return READ_REGISTER_UCHAR(Register);
788 VideoPortReadRegisterUshort(IN PUSHORT Register)
790 DPRINT("VideoPortReadPortRegisterUshort\n");
791 return READ_REGISTER_USHORT(Register);
800 VideoPortReadRegisterUlong(IN PULONG Register)
802 DPRINT("VideoPortReadPortRegisterUlong\n");
803 return READ_REGISTER_ULONG(Register);
812 VideoPortReadRegisterBufferUchar(IN PUCHAR Register,
816 DPRINT("VideoPortReadPortRegisterBufferUchar\n");
817 READ_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
826 VideoPortReadRegisterBufferUshort(IN PUSHORT Register,
830 DPRINT("VideoPortReadPortRegisterBufferUshort\n");
831 READ_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
840 VideoPortReadRegisterBufferUlong(IN PULONG Register,
844 DPRINT("VideoPortReadPortRegisterBufferUlong\n");
845 READ_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
854 VideoPortScanRom(IN PVOID HwDeviceExtension,
861 PUCHAR SearchLocation;
863 DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase, RomLength, String);
865 StringLength = strlen(String);
867 SearchLocation = RomBase;
868 for (SearchLocation = RomBase;
869 ! Found && SearchLocation < RomBase + RomLength - StringLength;
872 Found = (RtlCompareMemory(SearchLocation, String, StringLength) == StringLength);
875 DPRINT("Match found at %p\n", SearchLocation);
888 VideoPortSetBusData(IN PVOID HwDeviceExtension,
889 IN BUS_DATA_TYPE BusDataType,
895 DPRINT("VideoPortSetBusData\n");
896 return HalSetBusDataByOffset(BusDataType,
910 VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension,
913 IN ULONG ValueLength)
915 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
917 DPRINT("VideoSetRegistryParameters\n");
919 assert_irql(PASSIVE_LEVEL);
921 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
922 VIDEO_PORT_DEVICE_EXTENSION,
923 MiniPortDeviceExtension);
924 return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
925 DeviceExtension->RegistryPath.Buffer,
938 VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension,
939 IN ULONG NumAccessRanges,
940 IN PVIDEO_ACCESS_RANGE AccessRange)
942 DPRINT("VideoPortSetTrappedEmulatorPorts\n");
952 VideoPortStartTimer(IN PVOID HwDeviceExtension)
954 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
956 DPRINT("VideoPortStartTimer\n");
958 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
959 VIDEO_PORT_DEVICE_EXTENSION,
960 MiniPortDeviceExtension);
961 IoStartTimer(DeviceExtension->DeviceObject);
970 VideoPortStopTimer(IN PVOID HwDeviceExtension)
972 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
974 DPRINT("VideoPortStopTimer\n");
976 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
977 VIDEO_PORT_DEVICE_EXTENSION,
978 MiniPortDeviceExtension);
979 IoStopTimer(DeviceExtension->DeviceObject);
988 VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension,
989 IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
990 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
994 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
997 DPRINT("VideoPortSynchronizeExecution\n");
1002 Ret = (*SynchronizeRoutine)(Context);
1004 case VpMediumPriority:
1005 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
1006 VIDEO_PORT_DEVICE_EXTENSION,
1007 MiniPortDeviceExtension);
1008 if (NULL == DeviceExtension->InterruptObject)
1010 Ret = (*SynchronizeRoutine)(Context);
1014 Ret = KeSynchronizeExecution(DeviceExtension->InterruptObject,
1019 case VpHighPriority:
1020 OldIrql = KeGetCurrentIrql();
1021 if (OldIrql < SYNCH_LEVEL)
1023 OldIrql = KfRaiseIrql(SYNCH_LEVEL);
1025 Ret = (*SynchronizeRoutine)(Context);
1026 if (OldIrql < SYNCH_LEVEL)
1028 KfLowerIrql(OldIrql);
1044 VideoPortUnmapMemory(IN PVOID HwDeviceExtension,
1045 IN PVOID VirtualAddress,
1046 IN HANDLE ProcessHandle)
1048 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
1050 DPRINT("VideoPortFreeDeviceBase\n");
1052 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
1053 VIDEO_PORT_DEVICE_EXTENSION,
1054 MiniPortDeviceExtension);
1056 InternalUnmapMemory(DeviceExtension, VirtualAddress);
1058 return STATUS_SUCCESS;
1067 VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension,
1068 IN ULONG NumAccessRanges,
1069 IN PVIDEO_ACCESS_RANGE AccessRanges)
1071 DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
1081 VideoPortWritePortUchar(IN PUCHAR Port,
1084 DPRINT("VideoPortWritePortUchar\n");
1085 WRITE_PORT_UCHAR(Port, Value);
1094 VideoPortWritePortUshort(IN PUSHORT Port,
1097 DPRINT("VideoPortWritePortUshort\n");
1098 WRITE_PORT_USHORT(Port, Value);
1107 VideoPortWritePortUlong(IN PULONG Port,
1110 DPRINT("VideoPortWritePortUlong\n");
1111 WRITE_PORT_ULONG(Port, Value);
1120 VideoPortWritePortBufferUchar(IN PUCHAR Port,
1124 DPRINT("VideoPortWritePortBufferUchar\n");
1125 WRITE_PORT_BUFFER_UCHAR(Port, Buffer, Count);
1134 VideoPortWritePortBufferUshort(IN PUSHORT Port,
1138 DPRINT("VideoPortWritePortBufferUshort\n");
1139 WRITE_PORT_BUFFER_USHORT(Port, Buffer, Count);
1148 VideoPortWritePortBufferUlong(IN PULONG Port,
1152 DPRINT("VideoPortWritePortBufferUlong\n");
1153 WRITE_PORT_BUFFER_ULONG(Port, Buffer, Count);
1162 VideoPortWriteRegisterUchar(IN PUCHAR Register,
1165 DPRINT("VideoPortWriteRegisterUchar\n");
1166 WRITE_REGISTER_UCHAR(Register, Value);
1175 VideoPortWriteRegisterUshort(IN PUSHORT Register,
1178 DPRINT("VideoPortWriteRegisterUshort\n");
1179 WRITE_REGISTER_USHORT(Register, Value);
1188 VideoPortWriteRegisterUlong(IN PULONG Register,
1191 DPRINT("VideoPortWriteRegisterUlong\n");
1192 WRITE_REGISTER_ULONG(Register, Value);
1201 VideoPortWriteRegisterBufferUchar(IN PUCHAR Register,
1205 DPRINT("VideoPortWriteRegisterBufferUchar\n");
1206 WRITE_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
1214 VideoPortWriteRegisterBufferUshort(IN PUSHORT Register,
1218 DPRINT("VideoPortWriteRegisterBufferUshort\n");
1219 WRITE_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
1227 VideoPortWriteRegisterBufferUlong(IN PULONG Register,
1231 DPRINT("VideoPortWriteRegisterBufferUlong\n");
1232 WRITE_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
1240 VideoPortZeroDeviceMemory(OUT PVOID Destination,
1243 DPRINT("VideoPortZeroDeviceMemory\n");
1244 RtlZeroMemory(Destination, Length);
1248 * Reset display to blue screen
1250 static BOOLEAN STDCALL
1251 VideoPortResetDisplayParameters(Columns, Rows)
1253 if (NULL != ResetDisplayParametersDeviceExtension)
1257 if (NULL == ResetDisplayParametersDeviceExtension->HwResetHw)
1261 if (!ResetDisplayParametersDeviceExtension->HwResetHw(&ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
1267 ResetDisplayParametersDeviceExtension = NULL;
1276 // Answer requests for Open calls
1282 // Standard dispatch arguments
1288 static NTSTATUS STDCALL
1289 VidDispatchOpen(IN PDEVICE_OBJECT pDO,
1292 PIO_STACK_LOCATION IrpStack;
1293 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
1295 DPRINT("VidDispatchOpen() called\n");
1297 IrpStack = IoGetCurrentIrpStackLocation(Irp);
1299 if (! CsrssInitialized)
1301 DPRINT("Referencing CSRSS\n");
1302 Csrss = PsGetCurrentProcess();
1303 DPRINT("Csrss %p\n", Csrss);
1307 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION) pDO->DeviceExtension;
1308 if (DeviceExtension->HwInitialize(&DeviceExtension->MiniPortDeviceExtension))
1310 Irp->IoStatus.Status = STATUS_SUCCESS;
1311 /* Storing the device extension pointer in a static variable is an ugly
1312 * hack. Unfortunately, we need it in VideoPortResetDisplayParameters
1313 * and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
1314 * parameter. On the bright side, the DISPLAY device is opened
1315 * exclusively, so there can be only one device extension active at
1316 * any point in time. */
1317 ResetDisplayParametersDeviceExtension = DeviceExtension;
1318 HalAcquireDisplayOwnership(VideoPortResetDisplayParameters);
1322 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
1326 Irp->IoStatus.Information = FILE_OPENED;
1327 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1329 return STATUS_SUCCESS;
1335 // Answer requests for Close calls
1341 // Standard dispatch arguments
1347 static NTSTATUS STDCALL
1348 VidDispatchClose(IN PDEVICE_OBJECT pDO,
1351 PIO_STACK_LOCATION IrpStack;
1352 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
1354 DPRINT("VidDispatchClose() called\n");
1356 IrpStack = IoGetCurrentIrpStackLocation(Irp);
1358 if (! CsrssInitialized)
1360 CsrssInitialized = TRUE;
1364 HalReleaseDisplayOwnership();
1367 Irp->IoStatus.Status = STATUS_SUCCESS;
1368 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1370 return STATUS_SUCCESS;
1376 // Get the next requested I/O packet started
1382 // Dispatch routine standard arguments
1389 VidStartIo(IN PDEVICE_OBJECT DeviceObject,
1392 DPRINT("VidStartIo\n");
1396 // VidDispatchDeviceControl
1399 // Answer requests for device control calls
1405 // Standard dispatch arguments
1411 static NTSTATUS STDCALL
1412 VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
1415 PIO_STACK_LOCATION IrpStack;
1416 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
1417 PVIDEO_REQUEST_PACKET vrp;
1419 DPRINT("VidDispatchDeviceControl\n");
1420 IrpStack = IoGetCurrentIrpStackLocation(Irp);
1421 DeviceExtension = DeviceObject->DeviceExtension;
1423 /* Translate the IRP to a VRP */
1424 vrp = ExAllocatePool(PagedPool, sizeof(VIDEO_REQUEST_PACKET));
1427 return STATUS_NO_MEMORY;
1429 vrp->StatusBlock = (PSTATUS_BLOCK) &(Irp->IoStatus);
1430 vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
1432 /* We're assuming METHOD_BUFFERED */
1433 vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer;
1434 vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
1435 vrp->OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
1436 vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
1438 /* Call the Miniport Driver with the VRP */
1439 DeviceObject->DriverObject->DriverStartIo((PVOID) &DeviceExtension->MiniPortDeviceExtension, (PIRP)vrp);
1444 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1446 return STATUS_SUCCESS;
1449 static PVOID STDCALL
1450 InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
1451 IN PHYSICAL_ADDRESS IoAddress,
1452 IN ULONG NumberOfUchars,
1455 PHYSICAL_ADDRESS TranslatedAddress;
1456 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
1458 PVOID MappedAddress;
1461 if (0 != (InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE))
1463 DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
1464 InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE;
1466 if (! IsListEmpty(&DeviceExtension->AddressMappingListHead))
1468 Entry = DeviceExtension->AddressMappingListHead.Flink;
1469 while (Entry != &DeviceExtension->AddressMappingListHead)
1471 AddressMapping = CONTAINING_RECORD(Entry,
1472 VIDEO_PORT_ADDRESS_MAPPING,
1474 if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart &&
1475 NumberOfUchars <= AddressMapping->NumberOfUchars)
1477 AddressMapping->MappingCount++;
1478 return AddressMapping->MappedAddress;
1480 Entry = Entry->Flink;
1484 AddressSpace = (ULONG)InIoSpace;
1485 if (HalTranslateBusAddress(DeviceExtension->AdapterInterfaceType,
1486 DeviceExtension->SystemIoBusNumber,
1489 &TranslatedAddress) == FALSE)
1493 if (AddressSpace != 0)
1495 assert(0 == TranslatedAddress.u.HighPart);
1496 return (PVOID) TranslatedAddress.u.LowPart;
1499 MappedAddress = MmMapIoSpace(TranslatedAddress,
1503 AddressMapping = ExAllocatePoolWithTag(PagedPool,
1504 sizeof(VIDEO_PORT_ADDRESS_MAPPING),
1506 if (AddressMapping == NULL)
1507 return MappedAddress;
1509 AddressMapping->MappedAddress = MappedAddress;
1510 AddressMapping->NumberOfUchars = NumberOfUchars;
1511 AddressMapping->IoAddress = IoAddress;
1512 AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
1513 AddressMapping->MappingCount = 1;
1515 InsertHeadList(&DeviceExtension->AddressMappingListHead,
1516 &AddressMapping->List);
1518 return MappedAddress;
1522 InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
1523 IN PVOID MappedAddress)
1525 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
1528 Entry = DeviceExtension->AddressMappingListHead.Flink;
1529 while (Entry != &DeviceExtension->AddressMappingListHead)
1531 AddressMapping = CONTAINING_RECORD(Entry,
1532 VIDEO_PORT_ADDRESS_MAPPING,
1534 if (AddressMapping->MappedAddress == MappedAddress)
1536 assert(0 <= AddressMapping->MappingCount);
1537 AddressMapping->MappingCount--;
1538 if (0 == AddressMapping->MappingCount)
1540 MmUnmapIoSpace(AddressMapping->MappedAddress,
1541 AddressMapping->NumberOfUchars);
1542 RemoveEntryList(Entry);
1543 ExFreePool(AddressMapping);
1549 Entry = Entry->Flink;