[STORPORT] Initialize a miniport object and call the miniport HwFindAdapter and HwIni...
authorEric Kohl <eric.kohl@reactos.org>
Sat, 14 Oct 2017 17:12:24 +0000 (19:12 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 14 Oct 2017 17:12:24 +0000 (19:12 +0200)
CORE-13866

drivers/storage/port/storport/CMakeLists.txt
drivers/storage/port/storport/fdo.c
drivers/storage/port/storport/guid.c [new file with mode: 0644]
drivers/storage/port/storport/miniport.c [new file with mode: 0644]
drivers/storage/port/storport/misc.c
drivers/storage/port/storport/precomp.h
drivers/storage/port/storport/storport.c
drivers/storage/port/storport/storport.rc

index c531ee6..25b35a5 100644 (file)
@@ -3,6 +3,7 @@ spec2def(storport.sys storport.spec ADD_IMPORTLIB)
 
 list(APPEND SOURCE
     fdo.c
+    miniport.c
     misc.c
     pdo.c
     storport.c
@@ -11,6 +12,7 @@ list(APPEND SOURCE
 
 add_library(storport SHARED
     ${SOURCE}
+    guid.c
     storport.rc
     ${CMAKE_CURRENT_BINARY_DIR}/storport.def)
 
index c8508d0..be6b693 100644 (file)
 
 /* FUNCTIONS ******************************************************************/
 
+static
+NTSTATUS
+PortFdoStartMiniport(
+    _In_ PFDO_DEVICE_EXTENSION DeviceExtension)
+{
+    PHW_INITIALIZATION_DATA InitData;
+    INTERFACE_TYPE InterfaceType;
+    NTSTATUS Status;
+
+    DPRINT1("PortFdoStartDevice(%p)\n", DeviceExtension);
+
+    /* Get the interface type of the lower device */
+    InterfaceType = GetBusInterface(DeviceExtension->LowerDevice);
+    if (InterfaceType == InterfaceTypeUndefined)
+        return STATUS_NO_SUCH_DEVICE;
+
+    /* Get the driver init data for the given interface type */
+    InitData = PortGetDriverInitData(DeviceExtension->DriverExtension,
+                                     InterfaceType);
+    if (InitData == NULL)
+        return STATUS_NO_SUCH_DEVICE;
+
+    /* Initialize the miniport */
+    MiniportInitialize(&DeviceExtension->Miniport,
+                       DeviceExtension,
+                       InitData);
+
+    /* Call the miniports FindAdapter function */
+    Status = MiniportFindAdapter(&DeviceExtension->Miniport);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("MiniportFindAdapter() failed (Status 0x%08lx)\n", Status);
+        return Status;
+    }
+
+    /* Call the miniports HwInitialize function */
+    Status = MiniportHwInitialize(&DeviceExtension->Miniport);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("MiniportHwInitialize() failed (Status 0x%08lx)\n", Status);
+        return Status;
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
 static
 NTSTATUS
 NTAPI
@@ -22,12 +69,36 @@ PortFdoStartDevice(
     _In_ PFDO_DEVICE_EXTENSION DeviceExtension,
     _In_ PIRP Irp)
 {
+    NTSTATUS Status;
+
     DPRINT1("PortFdoStartDevice(%p %p)\n",
             DeviceExtension, Irp);
 
     ASSERT(DeviceExtension->ExtensionType == FdoExtension);
 
-    return STATUS_SUCCESS;
+    /* Start the lower device if the FDO is in 'stopped' state */
+    if (DeviceExtension->PnpState == dsStopped)
+    {
+        Status = ForwardIrpAndWait(DeviceExtension->LowerDevice, Irp);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("ForwardIrpAndWait() failed (Status 0x%08lx)\n", Status);
+            return Status;
+        }
+    }
+
+    /* Change to the 'started' state */
+    DeviceExtension->PnpState = dsStarted;
+
+    /* Start the miniport (FindAdapter & Initialize) */
+    Status = PortFdoStartMiniport(DeviceExtension);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("FdoStartMiniport() failed (Status 0x%08lx)\n", Status);
+        DeviceExtension->PnpState = dsStopped;
+    }
+
+    return Status;
 }
 
 
@@ -72,12 +143,7 @@ PortFdoPnp(
     {
         case IRP_MN_START_DEVICE: /* 0x00 */
             DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
-            /* Call lower driver */
-            Status = ForwardIrpAndWait(DeviceExtension->LowerDevice, Irp);
-            if (NT_SUCCESS(Status))
-            {
-                Status = PortFdoStartDevice(DeviceExtension, Irp);
-            }
+            Status = PortFdoStartDevice(DeviceExtension, Irp);
             break;
 
         case IRP_MN_QUERY_REMOVE_DEVICE: /* 0x01 */
diff --git a/drivers/storage/port/storport/guid.c b/drivers/storage/port/storport/guid.c
new file mode 100644 (file)
index 0000000..757901b
--- /dev/null
@@ -0,0 +1,11 @@
+/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */
+
+#include <ntdef.h>
+#include <initguid.h>
+#include <ioevent.h>
+#include <wdmguid.h>
+
+#define DEVICE_TYPE ULONG
+#include <ntddstor.h>
+
+/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */
diff --git a/drivers/storage/port/storport/miniport.c b/drivers/storage/port/storport/miniport.c
new file mode 100644 (file)
index 0000000..8e1346f
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * PROJECT:     ReactOS Storport Driver
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Miniport interface code
+ * COPYRIGHT:   Copyright 2017 Eric Kohl (eric.kohl@reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+MiniportInitialize(
+    _In_ PMINIPORT Miniport,
+    _In_ PFDO_DEVICE_EXTENSION DeviceExtension,
+    _In_ PHW_INITIALIZATION_DATA InitData)
+{
+    Miniport->DeviceExtension = DeviceExtension;
+    Miniport->InitData = InitData;
+}
+
+
+NTSTATUS
+MiniportFindAdapter(
+    _In_ PMINIPORT Miniport)
+{
+    BOOLEAN Reserved = FALSE;
+    ULONG Result;
+    NTSTATUS Status;
+
+    DPRINT1("MiniportFindAdapter(%p)\n", Miniport);
+
+    Result = Miniport->InitData->HwFindAdapter(NULL,
+                                               NULL,
+                                               NULL,
+                                               NULL,
+                                               NULL,
+                                               &Reserved);
+    DPRINT1("HwFindAdapter() returned %lu\n", Result);
+
+    switch (Result)
+    {
+        case SP_RETURN_NOT_FOUND:
+            DPRINT1("SP_RETURN_NOT_FOUND\n");
+            Status = STATUS_NOT_FOUND;
+            break;
+
+        case SP_RETURN_FOUND:
+            DPRINT1("SP_RETURN_FOUND\n");
+            Status = STATUS_SUCCESS;
+            break;
+
+        case SP_RETURN_ERROR:
+            DPRINT1("SP_RETURN_ERROR\n");
+            Status = STATUS_ADAPTER_HARDWARE_ERROR;
+            break;
+
+        case SP_RETURN_BAD_CONFIG:
+            DPRINT1("SP_RETURN_BAD_CONFIG\n");
+            Status = STATUS_DEVICE_CONFIGURATION_ERROR;
+            break;
+
+        default:
+            DPRINT1("Unknown result: %lu\n", Result);
+            Status = STATUS_INTERNAL_ERROR;
+            break;
+    }
+
+    return Status;
+}
+
+
+NTSTATUS
+MiniportHwInitialize(
+    _In_ PMINIPORT Miniport)
+{
+    NTSTATUS Status;
+
+    DPRINT1("MiniportHwInitialize(%p)\n", Miniport);
+
+    Status = Miniport->InitData->HwInitialize(NULL);
+    DPRINT1("HwInitialize() returned 0x%08lx\n", Status);
+
+    return Status;
+}
+
+/* EOF */
index 3f2e254..54832c4 100644 (file)
@@ -68,4 +68,31 @@ ForwardIrpAndForget(
     return IoCallDriver(LowerDevice, Irp);
 }
 
+
+INTERFACE_TYPE
+GetBusInterface(
+    PDEVICE_OBJECT DeviceObject)
+{
+    GUID Guid;
+    ULONG Length;
+    NTSTATUS Status;
+
+    Status = IoGetDeviceProperty(DeviceObject,
+                                 DevicePropertyBusTypeGuid,
+                                 sizeof(Guid),
+                                 &Guid,
+                                 &Length);
+    if (!NT_SUCCESS(Status))
+        return InterfaceTypeUndefined;
+
+    if (RtlCompareMemory(&Guid, &GUID_BUS_TYPE_PCMCIA, sizeof(GUID)) == sizeof(GUID))
+        return PCMCIABus;
+    else if (RtlCompareMemory(&Guid, &GUID_BUS_TYPE_PCI, sizeof(GUID)) == sizeof(GUID))
+        return PCIBus;
+    else if (RtlCompareMemory(&Guid, &GUID_BUS_TYPE_ISAPNP, sizeof(GUID)) == sizeof(GUID))
+        return PNPISABus;
+
+    return InterfaceTypeUndefined;
+}
+
 /* EOF */
index 68c59ba..fc1224e 100644 (file)
@@ -11,6 +11,7 @@
 #include <wdm.h>
 #include <ntddk.h>
 #include <stdio.h>
+#include <memory.h>
 
 /* Declare STORPORT_API functions as exports rather than imports */
 #define _STORPORT_
 #include <ntddscsi.h>
 #include <ntdddisk.h>
 #include <mountdev.h>
+#include <wdmguid.h>
+
+/* Memory Tags */
+#define TAG_GLOBAL_DATA 'DGtS'
+#define TAG_INIT_DATA   'DItS'
 
 typedef enum
 {
@@ -37,18 +43,30 @@ typedef enum
     PdoExtension
 } EXTENSION_TYPE;
 
+typedef struct _DRIVER_INIT_DATA
+{
+    LIST_ENTRY Entry;
+    HW_INITIALIZATION_DATA HwInitData;
+} DRIVER_INIT_DATA, *PDRIVER_INIT_DATA;
+
 typedef struct _DRIVER_OBJECT_EXTENSION
 {
     EXTENSION_TYPE ExtensionType;
-
     PDRIVER_OBJECT DriverObject;
 
     KSPIN_LOCK AdapterListLock;
     LIST_ENTRY AdapterListHead;
     ULONG AdapterCount;
 
+    LIST_ENTRY InitDataListHead;
 } DRIVER_OBJECT_EXTENSION, *PDRIVER_OBJECT_EXTENSION;
 
+typedef struct _MINIPORT
+{
+    struct _FDO_DEVICE_EXTENSION *DeviceExtension;
+    PHW_INITIALIZATION_DATA InitData;
+} MINIPORT, *PMINIPORT;
+
 typedef struct _FDO_DEVICE_EXTENSION
 {
     EXTENSION_TYPE ExtensionType;
@@ -57,9 +75,13 @@ typedef struct _FDO_DEVICE_EXTENSION
     PDEVICE_OBJECT LowerDevice;
     PDEVICE_OBJECT PhysicalDevice;
 
-    DEVICE_STATE PnpState;
+    PDRIVER_OBJECT_EXTENSION DriverExtension;
 
+    DEVICE_STATE PnpState;
     LIST_ENTRY AdapterListEntry;
+
+    MINIPORT Miniport;
+
 } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
 
 
@@ -83,6 +105,23 @@ PortFdoPnp(
     _In_ PIRP Irp);
 
 
+/* miniport.c */
+
+VOID
+MiniportInitialize(
+    _In_ PMINIPORT Miniport,
+    _In_ PFDO_DEVICE_EXTENSION DeviceExtension,
+    _In_ PHW_INITIALIZATION_DATA HwInitializationData);
+
+NTSTATUS
+MiniportFindAdapter(
+    _In_ PMINIPORT Miniport);
+
+NTSTATUS
+MiniportHwInitialize(
+    _In_ PMINIPORT Miniport);
+
+
 /* misc.c */
 
 NTSTATUS
@@ -96,6 +135,9 @@ ForwardIrpAndForget(
     _In_ PDEVICE_OBJECT LowerDevice,
     _In_ PIRP Irp);
 
+INTERFACE_TYPE
+GetBusInterface(
+    PDEVICE_OBJECT DeviceObject);
 
 /* pdo.c */
 
@@ -108,6 +150,11 @@ PortPdoPnp(
 
 /* storport.c */
 
+PHW_INITIALIZATION_DATA
+PortGetDriverInitData(
+    PDRIVER_OBJECT_EXTENSION DriverExtension,
+    INTERFACE_TYPE InterfaceType);
+
 NTSTATUS
 NTAPI
 DriverEntry(
index 9b227dd..3520bbf 100644 (file)
@@ -20,6 +20,86 @@ ULONG PortNumber = 0;
 
 /* FUNCTIONS ******************************************************************/
 
+static
+NTSTATUS
+PortAddDriverInitData(
+    PDRIVER_OBJECT_EXTENSION DriverExtension,
+    PHW_INITIALIZATION_DATA HwInitializationData)
+{
+    PDRIVER_INIT_DATA InitData;
+
+    DPRINT1("PortAddDriverInitData()\n");
+
+    InitData = ExAllocatePoolWithTag(NonPagedPool,
+                                     sizeof(DRIVER_INIT_DATA),
+                                     TAG_INIT_DATA);
+    if (InitData == NULL)
+        return STATUS_NO_MEMORY;
+
+    RtlCopyMemory(&InitData->HwInitData,
+                  HwInitializationData,
+                  sizeof(HW_INITIALIZATION_DATA));
+
+    InsertHeadList(&DriverExtension->InitDataListHead,
+                   &InitData->Entry);
+
+    return STATUS_SUCCESS;
+}
+
+
+static
+VOID
+PortDeleteDriverInitData(
+    PDRIVER_OBJECT_EXTENSION DriverExtension)
+{
+    PDRIVER_INIT_DATA InitData;
+    PLIST_ENTRY ListEntry;
+
+    DPRINT1("PortDeleteDriverInitData()\n");
+
+    ListEntry = DriverExtension->InitDataListHead.Flink;
+    while (ListEntry != &DriverExtension->InitDataListHead)
+    {
+        InitData = CONTAINING_RECORD(ListEntry,
+                                     DRIVER_INIT_DATA,
+                                     Entry);
+
+        RemoveEntryList(&InitData->Entry);
+
+        ExFreePoolWithTag(InitData,
+                          TAG_INIT_DATA);
+
+        ListEntry = DriverExtension->InitDataListHead.Flink;
+    }
+}
+
+
+PHW_INITIALIZATION_DATA
+PortGetDriverInitData(
+    PDRIVER_OBJECT_EXTENSION DriverExtension,
+    INTERFACE_TYPE InterfaceType)
+{
+    PDRIVER_INIT_DATA InitData;
+    PLIST_ENTRY ListEntry;
+
+    DPRINT1("PortGetDriverInitData()\n");
+
+    ListEntry = DriverExtension->InitDataListHead.Flink;
+    while (ListEntry != &DriverExtension->InitDataListHead)
+    {
+        InitData = CONTAINING_RECORD(ListEntry,
+                                     DRIVER_INIT_DATA,
+                                     Entry);
+        if (InitData->HwInitData.AdapterInterfaceType == InterfaceType)
+            return &InitData->HwInitData;
+
+        ListEntry = ListEntry->Flink;
+    }
+
+    return NULL;
+}
+
+
 static
 NTSTATUS
 NTAPI
@@ -96,6 +176,8 @@ PortAddDevice(
                                                        (PVOID)DriverEntry);
     ASSERT(DriverObjectExtension->ExtensionType == DriverExtension);
 
+    DeviceExtension->DriverExtension = DriverObjectExtension;
+
     KeAcquireInStackQueuedSpinLock(&DriverObjectExtension->AdapterListLock,
                                    &LockHandle);
 
@@ -120,8 +202,17 @@ NTAPI
 PortUnload(
     _In_ PDRIVER_OBJECT DriverObject)
 {
+    PDRIVER_OBJECT_EXTENSION DriverExtension;
+
     DPRINT1("PortUnload(%p)\n",
             DriverObject);
+
+    DriverExtension = IoGetDriverObjectExtension(DriverObject,
+                                                 (PVOID)DriverEntry);
+    if (DriverExtension != NULL)
+    {
+        PortDeleteDriverInitData(DriverExtension);
+    }
 }
 
 
@@ -138,7 +229,7 @@ PortDispatchCreate(
     Irp->IoStatus.Status = STATUS_SUCCESS;
     Irp->IoStatus.Information = FILE_OPENED;
 
-    IoCompleteRequest( Irp, IO_NO_INCREMENT );
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
     return STATUS_SUCCESS;
 }
@@ -690,6 +781,7 @@ StorPortInitialize(
         InitializeListHead(&DriverObjectExtension->AdapterListHead);
         KeInitializeSpinLock(&DriverObjectExtension->AdapterListLock);
 
+        InitializeListHead(&DriverObjectExtension->InitDataListHead);
 
         /* Set handlers */
         DriverObject->DriverExtension->AddDevice = PortAddDevice;
@@ -704,6 +796,10 @@ StorPortInitialize(
         DriverObject->MajorFunction[IRP_MJ_PNP] = PortDispatchPnp;
     }
 
+    /* Add the initialzation data to the driver extension */
+    Status = PortAddDriverInitData(DriverObjectExtension,
+                                   HwInitializationData);
+
     DPRINT1("StorPortInitialize() done (Status 0x%08lx)\n", Status);
 
     return Status;
index ec00692..1b3f70b 100644 (file)
@@ -2,4 +2,4 @@
 #define REACTOS_STR_FILE_DESCRIPTION  "Storport Driver"
 #define REACTOS_STR_INTERNAL_NAME     "storport"
 #define REACTOS_STR_ORIGINAL_FILENAME "storport.sys"
-#include <reactos/version.rc>
\ No newline at end of file
+#include <reactos/version.rc>