Modified: trunk/reactos/drivers/video/videoprt/Makefile
Added: trunk/reactos/drivers/video/videoprt/agp.c
Added: trunk/reactos/drivers/video/videoprt/ddc.c
Modified: trunk/reactos/drivers/video/videoprt/dispatch.c
Modified: trunk/reactos/drivers/video/videoprt/int10.c
Modified: trunk/reactos/drivers/video/videoprt/resource.c
Modified: trunk/reactos/drivers/video/videoprt/services.c
Modified: trunk/reactos/drivers/video/videoprt/videoprt.c
Modified: trunk/reactos/drivers/video/videoprt/videoprt.def
Modified: trunk/reactos/drivers/video/videoprt/videoprt.h
--- trunk/reactos/drivers/video/videoprt/Makefile 2005-01-07 00:02:56 UTC (rev 12859)
+++ trunk/reactos/drivers/video/videoprt/Makefile 2005-01-07 01:03:34 UTC (rev 12860)
@@ -9,6 +9,8 @@
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 \
--- trunk/reactos/drivers/video/videoprt/agp.c 2005-01-07 00:02:56 UTC (rev 12859)
+++ trunk/reactos/drivers/video/videoprt/agp.c 2005-01-07 01:03:34 UTC (rev 12860)
@@ -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;
+}
+
--- trunk/reactos/drivers/video/videoprt/ddc.c 2005-01-07 00:02:56 UTC (rev 12859)
+++ trunk/reactos/drivers/video/videoprt/ddc.c 2005-01-07 01:03:34 UTC (rev 12860)
@@ -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;
+}
+
--- trunk/reactos/drivers/video/videoprt/dispatch.c 2005-01-07 00:02:56 UTC (rev 12859)
+++ trunk/reactos/drivers/video/videoprt/dispatch.c 2005-01-07 01:03:34 UTC (rev 12860)
@@ -78,13 +78,14 @@
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);
}
/*
@@ -265,34 +266,177 @@
}
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:
case IRP_MN_CANCEL_REMOVE_DEVICE:
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:
[truncated at 1000 lines; 1115 more skipped]