2004-03-19 20:58:32 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*
|
2005-01-06 13:58:04 +00:00
|
|
|
* $Id$
|
2004-03-19 20:58:32 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "videoprt.h"
|
|
|
|
|
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
|
|
|
|
|
|
|
PVOID STDCALL
|
|
|
|
IntVideoPortMapMemory(
|
|
|
|
IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
|
|
|
|
IN PHYSICAL_ADDRESS IoAddress,
|
|
|
|
IN ULONG NumberOfUchars,
|
|
|
|
IN UCHAR InIoSpace,
|
|
|
|
OUT VP_STATUS *Status)
|
|
|
|
{
|
|
|
|
PHYSICAL_ADDRESS TranslatedAddress;
|
2004-12-18 22:14:39 +00:00
|
|
|
PVIDEO_PORT_ADDRESS_MAPPING AddressMapping = NULL;
|
2004-03-19 20:58:32 +00:00
|
|
|
ULONG AddressSpace;
|
|
|
|
PVOID MappedAddress;
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
|
|
|
|
DPRINT("- IoAddress: %lx\n", IoAddress.u.LowPart);
|
|
|
|
DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars);
|
|
|
|
DPRINT("- InIoSpace: %x\n", InIoSpace);
|
|
|
|
|
|
|
|
InIoSpace &= ~VIDEO_MEMORY_SPACE_DENSE;
|
|
|
|
if ((InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE) != 0)
|
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2004-12-18 22:14:39 +00:00
|
|
|
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;
|
2004-03-19 20:58:32 +00:00
|
|
|
}
|
|
|
|
Entry = Entry->Flink;
|
|
|
|
}
|
2004-12-18 22:14:39 +00:00
|
|
|
if (Entry == &DeviceExtension->AddressMappingListHead)
|
|
|
|
AddressMapping = NULL;
|
2004-03-19 20:58:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AddressSpace = (ULONG)InIoSpace;
|
2004-12-18 22:14:39 +00:00
|
|
|
AddressSpace &= ~VIDEO_MEMORY_SPACE_USER_MODE;
|
2004-03-19 20:58:32 +00:00
|
|
|
if (HalTranslateBusAddress(
|
|
|
|
DeviceExtension->AdapterInterfaceType,
|
|
|
|
DeviceExtension->SystemIoBusNumber,
|
|
|
|
IoAddress,
|
|
|
|
&AddressSpace,
|
|
|
|
&TranslatedAddress) == FALSE)
|
|
|
|
{
|
|
|
|
if (Status)
|
|
|
|
*Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* I/O space */
|
|
|
|
if (AddressSpace != 0)
|
|
|
|
{
|
|
|
|
ASSERT(0 == TranslatedAddress.u.HighPart);
|
|
|
|
if (Status)
|
|
|
|
*Status = NO_ERROR;
|
|
|
|
|
|
|
|
return (PVOID)TranslatedAddress.u.LowPart;
|
|
|
|
}
|
|
|
|
|
2004-12-18 22:14:39 +00:00
|
|
|
/* user space */
|
|
|
|
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
|
|
|
|
{
|
|
|
|
OBJECT_ATTRIBUTES ObjAttribs;
|
|
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
HANDLE hMemObj;
|
|
|
|
NTSTATUS NtStatus;
|
|
|
|
SIZE_T Size;
|
2004-03-19 20:58:32 +00:00
|
|
|
|
2004-12-18 22:14:39 +00:00
|
|
|
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*/);
|
|
|
|
if (!NT_SUCCESS(NtStatus))
|
|
|
|
{
|
|
|
|
DPRINT("ZwMapViewOfSection() failed! (0x%x)\n", NtStatus);
|
|
|
|
ZwClose(hMemObj);
|
|
|
|
if (Status)
|
|
|
|
*Status = NO_ERROR;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
ZwClose(hMemObj);
|
|
|
|
DPRINT("Mapped user address = 0x%08x\n", MappedAddress);
|
|
|
|
}
|
|
|
|
else /* kernel space */
|
2004-03-19 20:58:32 +00:00
|
|
|
{
|
2004-12-18 22:14:39 +00:00
|
|
|
MappedAddress = MmMapIoSpace(
|
|
|
|
TranslatedAddress,
|
|
|
|
NumberOfUchars,
|
|
|
|
MmNonCached);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MappedAddress != NULL)
|
|
|
|
{
|
|
|
|
BOOL InsertIntoList = FALSE;
|
|
|
|
|
2004-03-19 20:58:32 +00:00
|
|
|
if (Status)
|
|
|
|
{
|
|
|
|
*Status = NO_ERROR;
|
|
|
|
}
|
2004-12-18 22:14:39 +00:00
|
|
|
if (AddressMapping == NULL)
|
|
|
|
{
|
|
|
|
AddressMapping = ExAllocatePoolWithTag(
|
|
|
|
PagedPool,
|
|
|
|
sizeof(VIDEO_PORT_ADDRESS_MAPPING),
|
|
|
|
TAG_VIDEO_PORT);
|
2004-03-19 20:58:32 +00:00
|
|
|
|
2004-12-18 22:14:39 +00:00
|
|
|
if (AddressMapping == NULL)
|
|
|
|
return MappedAddress;
|
2004-03-19 20:58:32 +00:00
|
|
|
|
2004-12-18 22:14:39 +00:00
|
|
|
InsertIntoList = TRUE;
|
|
|
|
RtlZeroMemory(AddressMapping, sizeof(VIDEO_PORT_ADDRESS_MAPPING));
|
|
|
|
AddressMapping->NumberOfUchars = NumberOfUchars;
|
|
|
|
AddressMapping->IoAddress = IoAddress;
|
|
|
|
AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
|
|
|
|
}
|
2004-03-19 20:58:32 +00:00
|
|
|
|
2004-12-18 22:14:39 +00:00
|
|
|
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
|
|
|
|
{
|
|
|
|
AddressMapping->MappedUserAddress = MappedAddress;
|
|
|
|
AddressMapping->UserMappingCount = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AddressMapping->MappedAddress = MappedAddress;
|
|
|
|
AddressMapping->MappingCount = 1;
|
|
|
|
}
|
2004-03-19 20:58:32 +00:00
|
|
|
|
2004-12-18 22:14:39 +00:00
|
|
|
if (InsertIntoList)
|
|
|
|
{
|
|
|
|
InsertHeadList(
|
|
|
|
&DeviceExtension->AddressMappingListHead,
|
|
|
|
&AddressMapping->List);
|
|
|
|
}
|
2004-03-19 20:58:32 +00:00
|
|
|
|
|
|
|
return MappedAddress;
|
|
|
|
}
|
|
|
|
|
2004-12-18 22:14:39 +00:00
|
|
|
if (Status)
|
|
|
|
*Status = NO_ERROR;
|
|
|
|
|
|
|
|
return NULL;
|
2004-03-19 20:58:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID STDCALL
|
|
|
|
IntVideoPortUnmapMemory(
|
|
|
|
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);
|
2004-12-18 22:14:39 +00:00
|
|
|
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)
|
2004-03-19 20:58:32 +00:00
|
|
|
{
|
2004-12-18 22:14:39 +00:00
|
|
|
ASSERT(AddressMapping->MappingCount > 0);
|
2004-03-19 20:58:32 +00:00
|
|
|
AddressMapping->MappingCount--;
|
|
|
|
if (AddressMapping->MappingCount == 0)
|
|
|
|
{
|
|
|
|
MmUnmapIoSpace(
|
|
|
|
AddressMapping->MappedAddress,
|
|
|
|
AddressMapping->NumberOfUchars);
|
2004-12-18 22:14:39 +00:00
|
|
|
AddressMapping->MappedAddress = NULL;
|
|
|
|
if (AddressMapping->UserMappingCount == 0)
|
|
|
|
{
|
|
|
|
RemoveEntryList(Entry);
|
|
|
|
ExFreePool(AddressMapping);
|
|
|
|
}
|
2004-03-19 20:58:32 +00:00
|
|
|
}
|
2004-12-18 22:14:39 +00:00
|
|
|
return;
|
2004-03-19 20:58:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Entry = Entry->Flink;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
PVOID STDCALL
|
|
|
|
VideoPortGetDeviceBase(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN PHYSICAL_ADDRESS IoAddress,
|
|
|
|
IN ULONG NumberOfUchars,
|
|
|
|
IN UCHAR InIoSpace)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortGetDeviceBase\n");
|
|
|
|
return IntVideoPortMapMemory(
|
|
|
|
VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
|
|
|
|
IoAddress,
|
|
|
|
NumberOfUchars,
|
|
|
|
InIoSpace,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID STDCALL
|
|
|
|
VideoPortFreeDeviceBase(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN PVOID MappedAddress)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortFreeDeviceBase\n");
|
|
|
|
IntVideoPortUnmapMemory(
|
|
|
|
VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
|
|
|
|
MappedAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortMapBankedMemory\n");
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
VP_STATUS STDCALL
|
|
|
|
VideoPortMapMemory(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN PHYSICAL_ADDRESS PhysicalAddress,
|
|
|
|
IN PULONG Length,
|
|
|
|
IN PULONG InIoSpace,
|
|
|
|
OUT PVOID *VirtualAddress)
|
|
|
|
{
|
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("VideoPortMapMemory\n");
|
|
|
|
|
|
|
|
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
|
|
|
*VirtualAddress = IntVideoPortMapMemory(
|
|
|
|
DeviceExtension,
|
|
|
|
PhysicalAddress,
|
|
|
|
*Length,
|
|
|
|
*InIoSpace,
|
|
|
|
&Status);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
VP_STATUS STDCALL
|
|
|
|
VideoPortUnmapMemory(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN PVOID VirtualAddress,
|
|
|
|
IN HANDLE ProcessHandle)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortFreeDeviceBase\n");
|
|
|
|
|
|
|
|
IntVideoPortUnmapMemory(
|
|
|
|
VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
|
|
|
|
VirtualAddress);
|
|
|
|
|
|
|
|
return NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
PCI_SLOT_NUMBER PciSlotNumber;
|
|
|
|
ULONG FunctionNumber;
|
|
|
|
PCI_COMMON_CONFIG Config;
|
|
|
|
PCM_RESOURCE_LIST AllocatedResources;
|
|
|
|
NTSTATUS Status;
|
|
|
|
UINT AssignedCount;
|
|
|
|
CM_FULL_RESOURCE_DESCRIPTOR *FullList;
|
|
|
|
CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
|
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
USHORT VendorIdToFind;
|
|
|
|
USHORT DeviceIdToFind;
|
|
|
|
ULONG SlotIdToFind;
|
|
|
|
ULONG ReturnedLength;
|
|
|
|
|
|
|
|
DPRINT("VideoPortGetAccessRanges\n");
|
|
|
|
|
|
|
|
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
|
|
|
|
|
|
|
if (NumRequestedResources == 0 &&
|
|
|
|
DeviceExtension->AdapterInterfaceType == PCIBus)
|
|
|
|
{
|
|
|
|
if (DeviceExtension->PhysicalDeviceObject != NULL)
|
|
|
|
{
|
|
|
|
PciSlotNumber.u.AsULONG = DeviceExtension->SystemIoSlotNumber;
|
|
|
|
|
|
|
|
ReturnedLength = HalGetBusData(
|
|
|
|
PCIConfiguration,
|
|
|
|
DeviceExtension->SystemIoBusNumber,
|
|
|
|
PciSlotNumber.u.AsULONG,
|
|
|
|
&Config,
|
|
|
|
sizeof(PCI_COMMON_CONFIG));
|
|
|
|
|
|
|
|
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))
|
|
|
|
{
|
|
|
|
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");
|
2004-10-15 22:48:43 +00:00
|
|
|
return ERROR_DEV_NOT_EXIST;
|
2004-03-19 20:58:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = HalAssignSlotResources(
|
|
|
|
NULL, NULL, NULL, NULL,
|
|
|
|
DeviceExtension->AdapterInterfaceType,
|
|
|
|
DeviceExtension->SystemIoBusNumber,
|
|
|
|
PciSlotNumber.u.AsULONG,
|
|
|
|
&AllocatedResources);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
AssignedCount = 0;
|
|
|
|
for (FullList = AllocatedResources->List;
|
|
|
|
FullList < AllocatedResources->List + AllocatedResources->Count;
|
|
|
|
FullList++)
|
|
|
|
{
|
|
|
|
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 == CmResourceTypeMemory ||
|
|
|
|
Descriptor->Type == CmResourceTypePort) &&
|
|
|
|
AssignedCount >= NumAccessRanges)
|
|
|
|
{
|
|
|
|
DPRINT1("Too many access ranges found\n");
|
|
|
|
ExFreePool(AllocatedResources);
|
|
|
|
return ERROR_NO_SYSTEM_RESOURCES;
|
|
|
|
}
|
|
|
|
if (Descriptor->Type == CmResourceTypeMemory)
|
|
|
|
{
|
|
|
|
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",
|
|
|
|
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 =
|
|
|
|
(Descriptor->ShareDisposition == CmResourceShareShared);
|
|
|
|
AssignedCount++;
|
|
|
|
}
|
|
|
|
else if (Descriptor->Type == CmResourceTypePort)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
AssignedCount++;
|
|
|
|
}
|
|
|
|
else if (Descriptor->Type == CmResourceTypeInterrupt)
|
|
|
|
{
|
|
|
|
DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
|
|
|
|
DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ExFreePool(AllocatedResources);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
}
|
|
|
|
|
|
|
|
return NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
VP_STATUS STDCALL
|
|
|
|
VideoPortVerifyAccessRanges(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN ULONG NumAccessRanges,
|
|
|
|
IN PVIDEO_ACCESS_RANGE AccessRanges)
|
|
|
|
{
|
|
|
|
DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
|
|
|
|
return NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
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;
|
|
|
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
PVOID STDCALL
|
|
|
|
VideoPortAllocatePool(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN VP_POOL_TYPE PoolType,
|
|
|
|
IN SIZE_T NumberOfBytes,
|
|
|
|
IN ULONG Tag)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortAllocatePool\n");
|
|
|
|
return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID STDCALL
|
|
|
|
VideoPortFreePool(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN PVOID Ptr)
|
|
|
|
{
|
|
|
|
ExFreePool(Ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
VP_STATUS STDCALL
|
|
|
|
VideoPortAllocateBuffer(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN ULONG Size,
|
|
|
|
OUT PVOID *Buffer)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortAllocateBuffer\n");
|
|
|
|
*Buffer = ExAllocatePool(PagedPool, Size);
|
|
|
|
return *Buffer == NULL ? ERROR_NOT_ENOUGH_MEMORY : NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID STDCALL
|
|
|
|
VideoPortReleaseBuffer(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN PVOID Ptr)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortReleaseBuffer\n");
|
|
|
|
ExFreePool(Ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
PVOID STDCALL
|
|
|
|
VideoPortLockBuffer(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN PVOID BaseAddress,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN VP_LOCK_OPERATION Operation)
|
|
|
|
{
|
|
|
|
DPRINT1("VideoPortLockBuffer: Unimplemented.\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID STDCALL
|
|
|
|
VideoPortUnlockBuffer(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN PVOID Mdl)
|
|
|
|
{
|
|
|
|
DPRINT1("VideoPortUnlockBuffer: Unimplemented.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
VP_STATUS STDCALL
|
|
|
|
VideoPortSetTrappedEmulatorPorts(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN ULONG NumAccessRanges,
|
|
|
|
IN PVIDEO_ACCESS_RANGE AccessRange)
|
|
|
|
{
|
|
|
|
DPRINT("VideoPortSetTrappedEmulatorPorts\n");
|
|
|
|
/* Should store the ranges in the device extension for use by ntvdm. */
|
|
|
|
return NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
ULONG STDCALL
|
|
|
|
VideoPortGetBusData(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN BUS_DATA_TYPE BusDataType,
|
|
|
|
IN ULONG SlotNumber,
|
|
|
|
OUT PVOID Buffer,
|
|
|
|
IN ULONG Offset,
|
|
|
|
IN ULONG Length)
|
|
|
|
{
|
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT("VideoPortGetBusData\n");
|
|
|
|
|
|
|
|
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
|
|
|
|
|
|
|
if (BusDataType != Cmos)
|
|
|
|
{
|
|
|
|
/* Legacy vs. PnP behaviour */
|
|
|
|
if (DeviceExtension->PhysicalDeviceObject != NULL)
|
|
|
|
SlotNumber = DeviceExtension->SystemIoSlotNumber;
|
|
|
|
}
|
|
|
|
|
|
|
|
return HalGetBusDataByOffset(
|
|
|
|
BusDataType,
|
|
|
|
DeviceExtension->SystemIoBusNumber,
|
|
|
|
SlotNumber,
|
|
|
|
Buffer,
|
|
|
|
Offset,
|
|
|
|
Length);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
|
|
|
|
ULONG STDCALL
|
|
|
|
VideoPortSetBusData(
|
|
|
|
IN PVOID HwDeviceExtension,
|
|
|
|
IN BUS_DATA_TYPE BusDataType,
|
|
|
|
IN ULONG SlotNumber,
|
|
|
|
IN PVOID Buffer,
|
|
|
|
IN ULONG Offset,
|
|
|
|
IN ULONG Length)
|
|
|
|
{
|
|
|
|
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT("VideoPortSetBusData\n");
|
|
|
|
|
|
|
|
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
|
|
|
|
|
|
|
|
if (BusDataType != Cmos)
|
|
|
|
{
|
|
|
|
/* Legacy vs. PnP behaviour */
|
|
|
|
if (DeviceExtension->PhysicalDeviceObject != NULL)
|
|
|
|
SlotNumber = DeviceExtension->SystemIoSlotNumber;
|
|
|
|
}
|
|
|
|
|
|
|
|
return HalSetBusDataByOffset(
|
|
|
|
BusDataType,
|
|
|
|
DeviceExtension->SystemIoBusNumber,
|
|
|
|
SlotNumber,
|
|
|
|
Buffer,
|
|
|
|
Offset,
|
|
|
|
Length);
|
|
|
|
}
|