mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:42:57 +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
2 changed files with 268 additions and 85 deletions
|
@ -44,7 +44,6 @@
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// To Do:
|
// 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: a timer should be used to watch for device timeouts and errors
|
||||||
// FIXME: errors should be retried
|
// FIXME: errors should be retried
|
||||||
// FIXME: a drive reset/recalibrate should be attempted if errors occur
|
// FIXME: a drive reset/recalibrate should be attempted if errors occur
|
||||||
|
@ -175,7 +174,6 @@ static int IDEPolledRead(IN WORD Address,
|
||||||
IN BYTE DrvHead,
|
IN BYTE DrvHead,
|
||||||
IN BYTE Command,
|
IN BYTE Command,
|
||||||
OUT BYTE *Buffer);
|
OUT BYTE *Buffer);
|
||||||
|
|
||||||
static NTSTATUS IDEDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
static NTSTATUS IDEDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||||
static NTSTATUS IDEDispatchReadWrite(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 NTSTATUS IDEDispatchDeviceControl(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
|
||||||
|
@ -185,11 +183,13 @@ static IO_ALLOCATION_ACTION IDEAllocateController(IN PDEVICE_OBJECT DeviceObjec
|
||||||
IN PVOID MapRegisterBase,
|
IN PVOID MapRegisterBase,
|
||||||
IN PVOID Ccontext);
|
IN PVOID Ccontext);
|
||||||
static BOOLEAN IDEStartController(IN OUT PVOID Context);
|
static BOOLEAN IDEStartController(IN OUT PVOID Context);
|
||||||
|
VOID IDEBeginControllerReset(PIDE_CONTROLLER_EXTENSION ControllerExtension);
|
||||||
static BOOLEAN IDEIsr(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext);
|
static BOOLEAN IDEIsr(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext);
|
||||||
static VOID IDEDpcForIsr(IN PKDPC Dpc,
|
static VOID IDEDpcForIsr(IN PKDPC Dpc,
|
||||||
IN PDEVICE_OBJECT DpcDeviceObject,
|
IN PDEVICE_OBJECT DpcDeviceObject,
|
||||||
IN PIRP DpcIrp,
|
IN PIRP DpcIrp,
|
||||||
IN PVOID DpcContext);
|
IN PVOID DpcContext);
|
||||||
|
static VOID IDEFinishOperation(PIDE_CONTROLLER_EXTENSION ControllerExtension);
|
||||||
static VOID IDEIoTimer(PDEVICE_OBJECT DeviceObject, PVOID Context);
|
static VOID IDEIoTimer(PDEVICE_OBJECT DeviceObject, PVOID Context);
|
||||||
|
|
||||||
// ---------------------------------------------------------------- Inlines
|
// ---------------------------------------------------------------- Inlines
|
||||||
|
@ -393,23 +393,43 @@ IDEResetController(IN WORD CommandPort,
|
||||||
{
|
{
|
||||||
int Retries;
|
int Retries;
|
||||||
|
|
||||||
// Send the controller reset command
|
// Assert drive reset line
|
||||||
IDEWriteDriveControl(ControlPort, IDE_DC_SRST);
|
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);
|
IDEWriteDriveControl(ControlPort, 0);
|
||||||
|
|
||||||
// Loop on status register waiting for controller ready
|
// Wait for BUSY negation
|
||||||
for (Retries = 0; Retries < IDE_MAX_RESET_RETRIES; Retries++)
|
for (Retries = 0; Retries < IDE_RESET_BUSY_TIMEOUT * 1000; Retries++)
|
||||||
{
|
{
|
||||||
if (!(IDEReadStatus(CommandPort) & IDE_SR_BUSY))
|
if (!(IDEReadStatus(CommandPort) & IDE_SR_BUSY))
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
KeStallExecutionProcessor(10);
|
KeStallExecutionProcessor(10);
|
||||||
}
|
}
|
||||||
|
if (Retries >= IDE_RESET_BUSY_TIMEOUT * 1000)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// return TRUE if controller came back to life. and
|
// return TRUE if controller came back to life. and
|
||||||
// the registers are initialized correctly
|
// the registers are initialized correctly
|
||||||
return Retries < IDE_MAX_RESET_RETRIES &&
|
return IDEReadError(CommandPort) == 1 &&
|
||||||
IDEReadError(CommandPort) == 1 &&
|
|
||||||
IDEReadSectorCount(CommandPort) == 1 &&
|
IDEReadSectorCount(CommandPort) == 1 &&
|
||||||
IDEReadSectorNum(CommandPort) == 1 &&
|
IDEReadSectorNum(CommandPort) == 1 &&
|
||||||
IDEReadCylinderLow(CommandPort) == 0 &&
|
IDEReadCylinderLow(CommandPort) == 0 &&
|
||||||
|
@ -723,11 +743,10 @@ IDEGetDriveIdentification(IN int CommandPort,
|
||||||
DrvParms->ECCByteCnt,
|
DrvParms->ECCByteCnt,
|
||||||
DrvParms->FirmwareRev);
|
DrvParms->FirmwareRev);
|
||||||
DPRINT("Model:[%.40s]\n", DrvParms->ModelNumber);
|
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->RWMultImplemented) & 0xff,
|
||||||
DrvParms->DWordIOSupported,
|
(DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED) ? 1 : 0,
|
||||||
(DrvParms->LBADMASupported & 0x0200) ? 1 : 0,
|
(DrvParms->Capabilities & IDE_DRID_DMA_SUPPORTED) ? 1 : 0,
|
||||||
(DrvParms->LBADMASupported & 0x0100) ? 1 : 0,
|
|
||||||
DrvParms->MinPIOTransTime,
|
DrvParms->MinPIOTransTime,
|
||||||
DrvParms->MinDMATransTime);
|
DrvParms->MinDMATransTime);
|
||||||
DPRINT("TM:Cyls:%d Heads:%d Sectors/Trk:%d Capacity:%d\n",
|
DPRINT("TM:Cyls:%d Heads:%d Sectors/Trk:%d Capacity:%d\n",
|
||||||
|
@ -773,7 +792,7 @@ IDEGetPartitionTable(IN int CommandPort,
|
||||||
|
|
||||||
// Get sector at offset
|
// Get sector at offset
|
||||||
SaveOffset = Offset;
|
SaveOffset = Offset;
|
||||||
if (DrvParms->LBADMASupported & 0x0200)
|
if (DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED)
|
||||||
{
|
{
|
||||||
SectorNum = Offset & 0xff;
|
SectorNum = Offset & 0xff;
|
||||||
CylinderLow = (Offset >> 8) & 0xff;
|
CylinderLow = (Offset >> 8) & 0xff;
|
||||||
|
@ -913,8 +932,10 @@ IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
DeviceExtension->DeviceObject = (*DeviceObject);
|
DeviceExtension->DeviceObject = (*DeviceObject);
|
||||||
DeviceExtension->ControllerObject = ControllerObject;
|
DeviceExtension->ControllerObject = ControllerObject;
|
||||||
DeviceExtension->UnitNumber = UnitNumber;
|
DeviceExtension->UnitNumber = UnitNumber;
|
||||||
DeviceExtension->LBASupported = (DrvParms->LBADMASupported & 0x0200) ? 1 : 0;
|
DeviceExtension->LBASupported =
|
||||||
DeviceExtension->DMASupported = (DrvParms->LBADMASupported & 0x0100) ? 1 : 0;
|
(DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED) ? 1 : 0;
|
||||||
|
DeviceExtension->DMASupported =
|
||||||
|
(DrvParms->Capabilities & IDE_DRID_DMA_SUPPORTED) ? 1 : 0;
|
||||||
// FIXME: deal with bizarre sector sizes
|
// FIXME: deal with bizarre sector sizes
|
||||||
DeviceExtension->BytesPerSector = 512 /* DrvParms->BytesPerSector */;
|
DeviceExtension->BytesPerSector = 512 /* DrvParms->BytesPerSector */;
|
||||||
DeviceExtension->SectorsPerLogCyl = DrvParms->LogicalHeads *
|
DeviceExtension->SectorsPerLogCyl = DrvParms->LogicalHeads *
|
||||||
|
@ -1076,7 +1097,7 @@ IDEPolledRead(IN WORD Address,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read data into buffer
|
// Read data into buffer
|
||||||
IDEReadBlock(Address, Buffer);
|
IDEReadBlock(Address, Buffer, IDE_SECTOR_BUF_SZ);
|
||||||
Buffer += IDE_SECTOR_BUF_SZ;
|
Buffer += IDE_SECTOR_BUF_SZ;
|
||||||
|
|
||||||
// Check for more sectors to read
|
// Check for more sectors to read
|
||||||
|
@ -1318,7 +1339,9 @@ IDEStartIo(IN PDEVICE_OBJECT DeviceObject,
|
||||||
DeviceExtension->TargetAddress = (BYTE *)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
DeviceExtension->TargetAddress = (BYTE *)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||||
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
||||||
IoAllocateController(DeviceExtension->ControllerObject,
|
IoAllocateController(DeviceExtension->ControllerObject,
|
||||||
DeviceObject, IDEAllocateController, NULL);
|
DeviceObject,
|
||||||
|
IDEAllocateController,
|
||||||
|
NULL);
|
||||||
KeLowerIrql(OldIrql);
|
KeLowerIrql(OldIrql);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1346,6 +1369,7 @@ IDEAllocateController(IN PDEVICE_OBJECT DeviceObject,
|
||||||
ControllerExtension = (PIDE_CONTROLLER_EXTENSION)
|
ControllerExtension = (PIDE_CONTROLLER_EXTENSION)
|
||||||
DeviceExtension->ControllerObject->ControllerExtension;
|
DeviceExtension->ControllerObject->ControllerExtension;
|
||||||
ControllerExtension->CurrentIrp = Irp;
|
ControllerExtension->CurrentIrp = Irp;
|
||||||
|
ControllerExtension->Retries = 0;
|
||||||
return KeSynchronizeExecution(ControllerExtension->Interrupt,
|
return KeSynchronizeExecution(ControllerExtension->Interrupt,
|
||||||
IDEStartController,
|
IDEStartController,
|
||||||
DeviceExtension) ? KeepObject :
|
DeviceExtension) ? KeepObject :
|
||||||
|
@ -1429,14 +1453,23 @@ IDEStartController(IN OUT PVOID Context)
|
||||||
}
|
}
|
||||||
KeStallExecutionProcessor(10);
|
KeStallExecutionProcessor(10);
|
||||||
}
|
}
|
||||||
/* FIXME: should reset controller and try again */
|
Retries = IDE_MAX_BUSY_RETRIES;
|
||||||
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
||||||
|
{
|
||||||
|
if (++ControllerExtension->Retries > IDE_MAX_CMD_RETRIES)
|
||||||
{
|
{
|
||||||
Irp = ControllerExtension->CurrentIrp;
|
Irp = ControllerExtension->CurrentIrp;
|
||||||
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
return DeallocateObject;
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IDEBeginControllerReset(ControllerExtension);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select the desired drive */
|
/* Select the desired drive */
|
||||||
|
@ -1452,14 +1485,22 @@ IDEStartController(IN OUT PVOID Context)
|
||||||
}
|
}
|
||||||
KeStallExecutionProcessor(10);
|
KeStallExecutionProcessor(10);
|
||||||
}
|
}
|
||||||
/* FIXME: should reset controller and try again */
|
|
||||||
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
||||||
|
{
|
||||||
|
if (ControllerExtension->Retries++ > IDE_MAX_CMD_RETRIES)
|
||||||
{
|
{
|
||||||
Irp = ControllerExtension->CurrentIrp;
|
Irp = ControllerExtension->CurrentIrp;
|
||||||
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
return DeallocateObject;
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IDEBeginControllerReset(ControllerExtension);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup command parameters */
|
/* Setup command parameters */
|
||||||
|
@ -1472,6 +1513,9 @@ IDEStartController(IN OUT PVOID Context)
|
||||||
|
|
||||||
/* Issue command to drive */
|
/* Issue command to drive */
|
||||||
IDEWriteCommand(ControllerExtension->CommandPortBase, Command);
|
IDEWriteCommand(ControllerExtension->CommandPortBase, Command);
|
||||||
|
ControllerExtension->TimerState = IDETimerCmdWait;
|
||||||
|
ControllerExtension->TimerCount = IDE_CMD_TIMEOUT;
|
||||||
|
IoStartTimer(ControllerExtension->TimerDevice);
|
||||||
|
|
||||||
if (DeviceExtension->Operation == IRP_MJ_WRITE)
|
if (DeviceExtension->Operation == IRP_MJ_WRITE)
|
||||||
{
|
{
|
||||||
|
@ -1484,25 +1528,71 @@ IDEStartController(IN OUT PVOID Context)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
KeStallExecutionProcessor(10);
|
||||||
}
|
}
|
||||||
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
if (Retries >= IDE_MAX_BUSY_RETRIES)
|
||||||
|
{
|
||||||
|
if (ControllerExtension->Retries++ > IDE_MAX_CMD_RETRIES)
|
||||||
{
|
{
|
||||||
Irp = ControllerExtension->CurrentIrp;
|
Irp = ControllerExtension->CurrentIrp;
|
||||||
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
return DeallocateObject;
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IDEBeginControllerReset(ControllerExtension);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the first sector of data into the controller
|
// 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->TargetAddress += IDE_SECTOR_BUF_SZ;
|
||||||
DeviceExtension->BytesToTransfer -= DeviceExtension->BytesPerSector;
|
DeviceExtension->BytesToTransfer -= DeviceExtension->BytesPerSector;
|
||||||
|
DeviceExtension->SectorsTransferred++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
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
|
// IDEIsr
|
||||||
//
|
//
|
||||||
// DESCIPTION:
|
// DESCIPTION:
|
||||||
|
@ -1616,7 +1706,9 @@ IDEIsr(IN PKINTERRUPT Interrupt,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the block of data
|
// Copy the block of data
|
||||||
IDEReadBlock(ControllerExtension->CommandPortBase, TargetAddress);
|
IDEReadBlock(ControllerExtension->CommandPortBase,
|
||||||
|
TargetAddress,
|
||||||
|
IDE_SECTOR_BUF_SZ);
|
||||||
|
|
||||||
// check DRQ
|
// check DRQ
|
||||||
if (IsLastBlock)
|
if (IsLastBlock)
|
||||||
|
@ -1716,9 +1808,12 @@ IDEIsr(IN PKINTERRUPT Interrupt,
|
||||||
TargetAddress = DeviceExtension->TargetAddress;
|
TargetAddress = DeviceExtension->TargetAddress;
|
||||||
DeviceExtension->TargetAddress += DeviceExtension->BytesPerSector;
|
DeviceExtension->TargetAddress += DeviceExtension->BytesPerSector;
|
||||||
DeviceExtension->BytesToTransfer -= DeviceExtension->BytesPerSector;
|
DeviceExtension->BytesToTransfer -= DeviceExtension->BytesPerSector;
|
||||||
|
DeviceExtension->SectorsTransferred++;
|
||||||
|
|
||||||
// Write block to controller
|
// Write block to controller
|
||||||
IDEWriteBlock(ControllerExtension->CommandPortBase, TargetAddress);
|
IDEWriteBlock(ControllerExtension->CommandPortBase,
|
||||||
|
TargetAddress,
|
||||||
|
IDE_SECTOR_BUF_SZ);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1727,7 +1822,6 @@ IDEIsr(IN PKINTERRUPT Interrupt,
|
||||||
// If there was an error or the request is done, complete the packet
|
// If there was an error or the request is done, complete the packet
|
||||||
if (AnErrorOccured || RequestIsComplete)
|
if (AnErrorOccured || RequestIsComplete)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Set the return status and info values
|
// Set the return status and info values
|
||||||
Irp = ControllerExtension->CurrentIrp;
|
Irp = ControllerExtension->CurrentIrp;
|
||||||
Irp->IoStatus.Status = ErrorStatus;
|
Irp->IoStatus.Status = ErrorStatus;
|
||||||
|
@ -1768,15 +1862,22 @@ IDEDpcForIsr(IN PKDPC Dpc,
|
||||||
IN PIRP DpcIrp,
|
IN PIRP DpcIrp,
|
||||||
IN PVOID DpcContext)
|
IN PVOID DpcContext)
|
||||||
{
|
{
|
||||||
PIDE_CONTROLLER_EXTENSION ControllerExtension;
|
IDEFinishOperation((PIDE_CONTROLLER_EXTENSION) DpcContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDEFinishOperation
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
IDEFinishOperation(PIDE_CONTROLLER_EXTENSION ControllerExtension)
|
||||||
|
{
|
||||||
PIDE_DEVICE_EXTENSION DeviceExtension;
|
PIDE_DEVICE_EXTENSION DeviceExtension;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
ULONG Operation;
|
ULONG Operation;
|
||||||
|
|
||||||
ControllerExtension = (PIDE_CONTROLLER_EXTENSION) DpcContext;
|
|
||||||
DeviceExtension = ControllerExtension->DeviceForOperation;
|
DeviceExtension = ControllerExtension->DeviceForOperation;
|
||||||
Irp = ControllerExtension->CurrentIrp;
|
Irp = ControllerExtension->CurrentIrp;
|
||||||
Operation = DeviceExtension->Operation;
|
Operation = DeviceExtension->Operation;
|
||||||
|
ControllerExtension->OperationInProgress = FALSE;
|
||||||
ControllerExtension->DeviceForOperation = 0;
|
ControllerExtension->DeviceForOperation = 0;
|
||||||
ControllerExtension->CurrentIrp = 0;
|
ControllerExtension->CurrentIrp = 0;
|
||||||
|
|
||||||
|
@ -1815,9 +1916,49 @@ IDEIoTimer(PDEVICE_OBJECT DeviceObject,
|
||||||
{
|
{
|
||||||
PIDE_CONTROLLER_EXTENSION ControllerExtension;
|
PIDE_CONTROLLER_EXTENSION ControllerExtension;
|
||||||
|
|
||||||
|
DPRINT("entered timer\n");
|
||||||
|
|
||||||
// Setup Extension pointer
|
// Setup Extension pointer
|
||||||
ControllerExtension = (PIDE_CONTROLLER_EXTENSION) Context;
|
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 we're counting down, then count.
|
||||||
if (ControllerExtension->TimerCount > 0)
|
if (ControllerExtension->TimerCount > 0)
|
||||||
{
|
{
|
||||||
|
@ -1831,6 +1972,29 @@ IDEIoTimer(PDEVICE_OBJECT DeviceObject,
|
||||||
{
|
{
|
||||||
case IDETimerIdle:
|
case IDETimerIdle:
|
||||||
break;
|
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_WRITE_RETRIES 1000
|
||||||
#define IDE_MAX_BUSY_RETRIES 100
|
#define IDE_MAX_BUSY_RETRIES 100
|
||||||
#define IDE_MAX_DRQ_RETRIES 1000
|
#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_ALT_STATUS 0x0006
|
||||||
#define IDE_REG_DEV_CNTRL 0x0006 /* device control register */
|
#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 IDEWriteDriveHead(Address, Data) (outb_p((Address) + IDE_REG_DRV_HEAD, (Data)))
|
||||||
#define IDEReadStatus(Address) (inb_p((Address) + IDE_REG_STATUS))
|
#define IDEReadStatus(Address) (inb_p((Address) + IDE_REG_STATUS))
|
||||||
#define IDEWriteCommand(Address, Data) (outb_p((Address) + IDE_REG_COMMAND, (Data)))
|
#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
|
// Access macros for control registers
|
||||||
|
@ -130,7 +140,10 @@ typedef struct _IDE_DEVICE_EXTENSION {
|
||||||
//
|
//
|
||||||
|
|
||||||
typedef enum _IDE_TIMER_STATES {
|
typedef enum _IDE_TIMER_STATES {
|
||||||
IDETimerIdle
|
IDETimerIdle,
|
||||||
|
IDETimerCmdWait,
|
||||||
|
IDETimerResetWaitForBusyNegate,
|
||||||
|
IDETimerResetWaitForDrdyAssert
|
||||||
} IDE_TIMER_STATES;
|
} IDE_TIMER_STATES;
|
||||||
|
|
||||||
// IDE_CONTROLLER_EXTENSION
|
// IDE_CONTROLLER_EXTENSION
|
||||||
|
@ -157,6 +170,7 @@ typedef struct _IDE_CONTROLLER_EXTENSION {
|
||||||
BYTE DeviceStatus;
|
BYTE DeviceStatus;
|
||||||
PIDE_DEVICE_EXTENSION DeviceForOperation;
|
PIDE_DEVICE_EXTENSION DeviceForOperation;
|
||||||
PIRP CurrentIrp;
|
PIRP CurrentIrp;
|
||||||
|
int Retries;
|
||||||
|
|
||||||
IDE_TIMER_STATES TimerState;
|
IDE_TIMER_STATES TimerState;
|
||||||
LONG TimerCount;
|
LONG TimerCount;
|
||||||
|
@ -186,8 +200,13 @@ typedef struct _IDE_DRIVE_IDENTIFY {
|
||||||
char FirmwareRev[8]; /*23*/
|
char FirmwareRev[8]; /*23*/
|
||||||
char ModelNumber[40]; /*27*/
|
char ModelNumber[40]; /*27*/
|
||||||
WORD RWMultImplemented; /*47*/
|
WORD RWMultImplemented; /*47*/
|
||||||
WORD DWordIOSupported; /*48*/
|
WORD Reserved48; /*48*/
|
||||||
WORD LBADMASupported; /*49*/
|
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 Reserved50; /*50*/
|
||||||
WORD MinPIOTransTime; /*51*/
|
WORD MinPIOTransTime; /*51*/
|
||||||
WORD MinDMATransTime; /*52*/
|
WORD MinDMATransTime; /*52*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue