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/flo…
==============================================================================
--- 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/har…
==============================================================================
--- 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;
+ }
}