mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
added agp.c First try of implementing the AGP functions (Untested)
added ddc.c First try of implementing DDC functions (Untested) modified dispatch.c Handle IRP_MJ_PNP:IRP_MN_START_DEVICE. Let AddDevice create the device object and call HwFindAdapter from IRP_MN_START_DEVICE. modified int10.c Make VideoPortInt10 return ERROR_INVALID_PARAMETER when called while CSRSS is not initialized. modified Makefile Add agp.o and ddc.o modified resource.c Don't remember usermode mappings - they are valid only in the context of the process which they were created in. Add IntVideoPortMapPhysicalMemory() to map part of \Device\PhysicalMemory into UserMode. Make VideoPortGetAccessRanges use DeviceExtension->AllocatedResources (from the IRP_MJ_PNP:IRP_MN_START_DEVICE) if present. modified services.c Implement VideoPortGetAgpServices. VideoPortQueryServices support for VideoPortServicesAGP. modified videoprt.c Split IntVideoPortFindAdapter into IntVideoPortCreateAdapterDeviceObject and IntVideoPortFindAdapter. Basic implementation of VideoPortEnumerateChildren. Implement VideoPortAcquireDeviceLock/VideoPortReleaseDeviceLock. modified videoprt.def Export VideoPortAcquireDeviceLock/VideoPortReleaseDeviceLock. modified videoprt.h Various stuff. svn path=/trunk/; revision=12860
This commit is contained in:
parent
9e8fbcf903
commit
f0c39c8ec6
10 changed files with 1381 additions and 222 deletions
|
@ -9,6 +9,8 @@ TARGET_NAME = videoprt
|
|||
TARGET_CFLAGS += -Wall -Werror -D__USE_W32API -I$(PATH_TO_TOP)/ntoskrnl/include
|
||||
|
||||
TARGET_OBJECTS = \
|
||||
agp.o \
|
||||
ddc.o \
|
||||
dispatch.o \
|
||||
dma.o \
|
||||
event.o \
|
||||
|
|
566
reactos/drivers/video/videoprt/agp.c
Normal file
566
reactos/drivers/video/videoprt/agp.c
Normal file
|
@ -0,0 +1,566 @@
|
|||
/*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include "videoprt.h"
|
||||
#include <initguid.h>
|
||||
#include <ddk/wdmguid.h>
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
STATIC NTSTATUS
|
||||
IopInitiatePnpIrp(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
ULONG MinorFunction,
|
||||
PIO_STACK_LOCATION Stack OPTIONAL)
|
||||
{
|
||||
PDEVICE_OBJECT TopDeviceObject;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
PIRP Irp;
|
||||
|
||||
/* Always call the top of the device stack */
|
||||
TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
|
||||
|
||||
KeInitializeEvent(
|
||||
&Event,
|
||||
NotificationEvent,
|
||||
FALSE);
|
||||
|
||||
Irp = IoBuildSynchronousFsdRequest(
|
||||
IRP_MJ_PNP,
|
||||
TopDeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
&Event,
|
||||
IoStatusBlock);
|
||||
|
||||
/* PNP IRPs are always initialized with a status code of
|
||||
STATUS_NOT_IMPLEMENTED */
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IrpSp = IoGetNextIrpStackLocation(Irp);
|
||||
IrpSp->MinorFunction = MinorFunction;
|
||||
|
||||
if (Stack)
|
||||
{
|
||||
RtlMoveMemory(
|
||||
&IrpSp->Parameters,
|
||||
&Stack->Parameters,
|
||||
sizeof(Stack->Parameters));
|
||||
}
|
||||
|
||||
Status = IoCallDriver(TopDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(
|
||||
&Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
Status = IoStatusBlock->Status;
|
||||
}
|
||||
|
||||
ObDereferenceObject(TopDeviceObject);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN STDCALL
|
||||
IntAgpCommitPhysical(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PVOID PhysicalContext,
|
||||
IN ULONG Pages,
|
||||
IN ULONG Offset)
|
||||
{
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;
|
||||
PHYSICAL_ADDRESS MappingAddr = {{0}};
|
||||
PVIDEO_PORT_AGP_MAPPING AgpMapping;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("AgpCommitPhysical - PhysicalContext: 0x%x Pages: %d, Offset: 0x%x\n",
|
||||
PhysicalContext, Pages, Offset);
|
||||
|
||||
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
||||
AgpBusInterface = &DeviceExtension->AgpInterface;
|
||||
AgpMapping = (PVIDEO_PORT_AGP_MAPPING)PhysicalContext;
|
||||
|
||||
Status = AgpBusInterface->CommitMemory(AgpBusInterface->AgpContext,
|
||||
AgpMapping->MapHandle, Pages, Offset,
|
||||
NULL, &MappingAddr);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Warning: AgpBusInterface->CommitMemory failed (Status = 0x%x)\n",
|
||||
Status);
|
||||
}
|
||||
return NT_SUCCESS(Status);
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
IntAgpFreePhysical(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PVOID PhysicalContext,
|
||||
IN ULONG Pages,
|
||||
IN ULONG Offset)
|
||||
{
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;
|
||||
PVIDEO_PORT_AGP_MAPPING AgpMapping;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("AgpFreePhysical - PhysicalContext: 0x%x Pages: %d, Offset: 0x%x\n",
|
||||
PhysicalContext, Pages, Offset);
|
||||
|
||||
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
||||
AgpBusInterface = &DeviceExtension->AgpInterface;
|
||||
AgpMapping = (PVIDEO_PORT_AGP_MAPPING)PhysicalContext;
|
||||
|
||||
Status = AgpBusInterface->FreeMemory(AgpBusInterface->AgpContext,
|
||||
AgpMapping->MapHandle, Pages, Offset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Warning: AgpBusInterface->FreeMemory failed (Status = 0x%x)\n",
|
||||
Status);
|
||||
}
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
IntAgpReleasePhysical(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PVOID PhysicalContext)
|
||||
{
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;
|
||||
PVIDEO_PORT_AGP_MAPPING AgpMapping;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("AgpReleasePhysical - PhysicalContext: 0x%x\n", PhysicalContext);
|
||||
|
||||
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
||||
AgpBusInterface = &DeviceExtension->AgpInterface;
|
||||
AgpMapping = (PVIDEO_PORT_AGP_MAPPING)PhysicalContext;
|
||||
|
||||
/* Release memory */
|
||||
Status = AgpBusInterface->ReleaseMemory(AgpBusInterface->AgpContext,
|
||||
AgpMapping->MapHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Warning: AgpBusInterface->ReleaseMemory failed (Status = 0x%x)\n",
|
||||
Status);
|
||||
}
|
||||
|
||||
/* Free resources */
|
||||
ExFreePool(AgpMapping);
|
||||
}
|
||||
|
||||
PHYSICAL_ADDRESS STDCALL
|
||||
IntAgpReservePhysical(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN ULONG Pages,
|
||||
IN VIDEO_PORT_CACHE_TYPE Caching,
|
||||
OUT PVOID *PhysicalContext)
|
||||
{
|
||||
PHYSICAL_ADDRESS ZeroAddress = {{0}};
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;
|
||||
MEMORY_CACHING_TYPE MemCachingType;
|
||||
PVIDEO_PORT_AGP_MAPPING AgpMapping;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("AgpReservePhysical - Pages: %d, Caching: 0x%x\n", Pages, Caching);
|
||||
|
||||
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
||||
AgpBusInterface = &DeviceExtension->AgpInterface;
|
||||
|
||||
/* Translate memory caching type */
|
||||
if (Caching == VpNonCached)
|
||||
MemCachingType = MmNonCached;
|
||||
else if (Caching == VpCached)
|
||||
MemCachingType = MmCached;
|
||||
else if (Caching == VpWriteCombined)
|
||||
MemCachingType = MmWriteCombined;
|
||||
else
|
||||
{
|
||||
DPRINT1("Invalid caching type %d!\n", Caching);
|
||||
return ZeroAddress;
|
||||
}
|
||||
|
||||
/* Allocate an AGP mapping structure */
|
||||
AgpMapping = ExAllocatePoolWithTag(PagedPool,
|
||||
sizeof(VIDEO_PORT_AGP_MAPPING),
|
||||
TAG_VIDEO_PORT);
|
||||
if (AgpMapping == NULL)
|
||||
{
|
||||
DPRINT1("Out of memory! Couldn't allocate AGP mapping structure!\n");
|
||||
return ZeroAddress;
|
||||
}
|
||||
RtlZeroMemory(AgpMapping, sizeof(VIDEO_PORT_AGP_MAPPING));
|
||||
|
||||
/* Reserve memory for the AGP bus */
|
||||
Status = AgpBusInterface->ReserveMemory(AgpBusInterface->AgpContext,
|
||||
Pages,
|
||||
MemCachingType,
|
||||
&AgpMapping->MapHandle,
|
||||
&AgpMapping->PhysicalAddress);
|
||||
if (!NT_SUCCESS(Status) || AgpMapping->MapHandle == NULL)
|
||||
{
|
||||
ExFreePool(AgpMapping);
|
||||
DPRINT1("Warning: AgpBusInterface->ReserveMemory failed (Status = 0x%x)\n",
|
||||
Status);
|
||||
return ZeroAddress;
|
||||
}
|
||||
|
||||
/* Fill the rest of the AGP mapping */
|
||||
AgpMapping->NumberOfPages = Pages;
|
||||
|
||||
*PhysicalContext = (PVOID)AgpMapping;
|
||||
return AgpMapping->PhysicalAddress;
|
||||
}
|
||||
|
||||
|
||||
PVOID STDCALL
|
||||
IntAgpCommitVirtual(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PVOID VirtualContext,
|
||||
IN ULONG Pages,
|
||||
IN ULONG Offset)
|
||||
{
|
||||
PVIDEO_PORT_AGP_VIRTUAL_MAPPING VirtualMapping;
|
||||
PVOID BaseAddress = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("AgpCommitVirtual - VirtualContext: 0x%x Pages: %d, Offset: 0x%x\n",
|
||||
VirtualContext, Pages, Offset);
|
||||
|
||||
VirtualMapping = (PVIDEO_PORT_AGP_VIRTUAL_MAPPING)VirtualContext;
|
||||
|
||||
/* I think the NT API provides no way of reserving a part of the address space
|
||||
* and setting it up to map into a specified range of physical memory later.
|
||||
* This means that we will have to release some of the reserved virtual memory
|
||||
* and map the physical memory into it using MapViewOfSection.
|
||||
*
|
||||
* - blight (2004-12-21)
|
||||
*/
|
||||
|
||||
if (VirtualMapping->ProcessHandle == NULL)
|
||||
{
|
||||
/* FIXME: not implemented */
|
||||
}
|
||||
else /* ProcessHandle != NULL */
|
||||
{
|
||||
/* Release some virtual memory */
|
||||
ULONG Size = Pages * PAGE_SIZE;
|
||||
ULONG OffsetInBytes = Offset * PAGE_SIZE;
|
||||
BaseAddress = (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
|
||||
OffsetInBytes);
|
||||
PHYSICAL_ADDRESS PhysicalAddress = VirtualMapping->AgpMapping->PhysicalAddress;
|
||||
PhysicalAddress.QuadPart += OffsetInBytes;
|
||||
|
||||
Status = ZwFreeVirtualMemory(VirtualMapping->ProcessHandle,
|
||||
&BaseAddress,
|
||||
&Size, MEM_RELEASE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Warning: ZwFreeVirtualMemory() failed: Status = 0x%x\n", Status);
|
||||
return NULL;
|
||||
}
|
||||
ASSERT(Size == Pages * PAGE_SIZE);
|
||||
ASSERT(BaseAddress == (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
|
||||
OffsetInBytes));
|
||||
|
||||
/* Map the physical memory into the released virtual memory area */
|
||||
Status = IntVideoPortMapPhysicalMemory(VirtualMapping->ProcessHandle,
|
||||
PhysicalAddress,
|
||||
Size,
|
||||
PAGE_READWRITE,
|
||||
&BaseAddress);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Warning: IntVideoPortMapPhysicalMemory() failed: Status = 0x%x\n", Status);
|
||||
/* Reserve the released virtual memory area again */
|
||||
Status = ZwAllocateVirtualMemory(VirtualMapping->ProcessHandle,
|
||||
&BaseAddress, 0, &Size, MEM_RESERVE,
|
||||
PAGE_NOACCESS);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Warning: ZwAllocateVirtualMemory() failed: Status = 0x%x\n", Status);
|
||||
/* FIXME: What to do now?? */
|
||||
ASSERT(0);
|
||||
return NULL;
|
||||
}
|
||||
ASSERT(Size == Pages * PAGE_SIZE);
|
||||
ASSERT(BaseAddress == (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
|
||||
OffsetInBytes));
|
||||
return NULL;
|
||||
}
|
||||
ASSERT(BaseAddress == (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
|
||||
OffsetInBytes));
|
||||
}
|
||||
|
||||
return BaseAddress;
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
IntAgpFreeVirtual(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PVOID VirtualContext,
|
||||
IN ULONG Pages,
|
||||
IN ULONG Offset)
|
||||
{
|
||||
PVIDEO_PORT_AGP_VIRTUAL_MAPPING VirtualMapping;
|
||||
PVOID BaseAddress = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("AgpFreeVirtual - VirtualContext: 0x%x Pages: %d, Offset: 0x%x\n",
|
||||
VirtualContext, Pages, Offset);
|
||||
|
||||
VirtualMapping = (PVIDEO_PORT_AGP_VIRTUAL_MAPPING)VirtualContext;
|
||||
|
||||
if (VirtualMapping->ProcessHandle == NULL)
|
||||
{
|
||||
/* FIXME: not implemented */
|
||||
}
|
||||
else /* ProcessHandle != NULL */
|
||||
{
|
||||
/* Unmap the section view */
|
||||
ULONG Size = Pages * PAGE_SIZE;
|
||||
ULONG OffsetInBytes = Offset * PAGE_SIZE;
|
||||
BaseAddress = (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
|
||||
OffsetInBytes);
|
||||
|
||||
Status = ZwUnmapViewOfSection(VirtualMapping->ProcessHandle, BaseAddress);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Warning: ZwUnmapViewOfSection() failed: Status = 0x%x\n", Status);
|
||||
/* FIXME: What to do now?? */
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* And reserve the virtual memory area again */
|
||||
Status = ZwAllocateVirtualMemory(VirtualMapping->ProcessHandle,
|
||||
&BaseAddress, 0, &Size, MEM_RESERVE,
|
||||
PAGE_NOACCESS);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Warning: ZwAllocateVirtualMemory() failed: Status = 0x%x\n", Status);
|
||||
/* FIXME: What to do now?? */
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
ASSERT(Size == Pages * PAGE_SIZE);
|
||||
ASSERT(BaseAddress == (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
|
||||
OffsetInBytes));
|
||||
}
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
IntAgpReleaseVirtual(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PVOID VirtualContext)
|
||||
{
|
||||
PVIDEO_PORT_AGP_VIRTUAL_MAPPING VirtualMapping;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("AgpReleaseVirtual - VirtualContext: 0x%x\n", VirtualContext);
|
||||
|
||||
VirtualMapping = (PVIDEO_PORT_AGP_VIRTUAL_MAPPING)VirtualContext;
|
||||
|
||||
/* Release the virtual memory */
|
||||
if (VirtualMapping->ProcessHandle == NULL)
|
||||
{
|
||||
/* FIXME: not implemented */
|
||||
}
|
||||
else /* ProcessHandle != NULL */
|
||||
{
|
||||
/* Release the allocated virtual memory */
|
||||
ULONG Size = VirtualMapping->AgpMapping->NumberOfPages * PAGE_SIZE;
|
||||
Status = ZwFreeVirtualMemory(VirtualMapping->ProcessHandle,
|
||||
&VirtualMapping->MappedAddress,
|
||||
&Size, MEM_RELEASE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Warning: ZwFreeVirtualMemory() failed: Status = 0x%x\n", Status);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free resources */
|
||||
ExFreePool(VirtualMapping);
|
||||
}
|
||||
|
||||
PVOID STDCALL
|
||||
IntAgpReserveVirtual(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PVOID PhysicalContext,
|
||||
OUT PVOID *VirtualContext)
|
||||
{
|
||||
PVIDEO_PORT_AGP_MAPPING AgpMapping;
|
||||
PVIDEO_PORT_AGP_VIRTUAL_MAPPING VirtualMapping;
|
||||
PVOID MappedAddress;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("AgpReserveVirtual - ProcessHandle: 0x%x PhysicalContext: 0x%x\n",
|
||||
ProcessHandle, PhysicalContext);
|
||||
|
||||
AgpMapping = (PVIDEO_PORT_AGP_MAPPING)PhysicalContext;
|
||||
|
||||
/* Allocate an AGP virtual mapping structure */
|
||||
VirtualMapping = ExAllocatePoolWithTag(PagedPool,
|
||||
sizeof(VIDEO_PORT_AGP_VIRTUAL_MAPPING),
|
||||
TAG_VIDEO_PORT);
|
||||
if (VirtualMapping == NULL)
|
||||
{
|
||||
DPRINT1("Out of memory! Couldn't allocate AGP virtual mapping structure!\n");
|
||||
return NULL;
|
||||
}
|
||||
RtlZeroMemory(VirtualMapping, sizeof(VIDEO_PORT_AGP_VIRTUAL_MAPPING));
|
||||
|
||||
/* Reserve a virtual memory area for the physical pages. */
|
||||
if (ProcessHandle == NULL)
|
||||
{
|
||||
/* FIXME: What to do in this case? */
|
||||
ExFreePool(VirtualMapping);
|
||||
return NULL;
|
||||
}
|
||||
else /* ProcessHandle != NULL */
|
||||
{
|
||||
/* Reserve memory for usermode */
|
||||
ULONG Size = AgpMapping->NumberOfPages * PAGE_SIZE;
|
||||
MappedAddress = NULL;
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle, &MappedAddress, 0, &Size,
|
||||
MEM_RESERVE, PAGE_NOACCESS);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(VirtualMapping);
|
||||
DPRINT("ZwAllocateVirtualMemory() failed: Status = 0x%x\n", Status);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill the AGP virtual mapping */
|
||||
VirtualMapping->AgpMapping = AgpMapping;
|
||||
VirtualMapping->ProcessHandle = ProcessHandle;
|
||||
VirtualMapping->MappedAddress = MappedAddress;
|
||||
|
||||
*VirtualContext = (PVOID)VirtualMapping;
|
||||
return MappedAddress;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN STDCALL
|
||||
IntAgpSetRate(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN ULONG Rate)
|
||||
{
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;
|
||||
|
||||
DPRINT("AgpSetRate - Rate: %d\n", Rate);
|
||||
|
||||
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
||||
AgpBusInterface = &DeviceExtension->AgpInterface;
|
||||
|
||||
return NT_SUCCESS(AgpBusInterface->SetRate(AgpBusInterface->AgpContext, Rate));
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntAgpGetInterface(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN OUT PINTERFACE Interface)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
IO_STACK_LOCATION IoStack;
|
||||
NTSTATUS Status;
|
||||
PVIDEO_PORT_AGP_INTERFACE_2 AgpInterface;
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;
|
||||
|
||||
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
||||
AgpBusInterface = &DeviceExtension->AgpInterface;
|
||||
AgpInterface = (PVIDEO_PORT_AGP_INTERFACE_2)Interface;
|
||||
|
||||
ASSERT((Interface->Version == VIDEO_PORT_AGP_INTERFACE_VERSION_2 &&
|
||||
Interface->Size >= sizeof(VIDEO_PORT_AGP_INTERFACE_2)) ||
|
||||
(Interface->Version == VIDEO_PORT_AGP_INTERFACE_VERSION_1 &&
|
||||
Interface->Size >= sizeof(VIDEO_PORT_AGP_INTERFACE)));
|
||||
|
||||
if (DeviceExtension->NextDeviceObject == NULL)
|
||||
{
|
||||
DPRINT("DeviceExtension->NextDeviceObject is NULL!\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Query the interface from the AGP bus driver */
|
||||
if (DeviceExtension->AgpInterface.Size == 0)
|
||||
{
|
||||
AgpBusInterface->Size = sizeof(AGP_BUS_INTERFACE_STANDARD);
|
||||
if (Interface->Version == VIDEO_PORT_AGP_INTERFACE_VERSION_1)
|
||||
AgpBusInterface->Version = AGP_BUS_INTERFACE_V1;
|
||||
else /* if (InterfaceVersion == VIDEO_PORT_AGP_INTERFACE_VERSION_2) */
|
||||
AgpBusInterface->Version = AGP_BUS_INTERFACE_V2;
|
||||
IoStack.Parameters.QueryInterface.Size = AgpBusInterface->Size;
|
||||
IoStack.Parameters.QueryInterface.Version = AgpBusInterface->Version;
|
||||
IoStack.Parameters.QueryInterface.Interface = (PINTERFACE)AgpBusInterface;
|
||||
IoStack.Parameters.QueryInterface.InterfaceType =
|
||||
&GUID_AGP_TARGET_BUS_INTERFACE_STANDARD;
|
||||
Status = IopInitiatePnpIrp(DeviceExtension->NextDeviceObject,
|
||||
&IoStatusBlock, IRP_MN_QUERY_INTERFACE, &IoStack);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed! (Status 0x%x)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
DPRINT("Got AGP driver interface!\n");
|
||||
}
|
||||
|
||||
/* FIXME: Not sure if we should wrap the reference/dereference functions */
|
||||
AgpInterface->Context = AgpBusInterface->AgpContext;
|
||||
AgpInterface->InterfaceReference = AgpBusInterface->InterfaceReference;
|
||||
AgpInterface->InterfaceDereference = AgpBusInterface->InterfaceDereference;
|
||||
AgpInterface->AgpReservePhysical = IntAgpReservePhysical;
|
||||
AgpInterface->AgpReleasePhysical = IntAgpReleasePhysical;
|
||||
AgpInterface->AgpCommitPhysical = IntAgpCommitPhysical;
|
||||
AgpInterface->AgpFreePhysical = IntAgpFreePhysical;
|
||||
AgpInterface->AgpReserveVirtual = IntAgpReserveVirtual;
|
||||
AgpInterface->AgpReleaseVirtual = IntAgpReleaseVirtual;
|
||||
AgpInterface->AgpCommitVirtual = IntAgpCommitVirtual;
|
||||
AgpInterface->AgpFreeVirtual = IntAgpFreeVirtual;
|
||||
AgpInterface->AgpAllocationLimit = 0x1000000; /* FIXME: using 16 MB for now */
|
||||
|
||||
if (AgpInterface->Version >= VIDEO_PORT_AGP_INTERFACE_VERSION_2)
|
||||
{
|
||||
AgpInterface->AgpSetRate = IntAgpSetRate;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
227
reactos/drivers/video/videoprt/ddc.c
Normal file
227
reactos/drivers/video/videoprt/ddc.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include "videoprt.h"
|
||||
|
||||
#define DDC_EEPROM_ADDRESS 0xA0
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
#define LOW 0
|
||||
#define HIGH 1
|
||||
#define WRITE 0
|
||||
#define READ 1
|
||||
#define READ_SDA() (i2c->ReadDataLine(HwDeviceExtension))
|
||||
#define READ_SCL() (i2c->ReadClockLine(HwDeviceExtension))
|
||||
#define WRITE_SDA(state) (i2c->WriteDataLine(HwDeviceExtension, state))
|
||||
#define WRITE_SCL(state) (i2c->WriteClockLine(HwDeviceExtension, state))
|
||||
|
||||
STATIC LARGE_INTEGER HalfPeriodDelay = { { 70LL } };
|
||||
#define DELAY_HALF() KeDelayExecutionThread(KernelMode, FALSE, &HalfPeriodDelay)
|
||||
|
||||
|
||||
STATIC BOOL
|
||||
I2CWrite(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Data)
|
||||
{
|
||||
UCHAR Bit;
|
||||
BOOL Ack;
|
||||
|
||||
/* transmit data */
|
||||
for (Bit = (1 << 7); Bit != 0; Bit >>= 1)
|
||||
{
|
||||
WRITE_SCL(LOW);
|
||||
WRITE_SDA((Data & Bit) ? HIGH : LOW);
|
||||
DELAY_HALF();
|
||||
WRITE_SCL(HIGH);
|
||||
DELAY_HALF();
|
||||
}
|
||||
|
||||
/* get ack */
|
||||
WRITE_SCL(LOW);
|
||||
WRITE_SDA(HIGH);
|
||||
DELAY_HALF();
|
||||
WRITE_SCL(HIGH);
|
||||
do
|
||||
{
|
||||
DELAY_HALF();
|
||||
}
|
||||
while (READ_SCL() != HIGH);
|
||||
Ack = (READ_SDA() == LOW);
|
||||
DELAY_HALF();
|
||||
|
||||
DPRINT("I2CWrite: %s\n", Ack ? "Ack" : "Nak");
|
||||
return Ack;
|
||||
}
|
||||
|
||||
|
||||
STATIC UCHAR
|
||||
I2CRead(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, BOOL Ack)
|
||||
{
|
||||
INT Bit = 0x80;
|
||||
UCHAR Data = 0;
|
||||
|
||||
/* pull down SCL and release SDA */
|
||||
WRITE_SCL(LOW);
|
||||
WRITE_SDA(HIGH);
|
||||
|
||||
/* read byte */
|
||||
for (Bit = (1 << 7); Bit != 0; Bit >>= 1)
|
||||
{
|
||||
WRITE_SCL(LOW);
|
||||
DELAY_HALF();
|
||||
WRITE_SCL(HIGH);
|
||||
DELAY_HALF();
|
||||
if (READ_SDA() == HIGH)
|
||||
Data |= Bit;
|
||||
}
|
||||
|
||||
/* send ack/nak */
|
||||
WRITE_SCL(LOW);
|
||||
WRITE_SDA(Ack ? LOW : HIGH);
|
||||
DELAY_HALF();
|
||||
WRITE_SCL(HIGH);
|
||||
do
|
||||
{
|
||||
DELAY_HALF();
|
||||
}
|
||||
while (READ_SCL() != HIGH);
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
|
||||
STATIC VOID
|
||||
I2CStop(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c)
|
||||
{
|
||||
WRITE_SCL(LOW);
|
||||
WRITE_SDA(LOW);
|
||||
DELAY_HALF();
|
||||
WRITE_SCL(HIGH);
|
||||
DELAY_HALF();
|
||||
WRITE_SDA(HIGH);
|
||||
}
|
||||
|
||||
|
||||
STATIC BOOL
|
||||
I2CStart(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Address)
|
||||
{
|
||||
/* make sure the bus is free */
|
||||
if (READ_SDA() == LOW || READ_SCL() == LOW)
|
||||
{
|
||||
DPRINT1("I2CStart: Bus is not free!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* send address */
|
||||
WRITE_SDA(LOW);
|
||||
DELAY_HALF();
|
||||
if (!I2CWrite(HwDeviceExtension, i2c, Address))
|
||||
{
|
||||
/* ??release the bus?? */
|
||||
I2CStop(HwDeviceExtension, i2c);
|
||||
DPRINT1("I2CStart: Device not found (Address = 0x%x)\n", Address);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DPRINT("I2CStart: SUCCESS!\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
STATIC BOOL
|
||||
I2CRepStart(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Address)
|
||||
{
|
||||
/* setup lines for repeated start condition */
|
||||
WRITE_SCL(LOW);
|
||||
DELAY_HALF();
|
||||
WRITE_SDA(HIGH);
|
||||
DELAY_HALF();
|
||||
WRITE_SCL(HIGH);
|
||||
DELAY_HALF();
|
||||
|
||||
return I2CStart(HwDeviceExtension, i2c, Address);
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
BOOLEAN STDCALL
|
||||
VideoPortDDCMonitorHelper(
|
||||
PVOID HwDeviceExtension,
|
||||
PVOID I2CFunctions,
|
||||
PUCHAR pEdidBuffer,
|
||||
ULONG EdidBufferSize
|
||||
)
|
||||
{
|
||||
PDDC_CONTROL ddc = (PDDC_CONTROL)I2CFunctions;
|
||||
PI2C_CALLBACKS i2c = &ddc->I2CCallbacks;
|
||||
INT Count, i;
|
||||
PUCHAR pBuffer = (PUCHAR)pEdidBuffer;
|
||||
BOOL Ack;
|
||||
|
||||
DPRINT("VideoPortDDCMonitorHelper()\n");
|
||||
|
||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
if (ddc->Size != sizeof (ddc))
|
||||
{
|
||||
DPRINT("ddc->Size != %d (%d)\n", sizeof (ddc), ddc->Size);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* select eeprom */
|
||||
if (!I2CStart(HwDeviceExtension, i2c, DDC_EEPROM_ADDRESS | WRITE))
|
||||
return FALSE;
|
||||
/* set address */
|
||||
if (!I2CWrite(HwDeviceExtension, i2c, 0x00))
|
||||
return FALSE;
|
||||
/* change into read mode */
|
||||
if (!I2CRepStart(HwDeviceExtension, i2c, DDC_EEPROM_ADDRESS | READ))
|
||||
return FALSE;
|
||||
/* read eeprom */
|
||||
RtlZeroMemory(pEdidBuffer, EdidBufferSize);
|
||||
Count = min(128, EdidBufferSize);
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Ack = ((i + 1) < Count);
|
||||
pBuffer[i] = I2CRead(HwDeviceExtension, i2c, Ack);
|
||||
}
|
||||
I2CStop(HwDeviceExtension, i2c);
|
||||
|
||||
/* check EDID header */
|
||||
if (pBuffer[0] != 0x00 || pBuffer[1] != 0xff ||
|
||||
pBuffer[2] != 0xff || pBuffer[3] != 0xff ||
|
||||
pBuffer[4] != 0xff || pBuffer[5] != 0xff ||
|
||||
pBuffer[6] != 0xff || pBuffer[7] != 0x00)
|
||||
{
|
||||
DPRINT1("VideoPortDDCMonitorHelper(): Invalid EDID header!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DPRINT("VideoPortDDCMonitorHelper(): EDID version %d rev. %d\n", pBuffer[18], pBuffer[19]);
|
||||
DPRINT("VideoPortDDCMonitorHelper() - SUCCESS!\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -78,13 +78,14 @@ IntVideoPortAddDevice(
|
|||
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
|
||||
|
||||
/*
|
||||
* Use generic routine to find the adapter and create device object.
|
||||
* Create adapter device object.
|
||||
*/
|
||||
|
||||
return IntVideoPortFindAdapter(
|
||||
return IntVideoPortCreateAdapterDeviceObject(
|
||||
DriverObject,
|
||||
DriverExtension,
|
||||
PhysicalDeviceObject);
|
||||
PhysicalDeviceObject,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -264,18 +265,149 @@ IntVideoPortDispatchDeviceControl(
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntVideoPortPnPStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
PCM_RESOURCE_LIST AllocatedResources;
|
||||
|
||||
/*
|
||||
* Get the initialization data we saved in VideoPortInitialize.
|
||||
*/
|
||||
|
||||
DriverObject = DeviceObject->DriverObject;
|
||||
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
|
||||
DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/*
|
||||
* Store some resources in the DeviceExtension.
|
||||
*/
|
||||
|
||||
AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
|
||||
if (AllocatedResources != NULL)
|
||||
{
|
||||
CM_FULL_RESOURCE_DESCRIPTOR *FullList;
|
||||
CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
|
||||
ULONG ResourceCount;
|
||||
ULONG ResourceListSize;
|
||||
|
||||
/* Save the resource list */
|
||||
ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
|
||||
ResourceListSize =
|
||||
FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
|
||||
PartialDescriptors[ResourceCount]);
|
||||
DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
|
||||
if (DeviceExtension->AllocatedResources == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlCopyMemory(DeviceExtension->AllocatedResources,
|
||||
AllocatedResources,
|
||||
ResourceListSize);
|
||||
|
||||
/* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
|
||||
for (FullList = AllocatedResources->List;
|
||||
FullList < AllocatedResources->List + AllocatedResources->Count;
|
||||
FullList++)
|
||||
{
|
||||
/* FIXME: Is this ASSERT ok for resources from the PNP manager? */
|
||||
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 == CmResourceTypeInterrupt)
|
||||
{
|
||||
DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
|
||||
DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DPRINT("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
|
||||
DeviceExtension->InterruptLevel,
|
||||
DeviceExtension->InterruptVector);
|
||||
|
||||
/*
|
||||
* Create adapter device object.
|
||||
*/
|
||||
|
||||
return IntVideoPortFindAdapter(
|
||||
DriverObject,
|
||||
DriverExtension,
|
||||
DeviceObject);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
IntVideoPortForwardIrpAndWaitCompletionRoutine(
|
||||
PDEVICE_OBJECT Fdo,
|
||||
PIRP Irp,
|
||||
PVOID Context)
|
||||
{
|
||||
PKEVENT Event = Context;
|
||||
|
||||
if (Irp->PendingReturned)
|
||||
KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
|
||||
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
IntVideoPortForwardIrpAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension =
|
||||
(PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
IoSetCompletionRoutine(Irp, IntVideoPortForwardIrpAndWaitCompletionRoutine,
|
||||
&Event, TRUE, TRUE, TRUE);
|
||||
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntVideoPortDispatchPnp(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IrpSp->MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
|
||||
if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
|
||||
Status = IntVideoPortPnPStartDevice(DeviceObject, Irp);
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
break;
|
||||
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
|
@ -283,16 +415,28 @@ IntVideoPortDispatchPnp(
|
|||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
|
||||
if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
|
||||
Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||
Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
break;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
default:
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
|
|
|
@ -212,6 +212,11 @@ VideoPortInt10(
|
|||
|
||||
DPRINT("VideoPortInt10\n");
|
||||
|
||||
if (!CsrssInitialized)
|
||||
{
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
IntAttachToCSRSS(&CallingProcess, &PrevAttachedProcess);
|
||||
|
||||
memset(&Regs, 0, sizeof(Regs));
|
||||
|
|
|
@ -25,6 +25,57 @@
|
|||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntVideoPortMapPhysicalMemory(
|
||||
IN HANDLE Process,
|
||||
IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN ULONG SizeInBytes,
|
||||
IN ULONG Protect,
|
||||
IN OUT PVOID *VirtualAddress OPTIONAL)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjAttribs;
|
||||
UNICODE_STRING UnicodeString;
|
||||
HANDLE hMemObj;
|
||||
NTSTATUS Status;
|
||||
SIZE_T Size;
|
||||
|
||||
/* Initialize object attribs */
|
||||
RtlInitUnicodeString(&UnicodeString, L"\\Device\\PhysicalMemory");
|
||||
InitializeObjectAttributes(&ObjAttribs,
|
||||
&UnicodeString,
|
||||
OBJ_CASE_INSENSITIVE/* | OBJ_KERNEL_HANDLE*/,
|
||||
NULL, NULL);
|
||||
|
||||
/* Open physical memory section */
|
||||
Status = ZwOpenSection(&hMemObj, SECTION_ALL_ACCESS, &ObjAttribs);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwOpenSection() failed! (0x%x)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map view of section */
|
||||
Size = SizeInBytes;
|
||||
Status = ZwMapViewOfSection(hMemObj,
|
||||
Process,
|
||||
VirtualAddress,
|
||||
0,
|
||||
Size,
|
||||
(PLARGE_INTEGER)(&PhysicalAddress),
|
||||
&Size,
|
||||
ViewUnmap,
|
||||
0,
|
||||
Protect);
|
||||
ZwClose(hMemObj);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwMapViewOfSection() failed! (0x%x)\n", Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
PVOID STDCALL
|
||||
IntVideoPortMapMemory(
|
||||
IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
|
||||
|
@ -34,7 +85,7 @@ IntVideoPortMapMemory(
|
|||
OUT VP_STATUS *Status)
|
||||
{
|
||||
PHYSICAL_ADDRESS TranslatedAddress;
|
||||
PVIDEO_PORT_ADDRESS_MAPPING AddressMapping = NULL;
|
||||
PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
|
||||
ULONG AddressSpace;
|
||||
PVOID MappedAddress;
|
||||
PLIST_ENTRY Entry;
|
||||
|
@ -50,7 +101,8 @@ IntVideoPortMapMemory(
|
|||
InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE;
|
||||
}
|
||||
|
||||
if (!IsListEmpty(&DeviceExtension->AddressMappingListHead))
|
||||
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0 &&
|
||||
!IsListEmpty(&DeviceExtension->AddressMappingListHead))
|
||||
{
|
||||
Entry = DeviceExtension->AddressMappingListHead.Flink;
|
||||
while (Entry != &DeviceExtension->AddressMappingListHead)
|
||||
|
@ -62,28 +114,15 @@ IntVideoPortMapMemory(
|
|||
if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart &&
|
||||
NumberOfUchars <= AddressMapping->NumberOfUchars)
|
||||
{
|
||||
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0 &&
|
||||
AddressMapping->MappedUserAddress != NULL)
|
||||
{
|
||||
AddressMapping->UserMappingCount++;
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
return AddressMapping->MappedUserAddress;
|
||||
}
|
||||
else if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0 &&
|
||||
AddressMapping->MappedUserAddress != NULL)
|
||||
{
|
||||
AddressMapping->MappingCount++;
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
return AddressMapping->MappedAddress;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
if (Entry == &DeviceExtension->AddressMappingListHead)
|
||||
AddressMapping = NULL;
|
||||
}
|
||||
|
||||
AddressSpace = (ULONG)InIoSpace;
|
||||
|
@ -114,46 +153,20 @@ IntVideoPortMapMemory(
|
|||
/* user space */
|
||||
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjAttribs;
|
||||
UNICODE_STRING UnicodeString;
|
||||
HANDLE hMemObj;
|
||||
NTSTATUS NtStatus;
|
||||
SIZE_T Size;
|
||||
|
||||
RtlInitUnicodeString(&UnicodeString, L"\\Device\\PhysicalMemory");
|
||||
InitializeObjectAttributes(&ObjAttribs,
|
||||
&UnicodeString,
|
||||
OBJ_CASE_INSENSITIVE/* | OBJ_KERNEL_HANDLE*/,
|
||||
NULL, NULL);
|
||||
NtStatus = ZwOpenSection(&hMemObj, SECTION_ALL_ACCESS, &ObjAttribs);
|
||||
if (!NT_SUCCESS(NtStatus))
|
||||
{
|
||||
DPRINT("ZwOpenSection() failed! (0x%x)\n", NtStatus);
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
Size = NumberOfUchars;
|
||||
MappedAddress = NULL;
|
||||
NtStatus = ZwMapViewOfSection(hMemObj,
|
||||
NtCurrentProcess(),
|
||||
&MappedAddress,
|
||||
0,
|
||||
NtStatus = IntVideoPortMapPhysicalMemory(NtCurrentProcess(),
|
||||
TranslatedAddress,
|
||||
NumberOfUchars,
|
||||
(PLARGE_INTEGER)(&TranslatedAddress),
|
||||
&Size,
|
||||
ViewUnmap,
|
||||
0,
|
||||
PAGE_READWRITE/* | PAGE_WRITECOMBINE*/);
|
||||
PAGE_READWRITE/* | PAGE_WRITECOMBINE*/,
|
||||
&MappedAddress);
|
||||
if (!NT_SUCCESS(NtStatus))
|
||||
{
|
||||
DPRINT("ZwMapViewOfSection() failed! (0x%x)\n", NtStatus);
|
||||
ZwClose(hMemObj);
|
||||
DPRINT("IntVideoPortMapPhysicalMemory() failed! (0x%x)\n", NtStatus);
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
ZwClose(hMemObj);
|
||||
DPRINT("Mapped user address = 0x%08x\n", MappedAddress);
|
||||
}
|
||||
else /* kernel space */
|
||||
|
@ -166,13 +179,11 @@ IntVideoPortMapMemory(
|
|||
|
||||
if (MappedAddress != NULL)
|
||||
{
|
||||
BOOL InsertIntoList = FALSE;
|
||||
|
||||
if (Status)
|
||||
{
|
||||
*Status = NO_ERROR;
|
||||
}
|
||||
if (AddressMapping == NULL)
|
||||
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0)
|
||||
{
|
||||
AddressMapping = ExAllocatePoolWithTag(
|
||||
PagedPool,
|
||||
|
@ -182,26 +193,12 @@ IntVideoPortMapMemory(
|
|||
if (AddressMapping == NULL)
|
||||
return MappedAddress;
|
||||
|
||||
InsertIntoList = TRUE;
|
||||
RtlZeroMemory(AddressMapping, sizeof(VIDEO_PORT_ADDRESS_MAPPING));
|
||||
AddressMapping->NumberOfUchars = NumberOfUchars;
|
||||
AddressMapping->IoAddress = IoAddress;
|
||||
AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
|
||||
}
|
||||
|
||||
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
|
||||
{
|
||||
AddressMapping->MappedUserAddress = MappedAddress;
|
||||
AddressMapping->UserMappingCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
AddressMapping->MappedAddress = MappedAddress;
|
||||
AddressMapping->MappingCount = 1;
|
||||
}
|
||||
|
||||
if (InsertIntoList)
|
||||
{
|
||||
InsertHeadList(
|
||||
&DeviceExtension->AddressMappingListHead,
|
||||
&AddressMapping->List);
|
||||
|
@ -223,6 +220,7 @@ IntVideoPortUnmapMemory(
|
|||
{
|
||||
PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
|
||||
PLIST_ENTRY Entry;
|
||||
NTSTATUS Status;
|
||||
|
||||
Entry = DeviceExtension->AddressMappingListHead.Flink;
|
||||
while (Entry != &DeviceExtension->AddressMappingListHead)
|
||||
|
@ -231,24 +229,7 @@ IntVideoPortUnmapMemory(
|
|||
Entry,
|
||||
VIDEO_PORT_ADDRESS_MAPPING,
|
||||
List);
|
||||
if (AddressMapping->MappedUserAddress == MappedAddress)
|
||||
{
|
||||
ASSERT(AddressMapping->UserMappingCount > 0);
|
||||
AddressMapping->UserMappingCount--;
|
||||
if (AddressMapping->UserMappingCount == 0)
|
||||
{
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(),
|
||||
AddressMapping->MappedUserAddress);
|
||||
AddressMapping->MappedUserAddress = NULL;
|
||||
if (AddressMapping->MappingCount == 0)
|
||||
{
|
||||
RemoveEntryList(Entry);
|
||||
ExFreePool(AddressMapping);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (AddressMapping->MappedAddress == MappedAddress)
|
||||
if (AddressMapping->MappedAddress == MappedAddress)
|
||||
{
|
||||
ASSERT(AddressMapping->MappingCount > 0);
|
||||
AddressMapping->MappingCount--;
|
||||
|
@ -257,18 +238,23 @@ IntVideoPortUnmapMemory(
|
|||
MmUnmapIoSpace(
|
||||
AddressMapping->MappedAddress,
|
||||
AddressMapping->NumberOfUchars);
|
||||
AddressMapping->MappedAddress = NULL;
|
||||
if (AddressMapping->UserMappingCount == 0)
|
||||
{
|
||||
RemoveEntryList(Entry);
|
||||
ExFreePool(AddressMapping);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
/* If there was no kernelmode mapping for the given address found we assume
|
||||
* that the given address is a usermode mapping and try to unmap it.
|
||||
*/
|
||||
Status = ZwUnmapViewOfSection(NtCurrentProcess(), MappedAddress);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Warning: Mapping for address 0x%x not found!\n", (ULONG)MappedAddress);
|
||||
}
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
@ -410,7 +396,10 @@ VideoPortGetAccessRanges(
|
|||
|
||||
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
||||
|
||||
if (NumRequestedResources == 0 &&
|
||||
if (NumRequestedResources == 0)
|
||||
{
|
||||
AllocatedResources = DeviceExtension->AllocatedResources;
|
||||
if (AllocatedResources == NULL &&
|
||||
DeviceExtension->AdapterInterfaceType == PCIBus)
|
||||
{
|
||||
if (DeviceExtension->PhysicalDeviceObject != NULL)
|
||||
|
@ -490,6 +479,10 @@ VideoPortGetAccessRanges(
|
|||
{
|
||||
return Status;
|
||||
}
|
||||
DeviceExtension->AllocatedResources = AllocatedResources;
|
||||
}
|
||||
if (AllocatedResources == NULL)
|
||||
return ERROR_NO_SYSTEM_RESOURCES;
|
||||
|
||||
AssignedCount = 0;
|
||||
for (FullList = AllocatedResources->List;
|
||||
|
@ -509,7 +502,6 @@ VideoPortGetAccessRanges(
|
|||
AssignedCount >= NumAccessRanges)
|
||||
{
|
||||
DPRINT1("Too many access ranges found\n");
|
||||
ExFreePool(AllocatedResources);
|
||||
return ERROR_NO_SYSTEM_RESOURCES;
|
||||
}
|
||||
if (Descriptor->Type == CmResourceTypeMemory)
|
||||
|
@ -517,7 +509,6 @@ VideoPortGetAccessRanges(
|
|||
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",
|
||||
|
@ -548,7 +539,6 @@ VideoPortGetAccessRanges(
|
|||
}
|
||||
}
|
||||
}
|
||||
ExFreePool(AllocatedResources);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -41,6 +41,8 @@ VideoPortQueryServices(
|
|||
IN VIDEO_PORT_SERVICES ServicesType,
|
||||
IN OUT PINTERFACE Interface)
|
||||
{
|
||||
DPRINT("VideoPortQueryServices - ServicesType: 0x%x\n", ServicesType);
|
||||
|
||||
switch (ServicesType)
|
||||
{
|
||||
case VideoPortServicesInt10:
|
||||
|
@ -62,8 +64,22 @@ VideoPortQueryServices(
|
|||
break;
|
||||
|
||||
case VideoPortServicesAGP:
|
||||
if ((Interface->Version == VIDEO_PORT_AGP_INTERFACE_VERSION_2 &&
|
||||
Interface->Size >= sizeof(VIDEO_PORT_AGP_INTERFACE_2)) ||
|
||||
(Interface->Version == VIDEO_PORT_AGP_INTERFACE_VERSION_1 &&
|
||||
Interface->Size >= sizeof(VIDEO_PORT_AGP_INTERFACE)))
|
||||
{
|
||||
if (NT_SUCCESS(IntAgpGetInterface(HwDeviceExtension, Interface)))
|
||||
{
|
||||
return NO_ERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VideoPortServicesI2C:
|
||||
case VideoPortServicesHeadless:
|
||||
DPRINT1("VideoPortServices%s is UNIMPLEMENTED!\n",
|
||||
(ServicesType == VideoPortServicesI2C) ? "I2C" : "Headless");
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
|
||||
default:
|
||||
|
@ -76,9 +92,24 @@ VideoPortQueryServices(
|
|||
BOOLEAN STDCALL
|
||||
VideoPortGetAgpServices(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PVIDEO_PORT_AGP_SERVICES AgpServices)
|
||||
OUT PVIDEO_PORT_AGP_SERVICES AgpServices)
|
||||
{
|
||||
VIDEO_PORT_AGP_INTERFACE Interface;
|
||||
VP_STATUS Status;
|
||||
|
||||
DPRINT("VideoPortGetAgpServices\n");
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Interface.Size = sizeof(Interface);
|
||||
Interface.Version = VIDEO_PORT_AGP_INTERFACE_VERSION_1;
|
||||
|
||||
Status = VideoPortQueryServices(HwDeviceExtension, VideoPortServicesAGP,
|
||||
(PINTERFACE)&Interface);
|
||||
if (Status != NO_ERROR)
|
||||
{
|
||||
DPRINT("VideoPortQueryServices() failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(AgpServices, &Interface.AgpReservePhysical, sizeof(AgpServices));
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -162,25 +162,22 @@ IntVideoPortAllocateDeviceNumber(VOID)
|
|||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntVideoPortFindAdapter(
|
||||
IntVideoPortCreateAdapterDeviceObject(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject,
|
||||
OUT PDEVICE_OBJECT *DeviceObject OPTIONAL)
|
||||
{
|
||||
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 = FALSE;
|
||||
PDEVICE_OBJECT DeviceObject_;
|
||||
|
||||
if (DeviceObject == NULL)
|
||||
DeviceObject = &DeviceObject_;
|
||||
|
||||
/*
|
||||
* Find the first free device number that can be used for video device
|
||||
|
@ -195,7 +192,7 @@ IntVideoPortFindAdapter(
|
|||
}
|
||||
|
||||
/*
|
||||
* Create the device object, we need it even for calling HwFindAdapter :(
|
||||
* Create the device object.
|
||||
*/
|
||||
|
||||
/* Create a unicode device name. */
|
||||
|
@ -211,7 +208,7 @@ IntVideoPortFindAdapter(
|
|||
FILE_DEVICE_VIDEO,
|
||||
0,
|
||||
TRUE,
|
||||
&DeviceObject);
|
||||
DeviceObject);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -224,15 +221,16 @@ IntVideoPortFindAdapter(
|
|||
* to change VidDispatchDeviceControl too.
|
||||
*/
|
||||
|
||||
DeviceObject->Flags |= DO_BUFFERED_IO;
|
||||
(*DeviceObject)->Flags |= DO_BUFFERED_IO;
|
||||
|
||||
/*
|
||||
* Initialize device extension.
|
||||
*/
|
||||
|
||||
DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)((*DeviceObject)->DeviceExtension);
|
||||
DeviceExtension->DeviceNumber = DeviceNumber;
|
||||
DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
|
||||
DeviceExtension->FunctionalDeviceObject = DeviceObject;
|
||||
DeviceExtension->FunctionalDeviceObject = *DeviceObject;
|
||||
DeviceExtension->DriverExtension = DriverExtension;
|
||||
|
||||
DeviceExtension->RegistryPath.Length =
|
||||
|
@ -246,11 +244,7 @@ IntVideoPortFindAdapter(
|
|||
swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device0",
|
||||
DriverExtension->RegistryPath.Buffer);
|
||||
|
||||
if (PhysicalDeviceObject == NULL)
|
||||
{
|
||||
LegacyDetection = TRUE;
|
||||
}
|
||||
else
|
||||
if (PhysicalDeviceObject != NULL)
|
||||
{
|
||||
/* Get bus number from the upper level bus driver. */
|
||||
Size = sizeof(ULONG);
|
||||
|
@ -266,7 +260,6 @@ IntVideoPortFindAdapter(
|
|||
"use legacy detection method, but even that doesn't mean that\n"
|
||||
"it will work.\n");
|
||||
DeviceExtension->PhysicalDeviceObject = NULL;
|
||||
LegacyDetection = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,9 +293,43 @@ IntVideoPortFindAdapter(
|
|||
IntVideoPortDeferredRoutine,
|
||||
DeviceExtension);
|
||||
|
||||
KeInitializeMutex(&DeviceExtension->DeviceLock, 0);
|
||||
|
||||
/* Attach the device. */
|
||||
if (PhysicalDeviceObject != NULL)
|
||||
DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(
|
||||
*DeviceObject, PhysicalDeviceObject);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: we have to detach the device object in IntVideoPortFindAdapter if it fails */
|
||||
NTSTATUS STDCALL
|
||||
IntVideoPortFindAdapter(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
WCHAR DeviceVideoBuffer[20];
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG Size;
|
||||
NTSTATUS Status;
|
||||
VIDEO_PORT_CONFIG_INFO ConfigInfo;
|
||||
SYSTEM_BASIC_INFORMATION SystemBasicInfo;
|
||||
UCHAR Again = FALSE;
|
||||
WCHAR DeviceBuffer[20];
|
||||
UNICODE_STRING DeviceName;
|
||||
WCHAR SymlinkBuffer[20];
|
||||
UNICODE_STRING SymlinkName;
|
||||
BOOL LegacyDetection = FALSE;
|
||||
ULONG DeviceNumber;
|
||||
|
||||
DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
DeviceNumber = DeviceExtension->DeviceNumber;
|
||||
|
||||
/*
|
||||
* Uff, the DeviceExtension is setup. Now it's needed to setup
|
||||
* a ConfigInfo structure that we will pass to HwFindAdapter.
|
||||
* Setup a ConfigInfo structure that we will pass to HwFindAdapter.
|
||||
*/
|
||||
|
||||
RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
|
||||
|
@ -315,6 +342,8 @@ IntVideoPortFindAdapter(
|
|||
ConfigInfo.DriverRegistryPath = DriverExtension->RegistryPath.Buffer;
|
||||
ConfigInfo.VideoPortGetProcAddress = IntVideoPortGetProcAddress;
|
||||
ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
|
||||
ConfigInfo.BusInterruptLevel = DeviceExtension->InterruptLevel;
|
||||
ConfigInfo.BusInterruptVector = DeviceExtension->InterruptVector;
|
||||
|
||||
Size = sizeof(SystemBasicInfo);
|
||||
Status = ZwQuerySystemInformation(
|
||||
|
@ -337,6 +366,10 @@ IntVideoPortFindAdapter(
|
|||
* when we don't have information about what bus we're on. The
|
||||
* second case is the standard one for Plug & Play drivers.
|
||||
*/
|
||||
if (DeviceExtension->PhysicalDeviceObject == NULL)
|
||||
{
|
||||
LegacyDetection = TRUE;
|
||||
}
|
||||
|
||||
if (LegacyDetection)
|
||||
{
|
||||
|
@ -370,7 +403,7 @@ IntVideoPortFindAdapter(
|
|||
}
|
||||
else
|
||||
{
|
||||
DPRINT("HwFindAdapter call failed with error %X\n", Status);
|
||||
DPRINT("HwFindAdapter call failed with error 0x%X\n", Status);
|
||||
RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
|
||||
IoDeleteDevice(DeviceObject);
|
||||
|
||||
|
@ -391,7 +424,7 @@ IntVideoPortFindAdapter(
|
|||
|
||||
if (Status != NO_ERROR)
|
||||
{
|
||||
DPRINT("HwFindAdapter call failed with error %X\n", Status);
|
||||
DPRINT("HwFindAdapter call failed with error 0x%X\n", Status);
|
||||
RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
|
||||
IoDeleteDevice(DeviceObject);
|
||||
return Status;
|
||||
|
@ -402,6 +435,10 @@ IntVideoPortFindAdapter(
|
|||
* such as creating symlinks or setting up interrupts and timer.
|
||||
*/
|
||||
|
||||
/* Create a unicode device name. */
|
||||
swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber);
|
||||
RtlInitUnicodeString(&DeviceName, DeviceBuffer);
|
||||
|
||||
/* Create symbolic link "\??\DISPLAYx" */
|
||||
swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber + 1);
|
||||
RtlInitUnicodeString(&SymlinkName, SymlinkBuffer);
|
||||
|
@ -444,9 +481,10 @@ IntVideoPortFindAdapter(
|
|||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (PhysicalDeviceObject != NULL)
|
||||
DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(
|
||||
DeviceObject, PhysicalDeviceObject);
|
||||
/*
|
||||
* Query children of the device.
|
||||
*/
|
||||
VideoPortEnumerateChildren(&DeviceExtension->MiniPortDeviceExtension, NULL);
|
||||
|
||||
DPRINT("STATUS_SUCCESS\n");
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -537,6 +575,13 @@ VideoPortInitialize(
|
|||
HwInitializationData,
|
||||
min(sizeof(VIDEO_HW_INITIALIZATION_DATA),
|
||||
HwInitializationData->HwInitDataSize));
|
||||
if (sizeof(VIDEO_HW_INITIALIZATION_DATA) > HwInitializationData->HwInitDataSize)
|
||||
{
|
||||
RtlZeroMemory((PVOID)((ULONG_PTR)&DriverExtension->InitializationData +
|
||||
HwInitializationData->HwInitDataSize),
|
||||
sizeof(VIDEO_HW_INITIALIZATION_DATA) -
|
||||
HwInitializationData->HwInitDataSize);
|
||||
}
|
||||
DriverExtension->HwContext = HwContext;
|
||||
|
||||
RtlCopyMemory(&DriverExtension->RegistryPath, RegistryPath, sizeof(UNICODE_STRING));
|
||||
|
@ -578,7 +623,13 @@ VideoPortInitialize(
|
|||
|
||||
if (LegacyDetection)
|
||||
{
|
||||
Status = IntVideoPortFindAdapter(DriverObject, DriverExtension, NULL);
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
Status = IntVideoPortCreateAdapterDeviceObject(DriverObject, DriverExtension,
|
||||
NULL, &DeviceObject);
|
||||
DPRINT("IntVideoPortCreateAdapterDeviceObject returned 0x%x\n", Status);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
Status = IntVideoPortFindAdapter(DriverObject, DriverExtension, DeviceObject);
|
||||
DPRINT("IntVideoPortFindAdapter returned 0x%x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
@ -909,23 +960,7 @@ VideoPortSynchronizeExecution(
|
|||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
||||
BOOLEAN STDCALL
|
||||
VideoPortDDCMonitorHelper(
|
||||
PVOID HwDeviceExtension,
|
||||
/*PI2C_FNC_TABLE*/PVOID I2CFunctions,
|
||||
PUCHAR pEdidBuffer,
|
||||
ULONG EdidBufferSize
|
||||
)
|
||||
{
|
||||
DPRINT1("VideoPortDDCMonitorHelper() - Unimplemented.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
VP_STATUS STDCALL
|
||||
|
@ -933,7 +968,80 @@ VideoPortEnumerateChildren(
|
|||
IN PVOID HwDeviceExtension,
|
||||
IN PVOID Reserved)
|
||||
{
|
||||
DPRINT1("VideoPortEnumerateChildren(): Unimplemented.\n");
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG Status;
|
||||
VIDEO_CHILD_ENUM_INFO ChildEnumInfo;
|
||||
VIDEO_CHILD_TYPE ChildType;
|
||||
UCHAR ChildDescriptor[256];
|
||||
ULONG ChildId;
|
||||
ULONG Unused;
|
||||
INT i;
|
||||
|
||||
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
||||
if (DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor == NULL)
|
||||
{
|
||||
DPRINT("Miniport's HwGetVideoChildDescriptor is NULL!\n");
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
/* Setup the ChildEnumInfo */
|
||||
ChildEnumInfo.Size = sizeof (ChildEnumInfo);
|
||||
ChildEnumInfo.ChildDescriptorSize = sizeof (ChildDescriptor);
|
||||
ChildEnumInfo.ACPIHwId = 0;
|
||||
ChildEnumInfo.ChildHwDeviceExtension = NULL; /* FIXME: must be set to
|
||||
ChildHwDeviceExtension... */
|
||||
|
||||
/* Enumerate the children */
|
||||
for (i = 1; ; i++)
|
||||
{
|
||||
ChildEnumInfo.ChildIndex = i;
|
||||
RtlZeroMemory(ChildDescriptor, sizeof(ChildDescriptor));
|
||||
Status = DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor(
|
||||
HwDeviceExtension,
|
||||
&ChildEnumInfo,
|
||||
&ChildType,
|
||||
ChildDescriptor,
|
||||
&ChildId,
|
||||
&Unused);
|
||||
if (Status == VIDEO_ENUM_INVALID_DEVICE)
|
||||
{
|
||||
DPRINT("Child device %d is invalid!\n", ChildEnumInfo.ChildIndex);
|
||||
continue;
|
||||
}
|
||||
else if (Status == VIDEO_ENUM_NO_MORE_DEVICES)
|
||||
{
|
||||
DPRINT("End of child enumeration! (%d children enumerated)\n", i - 1);
|
||||
break;
|
||||
}
|
||||
else if (Status != VIDEO_ENUM_MORE_DEVICES)
|
||||
{
|
||||
DPRINT("HwGetVideoChildDescriptor returned unknown status code 0x%x!\n", Status);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ChildType == Monitor)
|
||||
{
|
||||
INT j;
|
||||
PUCHAR p = ChildDescriptor;
|
||||
DPRINT("Monitor device enumerated! (ChildId = 0x%x)\n", ChildId);
|
||||
for (j = 0; j < sizeof (ChildDescriptor); j += 8)
|
||||
{
|
||||
DPRINT("%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
p[j+0], p[j+1], p[j+2], p[j+3],
|
||||
p[j+4], p[j+5], p[j+6], p[j+7]);
|
||||
}
|
||||
}
|
||||
else if (ChildType == Other)
|
||||
{
|
||||
DPRINT("\"Other\" device enumerated: DeviceId = %S\n", (PWSTR)ChildDescriptor);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1064,3 +1172,41 @@ VideoPortQueryPerformanceCounter(
|
|||
Result = KeQueryPerformanceCounter((PLARGE_INTEGER)PerformanceFrequency);
|
||||
return Result.QuadPart;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
VOID STDCALL
|
||||
VideoPortAcquireDeviceLock(
|
||||
IN PVOID HwDeviceExtension)
|
||||
{
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
(void)Status;
|
||||
|
||||
DPRINT("VideoPortAcquireDeviceLock\n");
|
||||
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
||||
Status = KeWaitForMutexObject(&DeviceExtension->DeviceLock, Executive,
|
||||
KernelMode, FALSE, NULL);
|
||||
ASSERT(Status == STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
VOID STDCALL
|
||||
VideoPortReleaseDeviceLock(
|
||||
IN PVOID HwDeviceExtension)
|
||||
{
|
||||
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
LONG Status;
|
||||
(void)Status;
|
||||
|
||||
DPRINT("VideoPortReleaseDeviceLock\n");
|
||||
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
||||
Status = KeReleaseMutex(&DeviceExtension->DeviceLock, FALSE);
|
||||
ASSERT(Status == 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
; videoprt.def - export definition file for ReactOS
|
||||
;
|
||||
EXPORTS
|
||||
;VideoPortAcquireDeviceLock
|
||||
VideoPortAcquireDeviceLock@4
|
||||
VideoPortAcquireSpinLock@12
|
||||
VideoPortAcquireSpinLockAtDpcLevel@8
|
||||
VideoPortAllocateBuffer@12
|
||||
|
@ -80,7 +80,7 @@ VideoPortReadRegisterBufferUlong@12=NTOSKRNL.READ_REGISTER_BUFFER_ULONG
|
|||
VideoPortRegisterBugcheckCallback@16
|
||||
VideoPortReleaseBuffer@8
|
||||
VideoPortReleaseCommonBuffer@28
|
||||
;VideoPortReleaseDeviceLock
|
||||
VideoPortReleaseDeviceLock@4
|
||||
VideoPortReleaseSpinLock@12
|
||||
VideoPortReleaseSpinLockFromDpcLevel@8
|
||||
VideoPortScanRom@16
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
#include <ddk/video.h>
|
||||
#include <ddk/ntddvdeo.h>
|
||||
#include <ddk/ntapi.h>
|
||||
#define NDEBUG
|
||||
#include <ddk/ntagp.h>
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
int swprintf(wchar_t *buf, const wchar_t *fmt, ...);
|
||||
|
@ -51,14 +52,28 @@ typedef struct _VIDEO_PORT_ADDRESS_MAPPING
|
|||
{
|
||||
LIST_ENTRY List;
|
||||
PVOID MappedAddress;
|
||||
PVOID MappedUserAddress;
|
||||
ULONG NumberOfUchars;
|
||||
PHYSICAL_ADDRESS IoAddress;
|
||||
ULONG SystemIoBusNumber;
|
||||
UINT MappingCount;
|
||||
UINT UserMappingCount;
|
||||
} VIDEO_PORT_ADDRESS_MAPPING, *PVIDEO_PORT_ADDRESS_MAPPING;
|
||||
|
||||
struct _VIDEO_PORT_AGP_VIRTUAL_MAPPING;
|
||||
|
||||
typedef struct _VIDEO_PORT_AGP_MAPPING
|
||||
{
|
||||
ULONG NumberOfPages;
|
||||
PVOID MapHandle;
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
} VIDEO_PORT_AGP_MAPPING, *PVIDEO_PORT_AGP_MAPPING;
|
||||
|
||||
typedef struct _VIDEO_PORT_AGP_VIRTUAL_MAPPING
|
||||
{
|
||||
PVIDEO_PORT_AGP_MAPPING AgpMapping;
|
||||
HANDLE ProcessHandle;
|
||||
PVOID MappedAddress;
|
||||
} VIDEO_PORT_AGP_VIRTUAL_MAPPING, *PVIDEO_PORT_AGP_VIRTUAL_MAPPING;
|
||||
|
||||
typedef struct _VIDEO_PORT_DRIVER_EXTENSION
|
||||
{
|
||||
VIDEO_HW_INITIALIZATION_DATA InitializationData;
|
||||
|
@ -68,12 +83,14 @@ typedef struct _VIDEO_PORT_DRIVER_EXTENSION
|
|||
|
||||
typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
|
||||
{
|
||||
ULONG DeviceNumber;
|
||||
PDEVICE_OBJECT PhysicalDeviceObject;
|
||||
PDEVICE_OBJECT FunctionalDeviceObject;
|
||||
PDEVICE_OBJECT NextDeviceObject;
|
||||
UNICODE_STRING RegistryPath;
|
||||
PKINTERRUPT InterruptObject;
|
||||
KSPIN_LOCK InterruptSpinLock;
|
||||
PCM_RESOURCE_LIST AllocatedResources;
|
||||
ULONG InterruptVector;
|
||||
ULONG InterruptLevel;
|
||||
ULONG AdapterInterfaceType;
|
||||
|
@ -83,6 +100,8 @@ typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
|
|||
KDPC DpcObject;
|
||||
VIDEO_PORT_DRIVER_EXTENSION *DriverExtension;
|
||||
ULONG DeviceOpened;
|
||||
AGP_BUS_INTERFACE_STANDARD AgpInterface;
|
||||
KMUTEX DeviceLock;
|
||||
CHAR MiniPortDeviceExtension[1];
|
||||
} VIDEO_PORT_DEVICE_EXTENSION, *PVIDEO_PORT_DEVICE_EXTENSION;
|
||||
|
||||
|
@ -92,6 +111,13 @@ typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
|
|||
VIDEO_PORT_DEVICE_EXTENSION, \
|
||||
MiniPortDeviceExtension)
|
||||
|
||||
/* agp.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntAgpGetInterface(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN OUT PINTERFACE Interface);
|
||||
|
||||
/* dispatch.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
|
@ -147,11 +173,26 @@ IntVideoPortSetupInterrupt(
|
|||
IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
|
||||
IN PVIDEO_PORT_CONFIG_INFO ConfigInfo);
|
||||
|
||||
/* resource.c */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntVideoPortMapPhysicalMemory(
|
||||
IN HANDLE Process,
|
||||
IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN ULONG SizeInBytes,
|
||||
IN ULONG Protect,
|
||||
IN OUT PVOID *VirtualAddress OPTIONAL);
|
||||
|
||||
/* videoprt.c */
|
||||
|
||||
extern ULONG CsrssInitialized;
|
||||
extern PEPROCESS Csrss;
|
||||
|
||||
VP_STATUS STDCALL
|
||||
VideoPortEnumerateChildren(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PVOID Reserved);
|
||||
|
||||
PVOID STDCALL
|
||||
VideoPortGetProcAddress(
|
||||
IN PVOID HwDeviceExtension,
|
||||
|
@ -163,11 +204,18 @@ IntAttachToCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess);
|
|||
VOID FASTCALL
|
||||
IntDetachFromCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntVideoPortCreateAdapterDeviceObject(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL,
|
||||
OUT PDEVICE_OBJECT *DeviceObject OPTIONAL);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntVideoPortFindAdapter(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject);
|
||||
IN PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
/* int10.c */
|
||||
|
||||
|
|
Loading…
Reference in a new issue