X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fdrivers%2Fvideo%2Fvideoprt%2Fvideoprt.c;h=6c1dbac1b184cde240bc74b726222e336d3ae394;hp=0dc6ff6693a0930ca5f6d8fea01b25bd96f85741;hb=e988d530263d2da68136336e07cc6c89304c57b1;hpb=fa714393ca0eeccddd257b3d19cf5bb21e079274 diff --git a/reactos/drivers/video/videoprt/videoprt.c b/reactos/drivers/video/videoprt/videoprt.c index 0dc6ff6693a..6c1dbac1b18 100644 --- a/reactos/drivers/video/videoprt/videoprt.c +++ b/reactos/drivers/video/videoprt/videoprt.c @@ -18,1361 +18,1240 @@ * If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id: videoprt.c,v 1.7 2004/03/06 08:39:06 jimtabor Exp $ + * $Id$ */ #include "videoprt.h" -BOOLEAN CsrssInitialized = FALSE; -PEPROCESS Csrss = NULL; -PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL; - -// ------------------------------------------------------- Public Interface - -// DriverEntry -// -// DESCRIPTION: -// This function initializes the driver. -// -// RUN LEVEL: -// PASSIVE_LEVEL -// -// ARGUMENTS: -// IN PDRIVER_OBJECT DriverObject System allocated Driver Object -// for this driver -// IN PUNICODE_STRING RegistryPath Name of registry driver service -// key -// -// RETURNS: -// NTSTATUS - -NTSTATUS STDCALL -DriverEntry(IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath) +/* GLOBAL VARIABLES ***********************************************************/ + +ULONG CsrssInitialized = FALSE; +PKPROCESS Csrss = NULL; + +/* PRIVATE FUNCTIONS **********************************************************/ + +NTSTATUS NTAPI +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) { - DPRINT("DriverEntry()\n"); - return(STATUS_SUCCESS); + return STATUS_SUCCESS; } -/* - * @implemented - */ -VOID -VideoPortDebugPrint(IN VIDEO_DEBUG_LEVEL DebugPrintLevel, - IN PCHAR DebugMessage, ...) +PVOID NTAPI +IntVideoPortImageDirectoryEntryToData( + PVOID BaseAddress, + ULONG Directory) { - char Buffer[256]; - va_list ap; + PIMAGE_NT_HEADERS NtHeader; + ULONG Va; -/* - if (DebugPrintLevel > InternalDebugLevel) - return; -*/ - va_start (ap, DebugMessage); - vsprintf (Buffer, DebugMessage, ap); - va_end (ap); - - DbgPrint (Buffer); + NtHeader = RtlImageNtHeader(BaseAddress); + if (NtHeader == NULL) + return NULL; + + if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes) + return NULL; + + Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress; + if (Va == 0) + return NULL; + + return (PVOID)((ULONG_PTR)BaseAddress + Va); } +PVOID NTAPI +IntVideoPortGetProcAddress( + IN PVOID HwDeviceExtension, + IN PUCHAR FunctionName) +{ + SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo; + PVOID BaseAddress; + PIMAGE_EXPORT_DIRECTORY ExportDir; + PUSHORT OrdinalPtr; + PULONG NamePtr; + PULONG AddressPtr; + ULONG i = 0; + NTSTATUS Status; + + DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName); + + RtlInitUnicodeString(&GdiDriverInfo.DriverName, L"videoprt"); + Status = ZwSetSystemInformation( + SystemLoadGdiDriverInformation, + &GdiDriverInfo, + sizeof(SYSTEM_GDI_DRIVER_INFORMATION)); + if (!NT_SUCCESS(Status)) + { + DPRINT("Couldn't get our own module handle?\n"); + return NULL; + } + + BaseAddress = GdiDriverInfo.ImageAddress; + + /* Get the pointer to the export directory */ + ExportDir = (PIMAGE_EXPORT_DIRECTORY)IntVideoPortImageDirectoryEntryToData( + BaseAddress, + IMAGE_DIRECTORY_ENTRY_EXPORT); + + /* Search by name */ + AddressPtr = (PULONG) + ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfFunctions); + OrdinalPtr = (PUSHORT) + ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNameOrdinals); + NamePtr = (PULONG) + ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNames); + for (i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++) + { + if (!_strnicmp((PCHAR)FunctionName, (PCHAR)((ULONG_PTR)BaseAddress + *NamePtr), + strlen((PCHAR)FunctionName))) + { + return (PVOID)((ULONG_PTR)BaseAddress + + (ULONG_PTR)AddressPtr[*OrdinalPtr]); + } + } + + DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName); + + return NULL; +} -/* - * @implemented - */ -VOID -STDCALL -VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension, - IN PVOID MappedAddress) +VOID NTAPI +IntVideoPortDeferredRoutine( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) { - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + PVOID HwDeviceExtension = + &((PVIDEO_PORT_DEVICE_EXTENSION)DeferredContext)->MiniPortDeviceExtension; + ((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2); +} - DPRINT("VideoPortFreeDeviceBase\n"); +ULONG NTAPI +IntVideoPortAllocateDeviceNumber(VOID) +{ + NTSTATUS Status; + ULONG DeviceNumber; + WCHAR SymlinkBuffer[20]; + UNICODE_STRING SymlinkName; - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); + for (DeviceNumber = 0;;) + { + OBJECT_ATTRIBUTES Obj; + HANDLE ObjHandle; - InternalUnmapMemory(DeviceExtension, MappedAddress); -} + swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber + 1); + RtlInitUnicodeString(&SymlinkName, SymlinkBuffer); + InitializeObjectAttributes(&Obj, &SymlinkName, 0, NULL, NULL); + Status = ZwOpenSymbolicLinkObject(&ObjHandle, GENERIC_READ, &Obj); + if (NT_SUCCESS(Status)) + { + ZwClose(ObjHandle); + DeviceNumber++; + continue; + } + else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + break; + else + { + DPRINT1("ZwOpenSymbolicLinkObject() returned unexpected status: 0x%08lx\n", Status); + return 0xFFFFFFFF; + } + } + return DeviceNumber; +} -/* - * @implemented - */ -ULONG -STDCALL -VideoPortGetBusData(IN PVOID HwDeviceExtension, - IN BUS_DATA_TYPE BusDataType, - IN ULONG SlotNumber, - OUT PVOID Buffer, - IN ULONG Offset, - IN ULONG Length) +NTSTATUS NTAPI +IntVideoPortCreateAdapterDeviceObject( + IN PDRIVER_OBJECT DriverObject, + IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension, + IN PDEVICE_OBJECT PhysicalDeviceObject, + OUT PDEVICE_OBJECT *DeviceObject OPTIONAL) { - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + ULONG DeviceNumber; + ULONG Size; + NTSTATUS Status; + WCHAR DeviceBuffer[20]; + UNICODE_STRING DeviceName; + PDEVICE_OBJECT DeviceObject_; + + if (DeviceObject == NULL) + DeviceObject = &DeviceObject_; + + /* + * Find the first free device number that can be used for video device + * object names and symlinks. + */ + + DeviceNumber = IntVideoPortAllocateDeviceNumber(); + if (DeviceNumber == 0xFFFFFFFF) + { + DPRINT("Can't find free device number\n"); + return STATUS_UNSUCCESSFUL; + } + + /* + * Create the device object. + */ + + /* Create a unicode device name. */ + swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber); + RtlInitUnicodeString(&DeviceName, DeviceBuffer); + + /* Create the device object. */ + Status = IoCreateDevice( + DriverObject, + sizeof(VIDEO_PORT_DEVICE_EXTENSION) + + DriverExtension->InitializationData.HwDeviceExtensionSize, + &DeviceName, + FILE_DEVICE_VIDEO, + 0, + TRUE, + DeviceObject); + + if (!NT_SUCCESS(Status)) + { + DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status); + return Status; + } + + /* + * Set the buffering strategy here. If you change this, remember + * to change VidDispatchDeviceControl too. + */ + + (*DeviceObject)->Flags |= DO_BUFFERED_IO; + + /* + * Initialize device extension. + */ + + DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)((*DeviceObject)->DeviceExtension); + DeviceExtension->DeviceNumber = DeviceNumber; + DeviceExtension->DriverObject = DriverObject; + DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; + DeviceExtension->FunctionalDeviceObject = *DeviceObject; + DeviceExtension->DriverExtension = DriverExtension; + + DeviceExtension->RegistryPath.Length = + DeviceExtension->RegistryPath.MaximumLength = + DriverExtension->RegistryPath.Length + (9 * sizeof(WCHAR)); + DeviceExtension->RegistryPath.Length -= sizeof(WCHAR); + DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag( + NonPagedPool, + DeviceExtension->RegistryPath.MaximumLength, + TAG_VIDEO_PORT); + swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device0", + DriverExtension->RegistryPath.Buffer); + + if (PhysicalDeviceObject != NULL) + { + /* Get bus number from the upper level bus driver. */ + Size = sizeof(ULONG); + Status = IoGetDeviceProperty( + PhysicalDeviceObject, + DevicePropertyBusNumber, + Size, + &DeviceExtension->SystemIoBusNumber, + &Size); + if (!NT_SUCCESS(Status)) + { + DPRINT("Couldn't get an information from bus driver. We will try to\n" + "use legacy detection method, but even that doesn't mean that\n" + "it will work.\n"); + DeviceExtension->PhysicalDeviceObject = NULL; + } + } + + DeviceExtension->AdapterInterfaceType = + DriverExtension->InitializationData.AdapterInterfaceType; + + if (PhysicalDeviceObject != NULL) + { + /* Get bus type from the upper level bus driver. */ + Size = sizeof(ULONG); + IoGetDeviceProperty( + PhysicalDeviceObject, + DevicePropertyLegacyBusType, + Size, + &DeviceExtension->AdapterInterfaceType, + &Size); + + /* Get bus device address from the upper level bus driver. */ + Size = sizeof(ULONG); + IoGetDeviceProperty( + PhysicalDeviceObject, + DevicePropertyAddress, + Size, + &DeviceExtension->SystemIoSlotNumber, + &Size); + } + + InitializeListHead(&DeviceExtension->AddressMappingListHead); + KeInitializeDpc( + &DeviceExtension->DpcObject, + IntVideoPortDeferredRoutine, + DeviceExtension); + + KeInitializeMutex(&DeviceExtension->DeviceLock, 0); + + /* Attach the device. */ + if (PhysicalDeviceObject != NULL) + DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack( + *DeviceObject, PhysicalDeviceObject); + + return STATUS_SUCCESS; +} - DPRINT("VideoPortGetBusData\n"); - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); +/* FIXME: we have to detach the device object in IntVideoPortFindAdapter if it fails */ +NTSTATUS NTAPI +IntVideoPortFindAdapter( + IN PDRIVER_OBJECT DriverObject, + IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension, + IN PDEVICE_OBJECT DeviceObject) +{ + WCHAR DeviceVideoBuffer[20]; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + ULONG Size; + NTSTATUS Status; + VIDEO_PORT_CONFIG_INFO ConfigInfo; + SYSTEM_BASIC_INFORMATION SystemBasicInfo; + UCHAR Again = FALSE; + WCHAR DeviceBuffer[20]; + UNICODE_STRING DeviceName; + WCHAR SymlinkBuffer[20]; + UNICODE_STRING SymlinkName; + BOOL LegacyDetection = FALSE; + ULONG DeviceNumber; + + DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + DeviceNumber = DeviceExtension->DeviceNumber; + + /* + * Setup a ConfigInfo structure that we will pass to HwFindAdapter. + */ + + RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO)); + ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO); + ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType; + if (ConfigInfo.AdapterInterfaceType == PCIBus) + ConfigInfo.InterruptMode = LevelSensitive; + else + ConfigInfo.InterruptMode = Latched; + ConfigInfo.DriverRegistryPath = DriverExtension->RegistryPath.Buffer; + ConfigInfo.VideoPortGetProcAddress = IntVideoPortGetProcAddress; + ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber; + ConfigInfo.BusInterruptLevel = DeviceExtension->InterruptLevel; + ConfigInfo.BusInterruptVector = DeviceExtension->InterruptVector; + + Size = sizeof(SystemBasicInfo); + Status = ZwQuerySystemInformation( + SystemBasicInformation, + &SystemBasicInfo, + Size, + &Size); + + if (NT_SUCCESS(Status)) + { + ConfigInfo.SystemMemorySize = + SystemBasicInfo.NumberOfPhysicalPages * + SystemBasicInfo.PageSize; + } + + /* + * Call miniport HwVidFindAdapter entry point to detect if + * particular device is present. There are two possible code + * paths. The first one is for Legacy drivers (NT4) and cases + * when we don't have information about what bus we're on. The + * second case is the standard one for Plug & Play drivers. + */ + if (DeviceExtension->PhysicalDeviceObject == NULL) + { + LegacyDetection = TRUE; + } + + if (LegacyDetection) + { + ULONG BusNumber, MaxBuses; + + MaxBuses = DeviceExtension->AdapterInterfaceType == PCIBus ? 8 : 1; + + for (BusNumber = 0; BusNumber < MaxBuses; BusNumber++) + { + DeviceExtension->SystemIoBusNumber = + ConfigInfo.SystemIoBusNumber = BusNumber; + + RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension, + DriverExtension->InitializationData.HwDeviceExtensionSize); + + /* FIXME: Need to figure out what string to pass as param 3. */ + Status = DriverExtension->InitializationData.HwFindAdapter( + &DeviceExtension->MiniPortDeviceExtension, + DriverExtension->HwContext, + NULL, + &ConfigInfo, + &Again); + + if (Status == ERROR_DEV_NOT_EXIST) + { + continue; + } + else if (Status == NO_ERROR) + { + break; + } + else + { + DPRINT("HwFindAdapter call failed with error 0x%X\n", Status); + RtlFreeUnicodeString(&DeviceExtension->RegistryPath); + IoDeleteDevice(DeviceObject); + + return Status; + } + } + } + else + { + /* FIXME: Need to figure out what string to pass as param 3. */ + Status = DriverExtension->InitializationData.HwFindAdapter( + &DeviceExtension->MiniPortDeviceExtension, + DriverExtension->HwContext, + NULL, + &ConfigInfo, + &Again); + } + + if (Status != NO_ERROR) + { + DPRINT("HwFindAdapter call failed with error 0x%X\n", Status); + RtlFreeUnicodeString(&DeviceExtension->RegistryPath); + IoDeleteDevice(DeviceObject); + return Status; + } + + /* + * Now we know the device is present, so let's do all additional tasks + * such as creating symlinks or setting up interrupts and timer. + */ + + /* Create a unicode device name. */ + swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber); + RtlInitUnicodeString(&DeviceName, DeviceBuffer); + + /* Create symbolic link "\??\DISPLAYx" */ + swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber + 1); + RtlInitUnicodeString(&SymlinkName, SymlinkBuffer); + IoCreateSymbolicLink(&SymlinkName, &DeviceName); + + /* Add entry to DEVICEMAP\VIDEO key in registry. */ + swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DeviceNumber); + RtlWriteRegistryValue( + RTL_REGISTRY_DEVICEMAP, + L"VIDEO", + DeviceVideoBuffer, + REG_SZ, + DeviceExtension->RegistryPath.Buffer, + DeviceExtension->RegistryPath.MaximumLength); + + /* FIXME: Allocate hardware resources for device. */ + + /* + * Allocate interrupt for device. + */ + + if (!IntVideoPortSetupInterrupt(DeviceObject, DriverExtension, &ConfigInfo)) + { + RtlFreeUnicodeString(&DeviceExtension->RegistryPath); + IoDeleteDevice(DeviceObject); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* + * Allocate timer for device. + */ + + if (!IntVideoPortSetupTimer(DeviceObject, DriverExtension)) + { + if (DeviceExtension->InterruptObject != NULL) + IoDisconnectInterrupt(DeviceExtension->InterruptObject); + RtlFreeUnicodeString(&DeviceExtension->RegistryPath); + IoDeleteDevice(DeviceObject); + DPRINT("STATUS_INSUFFICIENT_RESOURCES\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* + * Query children of the device. + */ + VideoPortEnumerateChildren(&DeviceExtension->MiniPortDeviceExtension, NULL); + + DPRINT("STATUS_SUCCESS\n"); + return STATUS_SUCCESS; +} - return HalGetBusDataByOffset(BusDataType, - DeviceExtension->SystemIoBusNumber, - SlotNumber, - Buffer, - Offset, - Length); +VOID FASTCALL +IntAttachToCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState) +{ + *CallingProcess = (PKPROCESS)PsGetCurrentProcess(); + if (*CallingProcess != Csrss) + { + KeStackAttachProcess(Csrss, ApcState); + } } +VOID FASTCALL +IntDetachFromCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState) +{ + if (*CallingProcess != Csrss) + { + KeUnstackDetachProcess(ApcState); + } +} + +/* PUBLIC FUNCTIONS ***********************************************************/ /* * @implemented */ -UCHAR -STDCALL -VideoPortGetCurrentIrql(VOID) + +ULONG NTAPI +VideoPortInitialize( + IN PVOID Context1, + IN PVOID Context2, + IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData, + IN PVOID HwContext) { - DPRINT("VideoPortGetCurrentIrql\n"); - return KeGetCurrentIrql(); -} + PDRIVER_OBJECT DriverObject = Context1; + PUNICODE_STRING RegistryPath = Context2; + NTSTATUS Status; + PVIDEO_PORT_DRIVER_EXTENSION DriverExtension; + BOOL LegacyDetection = FALSE; + + DPRINT("VideoPortInitialize\n"); + + /* + * As a first thing do parameter checks. + */ + + if (HwInitializationData->HwInitDataSize > sizeof(VIDEO_HW_INITIALIZATION_DATA)) + { + return STATUS_REVISION_MISMATCH; + } + + if (HwInitializationData->HwFindAdapter == NULL || + HwInitializationData->HwInitialize == NULL || + HwInitializationData->HwStartIO == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + /* + * NOTE: + * The driver extension can be already allocated in case that we were + * called by legacy driver and failed detecting device. Some miniport + * drivers in that case adjust parameters and call VideoPortInitialize + * again. + */ + + DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject); + if (DriverExtension == NULL) + { + Status = IoAllocateDriverObjectExtension( + DriverObject, + DriverObject, + sizeof(VIDEO_PORT_DRIVER_EXTENSION), + (PVOID *)&DriverExtension); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* + * Save the registry path. This should be done only once even if + * VideoPortInitialize is called multiple times. + */ + + if (RegistryPath->Length != 0) + { + DriverExtension->RegistryPath.Length = 0; + DriverExtension->RegistryPath.MaximumLength = + RegistryPath->Length + sizeof(UNICODE_NULL); + DriverExtension->RegistryPath.Buffer = + ExAllocatePoolWithTag( + PagedPool, + DriverExtension->RegistryPath.MaximumLength, + TAG('U', 'S', 'T', 'R')); + if (DriverExtension->RegistryPath.Buffer == NULL) + { + RtlInitUnicodeString(&DriverExtension->RegistryPath, NULL); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlCopyUnicodeString(&DriverExtension->RegistryPath, RegistryPath); + } + else + { + RtlInitUnicodeString(&DriverExtension->RegistryPath, NULL); + } + } + + /* + * Copy the correct miniport initializtation data to the device extension. + */ + + RtlCopyMemory( + &DriverExtension->InitializationData, + HwInitializationData, + HwInitializationData->HwInitDataSize); + if (HwInitializationData->HwInitDataSize < + sizeof(VIDEO_HW_INITIALIZATION_DATA)) + { + RtlZeroMemory((PVOID)((ULONG_PTR)&DriverExtension->InitializationData + + HwInitializationData->HwInitDataSize), + sizeof(VIDEO_HW_INITIALIZATION_DATA) - + HwInitializationData->HwInitDataSize); + } + DriverExtension->HwContext = HwContext; + + switch (HwInitializationData->HwInitDataSize) + { + /* + * NT4 drivers are special case, because we must use legacy method + * of detection instead of the Plug & Play one. + */ + + case SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA: + DPRINT("We were loaded by a Windows NT miniport driver.\n"); + LegacyDetection = TRUE; + break; + + case SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA: + DPRINT("We were loaded by a Windows 2000 miniport driver.\n"); + break; + + case sizeof(VIDEO_HW_INITIALIZATION_DATA): + DPRINT("We were loaded by a Windows XP or later miniport driver.\n"); + break; + + default: + DPRINT("Invalid HwInitializationData size.\n"); + return STATUS_UNSUCCESSFUL; + } + + DriverObject->MajorFunction[IRP_MJ_CREATE] = IntVideoPortDispatchOpen; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = IntVideoPortDispatchClose; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IntVideoPortDispatchDeviceControl; + DriverObject->MajorFunction[IRP_MJ_WRITE] = IntVideoPortDispatchWrite; + DriverObject->DriverUnload = IntVideoPortUnload; + + /* + * Plug & Play drivers registers the device in AddDevice routine. For + * legacy drivers we must do it now. + */ + + if (LegacyDetection) + { + PDEVICE_OBJECT DeviceObject; + Status = IntVideoPortCreateAdapterDeviceObject(DriverObject, DriverExtension, + NULL, &DeviceObject); + DPRINT("IntVideoPortCreateAdapterDeviceObject returned 0x%x\n", Status); + if (!NT_SUCCESS(Status)) + return Status; + Status = IntVideoPortFindAdapter(DriverObject, DriverExtension, DeviceObject); + DPRINT("IntVideoPortFindAdapter returned 0x%x\n", Status); + return Status; + } + else + { + DriverObject->DriverExtension->AddDevice = IntVideoPortAddDevice; + DriverObject->MajorFunction[IRP_MJ_PNP] = IntVideoPortDispatchPnp; + DriverObject->MajorFunction[IRP_MJ_POWER] = IntVideoPortDispatchPower; + + return STATUS_SUCCESS; + } +} /* * @implemented */ -PVOID -STDCALL -VideoPortGetDeviceBase(IN PVOID HwDeviceExtension, - IN PHYSICAL_ADDRESS IoAddress, - IN ULONG NumberOfUchars, - IN UCHAR InIoSpace) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - DPRINT("VideoPortGetDeviceBase\n"); +VOID +VideoPortDebugPrint( + IN VIDEO_DEBUG_LEVEL DebugPrintLevel, + IN PCHAR DebugMessage, ...) +{ + char Buffer[256]; + va_list ap; - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); + va_start(ap, DebugMessage); + vsprintf(Buffer, DebugMessage, ap); + va_end(ap); - return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace, NULL); + DbgPrint(Buffer); } - /* * @unimplemented */ -VP_STATUS -STDCALL -VideoPortGetDeviceData(IN PVOID HwDeviceExtension, - IN VIDEO_DEVICE_DATA_TYPE DeviceDataType, - IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine, - IN PVOID Context) + +VOID NTAPI +VideoPortLogError( + IN PVOID HwDeviceExtension, + IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL, + IN VP_STATUS ErrorCode, + IN ULONG UniqueId) { - DPRINT("VideoPortGetDeviceData\n"); - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n", + ErrorCode, ErrorCode, UniqueId, UniqueId); + if (NULL != Vrp) + { + DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp->IoControlCode, Vrp->IoControlCode); + } } - /* * @implemented */ -VP_STATUS -STDCALL -VideoPortGetAccessRanges(IN PVOID HwDeviceExtension, - IN ULONG NumRequestedResources, - IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL, - IN ULONG NumAccessRanges, - IN PVIDEO_ACCESS_RANGE AccessRanges, - IN PVOID VendorId, - IN PVOID DeviceId, - IN PULONG Slot) + +UCHAR NTAPI +VideoPortGetCurrentIrql(VOID) { - PCI_SLOT_NUMBER PciSlotNumber; - BOOLEAN FoundDevice; - ULONG FunctionNumber; - PCI_COMMON_CONFIG Config; - PCM_RESOURCE_LIST AllocatedResources; - NTSTATUS Status; - UINT AssignedCount; - CM_FULL_RESOURCE_DESCRIPTOR *FullList; - CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor; - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT("VideoPortGetAccessRanges\n"); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - if (0 == NumRequestedResources && PCIBus == DeviceExtension->AdapterInterfaceType) - { - if (DeviceId != NULL && VendorId != NULL) - { - DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n", (int)*((USHORT *) VendorId), - (int)*((USHORT *) DeviceId)); - } - FoundDevice = FALSE; - PciSlotNumber.u.AsULONG = *Slot; - for (FunctionNumber = 0; ! FoundDevice && FunctionNumber < 8; FunctionNumber++) - { - PciSlotNumber.u.bits.FunctionNumber = FunctionNumber; - if (sizeof(PCI_COMMON_CONFIG) == - HalGetBusDataByOffset(PCIConfiguration, DeviceExtension->SystemIoBusNumber, - PciSlotNumber.u.AsULONG,&Config, 0, - sizeof(PCI_COMMON_CONFIG))) - { - if (DeviceId != NULL && VendorId != NULL) - { - DPRINT("Slot 0x%02x (Device %d Function %d) VendorId 0x%04x DeviceId 0x%04x\n", - PciSlotNumber.u.AsULONG, PciSlotNumber.u.bits.DeviceNumber, - PciSlotNumber.u.bits.FunctionNumber, Config.VendorID, Config.DeviceID); - } - - FoundDevice = (VendorId == NULL || Config.VendorID == *((USHORT *) VendorId)) && - (DeviceId == NULL || Config.DeviceID == *((USHORT *) DeviceId)); - } - } - if (! FoundDevice) - { - return STATUS_UNSUCCESSFUL; - } - Status = HalAssignSlotResources(NULL, NULL, NULL, NULL, - DeviceExtension->AdapterInterfaceType, - DeviceExtension->SystemIoBusNumber, - PciSlotNumber.u.AsULONG, &AllocatedResources); - if (! NT_SUCCESS(Status)) - { - return Status; - } - AssignedCount = 0; - for (FullList = AllocatedResources->List; - FullList < AllocatedResources->List + AllocatedResources->Count; - FullList++) - { - assert(FullList->InterfaceType == PCIBus && - FullList->BusNumber == DeviceExtension->SystemIoBusNumber && - 1 == FullList->PartialResourceList.Version && - 1 == FullList->PartialResourceList.Revision); - for (Descriptor = FullList->PartialResourceList.PartialDescriptors; - Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count; - Descriptor++) - { - if ((CmResourceTypeMemory == Descriptor->Type - || CmResourceTypePort == Descriptor->Type) - && NumAccessRanges <= AssignedCount) - { - DPRINT1("Too many access ranges found\n"); - ExFreePool(AllocatedResources); - return STATUS_UNSUCCESSFUL; - } - if (CmResourceTypeMemory == Descriptor->Type) - { - if (NumAccessRanges <= AssignedCount) - { - DPRINT1("Too many access ranges found\n"); - ExFreePool(AllocatedResources); - return STATUS_UNSUCCESSFUL; - } - DPRINT("Memory range starting at 0x%08x length 0x%08x\n", - Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length); - AccessRanges[AssignedCount].RangeStart = Descriptor->u.Memory.Start; - AccessRanges[AssignedCount].RangeLength = Descriptor->u.Memory.Length; - AccessRanges[AssignedCount].RangeInIoSpace = 0; - AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */ - AccessRanges[AssignedCount].RangeShareable = - (CmResourceShareShared == Descriptor->ShareDisposition); - AssignedCount++; - } - else if (CmResourceTypePort == Descriptor->Type) - { - DPRINT("Port range starting at 0x%04x length %d\n", - Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length); - AccessRanges[AssignedCount].RangeStart = Descriptor->u.Port.Start; - AccessRanges[AssignedCount].RangeLength = Descriptor->u.Port.Length; - AccessRanges[AssignedCount].RangeInIoSpace = 1; - AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */ - AccessRanges[AssignedCount].RangeShareable = 0; - AssignedCount++; - } - else if (CmResourceTypeInterrupt == Descriptor->Type) - { - DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level; - DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector; - } - } - } - ExFreePool(AllocatedResources); - } - else - { - UNIMPLEMENTED - } - - return STATUS_SUCCESS; + return KeGetCurrentIrql(); } typedef struct QueryRegistryCallbackContext { - PVOID HwDeviceExtension; - PVOID HwContext; - PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine; + PVOID HwDeviceExtension; + PVOID HwContext; + PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine; } QUERY_REGISTRY_CALLBACK_CONTEXT, *PQUERY_REGISTRY_CALLBACK_CONTEXT; -static NTSTATUS STDCALL -QueryRegistryCallback(IN PWSTR ValueName, - IN ULONG ValueType, - IN PVOID ValueData, - IN ULONG ValueLength, - IN PVOID Context, - IN PVOID EntryContext) +static NTSTATUS NTAPI +QueryRegistryCallback( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext) { - PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext = (PQUERY_REGISTRY_CALLBACK_CONTEXT) Context; - - DPRINT("Found registry value for name %S: type %d, length %d\n", - ValueName, ValueType, ValueLength); - return (*(CallbackContext->HwGetRegistryRoutine))(CallbackContext->HwDeviceExtension, - CallbackContext->HwContext, - ValueName, - ValueData, - ValueLength); + PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext = (PQUERY_REGISTRY_CALLBACK_CONTEXT) Context; + + DPRINT("Found registry value for name %S: type %d, length %d\n", + ValueName, ValueType, ValueLength); + return (*(CallbackContext->HwGetRegistryRoutine))( + CallbackContext->HwDeviceExtension, + CallbackContext->HwContext, + ValueName, + ValueData, + ValueLength); } /* * @unimplemented */ -VP_STATUS -STDCALL -VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension, - IN PWSTR ParameterName, - IN UCHAR IsParameterFileName, - IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine, - IN PVOID HwContext) + +VP_STATUS NTAPI +VideoPortGetRegistryParameters( + IN PVOID HwDeviceExtension, + IN PWSTR ParameterName, + IN UCHAR IsParameterFileName, + IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine, + IN PVOID HwContext) { - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - QUERY_REGISTRY_CALLBACK_CONTEXT Context; - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + QUERY_REGISTRY_CALLBACK_CONTEXT Context; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName); + DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName); - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); - if (IsParameterFileName) - { + if (IsParameterFileName) + { UNIMPLEMENTED; - } - - DPRINT("ParameterName %S\n", ParameterName); - - Context.HwDeviceExtension = HwDeviceExtension; - Context.HwContext = HwContext; - Context.HwGetRegistryRoutine = GetRegistryRoutine; - - QueryTable[0].QueryRoutine = QueryRegistryCallback; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; - QueryTable[0].Name = ParameterName; - QueryTable[0].EntryContext = NULL; - QueryTable[0].DefaultType = REG_NONE; - QueryTable[0].DefaultData = NULL; - QueryTable[0].DefaultLength = 0; - - QueryTable[1].QueryRoutine = NULL; - QueryTable[1].Name = NULL; - - return NT_SUCCESS(RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - DeviceExtension->RegistryPath.Buffer, - QueryTable, &Context, NULL)) - ? ERROR_SUCCESS : ERROR_INVALID_PARAMETER; + } + + Context.HwDeviceExtension = HwDeviceExtension; + Context.HwContext = HwContext; + Context.HwGetRegistryRoutine = GetRegistryRoutine; + + QueryTable[0].QueryRoutine = QueryRegistryCallback; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; + QueryTable[0].Name = ParameterName; + QueryTable[0].EntryContext = NULL; + QueryTable[0].DefaultType = REG_NONE; + QueryTable[0].DefaultData = NULL; + QueryTable[0].DefaultLength = 0; + + QueryTable[1].QueryRoutine = NULL; + QueryTable[1].Name = NULL; + + return NT_SUCCESS(RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + DeviceExtension->RegistryPath.Buffer, + QueryTable, + &Context, + NULL)) ? ERROR_SUCCESS : ERROR_INVALID_PARAMETER; } - /* * @implemented - */ -VP_STATUS -STDCALL -VideoPortGetVgaStatus(IN PVOID HwDeviceExtension, - OUT PULONG VgaStatus) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT1("VideoPortGetVgaStatus = %S \n", VgaStatus); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - if(KeGetCurrentIrql() == PASSIVE_LEVEL) - { - DPRINT1("VideoPortGetVgaStatus1 = %S \n", VgaStatus); - - if ( PCIBus == DeviceExtension->AdapterInterfaceType) - { -/* - VgaStatus 0 == VGA not enabled, 1 == VGA enabled. */ - DPRINT1("VideoPortGetVgaStatus2 = %S \n", VgaStatus); - - /* Assumed for now */ - - VgaStatus = (PULONG) 1; - - return STATUS_SUCCESS; - } - } - DPRINT1("VideoPortGetVgaStatus3 = %S \n", VgaStatus); - - return ERROR_INVALID_FUNCTION; -} - -static BOOLEAN -VPInterruptRoutine(IN struct _KINTERRUPT *Interrupt, - IN PVOID ServiceContext) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DeviceExtension = ServiceContext; - assert(NULL != DeviceExtension->HwInterrupt); - return DeviceExtension->HwInterrupt(&DeviceExtension->MiniPortDeviceExtension); -} - -static VOID STDCALL -VPTimerRoutine(IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) +VP_STATUS NTAPI +VideoPortSetRegistryParameters( + IN PVOID HwDeviceExtension, + IN PWSTR ValueName, + IN PVOID ValueData, + IN ULONG ValueLength) { - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DeviceExtension = Context; - assert(DeviceExtension == DeviceObject->DeviceExtension - && NULL != DeviceExtension->HwTimer); - - DeviceExtension->HwTimer(&DeviceExtension->MiniPortDeviceExtension); + DPRINT("VideoPortSetRegistryParameters\n"); + ASSERT_IRQL(PASSIVE_LEVEL); + return RtlWriteRegistryValue( + RTL_REGISTRY_ABSOLUTE, + VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->RegistryPath.Buffer, + ValueName, + REG_BINARY, + ValueData, + ValueLength); } /* * @implemented */ -ULONG STDCALL -VideoPortInitialize(IN PVOID Context1, - IN PVOID Context2, - IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData, - IN PVOID HwContext) -{ - PUNICODE_STRING RegistryPath; - UCHAR Again = FALSE; - WCHAR DeviceBuffer[20]; - WCHAR SymlinkBuffer[20]; - WCHAR DeviceVideoBuffer[20]; - NTSTATUS Status; - PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1; - PDEVICE_OBJECT MPDeviceObject; - VIDEO_PORT_CONFIG_INFO ConfigInfo; - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - ULONG DisplayNumber; - UNICODE_STRING DeviceName; - UNICODE_STRING SymlinkName; - ULONG MaxBus; - ULONG MaxLen; - KIRQL IRQL; - KAFFINITY Affinity; - ULONG InterruptVector; - OBJECT_ATTRIBUTES Obj; - HANDLE ObjHandle; - - DPRINT("VideoPortInitialize\n"); - - RegistryPath = (PUNICODE_STRING) Context2; - - /* Build Dispatch table from passed data */ - MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO; - - /* Find the first free device number */ - for (DisplayNumber = 0;;) - { - swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DisplayNumber + 1); - RtlInitUnicodeString(&SymlinkName, SymlinkBuffer); - InitializeObjectAttributes(&Obj, &SymlinkName, 0, NULL, NULL); - Status = ZwOpenSymbolicLinkObject(&ObjHandle, GENERIC_READ, &Obj); - if (NT_SUCCESS(Status)) - { - ZwClose(ObjHandle); - DisplayNumber++; - continue; - } - else if (Status == STATUS_NOT_FOUND || Status == STATUS_UNSUCCESSFUL) - { - break; - } - else - { - return Status; - } - } - - DPRINT("- DisplayNumber: %d\n", DisplayNumber); - - Again = FALSE; - - do - { - /* Create a unicode device name. */ - swprintf(DeviceBuffer, L"\\Device\\Video%lu", DisplayNumber); - RtlInitUnicodeString(&DeviceName, DeviceBuffer); - - /* Create the device. */ - Status = IoCreateDevice( - MPDriverObject, - HwInitializationData->HwDeviceExtensionSize + - sizeof(VIDEO_PORT_DEVICE_EXTENSION), - &DeviceName, - FILE_DEVICE_VIDEO, - 0, - TRUE, - &MPDeviceObject); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status); - return Status; - } - - MPDriverObject->DeviceObject = MPDeviceObject; - - /* Initialize the miniport drivers dispatch table */ - MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpen; - MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchClose; - MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl; - - /* Initialize our device extension */ - DeviceExtension = - (PVIDEO_PORT_DEVICE_EXTENSION) MPDeviceObject->DeviceExtension; - DeviceExtension->DeviceObject = MPDeviceObject; - DeviceExtension->HwInitialize = HwInitializationData->HwInitialize; - DeviceExtension->HwResetHw = HwInitializationData->HwResetHw; - DeviceExtension->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType; - DeviceExtension->SystemIoBusNumber = 0; - MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR); - DeviceExtension->RegistryPath.MaximumLength = MaxLen; - DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, - MaxLen, - TAG_VIDEO_PORT); - swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device0", - RegistryPath->Buffer); - DeviceExtension->RegistryPath.Length = wcslen(DeviceExtension->RegistryPath.Buffer) * - sizeof(WCHAR); - - MaxBus = (DeviceExtension->AdapterInterfaceType == PCIBus) ? 8 : 1; - DPRINT("MaxBus: %lu\n", MaxBus); - InitializeListHead(&DeviceExtension->AddressMappingListHead); - - /* Set the buffering strategy here... */ - /* If you change this, remember to change VidDispatchDeviceControl too */ - MPDeviceObject->Flags |= DO_BUFFERED_IO; - - do - { - RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension, - HwInitializationData->HwDeviceExtensionSize); - DPRINT("Searching on bus %d\n", DeviceExtension->SystemIoBusNumber); - /* Setup configuration info */ - RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO)); - ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO); - ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType; - ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber; - ConfigInfo.InterruptMode = (PCIBus == DeviceExtension->AdapterInterfaceType) ? - LevelSensitive : Latched; - - /* Call HwFindAdapter entry point */ - /* FIXME: Need to figure out what string to pass as param 3 */ - Status = HwInitializationData->HwFindAdapter(&DeviceExtension->MiniPortDeviceExtension, - Context2, - NULL, - &ConfigInfo, - &Again); - if (NO_ERROR != Status) - { - DPRINT("HwFindAdapter call failed with error %d\n", Status); - DeviceExtension->SystemIoBusNumber++; - } - } - while (NO_ERROR != Status && DeviceExtension->SystemIoBusNumber < MaxBus); - - if (NO_ERROR != Status) - { - RtlFreeUnicodeString(&DeviceExtension->RegistryPath); - IoDeleteDevice(MPDeviceObject); - - return Status; - } - DPRINT("Found adapter\n"); - - /* create symbolic link "\??\DISPLAYx" */ - swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DisplayNumber + 1); - RtlInitUnicodeString (&SymlinkName, - SymlinkBuffer); - IoCreateSymbolicLink (&SymlinkName, - &DeviceName); - - /* Add entry to DEVICEMAP\VIDEO key in registry */ - swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DisplayNumber); - RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, - L"VIDEO", - DeviceVideoBuffer, - REG_SZ, - DeviceExtension->RegistryPath.Buffer, - DeviceExtension->RegistryPath.Length + sizeof(WCHAR)); - - /* FIXME: Allocate hardware resources for device */ - - /* Allocate interrupt for device */ - DeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt; - if (0 == ConfigInfo.BusInterruptVector) - { - ConfigInfo.BusInterruptVector = DeviceExtension->InterruptVector; - } - if (0 == ConfigInfo.BusInterruptLevel) - { - ConfigInfo.BusInterruptLevel = DeviceExtension->InterruptLevel; - } - if (NULL != HwInitializationData->HwInterrupt) - { - InterruptVector = - HalGetInterruptVector(ConfigInfo.AdapterInterfaceType, - ConfigInfo.SystemIoBusNumber, - ConfigInfo.BusInterruptLevel, - ConfigInfo.BusInterruptVector, - &IRQL, - &Affinity); - if (0 == InterruptVector) - { - DPRINT1("HalGetInterruptVector failed\n"); - IoDeleteDevice(MPDeviceObject); - - return STATUS_INSUFFICIENT_RESOURCES; - } - KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock); - Status = IoConnectInterrupt(&DeviceExtension->InterruptObject, - VPInterruptRoutine, - DeviceExtension, - &DeviceExtension->InterruptSpinLock, - InterruptVector, - IRQL, - IRQL, - ConfigInfo.InterruptMode, - FALSE, - Affinity, - FALSE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IoConnectInterrupt failed with status 0x%08x\n", Status); - IoDeleteDevice(MPDeviceObject); - - return Status; - } - } - DisplayNumber++; - } - while (Again); - - DeviceExtension->HwTimer = HwInitializationData->HwTimer; - if (HwInitializationData->HwTimer != NULL) - { - DPRINT("Initializing timer\n"); - Status = IoInitializeTimer(MPDeviceObject, - VPTimerRoutine, - DeviceExtension); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status); - - if (HwInitializationData->HwInterrupt != NULL) - { - IoDisconnectInterrupt(DeviceExtension->InterruptObject); - } - IoDeleteDevice(MPDeviceObject); - - return Status; - } - } - - return STATUS_SUCCESS; -} -/* - * @unimplemented - */ -VOID -STDCALL -VideoPortLogError(IN PVOID HwDeviceExtension, - IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL, - IN VP_STATUS ErrorCode, - IN ULONG UniqueId) +VP_STATUS NTAPI +VideoPortGetVgaStatus( + IN PVOID HwDeviceExtension, + OUT PULONG VgaStatus) { - DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n", - ErrorCode, ErrorCode, UniqueId, UniqueId); - if (NULL != Vrp) - { - DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp->IoControlCode, Vrp->IoControlCode); - } + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortGetVgaStatus\n"); + + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + if (KeGetCurrentIrql() == PASSIVE_LEVEL) + { + if (DeviceExtension->AdapterInterfaceType == PCIBus) + { + /* VgaStatus: 0 == VGA not enabled, 1 == VGA enabled. */ + /* Assumed for now */ + *VgaStatus = 1; + return NO_ERROR; + } + } + + return ERROR_INVALID_FUNCTION; } - -/* - * @unimplemented - */ -VP_STATUS -STDCALL -VideoPortMapBankedMemory(IN PVOID HwDeviceExtension, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN PULONG Length, - IN PULONG InIoSpace, - OUT PVOID *VirtualAddress, - IN ULONG BankLength, - IN UCHAR ReadWriteBank, - IN PBANKED_SECTION_ROUTINE BankRoutine, - IN PVOID Context) -{ - DPRINT("VideoPortMapBankedMemory\n"); - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - /* * @implemented */ -VP_STATUS -STDCALL -VideoPortMapMemory(IN PVOID HwDeviceExtension, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN PULONG Length, - IN PULONG InIoSpace, - OUT PVOID *VirtualAddress) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - NTSTATUS Status; - - DPRINT("VideoPortMapMemory\n"); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - *VirtualAddress = InternalMapMemory(DeviceExtension, PhysicalAddress, - *Length, *InIoSpace, &Status); - return Status; +PVOID NTAPI +VideoPortGetRomImage( + IN PVOID HwDeviceExtension, + IN PVOID Unused1, + IN ULONG Unused2, + IN ULONG Length) +{ + static PVOID RomImageBuffer = NULL; + PKPROCESS CallingProcess; + KAPC_STATE ApcState; + + DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n", + HwDeviceExtension, Length); + + /* If the length is zero then free the existing buffer. */ + if (Length == 0) + { + if (RomImageBuffer != NULL) + { + ExFreePool(RomImageBuffer); + RomImageBuffer = NULL; + } + return NULL; + } + else + { + /* + * The DDK says we shouldn't use the legacy C0000 method but get the + * rom base address from the corresponding pci or acpi register but + * lets ignore that and use C0000 anyway. We have already mapped the + * bios area into memory so we'll copy from there. + */ + + /* Copy the bios. */ + Length = min(Length, 0x10000); + if (RomImageBuffer != NULL) + { + ExFreePool(RomImageBuffer); + } + + RomImageBuffer = ExAllocatePool(PagedPool, Length); + if (RomImageBuffer == NULL) + { + return NULL; + } + + IntAttachToCSRSS(&CallingProcess, &ApcState); + RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length); + IntDetachFromCSRSS(&CallingProcess, &ApcState); + + return RomImageBuffer; + } } - /* * @implemented */ -BOOLEAN -STDCALL -VideoPortScanRom(IN PVOID HwDeviceExtension, - IN PUCHAR RomBase, - IN ULONG RomLength, - IN PUCHAR String) + +BOOLEAN NTAPI +VideoPortScanRom( + IN PVOID HwDeviceExtension, + IN PUCHAR RomBase, + IN ULONG RomLength, + IN PUCHAR String) { - ULONG StringLength; - BOOLEAN Found; - PUCHAR SearchLocation; - - DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase, RomLength, String); - - StringLength = strlen(String); - Found = FALSE; - SearchLocation = RomBase; - for (SearchLocation = RomBase; - ! Found && SearchLocation < RomBase + RomLength - StringLength; - SearchLocation++) - { + ULONG StringLength; + BOOLEAN Found; + PUCHAR SearchLocation; + + DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase, RomLength, String); + + StringLength = strlen((PCHAR)String); + Found = FALSE; + SearchLocation = RomBase; + for (SearchLocation = RomBase; + !Found && SearchLocation < RomBase + RomLength - StringLength; + SearchLocation++) + { Found = (RtlCompareMemory(SearchLocation, String, StringLength) == StringLength); if (Found) - { - DPRINT("Match found at %p\n", SearchLocation); - } - } + { + DPRINT("Match found at %p\n", SearchLocation); + } + } - return Found; + return Found; } - /* * @implemented */ -ULONG -STDCALL -VideoPortSetBusData(IN PVOID HwDeviceExtension, - IN BUS_DATA_TYPE BusDataType, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length) + +BOOLEAN NTAPI +VideoPortSynchronizeExecution( + IN PVOID HwDeviceExtension, + IN VIDEO_SYNCHRONIZE_PRIORITY Priority, + IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine, + OUT PVOID Context) { - DPRINT("VideoPortSetBusData\n"); - return HalSetBusDataByOffset(BusDataType, - 0, - SlotNumber, - Buffer, - Offset, - Length); + BOOLEAN Ret; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + KIRQL OldIrql; + + switch (Priority) + { + case VpLowPriority: + Ret = (*SynchronizeRoutine)(Context); + break; + + case VpMediumPriority: + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + if (DeviceExtension->InterruptObject == NULL) + Ret = (*SynchronizeRoutine)(Context); + else + Ret = KeSynchronizeExecution( + DeviceExtension->InterruptObject, + SynchronizeRoutine, + Context); + break; + + case VpHighPriority: + OldIrql = KeGetCurrentIrql(); + if (OldIrql < SYNCH_LEVEL) + OldIrql = KfRaiseIrql(SYNCH_LEVEL); + + Ret = (*SynchronizeRoutine)(Context); + + if (OldIrql < SYNCH_LEVEL) + KfLowerIrql(OldIrql); + break; + + default: + Ret = FALSE; + } + + return Ret; } - /* * @implemented */ -VP_STATUS -STDCALL -VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension, - IN PWSTR ValueName, - IN PVOID ValueData, - IN ULONG ValueLength) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - DPRINT("VideoSetRegistryParameters\n"); +VP_STATUS NTAPI +VideoPortEnumerateChildren( + IN PVOID HwDeviceExtension, + IN PVOID Reserved) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + ULONG Status; + VIDEO_CHILD_ENUM_INFO ChildEnumInfo; + VIDEO_CHILD_TYPE ChildType; + UCHAR ChildDescriptor[256]; + ULONG ChildId; + ULONG Unused; + INT i; + + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + if (DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor == NULL) + { + DPRINT("Miniport's HwGetVideoChildDescriptor is NULL!\n"); + return NO_ERROR; + } + + /* Setup the ChildEnumInfo */ + ChildEnumInfo.Size = sizeof (ChildEnumInfo); + ChildEnumInfo.ChildDescriptorSize = sizeof (ChildDescriptor); + ChildEnumInfo.ACPIHwId = 0; + ChildEnumInfo.ChildHwDeviceExtension = NULL; /* FIXME: must be set to + ChildHwDeviceExtension... */ + + /* Enumerate the children */ + for (i = 1; ; i++) + { + ChildEnumInfo.ChildIndex = i; + RtlZeroMemory(ChildDescriptor, sizeof(ChildDescriptor)); + Status = DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor( + HwDeviceExtension, + &ChildEnumInfo, + &ChildType, + ChildDescriptor, + &ChildId, + &Unused); + if (Status == VIDEO_ENUM_INVALID_DEVICE) + { + DPRINT("Child device %d is invalid!\n", ChildEnumInfo.ChildIndex); + continue; + } + else if (Status == VIDEO_ENUM_NO_MORE_DEVICES) + { + DPRINT("End of child enumeration! (%d children enumerated)\n", i - 1); + break; + } + else if (Status != VIDEO_ENUM_MORE_DEVICES) + { + DPRINT("HwGetVideoChildDescriptor returned unknown status code 0x%x!\n", Status); + break; + } + +#ifndef NDEBUG + if (ChildType == Monitor) + { + INT j; + PUCHAR p = ChildDescriptor; + DPRINT("Monitor device enumerated! (ChildId = 0x%x)\n", ChildId); + for (j = 0; j < sizeof (ChildDescriptor); j += 8) + { + DPRINT("%02x %02x %02x %02x %02x %02x %02x %02x\n", + p[j+0], p[j+1], p[j+2], p[j+3], + p[j+4], p[j+5], p[j+6], p[j+7]); + } + } + else if (ChildType == Other) + { + DPRINT("\"Other\" device enumerated: DeviceId = %S\n", (PWSTR)ChildDescriptor); + } + else + { + DPRINT("HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildType); + } +#endif /* NDEBUG */ - assert_irql(PASSIVE_LEVEL); + } - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, - DeviceExtension->RegistryPath.Buffer, - ValueName, - REG_BINARY, - ValueData, - ValueLength); + return NO_ERROR; } - /* * @unimplemented */ -VP_STATUS -STDCALL -VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension, - IN ULONG NumAccessRanges, - IN PVIDEO_ACCESS_RANGE AccessRange) -{ - DPRINT("VideoPortSetTrappedEmulatorPorts\n"); - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @implemented - */ -VOID -STDCALL -VideoPortStartTimer(IN PVOID HwDeviceExtension) +VP_STATUS NTAPI +VideoPortCreateSecondaryDisplay( + IN PVOID HwDeviceExtension, + IN OUT PVOID *SecondaryDeviceExtension, + IN ULONG Flag) { - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT("VideoPortStartTimer\n"); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - IoStartTimer(DeviceExtension->DeviceObject); + DPRINT1("VideoPortCreateSecondaryDisplay: Unimplemented.\n"); + return NO_ERROR; } - /* * @implemented */ -VOID -STDCALL -VideoPortStopTimer(IN PVOID HwDeviceExtension) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT("VideoPortStopTimer\n"); - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - IoStopTimer(DeviceExtension->DeviceObject); +BOOLEAN NTAPI +VideoPortQueueDpc( + IN PVOID HwDeviceExtension, + IN PMINIPORT_DPC_ROUTINE CallbackRoutine, + IN PVOID Context) +{ + return KeInsertQueueDpc( + &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->DpcObject, + (PVOID)CallbackRoutine, + (PVOID)Context); } - /* - * @implemented + * @unimplemented */ -BOOLEAN -STDCALL -VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension, - IN VIDEO_SYNCHRONIZE_PRIORITY Priority, - IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine, - OUT PVOID Context) + +PVOID NTAPI +VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject) { - BOOLEAN Ret; - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - KIRQL OldIrql; - - DPRINT("VideoPortSynchronizeExecution\n"); - - switch(Priority) - { - case VpLowPriority: - Ret = (*SynchronizeRoutine)(Context); - break; - case VpMediumPriority: - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - if (NULL == DeviceExtension->InterruptObject) - { - Ret = (*SynchronizeRoutine)(Context); - } - else - { - Ret = KeSynchronizeExecution(DeviceExtension->InterruptObject, - SynchronizeRoutine, - Context); - } - break; - case VpHighPriority: - OldIrql = KeGetCurrentIrql(); - if (OldIrql < SYNCH_LEVEL) - { - OldIrql = KfRaiseIrql(SYNCH_LEVEL); - } - Ret = (*SynchronizeRoutine)(Context); - if (OldIrql < SYNCH_LEVEL) - { - KfLowerIrql(OldIrql); - } - break; - default: - Ret = FALSE; - } - - return Ret; + DPRINT1("VideoPortGetAssociatedDeviceExtension: Unimplemented.\n"); + return NULL; } - /* * @implemented */ -VP_STATUS -STDCALL -VideoPortUnmapMemory(IN PVOID HwDeviceExtension, - IN PVOID VirtualAddress, - IN HANDLE ProcessHandle) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT("VideoPortFreeDeviceBase\n"); - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - InternalUnmapMemory(DeviceExtension, VirtualAddress); - - return STATUS_SUCCESS; +VP_STATUS NTAPI +VideoPortGetVersion( + IN PVOID HwDeviceExtension, + IN OUT PVPOSVERSIONINFO VpOsVersionInfo) +{ + RTL_OSVERSIONINFOEXW Version; + + Version.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); + if (VpOsVersionInfo->Size >= sizeof(VPOSVERSIONINFO)) + { +#if 1 + if (NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&Version))) + { + VpOsVersionInfo->MajorVersion = Version.dwMajorVersion; + VpOsVersionInfo->MinorVersion = Version.dwMinorVersion; + VpOsVersionInfo->BuildNumber = Version.dwBuildNumber; + VpOsVersionInfo->ServicePackMajor = Version.wServicePackMajor; + VpOsVersionInfo->ServicePackMinor = Version.wServicePackMinor; + return NO_ERROR; + } + return ERROR_INVALID_PARAMETER; +#else + VpOsVersionInfo->MajorVersion = 5; + VpOsVersionInfo->MinorVersion = 0; + VpOsVersionInfo->BuildNumber = 2195; + VpOsVersionInfo->ServicePackMajor = 4; + VpOsVersionInfo->ServicePackMinor = 0; + return NO_ERROR; +#endif + } + + return ERROR_INVALID_PARAMETER; } - /* * @unimplemented */ -VP_STATUS -STDCALL -VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension, - IN ULONG NumAccessRanges, - IN PVIDEO_ACCESS_RANGE AccessRanges) -{ - DPRINT1("VideoPortVerifyAccessRanges not implemented\n"); - return NO_ERROR; -} - -/* - * Reset display to blue screen - */ -static BOOLEAN STDCALL -VideoPortResetDisplayParameters(Columns, Rows) +BOOLEAN NTAPI +VideoPortCheckForDeviceExistence( + IN PVOID HwDeviceExtension, + IN USHORT VendorId, + IN USHORT DeviceId, + IN UCHAR RevisionId, + IN USHORT SubVendorId, + IN USHORT SubSystemId, + IN ULONG Flags) { - if (NULL == ResetDisplayParametersDeviceExtension) - { - return(FALSE); - } - if (NULL == ResetDisplayParametersDeviceExtension->HwResetHw) - { - return(FALSE); - } - if (!ResetDisplayParametersDeviceExtension->HwResetHw(&ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension, - Columns, Rows)) - { - return(FALSE); - } - - ResetDisplayParametersDeviceExtension = NULL; - - return TRUE; + DPRINT1("VideoPortCheckForDeviceExistence: Unimplemented.\n"); + return TRUE; } /* - * @implemented + * @unimplemented */ -PVOID -STDCALL -VideoPortAllocatePool( +VP_STATUS NTAPI +VideoPortRegisterBugcheckCallback( IN PVOID HwDeviceExtension, - IN VP_POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes, - IN ULONG Tag) + IN ULONG BugcheckCode, + IN PVOID Callback, + IN ULONG BugcheckDataSize) { - return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); + DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n"); + return NO_ERROR; } /* * @implemented */ -VOID -STDCALL -VideoPortFreePool( +LONGLONG NTAPI +VideoPortQueryPerformanceCounter( IN PVOID HwDeviceExtension, - IN PVOID Ptr) + OUT PLONGLONG PerformanceFrequency OPTIONAL) { - ExFreePool(Ptr); -} + LARGE_INTEGER Result; -// VidDispatchOpen -// -// DESCRIPTION: -// Answer requests for Open calls -// -// RUN LEVEL: -// PASSIVE_LEVEL -// -// ARGUMENTS: -// Standard dispatch arguments -// -// RETURNS: -// NTSTATUS -// - -NTSTATUS STDCALL -VidDispatchOpen(IN PDEVICE_OBJECT pDO, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IrpStack; - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT("VidDispatchOpen() called\n"); - - IrpStack = IoGetCurrentIrpStackLocation(Irp); - - if (! CsrssInitialized) - { - DPRINT("Referencing CSRSS\n"); - Csrss = PsGetCurrentProcess(); - DPRINT("Csrss %p\n", Csrss); - } - else - { - DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION) pDO->DeviceExtension; - if (DeviceExtension->HwInitialize(&DeviceExtension->MiniPortDeviceExtension)) - { - Irp->IoStatus.Status = STATUS_SUCCESS; - /* Storing the device extension pointer in a static variable is an ugly - * hack. Unfortunately, we need it in VideoPortResetDisplayParameters - * and HalAcquireDisplayOwnership doesn't allow us to pass a userdata - * parameter. On the bright side, the DISPLAY device is opened - * exclusively, so there can be only one device extension active at - * any point in time. */ - ResetDisplayParametersDeviceExtension = DeviceExtension; - HalAcquireDisplayOwnership(VideoPortResetDisplayParameters); - } - else - { - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - } - } - - Irp->IoStatus.Information = FILE_OPENED; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; + DPRINT("VideoPortQueryPerformanceCounter\n"); + Result = KeQueryPerformanceCounter((PLARGE_INTEGER)PerformanceFrequency); + return Result.QuadPart; } -// VidDispatchClose -// -// DESCRIPTION: -// Answer requests for Close calls -// -// RUN LEVEL: -// PASSIVE_LEVEL -// -// ARGUMENTS: -// Standard dispatch arguments -// -// RETURNS: -// NTSTATUS -// - -NTSTATUS STDCALL -VidDispatchClose(IN PDEVICE_OBJECT pDO, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IrpStack; - - DPRINT("VidDispatchClose() called\n"); - - IrpStack = IoGetCurrentIrpStackLocation(Irp); - - if (! CsrssInitialized) - { - CsrssInitialized = TRUE; - } - else - { - HalReleaseDisplayOwnership(); - } - - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; -} - -// VidDispatchDeviceControl -// -// DESCRIPTION: -// Answer requests for device control calls -// -// RUN LEVEL: -// PASSIVE_LEVEL -// -// ARGUMENTS: -// Standard dispatch arguments -// -// RETURNS: -// NTSTATUS -// - -NTSTATUS STDCALL -VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IrpStack; - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - PVIDEO_REQUEST_PACKET vrp; - - DPRINT("VidDispatchDeviceControl\n"); - IrpStack = IoGetCurrentIrpStackLocation(Irp); - DeviceExtension = DeviceObject->DeviceExtension; - - /* Translate the IRP to a VRP */ - vrp = ExAllocatePool(NonPagedPool, sizeof(VIDEO_REQUEST_PACKET)); - if (NULL == vrp) - { - return STATUS_NO_MEMORY; - } - vrp->StatusBlock = (PSTATUS_BLOCK) &(Irp->IoStatus); - vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; - - DPRINT("- IoControlCode: %x\n", vrp->IoControlCode); - - /* We're assuming METHOD_BUFFERED */ - vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer; - vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; - vrp->OutputBuffer = Irp->AssociatedIrp.SystemBuffer; - vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; - - /* Call the Miniport Driver with the VRP */ - ((PDRIVER_STARTIO)DeviceObject->DriverObject->DriverStartIo)((PVOID) &DeviceExtension->MiniPortDeviceExtension, (PIRP)vrp); - - /* Free the VRP */ - ExFreePool(vrp); - - DPRINT("- Returned status: %x\n", Irp->IoStatus.Status); - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; -} +/* + * @implemented + */ -PVOID STDCALL -InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, - IN PHYSICAL_ADDRESS IoAddress, - IN ULONG NumberOfUchars, - IN UCHAR InIoSpace, - OUT NTSTATUS *Status) +VOID NTAPI +VideoPortAcquireDeviceLock( + IN PVOID HwDeviceExtension) { - PHYSICAL_ADDRESS TranslatedAddress; - PVIDEO_PORT_ADDRESS_MAPPING AddressMapping; - ULONG AddressSpace; - PVOID MappedAddress; - PLIST_ENTRY Entry; - - if (0 != (InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE)) - { - DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n"); - InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE; - } - if (! IsListEmpty(&DeviceExtension->AddressMappingListHead)) - { - Entry = DeviceExtension->AddressMappingListHead.Flink; - while (Entry != &DeviceExtension->AddressMappingListHead) - { - AddressMapping = CONTAINING_RECORD(Entry, - VIDEO_PORT_ADDRESS_MAPPING, - List); - if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart && - NumberOfUchars <= AddressMapping->NumberOfUchars) - { - AddressMapping->MappingCount++; - if (Status) - { - *Status = STATUS_SUCCESS; - } - return AddressMapping->MappedAddress; - } - Entry = Entry->Flink; - } - } - - AddressSpace = (ULONG)InIoSpace; - if (HalTranslateBusAddress(DeviceExtension->AdapterInterfaceType, - DeviceExtension->SystemIoBusNumber, - IoAddress, - &AddressSpace, - &TranslatedAddress) == FALSE) - { - if (Status) - { - *Status = STATUS_NO_MEMORY; - } - return NULL; - } - - /* i/o space */ - if (AddressSpace != 0) - { - assert(0 == TranslatedAddress.u.HighPart); - if (Status) - { - *Status = STATUS_SUCCESS; - } - return (PVOID) TranslatedAddress.u.LowPart; - } - - MappedAddress = MmMapIoSpace(TranslatedAddress, - NumberOfUchars, - FALSE); - - if (MappedAddress) - { - if (Status) - { - *Status = STATUS_SUCCESS; - } - - AddressMapping = ExAllocatePoolWithTag(PagedPool, - sizeof(VIDEO_PORT_ADDRESS_MAPPING), - TAG_VIDEO_PORT); - if (AddressMapping == NULL) - return MappedAddress; - - AddressMapping->MappedAddress = MappedAddress; - AddressMapping->NumberOfUchars = NumberOfUchars; - AddressMapping->IoAddress = IoAddress; - AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber; - AddressMapping->MappingCount = 1; - - InsertHeadList(&DeviceExtension->AddressMappingListHead, - &AddressMapping->List); - - return MappedAddress; - } - else - { - if (Status) - { - *Status = STATUS_NO_MEMORY; - } - - return NULL; - } + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + (void)Status; + + DPRINT("VideoPortAcquireDeviceLock\n"); + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + Status = KeWaitForMutexObject(&DeviceExtension->DeviceLock, Executive, + KernelMode, FALSE, NULL); + ASSERT(Status == STATUS_SUCCESS); } -VOID STDCALL -InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, - IN PVOID MappedAddress) -{ - PVIDEO_PORT_ADDRESS_MAPPING AddressMapping; - PLIST_ENTRY Entry; - - Entry = DeviceExtension->AddressMappingListHead.Flink; - while (Entry != &DeviceExtension->AddressMappingListHead) - { - AddressMapping = CONTAINING_RECORD(Entry, - VIDEO_PORT_ADDRESS_MAPPING, - List); - if (AddressMapping->MappedAddress == MappedAddress) - { - assert(0 <= AddressMapping->MappingCount); - AddressMapping->MappingCount--; - if (0 == AddressMapping->MappingCount) - { - MmUnmapIoSpace(AddressMapping->MappedAddress, - AddressMapping->NumberOfUchars); - RemoveEntryList(Entry); - ExFreePool(AddressMapping); - - return; - } - } - - Entry = Entry->Flink; - } -} +/* + * @implemented + */ -BOOLEAN STDCALL -VideoPortDDCMonitorHelper( - PVOID HwDeviceExtension, - /*PI2C_FNC_TABLE*/PVOID I2CFunctions, - PUCHAR pEdidBuffer, - ULONG EdidBufferSize - ) +VOID NTAPI +VideoPortReleaseDeviceLock( + IN PVOID HwDeviceExtension) { - return FALSE; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + LONG Status; + (void)Status; + + DPRINT("VideoPortReleaseDeviceLock\n"); + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + Status = KeReleaseMutex(&DeviceExtension->DeviceLock, FALSE); + ASSERT(Status == 0); } +/* + * @unimplemented + */ -VP_STATUS -STDCALL -VideoPortAllocateBuffer(IN PVOID HwDeviceExtension, - IN ULONG Size, - OUT PVOID *Buffer) +VOID NTAPI +VpNotifyEaData( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Data) { - DPRINT("VideoPortAllocateBuffer\n"); - - Buffer = ExAllocatePool (PagedPool, Size) ; - return STATUS_SUCCESS; - } - -VOID -STDCALL -VideoPortReleaseBuffer( IN PVOID HwDeviceExtension, - IN PVOID Ptr) -{ - DPRINT("VideoPortReleaseBuffer\n"); - - ExFreePool(Ptr); -} - -