Author: cgutman Date: Thu Feb 11 03:22:34 2010 New Revision: 45568
URL: http://svn.reactos.org/svn/reactos?rev=45568&view=rev Log: - Fix floppy controller detection - Simplify waiting in Get_Byte and Send_Byte - See issue #4391 for details
Modified: trunk/reactos/drivers/storage/floppy/floppy.c trunk/reactos/drivers/storage/floppy/hardware.c
Modified: trunk/reactos/drivers/storage/floppy/floppy.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/floppy/flop... ============================================================================== --- trunk/reactos/drivers/storage/floppy/floppy.c [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/floppy/floppy.c [iso-8859-1] Thu Feb 11 03:22:34 2010 @@ -686,19 +686,20 @@ return STATUS_IO_DEVICE_ERROR; }
- /* Check if floppy drive exists */ - if(HwSenseInterruptStatus(ControllerInfo) != STATUS_SUCCESS) - { - WARN_(FLOPPY, "Floppy drive not detected!\n"); + /* 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, "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; }
Modified: trunk/reactos/drivers/storage/floppy/hardware.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/floppy/hard... ============================================================================== --- trunk/reactos/drivers/storage/floppy/hardware.c [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/floppy/hardware.c [iso-8859-1] Thu Feb 11 03:22:34 2010 @@ -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 <ntddk.h> @@ -53,13 +52,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 @@ * - 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; - - PAGED_CODE(); - - Address = ControllerInfo->BaseAddress + FIFO; - - if(!TimeIncrement) - TimeIncrement = KeQueryTimeIncrement(); - - StartingTickCount.QuadPart = 0; - - for(;;) - { - 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; - } - - WRITE_PORT_UCHAR(Address, Byte); - return STATUS_SUCCESS; - } - - INFO_(FLOPPY, "Send_Byte: timed out trying to write\n"); - HwDumpRegisters(ControllerInfo); - return STATUS_UNSUCCESSFUL; + */ +{ + int i; + + PAGED_CODE(); + + for(i = 0; i < 5; i++) + { + if(ReadyForWrite(ControllerInfo)) + break; + + KeStallExecutionProcessor(50); + } + + 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 @@ * - PAGED_CODE because we spin for longer than Microsoft recommends */ { - LARGE_INTEGER StartingTickCount; - LARGE_INTEGER CurrentTickCount; - PUCHAR Address; - - PAGED_CODE(); - - Address = ControllerInfo->BaseAddress + FIFO; - - if(!TimeIncrement) - TimeIncrement = KeQueryTimeIncrement(); - - StartingTickCount.QuadPart = 0; - - for(;;) - { - if(!ReadyForRead(ControllerInfo)) - { - ULONG64 ElapsedTicks; - ULONG64 TimeUnits; - - /* if this is the first time through, start the timer */ - 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; - } - - *Byte = READ_PORT_UCHAR(Address); - - return STATUS_SUCCESS; - } - - WARN_(FLOPPY, "Get_Byte: timed out trying to read\n"); - HwDumpRegisters(ControllerInfo); - return STATUS_UNSUCCESSFUL; + int i; + + PAGED_CODE(); + + for(i = 0; i < 5; i++) + { + if(ReadyForRead(ControllerInfo)) + break; + + KeStallExecutionProcessor(50); + } + + 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; + } }