From 8dea67f8ba2bd2b83afcd40a4c53235be4596d37 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 14 Oct 2017 19:12:24 +0200 Subject: [PATCH] [STORPORT] Initialize a miniport object and call the miniport HwFindAdapter and HwInitialize routines. CORE-13866 --- drivers/storage/port/storport/CMakeLists.txt | 2 + drivers/storage/port/storport/fdo.c | 80 ++++++++++++++-- drivers/storage/port/storport/guid.c | 11 +++ drivers/storage/port/storport/miniport.c | 93 +++++++++++++++++++ drivers/storage/port/storport/misc.c | 27 ++++++ drivers/storage/port/storport/precomp.h | 51 +++++++++- drivers/storage/port/storport/storport.c | 98 +++++++++++++++++++- drivers/storage/port/storport/storport.rc | 2 +- 8 files changed, 353 insertions(+), 11 deletions(-) create mode 100644 drivers/storage/port/storport/guid.c create mode 100644 drivers/storage/port/storport/miniport.c diff --git a/drivers/storage/port/storport/CMakeLists.txt b/drivers/storage/port/storport/CMakeLists.txt index c531ee6f005..25b35a555d0 100644 --- a/drivers/storage/port/storport/CMakeLists.txt +++ b/drivers/storage/port/storport/CMakeLists.txt @@ -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) diff --git a/drivers/storage/port/storport/fdo.c b/drivers/storage/port/storport/fdo.c index c8508d05276..be6b6936941 100644 --- a/drivers/storage/port/storport/fdo.c +++ b/drivers/storage/port/storport/fdo.c @@ -15,6 +15,53 @@ /* 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 index 00000000000..757901b4222 --- /dev/null +++ b/drivers/storage/port/storport/guid.c @@ -0,0 +1,11 @@ +/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */ + +#include +#include +#include +#include + +#define DEVICE_TYPE ULONG +#include + +/* 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 index 00000000000..8e1346fe8b4 --- /dev/null +++ b/drivers/storage/port/storport/miniport.c @@ -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 + + +/* 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 */ diff --git a/drivers/storage/port/storport/misc.c b/drivers/storage/port/storport/misc.c index 3f2e254aa1d..54832c48aaa 100644 --- a/drivers/storage/port/storport/misc.c +++ b/drivers/storage/port/storport/misc.c @@ -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 */ diff --git a/drivers/storage/port/storport/precomp.h b/drivers/storage/port/storport/precomp.h index 68c59ba3398..fc1224e8513 100644 --- a/drivers/storage/port/storport/precomp.h +++ b/drivers/storage/port/storport/precomp.h @@ -11,6 +11,7 @@ #include #include #include +#include /* Declare STORPORT_API functions as exports rather than imports */ #define _STORPORT_ @@ -19,6 +20,11 @@ #include #include #include +#include + +/* 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( diff --git a/drivers/storage/port/storport/storport.c b/drivers/storage/port/storport/storport.c index 9b227dd8347..3520bbf3a3f 100644 --- a/drivers/storage/port/storport/storport.c +++ b/drivers/storage/port/storport/storport.c @@ -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; diff --git a/drivers/storage/port/storport/storport.rc b/drivers/storage/port/storport/storport.rc index ec00692e018..1b3f70bf9e7 100644 --- a/drivers/storage/port/storport/storport.rc +++ b/drivers/storage/port/storport/storport.rc @@ -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 \ No newline at end of file +#include