https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5cfc1e31527f9e8a56fee8b7e2462670f95606b9

commit 5cfc1e31527f9e8a56fee8b7e2462670f95606b9
Author: Eric Kohl <[email protected]>
AuthorDate: Mon Oct 23 23:21:58 2017 +0200

    [STORPORT] Get the interrupt from the resource list, connect it and call 
the miniports HwInterrupt routine.
    CORE-13866
---
 drivers/storage/port/storport/fdo.c      | 88 ++++++++++++++++++++++++++++++++
 drivers/storage/port/storport/miniport.c | 16 ++++++
 drivers/storage/port/storport/misc.c     | 49 ++++++++++++++++++
 drivers/storage/port/storport/precomp.h  | 14 +++++
 4 files changed, 167 insertions(+)

diff --git a/drivers/storage/port/storport/fdo.c 
b/drivers/storage/port/storport/fdo.c
index 9072971a91..3c49619b23 100644
--- a/drivers/storage/port/storport/fdo.c
+++ b/drivers/storage/port/storport/fdo.c
@@ -15,6 +15,90 @@
 
 /* FUNCTIONS 
******************************************************************/
 
+static
+BOOLEAN
+NTAPI
+PortFdoInterruptRoutine(
+    _In_ PKINTERRUPT Interrupt,
+    _In_ PVOID ServiceContext)
+{
+    PFDO_DEVICE_EXTENSION DeviceExtension;
+
+    DPRINT1("PortFdoInterruptRoutine(%p %p)\n",
+            Interrupt, ServiceContext);
+
+    DeviceExtension = (PFDO_DEVICE_EXTENSION)ServiceContext;
+
+    return MiniportHwInterrupt(&DeviceExtension->Miniport);
+}
+
+
+static
+NTSTATUS
+PortFdoConnectInterrupt(
+    _In_ PFDO_DEVICE_EXTENSION DeviceExtension)
+{
+    ULONG Vector;
+    KIRQL Irql;
+    KINTERRUPT_MODE InterruptMode;
+    BOOLEAN ShareVector;
+    KAFFINITY Affinity;
+    NTSTATUS Status;
+
+    DPRINT1("PortFdoConnectInterrupt(%p)\n",
+            DeviceExtension);
+
+    /* No resources, no interrupt. Done! */
+    if (DeviceExtension->AllocatedResources == NULL ||
+        DeviceExtension->TranslatedResources == NULL)
+    {
+        DPRINT1("Checkpoint\n");
+        return STATUS_SUCCESS;
+    }
+
+    /* Get the interrupt data from the resource list */
+    Status = GetResourceListInterrupt(DeviceExtension,
+                                      &Vector,
+                                      &Irql,
+                                      &InterruptMode,
+                                      &ShareVector,
+                                      &Affinity);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("GetResourceListInterrupt() failed (Status 0x%08lx)\n", 
Status);
+        return Status;
+    }
+
+    DPRINT1("Vector: %lu\n", Vector);
+    DPRINT1("Irql: %lu\n", Irql);
+
+    DPRINT1("Affinity: 0x%08lx\n", Affinity);
+
+    /* Connect the interrupt */
+    Status = IoConnectInterrupt(&DeviceExtension->Interrupt,
+                                PortFdoInterruptRoutine,
+                                DeviceExtension,
+                                NULL,
+                                Vector,
+                                Irql,
+                                Irql,
+                                InterruptMode,
+                                ShareVector,
+                                Affinity,
+                                FALSE);
+    if (NT_SUCCESS(Status))
+    {
+        DeviceExtension->InterruptIrql = Irql;
+    }
+    else
+    {
+        DPRINT1("IoConnectInterrupt() failed (Status 0x%08lx)\n", Status);
+    }
+
+    return Status;
+}
+
+
 static
 NTSTATUS
 PortFdoStartMiniport(
@@ -55,6 +139,10 @@ PortFdoStartMiniport(
         return Status;
     }
 
+
+    Status = PortFdoConnectInterrupt(DeviceExtension);
+
+
     /* Call the miniports HwInitialize function */
     Status = MiniportHwInitialize(&DeviceExtension->Miniport);
     if (!NT_SUCCESS(Status))
diff --git a/drivers/storage/port/storport/miniport.c 
b/drivers/storage/port/storport/miniport.c
index c13a3f37a5..815e609031 100644
--- a/drivers/storage/port/storport/miniport.c
+++ b/drivers/storage/port/storport/miniport.c
@@ -346,4 +346,20 @@ MiniportHwInitialize(
     return Result ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
 }
 
+
+BOOLEAN
+MiniportHwInterrupt(
+    _In_ PMINIPORT Miniport)
+{
+    BOOLEAN Result;
+
+    DPRINT1("MiniportHwInterrupt(%p)\n",
+            Miniport);
+
+    Result = 
Miniport->InitData->HwInterrupt(&Miniport->MiniportExtension->HwDeviceExtension);
+    DPRINT1("HwInterrupt() returned %u\n", Result);
+
+    return Result;
+}
+
 /* EOF */
diff --git a/drivers/storage/port/storport/misc.c 
b/drivers/storage/port/storport/misc.c
index 7710201876..f74fd3516f 100644
--- a/drivers/storage/port/storport/misc.c
+++ b/drivers/storage/port/storport/misc.c
@@ -287,6 +287,55 @@ TranslateResourceListAddress(
 }
 
 
+NTSTATUS
+GetResourceListInterrupt(
+    PFDO_DEVICE_EXTENSION DeviceExtension,
+    PULONG Vector,
+    PKIRQL Irql,
+    KINTERRUPT_MODE *InterruptMode,
+    PBOOLEAN ShareVector,
+    PKAFFINITY Affinity)
+{
+    PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+    INT i, j;
+
+    DPRINT1("GetResourceListInterrupt(%p)\n",
+            DeviceExtension);
+
+    FullDescriptor = DeviceExtension->TranslatedResources->List;
+    for (i = 0; i < DeviceExtension->TranslatedResources->Count; i++)
+    {
+        for (j = 0; j < FullDescriptor->PartialResourceList.Count; j++)
+        {
+            PartialDescriptor = 
FullDescriptor->PartialResourceList.PartialDescriptors + j;
+
+            switch (PartialDescriptor->Type)
+            {
+                case CmResourceTypeInterrupt:
+                    DPRINT1("Interrupt: Level %lu  Vector %lu\n",
+                            PartialDescriptor->u.Interrupt.Level,
+                            PartialDescriptor->u.Interrupt.Vector);
+
+                    *Vector = PartialDescriptor->u.Interrupt.Vector;
+                    *Irql = (KIRQL)PartialDescriptor->u.Interrupt.Level;
+                    *InterruptMode = (PartialDescriptor->Flags & 
CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;
+                    *ShareVector = (PartialDescriptor->ShareDisposition == 
CmResourceShareShared) ? TRUE : FALSE;
+                    *Affinity = PartialDescriptor->u.Interrupt.Affinity;
+
+                    return STATUS_SUCCESS;
+            }
+        }
+
+        /* Advance to next CM_FULL_RESOURCE_DESCRIPTOR block in memory. */
+        FullDescriptor = 
(PCM_FULL_RESOURCE_DESCRIPTOR)(FullDescriptor->PartialResourceList.PartialDescriptors
 + 
+                                                        
FullDescriptor->PartialResourceList.Count);
+    }
+
+    return STATUS_NOT_FOUND;
+}
+
+
 NTSTATUS
 AllocateAddressMapping(
     PMAPPED_ADDRESS *MappedAddressList,
diff --git a/drivers/storage/port/storport/precomp.h 
b/drivers/storage/port/storport/precomp.h
index 168c318544..5bd16f338f 100644
--- a/drivers/storage/port/storport/precomp.h
+++ b/drivers/storage/port/storport/precomp.h
@@ -101,6 +101,8 @@ typedef struct _FDO_DEVICE_EXTENSION
     PHYSICAL_ADDRESS UncachedExtensionPhysicalBase;
     ULONG UncachedExtensionSize;
     PHW_PASSIVE_INITIALIZE_ROUTINE HwPassiveInitRoutine;
+    PKINTERRUPT Interrupt;
+    ULONG InterruptIrql;
 } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
 
 
@@ -140,6 +142,9 @@ NTSTATUS
 MiniportHwInitialize(
     _In_ PMINIPORT Miniport);
 
+BOOLEAN
+MiniportHwInterrupt(
+    _In_ PMINIPORT Miniport);
 
 /* misc.c */
 
@@ -182,6 +187,15 @@ TranslateResourceListAddress(
     BOOLEAN InIoSpace,
     PPHYSICAL_ADDRESS TranslatedAddress);
 
+NTSTATUS
+GetResourceListInterrupt(
+    PFDO_DEVICE_EXTENSION DeviceExtension,
+    PULONG Vector,
+    PKIRQL Irql,
+    KINTERRUPT_MODE *InterruptMode,
+    PBOOLEAN ShareVector,
+    PKAFFINITY Affinity);
+
 NTSTATUS
 AllocateAddressMapping(
     PMAPPED_ADDRESS *MappedAddressList,

Reply via email to