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 LIST_ENTRY AddressMappingListHead;
42 INTERFACE_TYPE AdapterInterfaceType;
43 ULONG SystemIoBusNumber;
44 UNICODE_STRING RegistryPath;
46 UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */
47 } VIDEO_PORT_DEVICE_EXTENSION, *PVIDEO_PORT_DEVICE_EXTENSION;
50 static VOID STDCALL VidStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
51 static NTSTATUS STDCALL VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
52 static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
53 static PVOID STDCALL InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
54 IN PHYSICAL_ADDRESS IoAddress,
55 IN ULONG NumberOfUchars,
57 static VOID STDCALL InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
58 IN PVOID MappedAddress);
60 static BOOLEAN CsrssInitialized = FALSE;
61 static HANDLE CsrssHandle = 0;
62 static struct _EPROCESS* Csrss = NULL;
64 PBYTE ReturnCsrssAddress(void)
66 DPRINT("ReturnCsrssAddress()\n");
70 // ------------------------------------------------------- Public Interface
75 // This function initializes the driver.
81 // IN PDRIVER_OBJECT DriverObject System allocated Driver Object
83 // IN PUNICODE_STRING RegistryPath Name of registry driver service
90 DriverEntry(IN PDRIVER_OBJECT DriverObject,
91 IN PUNICODE_STRING RegistryPath)
93 DPRINT("DriverEntry()\n");
94 return(STATUS_SUCCESS);
98 VideoPortDebugPrint(IN ULONG DebugPrintLevel,
99 IN PCHAR DebugMessage, ...)
105 if (DebugPrintLevel > InternalDebugLevel)
108 va_start (ap, DebugMessage);
109 vsprintf (Buffer, DebugMessage, ap);
117 VideoPortDisableInterrupt(IN PVOID HwDeviceExtension)
119 DPRINT("VideoPortDisableInterrupt\n");
125 VideoPortEnableInterrupt(IN PVOID HwDeviceExtension)
127 DPRINT("VideoPortEnableInterrupt\n");
133 VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension,
134 IN PVOID MappedAddress)
136 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
138 DPRINT("VideoPortFreeDeviceBase\n");
140 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
141 VIDEO_PORT_DEVICE_EXTENSION,
142 MiniPortDeviceExtension);
144 InternalUnmapMemory(DeviceExtension, MappedAddress);
149 VideoPortGetBusData(IN PVOID HwDeviceExtension,
150 IN BUS_DATA_TYPE BusDataType,
156 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
158 DPRINT("VideoPortGetBusData\n");
160 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
161 VIDEO_PORT_DEVICE_EXTENSION,
162 MiniPortDeviceExtension);
164 return HalGetBusDataByOffset(BusDataType,
165 DeviceExtension->SystemIoBusNumber,
174 VideoPortGetCurrentIrql(VOID)
176 DPRINT("VideoPortGetCurrentIrql\n");
177 return KeGetCurrentIrql();
182 VideoPortGetDeviceBase(IN PVOID HwDeviceExtension,
183 IN PHYSICAL_ADDRESS IoAddress,
184 IN ULONG NumberOfUchars,
187 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
189 DPRINT("VideoPortGetDeviceBase\n");
191 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
192 VIDEO_PORT_DEVICE_EXTENSION,
193 MiniPortDeviceExtension);
195 return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace);
200 VideoPortGetDeviceData(IN PVOID HwDeviceExtension,
201 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType,
202 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine,
205 DPRINT("VideoPortGetDeviceData\n");
211 VideoPortGetAccessRanges(IN PVOID HwDeviceExtension,
212 IN ULONG NumRequestedResources,
213 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL,
214 IN ULONG NumAccessRanges,
215 IN PVIDEO_ACCESS_RANGE AccessRanges,
220 PCI_SLOT_NUMBER PciSlotNumber;
222 ULONG FunctionNumber;
223 PCI_COMMON_CONFIG Config;
224 PCM_RESOURCE_LIST AllocatedResources;
227 CM_FULL_RESOURCE_DESCRIPTOR *FullList;
228 CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
229 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
231 DPRINT("VideoPortGetAccessRanges\n");
233 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
234 VIDEO_PORT_DEVICE_EXTENSION,
235 MiniPortDeviceExtension);
237 if (0 == NumRequestedResources && PCIBus == DeviceExtension->AdapterInterfaceType)
239 DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n", (int)*((USHORT *) VendorId),
240 (int)*((USHORT *) DeviceId));
242 PciSlotNumber.u.AsULONG = *Slot;
243 for (FunctionNumber = 0; ! FoundDevice && FunctionNumber < 8; FunctionNumber++)
245 PciSlotNumber.u.bits.FunctionNumber = FunctionNumber;
246 if (sizeof(PCI_COMMON_CONFIG) ==
247 HalGetBusDataByOffset(PCIConfiguration, DeviceExtension->SystemIoBusNumber,
248 PciSlotNumber.u.AsULONG,&Config, 0,
249 sizeof(PCI_COMMON_CONFIG)))
251 DPRINT("Slot 0x%02x (Device %d Function %d) VendorId 0x%04x DeviceId 0x%04x\n",
252 PciSlotNumber.u.AsULONG, PciSlotNumber.u.bits.DeviceNumber,
253 PciSlotNumber.u.bits.FunctionNumber, Config.VendorID, Config.DeviceID);
254 FoundDevice = (Config.VendorID == *((USHORT *) VendorId) &&
255 Config.DeviceID == *((USHORT *) DeviceId));
260 return STATUS_UNSUCCESSFUL;
262 Status = HalAssignSlotResources(NULL, NULL, NULL, NULL,
263 DeviceExtension->AdapterInterfaceType,
264 DeviceExtension->SystemIoBusNumber,
265 PciSlotNumber.u.AsULONG, &AllocatedResources);
266 if (! NT_SUCCESS(Status))
271 for (FullList = AllocatedResources->List;
272 FullList < AllocatedResources->List + AllocatedResources->Count &&
273 AssignedCount < NumAccessRanges;
276 assert(FullList->InterfaceType == PCIBus &&
277 FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
278 1 == FullList->PartialResourceList.Version &&
279 1 == FullList->PartialResourceList.Revision);
280 for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
281 Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count &&
282 AssignedCount < NumAccessRanges;
285 if (CmResourceTypeMemory == Descriptor->Type)
287 DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
288 Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
289 AccessRanges[AssignedCount].RangeStart = Descriptor->u.Memory.Start;
290 AccessRanges[AssignedCount].RangeLength = Descriptor->u.Memory.Length;
291 AccessRanges[AssignedCount].RangeInIoSpace = 0;
292 AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
293 AccessRanges[AssignedCount].RangeShareable =
294 (CmResourceShareShared == Descriptor->ShareDisposition);
296 else if (CmResourceTypePort == Descriptor->Type)
298 DPRINT("Port range starting at 0x%04x length %d\n",
299 Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
300 AccessRanges[AssignedCount].RangeStart = Descriptor->u.Port.Start;
301 AccessRanges[AssignedCount].RangeLength = Descriptor->u.Port.Length;
302 AccessRanges[AssignedCount].RangeInIoSpace = 1;
303 AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
304 AccessRanges[AssignedCount].RangeShareable = 0;
308 ExFreePool(AllocatedResources);
309 return STATUS_UNSUCCESSFUL;
314 ExFreePool(AllocatedResources);
321 return STATUS_SUCCESS;
326 VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension,
327 IN PWSTR ParameterName,
328 IN UCHAR IsParameterFileName,
329 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine,
332 DPRINT("VideoPortGetRegistryParameters\n");
333 DPRINT("ParameterName %S\n", ParameterName);
334 return STATUS_OBJECT_NAME_NOT_FOUND;
341 VideoPortInitialize(IN PVOID Context1,
343 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData,
346 PUNICODE_STRING RegistryPath;
348 WCHAR DeviceBuffer[20];
349 WCHAR SymlinkBuffer[20];
350 WCHAR DeviceVideoBuffer[20];
352 PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1;
353 PDEVICE_OBJECT MPDeviceObject;
354 VIDEO_PORT_CONFIG_INFO ConfigInfo;
355 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
356 ULONG DeviceNumber = 0;
357 UNICODE_STRING DeviceName;
358 UNICODE_STRING SymlinkName;
362 DPRINT("VideoPortInitialize\n");
364 RegistryPath = (PUNICODE_STRING) Context2;
366 /* Build Dispatch table from passed data */
367 MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO;
369 /* Create a unicode device name */
373 swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber);
374 RtlInitUnicodeString(&DeviceName, DeviceBuffer);
376 /* Create the device */
377 Status = IoCreateDevice(MPDriverObject,
378 HwInitializationData->HwDeviceExtensionSize +
379 sizeof(VIDEO_PORT_DEVICE_EXTENSION),
385 if (!NT_SUCCESS(Status))
387 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
391 MPDriverObject->DeviceObject = MPDeviceObject;
393 /* Initialize the miniport drivers dispatch table */
394 MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpenClose;
395 MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchOpenClose;
396 MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl;
398 /* Initialize our device extension */
400 (PVIDEO_PORT_DEVICE_EXTENSION) MPDeviceObject->DeviceExtension;
401 DeviceExtension->DeviceObject = MPDeviceObject;
402 DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
403 DeviceExtension->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType;
404 DeviceExtension->SystemIoBusNumber = 0;
405 MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR);
406 DeviceExtension->RegistryPath.MaximumLength = MaxLen;
407 DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
410 swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device%d",
411 RegistryPath->Buffer, DeviceNumber);
412 DeviceExtension->RegistryPath.Length = wcslen(DeviceExtension->RegistryPath.Buffer) *
415 MaxBus = (DeviceExtension->AdapterInterfaceType == PCIBus) ? 8 : 1;
416 DPRINT("MaxBus: %lu\n", MaxBus);
417 InitializeListHead(&DeviceExtension->AddressMappingListHead);
419 /* Set the buffering strategy here... */
420 /* If you change this, remember to change VidDispatchDeviceControl too */
421 MPDeviceObject->Flags |= DO_BUFFERED_IO;
425 RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension,
426 HwInitializationData->HwDeviceExtensionSize);
427 DPRINT("Searching on bus %d\n", DeviceExtension->SystemIoBusNumber);
428 /* Setup configuration info */
429 RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
430 ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO);
431 ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType;
432 ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
433 ConfigInfo.InterruptMode = (PCIBus == DeviceExtension->AdapterInterfaceType) ?
434 LevelSensitive : Latched;
436 /* Call HwFindAdapter entry point */
437 /* FIXME: Need to figure out what string to pass as param 3 */
438 Status = HwInitializationData->HwFindAdapter(&DeviceExtension->MiniPortDeviceExtension,
443 if (NO_ERROR != Status)
445 DPRINT("HwFindAdapter call failed with error %d\n", Status);
446 DeviceExtension->SystemIoBusNumber++;
449 while (NO_ERROR != Status && DeviceExtension->SystemIoBusNumber < MaxBus);
451 if (NO_ERROR != Status)
453 RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
454 IoDeleteDevice(MPDeviceObject);
458 DPRINT("Found adapter\n");
460 /* create symbolic link "\??\DISPLAYx" */
461 swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber+1);
462 RtlInitUnicodeString (&SymlinkName,
464 IoCreateSymbolicLink (&SymlinkName,
467 /* Add entry to DEVICEMAP\VIDEO key in registry */
468 swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DeviceNumber);
469 RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
473 DeviceExtension->RegistryPath.Buffer,
474 DeviceExtension->RegistryPath.Length + sizeof(WCHAR));
476 /* FIXME: Allocate hardware resources for device */
478 /* Allocate interrupt for device */
479 if (HwInitializationData->HwInterrupt != NULL &&
480 !(ConfigInfo.BusInterruptLevel == 0 &&
481 ConfigInfo.BusInterruptVector == 0))
484 DeviceExtension->IRQL = ConfigInfo.BusInterruptLevel;
485 DeviceExtension->InterruptLevel =
486 HalGetInterruptVector(ConfigInfo.AdapterInterfaceType,
487 ConfigInfo.SystemIoBusNumber,
488 ConfigInfo.BusInterruptLevel,
489 ConfigInfo.BusInterruptVector,
490 &DeviceExtension->IRQL,
491 &DeviceExtension->Affinity);
492 KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock);
493 Status = IoConnectInterrupt(&DeviceExtension->InterruptObject,
495 HwInitializationData->HwInterrupt,
496 &DeviceExtension->MiniPortDeviceExtension,
497 &DeviceExtension->InterruptSpinLock,
498 DeviceExtension->InterruptLevel,
499 DeviceExtension->IRQL,
500 DeviceExtension->IRQL,
501 ConfigInfo.InterruptMode,
503 DeviceExtension->Affinity,
505 if (!NT_SUCCESS(Status))
507 DPRINT("IoConnectInterrupt failed with status 0x%08x\n", Status);
508 IoDeleteDevice(MPDeviceObject);
518 /* FIXME: initialize timer routine for MP Driver */
519 if (HwInitializationData->HwTimer != NULL)
521 Status = IoInitializeTimer(MPDeviceObject,
523 HwInitializationData->HwTimer,
524 &DeviceExtension->MiniPortDeviceExtension);
525 if (!NT_SUCCESS(Status))
527 DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status);
529 if (HwInitializationData->HwInterrupt != NULL)
531 IoDisconnectInterrupt(DeviceExtension->InterruptObject);
533 IoDeleteDevice(MPDeviceObject);
539 return STATUS_SUCCESS;
543 VideoPortInt10(IN PVOID HwDeviceExtension,
544 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
546 KV86M_REGISTERS Regs;
549 DPRINT("VideoPortInt10\n");
550 KeAttachProcess(Csrss);
552 memset(&Regs, 0, sizeof(Regs));
553 Regs.Eax = BiosArguments->Eax;
554 Regs.Ebx = BiosArguments->Ebx;
555 Regs.Ecx = BiosArguments->Ecx;
556 Regs.Edx = BiosArguments->Edx;
557 Regs.Esi = BiosArguments->Esi;
558 Regs.Edi = BiosArguments->Edi;
559 Regs.Ebp = BiosArguments->Ebp;
560 Status = Ke386CallBios(0x10, &Regs);
569 VideoPortLogError(IN PVOID HwDeviceExtension,
570 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL,
571 IN VP_STATUS ErrorCode,
574 DPRINT("VideoPortLogError\n");
580 VideoPortMapBankedMemory(IN PVOID HwDeviceExtension,
581 IN PHYSICAL_ADDRESS PhysicalAddress,
584 OUT PVOID *VirtualAddress,
586 IN UCHAR ReadWriteBank,
587 IN PBANKED_SECTION_ROUTINE BankRoutine,
590 DPRINT("VideoPortMapBankedMemory\n");
596 VideoPortMapMemory(IN PVOID HwDeviceExtension,
597 IN PHYSICAL_ADDRESS PhysicalAddress,
600 OUT PVOID *VirtualAddress)
602 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
603 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
606 DPRINT("VideoPortMapMemory\n");
608 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
609 VIDEO_PORT_DEVICE_EXTENSION,
610 MiniPortDeviceExtension);
611 *VirtualAddress = InternalMapMemory(DeviceExtension, PhysicalAddress,
612 *Length, *InIoSpace);
614 return NULL == *VirtualAddress ? STATUS_NO_MEMORY : STATUS_SUCCESS;
619 VideoPortReadPortUchar(IN PUCHAR Port)
621 DPRINT("VideoPortReadPortUchar\n");
622 return READ_PORT_UCHAR(Port);
627 VideoPortReadPortUshort(IN PUSHORT Port)
629 DPRINT("VideoPortReadPortUshort\n");
630 return READ_PORT_USHORT(Port);
635 VideoPortReadPortUlong(IN PULONG Port)
637 DPRINT("VideoPortReadPortUlong\n");
638 return READ_PORT_ULONG(Port);
643 VideoPortReadPortBufferUchar(IN PUCHAR Port,
647 DPRINT("VideoPortReadPortBufferUchar\n");
648 READ_PORT_BUFFER_UCHAR(Port, Buffer, Count);
653 VideoPortReadPortBufferUshort(IN PUSHORT Port,
657 DPRINT("VideoPortReadPortBufferUshort\n");
658 READ_PORT_BUFFER_USHORT(Port, Buffer, Count);
663 VideoPortReadPortBufferUlong(IN PULONG Port,
667 DPRINT("VideoPortReadPortBufferUlong\n");
668 READ_PORT_BUFFER_ULONG(Port, Buffer, Count);
673 VideoPortReadRegisterUchar(IN PUCHAR Register)
675 DPRINT("VideoPortReadPortRegisterUchar\n");
676 return READ_REGISTER_UCHAR(Register);
681 VideoPortReadRegisterUshort(IN PUSHORT Register)
683 DPRINT("VideoPortReadPortRegisterUshort\n");
684 return READ_REGISTER_USHORT(Register);
689 VideoPortReadRegisterUlong(IN PULONG Register)
691 DPRINT("VideoPortReadPortRegisterUlong\n");
692 return READ_REGISTER_ULONG(Register);
697 VideoPortReadRegisterBufferUchar(IN PUCHAR Register,
701 DPRINT("VideoPortReadPortRegisterBufferUchar\n");
702 READ_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
707 VideoPortReadRegisterBufferUshort(IN PUSHORT Register,
711 DPRINT("VideoPortReadPortRegisterBufferUshort\n");
712 READ_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
717 VideoPortReadRegisterBufferUlong(IN PULONG Register,
721 DPRINT("VideoPortReadPortRegisterBufferUlong\n");
722 READ_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
727 VideoPortScanRom(IN PVOID HwDeviceExtension,
732 DPRINT("VideoPortScanRom\n");
738 VideoPortSetBusData(IN PVOID HwDeviceExtension,
739 IN BUS_DATA_TYPE BusDataType,
745 DPRINT("VideoPortSetBusData\n");
746 return HalSetBusDataByOffset(BusDataType,
756 VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension,
759 IN ULONG ValueLength)
761 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
763 DPRINT("VideoSetRegistryParameters\n");
765 assert_irql(PASSIVE_LEVEL);
767 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
768 VIDEO_PORT_DEVICE_EXTENSION,
769 MiniPortDeviceExtension);
770 return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
771 DeviceExtension->RegistryPath.Buffer,
780 VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension,
781 IN ULONG NumAccessRanges,
782 IN PVIDEO_ACCESS_RANGE AccessRange)
784 DPRINT("VideoPortSetTrappedEmulatorPorts\n");
790 VideoPortStartTimer(IN PVOID HwDeviceExtension)
792 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
794 DPRINT("VideoPortStartTimer\n");
796 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
797 VIDEO_PORT_DEVICE_EXTENSION,
798 MiniPortDeviceExtension);
799 IoStartTimer(DeviceExtension->DeviceObject);
804 VideoPortStopTimer(IN PVOID HwDeviceExtension)
806 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
808 DPRINT("VideoPortStopTimer\n");
810 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
811 VIDEO_PORT_DEVICE_EXTENSION,
812 MiniPortDeviceExtension);
813 IoStopTimer(DeviceExtension->DeviceObject);
818 VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension,
819 IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
820 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
823 DPRINT("VideoPortSynchronizeExecution\n");
829 VideoPortUnmapMemory(IN PVOID HwDeviceExtension,
830 IN PVOID VirtualAddress,
831 IN HANDLE ProcessHandle)
833 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
835 DPRINT("VideoPortFreeDeviceBase\n");
837 DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
838 VIDEO_PORT_DEVICE_EXTENSION,
839 MiniPortDeviceExtension);
841 InternalUnmapMemory(DeviceExtension, VirtualAddress);
843 return STATUS_SUCCESS;
848 VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension,
849 IN ULONG NumAccessRanges,
850 IN PVIDEO_ACCESS_RANGE AccessRanges)
852 DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
858 VideoPortWritePortUchar(IN PUCHAR Port,
861 DPRINT("VideoPortWritePortUchar\n");
862 WRITE_PORT_UCHAR(Port, Value);
867 VideoPortWritePortUshort(IN PUSHORT Port,
870 DPRINT("VideoPortWritePortUshort\n");
871 WRITE_PORT_USHORT(Port, Value);
876 VideoPortWritePortUlong(IN PULONG Port,
879 DPRINT("VideoPortWritePortUlong\n");
880 WRITE_PORT_ULONG(Port, Value);
885 VideoPortWritePortBufferUchar(IN PUCHAR Port,
889 DPRINT("VideoPortWritePortBufferUchar\n");
890 WRITE_PORT_BUFFER_UCHAR(Port, Buffer, Count);
895 VideoPortWritePortBufferUshort(IN PUSHORT Port,
899 DPRINT("VideoPortWritePortBufferUshort\n");
900 WRITE_PORT_BUFFER_USHORT(Port, Buffer, Count);
905 VideoPortWritePortBufferUlong(IN PULONG Port,
909 DPRINT("VideoPortWritePortBufferUlong\n");
910 WRITE_PORT_BUFFER_ULONG(Port, Buffer, Count);
915 VideoPortWriteRegisterUchar(IN PUCHAR Register,
918 DPRINT("VideoPortWriteRegisterUchar\n");
919 WRITE_REGISTER_UCHAR(Register, Value);
924 VideoPortWriteRegisterUshort(IN PUSHORT Register,
927 DPRINT("VideoPortWriteRegisterUshort\n");
928 WRITE_REGISTER_USHORT(Register, Value);
933 VideoPortWriteRegisterUlong(IN PULONG Register,
936 DPRINT("VideoPortWriteRegisterUlong\n");
937 WRITE_REGISTER_ULONG(Register, Value);
942 VideoPortWriteRegisterBufferUchar(IN PUCHAR Register,
946 DPRINT("VideoPortWriteRegisterBufferUchar\n");
947 WRITE_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
951 VideoPortWriteRegisterBufferUshort(IN PUSHORT Register,
955 DPRINT("VideoPortWriteRegisterBufferUshort\n");
956 WRITE_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
960 VideoPortWriteRegisterBufferUlong(IN PULONG Register,
964 DPRINT("VideoPortWriteRegisterBufferUlong\n");
965 WRITE_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
969 VideoPortZeroDeviceMemory(OUT PVOID Destination,
972 DPRINT("VideoPortZeroDeviceMemory\n");
973 RtlZeroMemory(Destination, Length);
977 // ------------------------------------------- Nondiscardable statics
979 // VidDispatchOpenClose
982 // Answer requests for Open/Close calls: a null operation
988 // Standard dispatch arguments
994 static NTSTATUS STDCALL
995 VidDispatchOpenClose(IN PDEVICE_OBJECT pDO,
998 PIO_STACK_LOCATION IrpStack;
999 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
1001 DPRINT("VidDispatchOpenClose() called\n");
1003 IrpStack = IoGetCurrentIrpStackLocation(Irp);
1005 if (IrpStack->MajorFunction == IRP_MJ_CREATE &&
1006 CsrssInitialized == FALSE)
1008 DPRINT("Referencing CSRSS\n");
1009 Csrss = PsGetCurrentProcess();
1010 CsrssInitialized = TRUE;
1011 DPRINT("Csrss %p\n", Csrss);
1012 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION) pDO->DeviceExtension;
1013 if (DeviceExtension->HwInitialize(&DeviceExtension->MiniPortDeviceExtension))
1015 Irp->IoStatus.Status = STATUS_SUCCESS;
1019 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
1024 Irp->IoStatus.Status = STATUS_SUCCESS;
1027 Irp->IoStatus.Information = FILE_OPENED;
1028 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1030 return STATUS_SUCCESS;
1036 // Get the next requested I/O packet started
1042 // Dispatch routine standard arguments
1049 VidStartIo(IN PDEVICE_OBJECT DeviceObject,
1052 DPRINT("VidStartIo\n");
1056 // VidDispatchDeviceControl
1059 // Answer requests for device control calls
1065 // Standard dispatch arguments
1071 static NTSTATUS STDCALL
1072 VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
1075 PIO_STACK_LOCATION IrpStack;
1076 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
1077 PVIDEO_REQUEST_PACKET vrp;
1079 DPRINT("VidDispatchDeviceControl\n");
1080 IrpStack = IoGetCurrentIrpStackLocation(Irp);
1081 DeviceExtension = DeviceObject->DeviceExtension;
1083 /* Translate the IRP to a VRP */
1084 vrp = ExAllocatePool(PagedPool, sizeof(VIDEO_REQUEST_PACKET));
1087 return STATUS_NO_MEMORY;
1089 vrp->StatusBlock = (PSTATUS_BLOCK) &(Irp->IoStatus);
1090 vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
1092 /* We're assuming METHOD_BUFFERED */
1093 vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer;
1094 vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
1095 vrp->OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
1096 vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
1098 /* Call the Miniport Driver with the VRP */
1099 DeviceObject->DriverObject->DriverStartIo((PVOID) &DeviceExtension->MiniPortDeviceExtension, (PIRP)vrp);
1104 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1106 return STATUS_SUCCESS;
1109 static PVOID STDCALL
1110 InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
1111 IN PHYSICAL_ADDRESS IoAddress,
1112 IN ULONG NumberOfUchars,
1115 PHYSICAL_ADDRESS TranslatedAddress;
1116 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
1118 PVOID MappedAddress;
1121 if (0 != (InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE))
1123 DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
1124 InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE;
1126 if (! IsListEmpty(&DeviceExtension->AddressMappingListHead))
1128 Entry = DeviceExtension->AddressMappingListHead.Flink;
1129 while (Entry != &DeviceExtension->AddressMappingListHead)
1131 AddressMapping = CONTAINING_RECORD(Entry,
1132 VIDEO_PORT_ADDRESS_MAPPING,
1134 if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart &&
1135 NumberOfUchars <= AddressMapping->NumberOfUchars)
1137 AddressMapping->MappingCount++;
1138 return AddressMapping->MappedAddress;
1140 Entry = Entry->Flink;
1144 AddressSpace = (ULONG)InIoSpace;
1145 if (HalTranslateBusAddress(DeviceExtension->AdapterInterfaceType,
1146 DeviceExtension->SystemIoBusNumber,
1149 &TranslatedAddress) == FALSE)
1153 if (AddressSpace != 0)
1155 assert(0 == TranslatedAddress.u.HighPart);
1156 return (PVOID) TranslatedAddress.u.LowPart;
1159 MappedAddress = MmMapIoSpace(TranslatedAddress,
1163 AddressMapping = ExAllocatePoolWithTag(PagedPool,
1164 sizeof(VIDEO_PORT_ADDRESS_MAPPING),
1166 if (AddressMapping == NULL)
1167 return MappedAddress;
1169 AddressMapping->MappedAddress = MappedAddress;
1170 AddressMapping->NumberOfUchars = NumberOfUchars;
1171 AddressMapping->IoAddress = IoAddress;
1172 AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
1173 AddressMapping->MappingCount = 1;
1175 InsertHeadList(&DeviceExtension->AddressMappingListHead,
1176 &AddressMapping->List);
1178 return MappedAddress;
1182 InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
1183 IN PVOID MappedAddress)
1185 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
1188 Entry = DeviceExtension->AddressMappingListHead.Flink;
1189 while (Entry != &DeviceExtension->AddressMappingListHead)
1191 AddressMapping = CONTAINING_RECORD(Entry,
1192 VIDEO_PORT_ADDRESS_MAPPING,
1194 if (AddressMapping->MappedAddress == MappedAddress)
1196 assert(0 <= AddressMapping->MappingCount);
1197 AddressMapping->MappingCount--;
1198 if (0 == AddressMapping->MappingCount)
1201 MmUnmapIoSpace(AddressMapping->MappedAddress,
1202 AddressMapping->NumberOfUchars);
1204 DPRINT("MmUnmapIoSpace(0x%08x, 0x%08x)\n", AddressMapping->MappedAddress, AddressMapping->NumberOfUchars);
1206 RemoveEntryList(Entry);
1207 ExFreePool(AddressMapping);
1213 Entry = Entry->Flink;