From b22c128070db97a76b27a0d6fbacf2fc2558ce4e Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 17 Oct 2017 00:05:26 +0200 Subject: [PATCH] [STORPORT] Implement StorPortGetDeviceBase(). CORE-13866 --- drivers/storage/port/storport/misc.c | 104 +++++++++++++++++++++++ drivers/storage/port/storport/precomp.h | 29 +++++-- drivers/storage/port/storport/storport.c | 65 ++++++++++++-- 3 files changed, 188 insertions(+), 10 deletions(-) diff --git a/drivers/storage/port/storport/misc.c b/drivers/storage/port/storport/misc.c index bcbdb05912a60..56b7c6fd3d1af 100644 --- a/drivers/storage/port/storport/misc.c +++ b/drivers/storage/port/storport/misc.c @@ -217,4 +217,108 @@ QueryBusInterface( return Status; } + +BOOLEAN +TranslateResourceListAddress( + PFDO_DEVICE_EXTENSION DeviceExtension, + INTERFACE_TYPE BusType, + ULONG SystemIoBusNumber, + STOR_PHYSICAL_ADDRESS IoAddress, + ULONG NumberOfBytes, + BOOLEAN InIoSpace, + PPHYSICAL_ADDRESS TranslatedAddress) +{ + PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptorA, FullDescriptorT; + PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorA, PartialDescriptorT; + INT i, j; + + DPRINT1("TranslateResourceListAddress(%p)\n", DeviceExtension); + + FullDescriptorA = DeviceExtension->AllocatedResources->List; + FullDescriptorT = DeviceExtension->TranslatedResources->List; + for (i = 0; i < DeviceExtension->AllocatedResources->Count; i++) + { + for (j = 0; j < FullDescriptorA->PartialResourceList.Count; j++) + { + PartialDescriptorA = FullDescriptorA->PartialResourceList.PartialDescriptors + j; + PartialDescriptorT = FullDescriptorT->PartialResourceList.PartialDescriptors + j; + + switch (PartialDescriptorA->Type) + { + case CmResourceTypePort: + DPRINT1("Port: 0x%I64x (0x%lx)\n", + PartialDescriptorA->u.Port.Start.QuadPart, + PartialDescriptorA->u.Port.Length); + if (InIoSpace && + IoAddress.QuadPart >= PartialDescriptorA->u.Port.Start.QuadPart && + IoAddress.QuadPart + NumberOfBytes <= PartialDescriptorA->u.Port.Start.QuadPart + PartialDescriptorA->u.Port.Length) + { + TranslatedAddress->QuadPart = PartialDescriptorT->u.Port.Start.QuadPart + + (IoAddress.QuadPart - PartialDescriptorA->u.Port.Start.QuadPart); + return TRUE; + } + break; + + case CmResourceTypeMemory: + DPRINT1("Memory: 0x%I64x (0x%lx)\n", + PartialDescriptorA->u.Memory.Start.QuadPart, + PartialDescriptorA->u.Memory.Length); + if (!InIoSpace && + IoAddress.QuadPart >= PartialDescriptorA->u.Memory.Start.QuadPart && + IoAddress.QuadPart + NumberOfBytes <= PartialDescriptorA->u.Memory.Start.QuadPart + PartialDescriptorA->u.Memory.Length) + { + TranslatedAddress->QuadPart = PartialDescriptorT->u.Memory.Start.QuadPart + + (IoAddress.QuadPart - PartialDescriptorA->u.Memory.Start.QuadPart); + return TRUE; + } + break; + } + } + + /* Advance to next CM_FULL_RESOURCE_DESCRIPTOR block in memory. */ + FullDescriptorA = (PCM_FULL_RESOURCE_DESCRIPTOR)(FullDescriptorA->PartialResourceList.PartialDescriptors + + FullDescriptorA->PartialResourceList.Count); + + FullDescriptorT = (PCM_FULL_RESOURCE_DESCRIPTOR)(FullDescriptorT->PartialResourceList.PartialDescriptors + + FullDescriptorT->PartialResourceList.Count); + } + + return FALSE; +} + + +NTSTATUS +AllocateAddressMapping( + PMAPPED_ADDRESS *MappedAddressList, + STOR_PHYSICAL_ADDRESS IoAddress, + PVOID MappedAddress, + ULONG NumberOfBytes, + ULONG BusNumber) +{ + PMAPPED_ADDRESS Mapping; + + DPRINT1("AllocateAddressMapping()\n"); + + Mapping = ExAllocatePoolWithTag(NonPagedPool, + sizeof(MAPPED_ADDRESS), + TAG_ADDRESS_MAPPING); + if (Mapping == NULL) + { + DPRINT1("No memory!\n"); + return STATUS_NO_MEMORY; + } + + RtlZeroMemory(Mapping, sizeof(MAPPED_ADDRESS)); + + Mapping->NextMappedAddress = *MappedAddressList; + *MappedAddressList = Mapping; + + Mapping->IoAddress = IoAddress; + Mapping->MappedAddress = MappedAddress; + Mapping->NumberOfBytes = NumberOfBytes; + Mapping->BusNumber = BusNumber; + + return STATUS_SUCCESS; +} + /* EOF */ diff --git a/drivers/storage/port/storport/precomp.h b/drivers/storage/port/storport/precomp.h index 1bbd70c00ef6a..30ca7fe78dcd1 100644 --- a/drivers/storage/port/storport/precomp.h +++ b/drivers/storage/port/storport/precomp.h @@ -23,11 +23,12 @@ #include /* Memory Tags */ -#define TAG_GLOBAL_DATA 'DGtS' -#define TAG_INIT_DATA 'DItS' -#define TAG_MINIPORT_DATA 'DMtS' -#define TAG_ACCRESS_RANGE 'RAtS' -#define TAG_RESOURCE_LIST 'LRtS' +#define TAG_GLOBAL_DATA 'DGtS' +#define TAG_INIT_DATA 'DItS' +#define TAG_MINIPORT_DATA 'DMtS' +#define TAG_ACCRESS_RANGE 'RAtS' +#define TAG_RESOURCE_LIST 'LRtS' +#define TAG_ADDRESS_MAPPING 'MAtS' typedef enum { @@ -95,6 +96,7 @@ typedef struct _FDO_DEVICE_EXTENSION PCM_RESOURCE_LIST TranslatedResources; BUS_INTERFACE_STANDARD BusInterface; BOOLEAN BusInitialized; + PMAPPED_ADDRESS MappedAddressList; } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; @@ -166,6 +168,23 @@ QueryBusInterface( PBUS_INTERFACE_STANDARD Interface, PVOID InterfaceSpecificData); +BOOLEAN +TranslateResourceListAddress( + PFDO_DEVICE_EXTENSION DeviceExtension, + INTERFACE_TYPE BusType, + ULONG SystemIoBusNumber, + STOR_PHYSICAL_ADDRESS IoAddress, + ULONG NumberOfBytes, + BOOLEAN InIoSpace, + PPHYSICAL_ADDRESS TranslatedAddress); + +NTSTATUS +AllocateAddressMapping( + PMAPPED_ADDRESS *MappedAddressList, + STOR_PHYSICAL_ADDRESS IoAddress, + PVOID MappedAddress, + ULONG NumberOfBytes, + ULONG BusNumber); /* pdo.c */ diff --git a/drivers/storage/port/storport/storport.c b/drivers/storage/port/storport/storport.c index 706b0b50e4999..d25064bba183d 100644 --- a/drivers/storage/port/storport/storport.c +++ b/drivers/storage/port/storport/storport.c @@ -528,7 +528,8 @@ StorPortFreeDeviceBase( _In_ PVOID HwDeviceExtension, _In_ PVOID MappedAddress) { - DPRINT1("StorPortFreeDeviceBase()\n"); + DPRINT1("StorPortFreeDeviceBase(%p %p)\n", + HwDeviceExtension, MappedAddress); } @@ -568,6 +569,7 @@ StorPortGetBusData( DPRINT1("StorPortGetBusData(%p %lu %lu %lu %p %lu)\n", DeviceExtension, BusDataType, SystemIoBusNumber, SlotNumber, Buffer, Length); + /* Get the miniport extension */ MiniportExtension = CONTAINING_RECORD(DeviceExtension, MINIPORT_DEVICE_EXTENSION, HwDeviceExtension); @@ -591,7 +593,7 @@ StorPortGetBusData( /* - * @unimplemented + * @implemented */ STORPORT_API PVOID @@ -604,9 +606,62 @@ StorPortGetDeviceBase( _In_ ULONG NumberOfBytes, _In_ BOOLEAN InIoSpace) { - DPRINT1("StorPortGetDeviceBase()\n"); - UNIMPLEMENTED; - return NULL; + PMINIPORT_DEVICE_EXTENSION MiniportExtension; + + PHYSICAL_ADDRESS TranslatedAddress; + PVOID MappedAddress; + NTSTATUS Status; + + DPRINT1("StorPortGetDeviceBase(%p %lu %lu 0x%I64x %lu %u)\n", + HwDeviceExtension, BusType, SystemIoBusNumber, IoAddress.QuadPart, NumberOfBytes, InIoSpace); + + /* Get the miniport extension */ + MiniportExtension = CONTAINING_RECORD(HwDeviceExtension, + MINIPORT_DEVICE_EXTENSION, + HwDeviceExtension); + DPRINT1("HwDeviceExtension %p MiniportExtension %p\n", + HwDeviceExtension, MiniportExtension); + + if (!TranslateResourceListAddress(MiniportExtension->Miniport->DeviceExtension, + BusType, + SystemIoBusNumber, + IoAddress, + NumberOfBytes, + InIoSpace, + &TranslatedAddress)) + { + DPRINT1("Checkpoint!\n"); + return NULL; + } + + DPRINT1("Translated Address: 0x%I64x\n", TranslatedAddress.QuadPart); + + /* In I/O space */ + if (InIoSpace) + { + DPRINT1("Translated Address: %p\n", (PVOID)(ULONG_PTR)TranslatedAddress.QuadPart); + return (PVOID)(ULONG_PTR)TranslatedAddress.QuadPart; + } + + /* In memory space */ + MappedAddress = MmMapIoSpace(TranslatedAddress, + NumberOfBytes, + FALSE); + DPRINT1("Mapped Address: %p\n", MappedAddress); + + Status = AllocateAddressMapping(&MiniportExtension->Miniport->DeviceExtension->MappedAddressList, + IoAddress, + MappedAddress, + NumberOfBytes, + SystemIoBusNumber); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Checkpoint!\n"); + MappedAddress = NULL; + } + + DPRINT1("Mapped Address: %p\n", MappedAddress); + return MappedAddress; }