https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4b34e44782e44afe2af52…
commit 4b34e44782e44afe2af5277887d8e7df0d436a87
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Tue Nov 21 10:22:50 2017 +0100
[FLOPPY] Don't wait forever while trying to determine media type.
This should fix some virtual machines and real hardware machine with empty floopy
drive
not being able to boot ReactOS (stuck while initializing floppy.sys).
This fixes a regression introduced in r70746.
It could be generalized to other interrupts, floppy controllers not being reliable.
For more information:
http://wiki.osdev.org/Floppy_Disk_Controller
CORE-7935
CORE-12908
CORE-13080
---
drivers/storage/floppy/floppy.c | 19 ++++++++++++-------
drivers/storage/floppy/floppy.h | 4 ++--
drivers/storage/floppy/readwrite.c | 16 ++++++++++------
3 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/drivers/storage/floppy/floppy.c b/drivers/storage/floppy/floppy.c
index d388cf7d37..4234b0f8bb 100644
--- a/drivers/storage/floppy/floppy.c
+++ b/drivers/storage/floppy/floppy.c
@@ -159,12 +159,13 @@ StopMotor(PCONTROLLER_INFO ControllerInfo)
}
-VOID NTAPI
-WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo)
+NTSTATUS NTAPI
+WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo, PLARGE_INTEGER Timeout)
/*
* FUNCTION: Wait for the controller to interrupt, and then clear the event
* ARGUMENTS:
* ControllerInfo: Controller to wait for
+ * Timeout: How long to wait for
* NOTES:
* - There is a small chance that an unexpected or spurious interrupt could
* be lost with this clear/wait/clear scheme used in this driver. This is
@@ -173,11 +174,15 @@ WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo)
* - PAGED_CODE because it waits
*/
{
+ NTSTATUS Status;
+
PAGED_CODE();
ASSERT(ControllerInfo);
- KeWaitForSingleObject(&ControllerInfo->SynchEvent, Executive, KernelMode,
FALSE, NULL);
+ Status = KeWaitForSingleObject(&ControllerInfo->SynchEvent, Executive,
KernelMode, FALSE, Timeout);
KeClearEvent(&ControllerInfo->SynchEvent);
+
+ return Status;
}
static DRIVER_DISPATCH CreateClose;
@@ -262,7 +267,7 @@ Recalibrate(PDRIVE_INFO DriveInfo)
continue;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
/* Get the results */
Status = HwRecalibrateResult(DriveInfo->ControllerInfo);
@@ -323,7 +328,7 @@ ResetChangeFlag(PDRIVE_INFO DriveInfo)
return STATUS_IO_DEVICE_ERROR;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{
@@ -340,7 +345,7 @@ ResetChangeFlag(PDRIVE_INFO DriveInfo)
return STATUS_IO_DEVICE_ERROR;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{
@@ -701,7 +706,7 @@ InitController(PCONTROLLER_INFO ControllerInfo)
INFO_(FLOPPY, "InitController: waiting for initial interrupt\n");
/* Wait for an interrupt */
- WaitForControllerInterrupt(ControllerInfo);
+ WaitForControllerInterrupt(ControllerInfo, NULL);
/* Reset means you have to clear each of the four interrupts (one per drive) */
for(i = 0; i < MAX_DRIVES_PER_CONTROLLER; i++)
diff --git a/drivers/storage/floppy/floppy.h b/drivers/storage/floppy/floppy.h
index e1d0efcd88..cd0301ca53 100644
--- a/drivers/storage/floppy/floppy.h
+++ b/drivers/storage/floppy/floppy.h
@@ -92,8 +92,8 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
VOID NTAPI
SignalMediaChanged(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-VOID NTAPI
-WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo);
+NTSTATUS NTAPI
+WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo, PLARGE_INTEGER Timeout);
NTSTATUS NTAPI
ResetChangeFlag(PDRIVE_INFO DriveInfo);
diff --git a/drivers/storage/floppy/readwrite.c b/drivers/storage/floppy/readwrite.c
index 594d9c7e8b..2ce3a6ccf1 100644
--- a/drivers/storage/floppy/readwrite.c
+++ b/drivers/storage/floppy/readwrite.c
@@ -170,6 +170,7 @@ RWDetermineMediaType(PDRIVE_INFO DriveInfo, BOOLEAN OneShot)
UCHAR HeadLoadTime;
UCHAR HeadUnloadTime;
UCHAR StepRateTime;
+ LARGE_INTEGER Timeout;
PAGED_CODE();
@@ -181,9 +182,12 @@ RWDetermineMediaType(PDRIVE_INFO DriveInfo, BOOLEAN OneShot)
* Note that only 1.44 has been tested at all.
*/
+ Timeout.QuadPart = -10000000; /* 1 second. Is that enough? */
+
do
{
int i;
+ NTSTATUS Status;
/* Program data rate */
if(HwSetDataRate(DriveInfo->ControllerInfo, DRSR_DSEL_500KBPS) !=
STATUS_SUCCESS)
@@ -219,7 +223,7 @@ RWDetermineMediaType(PDRIVE_INFO DriveInfo, BOOLEAN OneShot)
}
/* Wait for the recalibrate to finish */
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
RecalStatus = HwRecalibrateResult(DriveInfo->ControllerInfo);
@@ -244,9 +248,9 @@ RWDetermineMediaType(PDRIVE_INFO DriveInfo, BOOLEAN OneShot)
}
/* Wait for the ReadID to finish */
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ Status = WaitForControllerInterrupt(DriveInfo->ControllerInfo, &Timeout);
- if(HwReadIdResult(DriveInfo->ControllerInfo, NULL, NULL) != STATUS_SUCCESS)
+ if(Status == STATUS_TIMEOUT || HwReadIdResult(DriveInfo->ControllerInfo, NULL,
NULL) != STATUS_SUCCESS)
{
WARN_(FLOPPY, "RWDetermineMediaType(): ReadIdResult failed;
continuing\n");
if (OneShot)
@@ -303,7 +307,7 @@ RWSeekToCylinder(PDRIVE_INFO DriveInfo, UCHAR Cylinder)
return STATUS_UNSUCCESSFUL;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{
@@ -318,7 +322,7 @@ RWSeekToCylinder(PDRIVE_INFO DriveInfo, UCHAR Cylinder)
return STATUS_UNSUCCESSFUL;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
if(HwReadIdResult(DriveInfo->ControllerInfo, &CurCylinder, NULL) !=
STATUS_SUCCESS)
{
@@ -732,7 +736,7 @@ ReadWritePassive(PDRIVE_INFO DriveInfo, PIRP Irp)
* At this point, we block and wait for an interrupt
* FIXME: this seems to take too long
*/
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
/* Read is complete; flush & free adapter channel */
IoFlushAdapterBuffers(DriveInfo->ControllerInfo->AdapterObject,
Irp->MdlAddress,