mirror of
https://github.com/reactos/reactos.git
synced 2024-09-27 21:16:34 +00:00
Added Fix for >255 sector read/write and first hack at timeout code
svn path=/trunk/; revision=76
This commit is contained in:
parent
267b8c4e8c
commit
e68e2e431a
|
@ -44,7 +44,6 @@
|
|||
//
|
||||
//
|
||||
// To Do:
|
||||
// FIXME: reads/writes that cause multiple calls to setup to device should be tested.
|
||||
// FIXME: a timer should be used to watch for device timeouts and errors
|
||||
// FIXME: errors should be retried
|
||||
// FIXME: a drive reset/recalibrate should be attempted if errors occur
|
||||
|
@ -140,32 +139,32 @@ static int TotalPartitions = 0;
|
|||
|
||||
// ---------------------------------------------------- Forward Declarations
|
||||
|
||||
static BOOLEAN IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PIDE_CONTROLLER_PARAMETERS ControllerParams,
|
||||
IN int ControllerIdx);
|
||||
static BOOLEAN IDEResetController(IN WORD CommandPort, IN WORD ControlPort);
|
||||
static BOOLEAN IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PCONTROLLER_OBJECT ControllerObject,
|
||||
IN PIDE_CONTROLLER_EXTENSION ControllerExtension,
|
||||
IN int DriveIdx,
|
||||
IN int HarddiskIdx);
|
||||
static BOOLEAN IDEGetDriveIdentification(IN int CommandPort,
|
||||
IN int DriveNum,
|
||||
OUT PIDE_DRIVE_IDENTIFY DrvParms);
|
||||
static BOOLEAN IDEGetPartitionTable(IN int CommandPort,
|
||||
IN int DriveNum,
|
||||
IN int Offset,
|
||||
IN PIDE_DRIVE_IDENTIFY DrvParms,
|
||||
PARTITION *PartitionTable);
|
||||
static NTSTATUS IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PCHAR DeviceName,
|
||||
OUT PDEVICE_OBJECT *DeviceObject,
|
||||
IN PCONTROLLER_OBJECT ControllerObject,
|
||||
IN int UnitNumber,
|
||||
IN char *Win32Alias,
|
||||
IN PIDE_DRIVE_IDENTIFY DrvParms,
|
||||
IN DWORD Offset,
|
||||
IN DWORD Size);
|
||||
static BOOLEAN IDECreateController(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PIDE_CONTROLLER_PARAMETERS ControllerParams,
|
||||
IN int ControllerIdx);
|
||||
static BOOLEAN IDEResetController(IN WORD CommandPort, IN WORD ControlPort);
|
||||
static BOOLEAN IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PCONTROLLER_OBJECT ControllerObject,
|
||||
IN PIDE_CONTROLLER_EXTENSION ControllerExtension,
|
||||
IN int DriveIdx,
|
||||
IN int HarddiskIdx);
|
||||
static BOOLEAN IDEGetDriveIdentification(IN int CommandPort,
|
||||
IN int DriveNum,
|
||||
OUT PIDE_DRIVE_IDENTIFY DrvParms);
|
||||
static BOOLEAN IDEGetPartitionTable(IN int CommandPort,
|
||||
IN int DriveNum,
|
||||
IN int Offset,
|
||||
IN PIDE_DRIVE_IDENTIFY DrvParms,
|
||||
PARTITION *PartitionTable);
|
||||
static NTSTATUS IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PCHAR DeviceName,
|
||||
OUT PDEVICE_OBJECT *DeviceObject,
|
||||
IN PCONTROLLER_OBJECT ControllerObject,
|
||||
IN int UnitNumber,
|
||||
IN char *Win32Alias,
|
||||
IN PIDE_DRIVE_IDENTIFY DrvParms,
|
||||
IN DWORD Offset,
|
||||
IN DWORD Size);
|
||||
static int IDEPolledRead(IN WORD Address,
|
||||
IN BYTE PreComp,
|
||||
IN BYTE SectorCnt,
|
||||
|
@ -175,22 +174,23 @@ static int IDEPolledRead(IN WORD Address,
|
|||
IN BYTE DrvHead,
|
||||
IN BYTE Command,
|
||||
OUT BYTE *Buffer);
|
||||
|
||||
static NTSTATUS IDEDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||
static NTSTATUS IDEDispatchReadWrite(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||
static NTSTATUS IDEDispatchDeviceControl(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||
static VOID IDEStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
||||
static IO_ALLOCATION_ACTION IDEAllocateController(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID MapRegisterBase,
|
||||
IN PVOID Ccontext);
|
||||
static BOOLEAN IDEStartController(IN OUT PVOID Context);
|
||||
static BOOLEAN IDEIsr(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext);
|
||||
static VOID IDEDpcForIsr(IN PKDPC Dpc,
|
||||
IN PDEVICE_OBJECT DpcDeviceObject,
|
||||
IN PIRP DpcIrp,
|
||||
IN PVOID DpcContext);
|
||||
static VOID IDEIoTimer(PDEVICE_OBJECT DeviceObject, PVOID Context);
|
||||
static NTSTATUS IDEDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||
static NTSTATUS IDEDispatchReadWrite(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||
static NTSTATUS IDEDispatchDeviceControl(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||
static VOID IDEStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
||||
static IO_ALLOCATION_ACTION IDEAllocateController(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID MapRegisterBase,
|
||||
IN PVOID Ccontext);
|
||||
static BOOLEAN IDEStartController(IN OUT PVOID Context);
|
||||
VOID IDEBeginControllerReset(PIDE_CONTROLLER_EXTENSION ControllerExtension);
|
||||
static BOOLEAN IDEIsr(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext);
|
||||
static VOID IDEDpcForIsr(IN PKDPC Dpc,
|
||||
IN PDEVICE_OBJECT DpcDeviceObject,
|
||||
IN PIRP DpcIrp,
|
||||
IN PVOID DpcContext);
|
||||
static VOID IDEFinishOperation(PIDE_CONTROLLER_EXTENSION ControllerExtension);
|
||||
static VOID IDEIoTimer(PDEVICE_OBJECT DeviceObject, PVOID Context);
|
||||
|
||||
// ---------------------------------------------------------------- Inlines
|
||||
|
||||
|
@ -393,23 +393,43 @@ IDEResetController(IN WORD CommandPort,
|
|||
{
|
||||
int Retries;
|
||||
|
||||
// Send the controller reset command
|
||||
// Assert drive reset line
|
||||
IDEWriteDriveControl(ControlPort, IDE_DC_SRST);
|
||||
KeStallExecutionProcessor(50);
|
||||
|
||||
// Wait for BUSY assertion
|
||||
for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES; Retries++)
|
||||
{
|
||||
if (IDEReadStatus(CommandPort) & IDE_SR_BUSY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
KeStallExecutionProcessor(10);
|
||||
}
|
||||
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Negate drive reset line
|
||||
IDEWriteDriveControl(ControlPort, 0);
|
||||
|
||||
// Loop on status register waiting for controller ready
|
||||
for (Retries = 0; Retries < IDE_MAX_RESET_RETRIES; Retries++)
|
||||
// Wait for BUSY negation
|
||||
for (Retries = 0; Retries < IDE_RESET_BUSY_TIMEOUT * 1000; Retries++)
|
||||
{
|
||||
if (!(IDEReadStatus(CommandPort) & IDE_SR_BUSY))
|
||||
break;
|
||||
{
|
||||
break;
|
||||
}
|
||||
KeStallExecutionProcessor(10);
|
||||
}
|
||||
if (Retries >= IDE_RESET_BUSY_TIMEOUT * 1000)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// return TRUE if controller came back to life. and
|
||||
// the registers are initialized correctly
|
||||
return Retries < IDE_MAX_RESET_RETRIES &&
|
||||
IDEReadError(CommandPort) == 1 &&
|
||||
return IDEReadError(CommandPort) == 1 &&
|
||||
IDEReadSectorCount(CommandPort) == 1 &&
|
||||
IDEReadSectorNum(CommandPort) == 1 &&
|
||||
IDEReadCylinderLow(CommandPort) == 0 &&
|
||||
|
@ -723,11 +743,10 @@ IDEGetDriveIdentification(IN int CommandPort,
|
|||
DrvParms->ECCByteCnt,
|
||||
DrvParms->FirmwareRev);
|
||||
DPRINT("Model:[%.40s]\n", DrvParms->ModelNumber);
|
||||
DPRINT("RWMult?:%02x DWrdIO?:%d LBA:%d DMA:%d MinPIO:%d ns MinDMA:%d ns\n",
|
||||
DPRINT("RWMult?:%02x LBA:%d DMA:%d MinPIO:%d ns MinDMA:%d ns\n",
|
||||
(DrvParms->RWMultImplemented) & 0xff,
|
||||
DrvParms->DWordIOSupported,
|
||||
(DrvParms->LBADMASupported & 0x0200) ? 1 : 0,
|
||||
(DrvParms->LBADMASupported & 0x0100) ? 1 : 0,
|
||||
(DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED) ? 1 : 0,
|
||||
(DrvParms->Capabilities & IDE_DRID_DMA_SUPPORTED) ? 1 : 0,
|
||||
DrvParms->MinPIOTransTime,
|
||||
DrvParms->MinDMATransTime);
|
||||
DPRINT("TM:Cyls:%d Heads:%d Sectors/Trk:%d Capacity:%d\n",
|
||||
|
@ -773,7 +792,7 @@ IDEGetPartitionTable(IN int CommandPort,
|
|||
|
||||
// Get sector at offset
|
||||
SaveOffset = Offset;
|
||||
if (DrvParms->LBADMASupported & 0x0200)
|
||||
if (DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED)
|
||||
{
|
||||
SectorNum = Offset & 0xff;
|
||||
CylinderLow = (Offset >> 8) & 0xff;
|
||||
|
@ -913,8 +932,10 @@ IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
|
|||
DeviceExtension->DeviceObject = (*DeviceObject);
|
||||
DeviceExtension->ControllerObject = ControllerObject;
|
||||
DeviceExtension->UnitNumber = UnitNumber;
|
||||
DeviceExtension->LBASupported = (DrvParms->LBADMASupported & 0x0200) ? 1 : 0;
|
||||
DeviceExtension->DMASupported = (DrvParms->LBADMASupported & 0x0100) ? 1 : 0;
|
||||
DeviceExtension->LBASupported =
|
||||
(DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED) ? 1 : 0;
|
||||
DeviceExtension->DMASupported =
|
||||
(DrvParms->Capabilities & IDE_DRID_DMA_SUPPORTED) ? 1 : 0;
|
||||
// FIXME: deal with bizarre sector sizes
|
||||
DeviceExtension->BytesPerSector = 512 /* DrvParms->BytesPerSector */;
|
||||
DeviceExtension->SectorsPerLogCyl = DrvParms->LogicalHeads *
|
||||
|
@ -1076,7 +1097,7 @@ IDEPolledRead(IN WORD Address,
|
|||
}
|
||||
|
||||
// Read data into buffer
|
||||
IDEReadBlock(Address, Buffer);
|
||||
IDEReadBlock(Address, Buffer, IDE_SECTOR_BUF_SZ);
|
||||
Buffer += IDE_SECTOR_BUF_SZ;
|
||||
|
||||
// Check for more sectors to read
|
||||
|
@ -1318,7 +1339,9 @@ IDEStartIo(IN PDEVICE_OBJECT DeviceObject,
|
|||
DeviceExtension->TargetAddress = (BYTE *)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
||||
IoAllocateController(DeviceExtension->ControllerObject,
|
||||
DeviceObject, IDEAllocateController, NULL);
|
||||
DeviceObject,
|
||||
IDEAllocateController,
|
||||
NULL);
|
||||
KeLowerIrql(OldIrql);
|
||||
break;
|
||||
|
||||
|
@ -1346,6 +1369,7 @@ IDEAllocateController(IN PDEVICE_OBJECT DeviceObject,
|
|||
ControllerExtension = (PIDE_CONTROLLER_EXTENSION)
|
||||
DeviceExtension->ControllerObject->ControllerExtension;
|
||||
ControllerExtension->CurrentIrp = Irp;
|
||||
ControllerExtension->Retries = 0;
|
||||
return KeSynchronizeExecution(ControllerExtension->Interrupt,
|
||||
IDEStartController,
|
||||
DeviceExtension) ? KeepObject :
|
||||
|
@ -1429,14 +1453,23 @@ IDEStartController(IN OUT PVOID Context)
|
|||
}
|
||||
KeStallExecutionProcessor(10);
|
||||
}
|
||||
/* FIXME: should reset controller and try again */
|
||||
Retries = IDE_MAX_BUSY_RETRIES;
|
||||
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
||||
{
|
||||
Irp = ControllerExtension->CurrentIrp;
|
||||
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
if (++ControllerExtension->Retries > IDE_MAX_CMD_RETRIES)
|
||||
{
|
||||
Irp = ControllerExtension->CurrentIrp;
|
||||
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
return DeallocateObject;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
IDEBeginControllerReset(ControllerExtension);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Select the desired drive */
|
||||
|
@ -1452,14 +1485,22 @@ IDEStartController(IN OUT PVOID Context)
|
|||
}
|
||||
KeStallExecutionProcessor(10);
|
||||
}
|
||||
/* FIXME: should reset controller and try again */
|
||||
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
||||
{
|
||||
Irp = ControllerExtension->CurrentIrp;
|
||||
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
if (ControllerExtension->Retries++ > IDE_MAX_CMD_RETRIES)
|
||||
{
|
||||
Irp = ControllerExtension->CurrentIrp;
|
||||
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
return DeallocateObject;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
IDEBeginControllerReset(ControllerExtension);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup command parameters */
|
||||
|
@ -1472,7 +1513,10 @@ IDEStartController(IN OUT PVOID Context)
|
|||
|
||||
/* Issue command to drive */
|
||||
IDEWriteCommand(ControllerExtension->CommandPortBase, Command);
|
||||
|
||||
ControllerExtension->TimerState = IDETimerCmdWait;
|
||||
ControllerExtension->TimerCount = IDE_CMD_TIMEOUT;
|
||||
IoStartTimer(ControllerExtension->TimerDevice);
|
||||
|
||||
if (DeviceExtension->Operation == IRP_MJ_WRITE)
|
||||
{
|
||||
|
||||
|
@ -1484,25 +1528,71 @@ IDEStartController(IN OUT PVOID Context)
|
|||
{
|
||||
break;
|
||||
}
|
||||
KeStallExecutionProcessor(10);
|
||||
}
|
||||
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
||||
{
|
||||
Irp = ControllerExtension->CurrentIrp;
|
||||
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
if (ControllerExtension->Retries++ > IDE_MAX_CMD_RETRIES)
|
||||
{
|
||||
Irp = ControllerExtension->CurrentIrp;
|
||||
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
return DeallocateObject;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
IDEBeginControllerReset(ControllerExtension);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Load the first sector of data into the controller
|
||||
IDEWriteBlock(ControllerExtension->CommandPortBase, DeviceExtension->TargetAddress);
|
||||
IDEWriteBlock(ControllerExtension->CommandPortBase,
|
||||
DeviceExtension->TargetAddress,
|
||||
IDE_SECTOR_BUF_SZ);
|
||||
DeviceExtension->TargetAddress += IDE_SECTOR_BUF_SZ;
|
||||
DeviceExtension->BytesToTransfer -= DeviceExtension->BytesPerSector;
|
||||
DeviceExtension->SectorsTransferred++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// IDEBeginControllerReset
|
||||
|
||||
VOID
|
||||
IDEBeginControllerReset(PIDE_CONTROLLER_EXTENSION ControllerExtension)
|
||||
{
|
||||
int Retries;
|
||||
|
||||
// Assert drive reset line
|
||||
IDEWriteDriveControl(ControllerExtension->ControlPortBase, IDE_DC_SRST);
|
||||
|
||||
// FIXME: wait for BSY assertion
|
||||
for (Retries = 0; Retries < IDE_MAX_RESET_RETRIES; Retries++)
|
||||
{
|
||||
BYTE Status = IDEReadStatus(ControllerExtension->CommandPortBase);
|
||||
if ((Status & IDE_SR_BUSY))
|
||||
{
|
||||
break;
|
||||
}
|
||||
KeStallExecutionProcessor(10);
|
||||
}
|
||||
|
||||
// Negate drive reset line
|
||||
IDEWriteDriveControl(ControllerExtension->ControlPortBase, 0);
|
||||
|
||||
// FIXME: handle case of no device 0
|
||||
|
||||
// FIXME: set timer to check for end of reset
|
||||
ControllerExtension->TimerState = IDETimerResetWaitForBusyNegate;
|
||||
ControllerExtension->TimerCount = IDE_RESET_BUSY_TIMEOUT;
|
||||
IoStartTimer(ControllerExtension->TimerDevice);
|
||||
|
||||
}
|
||||
|
||||
// IDEIsr
|
||||
//
|
||||
// DESCIPTION:
|
||||
|
@ -1616,7 +1706,9 @@ IDEIsr(IN PKINTERRUPT Interrupt,
|
|||
}
|
||||
|
||||
// Copy the block of data
|
||||
IDEReadBlock(ControllerExtension->CommandPortBase, TargetAddress);
|
||||
IDEReadBlock(ControllerExtension->CommandPortBase,
|
||||
TargetAddress,
|
||||
IDE_SECTOR_BUF_SZ);
|
||||
|
||||
// check DRQ
|
||||
if (IsLastBlock)
|
||||
|
@ -1716,9 +1808,12 @@ IDEIsr(IN PKINTERRUPT Interrupt,
|
|||
TargetAddress = DeviceExtension->TargetAddress;
|
||||
DeviceExtension->TargetAddress += DeviceExtension->BytesPerSector;
|
||||
DeviceExtension->BytesToTransfer -= DeviceExtension->BytesPerSector;
|
||||
DeviceExtension->SectorsTransferred++;
|
||||
|
||||
// Write block to controller
|
||||
IDEWriteBlock(ControllerExtension->CommandPortBase, TargetAddress);
|
||||
IDEWriteBlock(ControllerExtension->CommandPortBase,
|
||||
TargetAddress,
|
||||
IDE_SECTOR_BUF_SZ);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1727,7 +1822,6 @@ IDEIsr(IN PKINTERRUPT Interrupt,
|
|||
// If there was an error or the request is done, complete the packet
|
||||
if (AnErrorOccured || RequestIsComplete)
|
||||
{
|
||||
|
||||
// Set the return status and info values
|
||||
Irp = ControllerExtension->CurrentIrp;
|
||||
Irp->IoStatus.Status = ErrorStatus;
|
||||
|
@ -1768,15 +1862,22 @@ IDEDpcForIsr(IN PKDPC Dpc,
|
|||
IN PIRP DpcIrp,
|
||||
IN PVOID DpcContext)
|
||||
{
|
||||
PIDE_CONTROLLER_EXTENSION ControllerExtension;
|
||||
IDEFinishOperation((PIDE_CONTROLLER_EXTENSION) DpcContext);
|
||||
}
|
||||
|
||||
// IDEFinishOperation
|
||||
|
||||
static VOID
|
||||
IDEFinishOperation(PIDE_CONTROLLER_EXTENSION ControllerExtension)
|
||||
{
|
||||
PIDE_DEVICE_EXTENSION DeviceExtension;
|
||||
PIRP Irp;
|
||||
ULONG Operation;
|
||||
|
||||
ControllerExtension = (PIDE_CONTROLLER_EXTENSION) DpcContext;
|
||||
DeviceExtension = ControllerExtension->DeviceForOperation;
|
||||
Irp = ControllerExtension->CurrentIrp;
|
||||
Operation = DeviceExtension->Operation;
|
||||
ControllerExtension->OperationInProgress = FALSE;
|
||||
ControllerExtension->DeviceForOperation = 0;
|
||||
ControllerExtension->CurrentIrp = 0;
|
||||
|
||||
|
@ -1815,9 +1916,49 @@ IDEIoTimer(PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
PIDE_CONTROLLER_EXTENSION ControllerExtension;
|
||||
|
||||
DPRINT("entered timer\n");
|
||||
|
||||
// Setup Extension pointer
|
||||
ControllerExtension = (PIDE_CONTROLLER_EXTENSION) Context;
|
||||
|
||||
// Handle state change if necessary
|
||||
switch (ControllerExtension->TimerState)
|
||||
{
|
||||
case IDETimerResetWaitForBusyNegate:
|
||||
if (!(IDEReadStatus(ControllerExtension->CommandPortBase) &
|
||||
IDE_SR_BUSY))
|
||||
{
|
||||
ControllerExtension->TimerState = IDETimerResetWaitForDrdyAssert;
|
||||
ControllerExtension->TimerCount = IDE_RESET_DRDY_TIMEOUT;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDETimerResetWaitForDrdyAssert:
|
||||
if (IDEReadStatus(ControllerExtension->CommandPortBase) &
|
||||
IDE_SR_DRQ)
|
||||
{
|
||||
ControllerExtension->TimerState = IDETimerIdle;
|
||||
ControllerExtension->TimerCount = 0;
|
||||
IoStopTimer(ControllerExtension->TimerDevice);
|
||||
|
||||
// FIXME: get diagnostic code from drive 0
|
||||
|
||||
// Start current packet command again
|
||||
if (!KeSynchronizeExecution(ControllerExtension->Interrupt,
|
||||
IDEStartController,
|
||||
ControllerExtension->DeviceForOperation))
|
||||
{
|
||||
IDEFinishOperation(ControllerExtension);
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// If we're counting down, then count.
|
||||
if (ControllerExtension->TimerCount > 0)
|
||||
{
|
||||
|
@ -1831,6 +1972,29 @@ IDEIoTimer(PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
case IDETimerIdle:
|
||||
break;
|
||||
|
||||
case IDETimerCmdWait:
|
||||
// Command timed out, reset drive and try again or fail
|
||||
if (++ControllerExtension->Retries > IDE_MAX_CMD_RETRIES)
|
||||
{
|
||||
ControllerExtension->CurrentIrp->IoStatus.Status = STATUS_IO_TIMEOUT;
|
||||
ControllerExtension->CurrentIrp->IoStatus.Information = 0;
|
||||
IoStopTimer(ControllerExtension->TimerDevice);
|
||||
IDEFinishOperation(ControllerExtension);
|
||||
}
|
||||
else
|
||||
{
|
||||
IDEBeginControllerReset(ControllerExtension);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDETimerResetWaitForBusyNegate:
|
||||
case IDETimerResetWaitForDrdyAssert:
|
||||
ControllerExtension->CurrentIrp->IoStatus.Status = STATUS_IO_TIMEOUT;
|
||||
ControllerExtension->CurrentIrp->IoStatus.Information = 0;
|
||||
IoStopTimer(ControllerExtension->TimerDevice);
|
||||
IDEFinishOperation(ControllerExtension);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,10 @@ extern "C" {
|
|||
#define IDE_MAX_WRITE_RETRIES 1000
|
||||
#define IDE_MAX_BUSY_RETRIES 100
|
||||
#define IDE_MAX_DRQ_RETRIES 1000
|
||||
#define IDE_MAX_CMD_RETRIES 1
|
||||
#define IDE_CMD_TIMEOUT 5
|
||||
#define IDE_RESET_BUSY_TIMEOUT 31
|
||||
#define IDE_RESET_DRDY_TIMEOUT 120
|
||||
|
||||
#define IDE_REG_ALT_STATUS 0x0006
|
||||
#define IDE_REG_DEV_CNTRL 0x0006 /* device control register */
|
||||
|
@ -80,8 +84,14 @@ extern "C" {
|
|||
#define IDEWriteDriveHead(Address, Data) (outb_p((Address) + IDE_REG_DRV_HEAD, (Data)))
|
||||
#define IDEReadStatus(Address) (inb_p((Address) + IDE_REG_STATUS))
|
||||
#define IDEWriteCommand(Address, Data) (outb_p((Address) + IDE_REG_COMMAND, (Data)))
|
||||
#define IDEReadBlock(Address, Buffer) (insw((Address) + IDE_REG_DATA_PORT, (Buffer), IDE_SECTOR_BUF_SZ / 2))
|
||||
#define IDEWriteBlock(Address, Buffer) (outsw((Address) + IDE_REG_DATA_PORT, (Buffer), IDE_SECTOR_BUF_SZ / 2))
|
||||
|
||||
//
|
||||
// Data block read and write commands
|
||||
//
|
||||
#define IDEReadBlock(Address, Buffer, Count) \
|
||||
(insw((Address) + IDE_REG_DATA_PORT, (Buffer), (Count) / 2))
|
||||
#define IDEWriteBlock(Address, Buffer, Count) \
|
||||
(outsw((Address) + IDE_REG_DATA_PORT, (Buffer), (Count) / 2))
|
||||
|
||||
//
|
||||
// Access macros for control registers
|
||||
|
@ -130,7 +140,10 @@ typedef struct _IDE_DEVICE_EXTENSION {
|
|||
//
|
||||
|
||||
typedef enum _IDE_TIMER_STATES {
|
||||
IDETimerIdle
|
||||
IDETimerIdle,
|
||||
IDETimerCmdWait,
|
||||
IDETimerResetWaitForBusyNegate,
|
||||
IDETimerResetWaitForDrdyAssert
|
||||
} IDE_TIMER_STATES;
|
||||
|
||||
// IDE_CONTROLLER_EXTENSION
|
||||
|
@ -157,6 +170,7 @@ typedef struct _IDE_CONTROLLER_EXTENSION {
|
|||
BYTE DeviceStatus;
|
||||
PIDE_DEVICE_EXTENSION DeviceForOperation;
|
||||
PIRP CurrentIrp;
|
||||
int Retries;
|
||||
|
||||
IDE_TIMER_STATES TimerState;
|
||||
LONG TimerCount;
|
||||
|
@ -186,8 +200,13 @@ typedef struct _IDE_DRIVE_IDENTIFY {
|
|||
char FirmwareRev[8]; /*23*/
|
||||
char ModelNumber[40]; /*27*/
|
||||
WORD RWMultImplemented; /*47*/
|
||||
WORD DWordIOSupported; /*48*/
|
||||
WORD LBADMASupported; /*49*/
|
||||
WORD Reserved48; /*48*/
|
||||
WORD Capabilities; /*49*/
|
||||
#define IDE_DRID_STBY_SUPPORTED 0x2000
|
||||
#define IDE_DRID_IORDY_SUPPORTED 0x0800
|
||||
#define IDE_DRID_IORDY_DISABLE 0x0400
|
||||
#define IDE_DRID_LBA_SUPPORTED 0x0200
|
||||
#define IDE_DRID_DMA_SUPPORTED 0x0100
|
||||
WORD Reserved50; /*50*/
|
||||
WORD MinPIOTransTime; /*51*/
|
||||
WORD MinDMATransTime; /*52*/
|
||||
|
|
Loading…
Reference in a new issue