From dc3c360885639e158ecb79e723680f3056c7b14d Mon Sep 17 00:00:00 2001 From: Phillip Susi Date: Thu, 26 Apr 2001 01:24:31 +0000 Subject: [PATCH] Floppy driver updates, managed to boot system from floppy svn path=/trunk/; revision=1824 --- reactos/drivers/dd/floppy/dpc.c | 78 ++++++++++++++++++++++++------ reactos/drivers/dd/floppy/floppy.c | 55 ++++++++++++++++----- reactos/drivers/dd/floppy/floppy.h | 25 ++++++---- reactos/drivers/dd/floppy/isr.c | 8 +-- 4 files changed, 127 insertions(+), 39 deletions(-) diff --git a/reactos/drivers/dd/floppy/dpc.c b/reactos/drivers/dd/floppy/dpc.c index 7c4eabfc0c9..b08ebec8d9c 100644 --- a/reactos/drivers/dd/floppy/dpc.c +++ b/reactos/drivers/dd/floppy/dpc.c @@ -5,6 +5,7 @@ ***************************************************************************/ #include +#define NDEBUG #include #include "floppy.h" @@ -16,7 +17,6 @@ VOID FloppyDpc( PKDPC Dpc, { PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)Context; PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension; - CHECKPOINT1; ControllerExtension->DpcState( Dpc, DeviceObject, Irp, @@ -31,7 +31,6 @@ VOID FloppyDpcDetect( PKDPC Dpc, { PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)Context; PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension; - CHECKPOINT1; KeSetEvent( &ControllerExtension->Event, 0, FALSE ); } @@ -40,8 +39,8 @@ VOID FloppyDpcFailIrp( PKDPC Dpc, PIRP Irp, PVOID Context ) { - CHECKPOINT1; Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY; + CHECKPOINT; IoCompleteRequest( Irp, 0 ); } @@ -54,7 +53,6 @@ VOID FloppyMotorSpindownDpc( PKDPC Dpc, PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension; PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension; - CHECKPOINT1; // queue call to turn off motor IoAllocateController( Controller, ControllerExtension->Device, @@ -72,7 +70,6 @@ VOID FloppyMotorSpinupDpc( PKDPC Dpc, PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension; LARGE_INTEGER Timeout; - CHECKPOINT1; Timeout.QuadPart = FLOPPY_MOTOR_SPINDOWN_TIME; // Motor has had time to spin up, mark motor as spun up and restart IRP // don't forget to set the spindown timer @@ -88,6 +85,38 @@ VOID FloppyMotorSpinupDpc( PKDPC Dpc, ControllerExtension->Irp ); } +VOID FloppySeekDpc( PKDPC Dpc, + PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Context ) +{ + PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)DeviceExtension->Controller->ControllerExtension; + + // if the seek failed, fail the IRP + if( ControllerExtension->St0 & FLOPPY_ST0_GDMASK ) + { + ControllerExtension->Irp->IoStatus.Status = STATUS_DISK_CORRUPT_ERROR; + ControllerExtension->Irp->IoStatus.Information = 0; + DPRINT( "Failing IRP: St0 = %2x, St1 = %2x, St2 = %2x\n", + ControllerExtension->St0, + ControllerExtension->St1, + ControllerExtension->St2 ); + for(;;); + IoCompleteRequest( ControllerExtension->Irp, 0 ); + IoFreeController( DeviceExtension->Controller ); + return; + } + KeStallExecutionProcessor( 10000000 ); + DPRINT( "Seek completed, now on cyl %2x\n", DeviceExtension->Cyl ); + // now that we are on the right cyl, restart the read + if( FloppyExecuteReadWrite( DeviceObject, + ControllerExtension->Irp, + ControllerExtension->MapRegisterBase, + ControllerExtension->Irp ) == DeallocateObject ) + IoFreeController( DeviceExtension->Controller ); +} + VOID FloppyDpcReadWrite( PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, @@ -95,26 +124,48 @@ VOID FloppyDpcReadWrite( PKDPC Dpc, { PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)Context; PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension; + PFLOPPY_DEVICE_EXTENSION DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)ControllerExtension->Device->DeviceExtension; DWORD SectorSize = 128 << ControllerExtension->SectorSizeCode; + PIO_STACK_LOCATION Stk = IoGetCurrentIrpStackLocation( ControllerExtension->Irp ); + BOOLEAN WriteToDevice = Stk->MajorFunction == IRP_MJ_WRITE ? TRUE : FALSE; - CHECKPOINT1; Irp = ControllerExtension->Irp; // if the IO failed, fail the IRP if( ControllerExtension->St0 & FLOPPY_ST0_GDMASK ) { Irp->IoStatus.Status = STATUS_DISK_CORRUPT_ERROR; Irp->IoStatus.Information = 0; + DPRINT( "Failing IRP: St0 = %2x, St1 = %2x, St2 = %2x\n", + ControllerExtension->St0, + ControllerExtension->St1, + ControllerExtension->St2 ); + for(;;); IoCompleteRequest( Irp, 0 ); - CHECKPOINT1; + IoFreeController( Controller ); return; } - ControllerExtension->CurrentOffset += SectorSize; - ControllerExtension->CurrentLength -= SectorSize; - (char *)ControllerExtension->CurrentVa += SectorSize; + // don't forget to flush the buffers + IoFlushAdapterBuffers( ControllerExtension->AdapterObject, + ControllerExtension->Irp->MdlAddress, + ControllerExtension->MapRegisterBase, + ControllerExtension->Irp->Tail.Overlay.DriverContext[0], + MediaTypes[DeviceExtension->MediaType].BytesPerSector, + 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; + // drivercontext used for current va + (DWORD)ControllerExtension->Irp->Tail.Overlay.DriverContext[0] += SectorSize; + + DPRINT( "First dword: %x\n", *((DWORD *)ControllerExtension->MapRegisterBase) ) + // if there is more IO to be done, restart execute routine to issue next read - if( ControllerExtension->CurrentLength ) + if( Stk->Parameters.Read.Length ) { - CHECKPOINT1; if( FloppyExecuteReadWrite( DeviceObject, Irp, ControllerExtension->MapRegisterBase, @@ -122,7 +173,7 @@ VOID FloppyDpcReadWrite( PKDPC Dpc, IoFreeController( Controller ); } else { - CHECKPOINT1; + IoFreeController( Controller ); // oetherwise, complete the Irp IoCompleteRequest( Irp, 0 ); } @@ -134,7 +185,6 @@ VOID FloppyDpcDetectMedia( PKDPC Dpc, { PCONTROLLER_OBJECT Controller = (PCONTROLLER_OBJECT)Context; PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension; - CHECKPOINT1; // If the read ID failed, fail the irp if( ControllerExtension->St1 != 0 ) { diff --git a/reactos/drivers/dd/floppy/floppy.c b/reactos/drivers/dd/floppy/floppy.c index c3d98ac454e..9276608e952 100644 --- a/reactos/drivers/dd/floppy/floppy.c +++ b/reactos/drivers/dd/floppy/floppy.c @@ -17,7 +17,7 @@ #include #include "floppy.h" - +#define NDEBUG #include @@ -28,7 +28,7 @@ FLOPPY_CONTROLLER_PARAMETERS ControllerParameters[FLOPPY_MAX_CONTROLLERS] = }; const FLOPPY_MEDIA_TYPE MediaTypes[] = { - { 0x02, 9, 80, 18, 512 }, + { 0x02, 80, 2, 18, 512 }, { 0, 0, 0, 0, 0 } }; @@ -41,6 +41,7 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, PFLOPPY_CONTROLLER_EXTENSION ControllerExtension; PFLOPPY_DEVICE_EXTENSION DeviceExtension; UNICODE_STRING DeviceName; + UNICODE_STRING arcname; UNICODE_STRING SymlinkName; NTSTATUS Status; PDEVICE_OBJECT DeviceObject; @@ -182,6 +183,7 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, DPRINT( "MSTAT: %2x\n", FloppyReadMSTAT( ControllerExtension->PortBase ) ); FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_RECAL ); DPRINT( "MSTAT: %2x\n", FloppyReadMSTAT( ControllerExtension->PortBase ) ); + KeStallExecutionProcessor( 10000 ); FloppyWriteDATA( ControllerExtension->PortBase, 0 ); // drive select Timeout.QuadPart = FLOPPY_RECAL_TIMEOUT; Status = KeWaitForSingleObject( &ControllerExtension->Event, @@ -199,6 +201,7 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, DbgPrint( "Floppy: error recalibrating drive, ST0: %2x\n", (DWORD)ControllerExtension->St0 ); goto interruptcleanup; } + DeviceExtension->Cyl = 0; // drive is good, and it is now on track 0, turn off the motor FloppyWriteDOR( ControllerExtension->PortBase, FLOPPY_DOR_ENABLE | FLOPPY_DOR_DMA ); /* Initialize the device */ @@ -234,6 +237,9 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, } // Ok, we own the adapter object, from now on we can just IoMapTransfer, and not // bother releasing the adapter ever. + + RtlInitUnicodeString( &arcname, L"\\ArcName\\multi(0)disk(0)fdisk(0)" ); + Status = IoAssignArcName( &arcname, &DeviceName ); DbgPrint( "Floppy drive initialized\n" ); return TRUE; @@ -273,13 +279,15 @@ IO_ALLOCATION_ACTION FloppyExecuteReadWrite( PDEVICE_OBJECT DeviceObject, PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)DeviceExtension->Controller->ControllerExtension; LARGE_INTEGER Timeout; BOOLEAN WriteToDevice; - UCHAR Cyl, Sector, Head; + DWORD Cyl, Sector, Head; + PIO_STACK_LOCATION Stk; ControllerExtension->Irp = Irp = (PIRP)Context; + Stk = IoGetCurrentIrpStackLocation( Irp ); ControllerExtension->Device = DeviceObject; Timeout.QuadPart = FLOPPY_MOTOR_SPINUP_TIME; CHECKPOINT; - WriteToDevice = IoGetCurrentIrpStackLocation( Irp )->MajorFunction == IRP_MJ_WRITE ? TRUE : FALSE; + WriteToDevice = Stk->MajorFunction == IRP_MJ_WRITE ? TRUE : FALSE; // verify drive is spun up and selected if( ControllerExtension->MotorOn != DeviceExtension->DriveSelect ) { @@ -296,7 +304,14 @@ IO_ALLOCATION_ACTION FloppyExecuteReadWrite( PDEVICE_OBJECT DeviceObject, &ControllerExtension->MotorSpinupDpc ); return KeepObject; } - + else { + Timeout.QuadPart = FLOPPY_MOTOR_SPINDOWN_TIME; + // motor is already spinning, so reset the spindown timer + KeCancelTimer( &ControllerExtension->SpinupTimer ); + KeSetTimer( &ControllerExtension->SpinupTimer, + Timeout, + &ControllerExtension->MotorSpindownDpc ); + } // verify media content if( FloppyReadDIR( ControllerExtension->PortBase ) & FLOPPY_DI_DSKCHNG ) { @@ -322,21 +337,37 @@ IO_ALLOCATION_ACTION FloppyExecuteReadWrite( PDEVICE_OBJECT DeviceObject, } // looks like we have media in the drive.... do the read // first, calculate geometry for read - Sector = ControllerExtension->CurrentOffset / MediaTypes[DeviceExtension->MediaType].BytesPerSector; + 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 ); Head = Cyl % MediaTypes[DeviceExtension->MediaType].Heads; + DPRINT( "Head = %2x\n", Head ); // convert absolute cyl to relative Cyl /= MediaTypes[DeviceExtension->MediaType].Heads; // convert absolute sector to relative Sector %= MediaTypes[DeviceExtension->MediaType].SectorsPerTrack; Sector++; // track relative sector numbers are 1 based, not 0 based DPRINT( "Cyl = %2x, Head = %2x, Sector = %2x\n", Cyl, Head, Sector ); + + // seek if we need to seek + if( DeviceExtension->Cyl != Cyl ) + { + DPRINT( "Seeking...\n" ); + ControllerExtension->IsrState = FloppyIsrDetect; + ControllerExtension->DpcState = FloppySeekDpc; + FloppyWriteDATA( ControllerExtension->PortBase, FLOPPY_CMD_SEEK ); + KeStallExecutionProcessor( 1000 ); + FloppyWriteDATA( ControllerExtension->PortBase, DeviceExtension->DriveSelect ); + KeStallExecutionProcessor( 1000 ); + FloppyWriteDATA( ControllerExtension->PortBase, Cyl ); + return KeepObject; + } //set up DMA and issue read command IoMapTransfer( ControllerExtension->AdapterObject, Irp->MdlAddress, ControllerExtension->MapRegisterBase, - ControllerExtension->CurrentVa, + Irp->Tail.Overlay.DriverContext[0], // current va &MediaTypes[DeviceExtension->MediaType].BytesPerSector, WriteToDevice ); ControllerExtension->IsrState = FloppyIsrReadWrite; @@ -386,17 +417,15 @@ NTSTATUS STDCALL FloppyDispatchReadWrite(PDEVICE_OBJECT DeviceObject, IoCompleteRequest( Irp, 1 ); return STATUS_INVALID_PARAMETER; } - ControllerExtension->CurrentOffset = Stk->Parameters.Read.ByteOffset.u.LowPart; - ControllerExtension->CurrentLength = Stk->Parameters.Read.Length; - ControllerExtension->CurrentVa = MmGetMdlVirtualAddress( Irp->MdlAddress ); + // 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 ); - // Queue IRP Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = ControllerExtension->CurrentLength; + Irp->IoStatus.Information = Stk->Parameters.Read.Length; IoMarkIrpPending( Irp ); KeRaiseIrql( DISPATCH_LEVEL, &oldlvl ); IoAllocateController( ((PFLOPPY_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Controller, @@ -404,6 +433,7 @@ NTSTATUS STDCALL FloppyDispatchReadWrite(PDEVICE_OBJECT DeviceObject, FloppyExecuteReadWrite, Irp ); KeLowerIrql( oldlvl ); + DPRINT( "oldlvl = %x\n", oldlvl ); return STATUS_PENDING; } @@ -473,3 +503,4 @@ NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject, } /* EOF */ + diff --git a/reactos/drivers/dd/floppy/floppy.h b/reactos/drivers/dd/floppy/floppy.h index 2f1fada6ac1..7f6f9ae60d2 100644 --- a/reactos/drivers/dd/floppy/floppy.h +++ b/reactos/drivers/dd/floppy/floppy.h @@ -116,6 +116,8 @@ typedef struct _FLOPPY_MEDIA_TYPE ULONG BytesPerSector; } FLOPPY_MEDIA_TYPE; +extern const FLOPPY_MEDIA_TYPE MediaTypes[]; + #define FDP_DEBUG 0x02 #define FDP_SILENT_DCL_CLEAR 0x04 #define FDP_MSG 0x10 @@ -123,19 +125,20 @@ typedef struct _FLOPPY_MEDIA_TYPE #define FDP_INVERTED_DCL 0x80 // time to hold reset line low -#define FLOPPY_RESET_TIME 1000 -#define FLOPPY_MOTOR_SPINUP_TIME -10000000 -#define FLOPPY_MOTOR_SPINDOWN_TIME -30000000 -#define FLOPPY_RECAL_TIMEOUT -5000000 +#define FLOPPY_RESET_TIME 50000 +#define FLOPPY_MOTOR_SPINUP_TIME -15000000 +#define FLOPPY_MOTOR_SPINDOWN_TIME -50000000 +#define FLOPPY_RECAL_TIMEOUT -30000000 typedef BOOLEAN (*FloppyIsrStateRoutine)( PCONTROLLER_OBJECT Controller ); typedef PIO_DPC_ROUTINE FloppyDpcStateRoutine; typedef struct _FLOPPY_DEVICE_EXTENSION { - PCONTROLLER_OBJECT Controller; - CHAR DriveSelect; - ULONG MediaType; // Media type index + PCONTROLLER_OBJECT Controller; + CHAR DriveSelect; + CHAR Cyl; // current cylinder + ULONG MediaType; // Media type index } FLOPPY_DEVICE_EXTENSION, *PFLOPPY_DEVICE_EXTENSION; typedef struct _FLOPPY_CONTROLLER_EXTENSION @@ -160,9 +163,6 @@ typedef struct _FLOPPY_CONTROLLER_EXTENSION KDPC MotorSpindownDpc; // DPC for motor spin down PADAPTER_OBJECT AdapterObject; // Adapter object for dma PVOID MapRegisterBase; - DWORD CurrentOffset; - DWORD CurrentLength; // offset and length of next operation - PVOID CurrentVa; // current VA offset for IoMapTransfer } FLOPPY_CONTROLLER_EXTENSION, *PFLOPPY_CONTROLLER_EXTENSION; typedef struct _FLOPPY_CONTROLLER_PARAMETERS @@ -202,6 +202,11 @@ VOID FloppyMotorSpinupDpc( PKDPC Dpc, PVOID Arg1, PVOID Arg2 ); +VOID FloppySeekDpc( PKDPC Dpc, + PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Context ); + VOID FloppyMotorSpindownDpc( PKDPC Dpc, PVOID Context, PVOID Arg1, diff --git a/reactos/drivers/dd/floppy/isr.c b/reactos/drivers/dd/floppy/isr.c index 0842c6e1036..fc7b78829b9 100644 --- a/reactos/drivers/dd/floppy/isr.c +++ b/reactos/drivers/dd/floppy/isr.c @@ -5,6 +5,7 @@ ***********************************************************************/ #include +#define NDEBUG #include #include "floppy.h" @@ -15,12 +16,13 @@ BOOLEAN FloppyIsrDetect( PCONTROLLER_OBJECT Controller ) { PFLOPPY_CONTROLLER_EXTENSION ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)Controller->ControllerExtension; + 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 ); ControllerExtension->St0 = FloppyReadDATA( ControllerExtension->PortBase ); KeStallExecutionProcessor( 1000 ); - FloppyReadDATA( ControllerExtension->PortBase ); // ignore cyl + DeviceExtension->Cyl = FloppyReadDATA( ControllerExtension->PortBase ); // now queue DPC to set the event IoRequestDpc( ControllerExtension->Device, 0, @@ -106,7 +108,6 @@ 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; - CHECKPOINT1; ControllerExtension->St0 = FloppyReadDATA( ControllerExtension->PortBase ); KeStallExecutionProcessor( 1000 ); ControllerExtension->St1 = FloppyReadDATA( ControllerExtension->PortBase ); @@ -120,7 +121,6 @@ BOOLEAN FloppyIsrReadWrite( PCONTROLLER_OBJECT Controller ) FloppyReadDATA( ControllerExtension->PortBase ); // sector KeStallExecutionProcessor( 1000 ); ControllerExtension->SectorSizeCode = FloppyReadDATA( ControllerExtension->PortBase ); - CHECKPOINT1; IoRequestDpc( ControllerExtension->Device, ControllerExtension->Irp, Controller ); @@ -138,7 +138,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 ); Byte = FloppyReadMSTAT( ControllerExtension->PortBase ); + KeStallExecutionProcessor( 1000 ); if( Byte == 0 ) { DPRINT( "Ignoring interrupt, MSTAT = 0\n" );