diff --git a/reactos/drivers/video/videoprt/Makefile b/reactos/drivers/video/videoprt/Makefile index a7bbc0a056e..d5d535fc56d 100644 --- a/reactos/drivers/video/videoprt/Makefile +++ b/reactos/drivers/video/videoprt/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.3 2004/03/09 17:28:49 navaraf Exp $ +# $Id: Makefile,v 1.4 2004/03/19 20:58:31 navaraf Exp $ PATH_TO_TOP = ../../.. @@ -9,11 +9,17 @@ TARGET_NAME = videoprt TARGET_CFLAGS += -Wall -Werror -D__USE_W32API -I$(PATH_TO_TOP)/ntoskrnl/include TARGET_OBJECTS = \ + dispatch.o \ + dma.o \ + event.o \ int10.o \ interrupt.o \ videoprt.o \ + resource.o \ services.o \ - spinlock.o + spinlock.o \ + timer.o + include $(PATH_TO_TOP)/rules.mak diff --git a/reactos/drivers/video/videoprt/dispatch.c b/reactos/drivers/video/videoprt/dispatch.c new file mode 100644 index 00000000000..617ef9d99a8 --- /dev/null +++ b/reactos/drivers/video/videoprt/dispatch.c @@ -0,0 +1,316 @@ +/* + * VideoPort driver + * + * Copyright (C) 2002, 2003, 2004 ReactOS Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: dispatch.c,v 1.2 2004/03/19 20:58:32 navaraf Exp $ + */ + +#include "videoprt.h" + +/* EXTERNAL FUNCTIONS *********************************************************/ + +typedef PVOID PHAL_RESET_DISPLAY_PARAMETERS; +VOID STDCALL HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters); +VOID STDCALL HalReleaseDisplayOwnership(); + +/* GLOBAL VARIABLES ***********************************************************/ + +PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL; + +/* PRIVATE FUNCTIONS **********************************************************/ + +/* + * Reset display to blue screen + */ + +BOOLEAN STDCALL +IntVideoPortResetDisplayParameters(ULONG Columns, ULONG Rows) +{ + PVIDEO_PORT_DRIVER_EXTENSION DriverExtension; + + if (ResetDisplayParametersDeviceExtension == NULL) + return FALSE; + + DriverExtension = ResetDisplayParametersDeviceExtension->DriverExtension; + + ASSERT(DriverExtension->InitializationData.HwResetHw != NULL); + + if (!DriverExtension->InitializationData.HwResetHw( + &ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension, + Columns, Rows)) + { + return FALSE; + } + + ResetDisplayParametersDeviceExtension = NULL; + + return TRUE; +} + +NTSTATUS STDCALL +IntVideoPortAddDevice( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT PhysicalDeviceObject) +{ + PVIDEO_PORT_DRIVER_EXTENSION DriverExtension; + + /* + * Get the initialization data we saved in VideoPortInitialize. + */ + + DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject); + + /* + * Use generic routine to find the adapter and create device object. + */ + + return IntVideoPortFindAdapter( + DriverObject, + DriverExtension, + PhysicalDeviceObject); +} + +/* + * IntVideoPortDispatchOpen + * + * Answer requests for Open calls. + * + * Run Level + * PASSIVE_LEVEL + */ + +NTSTATUS STDCALL +IntVideoPortDispatchOpen( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + PVIDEO_PORT_DRIVER_EXTENSION DriverExtension; + + DPRINT("IntVideoPortDispatchOpen\n"); + + if (CsrssInitialized == FALSE) + { + /* + * We know the first open call will be from the CSRSS process + * to let us know its handle. + */ + + DPRINT("Referencing CSRSS\n"); + Csrss = PsGetCurrentProcess(); + DPRINT("Csrss %p\n", Csrss); + + CsrssInitialized = TRUE; + + Irp->IoStatus.Information = FILE_OPENED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; + } + + DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + DriverExtension = DeviceExtension->DriverExtension; + + if (DriverExtension->InitializationData.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(IntVideoPortResetDisplayParameters); + } + else + { + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + } + + Irp->IoStatus.Information = FILE_OPENED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +/* + * IntVideoPortDispatchClose + * + * Answer requests for Close calls. + * + * Run Level + * PASSIVE_LEVEL + */ + +NTSTATUS STDCALL +IntVideoPortDispatchClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("IntVideoPortDispatchClose\n"); + + if (ResetDisplayParametersDeviceExtension != NULL) + HalReleaseDisplayOwnership(); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +/* + * IntVideoPortDispatchDeviceControl + * + * Answer requests for device control calls. + * + * Run Level + * PASSIVE_LEVEL + */ + +NTSTATUS STDCALL +IntVideoPortDispatchDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IrpStack; + PVIDEO_PORT_DRIVER_EXTENSION DriverExtension; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + PVIDEO_REQUEST_PACKET vrp; + NTSTATUS Status; + + DPRINT("IntVideoPortDispatchDeviceControl\n"); + + IrpStack = IoGetCurrentIrpStackLocation(Irp); + DeviceExtension = DeviceObject->DeviceExtension; + DriverExtension = DeviceExtension->DriverExtension; + + /* 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 */ + DriverExtension->InitializationData.HwStartIO( + &DeviceExtension->MiniPortDeviceExtension, + vrp); + + /* Free the VRP */ + ExFreePool(vrp); + + DPRINT("- Returned status: %x\n", Irp->IoStatus.Status); + + if (Irp->IoStatus.Status != STATUS_SUCCESS) + { + /* Map from win32 error codes to NT status values. */ + switch (Irp->IoStatus.Status) + { + case ERROR_NOT_ENOUGH_MEMORY: Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; break; + case ERROR_MORE_DATA: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; break; + case ERROR_INVALID_FUNCTION: Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; break; + case ERROR_INVALID_PARAMETER: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; + case ERROR_INSUFFICIENT_BUFFER: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; break; + case ERROR_DEV_NOT_EXIST: Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST; break; + case ERROR_IO_PENDING: Irp->IoStatus.Status = STATUS_PENDING; break; + } + } + + Status = Irp->IoStatus.Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +} + +NTSTATUS STDCALL +IntVideoPortDispatchPnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IrpSp; + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + switch (IrpSp->MinorFunction) + { + case IRP_MN_START_DEVICE: + + case IRP_MN_REMOVE_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_CANCEL_REMOVE_DEVICE: + case IRP_MN_SURPRISE_REMOVAL: + + case IRP_MN_STOP_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_CANCEL_STOP_DEVICE: + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; + } + + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS STDCALL +IntVideoPortDispatchCleanup( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DeviceExtension = DeviceObject->DeviceExtension; + RtlFreeUnicodeString(&DeviceExtension->RegistryPath); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +NTSTATUS STDCALL +IntVideoPortDispatchPower( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return STATUS_NOT_IMPLEMENTED; +} + +VOID STDCALL +IntVideoPortUnload(PDRIVER_OBJECT DriverObject) +{ +} diff --git a/reactos/drivers/video/videoprt/dma.c b/reactos/drivers/video/videoprt/dma.c new file mode 100644 index 00000000000..b7fe295856e --- /dev/null +++ b/reactos/drivers/video/videoprt/dma.c @@ -0,0 +1,119 @@ +/* + * VideoPort driver + * + * Copyright (C) 2002, 2003, 2004 ReactOS Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: dma.c,v 1.2 2004/03/19 20:58:32 navaraf Exp $ + */ + +#include "videoprt.h" + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @implemented + */ + +PVOID STDCALL +VideoPortAllocateCommonBuffer( + IN PVOID HwDeviceExtension, + IN PVP_DMA_ADAPTER VpDmaAdapter, + IN ULONG DesiredLength, + OUT PPHYSICAL_ADDRESS LogicalAddress, + IN BOOLEAN CacheEnabled, + PVOID Reserved) +{ + return HalAllocateCommonBuffer( + (PADAPTER_OBJECT)VpDmaAdapter, + DesiredLength, + LogicalAddress, + CacheEnabled); +} + +/* + * @implemented + */ + +VOID STDCALL +VideoPortReleaseCommonBuffer( + IN PVOID HwDeviceExtension, + IN PVP_DMA_ADAPTER VpDmaAdapter, + IN ULONG Length, + IN PHYSICAL_ADDRESS LogicalAddress, + IN PVOID VirtualAddress, + IN BOOLEAN CacheEnabled) +{ + HalFreeCommonBuffer( + (PADAPTER_OBJECT)VpDmaAdapter, + Length, + LogicalAddress, + VirtualAddress, + CacheEnabled); +} + +/* + * @unimplemented + */ + +VOID STDCALL +VideoPortPutDmaAdapter( + IN PVOID HwDeviceExtension, + IN PVP_DMA_ADAPTER VpDmaAdapter) +{ + DPRINT("VideoPortPutDmaAdapter: Unimplemented.\n"); +} + +/* + * @unimplemented + */ + +PVP_DMA_ADAPTER STDCALL +VideoPortGetDmaAdapter( + IN PVOID HwDeviceExtension, + IN PVP_DEVICE_DESCRIPTION VpDeviceExtension) +{ + DEVICE_DESCRIPTION DeviceDescription; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + ULONG NumberOfMapRegisters; + PVP_DMA_ADAPTER Adapter; + + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + + DPRINT("VideoPortGetDmaAdapter\n"); + + DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; + DeviceDescription.Master = TRUE /* ?? */; + DeviceDescription.ScatterGather = VpDeviceExtension->ScatterGather; + DeviceDescription.DemandMode = FALSE /* ?? */; + DeviceDescription.AutoInitialize = FALSE /* ?? */; + DeviceDescription.Dma32BitAddresses = VpDeviceExtension->Dma32BitAddresses; + DeviceDescription.IgnoreCount = FALSE /* ?? */; + DeviceDescription.Reserved1 = FALSE; + DeviceDescription.BusNumber = DeviceExtension->SystemIoBusNumber; + DeviceDescription.DmaChannel = 0 /* ?? */; + DeviceDescription.InterfaceType = DeviceExtension->AdapterInterfaceType; + DeviceDescription.DmaWidth = Width8Bits; + DeviceDescription.DmaSpeed = Compatible; + DeviceDescription.MaximumLength = VpDeviceExtension->MaximumLength; + DeviceDescription.DmaPort = 0; + + Adapter = + (PVP_DMA_ADAPTER)HalGetAdapter(&DeviceDescription, &NumberOfMapRegisters); + DPRINT("Adapter %X\n", Adapter); + return(Adapter); +} diff --git a/reactos/drivers/video/videoprt/event.c b/reactos/drivers/video/videoprt/event.c new file mode 100644 index 00000000000..170eb408444 --- /dev/null +++ b/reactos/drivers/video/videoprt/event.c @@ -0,0 +1,111 @@ +/* + * VideoPort driver + * + * Copyright (C) 2002, 2003, 2004 ReactOS Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: event.c,v 1.2 2004/03/19 20:58:32 navaraf Exp $ + */ + +#include "videoprt.h" + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @implemented + */ + +VP_STATUS STDCALL +VideoPortCreateEvent( + IN PVOID HwDeviceExtension, + IN ULONG EventFlag, + IN PVOID Unused, + OUT PEVENT *Event) +{ + EVENT_TYPE Type; + + (*Event) = ExAllocatePoolWithTag( + NonPagedPool, + sizeof(KEVENT), + TAG_VIDEO_PORT); + + if ((*Event) == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + if (EventFlag & NOTIFICATION_EVENT) + Type = NotificationEvent; + else + Type = SynchronizationEvent; + + KeInitializeEvent((PKEVENT)*Event, Type, EventFlag & INITIAL_EVENT_SIGNALED); + return NO_ERROR; +} + +/* + * @implemented + */ + +VP_STATUS STDCALL +VideoPortDeleteEvent( + IN PVOID HwDeviceExtension, + IN PEVENT Event) +{ + ExFreePool(Event); + return NO_ERROR; +} + +/* + * @implemented + */ + +LONG STDCALL +VideoPortSetEvent( + IN PVOID HwDeviceExtension, + IN PEVENT Event) +{ + return KeSetEvent((PKEVENT)Event, IO_NO_INCREMENT, FALSE); +} + +/* + * @implemented + */ + +VOID STDCALL +VideoPortClearEvent( + IN PVOID HwDeviceExtension, + IN PEVENT Event) +{ + KeClearEvent((PKEVENT)Event); +} + +/* + * @implemented + */ + +VP_STATUS STDCALL +VideoPortWaitForSingleObject( + IN PVOID HwDeviceExtension, + IN PVOID Object, + IN PLARGE_INTEGER Timeout OPTIONAL) +{ + return KeWaitForSingleObject( + Object, + Executive, + KernelMode, + FALSE, + Timeout); +} diff --git a/reactos/drivers/video/videoprt/int10.c b/reactos/drivers/video/videoprt/int10.c index f822c295fd4..ad517aac6fd 100644 --- a/reactos/drivers/video/videoprt/int10.c +++ b/reactos/drivers/video/videoprt/int10.c @@ -18,84 +18,13 @@ * If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id: int10.c,v 1.4 2004/03/08 21:45:39 navaraf Exp $ + * $Id: int10.c,v 1.5 2004/03/19 20:58:31 navaraf Exp $ */ #include "videoprt.h" #include "internal/v86m.h" -VOID FASTCALL -IntAttachToCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess) -{ - *CallingProcess = PsGetCurrentProcess(); - if (*CallingProcess != Csrss) - { - if (NULL != PsGetCurrentThread()->OldProcess) - { - *PrevAttachedProcess = *CallingProcess; - KeDetachProcess(); - } - else - { - *PrevAttachedProcess = NULL; - } - KeAttachProcess(Csrss); - } -} - -VOID FASTCALL -IntDetachFromCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess) -{ - if (*CallingProcess != Csrss) - { - KeDetachProcess(); - if (NULL != *PrevAttachedProcess) - { - KeAttachProcess(*PrevAttachedProcess); - } - } -} - - -/* - * @implemented - */ - -VP_STATUS STDCALL -VideoPortInt10( - IN PVOID HwDeviceExtension, - IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments) -{ - KV86M_REGISTERS Regs; - NTSTATUS Status; - PEPROCESS CallingProcess; - PEPROCESS PrevAttachedProcess; - - DPRINT("VideoPortInt10\n"); - - IntAttachToCSRSS(&CallingProcess, &PrevAttachedProcess); - - memset(&Regs, 0, sizeof(Regs)); - DPRINT("- Input register Eax: %x\n", BiosArguments->Eax); - Regs.Eax = BiosArguments->Eax; - DPRINT("- Input register Ebx: %x\n", BiosArguments->Ebx); - Regs.Ebx = BiosArguments->Ebx; - DPRINT("- Input register Ecx: %x\n", BiosArguments->Ecx); - Regs.Ecx = BiosArguments->Ecx; - DPRINT("- Input register Edx: %x\n", BiosArguments->Edx); - Regs.Edx = BiosArguments->Edx; - DPRINT("- Input register Esi: %x\n", BiosArguments->Esi); - Regs.Esi = BiosArguments->Esi; - DPRINT("- Input register Edi: %x\n", BiosArguments->Edi); - Regs.Edi = BiosArguments->Edi; - DPRINT("- Input register Ebp: %x\n", BiosArguments->Ebp); - Regs.Ebp = BiosArguments->Ebp; - Status = Ke386CallBios(0x10, &Regs); - - IntDetachFromCSRSS(&CallingProcess, &PrevAttachedProcess); - - return Status; -} +/* PRIVATE FUNCTIONS **********************************************************/ VP_STATUS STDCALL IntInt10AllocateBuffer( @@ -106,8 +35,8 @@ IntInt10AllocateBuffer( { PVOID MemoryAddress; NTSTATUS Status; - PEPROCESS CallingProcess; - PEPROCESS PrevAttachedProcess; + PEPROCESS CallingProcess; + PEPROCESS PrevAttachedProcess; DPRINT("IntInt10AllocateBuffer\n"); @@ -116,17 +45,21 @@ IntInt10AllocateBuffer( MemoryAddress = (PVOID)0x20000; Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &MemoryAddress, 0, Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (!NT_SUCCESS(Status)) { DPRINT("- ZwAllocateVirtualMemory failed\n"); - return STATUS_NO_MEMORY; + IntDetachFromCSRSS(&CallingProcess, &PrevAttachedProcess); + return ERROR_NOT_ENOUGH_MEMORY; } + if (MemoryAddress > (PVOID)(0x100000 - *Length)) { ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress, Length, MEM_RELEASE); DPRINT("- Unacceptable memory allocated\n"); - return STATUS_NO_MEMORY; + IntDetachFromCSRSS(&CallingProcess, &PrevAttachedProcess); + return ERROR_NOT_ENOUGH_MEMORY; } *Seg = (ULONG)MemoryAddress >> 4; @@ -138,7 +71,7 @@ IntInt10AllocateBuffer( IntDetachFromCSRSS(&CallingProcess, &PrevAttachedProcess); - return STATUS_SUCCESS; + return NO_ERROR; } VP_STATUS STDCALL @@ -149,8 +82,8 @@ IntInt10FreeBuffer( { PVOID MemoryAddress = (PVOID)((Seg << 4) + Off); NTSTATUS Status; - PEPROCESS CallingProcess; - PEPROCESS PrevAttachedProcess; + PEPROCESS CallingProcess; + PEPROCESS PrevAttachedProcess; DPRINT("IntInt10FreeBuffer\n"); DPRINT("- Segment: %x\n", Seg); @@ -172,8 +105,8 @@ IntInt10ReadMemory( OUT PVOID Buffer, IN ULONG Length) { - PEPROCESS CallingProcess; - PEPROCESS PrevAttachedProcess; + PEPROCESS CallingProcess; + PEPROCESS PrevAttachedProcess; DPRINT("IntInt10ReadMemory\n"); DPRINT("- Segment: %x\n", Seg); @@ -185,7 +118,7 @@ IntInt10ReadMemory( RtlCopyMemory(Buffer, (PVOID)((Seg << 4) + Off), Length); IntDetachFromCSRSS(&CallingProcess, &PrevAttachedProcess); - return STATUS_SUCCESS; + return NO_ERROR; } VP_STATUS STDCALL @@ -196,8 +129,8 @@ IntInt10WriteMemory( IN PVOID Buffer, IN ULONG Length) { - PEPROCESS CallingProcess; - PEPROCESS PrevAttachedProcess; + PEPROCESS CallingProcess; + PEPROCESS PrevAttachedProcess; DPRINT("IntInt10WriteMemory\n"); DPRINT("- Segment: %x\n", Seg); @@ -209,7 +142,7 @@ IntInt10WriteMemory( RtlCopyMemory((PVOID)((Seg << 4) + Off), Buffer, Length); IntDetachFromCSRSS(&CallingProcess, &PrevAttachedProcess); - return STATUS_SUCCESS; + return NO_ERROR; } VP_STATUS STDCALL @@ -219,8 +152,8 @@ IntInt10CallBios( { KV86M_REGISTERS Regs; NTSTATUS Status; - PEPROCESS CallingProcess; - PEPROCESS PrevAttachedProcess; + PEPROCESS CallingProcess; + PEPROCESS PrevAttachedProcess; DPRINT("IntInt10CallBios\n"); @@ -260,3 +193,45 @@ IntInt10CallBios( return Status; } + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @implemented + */ + +VP_STATUS STDCALL +VideoPortInt10( + IN PVOID HwDeviceExtension, + IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments) +{ + KV86M_REGISTERS Regs; + NTSTATUS Status; + PEPROCESS CallingProcess; + PEPROCESS PrevAttachedProcess; + + DPRINT("VideoPortInt10\n"); + + IntAttachToCSRSS(&CallingProcess, &PrevAttachedProcess); + + memset(&Regs, 0, sizeof(Regs)); + DPRINT("- Input register Eax: %x\n", BiosArguments->Eax); + Regs.Eax = BiosArguments->Eax; + DPRINT("- Input register Ebx: %x\n", BiosArguments->Ebx); + Regs.Ebx = BiosArguments->Ebx; + DPRINT("- Input register Ecx: %x\n", BiosArguments->Ecx); + Regs.Ecx = BiosArguments->Ecx; + DPRINT("- Input register Edx: %x\n", BiosArguments->Edx); + Regs.Edx = BiosArguments->Edx; + DPRINT("- Input register Esi: %x\n", BiosArguments->Esi); + Regs.Esi = BiosArguments->Esi; + DPRINT("- Input register Edi: %x\n", BiosArguments->Edi); + Regs.Edi = BiosArguments->Edi; + DPRINT("- Input register Ebp: %x\n", BiosArguments->Ebp); + Regs.Ebp = BiosArguments->Ebp; + Status = Ke386CallBios(0x10, &Regs); + + IntDetachFromCSRSS(&CallingProcess, &PrevAttachedProcess); + + return Status; +} diff --git a/reactos/drivers/video/videoprt/interrupt.c b/reactos/drivers/video/videoprt/interrupt.c index 248ae5e7fbf..0f3249d72bc 100644 --- a/reactos/drivers/video/videoprt/interrupt.c +++ b/reactos/drivers/video/videoprt/interrupt.c @@ -18,11 +18,89 @@ * If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id: interrupt.c,v 1.1 2004/03/04 18:51:58 navaraf Exp $ + * $Id: interrupt.c,v 1.2 2004/03/19 20:58:31 navaraf Exp $ */ #include "videoprt.h" +/* PRIVATE FUNCTIONS **********************************************************/ + +BOOLEAN STDCALL +IntVideoPortInterruptRoutine( + IN struct _KINTERRUPT *Interrupt, + IN PVOID ServiceContext) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = ServiceContext; + + ASSERT(DeviceExtension->DriverExtension->InitializationData.HwInterrupt != NULL); + + return DeviceExtension->DriverExtension->InitializationData.HwInterrupt( + &DeviceExtension->MiniPortDeviceExtension); +} + +BOOLEAN STDCALL +IntVideoPortSetupInterrupt( + IN PDEVICE_OBJECT DeviceObject, + IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension, + IN PVIDEO_PORT_CONFIG_INFO ConfigInfo) +{ + NTSTATUS Status; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + if (ConfigInfo->BusInterruptVector == 0) + ConfigInfo->BusInterruptVector = DeviceExtension->InterruptVector; + + if (ConfigInfo->BusInterruptLevel == 0) + ConfigInfo->BusInterruptLevel = DeviceExtension->InterruptLevel; + + if (DriverExtension->InitializationData.HwInterrupt != NULL) + { + ULONG InterruptVector; + KIRQL Irql; + KAFFINITY Affinity; + + InterruptVector = HalGetInterruptVector( + ConfigInfo->AdapterInterfaceType, + ConfigInfo->SystemIoBusNumber, + ConfigInfo->BusInterruptLevel, + ConfigInfo->BusInterruptVector, + &Irql, + &Affinity); + + if (InterruptVector == 0) + { + DPRINT("HalGetInterruptVector failed\n"); + return FALSE; + } + + KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock); + Status = IoConnectInterrupt( + &DeviceExtension->InterruptObject, + IntVideoPortInterruptRoutine, + DeviceExtension, + &DeviceExtension->InterruptSpinLock, + InterruptVector, + Irql, + Irql, + ConfigInfo->InterruptMode, + FALSE, + Affinity, + FALSE); + + if (!NT_SUCCESS(Status)) + { + DPRINT("IoConnectInterrupt failed with status 0x%08x\n", Status); + return FALSE; + } + } + + return TRUE; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + /* * @implemented */ @@ -35,17 +113,14 @@ VideoPortEnableInterrupt(IN PVOID HwDeviceExtension) DPRINT("VideoPortEnableInterrupt\n"); - DeviceExtension = CONTAINING_RECORD( - HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); Status = HalEnableSystemInterrupt( DeviceExtension->InterruptVector, 0, DeviceExtension->InterruptLevel); - return Status ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; + return Status ? NO_ERROR : ERROR_INVALID_ACCESS; } /* @@ -60,14 +135,11 @@ VideoPortDisableInterrupt(IN PVOID HwDeviceExtension) DPRINT("VideoPortDisableInterrupt\n"); - DeviceExtension = CONTAINING_RECORD( - HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); Status = HalDisableSystemInterrupt( DeviceExtension->InterruptVector, 0); - return Status ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; + return Status ? NO_ERROR : ERROR_INVALID_ACCESS; } diff --git a/reactos/drivers/video/videoprt/resource.c b/reactos/drivers/video/videoprt/resource.c new file mode 100644 index 00000000000..d37e5f82cb7 --- /dev/null +++ b/reactos/drivers/video/videoprt/resource.c @@ -0,0 +1,657 @@ +/* + * VideoPort driver + * + * Copyright (C) 2002, 2003, 2004 ReactOS Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: resource.c,v 1.2 2004/03/19 20:58:32 navaraf Exp $ + */ + +#include "videoprt.h" + +/* PRIVATE FUNCTIONS **********************************************************/ + +PVOID STDCALL +IntVideoPortMapMemory( + IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, + IN PHYSICAL_ADDRESS IoAddress, + IN ULONG NumberOfUchars, + IN UCHAR InIoSpace, + OUT VP_STATUS *Status) +{ + PHYSICAL_ADDRESS TranslatedAddress; + PVIDEO_PORT_ADDRESS_MAPPING AddressMapping; + ULONG AddressSpace; + PVOID MappedAddress; + PLIST_ENTRY Entry; + + DPRINT("- IoAddress: %lx\n", IoAddress.u.LowPart); + DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars); + DPRINT("- InIoSpace: %x\n", InIoSpace); + + InIoSpace &= ~VIDEO_MEMORY_SPACE_DENSE; + if ((InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE) != 0) + { + 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 = NO_ERROR; + + return AddressMapping->MappedAddress; + } + Entry = Entry->Flink; + } + } + + AddressSpace = (ULONG)InIoSpace; + if (HalTranslateBusAddress( + DeviceExtension->AdapterInterfaceType, + DeviceExtension->SystemIoBusNumber, + IoAddress, + &AddressSpace, + &TranslatedAddress) == FALSE) + { + if (Status) + *Status = ERROR_NOT_ENOUGH_MEMORY; + + return NULL; + } + + /* I/O space */ + if (AddressSpace != 0) + { + ASSERT(0 == TranslatedAddress.u.HighPart); + if (Status) + *Status = NO_ERROR; + + return (PVOID)TranslatedAddress.u.LowPart; + } + + MappedAddress = MmMapIoSpace( + TranslatedAddress, + NumberOfUchars, + FALSE); + + if (MappedAddress) + { + if (Status) + { + *Status = NO_ERROR; + } + + 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 = NO_ERROR; + + return NULL; + } +} + +VOID STDCALL +IntVideoPortUnmapMemory( + 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(AddressMapping->MappingCount >= 0); + AddressMapping->MappingCount--; + if (AddressMapping->MappingCount == 0) + { + MmUnmapIoSpace( + AddressMapping->MappedAddress, + AddressMapping->NumberOfUchars); + RemoveEntryList(Entry); + ExFreePool(AddressMapping); + + return; + } + } + + Entry = Entry->Flink; + } +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @implemented + */ + +PVOID STDCALL +VideoPortGetDeviceBase( + IN PVOID HwDeviceExtension, + IN PHYSICAL_ADDRESS IoAddress, + IN ULONG NumberOfUchars, + IN UCHAR InIoSpace) +{ + DPRINT("VideoPortGetDeviceBase\n"); + return IntVideoPortMapMemory( + VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension), + IoAddress, + NumberOfUchars, + InIoSpace, + NULL); +} + +/* + * @implemented + */ + +VOID STDCALL +VideoPortFreeDeviceBase( + IN PVOID HwDeviceExtension, + IN PVOID MappedAddress) +{ + DPRINT("VideoPortFreeDeviceBase\n"); + IntVideoPortUnmapMemory( + VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension), + MappedAddress); +} + +/* + * @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 ERROR_CALL_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 = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + *VirtualAddress = IntVideoPortMapMemory( + DeviceExtension, + PhysicalAddress, + *Length, + *InIoSpace, + &Status); + + return Status; +} + +/* + * @implemented + */ + +VP_STATUS STDCALL +VideoPortUnmapMemory( + IN PVOID HwDeviceExtension, + IN PVOID VirtualAddress, + IN HANDLE ProcessHandle) +{ + DPRINT("VideoPortFreeDeviceBase\n"); + + IntVideoPortUnmapMemory( + VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension), + VirtualAddress); + + return NO_ERROR; +} + +/* + * @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) +{ + PCI_SLOT_NUMBER PciSlotNumber; + 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; + USHORT VendorIdToFind; + USHORT DeviceIdToFind; + ULONG SlotIdToFind; + ULONG ReturnedLength; + + DPRINT("VideoPortGetAccessRanges\n"); + + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + + if (NumRequestedResources == 0 && + DeviceExtension->AdapterInterfaceType == PCIBus) + { + if (DeviceExtension->PhysicalDeviceObject != NULL) + { + PciSlotNumber.u.AsULONG = DeviceExtension->SystemIoSlotNumber; + + ReturnedLength = HalGetBusData( + PCIConfiguration, + DeviceExtension->SystemIoBusNumber, + PciSlotNumber.u.AsULONG, + &Config, + sizeof(PCI_COMMON_CONFIG)); + + if (ReturnedLength != sizeof(PCI_COMMON_CONFIG)) + { + return ERROR_NO_SYSTEM_RESOURCES; + } + } + else + { + VendorIdToFind = VendorId != NULL ? *(PUSHORT)VendorId : 0; + DeviceIdToFind = DeviceId != NULL ? *(PUSHORT)DeviceId : 0; + SlotIdToFind = Slot != NULL ? *Slot : 0; + PciSlotNumber.u.AsULONG = SlotIdToFind; + + DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n", + VendorIdToFind, DeviceIdToFind); + + /* + * Search for the device id and vendor id on this bus. + */ + + for (FunctionNumber = 0; FunctionNumber < 8; FunctionNumber++) + { + DPRINT("- Function number: %d\n", FunctionNumber); + PciSlotNumber.u.bits.FunctionNumber = FunctionNumber; + ReturnedLength = HalGetBusData( + PCIConfiguration, + DeviceExtension->SystemIoBusNumber, + PciSlotNumber.u.AsULONG, + &Config, + sizeof(PCI_COMMON_CONFIG)); + DPRINT("- Length of data: %x\n", ReturnedLength); + if (ReturnedLength == sizeof(PCI_COMMON_CONFIG)) + { + 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); + + if ((VendorIdToFind == 0 || Config.VendorID == VendorIdToFind) && + (DeviceIdToFind == 0 || Config.DeviceID == DeviceIdToFind)) + { + break; + } + } + } + + if (FunctionNumber == 8) + { + DPRINT("Didn't find device.\n"); + return ERROR_NO_SYSTEM_RESOURCES; + } + } + + 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 ((Descriptor->Type == CmResourceTypeMemory || + Descriptor->Type == CmResourceTypePort) && + AssignedCount >= NumAccessRanges) + { + DPRINT1("Too many access ranges found\n"); + ExFreePool(AllocatedResources); + return ERROR_NO_SYSTEM_RESOURCES; + } + if (Descriptor->Type == CmResourceTypeMemory) + { + if (NumAccessRanges <= AssignedCount) + { + DPRINT1("Too many access ranges found\n"); + ExFreePool(AllocatedResources); + return ERROR_NO_SYSTEM_RESOURCES; + } + 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 = + (Descriptor->ShareDisposition == CmResourceShareShared); + AssignedCount++; + } + else if (Descriptor->Type == CmResourceTypePort) + { + 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 (Descriptor->Type == CmResourceTypeInterrupt) + { + DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level; + DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector; + } + } + } + ExFreePool(AllocatedResources); + } + else + { + UNIMPLEMENTED + } + + return NO_ERROR; +} + +/* + * @unimplemented + */ + +VP_STATUS STDCALL +VideoPortVerifyAccessRanges( + IN PVOID HwDeviceExtension, + IN ULONG NumAccessRanges, + IN PVIDEO_ACCESS_RANGE AccessRanges) +{ + DPRINT1("VideoPortVerifyAccessRanges not implemented\n"); + return NO_ERROR; +} + +/* + * @unimplemented + */ + +VP_STATUS STDCALL +VideoPortGetDeviceData( + IN PVOID HwDeviceExtension, + IN VIDEO_DEVICE_DATA_TYPE DeviceDataType, + IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine, + IN PVOID Context) +{ + DPRINT("VideoPortGetDeviceData\n"); + UNIMPLEMENTED; + return ERROR_CALL_NOT_IMPLEMENTED; +} + +/* + * @implemented + */ + +PVOID STDCALL +VideoPortAllocatePool( + IN PVOID HwDeviceExtension, + IN VP_POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes, + IN ULONG Tag) +{ + DPRINT("VideoPortAllocatePool\n"); + return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); +} + +/* + * @implemented + */ + +VOID STDCALL +VideoPortFreePool( + IN PVOID HwDeviceExtension, + IN PVOID Ptr) +{ + ExFreePool(Ptr); +} + +/* + * @implemented + */ + +VP_STATUS STDCALL +VideoPortAllocateBuffer( + IN PVOID HwDeviceExtension, + IN ULONG Size, + OUT PVOID *Buffer) +{ + DPRINT("VideoPortAllocateBuffer\n"); + *Buffer = ExAllocatePool(PagedPool, Size); + return *Buffer == NULL ? ERROR_NOT_ENOUGH_MEMORY : NO_ERROR; +} + +/* + * @implemented + */ + +VOID STDCALL +VideoPortReleaseBuffer( + IN PVOID HwDeviceExtension, + IN PVOID Ptr) +{ + DPRINT("VideoPortReleaseBuffer\n"); + ExFreePool(Ptr); +} + +/* + * @unimplemented + */ + +PVOID STDCALL +VideoPortLockBuffer( + IN PVOID HwDeviceExtension, + IN PVOID BaseAddress, + IN ULONG Length, + IN VP_LOCK_OPERATION Operation) +{ + DPRINT1("VideoPortLockBuffer: Unimplemented.\n"); + return NULL; +} + +/* + * @unimplemented + */ + +VOID STDCALL +VideoPortUnlockBuffer( + IN PVOID HwDeviceExtension, + IN PVOID Mdl) +{ + DPRINT1("VideoPortUnlockBuffer: Unimplemented.\n"); +} + +/* + * @unimplemented + */ + +VP_STATUS STDCALL +VideoPortSetTrappedEmulatorPorts( + IN PVOID HwDeviceExtension, + IN ULONG NumAccessRanges, + IN PVIDEO_ACCESS_RANGE AccessRange) +{ + DPRINT("VideoPortSetTrappedEmulatorPorts\n"); + /* Should store the ranges in the device extension for use by ntvdm. */ + return NO_ERROR; +} + +/* + * @implemented + */ + +ULONG STDCALL +VideoPortGetBusData( + IN PVOID HwDeviceExtension, + IN BUS_DATA_TYPE BusDataType, + IN ULONG SlotNumber, + OUT PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortGetBusData\n"); + + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + + if (BusDataType != Cmos) + { + /* Legacy vs. PnP behaviour */ + if (DeviceExtension->PhysicalDeviceObject != NULL) + SlotNumber = DeviceExtension->SystemIoSlotNumber; + } + + return HalGetBusDataByOffset( + BusDataType, + DeviceExtension->SystemIoBusNumber, + SlotNumber, + Buffer, + Offset, + Length); +} + +/* + * @implemented + */ + +ULONG STDCALL +VideoPortSetBusData( + IN PVOID HwDeviceExtension, + IN BUS_DATA_TYPE BusDataType, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortSetBusData\n"); + + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + + if (BusDataType != Cmos) + { + /* Legacy vs. PnP behaviour */ + if (DeviceExtension->PhysicalDeviceObject != NULL) + SlotNumber = DeviceExtension->SystemIoSlotNumber; + } + + return HalSetBusDataByOffset( + BusDataType, + DeviceExtension->SystemIoBusNumber, + SlotNumber, + Buffer, + Offset, + Length); +} diff --git a/reactos/drivers/video/videoprt/services.c b/reactos/drivers/video/videoprt/services.c index 67dd27eed72..8e773a2c872 100644 --- a/reactos/drivers/video/videoprt/services.c +++ b/reactos/drivers/video/videoprt/services.c @@ -18,7 +18,7 @@ * If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id: services.c,v 1.2 2004/03/06 08:39:06 jimtabor Exp $ + * $Id: services.c,v 1.3 2004/03/19 20:58:32 navaraf Exp $ */ #include "videoprt.h" @@ -35,8 +35,7 @@ IntInterfaceDereference(PVOID Context) /* Do nothing */ } -VP_STATUS -STDCALL +VP_STATUS STDCALL VideoPortQueryServices( IN PVOID HwDeviceExtension, IN VIDEO_PORT_SERVICES ServicesType, @@ -58,32 +57,28 @@ VideoPortQueryServices( Int10Interface->Int10ReadMemory = IntInt10ReadMemory; Int10Interface->Int10WriteMemory = IntInt10WriteMemory; Int10Interface->Int10CallBios = IntInt10CallBios; - return STATUS_SUCCESS; + return NO_ERROR; } break; case VideoPortServicesAGP: case VideoPortServicesI2C: case VideoPortServicesHeadless: - return STATUS_NOT_IMPLEMENTED; + return ERROR_CALL_NOT_IMPLEMENTED; default: break; } - return STATUS_UNSUCCESSFUL; + return ERROR_INVALID_FUNCTION; } - -BOOLEAN -STDCALL -VideoPortGetAgpServices(IN PVOID HwDeviceExtension, - IN PVIDEO_PORT_AGP_SERVICES AgpServices) +BOOLEAN STDCALL +VideoPortGetAgpServices( + IN PVOID HwDeviceExtension, + IN PVIDEO_PORT_AGP_SERVICES AgpServices) { - - DPRINT("VideoPortGetAgpServices\n"); - UNIMPLEMENTED; - return FALSE; + DPRINT("VideoPortGetAgpServices\n"); + UNIMPLEMENTED; + return FALSE; } - - diff --git a/reactos/drivers/video/videoprt/spinlock.c b/reactos/drivers/video/videoprt/spinlock.c index 3aa4721d37f..c66fea908f3 100644 --- a/reactos/drivers/video/videoprt/spinlock.c +++ b/reactos/drivers/video/videoprt/spinlock.c @@ -18,7 +18,7 @@ * If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id: spinlock.c,v 1.1 2004/03/09 17:28:49 navaraf Exp $ + * $Id: spinlock.c,v 1.2 2004/03/19 20:58:32 navaraf Exp $ */ #include "videoprt.h" @@ -35,9 +35,9 @@ VideoPortCreateSpinLock( DPRINT("VideoPortCreateSpinLock\n"); *SpinLock = ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK)); if (*SpinLock == NULL) - return STATUS_UNSUCCESSFUL; + return ERROR_NOT_ENOUGH_MEMORY; KeInitializeSpinLock((PKSPIN_LOCK)*SpinLock); - return STATUS_SUCCESS; + return NO_ERROR; } /* @@ -51,7 +51,7 @@ VideoPortDeleteSpinLock( { DPRINT("VideoPortDeleteSpinLock\n"); ExFreePool(SpinLock); - return STATUS_SUCCESS; + return NO_ERROR; } /* diff --git a/reactos/drivers/video/videoprt/timer.c b/reactos/drivers/video/videoprt/timer.c new file mode 100644 index 00000000000..dcb63bb6038 --- /dev/null +++ b/reactos/drivers/video/videoprt/timer.c @@ -0,0 +1,92 @@ +/* + * VideoPort driver + * + * Copyright (C) 2002, 2003, 2004 ReactOS Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: timer.c,v 1.2 2004/03/19 20:58:32 navaraf Exp $ + */ + +#include "videoprt.h" + +/* PRIVATE FUNCTIONS **********************************************************/ + +VOID STDCALL +IntVideoPortTimerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID ServiceContext) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = ServiceContext; + + ASSERT(DeviceExtension->DriverExtension->InitializationData.HwTimer != NULL); + + DeviceExtension->DriverExtension->InitializationData.HwTimer( + &DeviceExtension->MiniPortDeviceExtension); +} + +BOOLEAN STDCALL +IntVideoPortSetupTimer( + IN PDEVICE_OBJECT DeviceObject, + IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension) +{ + NTSTATUS Status; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + if (DriverExtension->InitializationData.HwTimer != NULL) + { + DPRINT("Initializing timer\n"); + + Status = IoInitializeTimer( + DeviceObject, + IntVideoPortTimerRoutine, + DeviceExtension); + + if (!NT_SUCCESS(Status)) + { + DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status); + return FALSE; + } + } + + return TRUE; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @implemented + */ + +VOID STDCALL +VideoPortStartTimer(IN PVOID HwDeviceExtension) +{ + DPRINT("VideoPortStartTimer\n"); + IoStartTimer(VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->FunctionalDeviceObject); +} + +/* + * @implemented + */ + +VOID STDCALL +VideoPortStopTimer(IN PVOID HwDeviceExtension) +{ + DPRINT("VideoPortStopTimer\n"); + IoStopTimer(VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->FunctionalDeviceObject); +} diff --git a/reactos/drivers/video/videoprt/videoprt.c b/reactos/drivers/video/videoprt/videoprt.c index 349f90bb2bb..3fc4bb3e2e2 100644 --- a/reactos/drivers/video/videoprt/videoprt.c +++ b/reactos/drivers/video/videoprt/videoprt.c @@ -18,1059 +18,576 @@ * If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id: videoprt.c,v 1.23 2004/03/14 19:25:34 dwelch Exp $ + * $Id: videoprt.c,v 1.24 2004/03/19 20:58:32 navaraf Exp $ */ #include "videoprt.h" +#include "internal/ps.h" -BOOLEAN CsrssInitialized = FALSE; +/* GLOBAL VARIABLES ***********************************************************/ + +ULONG CsrssInitialized = FALSE; PEPROCESS Csrss = NULL; -PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL; -static PVOID RomImageBuffer = NULL; -VOID STDCALL STATIC -VideoPortDeferredRoutine( +/* PRIVATE FUNCTIONS **********************************************************/ + +NTSTATUS STDCALL +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + return STATUS_SUCCESS; +} + +PVOID STDCALL +IntVideoPortImageDirectoryEntryToData( + PVOID BaseAddress, + ULONG Directory) +{ + PIMAGE_NT_HEADERS NtHeader; + ULONG Va; + + 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)(BaseAddress + Va); +} + +PVOID STDCALL +IntVideoPortGetProcAddress( + IN PVOID HwDeviceExtension, + IN PUCHAR FunctionName) +{ + SYSTEM_LOAD_IMAGE 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.ModuleName, L"videoprt"); + Status = ZwSetSystemInformation( + SystemLoadImage, + &GdiDriverInfo, + sizeof(SYSTEM_LOAD_IMAGE)); + if (!NT_SUCCESS(Status)) + { + DPRINT("Couldn't get our own module handle?\n"); + return NULL; + } + + BaseAddress = GdiDriverInfo.ModuleBase; + + /* 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(FunctionName, (char*)(BaseAddress + *NamePtr), + strlen(FunctionName))) + { + return (PVOID)((ULONG_PTR)BaseAddress + + (ULONG_PTR)AddressPtr[*OrdinalPtr]); + } + } + + DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName); + + return NULL; +} + +VOID STDCALL +IntVideoPortDeferredRoutine( IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, - IN PVOID SystemArgument2 - ); -PVOID STDCALL -VideoPortGetProcAddress(IN PVOID HwDeviceExtension, - IN PUCHAR FunctionName); - -// ------------------------------------------------------- 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) + IN PVOID SystemArgument2) { - DPRINT("DriverEntry()\n"); - return(STATUS_SUCCESS); + PVOID HwDeviceExtension = + &((PVIDEO_PORT_DEVICE_EXTENSION)DeferredContext)->MiniPortDeviceExtension; + ((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2); } -/* - * @implemented - */ -VOID -VideoPortDebugPrint(IN VIDEO_DEBUG_LEVEL DebugPrintLevel, - IN PCHAR DebugMessage, ...) -{ - char Buffer[256]; - va_list ap; - -/* - if (DebugPrintLevel > InternalDebugLevel) - return; -*/ - va_start (ap, DebugMessage); - vsprintf (Buffer, DebugMessage, ap); - va_end (ap); - - DbgPrint (Buffer); -} - - -/* - * @implemented - */ -VOID -STDCALL -VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension, - IN PVOID MappedAddress) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT("VideoPortFreeDeviceBase\n"); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - InternalUnmapMemory(DeviceExtension, MappedAddress); -} - - -/* - * @implemented - */ -ULONG -STDCALL -VideoPortGetBusData(IN PVOID HwDeviceExtension, - IN BUS_DATA_TYPE BusDataType, - IN ULONG SlotNumber, - OUT PVOID Buffer, - IN ULONG Offset, - IN ULONG Length) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT("VideoPortGetBusData\n"); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - return HalGetBusDataByOffset(BusDataType, - DeviceExtension->SystemIoBusNumber, - SlotNumber, - Buffer, - Offset, - Length); -} - - -/* - * @implemented - */ -UCHAR -STDCALL -VideoPortGetCurrentIrql(VOID) -{ - return KeGetCurrentIrql(); -} - - -/* - * @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"); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace, NULL); -} - - -/* - * @unimplemented - */ -VP_STATUS -STDCALL -VideoPortGetDeviceData(IN PVOID HwDeviceExtension, - IN VIDEO_DEVICE_DATA_TYPE DeviceDataType, - IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine, - IN PVOID Context) -{ - DPRINT("VideoPortGetDeviceData\n"); - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - -/* - * @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) -{ - PCI_SLOT_NUMBER PciSlotNumber; - 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; - USHORT VendorIdToFind; - USHORT DeviceIdToFind; - ULONG SlotIdToFind; - - DPRINT("VideoPortGetAccessRanges\n"); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - if (0 == NumRequestedResources && - PCIBus == DeviceExtension->AdapterInterfaceType) - { - VendorIdToFind = VendorId != NULL ? *(PUSHORT)VendorId : 0; - DeviceIdToFind = DeviceId != NULL ? *(PUSHORT)DeviceId : 0; - SlotIdToFind = Slot != NULL ? *Slot : 0; - - DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x SlotId 0x%04x\n", - VendorIdToFind, DeviceIdToFind, SlotIdToFind); - - PciSlotNumber.u.AsULONG = SlotIdToFind; - - /* - Search for the device id and vendor id on this bus. - */ - for (FunctionNumber = 0; FunctionNumber < 8; FunctionNumber++) - { - ULONG ReturnedLength; - DPRINT("- Function number: %d\n", FunctionNumber); - PciSlotNumber.u.bits.FunctionNumber = FunctionNumber; - ReturnedLength = HalGetBusData(PCIConfiguration, - DeviceExtension->SystemIoBusNumber, - PciSlotNumber.u.AsULONG, - &Config, - sizeof(PCI_COMMON_CONFIG)); - DPRINT("- Length of data: %x\n", ReturnedLength); - if (sizeof(PCI_COMMON_CONFIG) == ReturnedLength) - { - 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); - - if ((VendorIdToFind == 0 || Config.VendorID == VendorIdToFind) && - (DeviceIdToFind == 0 || Config.DeviceID == DeviceIdToFind)) - { - break; - } - } - } - if (FunctionNumber == 8) - { - DPRINT("Didn't find device.\n"); - 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; -} - -typedef struct QueryRegistryCallbackContext -{ - 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) -{ - 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) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - QUERY_REGISTRY_CALLBACK_CONTEXT Context; - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - if (IsParameterFileName) - { - UNIMPLEMENTED; - } - - 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; - - DPRINT("VideoPortGetVgaStatus = %x \n", VgaStatus); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - if(KeGetCurrentIrql() == PASSIVE_LEVEL) - { - DPRINT("VideoPortGetVgaStatus1 = %x \n", VgaStatus); - - if ( PCIBus == DeviceExtension->AdapterInterfaceType) - { -/* - VgaStatus 0 == VGA not enabled, 1 == VGA enabled. - */ - DPRINT("VideoPortGetVgaStatus2 = %x \n", VgaStatus); - - /* Assumed for now */ - - VgaStatus = (PULONG) 1; - - return STATUS_SUCCESS; - } - } - DPRINT("VideoPortGetVgaStatus3 = %x \n", VgaStatus); - - return ERROR_INVALID_FUNCTION; -} - -static BOOLEAN STDCALL -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) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DeviceExtension = Context; - assert(DeviceExtension == DeviceObject->DeviceExtension - && NULL != DeviceExtension->HwTimer); - - DeviceExtension->HwTimer(&DeviceExtension->MiniPortDeviceExtension); -} - -/* - * @implemented - */ ULONG STDCALL -VideoPortInitialize(IN PVOID Context1, - IN PVOID Context2, - IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData, - IN PVOID HwContext) +IntVideoPortAllocateDeviceNumber(VOID) { - 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; + NTSTATUS Status; + ULONG DeviceNumber; + WCHAR SymlinkBuffer[20]; + UNICODE_STRING SymlinkName; - DPRINT("VideoPortInitialize\n"); + for (DeviceNumber = 0;;) + { + OBJECT_ATTRIBUTES Obj; + HANDLE ObjHandle; - 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); + 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); - DisplayNumber++; - continue; - } + { + ZwClose(ObjHandle); + DeviceNumber++; + continue; + } else if (Status == STATUS_NOT_FOUND || Status == STATUS_UNSUCCESSFUL) - { - break; - } + break; else - { - return Status; - } - } + return 0xFFFFFFFF; + } - DPRINT("- DisplayNumber: %d\n", DisplayNumber); + return DeviceNumber; +} - Again = FALSE; +NTSTATUS STDCALL +IntVideoPortFindAdapter( + IN PDRIVER_OBJECT DriverObject, + IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension, + IN PDEVICE_OBJECT PhysicalDeviceObject) +{ + WCHAR DeviceVideoBuffer[20]; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + ULONG DeviceNumber; + 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; + PDEVICE_OBJECT DeviceObject; + BOOL LegacyDetection; - do - { - /* Create a unicode device name. */ - swprintf(DeviceBuffer, L"\\Device\\Video%lu", DisplayNumber); - RtlInitUnicodeString(&DeviceName, DeviceBuffer); + /* + * Find the first free device number that can be used for video device + * object names and symlinks. + */ - /* Create the device. */ - Status = IoCreateDevice( - MPDriverObject, - HwInitializationData->HwDeviceExtensionSize + - sizeof(VIDEO_PORT_DEVICE_EXTENSION), - &DeviceName, - FILE_DEVICE_VIDEO, - 0, - TRUE, - &MPDeviceObject); + DeviceNumber = IntVideoPortAllocateDeviceNumber(); + if (DeviceNumber == 0xFFFFFFFF) + { + DPRINT("Can't find free device number\n"); + return STATUS_UNSUCCESSFUL; + } + + /* + * Create the device object, we need it even for calling HwFindAdapter :( + */ + + /* 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->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) + { + LegacyDetection = TRUE; + } + else + { + /* 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("IoCreateDevice call failed with status 0x%08x\n", Status); - return 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; + LegacyDetection = TRUE; + } + } - MPDriverObject->DeviceObject = MPDeviceObject; + DeviceExtension->AdapterInterfaceType = + DriverExtension->InitializationData.AdapterInterfaceType; - /* 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; + if (PhysicalDeviceObject != NULL) + { + /* Get bus type from the upper level bus driver. */ + Size = sizeof(ULONG); + IoGetDeviceProperty( + PhysicalDeviceObject, + DevicePropertyLegacyBusType, + Size, + &DeviceExtension->AdapterInterfaceType, + &Size); - /* 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; - KeInitializeDpc(&DeviceExtension->DpcObject, VideoPortDeferredRoutine, - (PVOID)DeviceExtension); - 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); + /* Get bus device address from the upper level bus driver. */ + Size = sizeof(ULONG); + IoGetDeviceProperty( + PhysicalDeviceObject, + DevicePropertyAddress, + Size, + &DeviceExtension->SystemIoSlotNumber, + &Size); + } - 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; + InitializeListHead(&DeviceExtension->AddressMappingListHead); + KeInitializeDpc( + &DeviceExtension->DpcObject, + IntVideoPortDeferredRoutine, + DeviceExtension); - 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; - ConfigInfo.DriverRegistryPath = RegistryPath->Buffer; - ConfigInfo.VideoPortGetProcAddress = VideoPortGetProcAddress; + /* + * Uff, the DeviceExtension is setup. Now it's needed to setup + * a ConfigInfo structure that we will pass to HwFindAdapter. + */ - /* 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 %X\n", Status); - DeviceExtension->SystemIoBusNumber++; - } - } - while (NO_ERROR != Status && DeviceExtension->SystemIoBusNumber < MaxBus); + 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; - if (NO_ERROR != Status) - { - RtlFreeUnicodeString(&DeviceExtension->RegistryPath); - IoDeleteDevice(MPDeviceObject); + Size = sizeof(SystemBasicInfo); + Status = ZwQuerySystemInformation( + SystemBasicInformation, + &SystemBasicInfo, + Size, + &Size); - return Status; - } - DPRINT("Found adapter\n"); + if (NT_SUCCESS(Status)) + { + ConfigInfo.SystemMemorySize = + SystemBasicInfo.NumberOfPhysicalPages * + SystemBasicInfo.PhysicalPageSize; + } - /* create symbolic link "\??\DISPLAYx" */ - swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DisplayNumber + 1); - RtlInitUnicodeString (&SymlinkName, - SymlinkBuffer); - IoCreateSymbolicLink (&SymlinkName, - &DeviceName); + /* + * 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 (LegacyDetection) + { + ULONG BusNumber, MaxBuses; - /* 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)); + MaxBuses = DeviceExtension->AdapterInterfaceType == PCIBus ? 8 : 1; - /* FIXME: Allocate hardware resources for device */ + for (BusNumber = 0; BusNumber < MaxBuses; BusNumber++) + { + DeviceExtension->SystemIoBusNumber = + ConfigInfo.SystemIoBusNumber = BusNumber; - /* 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); + 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 %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 %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 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; + } + + if (PhysicalDeviceObject != NULL) + IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); + + DPRINT("STATUS_SUCCESS\n"); + return STATUS_SUCCESS; +} + +VOID FASTCALL +IntAttachToCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess) +{ + *CallingProcess = PsGetCurrentProcess(); + if (*CallingProcess != Csrss) + { + if (PsGetCurrentThread()->OldProcess != NULL) + { + *PrevAttachedProcess = *CallingProcess; + KeDetachProcess(); + } + else + { + *PrevAttachedProcess = NULL; + } + KeAttachProcess(Csrss); + } +} + +VOID FASTCALL +IntDetachFromCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess) +{ + if (*CallingProcess != Csrss) + { + KeDetachProcess(); + if (NULL != *PrevAttachedProcess) + { + KeAttachProcess(*PrevAttachedProcess); + } + } +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @implemented + */ + +ULONG STDCALL +VideoPortInitialize( + IN PVOID Context1, + IN PVOID Context2, + IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData, + IN PVOID HwContext) +{ + PDRIVER_OBJECT DriverObject = Context1; + PUNICODE_STRING RegistryPath = Context2; + NTSTATUS Status; + PVIDEO_PORT_DRIVER_EXTENSION DriverExtension; + BOOL LegacyDetection = FALSE; + + DPRINT("VideoPortInitialize\n"); + + /* + * 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 calls VideoPortInitialize + * again. + */ + + DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject); + if (DriverExtension == NULL) + { + Status = IoAllocateDriverObjectExtension( + DriverObject, + DriverObject, + sizeof(VIDEO_PORT_DRIVER_EXTENSION), + (PVOID *)&DriverExtension); - 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; + } + } - return STATUS_SUCCESS; -} + /* + * Copy the correct miniport initializtation data to the device extension. + */ -/* - * @unimplemented - */ -VOID -STDCALL -VideoPortLogError(IN PVOID HwDeviceExtension, - IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL, - IN VP_STATUS ErrorCode, - IN ULONG UniqueId) -{ - 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); - } -} + RtlCopyMemory( + &DriverExtension->InitializationData, + HwInitializationData, + sizeof(VIDEO_HW_INITIALIZATION_DATA)); + DriverExtension->HwContext = HwContext; + RtlCopyMemory(&DriverExtension->RegistryPath, RegistryPath, sizeof(UNICODE_STRING)); -/* - * @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; -} + 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; -/* - * @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; + case SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA: + DPRINT("We were loaded by a Windows 2000 miniport driver.\n"); + break; - DPRINT("VideoPortMapMemory\n"); + case sizeof(VIDEO_HW_INITIALIZATION_DATA): + DPRINT("We were loaded by a Windows XP or later miniport driver.\n"); + break; - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - *VirtualAddress = InternalMapMemory(DeviceExtension, PhysicalAddress, - *Length, *InIoSpace, &Status); + default: + DPRINT("Invalid HwInitializationData size.\n"); + return STATUS_UNSUCCESSFUL; + } - return Status; -} + DriverObject->MajorFunction[IRP_MJ_CREATE] = IntVideoPortDispatchOpen; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = IntVideoPortDispatchClose; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IntVideoPortDispatchDeviceControl; + DriverObject->DriverUnload = IntVideoPortUnload; + /* + * Plug & Play drivers registers the device in AddDevice routine. For + * legacy drivers we must do it now. + */ -/* - * @implemented - */ -BOOLEAN -STDCALL -VideoPortScanRom(IN PVOID HwDeviceExtension, - IN PUCHAR RomBase, - IN ULONG RomLength, - IN PUCHAR String) -{ - ULONG StringLength; - BOOLEAN Found; - PUCHAR SearchLocation; + if (LegacyDetection) + { + Status = IntVideoPortFindAdapter(DriverObject, DriverExtension, NULL); + 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; - 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++) - { - Found = (RtlCompareMemory(SearchLocation, String, StringLength) == StringLength); - if (Found) - { - DPRINT("Match found at %p\n", SearchLocation); - } - } - - 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) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT("VideoPortSetBusData\n"); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - return HalSetBusDataByOffset(BusDataType, - DeviceExtension->SystemIoBusNumber, - SlotNumber, - Buffer, - Offset, - Length); -} - - -/* - * @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"); - - 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); -} - - -/* - * @unimplemented - */ -VP_STATUS -STDCALL -VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension, - IN ULONG NumAccessRanges, - IN PVIDEO_ACCESS_RANGE AccessRange) -{ - DPRINT("VideoPortSetTrappedEmulatorPorts\n"); - /* Should store the ranges in the device extension for use by ntvdm. */ - return STATUS_SUCCESS; -} - - -/* - * @implemented - */ -VOID -STDCALL -VideoPortStartTimer(IN PVOID HwDeviceExtension) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DPRINT("VideoPortStartTimer\n"); - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - IoStartTimer(DeviceExtension->DeviceObject); -} - - -/* - * @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); -} - - -/* - * @implemented - */ -BOOLEAN -STDCALL -VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension, - IN VIDEO_SYNCHRONIZE_PRIORITY Priority, - IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine, - OUT PVOID Context) -{ - BOOLEAN Ret; - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - KIRQL OldIrql; - - 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; -} - - -/* - * @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; -} - - -/* - * @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) -{ - if (NULL == ResetDisplayParametersDeviceExtension) - { - return(FALSE); - } - if (NULL == ResetDisplayParametersDeviceExtension->HwResetHw) - { - return(FALSE); - } - if (!ResetDisplayParametersDeviceExtension->HwResetHw(&ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension, - Columns, Rows)) - { - return(FALSE); - } - - ResetDisplayParametersDeviceExtension = NULL; - - return TRUE; -} - -/* - * @implemented - */ - -PVOID -STDCALL -VideoPortAllocatePool( - IN PVOID HwDeviceExtension, - IN VP_POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes, - IN ULONG Tag) -{ - return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); + return STATUS_SUCCESS; + } } /* @@ -1078,347 +595,321 @@ VideoPortAllocatePool( */ VOID -STDCALL -VideoPortFreePool( - IN PVOID HwDeviceExtension, - IN PVOID Ptr) +VideoPortDebugPrint( + IN VIDEO_DEBUG_LEVEL DebugPrintLevel, + IN PCHAR DebugMessage, ...) { - ExFreePool(Ptr); + char Buffer[256]; + va_list ap; + + va_start(ap, DebugMessage); + vsprintf(Buffer, DebugMessage, ap); + va_end(ap); + + DbgPrint(Buffer); } -// 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; -} - -// 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; - BOOLEAN Ret; - NTSTATUS Status; - - 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 */ - Ret = ((PDRIVER_STARTIO)DeviceObject->DriverObject->DriverStartIo)((PVOID) &DeviceExtension->MiniPortDeviceExtension, (PIRP)vrp); - assert(Ret); - - /* Free the VRP */ - ExFreePool(vrp); - - DPRINT("- Returned status: %x/%d\n", Irp->IoStatus.Status, - Irp->IoStatus.Information); - if (Irp->IoStatus.Status != STATUS_SUCCESS) - { - if (Irp->IoStatus.Status != ERROR_MORE_DATA) - { - Irp->IoStatus.Information = 0; - } - /* Map from win32 error codes to ntstatus values. */ - switch (Irp->IoStatus.Status) - { - case ERROR_NOT_ENOUGH_MEMORY: - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - break; - case ERROR_MORE_DATA: - Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; - break; - case ERROR_INVALID_FUNCTION: - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - break; - case ERROR_INVALID_PARAMETER: - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - break; - case ERROR_INSUFFICIENT_BUFFER: - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - break; - case ERROR_DEV_NOT_EXIST: - Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST; - break; - case ERROR_IO_PENDING: - Irp->IoStatus.Status = STATUS_PENDING; - break; - } - } - - Status = Irp->IoStatus.Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return Status; -} - -PVOID STDCALL -InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, - IN PHYSICAL_ADDRESS IoAddress, - IN ULONG NumberOfUchars, - IN UCHAR InIoSpace, - OUT NTSTATUS *Status) -{ - PHYSICAL_ADDRESS TranslatedAddress; - PVIDEO_PORT_ADDRESS_MAPPING AddressMapping; - ULONG AddressSpace; - PVOID MappedAddress; - PLIST_ENTRY Entry; - - DPRINT("- IoAddress: %lx\n", IoAddress.u.LowPart); - DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars); - DPRINT("- InIoSpace: %x\n", InIoSpace); - InIoSpace &= ~VIDEO_MEMORY_SPACE_DENSE; - 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; - } -} +/* + * @unimplemented + */ VOID STDCALL -InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, - IN PVOID MappedAddress) +VideoPortLogError( + IN PVOID HwDeviceExtension, + IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL, + IN VP_STATUS ErrorCode, + IN ULONG UniqueId) { - 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; - } + 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 + */ + +UCHAR STDCALL +VideoPortGetCurrentIrql(VOID) +{ + return KeGetCurrentIrql(); +} + +typedef struct QueryRegistryCallbackContext +{ + 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) +{ + 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) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + QUERY_REGISTRY_CALLBACK_CONTEXT Context; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName); + + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + + if (IsParameterFileName) + { + UNIMPLEMENTED; + } + + 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 +VideoPortSetRegistryParameters( + IN PVOID HwDeviceExtension, + IN PWSTR ValueName, + IN PVOID ValueData, + IN ULONG ValueLength) +{ + 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 + */ + +VP_STATUS STDCALL +VideoPortGetVgaStatus( + IN PVOID HwDeviceExtension, + OUT PULONG VgaStatus) +{ + 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; +} + +/* + * @implemented + */ + +PVOID STDCALL +VideoPortGetRomImage( + IN PVOID HwDeviceExtension, + IN PVOID Unused1, + IN ULONG Unused2, + IN ULONG Length) +{ + static PVOID RomImageBuffer = NULL; + PEPROCESS CallingProcess; + PEPROCESS PrevAttachedProcess; + + 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, &PrevAttachedProcess); + RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length); + IntDetachFromCSRSS(&CallingProcess, &PrevAttachedProcess); + + return RomImageBuffer; + } +} + +/* + * @implemented + */ + +BOOLEAN STDCALL +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++) + { + Found = (RtlCompareMemory(SearchLocation, String, StringLength) == StringLength); + if (Found) + { + DPRINT("Match found at %p\n", SearchLocation); + } + } + + return Found; +} + +/* + * @implemented + */ + +BOOLEAN STDCALL +VideoPortSynchronizeExecution( + IN PVOID HwDeviceExtension, + IN VIDEO_SYNCHRONIZE_PRIORITY Priority, + IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine, + OUT PVOID Context) +{ + 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; +} + +/* + * @unimplemented + */ + BOOLEAN STDCALL VideoPortDDCMonitorHelper( PVOID HwDeviceExtension, @@ -1432,252 +923,67 @@ VideoPortDDCMonitorHelper( } /* - * @implemented + * @unimplemented */ -VP_STATUS -STDCALL -VideoPortAllocateBuffer(IN PVOID HwDeviceExtension, - IN ULONG Size, - OUT PVOID *Buffer) + +VP_STATUS STDCALL +VideoPortEnumerateChildren( + IN PVOID HwDeviceExtension, + IN PVOID Reserved) { - DPRINT("VideoPortAllocateBuffer()\n"); - - Buffer = ExAllocatePool(PagedPool, Size); - return STATUS_SUCCESS; - + DPRINT1("VideoPortEnumerateChildren(): Unimplemented.\n"); + return NO_ERROR; +} + +/* + * @unimplemented + */ + +VP_STATUS STDCALL +VideoPortCreateSecondaryDisplay( + IN PVOID HwDeviceExtension, + IN OUT PVOID *SecondaryDeviceExtension, + IN ULONG Flag) +{ + DPRINT1("VideoPortCreateSecondaryDisplay: Unimplemented.\n"); + return NO_ERROR; } /* * @implemented */ -VOID -STDCALL -VideoPortReleaseBuffer( IN PVOID HwDeviceExtension, - IN PVOID Ptr) + +BOOLEAN STDCALL +VideoPortQueueDpc( + IN PVOID HwDeviceExtension, + IN PMINIPORT_DPC_ROUTINE CallbackRoutine, + IN PVOID Context) { - DPRINT("VideoPortReleaseBuffer()\n"); - - ExFreePool(Ptr); -} - - -VP_STATUS -STDCALL -VideoPortEnumerateChildren ( IN PVOID HwDeviceExtension, - IN PVOID Reserved ) -{ - DPRINT1("VideoPortEnumerateChildren(): Unimplemented.\n"); - return STATUS_SUCCESS; + return KeInsertQueueDpc( + &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->DpcObject, + (PVOID)CallbackRoutine, + (PVOID)Context); } -PVOID -STDCALL -VideoPortGetRomImage ( IN PVOID HwDeviceExtension, - IN PVOID Unused1, - IN ULONG Unused2, - IN ULONG Length ) +/* + * @unimplemented + */ + +PVOID STDCALL +VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject) { - 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 - { - PEPROCESS CallingProcess, PrevAttachedProcess; - - /* - The DDK says we shouldn't use the legacy C000 method but get the - rom base address from the corresponding pci or acpi register but - lets ignore that and use C000 anyway. CSRSS has already mapped the - bios area into memory so we'll copy from there. - */ - CallingProcess = PsGetCurrentProcess(); - if (CallingProcess != Csrss) - { - if (NULL != PsGetCurrentThread()->OldProcess) - { - PrevAttachedProcess = CallingProcess; - KeDetachProcess(); - } - else - { - PrevAttachedProcess = NULL; - } - KeAttachProcess(Csrss); - } - - /* - Copy the bios. - */ - Length = min(Length, 0x10000); - if (RomImageBuffer != NULL) - { - ExFreePool(RomImageBuffer); - } - RomImageBuffer = ExAllocatePool(PagedPool, Length); - if (RomImageBuffer == NULL) - { - return(NULL); - } - RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length); - - /* - Detach from csrss if we attached. - */ - if (CallingProcess != Csrss) - { - KeDetachProcess(); - if (NULL != PrevAttachedProcess) - { - KeAttachProcess(PrevAttachedProcess); - } - } - - return(RomImageBuffer); - } + DPRINT1("VideoPortGetAssociatedDeviceExtension: Unimplemented.\n"); + return NULL; } -VOID -STDCALL -STATIC -VideoPortDeferredRoutine ( IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2 ) -{ - PVOID HwDeviceExtension = - ((PVIDEO_PORT_DEVICE_EXTENSION)DeferredContext)->MiniPortDeviceExtension; - ((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2); -} - -BOOLEAN -STDCALL -VideoPortQueueDpc ( IN PVOID HwDeviceExtension, - IN PMINIPORT_DPC_ROUTINE CallbackRoutine, - IN PVOID Context ) -{ - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - return KeInsertQueueDpc(&DeviceExtension->DpcObject, - (PVOID)CallbackRoutine, - (PVOID)Context); -} - -PVOID -STDCALL -VideoPortGetAssociatedDeviceExtension ( IN PVOID DeviceObject ) -{ - DPRINT1("VideoPortGetAssociatedDeviceExtension(): Unimplemented.\n"); - return(NULL); -} - -PVOID -STDCALL -VideoPortAllocateCommonBuffer ( IN PVOID HwDeviceExtension, - IN PVP_DMA_ADAPTER VpDmaAdapter, - IN ULONG DesiredLength, - OUT PPHYSICAL_ADDRESS LogicalAddress, - IN BOOLEAN CacheEnabled, - PVOID Reserved ) -{ - return HalAllocateCommonBuffer((PADAPTER_OBJECT)VpDmaAdapter, - DesiredLength, - LogicalAddress, - CacheEnabled); -} - -VOID -STDCALL -VideoPortReleaseCommonBuffer ( IN PVOID HwDeviceExtension, - IN PVP_DMA_ADAPTER VpDmaAdapter, - IN ULONG Length, - IN PHYSICAL_ADDRESS LogicalAddress, - IN PVOID VirtualAddress, - IN BOOLEAN CacheEnabled ) -{ - HalFreeCommonBuffer((PADAPTER_OBJECT)VpDmaAdapter, - Length, - LogicalAddress, - VirtualAddress, - CacheEnabled); -} - -VP_STATUS -STDCALL -VideoPortCreateSecondaryDisplay ( IN PVOID HwDeviceExtension, - IN OUT PVOID *SecondaryDeviceExtension, - IN ULONG Flag ) -{ - DPRINT1("VideoPortCreateSecondaryDisplay(): Unimplemented.\n"); - return STATUS_UNSUCCESSFUL; -} - -VOID -STDCALL -VideoPortPutDmaAdapter ( IN PVOID HwDeviceExtension, - IN PVP_DMA_ADAPTER VpDmaAdapter ) -{ - DPRINT("VideoPortPutDmaAdapter(): Unimplemented.\n"); -} - -PVP_DMA_ADAPTER -STDCALL -VideoPortGetDmaAdapter ( IN PVOID HwDeviceExtension, - IN PVP_DEVICE_DESCRIPTION VpDeviceExtension ) -{ - DEVICE_DESCRIPTION DeviceDescription; - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - ULONG NumberOfMapRegisters; - PVP_DMA_ADAPTER Adapter; - - DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, - VIDEO_PORT_DEVICE_EXTENSION, - MiniPortDeviceExtension); - - DPRINT("VideoPortGetDmaAdapter()\n"); - - DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; - DeviceDescription.Master = TRUE /* ?? */; - DeviceDescription.ScatterGather = VpDeviceExtension->ScatterGather; - DeviceDescription.DemandMode = FALSE /* ?? */; - DeviceDescription.AutoInitialize = FALSE /* ?? */; - DeviceDescription.Dma32BitAddresses = VpDeviceExtension->Dma32BitAddresses; - DeviceDescription.IgnoreCount = FALSE /* ?? */; - DeviceDescription.Reserved1 = FALSE; - DeviceDescription.BusNumber = DeviceExtension->SystemIoBusNumber; - DeviceDescription.DmaChannel = 0 /* ?? */; - DeviceDescription.InterfaceType = DeviceExtension->AdapterInterfaceType; - DeviceDescription.DmaWidth = Width8Bits; - DeviceDescription.DmaSpeed = Compatible; - DeviceDescription.MaximumLength = VpDeviceExtension->MaximumLength; - DeviceDescription.DmaPort = 0; - - Adapter = - (PVP_DMA_ADAPTER)HalGetAdapter(&DeviceDescription, &NumberOfMapRegisters); - DPRINT("Adapter %X\n", Adapter); - return(Adapter); -} - - /* * @implemented */ -VP_STATUS -STDCALL -VideoPortGetVersion ( IN PVOID HwDeviceExtension, - IN OUT PVPOSVERSIONINFO VpOsVersionInfo ) + +VP_STATUS STDCALL +VideoPortGetVersion( + IN PVOID HwDeviceExtension, + IN OUT PVPOSVERSIONINFO VpOsVersionInfo) { RTL_OSVERSIONINFOEXW Version; @@ -1692,202 +998,58 @@ VideoPortGetVersion ( IN PVOID HwDeviceExtension, VpOsVersionInfo->BuildNumber = Version.dwBuildNumber; VpOsVersionInfo->ServicePackMajor = Version.wServicePackMajor; VpOsVersionInfo->ServicePackMinor = Version.wServicePackMinor; - return STATUS_SUCCESS; + return NO_ERROR; } - return STATUS_UNSUCCESSFUL; + return ERROR_INVALID_PARAMETER; #else VpOsVersionInfo->MajorVersion = 5; VpOsVersionInfo->MinorVersion = 0; VpOsVersionInfo->BuildNumber = 2195; VpOsVersionInfo->ServicePackMajor = 4; VpOsVersionInfo->ServicePackMinor = 0; - return(STATUS_SUCCESS); + return NO_ERROR; #endif } return ERROR_INVALID_PARAMETER; } -PVOID -STDCALL -VideoPortLockBuffer ( IN PVOID HwDeviceExtension, - IN PVOID BaseAddress, - IN ULONG Length, - IN VP_LOCK_OPERATION Operation ) +/* + * @unimplemented + */ + +BOOLEAN STDCALL +VideoPortCheckForDeviceExistence( + IN PVOID HwDeviceExtension, + IN USHORT VendorId, + IN USHORT DeviceId, + IN UCHAR RevisionId, + IN USHORT SubVendorId, + IN USHORT SubSystemId, + IN ULONG Flags) { - DPRINT1("VideoPortLockBuffer(): Unimplemented.\n"); - return NULL; + DPRINT1("VideoPortCheckForDeviceExistence: Unimplemented.\n"); + return TRUE; } -VOID -STDCALL -VideoPortUnlockBuffer ( IN PVOID HwDeviceExtension, - IN PVOID Mdl ) +/* + * @unimplemented + */ + +VP_STATUS STDCALL +VideoPortRegisterBugcheckCallback( + IN PVOID HwDeviceExtension, + IN ULONG BugcheckCode, + IN PVOID Callback, + IN ULONG BugcheckDataSize) { - DPRINT1("VideoPortUnlockBuffer(): Unimplemented.\n"); + DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n"); + return NO_ERROR; } -VP_STATUS -STDCALL -VideoPortCreateEvent ( IN PVOID HwDeviceExtension, - IN ULONG EventFlag, - IN PVOID Unused, - OUT PEVENT *Event) -{ - EVENT_TYPE Type; - (*Event) = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), - TAG_VIDEO_PORT); - if ((*Event) == NULL) - { - return STATUS_NO_MEMORY; - } - if (EventFlag & NOTIFICATION_EVENT) - { - Type = NotificationEvent; - } - else - { - Type = SynchronizationEvent; - } - KeInitializeEvent((PKEVENT)*Event, Type, EventFlag & INITIAL_EVENT_SIGNALED); - return STATUS_SUCCESS; -} - -VP_STATUS -STDCALL -VideoPortDeleteEvent ( IN PVOID HwDeviceExtension, - IN PEVENT Event) -{ - ExFreePool(Event); - return STATUS_SUCCESS; -} - -LONG -STDCALL -VideoPortSetEvent ( IN PVOID HwDeviceExtension, - IN PEVENT Event ) -{ - return KeSetEvent((PKEVENT)Event, IO_NO_INCREMENT, FALSE); -} - -VOID -STDCALL -VideoPortClearEvent ( IN PVOID HwDeviceExtension, - IN PEVENT Event ) -{ - KeClearEvent((PKEVENT)Event); -} - -VP_STATUS -STDCALL -VideoPortWaitForSingleObject ( IN PVOID HwDeviceExtension, - IN PVOID Object, - IN PLARGE_INTEGER Timeout OPTIONAL ) -{ - return KeWaitForSingleObject(Object, - Executive, - KernelMode, - FALSE, - Timeout); -} - -BOOLEAN -STDCALL -VideoPortCheckForDeviceExistence ( IN PVOID HwDeviceExtension, - IN USHORT VendorId, - IN USHORT DeviceId, - IN UCHAR RevisionId, - IN USHORT SubVendorId, - IN USHORT SubSystemId, - IN ULONG Flags ) -{ - DPRINT1("VideoPortCheckForDeviceExistence(): Unimplemented.\n"); - return TRUE; -} - -VP_STATUS -STDCALL -VideoPortRegisterBugcheckCallback ( IN PVOID HwDeviceExtension, - IN ULONG BugcheckCode, - IN PVOID Callback, - IN ULONG BugcheckDataSize ) -{ - DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n"); - return STATUS_UNSUCCESSFUL; -} - -PVOID -STDCALL -VideoPortImageDirectoryEntryToData ( PVOID BaseAddress, - ULONG Directory ) -{ - PIMAGE_NT_HEADERS NtHeader; - ULONG Va; - - 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)(BaseAddress + Va); -} - -PVOID STDCALL -VideoPortGetProcAddress(IN PVOID HwDeviceExtension, - IN PUCHAR FunctionName) -{ - SYSTEM_LOAD_IMAGE 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.ModuleName, L"videoprt"); - Status = ZwSetSystemInformation(SystemLoadImage, &GdiDriverInfo, - sizeof(SYSTEM_LOAD_IMAGE)); - if (!NT_SUCCESS(Status)) - { - DPRINT("Couldn't get our own module handle?\n"); - return NULL; - } - - BaseAddress = GdiDriverInfo.ModuleBase; - - /* Get the pointer to the export directory */ - ExportDir = (PIMAGE_EXPORT_DIRECTORY) - VideoPortImageDirectoryEntryToData (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(FunctionName, (char*)(BaseAddress + *NamePtr), - strlen(FunctionName))) - { - return (PVOID)((ULONG_PTR)BaseAddress + - (ULONG_PTR)AddressPtr[*OrdinalPtr]); - } - } - DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName); - return(NULL); -} +/* + * @implemented + */ LONGLONG STDCALL VideoPortQueryPerformanceCounter( @@ -1900,4 +1062,3 @@ VideoPortQueryPerformanceCounter( Result = KeQueryPerformanceCounter((PLARGE_INTEGER)PerformanceFrequency); return Result.QuadPart; } - diff --git a/reactos/drivers/video/videoprt/videoprt.h b/reactos/drivers/video/videoprt/videoprt.h index a25d544a702..54fa8c27801 100644 --- a/reactos/drivers/video/videoprt/videoprt.h +++ b/reactos/drivers/video/videoprt/videoprt.h @@ -18,7 +18,7 @@ * If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id: videoprt.h,v 1.6 2004/03/09 18:56:32 navaraf Exp $ + * $Id: videoprt.h,v 1.7 2004/03/19 20:58:32 navaraf Exp $ */ #ifndef VIDEOPRT_H @@ -27,25 +27,19 @@ #include #include #include -#include "internal/ps.h" -#define NDEBUG +#include +/* #define NDEBUG */ #include -/* - * FIXME: Definition missing from w32api! - */ -#ifndef SYNCH_LEVEL -#define SYNCH_LEVEL (IPI_LEVEL - 2) -#endif -VOID FASTCALL KfLowerIrql(IN KIRQL NewIrql); -#define KeRaiseIrql(a,b) *(b) = KfRaiseIrql(a) -KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql); -NTKERNELAPI VOID HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters); +int swprintf(wchar_t *buf, const wchar_t *fmt, ...); +int vsprintf(char *buf, const char *fmt, va_list args); +BOOLEAN STDCALL HalDisableSystemInterrupt(ULONG Vector, ULONG Unknown2); +BOOLEAN STDCALL HalEnableSystemInterrupt(ULONG Vector, ULONG Unknown2, ULONG Unknown3); +PIMAGE_NT_HEADERS STDCALL RtlImageNtHeader(IN PVOID BaseAddress); +#define NtCurrentProcess() ((HANDLE)0xFFFFFFFF) #define TAG_VIDEO_PORT TAG('V', 'I', 'D', 'P') -extern PEPROCESS Csrss; - typedef struct _VIDEO_PORT_ADDRESS_MAPPING { LIST_ENTRY List; @@ -56,46 +50,115 @@ typedef struct _VIDEO_PORT_ADDRESS_MAPPING UINT MappingCount; } VIDEO_PORT_ADDRESS_MAPPING, *PVIDEO_PORT_ADDRESS_MAPPING; +typedef struct _VIDEO_PORT_DRIVER_EXTENSION +{ + VIDEO_HW_INITIALIZATION_DATA InitializationData; + PVOID HwContext; + UNICODE_STRING RegistryPath; +} VIDEO_PORT_DRIVER_EXTENSION, *PVIDEO_PORT_DRIVER_EXTENSION; + typedef struct _VIDEO_PORT_DEVICE_EXTENSTION { - PDEVICE_OBJECT DeviceObject; + PDEVICE_OBJECT PhysicalDeviceObject; + PDEVICE_OBJECT FunctionalDeviceObject; + UNICODE_STRING RegistryPath; PKINTERRUPT InterruptObject; KSPIN_LOCK InterruptSpinLock; ULONG InterruptVector; ULONG InterruptLevel; - PVIDEO_HW_INITIALIZE HwInitialize; - PVIDEO_HW_RESET_HW HwResetHw; - PVIDEO_HW_TIMER HwTimer; - PVIDEO_HW_INTERRUPT HwInterrupt; - LIST_ENTRY AddressMappingListHead; - INTERFACE_TYPE AdapterInterfaceType; + ULONG AdapterInterfaceType; ULONG SystemIoBusNumber; - UNICODE_STRING RegistryPath; + ULONG SystemIoSlotNumber; + LIST_ENTRY AddressMappingListHead; KDPC DpcObject; - UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */ + VIDEO_PORT_DRIVER_EXTENSION *DriverExtension; + CHAR MiniPortDeviceExtension[1]; } VIDEO_PORT_DEVICE_EXTENSION, *PVIDEO_PORT_DEVICE_EXTENSION; -NTSTATUS STDCALL -VidDispatchOpen(IN PDEVICE_OBJECT pDO, IN PIRP Irp); +#define VIDEO_PORT_GET_DEVICE_EXTENSION(MiniportExtension) \ + CONTAINING_RECORD( \ + HwDeviceExtension, \ + VIDEO_PORT_DEVICE_EXTENSION, \ + MiniPortDeviceExtension) + +/* dispatch.c */ NTSTATUS STDCALL -VidDispatchClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp); +IntVideoPortAddDevice( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT PhysicalDeviceObject); NTSTATUS STDCALL -VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +IntVideoPortDispatchOpen( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); -PVOID STDCALL -InternalMapMemory( - IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, - IN PHYSICAL_ADDRESS IoAddress, - IN ULONG NumberOfUchars, - IN UCHAR InIoSpace, - OUT NTSTATUS *Status); +NTSTATUS STDCALL +IntVideoPortDispatchClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS STDCALL +IntVideoPortDispatchCleanup( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS STDCALL +IntVideoPortDispatchDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS STDCALL +IntVideoPortDispatchPnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS STDCALL +IntVideoPortDispatchPower( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); VOID STDCALL -InternalUnmapMemory( - IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, - IN PVOID MappedAddress); +IntVideoPortUnload(PDRIVER_OBJECT DriverObject); + +/* timer.c */ + +BOOLEAN STDCALL +IntVideoPortSetupTimer( + IN PDEVICE_OBJECT DeviceObject, + IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension); + +/* interrupt.c */ + +BOOLEAN STDCALL +IntVideoPortSetupInterrupt( + IN PDEVICE_OBJECT DeviceObject, + IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension, + IN PVIDEO_PORT_CONFIG_INFO ConfigInfo); + +/* videoprt.c */ + +extern ULONG CsrssInitialized; +extern PEPROCESS Csrss; + +PVOID STDCALL +VideoPortGetProcAddress( + IN PVOID HwDeviceExtension, + IN PUCHAR FunctionName); + +VOID FASTCALL +IntAttachToCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess); + +VOID FASTCALL +IntDetachFromCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess); + +NTSTATUS STDCALL +IntVideoPortFindAdapter( + IN PDRIVER_OBJECT DriverObject, + IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension, + IN PDEVICE_OBJECT PhysicalDeviceObject); + +/* int10.c */ VP_STATUS STDCALL IntInt10AllocateBuffer( @@ -131,4 +194,9 @@ IntInt10CallBios( IN PVOID Context, IN OUT PINT10_BIOS_ARGUMENTS BiosArguments); +VP_STATUS STDCALL +VideoPortInt10( + IN PVOID HwDeviceExtension, + IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments); + #endif /* VIDEOPRT_H */ diff --git a/reactos/drivers/video/videoprt/videoprt.rc b/reactos/drivers/video/videoprt/videoprt.rc index c2900509d77..21c500e06c7 100644 --- a/reactos/drivers/video/videoprt/videoprt.rc +++ b/reactos/drivers/video/videoprt/videoprt.rc @@ -24,9 +24,9 @@ BEGIN VALUE "CompanyName", RES_STR_COMPANY_NAME VALUE "FileDescription", "Videoport Driver\0" VALUE "FileVersion", "0.0.0\0" - VALUE "InternalName", "vidport\0" + VALUE "InternalName", "videoprt\0" VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT - VALUE "OriginalFilename", "vidport.sys\0" + VALUE "OriginalFilename", "videoprt.sys\0" VALUE "ProductName", RES_STR_PRODUCT_NAME VALUE "ProductVersion", RES_STR_PRODUCT_VERSION END