https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4ba8a8b59bebabd941e42…
commit 4ba8a8b59bebabd941e42d14493e4cd02a3e5972
Author: Dmitry Borisov <di.sean(a)protonmail.com>
AuthorDate: Sun Jan 15 22:41:49 2023 +0600
Commit: Dmitry Borisov <di.sean(a)protonmail.com>
CommitDate: Sat Aug 3 17:08:42 2024 +0600
[ISAPNP] Allocate the Read Port resources on demand
This will simplify failure paths and reduce memory usage
---
drivers/bus/isapnp/isapnp.c | 43 +++++++------------------------------------
drivers/bus/isapnp/isapnp.h | 28 +++++++++++++++++++++-------
drivers/bus/isapnp/pdo.c | 35 ++++++++++++++++++++++-------------
3 files changed, 50 insertions(+), 56 deletions(-)
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index 0ff17876e75..514322c69c0 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -1038,9 +1038,8 @@ IsaForwardOrIgnore(
}
CODE_SEG("PAGE")
-NTSTATUS
+PIO_RESOURCE_REQUIREMENTS_LIST
IsaPnpCreateReadPortDORequirements(
- _In_ PISAPNP_PDO_EXTENSION PdoExt,
_In_opt_ ULONG SelectedReadPort)
{
ULONG ResourceCount, ListSize, i;
@@ -1087,7 +1086,7 @@ IsaPnpCreateReadPortDORequirements(
sizeof(IO_RESOURCE_DESCRIPTOR) * (ResourceCount - 1);
RequirementsList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP);
if (!RequirementsList)
- return STATUS_NO_MEMORY;
+ return NULL;
RequirementsList->ListSize = ListSize;
RequirementsList->AlternativeLists = 1;
@@ -1182,15 +1181,12 @@ IsaPnpCreateReadPortDORequirements(
}
}
- PdoExt->RequirementsList = RequirementsList;
- return STATUS_SUCCESS;
+ return RequirementsList;
}
-static
CODE_SEG("PAGE")
-NTSTATUS
-IsaPnpCreateReadPortDOResources(
- _In_ PISAPNP_PDO_EXTENSION PdoExt)
+PCM_RESOURCE_LIST
+IsaPnpCreateReadPortDOResources(VOID)
{
const USHORT Ports[] = { ISAPNP_WRITE_DATA, ISAPNP_ADDRESS };
ULONG ListSize, i;
@@ -1203,7 +1199,7 @@ IsaPnpCreateReadPortDOResources(
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (RTL_NUMBER_OF(Ports) - 1);
ResourceList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP);
if (!ResourceList)
- return STATUS_NO_MEMORY;
+ return NULL;
ResourceList->Count = 1;
ResourceList->List[0].InterfaceType = Internal;
@@ -1223,9 +1219,7 @@ IsaPnpCreateReadPortDOResources(
Descriptor++;
}
- PdoExt->ResourceList = ResourceList;
- PdoExt->ResourceListSize = ListSize;
- return STATUS_SUCCESS;
+ return ResourceList;
}
static
@@ -1259,23 +1253,8 @@ IsaPnpCreateReadPortDO(
PdoExt->Common.State = dsStopped;
PdoExt->FdoExt = FdoExt;
- Status = IsaPnpCreateReadPortDORequirements(PdoExt, 0);
- if (!NT_SUCCESS(Status))
- goto Failure;
-
- Status = IsaPnpCreateReadPortDOResources(PdoExt);
- if (!NT_SUCCESS(Status))
- goto Failure;
-
FdoExt->ReadPortPdo->Flags &= ~DO_DEVICE_INITIALIZING;
- return Status;
-
-Failure:
- IsaPnpRemoveReadPortDO(FdoExt->ReadPortPdo);
-
- FdoExt->ReadPortPdo = NULL;
-
return Status;
}
@@ -1284,18 +1263,10 @@ VOID
IsaPnpRemoveReadPortDO(
_In_ PDEVICE_OBJECT Pdo)
{
- PISAPNP_PDO_EXTENSION ReadPortExt = Pdo->DeviceExtension;
-
PAGED_CODE();
DPRINT("Removing Read Port\n");
- if (ReadPortExt->RequirementsList)
- ExFreePoolWithTag(ReadPortExt->RequirementsList, TAG_ISAPNP);
-
- if (ReadPortExt->ResourceList)
- ExFreePoolWithTag(ReadPortExt->ResourceList, TAG_ISAPNP);
-
IoDeleteDevice(Pdo);
}
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index ad48008251f..ea84d2d5148 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -176,12 +176,7 @@ typedef struct _ISAPNP_FDO_EXTENSION
typedef struct _ISAPNP_PDO_EXTENSION
{
ISAPNP_COMMON_EXTENSION Common;
- PISAPNP_LOGICAL_DEVICE IsaPnpDevice;
PISAPNP_FDO_EXTENSION FdoExt;
- PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
-
- PCM_RESOURCE_LIST ResourceList;
- ULONG ResourceListSize;
ULONG Flags;
#define ISAPNP_ENUMERATED 0x00000001 /**< @brief Whether the device has
been reported to the PnP manager. */
@@ -189,6 +184,22 @@ typedef struct _ISAPNP_PDO_EXTENSION
#define ISAPNP_READ_PORT_ALLOW_FDO_SCAN 0x00000004 /**< @brief Allows the active FDO
to scan the bus. */
#define ISAPNP_READ_PORT_NEED_REBALANCE 0x00000008 /**< @brief The I/O resource
requirements have changed. */
+ union
+ {
+ /* Data belonging to logical devices */
+ struct
+ {
+ PISAPNP_LOGICAL_DEVICE IsaPnpDevice;
+
+ PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
+
+ PCM_RESOURCE_LIST ResourceList;
+ ULONG ResourceListSize;
+ };
+
+ ULONG SelectedPort;
+ };
+
_Write_guarded_by_(_Global_interlock_)
volatile LONG SpecialFiles;
} ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION;
@@ -315,11 +326,14 @@ FindMemoryDescriptor(
_Out_opt_ PUCHAR WriteOrder);
CODE_SEG("PAGE")
-NTSTATUS
+PIO_RESOURCE_REQUIREMENTS_LIST
IsaPnpCreateReadPortDORequirements(
- _In_ PISAPNP_PDO_EXTENSION PdoExt,
_In_opt_ ULONG SelectedReadPort);
+CODE_SEG("PAGE")
+PCM_RESOURCE_LIST
+IsaPnpCreateReadPortDOResources(VOID);
+
CODE_SEG("PAGE")
VOID
IsaPnpRemoveReadPortDO(
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 3946ce31485..5e8979ad274 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -478,8 +478,17 @@ IsaPdoQueryResources(
PAGED_CODE();
- if (PdoExt->Common.Signature == IsaPnpLogicalDevice &&
- !(PdoExt->IsaPnpDevice->Flags & ISAPNP_HAS_RESOURCES))
+ if (PdoExt->Common.Signature == IsaPnpReadDataPort)
+ {
+ ResourceList = IsaPnpCreateReadPortDOResources();
+ if (!ResourceList)
+ return STATUS_NO_MEMORY;
+
+ Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+ return STATUS_SUCCESS;
+ }
+
+ if (!(PdoExt->IsaPnpDevice->Flags & ISAPNP_HAS_RESOURCES))
{
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
@@ -513,6 +522,16 @@ IsaPdoQueryResourceRequirements(
PAGED_CODE();
+ if (PdoExt->Common.Signature == IsaPnpReadDataPort)
+ {
+ RequirementsList = IsaPnpCreateReadPortDORequirements(PdoExt->SelectedPort);
+ if (!RequirementsList)
+ return STATUS_NO_MEMORY;
+
+ Irp->IoStatus.Information = (ULONG_PTR)RequirementsList;
+ return STATUS_SUCCESS;
+ }
+
if (!PdoExt->RequirementsList)
return Irp->IoStatus.Status;
@@ -593,19 +612,9 @@ IsaPdoStartReadPort(
ASSERT(SelectedPort != 0);
- if (PdoExt->RequirementsList)
- {
- ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP);
- PdoExt->RequirementsList = NULL;
- }
-
/* Discard the Read Ports at conflicting locations */
- Status = IsaPnpCreateReadPortDORequirements(PdoExt, SelectedPort);
- if (!NT_SUCCESS(Status))
- return Status;
-
+ PdoExt->SelectedPort = SelectedPort;
PdoExt->Flags |= ISAPNP_READ_PORT_NEED_REBALANCE;
-
IoInvalidateDeviceState(PdoExt->Common.Self);
return STATUS_SUCCESS;