[VIDEOPRT]

- Support passing a resource requirements list to VideoPortGetAccessRanges

svn path=/trunk/; revision=54239
This commit is contained in:
Cameron Gutman 2011-10-23 03:55:35 +00:00
parent 69fdb2ac71
commit c64e8b00c0

View file

@ -559,210 +559,241 @@ VideoPortGetAccessRanges(
IN PVOID DeviceId, IN PVOID DeviceId,
OUT PULONG Slot) OUT PULONG Slot)
{ {
PCI_SLOT_NUMBER PciSlotNumber; PCI_SLOT_NUMBER PciSlotNumber;
ULONG DeviceNumber; ULONG DeviceNumber;
ULONG FunctionNumber; ULONG FunctionNumber;
PCI_COMMON_CONFIG Config; PCI_COMMON_CONFIG Config;
PCM_RESOURCE_LIST AllocatedResources; PCM_RESOURCE_LIST AllocatedResources;
NTSTATUS Status; NTSTATUS Status;
UINT AssignedCount; UINT AssignedCount;
CM_FULL_RESOURCE_DESCRIPTOR *FullList; CM_FULL_RESOURCE_DESCRIPTOR *FullList;
CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor; CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
PVIDEO_PORT_DRIVER_EXTENSION DriverExtension; PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
USHORT VendorIdToFind; USHORT VendorIdToFind;
USHORT DeviceIdToFind; USHORT DeviceIdToFind;
ULONG ReturnedLength; ULONG ReturnedLength;
PVIDEO_ACCESS_RANGE LegacyAccessRanges; PVIDEO_ACCESS_RANGE LegacyAccessRanges;
ULONG LegacyAccessRangeCount; ULONG LegacyAccessRangeCount;
PDRIVER_OBJECT DriverObject; PDRIVER_OBJECT DriverObject;
BOOLEAN DeviceAndVendorFound = FALSE; ULONG ListSize;
PIO_RESOURCE_REQUIREMENTS_LIST ResReqList;
BOOLEAN DeviceAndVendorFound = FALSE;
TRACE_(VIDEOPRT, "VideoPortGetAccessRanges\n");
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
DriverObject = DeviceExtension->DriverObject;
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
TRACE_(VIDEOPRT, "VideoPortGetAccessRanges\n"); if (NumRequestedResources == 0)
{
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); AllocatedResources = DeviceExtension->AllocatedResources;
DriverObject = DeviceExtension->DriverObject; if (AllocatedResources == NULL &&
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject); DeviceExtension->AdapterInterfaceType == PCIBus)
{
if (NumRequestedResources == 0) if (DeviceExtension->PhysicalDeviceObject != NULL)
{
AllocatedResources = DeviceExtension->AllocatedResources;
if (AllocatedResources == NULL &&
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_NOT_ENOUGH_MEMORY; 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_NOT_ENOUGH_MEMORY;
}
} }
} else
else
{
VendorIdToFind = VendorId != NULL ? *(PUSHORT)VendorId : 0;
DeviceIdToFind = DeviceId != NULL ? *(PUSHORT)DeviceId : 0;
if (VendorIdToFind == 0 && DeviceIdToFind == 0)
{ {
/* We're screwed */ VendorIdToFind = VendorId != NULL ? *(PUSHORT)VendorId : 0;
return ERROR_DEV_NOT_EXIST; DeviceIdToFind = DeviceId != NULL ? *(PUSHORT)DeviceId : 0;
if (VendorIdToFind == 0 && DeviceIdToFind == 0)
{
/* We're screwed */
return ERROR_DEV_NOT_EXIST;
}
INFO_(VIDEOPRT, "Looking for VendorId 0x%04x DeviceId 0x%04x\n",
VendorIdToFind, DeviceIdToFind);
/*
* Search for the device id and vendor id on this bus.
*/
for (DeviceNumber = 0; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
{
PciSlotNumber.u.bits.DeviceNumber = DeviceNumber;
for (FunctionNumber = 0; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
{
INFO_(VIDEOPRT, "- Function number: %d\n", FunctionNumber);
PciSlotNumber.u.bits.FunctionNumber = FunctionNumber;
ReturnedLength = HalGetBusData(PCIConfiguration,
DeviceExtension->SystemIoBusNumber,
PciSlotNumber.u.AsULONG,
&Config,
sizeof(PCI_COMMON_CONFIG));
INFO_(VIDEOPRT, "- Length of data: %x\n", ReturnedLength);
if (ReturnedLength == sizeof(PCI_COMMON_CONFIG))
{
INFO_(VIDEOPRT, "- 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))
{
DeviceAndVendorFound = TRUE;
break;
}
}
}
if (DeviceAndVendorFound) break;
}
if (FunctionNumber == PCI_MAX_FUNCTION)
{
WARN_(VIDEOPRT, "Didn't find device.\n");
return ERROR_DEV_NOT_EXIST;
}
} }
INFO_(VIDEOPRT, "Looking for VendorId 0x%04x DeviceId 0x%04x\n", Status = HalAssignSlotResources(&DeviceExtension->RegistryPath,
VendorIdToFind, DeviceIdToFind); NULL,
DeviceExtension->DriverObject,
/* DeviceExtension->DriverObject->DeviceObject,
* Search for the device id and vendor id on this bus. DeviceExtension->AdapterInterfaceType,
*/ DeviceExtension->SystemIoBusNumber,
for (DeviceNumber = 0; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++) PciSlotNumber.u.AsULONG,
&AllocatedResources);
if (!NT_SUCCESS(Status))
{ {
PciSlotNumber.u.bits.DeviceNumber = DeviceNumber; WARN_(VIDEOPRT, "HalAssignSlotResources failed with status %x.\n",Status);
for (FunctionNumber = 0; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++) return Status;
{
INFO_(VIDEOPRT, "- Function number: %d\n", FunctionNumber);
PciSlotNumber.u.bits.FunctionNumber = FunctionNumber;
ReturnedLength = HalGetBusData(
PCIConfiguration,
DeviceExtension->SystemIoBusNumber,
PciSlotNumber.u.AsULONG,
&Config,
sizeof(PCI_COMMON_CONFIG));
INFO_(VIDEOPRT, "- Length of data: %x\n", ReturnedLength);
if (ReturnedLength == sizeof(PCI_COMMON_CONFIG))
{
INFO_(VIDEOPRT, "- 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))
{
DeviceAndVendorFound = TRUE;
break;
}
}
}
if (DeviceAndVendorFound) break;
} }
if (FunctionNumber == PCI_MAX_FUNCTION) DeviceExtension->AllocatedResources = AllocatedResources;
{ }
WARN_(VIDEOPRT, "Didn't find device.\n"); }
return ERROR_DEV_NOT_EXIST; else
} {
} ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) + (NumRequestedResources - 1) * sizeof(IO_RESOURCE_DESCRIPTOR);
ResReqList = ExAllocatePool(NonPagedPool, ListSize);
if (!ResReqList) return ERROR_NOT_ENOUGH_MEMORY;
ResReqList->ListSize = ListSize;
ResReqList->InterfaceType = DeviceExtension->AdapterInterfaceType;
ResReqList->BusNumber = DeviceExtension->SystemIoBusNumber;
ResReqList->SlotNumber = DeviceExtension->SystemIoSlotNumber;
ResReqList->AlternativeLists = 1;
ResReqList->List[0].Version = 1;
ResReqList->List[0].Revision = 1;
ResReqList->List[0].Count = NumRequestedResources;
/* Copy in the caller's resource list */
RtlCopyMemory(ResReqList->List[0].Descriptors,
RequestedResources,
NumRequestedResources * sizeof(IO_RESOURCE_DESCRIPTOR));
Status = IoAssignResources(&DeviceExtension->RegistryPath,
NULL,
DeviceExtension->DriverObject,
DeviceExtension->PhysicalDeviceObject ?
DeviceExtension->PhysicalDeviceObject :
DeviceExtension->DriverObject->DeviceObject,
ResReqList,
&AllocatedResources);
Status = HalAssignSlotResources( if (!NT_SUCCESS(Status))
&DeviceExtension->RegistryPath,
NULL,
DeviceExtension->DriverObject,
DeviceExtension->DriverObject->DeviceObject,
DeviceExtension->AdapterInterfaceType,
DeviceExtension->SystemIoBusNumber,
PciSlotNumber.u.AsULONG,
&AllocatedResources);
if (!NT_SUCCESS(Status))
{
WARN_(VIDEOPRT, "HalAssignSlotResources failed with status %x.\n",Status);
return Status; return Status;
}
DeviceExtension->AllocatedResources = AllocatedResources; if (!DeviceExtension->AllocatedResources)
DeviceExtension->AllocatedResources = AllocatedResources;
/* Return the slot number if the caller wants it */ }
if (Slot != NULL) *Slot = PciSlotNumber.u.AsULONG;
if (AllocatedResources == NULL)
} return ERROR_NOT_ENOUGH_MEMORY;
if (AllocatedResources == NULL)
return ERROR_NOT_ENOUGH_MEMORY; /* Return the slot number if the caller wants it */
Status = IntVideoPortGetLegacyResources(DriverExtension, DeviceExtension, if (Slot != NULL) *Slot = DeviceExtension->SystemIoBusNumber;
&LegacyAccessRanges, &LegacyAccessRangeCount);
if (!NT_SUCCESS(Status)) Status = IntVideoPortGetLegacyResources(DriverExtension, DeviceExtension,
return ERROR_DEV_NOT_EXIST; &LegacyAccessRanges, &LegacyAccessRangeCount);
if (NumAccessRanges < LegacyAccessRangeCount) if (!NT_SUCCESS(Status))
return ERROR_NOT_ENOUGH_MEMORY; return ERROR_DEV_NOT_EXIST;
RtlCopyMemory(AccessRanges, LegacyAccessRanges, LegacyAccessRangeCount * sizeof(VIDEO_ACCESS_RANGE)); if (NumAccessRanges < LegacyAccessRangeCount)
AssignedCount = LegacyAccessRangeCount; return ERROR_NOT_ENOUGH_MEMORY;
for (FullList = AllocatedResources->List; RtlCopyMemory(AccessRanges, LegacyAccessRanges, LegacyAccessRangeCount * sizeof(VIDEO_ACCESS_RANGE));
FullList < AllocatedResources->List + AllocatedResources->Count; AssignedCount = LegacyAccessRangeCount;
FullList++) for (FullList = AllocatedResources->List;
{ FullList < AllocatedResources->List + AllocatedResources->Count;
INFO_(VIDEOPRT, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n", FullList++)
FullList->InterfaceType, FullList->BusNumber, DeviceExtension->SystemIoBusNumber, FullList->PartialResourceList.Version, FullList->PartialResourceList.Revision); {
INFO_(VIDEOPRT, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n",
ASSERT(FullList->InterfaceType == PCIBus); FullList->InterfaceType, FullList->BusNumber, DeviceExtension->SystemIoBusNumber, FullList->PartialResourceList.Version, FullList->PartialResourceList.Revision);
ASSERT(FullList->BusNumber == DeviceExtension->SystemIoBusNumber);
ASSERT(1 == FullList->PartialResourceList.Version); ASSERT(FullList->InterfaceType == PCIBus);
ASSERT(1 == FullList->PartialResourceList.Revision); ASSERT(FullList->BusNumber == DeviceExtension->SystemIoBusNumber);
for (Descriptor = FullList->PartialResourceList.PartialDescriptors; ASSERT(1 == FullList->PartialResourceList.Version);
Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count; ASSERT(1 == FullList->PartialResourceList.Revision);
Descriptor++) for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
{ Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
Descriptor++)
{
if ((Descriptor->Type == CmResourceTypeMemory || if ((Descriptor->Type == CmResourceTypeMemory ||
Descriptor->Type == CmResourceTypePort) && Descriptor->Type == CmResourceTypePort) &&
AssignedCount >= NumAccessRanges) AssignedCount >= NumAccessRanges)
{ {
WARN_(VIDEOPRT, "Too many access ranges found\n"); WARN_(VIDEOPRT, "Too many access ranges found\n");
return ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY;
} }
if (Descriptor->Type == CmResourceTypeMemory) if (Descriptor->Type == CmResourceTypeMemory)
{ {
INFO_(VIDEOPRT, "Memory range starting at 0x%08x length 0x%08x\n", INFO_(VIDEOPRT, "Memory range starting at 0x%08x length 0x%08x\n",
Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length); Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
AccessRanges[AssignedCount].RangeStart = Descriptor->u.Memory.Start; AccessRanges[AssignedCount].RangeStart = Descriptor->u.Memory.Start;
AccessRanges[AssignedCount].RangeLength = Descriptor->u.Memory.Length; AccessRanges[AssignedCount].RangeLength = Descriptor->u.Memory.Length;
AccessRanges[AssignedCount].RangeInIoSpace = 0; AccessRanges[AssignedCount].RangeInIoSpace = 0;
AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */ AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
AccessRanges[AssignedCount].RangeShareable = AccessRanges[AssignedCount].RangeShareable =
(Descriptor->ShareDisposition == CmResourceShareShared); (Descriptor->ShareDisposition == CmResourceShareShared);
AccessRanges[AssignedCount].RangePassive = 0; AccessRanges[AssignedCount].RangePassive = 0;
AssignedCount++; AssignedCount++;
} }
else if (Descriptor->Type == CmResourceTypePort) else if (Descriptor->Type == CmResourceTypePort)
{ {
INFO_(VIDEOPRT, "Port range starting at 0x%04x length %d\n", INFO_(VIDEOPRT, "Port range starting at 0x%04x length %d\n",
Descriptor->u.Port.Start.u.LowPart, Descriptor->u.Port.Length); Descriptor->u.Port.Start.u.LowPart, Descriptor->u.Port.Length);
AccessRanges[AssignedCount].RangeStart = Descriptor->u.Port.Start; AccessRanges[AssignedCount].RangeStart = Descriptor->u.Port.Start;
AccessRanges[AssignedCount].RangeLength = Descriptor->u.Port.Length; AccessRanges[AssignedCount].RangeLength = Descriptor->u.Port.Length;
AccessRanges[AssignedCount].RangeInIoSpace = 1; AccessRanges[AssignedCount].RangeInIoSpace = 1;
AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */ AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
AccessRanges[AssignedCount].RangeShareable = AccessRanges[AssignedCount].RangeShareable =
(Descriptor->ShareDisposition == CmResourceShareShared); (Descriptor->ShareDisposition == CmResourceShareShared);
AccessRanges[AssignedCount].RangePassive = 0; AccessRanges[AssignedCount].RangePassive = 0;
if (Descriptor->Flags & CM_RESOURCE_PORT_10_BIT_DECODE) if (Descriptor->Flags & CM_RESOURCE_PORT_10_BIT_DECODE)
AccessRanges[AssignedCount].RangePassive |= VIDEO_RANGE_10_BIT_DECODE; AccessRanges[AssignedCount].RangePassive |= VIDEO_RANGE_10_BIT_DECODE;
if (Descriptor->Flags & CM_RESOURCE_PORT_PASSIVE_DECODE) if (Descriptor->Flags & CM_RESOURCE_PORT_PASSIVE_DECODE)
AccessRanges[AssignedCount].RangePassive |= VIDEO_RANGE_PASSIVE_DECODE; AccessRanges[AssignedCount].RangePassive |= VIDEO_RANGE_PASSIVE_DECODE;
AssignedCount++; AssignedCount++;
} }
else if (Descriptor->Type == CmResourceTypeInterrupt) else if (Descriptor->Type == CmResourceTypeInterrupt)
{ {
DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level; DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector; DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
if (Descriptor->ShareDisposition == CmResourceShareShared) if (Descriptor->ShareDisposition == CmResourceShareShared)
DeviceExtension->InterruptShared = TRUE; DeviceExtension->InterruptShared = TRUE;
else else
DeviceExtension->InterruptShared = FALSE; DeviceExtension->InterruptShared = FALSE;
} }
} }
} }
}
else
{
UNIMPLEMENTED
}
return NO_ERROR; return NO_ERROR;
} }