mirror of
https://github.com/reactos/reactos.git
synced 2025-05-18 00:31:27 +00:00
Enhanced floppy driver to read up to an entire track at a time
Not sure if I did this correctly, but it seems to work: By accident, I noticed that it seems to return more than the sector you requested if you program the DMAC to transfer more than one sector of bytes, so I decided to go with it. Minor fixes. svn path=/trunk/; revision=1987
This commit is contained in:
parent
d28ae7e82f
commit
439bc219e0
4 changed files with 80 additions and 38 deletions
|
@ -107,7 +107,7 @@ VOID FloppySeekDpc( PKDPC Dpc,
|
|||
IoFreeController( DeviceExtension->Controller );
|
||||
return;
|
||||
}
|
||||
KeStallExecutionProcessor( 10000000 );
|
||||
KeStallExecutionProcessor( 10000 );
|
||||
DPRINT( "Seek completed, now on cyl %2x\n", DeviceExtension->Cyl );
|
||||
// now that we are on the right cyl, restart the read
|
||||
if( FloppyExecuteReadWrite( DeviceObject,
|
||||
|
@ -149,17 +149,17 @@ VOID FloppyDpcReadWrite( PKDPC Dpc,
|
|||
ControllerExtension->Irp->MdlAddress,
|
||||
ControllerExtension->MapRegisterBase,
|
||||
ControllerExtension->Irp->Tail.Overlay.DriverContext[0],
|
||||
MediaTypes[DeviceExtension->MediaType].BytesPerSector,
|
||||
ControllerExtension->TransferLength,
|
||||
WriteToDevice );
|
||||
DPRINT( "St0 = %2x, St1 %2x, St2 = %2x\n",
|
||||
ControllerExtension->St0,
|
||||
ControllerExtension->St1,
|
||||
ControllerExtension->St2 );
|
||||
// update buffer info
|
||||
Stk->Parameters.Read.ByteOffset.u.LowPart += SectorSize;
|
||||
Stk->Parameters.Read.Length -= SectorSize;
|
||||
Stk->Parameters.Read.ByteOffset.u.LowPart += ControllerExtension->TransferLength;
|
||||
Stk->Parameters.Read.Length -= ControllerExtension->TransferLength;
|
||||
// drivercontext used for current va
|
||||
(DWORD)ControllerExtension->Irp->Tail.Overlay.DriverContext[0] += SectorSize;
|
||||
(DWORD)ControllerExtension->Irp->Tail.Overlay.DriverContext[0] += ControllerExtension->TransferLength;
|
||||
|
||||
DPRINT( "First dword: %x\n", *((DWORD *)ControllerExtension->MapRegisterBase) )
|
||||
|
||||
|
@ -188,7 +188,7 @@ VOID FloppyDpcDetectMedia( PKDPC Dpc,
|
|||
// If the read ID failed, fail the irp
|
||||
if( ControllerExtension->St1 != 0 )
|
||||
{
|
||||
DPRINT( "Read ID failed: ST1 = %2x\n", ControllerExtension->St1 );
|
||||
DPRINT1( "Read ID failed: ST1 = %2x\n", ControllerExtension->St1 );
|
||||
Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
|
||||
IoCompleteRequest( Irp, 0 );
|
||||
return;
|
||||
|
|
|
@ -170,6 +170,9 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject,
|
|||
DPRINT1( "Error: KeWaitForSingleObject returned: %x\n", Status );
|
||||
goto devicecleanup;
|
||||
}
|
||||
// set for high speed mode
|
||||
// FloppyWriteCCNTL( ControllerExtension->PortBase, FLOPPY_CCNTL_1MBIT );
|
||||
|
||||
// ok, so we have an FDC, now check for drives
|
||||
// aparently the sense drive status command does not work on any FDC I can find
|
||||
// so instead we will just have to assume a 1.44 meg 3.5 inch floppy. At some
|
||||
|
@ -281,11 +284,13 @@ IO_ALLOCATION_ACTION FloppyExecuteReadWrite( PDEVICE_OBJECT DeviceObject,
|
|||
BOOLEAN WriteToDevice;
|
||||
DWORD Cyl, Sector, Head;
|
||||
PIO_STACK_LOCATION Stk;
|
||||
DWORD Length;
|
||||
|
||||
ControllerExtension->Irp = Irp = (PIRP)Context;
|
||||
Stk = IoGetCurrentIrpStackLocation( Irp );
|
||||
ControllerExtension->Device = DeviceObject;
|
||||
Timeout.QuadPart = FLOPPY_MOTOR_SPINUP_TIME;
|
||||
DPRINT( "FloppyExecuteReadWrite()\n" );
|
||||
CHECKPOINT;
|
||||
WriteToDevice = Stk->MajorFunction == IRP_MJ_WRITE ? TRUE : FALSE;
|
||||
// verify drive is spun up and selected
|
||||
|
@ -340,7 +345,7 @@ IO_ALLOCATION_ACTION FloppyExecuteReadWrite( PDEVICE_OBJECT DeviceObject,
|
|||
Sector = Stk->Parameters.Read.ByteOffset.u.LowPart / MediaTypes[DeviceExtension->MediaType].BytesPerSector;
|
||||
// absolute sector right now
|
||||
Cyl = Sector / MediaTypes[DeviceExtension->MediaType].SectorsPerTrack;
|
||||
DPRINT( "Sector = %x, Offset = %x, Cyl = %x, Heads = %x MediaType = %x\n", Sector, Irp->Parameters.Read.ByteOffset.u.LowPart, (DWORD)Cyl, (DWORD)MediaTypes[DeviceExtension->MediaType].Heads, (DWORD)DeviceExtension->MediaType );
|
||||
DPRINT( "Sector = %x, Offset = %x, Cyl = %x, Heads = %x MediaType = %x\n", Sector, Stk->Parameters.Read.ByteOffset.u.LowPart, (DWORD)Cyl, (DWORD)MediaTypes[DeviceExtension->MediaType].Heads, (DWORD)DeviceExtension->MediaType );
|
||||
Head = Cyl % MediaTypes[DeviceExtension->MediaType].Heads;
|
||||
DPRINT( "Head = %2x\n", Head );
|
||||
// convert absolute cyl to relative
|
||||
|
@ -357,38 +362,45 @@ IO_ALLOCATION_ACTION FloppyExecuteReadWrite( PDEVICE_OBJECT DeviceObject,
|
|||
ControllerExtension->IsrState = FloppyIsrDetect;
|
||||
ControllerExtension->DpcState = FloppySeekDpc;
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_SEEK );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, DeviceExtension->DriveSelect );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, Cyl );
|
||||
return KeepObject;
|
||||
}
|
||||
//set up DMA and issue read command
|
||||
Length = MediaTypes[DeviceExtension->MediaType].SectorsPerTrack - Sector + 1;
|
||||
// number of sectors untill end of track
|
||||
Length *= 512; // convert to bytes
|
||||
if( Length > Stk->Parameters.Read.Length )
|
||||
Length = Stk->Parameters.Read.Length;
|
||||
DPRINT( "Sector: %d, Length: %d\n", Sector, Length );
|
||||
ControllerExtension->TransferLength = Length;
|
||||
IoMapTransfer( ControllerExtension->AdapterObject,
|
||||
Irp->MdlAddress,
|
||||
ControllerExtension->MapRegisterBase,
|
||||
Irp->Tail.Overlay.DriverContext[0], // current va
|
||||
&MediaTypes[DeviceExtension->MediaType].BytesPerSector,
|
||||
&Length,
|
||||
WriteToDevice );
|
||||
ControllerExtension->IsrState = FloppyIsrReadWrite;
|
||||
ControllerExtension->DpcState = FloppyDpcReadWrite;
|
||||
CHECKPOINT;
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_READ );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, WriteToDevice ? FLOPPY_CMD_WRITE : FLOPPY_CMD_READ );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, ( Head << 2 ) | DeviceExtension->DriveSelect );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, Cyl );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, Head );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, Sector );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, MediaTypes[DeviceExtension->MediaType].SectorSizeCode );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, MediaTypes[DeviceExtension->MediaType].SectorsPerTrack );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, 0 );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, 0xFF );
|
||||
CHECKPOINT;
|
||||
// eventually, the FDC will interrupt and we will read results then
|
||||
|
@ -420,9 +432,9 @@ NTSTATUS STDCALL FloppyDispatchReadWrite(PDEVICE_OBJECT DeviceObject,
|
|||
// store currentva in drivercontext
|
||||
Irp->Tail.Overlay.DriverContext[0] = MmGetMdlVirtualAddress( Irp->MdlAddress );
|
||||
DPRINT( "FloppyDispatchReadWrite: offset = %x, length = %x, va = %x\n",
|
||||
ControllerExtension->CurrentOffset,
|
||||
ControllerExtension->CurrentLength,
|
||||
ControllerExtension->CurrentVa );
|
||||
Stk->Parameters.Read.ByteOffset.u.LowPart,
|
||||
Stk->Parameters.Read.Length,
|
||||
Irp->Tail.Overlay.DriverContext[0] );
|
||||
// Queue IRP
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = Stk->Parameters.Read.Length;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define FLOPPY_REG_DIR 0x0007 /* READ ONLY */
|
||||
#define FLOPPY_DI_DSKCHNG 0x80
|
||||
#define FLOPPY_REG_CCNTL 0x0007 /* WRITE ONLY */
|
||||
#define FLOPPY_CCNTL_1MBIT 0x03
|
||||
|
||||
#define FLOPPY_CMD_RD_TRK 0x02
|
||||
#define FLOPPY_CMD_SPEC_CHARS 0x03
|
||||
|
@ -163,6 +164,7 @@ typedef struct _FLOPPY_CONTROLLER_EXTENSION
|
|||
KDPC MotorSpindownDpc; // DPC for motor spin down
|
||||
PADAPTER_OBJECT AdapterObject; // Adapter object for dma
|
||||
PVOID MapRegisterBase;
|
||||
DWORD TransferLength; // Length of the transfer
|
||||
} FLOPPY_CONTROLLER_EXTENSION, *PFLOPPY_CONTROLLER_EXTENSION;
|
||||
|
||||
typedef struct _FLOPPY_CONTROLLER_PARAMETERS
|
||||
|
|
|
@ -19,9 +19,9 @@ BOOLEAN FloppyIsrDetect( PCONTROLLER_OBJECT Controller )
|
|||
PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension;
|
||||
// Issue read interrupt status, and store the results
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_SNS_INTR );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
ControllerExtension->St0 = FloppyReadDATA( ControllerExtension->PortBase );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
DeviceExtension->Cyl = FloppyReadDATA( ControllerExtension->PortBase );
|
||||
// now queue DPC to set the event
|
||||
IoRequestDpc( ControllerExtension->Device,
|
||||
|
@ -107,23 +107,51 @@ BOOLEAN FloppyIsrReadWrite( PCONTROLLER_OBJECT Controller )
|
|||
{
|
||||
// read result registers from read or write command, and queue dpc to start next operation
|
||||
PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension;
|
||||
BYTE Cyl, Head, Sector;
|
||||
PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension;
|
||||
PIO_STACK_LOCATION Stk = IoGetCurrentIrpStackLocation( ControllerExtension->Irp );
|
||||
BOOLEAN WriteToDevice = Stk->MajorFunction == IRP_MJ_WRITE ? TRUE : FALSE;
|
||||
|
||||
|
||||
ControllerExtension->St0 = FloppyReadDATA( ControllerExtension->PortBase );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
ControllerExtension->St1 = FloppyReadDATA( ControllerExtension->PortBase );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
ControllerExtension->St2 = FloppyReadDATA( ControllerExtension->PortBase );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
FloppyReadDATA( ControllerExtension->PortBase ); // cyl
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
FloppyReadDATA( ControllerExtension->PortBase ); // head
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
FloppyReadDATA( ControllerExtension->PortBase ); // sector
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
Cyl = FloppyReadDATA( ControllerExtension->PortBase ); // cyl
|
||||
KeStallExecutionProcessor( 100 );
|
||||
Head = FloppyReadDATA( ControllerExtension->PortBase ); // head
|
||||
KeStallExecutionProcessor( 100 );
|
||||
Sector = FloppyReadDATA( ControllerExtension->PortBase ); // sector
|
||||
KeStallExecutionProcessor( 100 );
|
||||
ControllerExtension->SectorSizeCode = FloppyReadDATA( ControllerExtension->PortBase );
|
||||
IoRequestDpc( ControllerExtension->Device,
|
||||
ControllerExtension->Irp,
|
||||
Controller );
|
||||
// reprogam for next sector if we are not done reading track
|
||||
/* if( ( ControllerExtension->TransferLength -= ( 128 << ControllerExtension->SectorSizeCode ) ) )
|
||||
{
|
||||
DPRINT1( "ISR reprogramming for next sector: %d\n", Sector );
|
||||
Sector++;
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, WriteToDevice ? FLOPPY_CMD_WRITE : FLOPPY_CMD_READ );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, ( Head << 2 ) | DeviceExtension->DriveSelect );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, Cyl );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, Head );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, Sector );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, ControllerExtension->SectorSizeCode );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, MediaTypes[DeviceExtension->MediaType].SectorsPerTrack );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, 0 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
FloppyWriteDATA( ControllerExtension->PortBase, 0xFF );
|
||||
}
|
||||
else */IoRequestDpc( ControllerExtension->Device,
|
||||
ControllerExtension->Irp,
|
||||
Controller );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -138,9 +166,9 @@ BOOLEAN FloppyIsr(PKINTERRUPT Interrupt, PVOID ServiceContext)
|
|||
// need to make sure interrupt is for us, and add some delay for the damn FDC
|
||||
// without the delay, even though the thing has interrupted, it's still not ready
|
||||
// for us to read the data register.
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
Byte = FloppyReadMSTAT( ControllerExtension->PortBase );
|
||||
KeStallExecutionProcessor( 1000 );
|
||||
KeStallExecutionProcessor( 100 );
|
||||
if( Byte == 0 )
|
||||
{
|
||||
DPRINT( "Ignoring interrupt, MSTAT = 0\n" );
|
||||
|
|
Loading…
Reference in a new issue