[STORPORT] Implement StorPortGetDeviceBase().
authorEric Kohl <eric.kohl@reactos.org>
Mon, 16 Oct 2017 22:05:26 +0000 (00:05 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 16 Oct 2017 22:05:26 +0000 (00:05 +0200)
CORE-13866

drivers/storage/port/storport/misc.c
drivers/storage/port/storport/precomp.h
drivers/storage/port/storport/storport.c

index bcbdb05..56b7c6f 100644 (file)
@@ -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 */
index 1bbd70c..30ca7fe 100644 (file)
 #include <wdmguid.h>
 
 /* 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 */
 
index 706b0b5..d25064b 100644 (file)
@@ -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;
 }