2004-01-19 15:56:53 +00:00
|
|
|
/*
|
2003-02-15 19:16:34 +00:00
|
|
|
* VideoPort driver
|
|
|
|
*
|
2004-01-19 15:56:53 +00:00
|
|
|
* 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.
|
|
|
|
*
|
2004-03-04 18:51:58 +00:00
|
|
|
* $Id: videoprt.c,v 1.5 2004/03/04 18:51:58 navaraf Exp $
|
2003-02-15 19:16:34 +00:00
|
|
|
*/
|
|
|
|
|
2004-01-19 15:56:53 +00:00
|
|
|
#include "videoprt.h"
|
2003-02-15 19:16:34 +00:00
|
|
|
|
2004-01-19 15:56:53 +00:00
|
|
|
BOOLEAN CsrssInitialized = FALSE;
|
|
|
|
PEPROCESS Csrss = NULL;
|
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
|
2003-02-15 19:16:34 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------- Public Interface
|
|
|
|
|
|
|
|
// DriverEntry
|
|
|
|
//
|
|
|
|
// DESCRIPTION:
|
|
|
|
// This function initializes the driver.
|
|
|
|
//
|
|
|
|
// RUN LEVEL:
|
|
|
|
// PASSIVE_LEVEL
|
|
|
|
//
|
|
|
|
// ARGUMENTS:
|
|
|
|
// IN PDRIVER_OBJECT DriverObject System allocated Driver Object
|
|
|
|
// for this driver
|
|
|
|
// IN PUNICODE_STRING RegistryPath Name of registry driver service
|
|
|
|
// key
|
|
|
|
//
|
|
|
|
// RETURNS:
|
|
|
|
// NTSTATUS
|
|
|
|
|
2004-01-19 15:56:53 +00:00
|
|
|
NTSTATUS STDCALL
|
2003-02-15 19:16:34 +00:00
|
|
|
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
|
|
|
IN PUNICODE_STRING RegistryPath)
|
|
|
|
{
|
|
|
|
DPRINT("DriverEntry()\n");
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VOID
|
2004-01-19 15:56:53 +00:00
|
|
|
VideoPortDebugPrint(IN VIDEO_DEBUG_LEVEL DebugPrintLevel,
|
2003-02-15 19:16:34 +00:00
|
|
|
IN PCHAR DebugMessage, ...)
|
|
|
|
{
|
|
|
|
char Buffer[256];
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
/*
|
|
|
|
if (DebugPrintLevel > InternalDebugLevel)
|
|
|
|
return;
|
|
|
|
*/
|
|
|
|
va_start (ap, DebugMessage);
|
|
|
|
vsprintf (Buffer, DebugMessage, ap);
|
|
|
|
va_end (ap);
|
|
|
|
|
|
|
|
DbgPrint (Buffer);
|
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VOID
|
|
|
|
STDCALL
|
|
|
|
VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension,
|
|
|
|
IN PVOID MappedAddress)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT("VideoPortFreeDeviceBase\n");
|
|
|
|
|
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
|
|
|
|
InternalUnmapMemory(DeviceExtension, MappedAddress);
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
ULONG
|
|
|
|
STDCALL
|
|
|
|
VideoPortGetBusData(IN PVOID HwDeviceExtension,
|
|
|
|
IN BUS_DATA_TYPE BusDataType,
|
|
|
|
IN ULONG SlotNumber,
|
|
|
|
OUT PVOID Buffer,
|
|
|
|
IN ULONG Offset,
|
|
|
|
IN ULONG Length)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
2003-02-17 21:24:42 +00:00
|
|
|
|
2003-02-15 19:16:34 +00:00
|
|
|
DPRINT("VideoPortGetBusData\n");
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
|
2003-02-15 19:16:34 +00:00
|
|
|
return HalGetBusDataByOffset(BusDataType,
|
2003-02-25 23:08:54 +00:00
|
|
|
DeviceExtension->SystemIoBusNumber,
|
2003-02-15 19:16:34 +00:00
|
|
|
SlotNumber,
|
|
|
|
Buffer,
|
|
|
|
Offset,
|
|
|
|
Length);
|
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
UCHAR
|
|
|
|
STDCALL
|
|
|
|
VideoPortGetCurrentIrql(VOID)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortGetCurrentIrql\n");
|
|
|
|
return KeGetCurrentIrql();
|
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
PVOID
|
|
|
|
STDCALL
|
|
|
|
VideoPortGetDeviceBase(IN PVOID HwDeviceExtension,
|
|
|
|
IN PHYSICAL_ADDRESS IoAddress,
|
|
|
|
IN ULONG NumberOfUchars,
|
|
|
|
IN UCHAR InIoSpace)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
2003-02-15 19:16:34 +00:00
|
|
|
|
|
|
|
DPRINT("VideoPortGetDeviceBase\n");
|
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
|
|
|
|
return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace);
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VP_STATUS
|
|
|
|
STDCALL
|
|
|
|
VideoPortGetDeviceData(IN PVOID HwDeviceExtension,
|
|
|
|
IN VIDEO_DEVICE_DATA_TYPE DeviceDataType,
|
|
|
|
IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine,
|
|
|
|
IN PVOID Context)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortGetDeviceData\n");
|
|
|
|
UNIMPLEMENTED;
|
2003-11-05 22:31:50 +00:00
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VP_STATUS
|
|
|
|
STDCALL
|
|
|
|
VideoPortGetAccessRanges(IN PVOID HwDeviceExtension,
|
|
|
|
IN ULONG NumRequestedResources,
|
|
|
|
IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL,
|
|
|
|
IN ULONG NumAccessRanges,
|
|
|
|
IN PVIDEO_ACCESS_RANGE AccessRanges,
|
|
|
|
IN PVOID VendorId,
|
|
|
|
IN PVOID DeviceId,
|
|
|
|
IN PULONG Slot)
|
|
|
|
{
|
2003-02-17 21:24:42 +00:00
|
|
|
PCI_SLOT_NUMBER PciSlotNumber;
|
|
|
|
BOOLEAN FoundDevice;
|
|
|
|
ULONG FunctionNumber;
|
|
|
|
PCI_COMMON_CONFIG Config;
|
|
|
|
PCM_RESOURCE_LIST AllocatedResources;
|
|
|
|
NTSTATUS Status;
|
|
|
|
UINT AssignedCount;
|
|
|
|
CM_FULL_RESOURCE_DESCRIPTOR *FullList;
|
|
|
|
CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
2003-02-17 21:24:42 +00:00
|
|
|
|
2003-02-15 19:16:34 +00:00
|
|
|
DPRINT("VideoPortGetAccessRanges\n");
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
|
|
|
|
if (0 == NumRequestedResources && PCIBus == DeviceExtension->AdapterInterfaceType)
|
2003-02-17 21:24:42 +00:00
|
|
|
{
|
|
|
|
DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n", (int)*((USHORT *) VendorId),
|
|
|
|
(int)*((USHORT *) DeviceId));
|
|
|
|
FoundDevice = FALSE;
|
|
|
|
PciSlotNumber.u.AsULONG = *Slot;
|
|
|
|
for (FunctionNumber = 0; ! FoundDevice && FunctionNumber < 8; FunctionNumber++)
|
|
|
|
{
|
|
|
|
PciSlotNumber.u.bits.FunctionNumber = FunctionNumber;
|
|
|
|
if (sizeof(PCI_COMMON_CONFIG) ==
|
2003-02-25 23:08:54 +00:00
|
|
|
HalGetBusDataByOffset(PCIConfiguration, DeviceExtension->SystemIoBusNumber,
|
|
|
|
PciSlotNumber.u.AsULONG,&Config, 0,
|
|
|
|
sizeof(PCI_COMMON_CONFIG)))
|
2003-02-17 21:24:42 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
FoundDevice = (Config.VendorID == *((USHORT *) VendorId) &&
|
|
|
|
Config.DeviceID == *((USHORT *) DeviceId));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (! FoundDevice)
|
|
|
|
{
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
Status = HalAssignSlotResources(NULL, NULL, NULL, NULL,
|
|
|
|
DeviceExtension->AdapterInterfaceType,
|
|
|
|
DeviceExtension->SystemIoBusNumber,
|
2003-02-17 21:24:42 +00:00
|
|
|
PciSlotNumber.u.AsULONG, &AllocatedResources);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
AssignedCount = 0;
|
|
|
|
for (FullList = AllocatedResources->List;
|
2003-11-05 22:31:50 +00:00
|
|
|
FullList < AllocatedResources->List + AllocatedResources->Count;
|
2003-02-17 21:24:42 +00:00
|
|
|
FullList++)
|
|
|
|
{
|
|
|
|
assert(FullList->InterfaceType == PCIBus &&
|
2003-02-25 23:08:54 +00:00
|
|
|
FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
|
2003-02-17 21:24:42 +00:00
|
|
|
1 == FullList->PartialResourceList.Version &&
|
|
|
|
1 == FullList->PartialResourceList.Revision);
|
|
|
|
for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
|
2003-11-05 22:31:50 +00:00
|
|
|
Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
|
2003-02-17 21:24:42 +00:00
|
|
|
Descriptor++)
|
|
|
|
{
|
2003-11-05 22:31:50 +00:00
|
|
|
if ((CmResourceTypeMemory == Descriptor->Type
|
|
|
|
|| CmResourceTypePort == Descriptor->Type)
|
|
|
|
&& NumAccessRanges <= AssignedCount)
|
|
|
|
{
|
|
|
|
DPRINT1("Too many access ranges found\n");
|
|
|
|
ExFreePool(AllocatedResources);
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
2003-02-17 21:24:42 +00:00
|
|
|
if (CmResourceTypeMemory == Descriptor->Type)
|
|
|
|
{
|
2003-11-05 22:31:50 +00:00
|
|
|
if (NumAccessRanges <= AssignedCount)
|
|
|
|
{
|
|
|
|
DPRINT1("Too many access ranges found\n");
|
|
|
|
ExFreePool(AllocatedResources);
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
2003-02-17 21:24:42 +00:00
|
|
|
DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
|
|
|
|
Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
|
|
|
|
AccessRanges[AssignedCount].RangeStart = Descriptor->u.Memory.Start;
|
|
|
|
AccessRanges[AssignedCount].RangeLength = Descriptor->u.Memory.Length;
|
|
|
|
AccessRanges[AssignedCount].RangeInIoSpace = 0;
|
|
|
|
AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
|
|
|
|
AccessRanges[AssignedCount].RangeShareable =
|
|
|
|
(CmResourceShareShared == Descriptor->ShareDisposition);
|
2003-11-05 22:31:50 +00:00
|
|
|
AssignedCount++;
|
2003-02-17 21:24:42 +00:00
|
|
|
}
|
|
|
|
else if (CmResourceTypePort == Descriptor->Type)
|
|
|
|
{
|
|
|
|
DPRINT("Port range starting at 0x%04x length %d\n",
|
|
|
|
Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
|
|
|
|
AccessRanges[AssignedCount].RangeStart = Descriptor->u.Port.Start;
|
|
|
|
AccessRanges[AssignedCount].RangeLength = Descriptor->u.Port.Length;
|
|
|
|
AccessRanges[AssignedCount].RangeInIoSpace = 1;
|
|
|
|
AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
|
|
|
|
AccessRanges[AssignedCount].RangeShareable = 0;
|
2003-11-05 22:31:50 +00:00
|
|
|
AssignedCount++;
|
2003-02-17 21:24:42 +00:00
|
|
|
}
|
2003-11-05 22:31:50 +00:00
|
|
|
else if (CmResourceTypeInterrupt == Descriptor->Type)
|
|
|
|
{
|
|
|
|
DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
|
|
|
|
DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
|
|
|
|
}
|
2003-02-17 21:24:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ExFreePool(AllocatedResources);
|
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
}
|
2003-02-17 21:24:42 +00:00
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-10-24 21:39:59 +00:00
|
|
|
typedef struct QueryRegistryCallbackContext
|
|
|
|
{
|
|
|
|
PVOID HwDeviceExtension;
|
|
|
|
PVOID HwContext;
|
|
|
|
PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine;
|
|
|
|
} QUERY_REGISTRY_CALLBACK_CONTEXT, *PQUERY_REGISTRY_CALLBACK_CONTEXT;
|
|
|
|
|
|
|
|
static NTSTATUS STDCALL
|
|
|
|
QueryRegistryCallback(IN PWSTR ValueName,
|
|
|
|
IN ULONG ValueType,
|
|
|
|
IN PVOID ValueData,
|
|
|
|
IN ULONG ValueLength,
|
|
|
|
IN PVOID Context,
|
|
|
|
IN PVOID EntryContext)
|
|
|
|
{
|
|
|
|
PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext = (PQUERY_REGISTRY_CALLBACK_CONTEXT) Context;
|
|
|
|
|
|
|
|
DPRINT("Found registry value for name %S: type %d, length %d\n",
|
|
|
|
ValueName, ValueType, ValueLength);
|
|
|
|
return (*(CallbackContext->HwGetRegistryRoutine))(CallbackContext->HwDeviceExtension,
|
|
|
|
CallbackContext->HwContext,
|
|
|
|
ValueName,
|
|
|
|
ValueData,
|
|
|
|
ValueLength);
|
|
|
|
}
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VP_STATUS
|
|
|
|
STDCALL
|
|
|
|
VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension,
|
|
|
|
IN PWSTR ParameterName,
|
|
|
|
IN UCHAR IsParameterFileName,
|
|
|
|
IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine,
|
2003-10-24 21:39:59 +00:00
|
|
|
IN PVOID HwContext)
|
2003-02-15 19:16:34 +00:00
|
|
|
{
|
2003-10-24 21:39:59 +00:00
|
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
|
|
|
QUERY_REGISTRY_CALLBACK_CONTEXT Context;
|
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName);
|
|
|
|
|
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
|
|
|
|
if (IsParameterFileName)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2003-02-17 21:24:42 +00:00
|
|
|
DPRINT("ParameterName %S\n", ParameterName);
|
2003-10-24 21:39:59 +00:00
|
|
|
|
|
|
|
Context.HwDeviceExtension = HwDeviceExtension;
|
|
|
|
Context.HwContext = HwContext;
|
|
|
|
Context.HwGetRegistryRoutine = GetRegistryRoutine;
|
|
|
|
|
|
|
|
QueryTable[0].QueryRoutine = QueryRegistryCallback;
|
|
|
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
|
|
|
|
QueryTable[0].Name = ParameterName;
|
|
|
|
QueryTable[0].EntryContext = NULL;
|
|
|
|
QueryTable[0].DefaultType = REG_NONE;
|
|
|
|
QueryTable[0].DefaultData = NULL;
|
|
|
|
QueryTable[0].DefaultLength = 0;
|
|
|
|
|
|
|
|
QueryTable[1].QueryRoutine = NULL;
|
|
|
|
QueryTable[1].Name = NULL;
|
|
|
|
|
|
|
|
return NT_SUCCESS(RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
|
|
|
DeviceExtension->RegistryPath.Buffer,
|
|
|
|
QueryTable, &Context, NULL))
|
|
|
|
? ERROR_SUCCESS : ERROR_INVALID_PARAMETER;
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2004-02-25 02:59:55 +00:00
|
|
|
|
|
|
|
/*
|
2004-02-25 05:38:33 +00:00
|
|
|
* @implemented
|
|
|
|
*/
|
2004-02-25 02:59:55 +00:00
|
|
|
VP_STATUS
|
|
|
|
STDCALL
|
|
|
|
VideoPortGetVgaStatus(IN PVOID HwDeviceExtension,
|
|
|
|
OUT PULONG VgaStatus)
|
|
|
|
{
|
2004-02-25 05:38:33 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT("VideoPortGetVgaStatus = %S \n", VgaStatus);
|
|
|
|
|
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
|
|
|
|
if(KeGetCurrentIrql() == PASSIVE_LEVEL)
|
|
|
|
{
|
|
|
|
if ( PCIBus == DeviceExtension->AdapterInterfaceType)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
VgaStatus 0 == VGA not enabled, 1 == VGA enabled.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Assumed for now */
|
|
|
|
|
|
|
|
VgaStatus = (PULONG) 1;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ERROR_INVALID_FUNCTION;
|
2004-02-25 02:59:55 +00:00
|
|
|
}
|
|
|
|
|
2003-11-05 22:31:50 +00:00
|
|
|
static BOOLEAN
|
|
|
|
VPInterruptRoutine(IN struct _KINTERRUPT *Interrupt,
|
|
|
|
IN PVOID ServiceContext)
|
|
|
|
{
|
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DeviceExtension = ServiceContext;
|
|
|
|
assert(NULL != DeviceExtension->HwInterrupt);
|
|
|
|
|
|
|
|
return DeviceExtension->HwInterrupt(&DeviceExtension->MiniPortDeviceExtension);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VOID STDCALL
|
|
|
|
VPTimerRoutine(IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PVOID Context)
|
|
|
|
{
|
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DeviceExtension = Context;
|
|
|
|
assert(DeviceExtension == DeviceObject->DeviceExtension
|
|
|
|
&& NULL != DeviceExtension->HwTimer);
|
|
|
|
|
|
|
|
DeviceExtension->HwTimer(&DeviceExtension->MiniPortDeviceExtension);
|
|
|
|
}
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
ULONG STDCALL
|
|
|
|
VideoPortInitialize(IN PVOID Context1,
|
|
|
|
IN PVOID Context2,
|
|
|
|
IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData,
|
|
|
|
IN PVOID HwContext)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
PUNICODE_STRING RegistryPath;
|
2003-11-05 22:31:50 +00:00
|
|
|
UCHAR Again;
|
|
|
|
WCHAR DeviceBuffer[20];
|
|
|
|
WCHAR SymlinkBuffer[20];
|
|
|
|
WCHAR DeviceVideoBuffer[20];
|
|
|
|
NTSTATUS Status;
|
|
|
|
PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1;
|
|
|
|
PDEVICE_OBJECT MPDeviceObject;
|
|
|
|
VIDEO_PORT_CONFIG_INFO ConfigInfo;
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
2003-02-15 19:16:34 +00:00
|
|
|
ULONG DeviceNumber = 0;
|
|
|
|
UNICODE_STRING DeviceName;
|
|
|
|
UNICODE_STRING SymlinkName;
|
2003-02-25 23:08:54 +00:00
|
|
|
ULONG MaxBus;
|
|
|
|
ULONG MaxLen;
|
2003-11-05 22:31:50 +00:00
|
|
|
KIRQL IRQL;
|
|
|
|
KAFFINITY Affinity;
|
|
|
|
ULONG InterruptVector;
|
2003-02-15 19:16:34 +00:00
|
|
|
|
|
|
|
DPRINT("VideoPortInitialize\n");
|
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
RegistryPath = (PUNICODE_STRING) Context2;
|
|
|
|
|
2003-02-15 19:16:34 +00:00
|
|
|
/* Build Dispatch table from passed data */
|
|
|
|
MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO;
|
|
|
|
|
|
|
|
/* Create a unicode device name */
|
|
|
|
Again = FALSE;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber);
|
|
|
|
RtlInitUnicodeString(&DeviceName, DeviceBuffer);
|
|
|
|
|
|
|
|
/* Create the device */
|
|
|
|
Status = IoCreateDevice(MPDriverObject,
|
|
|
|
HwInitializationData->HwDeviceExtensionSize +
|
2003-02-25 23:08:54 +00:00
|
|
|
sizeof(VIDEO_PORT_DEVICE_EXTENSION),
|
2003-02-15 19:16:34 +00:00
|
|
|
&DeviceName,
|
|
|
|
FILE_DEVICE_VIDEO,
|
|
|
|
0,
|
|
|
|
TRUE,
|
|
|
|
&MPDeviceObject);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
MPDriverObject->DeviceObject = MPDeviceObject;
|
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
/* Initialize the miniport drivers dispatch table */
|
2004-02-10 16:22:57 +00:00
|
|
|
MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpen;
|
|
|
|
MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchClose;
|
|
|
|
MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl;
|
2003-02-15 19:16:34 +00:00
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
/* Initialize our device extension */
|
|
|
|
DeviceExtension =
|
|
|
|
(PVIDEO_PORT_DEVICE_EXTENSION) MPDeviceObject->DeviceExtension;
|
|
|
|
DeviceExtension->DeviceObject = MPDeviceObject;
|
|
|
|
DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
|
2003-06-21 14:25:30 +00:00
|
|
|
DeviceExtension->HwResetHw = HwInitializationData->HwResetHw;
|
2003-02-25 23:08:54 +00:00
|
|
|
DeviceExtension->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType;
|
|
|
|
DeviceExtension->SystemIoBusNumber = 0;
|
|
|
|
MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR);
|
|
|
|
DeviceExtension->RegistryPath.MaximumLength = MaxLen;
|
|
|
|
DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
MaxLen,
|
|
|
|
TAG_VIDEO_PORT);
|
|
|
|
swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device%d",
|
|
|
|
RegistryPath->Buffer, DeviceNumber);
|
|
|
|
DeviceExtension->RegistryPath.Length = wcslen(DeviceExtension->RegistryPath.Buffer) *
|
|
|
|
sizeof(WCHAR);
|
|
|
|
|
|
|
|
MaxBus = (DeviceExtension->AdapterInterfaceType == PCIBus) ? 8 : 1;
|
|
|
|
DPRINT("MaxBus: %lu\n", MaxBus);
|
|
|
|
InitializeListHead(&DeviceExtension->AddressMappingListHead);
|
2003-02-15 19:16:34 +00:00
|
|
|
|
|
|
|
/* Set the buffering strategy here... */
|
|
|
|
/* If you change this, remember to change VidDispatchDeviceControl too */
|
|
|
|
MPDeviceObject->Flags |= DO_BUFFERED_IO;
|
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension,
|
|
|
|
HwInitializationData->HwDeviceExtensionSize);
|
|
|
|
DPRINT("Searching on bus %d\n", DeviceExtension->SystemIoBusNumber);
|
|
|
|
/* Setup configuration info */
|
2003-03-03 00:17:24 +00:00
|
|
|
RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
|
|
|
|
ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO);
|
2003-02-25 23:08:54 +00:00
|
|
|
ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType;
|
|
|
|
ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
|
|
|
|
ConfigInfo.InterruptMode = (PCIBus == DeviceExtension->AdapterInterfaceType) ?
|
|
|
|
LevelSensitive : Latched;
|
|
|
|
|
|
|
|
/* Call HwFindAdapter entry point */
|
|
|
|
/* FIXME: Need to figure out what string to pass as param 3 */
|
|
|
|
Status = HwInitializationData->HwFindAdapter(&DeviceExtension->MiniPortDeviceExtension,
|
|
|
|
Context2,
|
|
|
|
NULL,
|
|
|
|
&ConfigInfo,
|
|
|
|
&Again);
|
|
|
|
if (NO_ERROR != Status)
|
|
|
|
{
|
|
|
|
DPRINT("HwFindAdapter call failed with error %d\n", Status);
|
|
|
|
DeviceExtension->SystemIoBusNumber++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (NO_ERROR != Status && DeviceExtension->SystemIoBusNumber < MaxBus);
|
|
|
|
|
2003-02-15 19:16:34 +00:00
|
|
|
if (NO_ERROR != Status)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
|
2003-02-15 19:16:34 +00:00
|
|
|
IoDeleteDevice(MPDeviceObject);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
DPRINT("Found adapter\n");
|
|
|
|
|
|
|
|
/* create symbolic link "\??\DISPLAYx" */
|
|
|
|
swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber+1);
|
|
|
|
RtlInitUnicodeString (&SymlinkName,
|
|
|
|
SymlinkBuffer);
|
|
|
|
IoCreateSymbolicLink (&SymlinkName,
|
|
|
|
&DeviceName);
|
|
|
|
|
|
|
|
/* Add entry to DEVICEMAP\VIDEO key in registry */
|
|
|
|
swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DeviceNumber);
|
|
|
|
RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
|
|
|
|
L"VIDEO",
|
|
|
|
DeviceVideoBuffer,
|
|
|
|
REG_SZ,
|
|
|
|
DeviceExtension->RegistryPath.Buffer,
|
|
|
|
DeviceExtension->RegistryPath.Length + sizeof(WCHAR));
|
2003-02-15 19:16:34 +00:00
|
|
|
|
|
|
|
/* FIXME: Allocate hardware resources for device */
|
|
|
|
|
|
|
|
/* Allocate interrupt for device */
|
2003-11-05 22:31:50 +00:00
|
|
|
DeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt;
|
|
|
|
if (0 == ConfigInfo.BusInterruptVector)
|
|
|
|
{
|
|
|
|
ConfigInfo.BusInterruptVector = DeviceExtension->InterruptVector;
|
|
|
|
}
|
|
|
|
if (0 == ConfigInfo.BusInterruptLevel)
|
|
|
|
{
|
|
|
|
ConfigInfo.BusInterruptLevel = DeviceExtension->InterruptLevel;
|
|
|
|
}
|
|
|
|
if (NULL != HwInitializationData->HwInterrupt)
|
2003-02-15 19:16:34 +00:00
|
|
|
{
|
2003-11-05 22:31:50 +00:00
|
|
|
InterruptVector =
|
2003-02-15 19:16:34 +00:00
|
|
|
HalGetInterruptVector(ConfigInfo.AdapterInterfaceType,
|
|
|
|
ConfigInfo.SystemIoBusNumber,
|
|
|
|
ConfigInfo.BusInterruptLevel,
|
|
|
|
ConfigInfo.BusInterruptVector,
|
2003-11-05 22:31:50 +00:00
|
|
|
&IRQL,
|
|
|
|
&Affinity);
|
|
|
|
if (0 == InterruptVector)
|
|
|
|
{
|
|
|
|
DPRINT1("HalGetInterruptVector failed\n");
|
|
|
|
IoDeleteDevice(MPDeviceObject);
|
|
|
|
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock);
|
|
|
|
Status = IoConnectInterrupt(&DeviceExtension->InterruptObject,
|
2003-11-05 22:31:50 +00:00
|
|
|
VPInterruptRoutine,
|
|
|
|
DeviceExtension,
|
2003-02-25 23:08:54 +00:00
|
|
|
&DeviceExtension->InterruptSpinLock,
|
2003-11-05 22:31:50 +00:00
|
|
|
InterruptVector,
|
|
|
|
IRQL,
|
|
|
|
IRQL,
|
2003-02-15 19:16:34 +00:00
|
|
|
ConfigInfo.InterruptMode,
|
|
|
|
FALSE,
|
2003-11-05 22:31:50 +00:00
|
|
|
Affinity,
|
2003-02-15 19:16:34 +00:00
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2003-11-05 22:31:50 +00:00
|
|
|
DPRINT1("IoConnectInterrupt failed with status 0x%08x\n", Status);
|
2003-02-15 19:16:34 +00:00
|
|
|
IoDeleteDevice(MPDeviceObject);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DeviceNumber++;
|
|
|
|
}
|
|
|
|
while (Again);
|
|
|
|
|
2003-11-05 22:31:50 +00:00
|
|
|
DeviceExtension->HwTimer = HwInitializationData->HwTimer;
|
2003-02-15 19:16:34 +00:00
|
|
|
if (HwInitializationData->HwTimer != NULL)
|
|
|
|
{
|
2003-11-05 22:31:50 +00:00
|
|
|
DPRINT("Initializing timer\n");
|
2003-02-15 19:16:34 +00:00
|
|
|
Status = IoInitializeTimer(MPDeviceObject,
|
2003-11-05 22:31:50 +00:00
|
|
|
VPTimerRoutine,
|
|
|
|
DeviceExtension);
|
2003-02-15 19:16:34 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status);
|
|
|
|
|
|
|
|
if (HwInitializationData->HwInterrupt != NULL)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
IoDisconnectInterrupt(DeviceExtension->InterruptObject);
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
IoDeleteDevice(MPDeviceObject);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VOID
|
|
|
|
STDCALL
|
|
|
|
VideoPortLogError(IN PVOID HwDeviceExtension,
|
|
|
|
IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL,
|
|
|
|
IN VP_STATUS ErrorCode,
|
|
|
|
IN ULONG UniqueId)
|
|
|
|
{
|
2003-07-08 17:06:44 +00:00
|
|
|
DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
|
|
|
|
ErrorCode, ErrorCode, UniqueId, UniqueId);
|
|
|
|
if (NULL != Vrp)
|
|
|
|
{
|
|
|
|
DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp->IoControlCode, Vrp->IoControlCode);
|
|
|
|
}
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VP_STATUS
|
|
|
|
STDCALL
|
|
|
|
VideoPortMapBankedMemory(IN PVOID HwDeviceExtension,
|
|
|
|
IN PHYSICAL_ADDRESS PhysicalAddress,
|
|
|
|
IN PULONG Length,
|
|
|
|
IN PULONG InIoSpace,
|
|
|
|
OUT PVOID *VirtualAddress,
|
|
|
|
IN ULONG BankLength,
|
|
|
|
IN UCHAR ReadWriteBank,
|
|
|
|
IN PBANKED_SECTION_ROUTINE BankRoutine,
|
|
|
|
IN PVOID Context)
|
|
|
|
{
|
2004-03-04 18:51:58 +00:00
|
|
|
DPRINT("VideoPortMapBankedMemory\n");
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VP_STATUS
|
|
|
|
STDCALL
|
|
|
|
VideoPortMapMemory(IN PVOID HwDeviceExtension,
|
|
|
|
IN PHYSICAL_ADDRESS PhysicalAddress,
|
|
|
|
IN PULONG Length,
|
|
|
|
IN PULONG InIoSpace,
|
|
|
|
OUT PVOID *VirtualAddress)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
2003-02-15 19:16:34 +00:00
|
|
|
|
|
|
|
DPRINT("VideoPortMapMemory\n");
|
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
*VirtualAddress = InternalMapMemory(DeviceExtension, PhysicalAddress,
|
|
|
|
*Length, *InIoSpace);
|
2003-02-15 19:16:34 +00:00
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
return NULL == *VirtualAddress ? STATUS_NO_MEMORY : STATUS_SUCCESS;
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
BOOLEAN
|
|
|
|
STDCALL
|
|
|
|
VideoPortScanRom(IN PVOID HwDeviceExtension,
|
|
|
|
IN PUCHAR RomBase,
|
|
|
|
IN ULONG RomLength,
|
|
|
|
IN PUCHAR String)
|
|
|
|
{
|
2003-06-19 15:57:45 +00:00
|
|
|
ULONG StringLength;
|
|
|
|
BOOLEAN Found;
|
|
|
|
PUCHAR SearchLocation;
|
|
|
|
|
|
|
|
DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase, RomLength, String);
|
|
|
|
|
|
|
|
StringLength = strlen(String);
|
|
|
|
Found = FALSE;
|
|
|
|
SearchLocation = RomBase;
|
|
|
|
for (SearchLocation = RomBase;
|
|
|
|
! Found && SearchLocation < RomBase + RomLength - StringLength;
|
|
|
|
SearchLocation++)
|
|
|
|
{
|
|
|
|
Found = (RtlCompareMemory(SearchLocation, String, StringLength) == StringLength);
|
|
|
|
if (Found)
|
|
|
|
{
|
|
|
|
DPRINT("Match found at %p\n", SearchLocation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Found;
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
ULONG
|
|
|
|
STDCALL
|
|
|
|
VideoPortSetBusData(IN PVOID HwDeviceExtension,
|
|
|
|
IN BUS_DATA_TYPE BusDataType,
|
|
|
|
IN ULONG SlotNumber,
|
|
|
|
IN PVOID Buffer,
|
|
|
|
IN ULONG Offset,
|
|
|
|
IN ULONG Length)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortSetBusData\n");
|
|
|
|
return HalSetBusDataByOffset(BusDataType,
|
|
|
|
0,
|
|
|
|
SlotNumber,
|
|
|
|
Buffer,
|
|
|
|
Offset,
|
|
|
|
Length);
|
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VP_STATUS
|
|
|
|
STDCALL
|
|
|
|
VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension,
|
|
|
|
IN PWSTR ValueName,
|
|
|
|
IN PVOID ValueData,
|
|
|
|
IN ULONG ValueLength)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT("VideoSetRegistryParameters\n");
|
|
|
|
|
|
|
|
assert_irql(PASSIVE_LEVEL);
|
|
|
|
|
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
|
|
|
|
DeviceExtension->RegistryPath.Buffer,
|
|
|
|
ValueName,
|
|
|
|
REG_BINARY,
|
|
|
|
ValueData,
|
|
|
|
ValueLength);
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VP_STATUS
|
|
|
|
STDCALL
|
|
|
|
VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension,
|
|
|
|
IN ULONG NumAccessRanges,
|
|
|
|
IN PVIDEO_ACCESS_RANGE AccessRange)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortSetTrappedEmulatorPorts\n");
|
|
|
|
UNIMPLEMENTED;
|
2003-11-05 22:31:50 +00:00
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VOID
|
|
|
|
STDCALL
|
|
|
|
VideoPortStartTimer(IN PVOID HwDeviceExtension)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
2003-02-15 19:16:34 +00:00
|
|
|
|
|
|
|
DPRINT("VideoPortStartTimer\n");
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
IoStartTimer(DeviceExtension->DeviceObject);
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VOID
|
|
|
|
STDCALL
|
|
|
|
VideoPortStopTimer(IN PVOID HwDeviceExtension)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
2003-02-15 19:16:34 +00:00
|
|
|
|
|
|
|
DPRINT("VideoPortStopTimer\n");
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
IoStopTimer(DeviceExtension->DeviceObject);
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
BOOLEAN
|
|
|
|
STDCALL
|
|
|
|
VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension,
|
|
|
|
IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
|
|
|
|
IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
|
|
|
|
OUT PVOID Context)
|
|
|
|
{
|
2003-06-19 15:57:45 +00:00
|
|
|
BOOLEAN Ret;
|
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
KIRQL OldIrql;
|
|
|
|
|
2003-02-15 19:16:34 +00:00
|
|
|
DPRINT("VideoPortSynchronizeExecution\n");
|
2003-06-19 15:57:45 +00:00
|
|
|
|
|
|
|
switch(Priority)
|
|
|
|
{
|
|
|
|
case VpLowPriority:
|
|
|
|
Ret = (*SynchronizeRoutine)(Context);
|
|
|
|
break;
|
|
|
|
case VpMediumPriority:
|
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
if (NULL == DeviceExtension->InterruptObject)
|
|
|
|
{
|
|
|
|
Ret = (*SynchronizeRoutine)(Context);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Ret = KeSynchronizeExecution(DeviceExtension->InterruptObject,
|
|
|
|
SynchronizeRoutine,
|
|
|
|
Context);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case VpHighPriority:
|
|
|
|
OldIrql = KeGetCurrentIrql();
|
|
|
|
if (OldIrql < SYNCH_LEVEL)
|
|
|
|
{
|
|
|
|
OldIrql = KfRaiseIrql(SYNCH_LEVEL);
|
|
|
|
}
|
|
|
|
Ret = (*SynchronizeRoutine)(Context);
|
|
|
|
if (OldIrql < SYNCH_LEVEL)
|
|
|
|
{
|
|
|
|
KfLowerIrql(OldIrql);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Ret = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ret;
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VP_STATUS
|
|
|
|
STDCALL
|
|
|
|
VideoPortUnmapMemory(IN PVOID HwDeviceExtension,
|
|
|
|
IN PVOID VirtualAddress,
|
|
|
|
IN HANDLE ProcessHandle)
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT("VideoPortFreeDeviceBase\n");
|
|
|
|
|
|
|
|
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
|
|
VIDEO_PORT_DEVICE_EXTENSION,
|
|
|
|
MiniPortDeviceExtension);
|
|
|
|
|
|
|
|
InternalUnmapMemory(DeviceExtension, VirtualAddress);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2003-02-15 19:16:34 +00:00
|
|
|
VP_STATUS
|
|
|
|
STDCALL
|
|
|
|
VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension,
|
|
|
|
IN ULONG NumAccessRanges,
|
|
|
|
IN PVIDEO_ACCESS_RANGE AccessRanges)
|
|
|
|
{
|
|
|
|
DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
|
|
|
|
return NO_ERROR;
|
|
|
|
}
|
|
|
|
|
2003-07-10 21:12:40 +00:00
|
|
|
|
2003-06-21 14:25:30 +00:00
|
|
|
/*
|
|
|
|
* Reset display to blue screen
|
|
|
|
*/
|
|
|
|
static BOOLEAN STDCALL
|
|
|
|
VideoPortResetDisplayParameters(Columns, Rows)
|
|
|
|
{
|
2003-12-03 18:58:41 +00:00
|
|
|
if (NULL == ResetDisplayParametersDeviceExtension)
|
2003-08-24 11:30:02 +00:00
|
|
|
{
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
if (NULL == ResetDisplayParametersDeviceExtension->HwResetHw)
|
2003-06-21 14:25:30 +00:00
|
|
|
{
|
2003-08-24 11:30:02 +00:00
|
|
|
return(FALSE);
|
2003-06-21 14:25:30 +00:00
|
|
|
}
|
2003-08-24 11:30:02 +00:00
|
|
|
if (!ResetDisplayParametersDeviceExtension->HwResetHw(&ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
|
|
|
|
Columns, Rows))
|
|
|
|
{
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
2003-06-21 14:25:30 +00:00
|
|
|
ResetDisplayParametersDeviceExtension = NULL;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
2003-02-15 19:16:34 +00:00
|
|
|
|
2004-01-19 15:56:53 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
PVOID
|
|
|
|
STDCALL
|
|
|
|
VideoPortAllocatePool(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN VP_POOL_TYPE PoolType,
|
|
|
|
IN SIZE_T NumberOfBytes,
|
|
|
|
IN ULONG Tag)
|
|
|
|
{
|
|
|
|
return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID
|
|
|
|
STDCALL
|
|
|
|
VideoPortFreePool(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN PVOID Ptr)
|
|
|
|
{
|
|
|
|
ExFreePool(Ptr);
|
|
|
|
}
|
2003-02-15 19:16:34 +00:00
|
|
|
|
2003-06-21 14:25:30 +00:00
|
|
|
// VidDispatchOpen
|
2003-02-15 19:16:34 +00:00
|
|
|
//
|
|
|
|
// DESCRIPTION:
|
2003-06-21 14:25:30 +00:00
|
|
|
// Answer requests for Open calls
|
2003-02-15 19:16:34 +00:00
|
|
|
//
|
|
|
|
// RUN LEVEL:
|
|
|
|
// PASSIVE_LEVEL
|
|
|
|
//
|
|
|
|
// ARGUMENTS:
|
|
|
|
// Standard dispatch arguments
|
|
|
|
//
|
|
|
|
// RETURNS:
|
|
|
|
// NTSTATUS
|
|
|
|
//
|
|
|
|
|
2004-01-19 15:56:53 +00:00
|
|
|
NTSTATUS STDCALL
|
2003-06-21 14:25:30 +00:00
|
|
|
VidDispatchOpen(IN PDEVICE_OBJECT pDO,
|
|
|
|
IN PIRP Irp)
|
2003-02-15 19:16:34 +00:00
|
|
|
{
|
|
|
|
PIO_STACK_LOCATION IrpStack;
|
2003-06-21 14:25:30 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
2003-02-15 19:16:34 +00:00
|
|
|
|
2003-06-21 14:25:30 +00:00
|
|
|
DPRINT("VidDispatchOpen() called\n");
|
2003-02-15 19:16:34 +00:00
|
|
|
|
|
|
|
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
|
2003-06-21 14:25:30 +00:00
|
|
|
if (! CsrssInitialized)
|
2003-02-15 19:16:34 +00:00
|
|
|
{
|
|
|
|
DPRINT("Referencing CSRSS\n");
|
|
|
|
Csrss = PsGetCurrentProcess();
|
|
|
|
DPRINT("Csrss %p\n", Csrss);
|
2003-06-21 14:25:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION) pDO->DeviceExtension;
|
|
|
|
if (DeviceExtension->HwInitialize(&DeviceExtension->MiniPortDeviceExtension))
|
2003-02-15 19:16:34 +00:00
|
|
|
{
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
2003-06-21 14:25:30 +00:00
|
|
|
/* Storing the device extension pointer in a static variable is an ugly
|
|
|
|
* hack. Unfortunately, we need it in VideoPortResetDisplayParameters
|
|
|
|
* and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
|
|
|
|
* parameter. On the bright side, the DISPLAY device is opened
|
|
|
|
* exclusively, so there can be only one device extension active at
|
|
|
|
* any point in time. */
|
|
|
|
ResetDisplayParametersDeviceExtension = DeviceExtension;
|
|
|
|
HalAcquireDisplayOwnership(VideoPortResetDisplayParameters);
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
}
|
2003-06-21 14:25:30 +00:00
|
|
|
|
|
|
|
Irp->IoStatus.Information = FILE_OPENED;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
// VidDispatchClose
|
|
|
|
//
|
|
|
|
// DESCRIPTION:
|
|
|
|
// Answer requests for Close calls
|
|
|
|
//
|
|
|
|
// RUN LEVEL:
|
|
|
|
// PASSIVE_LEVEL
|
|
|
|
//
|
|
|
|
// ARGUMENTS:
|
|
|
|
// Standard dispatch arguments
|
|
|
|
//
|
|
|
|
// RETURNS:
|
|
|
|
// NTSTATUS
|
|
|
|
//
|
|
|
|
|
2004-01-19 15:56:53 +00:00
|
|
|
NTSTATUS STDCALL
|
2003-06-21 14:25:30 +00:00
|
|
|
VidDispatchClose(IN PDEVICE_OBJECT pDO,
|
|
|
|
IN PIRP Irp)
|
|
|
|
{
|
|
|
|
PIO_STACK_LOCATION IrpStack;
|
|
|
|
|
|
|
|
DPRINT("VidDispatchClose() called\n");
|
|
|
|
|
|
|
|
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
|
|
|
|
if (! CsrssInitialized)
|
|
|
|
{
|
|
|
|
CsrssInitialized = TRUE;
|
|
|
|
}
|
2003-02-15 19:16:34 +00:00
|
|
|
else
|
|
|
|
{
|
2003-06-21 14:25:30 +00:00
|
|
|
HalReleaseDisplayOwnership();
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
2003-06-21 14:25:30 +00:00
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
2003-02-15 19:16:34 +00:00
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
// VidDispatchDeviceControl
|
|
|
|
//
|
|
|
|
// DESCRIPTION:
|
|
|
|
// Answer requests for device control calls
|
|
|
|
//
|
|
|
|
// RUN LEVEL:
|
|
|
|
// PASSIVE_LEVEL
|
|
|
|
//
|
|
|
|
// ARGUMENTS:
|
|
|
|
// Standard dispatch arguments
|
|
|
|
//
|
|
|
|
// RETURNS:
|
|
|
|
// NTSTATUS
|
|
|
|
//
|
|
|
|
|
2004-01-19 15:56:53 +00:00
|
|
|
NTSTATUS STDCALL
|
2003-02-15 19:16:34 +00:00
|
|
|
VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp)
|
|
|
|
{
|
|
|
|
PIO_STACK_LOCATION IrpStack;
|
2003-02-25 23:08:54 +00:00
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
2003-02-15 19:16:34 +00:00
|
|
|
PVIDEO_REQUEST_PACKET vrp;
|
|
|
|
|
|
|
|
DPRINT("VidDispatchDeviceControl\n");
|
|
|
|
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
2003-02-25 23:08:54 +00:00
|
|
|
DeviceExtension = DeviceObject->DeviceExtension;
|
2003-02-15 19:16:34 +00:00
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
/* Translate the IRP to a VRP */
|
2003-02-15 19:16:34 +00:00
|
|
|
vrp = ExAllocatePool(PagedPool, sizeof(VIDEO_REQUEST_PACKET));
|
2003-02-25 23:08:54 +00:00
|
|
|
if (NULL == vrp)
|
|
|
|
{
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
vrp->StatusBlock = (PSTATUS_BLOCK) &(Irp->IoStatus);
|
2003-02-15 19:16:34 +00:00
|
|
|
vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
|
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
/* We're assuming METHOD_BUFFERED */
|
2003-02-15 19:16:34 +00:00
|
|
|
vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
|
2003-02-25 23:08:54 +00:00
|
|
|
vrp->OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
|
2003-02-15 19:16:34 +00:00
|
|
|
vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
|
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
/* Call the Miniport Driver with the VRP */
|
2004-01-19 15:56:53 +00:00
|
|
|
((PDRIVER_STARTIO)DeviceObject->DriverObject->DriverStartIo)((PVOID) &DeviceExtension->MiniPortDeviceExtension, (PIRP)vrp);
|
2003-02-15 19:16:34 +00:00
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
/* Free the VRP */
|
2003-02-15 19:16:34 +00:00
|
|
|
ExFreePool(vrp);
|
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
|
2003-02-15 19:16:34 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
|
2004-01-19 15:56:53 +00:00
|
|
|
PVOID STDCALL
|
2003-02-25 23:08:54 +00:00
|
|
|
InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
|
|
|
|
IN PHYSICAL_ADDRESS IoAddress,
|
|
|
|
IN ULONG NumberOfUchars,
|
|
|
|
IN UCHAR InIoSpace)
|
|
|
|
{
|
|
|
|
PHYSICAL_ADDRESS TranslatedAddress;
|
|
|
|
PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
|
|
|
|
ULONG AddressSpace;
|
|
|
|
PVOID MappedAddress;
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
|
|
|
|
if (0 != (InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE))
|
|
|
|
{
|
|
|
|
DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
|
|
|
|
InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE;
|
|
|
|
}
|
|
|
|
if (! IsListEmpty(&DeviceExtension->AddressMappingListHead))
|
|
|
|
{
|
|
|
|
Entry = DeviceExtension->AddressMappingListHead.Flink;
|
|
|
|
while (Entry != &DeviceExtension->AddressMappingListHead)
|
|
|
|
{
|
|
|
|
AddressMapping = CONTAINING_RECORD(Entry,
|
|
|
|
VIDEO_PORT_ADDRESS_MAPPING,
|
|
|
|
List);
|
|
|
|
if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart &&
|
|
|
|
NumberOfUchars <= AddressMapping->NumberOfUchars)
|
|
|
|
{
|
|
|
|
AddressMapping->MappingCount++;
|
|
|
|
return AddressMapping->MappedAddress;
|
|
|
|
}
|
|
|
|
Entry = Entry->Flink;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AddressSpace = (ULONG)InIoSpace;
|
2003-03-03 00:17:24 +00:00
|
|
|
if (HalTranslateBusAddress(DeviceExtension->AdapterInterfaceType,
|
2003-02-25 23:08:54 +00:00
|
|
|
DeviceExtension->SystemIoBusNumber,
|
|
|
|
IoAddress,
|
|
|
|
&AddressSpace,
|
|
|
|
&TranslatedAddress) == FALSE)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* i/o space */
|
|
|
|
if (AddressSpace != 0)
|
|
|
|
{
|
|
|
|
assert(0 == TranslatedAddress.u.HighPart);
|
|
|
|
return (PVOID) TranslatedAddress.u.LowPart;
|
|
|
|
}
|
|
|
|
|
|
|
|
MappedAddress = MmMapIoSpace(TranslatedAddress,
|
|
|
|
NumberOfUchars,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
AddressMapping = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
sizeof(VIDEO_PORT_ADDRESS_MAPPING),
|
|
|
|
TAG_VIDEO_PORT);
|
|
|
|
if (AddressMapping == NULL)
|
|
|
|
return MappedAddress;
|
|
|
|
|
|
|
|
AddressMapping->MappedAddress = MappedAddress;
|
|
|
|
AddressMapping->NumberOfUchars = NumberOfUchars;
|
|
|
|
AddressMapping->IoAddress = IoAddress;
|
|
|
|
AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
|
|
|
|
AddressMapping->MappingCount = 1;
|
|
|
|
|
|
|
|
InsertHeadList(&DeviceExtension->AddressMappingListHead,
|
|
|
|
&AddressMapping->List);
|
|
|
|
|
|
|
|
return MappedAddress;
|
|
|
|
}
|
|
|
|
|
2004-01-19 15:56:53 +00:00
|
|
|
VOID STDCALL
|
2003-02-25 23:08:54 +00:00
|
|
|
InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
|
|
|
|
IN PVOID MappedAddress)
|
|
|
|
{
|
|
|
|
PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
|
|
|
|
Entry = DeviceExtension->AddressMappingListHead.Flink;
|
|
|
|
while (Entry != &DeviceExtension->AddressMappingListHead)
|
|
|
|
{
|
|
|
|
AddressMapping = CONTAINING_RECORD(Entry,
|
|
|
|
VIDEO_PORT_ADDRESS_MAPPING,
|
|
|
|
List);
|
|
|
|
if (AddressMapping->MappedAddress == MappedAddress)
|
|
|
|
{
|
|
|
|
assert(0 <= AddressMapping->MappingCount);
|
|
|
|
AddressMapping->MappingCount--;
|
|
|
|
if (0 == AddressMapping->MappingCount)
|
|
|
|
{
|
|
|
|
MmUnmapIoSpace(AddressMapping->MappedAddress,
|
|
|
|
AddressMapping->NumberOfUchars);
|
|
|
|
RemoveEntryList(Entry);
|
|
|
|
ExFreePool(AddressMapping);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry = Entry->Flink;
|
|
|
|
}
|
|
|
|
}
|