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:
Phillip Susi 2001-06-18 03:14:24 +00:00
parent d28ae7e82f
commit 439bc219e0
4 changed files with 80 additions and 38 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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" );