mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
- Fix floppy controller detection
- Simplify waiting in Get_Byte and Send_Byte - See issue #4391 for details svn path=/trunk/; revision=45568
This commit is contained in:
parent
c7f7e3bac7
commit
aa9a3648eb
2 changed files with 40 additions and 95 deletions
|
@ -686,19 +686,20 @@ static NTSTATUS NTAPI InitController(PCONTROLLER_INFO ControllerInfo)
|
||||||
return STATUS_IO_DEVICE_ERROR;
|
return STATUS_IO_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if floppy drive exists */
|
/* All controllers should support this so
|
||||||
if(HwSenseInterruptStatus(ControllerInfo) != STATUS_SUCCESS)
|
* 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;
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_(FLOPPY, "InitController: resetting the controller after floppy detection\n");
|
/* Reset the controller to avoid interrupt garbage on certain controllers */
|
||||||
|
|
||||||
/* Reset the controller again after drive detection */
|
|
||||||
if(HwReset(ControllerInfo) != STATUS_SUCCESS)
|
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;
|
return STATUS_IO_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
* with the bit position in the register, or they *might not*. This should
|
* with the bit position in the register, or they *might not*. This should
|
||||||
* all be converted to standardize on absolute values or shifts.
|
* all be converted to standardize on absolute values or shifts.
|
||||||
* I prefer bit fields, but they break endianness.
|
* I prefer bit fields, but they break endianness.
|
||||||
* TODO: Figure out the right delays in Send_Byte and Get_Byte
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
|
@ -54,13 +53,6 @@
|
||||||
#include "floppy.h"
|
#include "floppy.h"
|
||||||
#include "hardware.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
|
* Hardware Support Routines
|
||||||
*/
|
*/
|
||||||
|
@ -131,60 +123,35 @@ static NTSTATUS NTAPI Send_Byte(PCONTROLLER_INFO ControllerInfo,
|
||||||
* - Function designed after flowchart in intel datasheet
|
* - Function designed after flowchart in intel datasheet
|
||||||
* - 250us max delay. Note that this is exactly 5 times longer
|
* - 250us max delay. Note that this is exactly 5 times longer
|
||||||
* than Microsoft recommends stalling the processor
|
* 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
|
* - PAGED_CODE, because we spin for more than the Microsoft-recommended
|
||||||
* maximum.
|
* maximum.
|
||||||
* - This function is necessary because sometimes the FIFO reacts slowly
|
* - This function is necessary because sometimes the FIFO reacts slowly
|
||||||
* and isn't yet ready to read or write the next byte
|
* and isn't yet ready to read or write the next byte
|
||||||
* FIXME: time interval here and in Get_Byte
|
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
LARGE_INTEGER StartingTickCount;
|
int i;
|
||||||
LARGE_INTEGER CurrentTickCount;
|
|
||||||
PUCHAR Address;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
Address = ControllerInfo->BaseAddress + FIFO;
|
for(i = 0; i < 5; i++)
|
||||||
|
|
||||||
if(!TimeIncrement)
|
|
||||||
TimeIncrement = KeQueryTimeIncrement();
|
|
||||||
|
|
||||||
StartingTickCount.QuadPart = 0;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
{
|
||||||
if(!ReadyForWrite(ControllerInfo))
|
if(ReadyForWrite(ControllerInfo))
|
||||||
{
|
break;
|
||||||
ULONG64 ElapsedTicks;
|
|
||||||
ULONG64 TimeUnits;
|
|
||||||
|
|
||||||
/* If this is the first time through... */
|
KeStallExecutionProcessor(50);
|
||||||
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");
|
if (i < 5)
|
||||||
HwDumpRegisters(ControllerInfo);
|
{
|
||||||
return STATUS_UNSUCCESSFUL;
|
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
|
* - PAGED_CODE because we spin for longer than Microsoft recommends
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
LARGE_INTEGER StartingTickCount;
|
int i;
|
||||||
LARGE_INTEGER CurrentTickCount;
|
|
||||||
PUCHAR Address;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
Address = ControllerInfo->BaseAddress + FIFO;
|
for(i = 0; i < 5; i++)
|
||||||
|
|
||||||
if(!TimeIncrement)
|
|
||||||
TimeIncrement = KeQueryTimeIncrement();
|
|
||||||
|
|
||||||
StartingTickCount.QuadPart = 0;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
{
|
||||||
if(!ReadyForRead(ControllerInfo))
|
if(ReadyForRead(ControllerInfo))
|
||||||
{
|
break;
|
||||||
ULONG64 ElapsedTicks;
|
|
||||||
ULONG64 TimeUnits;
|
|
||||||
|
|
||||||
/* if this is the first time through, start the timer */
|
KeStallExecutionProcessor(50);
|
||||||
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");
|
if (i < 5)
|
||||||
HwDumpRegisters(ControllerInfo);
|
{
|
||||||
return STATUS_UNSUCCESSFUL;
|
*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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue