diff --git a/reactos/drivers/video/videoprt/Makefile b/reactos/drivers/video/videoprt/Makefile index b9d8197ed7e..68b83b0da9e 100644 --- a/reactos/drivers/video/videoprt/Makefile +++ b/reactos/drivers/video/videoprt/Makefile @@ -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 \ diff --git a/reactos/drivers/video/videoprt/agp.c b/reactos/drivers/video/videoprt/agp.c new file mode 100644 index 00000000000..a40d96bcb09 --- /dev/null +++ b/reactos/drivers/video/videoprt/agp.c @@ -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 +#include + +/* 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; +} + diff --git a/reactos/drivers/video/videoprt/ddc.c b/reactos/drivers/video/videoprt/ddc.c new file mode 100644 index 00000000000..c200c3a827f --- /dev/null +++ b/reactos/drivers/video/videoprt/ddc.c @@ -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; +} + diff --git a/reactos/drivers/video/videoprt/dispatch.c b/reactos/drivers/video/videoprt/dispatch.c index 170fbe22266..504cbbde074 100644 --- a/reactos/drivers/video/videoprt/dispatch.c +++ b/reactos/drivers/video/videoprt/dispatch.c @@ -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 diff --git a/reactos/drivers/video/videoprt/int10.c b/reactos/drivers/video/videoprt/int10.c index 2b65079d5ee..105a868f150 100644 --- a/reactos/drivers/video/videoprt/int10.c +++ b/reactos/drivers/video/videoprt/int10.c @@ -212,6 +212,11 @@ VideoPortInt10( DPRINT("VideoPortInt10\n"); + if (!CsrssInitialized) + { + return ERROR_INVALID_PARAMETER; + } + IntAttachToCSRSS(&CallingProcess, &PrevAttachedProcess); memset(&Regs, 0, sizeof(Regs)); diff --git a/reactos/drivers/video/videoprt/resource.c b/reactos/drivers/video/videoprt/resource.c index b6cd32a17a9..397a167eb0f 100644 --- a/reactos/drivers/video/videoprt/resource.c +++ b/reactos/drivers/video/videoprt/resource.c @@ -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 { diff --git a/reactos/drivers/video/videoprt/services.c b/reactos/drivers/video/videoprt/services.c index 379aacb65a9..c313649a514 100644 --- a/reactos/drivers/video/videoprt/services.c +++ b/reactos/drivers/video/videoprt/services.c @@ -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; } diff --git a/reactos/drivers/video/videoprt/videoprt.c b/reactos/drivers/video/videoprt/videoprt.c index 7384b5bf956..5a867054180 100644 --- a/reactos/drivers/video/videoprt/videoprt.c +++ b/reactos/drivers/video/videoprt/videoprt.c @@ -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); +} + diff --git a/reactos/drivers/video/videoprt/videoprt.def b/reactos/drivers/video/videoprt/videoprt.def index 832fac4d167..28f3e14619b 100644 --- a/reactos/drivers/video/videoprt/videoprt.def +++ b/reactos/drivers/video/videoprt/videoprt.def @@ -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 diff --git a/reactos/drivers/video/videoprt/videoprt.h b/reactos/drivers/video/videoprt/videoprt.h index 3412b95b2e3..2de74cab2a4 100644 --- a/reactos/drivers/video/videoprt/videoprt.h +++ b/reactos/drivers/video/videoprt/videoprt.h @@ -28,7 +28,8 @@ #include #include #include -#define NDEBUG +#include +//#define NDEBUG #include 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 */