https://git.reactos.org/?p=reactos.git;a=commitdiff;h=367f4b1581c0ebdc41edeā¦
commit 367f4b1581c0ebdc41ede579bbd7b6efc285d477
Author: Dmitry Borisov <di.sean(a)protonmail.com>
AuthorDate: Sat Mar 20 20:52:40 2021 +0600
Commit: Dmitry Borisov <di.sean(a)protonmail.com>
CommitDate: Sun Jun 20 19:24:31 2021 +0600
[ISAPNP] Map configuration states to PnP states
Rework the hardware support code to avoid unneeded transitions
between configuration states.
- Only call WaitForKey when needed.
- Each PnP state transition causes the bus to move to WaitForKey state.
Besides, deactivate logical device during processing remove request.
---
drivers/bus/isapnp/hardware.c | 152 ++++++++++++++++--------------------------
drivers/bus/isapnp/isapnp.c | 2 +
drivers/bus/isapnp/isapnp.h | 15 ++++-
drivers/bus/isapnp/pdo.c | 44 ++++++++++--
4 files changed, 112 insertions(+), 101 deletions(-)
diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c
index 671a198baf6..62e538a49d4 100644
--- a/drivers/bus/isapnp/hardware.c
+++ b/drivers/bus/isapnp/hardware.c
@@ -119,14 +119,6 @@ WaitForKey(VOID)
WriteByte(ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_WAIT_FOR_KEY);
}
-static
-inline
-VOID
-ResetCsn(VOID)
-{
- WriteByte(ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_RESET_CSN);
-}
-
static
inline
VOID
@@ -1167,92 +1159,81 @@ ReadCurrentResources(
return TRUE;
}
-static
CODE_SEG("PAGE")
-INT
-TryIsolate(
+UCHAR
+IsaHwTryReadDataPort(
_In_ PUCHAR ReadDataPort)
{
- ISAPNP_IDENTIFIER Identifier;
- USHORT i, j;
- BOOLEAN Seen55aa, SeenLife;
- INT Csn = 0;
- USHORT Byte, Data;
+ ULONG NumberOfRead = 0;
+ UCHAR Csn = 0;
PAGED_CODE();
DPRINT("Setting read data port: 0x%p\n", ReadDataPort);
- WaitForKey();
SendKey();
- ResetCsn();
+ WriteByte(ISAPNP_CONFIGCONTROL,
+ ISAPNP_CONFIG_RESET_CSN | ISAPNP_CONFIG_WAIT_FOR_KEY);
KeStallExecutionProcessor(2000);
- WaitForKey();
SendKey();
+
Wake(0x00);
KeStallExecutionProcessor(1000);
SetReadDataPort(ReadDataPort);
+ Wake(0x00);
+
while (TRUE)
{
+ ISAPNP_IDENTIFIER Identifier;
+ UCHAR i, j;
+ BOOLEAN Seen55aa = FALSE;
+
EnterIsolationState();
KeStallExecutionProcessor(1000);
RtlZeroMemory(&Identifier, sizeof(Identifier));
- Seen55aa = SeenLife = FALSE;
- for (i = 0; i < 9; i++)
+ for (i = 0; i < sizeof(Identifier); i++)
{
- Byte = 0;
- for (j = 0; j < 8; j++)
+ UCHAR Byte = 0;
+
+ for (j = 0; j < RTL_BITS_OF(Byte); j++)
{
- Data = ReadData(ReadDataPort);
+ USHORT Data;
+
+ Data = ReadData(ReadDataPort) << 8;
KeStallExecutionProcessor(250);
- Data = ((Data << 8) | ReadData(ReadDataPort));
+ Data |= ReadData(ReadDataPort);
KeStallExecutionProcessor(250);
+
Byte >>= 1;
- if (Data != 0xFFFF)
+ if (Data == 0x55AA)
{
- SeenLife = TRUE;
- if (Data == 0x55AA)
- {
- Byte |= 0x80;
- Seen55aa = TRUE;
- }
+ Byte |= 0x80;
+ Seen55aa = TRUE;
}
}
- *(((PUCHAR)&Identifier) + i) = Byte;
+
+ ((PUCHAR)&Identifier)[i] = Byte;
}
- if (!Seen55aa)
+ ++NumberOfRead;
+
+ if (Identifier.Checksum != 0x00 &&
+ Identifier.Checksum != IsaPnpChecksum(&Identifier))
{
- if (Csn)
- {
- DPRINT("Found no more cards\n");
- }
- else
- {
- if (SeenLife)
- {
- DPRINT("Saw life but no cards, trying new read port\n");
- Csn = -1;
- }
- else
- {
- DPRINT("Saw no sign of life, abandoning isolation\n");
- }
- }
+ DPRINT("Bad checksum\n");
break;
}
- if (Identifier.Checksum != IsaPnpChecksum(&Identifier))
+ if (!Seen55aa)
{
- DPRINT("Bad checksum, trying next read data port\n");
- Csn = -1;
+ DPRINT("Saw no sign of life\n");
break;
}
@@ -1264,32 +1245,18 @@ TryIsolate(
Wake(0x00);
}
- WaitForKey();
+ Wake(0x00);
- if (Csn > 0)
+ if (NumberOfRead == 1)
{
- DPRINT("Found %d cards at read port 0x%p\n", Csn, ReadDataPort);
+ DPRINT("Trying next read data port\n");
+ return 0;
}
-
- return Csn;
-}
-
-static
-VOID
-DeviceActivation(
- _In_ PISAPNP_LOGICAL_DEVICE IsaDevice,
- _In_ BOOLEAN Activate)
-{
- WaitForKey();
- SendKey();
- Wake(IsaDevice->CSN);
-
- if (Activate)
- ActivateDevice(IsaDevice->LDN);
else
- DeactivateDevice(IsaDevice->LDN);
-
- WaitForKey();
+ {
+ DPRINT("Found %u cards at read port 0x%p\n", Csn, ReadDataPort);
+ return Csn;
+ }
}
_Requires_lock_held_(FdoExt->DeviceSyncEvent)
@@ -1324,9 +1291,6 @@ IsaHwFillDeviceList(
LogDevice->Flags &= ~ISAPNP_PRESENT;
}
- WaitForKey();
- SendKey();
-
for (Csn = 1; Csn <= FdoExt->Cards; Csn++)
{
NTSTATUS Status;
@@ -1436,34 +1400,34 @@ Deactivate:
return STATUS_SUCCESS;
}
-CODE_SEG("PAGE")
-ULONG
-IsaHwTryReadDataPort(
- _In_ PUCHAR ReadDataPort)
+_IRQL_requires_max_(DISPATCH_LEVEL)
+VOID
+IsaHwWakeDevice(
+ _In_ PISAPNP_LOGICAL_DEVICE LogicalDevice)
{
- PAGED_CODE();
-
- return TryIsolate(ReadDataPort);
+ SendKey();
+ Wake(LogicalDevice->CSN);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
-NTSTATUS
+VOID
IsaHwActivateDevice(
_In_ PISAPNP_LOGICAL_DEVICE LogicalDevice)
{
- DeviceActivation(LogicalDevice,
- TRUE);
-
- return STATUS_SUCCESS;
+ ActivateDevice(LogicalDevice->LDN);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
-NTSTATUS
+VOID
IsaHwDeactivateDevice(
_In_ PISAPNP_LOGICAL_DEVICE LogicalDevice)
{
- DeviceActivation(LogicalDevice,
- FALSE);
+ DeactivateDevice(LogicalDevice->LDN);
+}
- return STATUS_SUCCESS;
+_IRQL_requires_max_(DISPATCH_LEVEL)
+VOID
+IsaHwWaitForKey(VOID)
+{
+ WaitForKey();
}
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index 343a0ca69b3..877d69bf5a5 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -1350,6 +1350,8 @@ IsaPnpFillDeviceRelations(
/* Card identification */
if (FdoExt->Cards > 0)
(VOID)IsaHwFillDeviceList(FdoExt);
+
+ IsaHwWaitForKey();
}
ReadPortExt->Flags &= ~ISAPNP_SCANNED_BY_READ_PORT;
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index 00b82cb104b..e941020f783 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -365,7 +365,7 @@ IsaPnpRemoveLogicalDeviceDO(
/* hardware.c */
CODE_SEG("PAGE")
-ULONG
+UCHAR
IsaHwTryReadDataPort(
_In_ PUCHAR ReadDataPort);
@@ -376,15 +376,24 @@ IsaHwFillDeviceList(
_In_ PISAPNP_FDO_EXTENSION FdoExt);
_IRQL_requires_max_(DISPATCH_LEVEL)
-NTSTATUS
+VOID
+IsaHwWakeDevice(
+ _In_ PISAPNP_LOGICAL_DEVICE LogicalDevice);
+
+_IRQL_requires_max_(DISPATCH_LEVEL)
+VOID
IsaHwDeactivateDevice(
_In_ PISAPNP_LOGICAL_DEVICE LogicalDevice);
_IRQL_requires_max_(DISPATCH_LEVEL)
-NTSTATUS
+VOID
IsaHwActivateDevice(
_In_ PISAPNP_LOGICAL_DEVICE LogicalDevice);
+_IRQL_requires_max_(DISPATCH_LEVEL)
+VOID
+IsaHwWaitForKey(VOID);
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 8490bf9c14d..2c0a4641cb2 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -570,6 +570,7 @@ IsaPdoStartReadPort(
if (IS_READ_PORT(PartialDescriptor))
{
PUCHAR ReadDataPort =
ULongToPtr(PartialDescriptor->u.Port.Start.u.LowPart + 3);
+ ULONG Cards;
/*
* Remember the first Read Port in the resource list.
@@ -578,8 +579,11 @@ IsaPdoStartReadPort(
if (!SelectedPort)
SelectedPort = PartialDescriptor->u.Port.Start.u.LowPart;
+ Cards = IsaHwTryReadDataPort(ReadDataPort);
+ IsaHwWaitForKey();
+
/* We detected some ISAPNP cards */
- if (IsaHwTryReadDataPort(ReadDataPort) > 0)
+ if (Cards > 0)
{
SelectedPort = PartialDescriptor->u.Port.Start.u.LowPart;
break;
@@ -634,6 +638,7 @@ IsaPdoStartReadPort(
/* Card identification */
Status = IsaHwFillDeviceList(FdoExt);
+ IsaHwWaitForKey();
IsaPnpReleaseDeviceDataLock(FdoExt);
@@ -647,7 +652,10 @@ IsaPdoStartReadPort(
}
else
{
+ IsaHwWaitForKey();
+#if 0 /* See the 'if 0' above */
break;
+#endif
}
}
}
@@ -742,6 +750,17 @@ IsaPdoRemoveDevice(
PAGED_CODE();
+ /* Deactivate the device if previously activated */
+ if (PdoExt->Common.State == dsStarted)
+ {
+ IsaHwWakeDevice(PdoExt->IsaPnpDevice);
+ IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
+
+ IsaHwWaitForKey();
+
+ PdoExt->Common.State = dsStopped;
+ }
+
if (FinalRemove && !(PdoExt->Flags & ISAPNP_ENUMERATED))
{
IsaPnpAcquireDeviceDataLock(FdoExt);
@@ -873,8 +892,16 @@ IsaPdoPnp(
switch (IrpSp->MinorFunction)
{
case IRP_MN_START_DEVICE:
+ {
if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
- Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
+ {
+ IsaHwWakeDevice(PdoExt->IsaPnpDevice);
+
+ Status = STATUS_SUCCESS;
+
+ IsaHwActivateDevice(PdoExt->IsaPnpDevice);
+ IsaHwWaitForKey();
+ }
else
{
Status = IsaPdoStartReadPort(PdoExt,
@@ -884,19 +911,28 @@ IsaPdoPnp(
if (NT_SUCCESS(Status))
PdoExt->Common.State = dsStarted;
break;
+ }
case IRP_MN_STOP_DEVICE:
+ {
if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
- Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
+ {
+ IsaHwWakeDevice(PdoExt->IsaPnpDevice);
+ IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
+
+ IsaHwWaitForKey();
+ }
else
{
PdoExt->Flags &= ~ISAPNP_READ_PORT_ALLOW_FDO_SCAN;
- Status = STATUS_SUCCESS;
}
+ Status = STATUS_SUCCESS;
+
if (NT_SUCCESS(Status))
PdoExt->Common.State = dsStopped;
break;
+ }
case IRP_MN_QUERY_STOP_DEVICE:
{