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:
Gregor Anich 2005-01-07 01:03:34 +00:00
parent 9e8fbcf903
commit f0c39c8ec6
10 changed files with 1381 additions and 222 deletions

View file

@ -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 \

View 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;
}

View 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;
}

View file

@ -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);
return STATUS_SUCCESS;
break;
default:
return STATUS_NOT_IMPLEMENTED;
break;
}
return STATUS_NOT_IMPLEMENTED;
return Status;
}
NTSTATUS STDCALL

View file

@ -212,6 +212,11 @@ VideoPortInt10(
DPRINT("VideoPortInt10\n");
if (!CsrssInitialized)
{
return ERROR_INVALID_PARAMETER;
}
IntAttachToCSRSS(&CallingProcess, &PrevAttachedProcess);
memset(&Regs, 0, sizeof(Regs));

View file

@ -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,
NumberOfUchars,
(PLARGE_INTEGER)(&TranslatedAddress),
&Size,
ViewUnmap,
0,
PAGE_READWRITE/* | PAGE_WRITECOMBINE*/);
NtStatus = IntVideoPortMapPhysicalMemory(NtCurrentProcess(),
TranslatedAddress,
NumberOfUchars,
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);
}
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,86 +396,93 @@ VideoPortGetAccessRanges(
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
if (NumRequestedResources == 0 &&
DeviceExtension->AdapterInterfaceType == PCIBus)
if (NumRequestedResources == 0)
{
if (DeviceExtension->PhysicalDeviceObject != NULL)
AllocatedResources = DeviceExtension->AllocatedResources;
if (AllocatedResources == NULL &&
DeviceExtension->AdapterInterfaceType == PCIBus)
{
PciSlotNumber.u.AsULONG = DeviceExtension->SystemIoSlotNumber;
ReturnedLength = HalGetBusData(
PCIConfiguration,
DeviceExtension->SystemIoBusNumber,
PciSlotNumber.u.AsULONG,
&Config,
sizeof(PCI_COMMON_CONFIG));
if (ReturnedLength != sizeof(PCI_COMMON_CONFIG))
if (DeviceExtension->PhysicalDeviceObject != NULL)
{
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;
PciSlotNumber.u.AsULONG = DeviceExtension->SystemIoSlotNumber;
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,
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))
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))
{
break;
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_DEV_NOT_EXIST;
}
}
if (FunctionNumber == 8)
Status = HalAssignSlotResources(
NULL, NULL, NULL, NULL,
DeviceExtension->AdapterInterfaceType,
DeviceExtension->SystemIoBusNumber,
PciSlotNumber.u.AsULONG,
&AllocatedResources);
if (!NT_SUCCESS(Status))
{
DPRINT("Didn't find device.\n");
return ERROR_DEV_NOT_EXIST;
return Status;
}
DeviceExtension->AllocatedResources = AllocatedResources;
}
Status = HalAssignSlotResources(
NULL, NULL, NULL, NULL,
DeviceExtension->AdapterInterfaceType,
DeviceExtension->SystemIoBusNumber,
PciSlotNumber.u.AsULONG,
&AllocatedResources);
if (!NT_SUCCESS(Status))
{
return Status;
}
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
{

View file

@ -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;
return FALSE;
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;
}

View file

@ -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))
{
@ -219,38 +216,35 @@ IntVideoPortFindAdapter(
return Status;
}
/*
/*
* Set the buffering strategy here. If you change this, remember
* 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 =
DeviceExtension->RegistryPath.MaximumLength =
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);
TAG_VIDEO_PORT);
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,11 +260,10 @@ IntVideoPortFindAdapter(
"use legacy detection method, but even that doesn't mean that\n"
"it will work.\n");
DeviceExtension->PhysicalDeviceObject = NULL;
LegacyDetection = TRUE;
}
}
DeviceExtension->AdapterInterfaceType =
DeviceExtension->AdapterInterfaceType =
DriverExtension->InitializationData.AdapterInterfaceType;
if (PhysicalDeviceObject != NULL)
@ -291,7 +284,7 @@ IntVideoPortFindAdapter(
DevicePropertyAddress,
Size,
&DeviceExtension->SystemIoSlotNumber,
&Size);
&Size);
}
InitializeListHead(&DeviceExtension->AddressMappingListHead);
@ -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,7 +366,11 @@ 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)
{
ULONG BusNumber, MaxBuses;
@ -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);
}

View file

@ -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

View file

@ -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 */