From aa9a3648eb062a4fde900837d77b68643d18b981 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 11 Feb 2010 02:22:34 +0000 Subject: [PATCH] - Fix floppy controller detection - Simplify waiting in Get_Byte and Send_Byte - See issue #4391 for details svn path=/trunk/; revision=45568 --- reactos/drivers/storage/floppy/floppy.c | 15 +-- reactos/drivers/storage/floppy/hardware.c | 120 ++++++---------------- 2 files changed, 40 insertions(+), 95 deletions(-) diff --git a/reactos/drivers/storage/floppy/floppy.c b/reactos/drivers/storage/floppy/floppy.c index fe22d3f00ae..dcb79e04a0c 100644 --- a/reactos/drivers/storage/floppy/floppy.c +++ b/reactos/drivers/storage/floppy/floppy.c @@ -686,19 +686,20 @@ static NTSTATUS NTAPI InitController(PCONTROLLER_INFO ControllerInfo) return STATUS_IO_DEVICE_ERROR; } - /* Check if floppy drive exists */ - if(HwSenseInterruptStatus(ControllerInfo) != STATUS_SUCCESS) + /* All controllers should support this so + * if we get something strange back then we + * know that this isn't a floppy controller + */ + if (HwGetVersion(ControllerInfo) <= 0) { - WARN_(FLOPPY, "Floppy drive not detected!\n"); + WARN_(FLOPPY, "InitController: unable to contact controller\n"); return STATUS_NO_SUCH_DEVICE; } - INFO_(FLOPPY, "InitController: resetting the controller after floppy detection\n"); - - /* Reset the controller again after drive detection */ + /* Reset the controller to avoid interrupt garbage on certain controllers */ if(HwReset(ControllerInfo) != STATUS_SUCCESS) { - WARN_(FLOPPY, "InitController: unable to reset controller\n"); + WARN_(FLOPPY, "InitController: unable to reset controller #2\n"); return STATUS_IO_DEVICE_ERROR; } diff --git a/reactos/drivers/storage/floppy/hardware.c b/reactos/drivers/storage/floppy/hardware.c index 206e56e50a1..d89b5dc9224 100644 --- a/reactos/drivers/storage/floppy/hardware.c +++ b/reactos/drivers/storage/floppy/hardware.c @@ -45,7 +45,6 @@ * with the bit position in the register, or they *might not*. This should * all be converted to standardize on absolute values or shifts. * I prefer bit fields, but they break endianness. - * TODO: Figure out the right delays in Send_Byte and Get_Byte */ #include @@ -54,13 +53,6 @@ #include "floppy.h" #include "hardware.h" -/* - * Global variable that tracks the amount of time we've - * been waiting on the controller - */ -static ULONG TimeIncrement = 0; - - /* * Hardware Support Routines */ @@ -131,60 +123,35 @@ static NTSTATUS NTAPI Send_Byte(PCONTROLLER_INFO ControllerInfo, * - Function designed after flowchart in intel datasheet * - 250us max delay. Note that this is exactly 5 times longer * than Microsoft recommends stalling the processor - * - Remember that we can be interrupted here, so this might - * take much more wall clock time than 250us * - PAGED_CODE, because we spin for more than the Microsoft-recommended * maximum. * - This function is necessary because sometimes the FIFO reacts slowly * and isn't yet ready to read or write the next byte - * FIXME: time interval here and in Get_Byte */ { - LARGE_INTEGER StartingTickCount; - LARGE_INTEGER CurrentTickCount; - PUCHAR Address; + int i; PAGED_CODE(); - Address = ControllerInfo->BaseAddress + FIFO; - - if(!TimeIncrement) - TimeIncrement = KeQueryTimeIncrement(); - - StartingTickCount.QuadPart = 0; - - for(;;) + for(i = 0; i < 5; i++) { - if(!ReadyForWrite(ControllerInfo)) - { - ULONG64 ElapsedTicks; - ULONG64 TimeUnits; - - /* If this is the first time through... */ - if(!StartingTickCount.QuadPart) - { - KeQueryTickCount(&StartingTickCount); - continue; - } - - /* Otherwise, only do this for 250 us == 2500 100ns units */ - KeQueryTickCount(&CurrentTickCount); - ElapsedTicks = CurrentTickCount.QuadPart - StartingTickCount.QuadPart; - TimeUnits = ElapsedTicks * TimeIncrement; - - if(TimeUnits > 25000000) - break; - - continue; - } + if(ReadyForWrite(ControllerInfo)) + break; - WRITE_PORT_UCHAR(Address, Byte); - return STATUS_SUCCESS; + KeStallExecutionProcessor(50); } - INFO_(FLOPPY, "Send_Byte: timed out trying to write\n"); - HwDumpRegisters(ControllerInfo); - return STATUS_UNSUCCESSFUL; + if (i < 5) + { + WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + FIFO, Byte); + return STATUS_SUCCESS; + } + else + { + INFO_(FLOPPY, "Send_Byte: timed out trying to write\n"); + HwDumpRegisters(ControllerInfo); + return STATUS_UNSUCCESSFUL; + } } @@ -208,52 +175,29 @@ static NTSTATUS NTAPI Get_Byte(PCONTROLLER_INFO ControllerInfo, * - PAGED_CODE because we spin for longer than Microsoft recommends */ { - LARGE_INTEGER StartingTickCount; - LARGE_INTEGER CurrentTickCount; - PUCHAR Address; + int i; PAGED_CODE(); - Address = ControllerInfo->BaseAddress + FIFO; - - if(!TimeIncrement) - TimeIncrement = KeQueryTimeIncrement(); - - StartingTickCount.QuadPart = 0; - - for(;;) + for(i = 0; i < 5; i++) { - if(!ReadyForRead(ControllerInfo)) - { - ULONG64 ElapsedTicks; - ULONG64 TimeUnits; - - /* if this is the first time through, start the timer */ - if(!StartingTickCount.QuadPart) - { - KeQueryTickCount(&StartingTickCount); - continue; - } + if(ReadyForRead(ControllerInfo)) + break; - /* Otherwise, only do this for 250 us == 2500 100ns units */ - KeQueryTickCount(&CurrentTickCount); - ElapsedTicks = CurrentTickCount.QuadPart - StartingTickCount.QuadPart; - TimeUnits = ElapsedTicks * TimeIncrement; - - if(TimeUnits > 25000000) - break; - - continue; - } - - *Byte = READ_PORT_UCHAR(Address); - - return STATUS_SUCCESS; + KeStallExecutionProcessor(50); } - WARN_(FLOPPY, "Get_Byte: timed out trying to read\n"); - HwDumpRegisters(ControllerInfo); - return STATUS_UNSUCCESSFUL; + if (i < 5) + { + *Byte = READ_PORT_UCHAR(ControllerInfo->BaseAddress + FIFO); + return STATUS_SUCCESS; + } + else + { + INFO_(FLOPPY, "Get_Byte: timed out trying to write\n"); + HwDumpRegisters(ControllerInfo); + return STATUS_UNSUCCESSFUL; + } } -- 2.17.1