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
}
-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
* - 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;
continue;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
/* Get the results */
Status = HwRecalibrateResult(DriveInfo->ControllerInfo);
return STATUS_IO_DEVICE_ERROR;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{
return STATUS_IO_DEVICE_ERROR;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{
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++)
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);
UCHAR HeadLoadTime;
UCHAR HeadUnloadTime;
UCHAR StepRateTime;
+ LARGE_INTEGER Timeout;
PAGED_CODE();
* 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)
}
/* Wait for the recalibrate to finish */
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
RecalStatus = HwRecalibrateResult(DriveInfo->ControllerInfo);
}
/* 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)
return STATUS_UNSUCCESSFUL;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
if(HwSenseInterruptStatus(DriveInfo->ControllerInfo) != STATUS_SUCCESS)
{
return STATUS_UNSUCCESSFUL;
}
- WaitForControllerInterrupt(DriveInfo->ControllerInfo);
+ WaitForControllerInterrupt(DriveInfo->ControllerInfo, NULL);
if(HwReadIdResult(DriveInfo->ControllerInfo, &CurCylinder, NULL) != STATUS_SUCCESS)
{
* 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,