Started improving error handling and retries.

svn path=/trunk/; revision=2783
This commit is contained in:
Eric Kohl 2002-03-25 21:56:19 +00:00
parent 5ede96eff7
commit c773562024
5 changed files with 246 additions and 55 deletions

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: atapi.c,v 1.17 2002/03/24 15:29:57 ekohl Exp $
/* $Id: atapi.c,v 1.18 2002/03/25 21:54:41 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS ATAPI miniport driver
@ -203,6 +203,11 @@ static ULONG
AtapiReadWrite(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb);
static UCHAR
AtapiErrorToScsi(PVOID DeviceExtension,
PSCSI_REQUEST_BLOCK Srb);
// ---------------------------------------------------------------- Inlines
void
@ -685,29 +690,10 @@ AtapiInterrupt(IN PVOID DeviceExtension)
DeviceStatus = IDEReadStatus(CommandPortBase);
/* Handle error condition if it exists */
if (DeviceStatus & IDE_SR_ERR)
if ((DeviceStatus & IDE_SR_ERR) &&
(Srb->Cdb[0] != SCSIOP_REQUEST_SENSE))
{
BYTE ErrorReg, SectorCount, SectorNum, CylinderLow, CylinderHigh;
BYTE DriveHead;
/* Log the error */
ErrorReg = IDEReadError(CommandPortBase);
CylinderLow = IDEReadCylinderLow(CommandPortBase);
CylinderHigh = IDEReadCylinderHigh(CommandPortBase);
DriveHead = IDEReadDriveHead(CommandPortBase);
SectorCount = IDEReadSectorCount(CommandPortBase);
SectorNum = IDEReadSectorNum(CommandPortBase);
DPRINT1("ATAPI Error: STAT:%02x ERR:%02x CYLLO:%02x CYLHI:%02x SCNT:%02x SNUM:%02x\n",
DeviceStatus,
ErrorReg,
CylinderLow,
CylinderHigh,
SectorCount,
SectorNum);
/* FIXME: set a useful status code */
/* Report error condition */
Srb->SrbStatus = SRB_STATUS_ERROR;
IsLastBlock = TRUE;
}
@ -823,11 +809,19 @@ AtapiInterrupt(IN PVOID DeviceExtension)
else
{
DPRINT1("Unspecified transfer direction!\n");
Srb->SrbStatus = SRB_STATUS_ERROR;
Srb->SrbStatus = SRB_STATUS_SUCCESS; // SRB_STATUS_ERROR;
IsLastBlock = TRUE;
}
}
if (Srb->SrbStatus == SRB_STATUS_ERROR)
{
Srb->SrbStatus = AtapiErrorToScsi(DeviceExtension,
Srb);
}
/* complete this packet */
if (IsLastBlock)
{
@ -1664,8 +1658,7 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
PSCSI_REQUEST_BLOCK Srb)
{
PIDE_DRIVE_IDENTIFY DeviceParams;
ULONG StartingSector,i;
ULONG StartingSector;
ULONG SectorCount;
UCHAR CylinderHigh;
UCHAR CylinderLow;
@ -1675,7 +1668,6 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
ULONG Retries;
UCHAR Status;
DPRINT("AtapiReadWrite() called!\n");
if ((Srb->PathId != 0) ||
@ -1914,4 +1906,130 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
return(SRB_STATUS_PENDING);
}
static UCHAR
AtapiErrorToScsi(PVOID DeviceExtension,
PSCSI_REQUEST_BLOCK Srb)
{
PATAPI_MINIPORT_EXTENSION DevExt;
ULONG CommandPortBase;
ULONG ControlPortBase;
UCHAR ErrorReg;
UCHAR ScsiStatus;
UCHAR SrbStatus;
DPRINT1("AtapiErrorToScsi() called\n");
DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension;
CommandPortBase = DevExt->CommandPortBase;
ControlPortBase = DevExt->ControlPortBase;
ErrorReg = IDEReadError(CommandPortBase);
if (DevExt->DeviceAtapi[Srb->TargetId])
{
switch (ErrorReg >> 4)
{
case SCSI_SENSE_NO_SENSE:
DPRINT1("ATAPI error: SCSI_SENSE_NO_SENSE\n");
ScsiStatus = SCSISTAT_CHECK_CONDITION;
SrbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_RECOVERED_ERROR:
DPRINT1("ATAPI error: SCSI_SENSE_RECOVERED_SENSE\n");
ScsiStatus = 0;
SrbStatus = SRB_STATUS_SUCCESS;
break;
case SCSI_SENSE_NOT_READY:
DPRINT1("ATAPI error: SCSI_SENSE_NOT_READY\n");
ScsiStatus = SCSISTAT_CHECK_CONDITION;
SrbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_MEDIUM_ERROR:
DPRINT1("ATAPI error: SCSI_SENSE_MEDIUM_ERROR\n");
ScsiStatus = SCSISTAT_CHECK_CONDITION;
SrbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_HARDWARE_ERROR:
DPRINT1("ATAPI error: SCSI_SENSE_HARDWARE_ERROR\n");
ScsiStatus = SCSISTAT_CHECK_CONDITION;
SrbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_ILLEGAL_REQUEST:
DPRINT1("ATAPI error: SCSI_SENSE_ILLEGAL_REQUEST\n");
ScsiStatus = SCSISTAT_CHECK_CONDITION;
SrbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_UNIT_ATTENTION:
DPRINT1("ATAPI error: SCSI_SENSE_UNIT_ATTENTION\n");
ScsiStatus = SCSISTAT_CHECK_CONDITION;
SrbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_DATA_PROTECT:
DPRINT1("ATAPI error: SCSI_SENSE_DATA_PROTECT\n");
ScsiStatus = SCSISTAT_CHECK_CONDITION;
SrbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_BLANK_CHECK:
DPRINT1("ATAPI error: SCSI_SENSE_BLANK_CHECK\n");
ScsiStatus = SCSISTAT_CHECK_CONDITION;
SrbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_ABORTED_COMMAND:
DPRINT1("ATAPI error: SCSI_SENSE_ABORTED_COMMAND\n");
ScsiStatus = SCSISTAT_CHECK_CONDITION;
SrbStatus = SRB_STATUS_ERROR;
break;
default:
DPRINT1("ATAPI error: Invalid sense key\n");
ScsiStatus = 0;
SrbStatus = SRB_STATUS_ERROR;
break;
}
}
else
{
DPRINT1("IDE error: %02x\n", ErrorReg);
ScsiStatus = 0;
#if 0
UCHAR SectorCount, SectorNum, CylinderLow, CylinderHigh;
UCHAR DriveHead;
CylinderLow = IDEReadCylinderLow(CommandPortBase);
CylinderHigh = IDEReadCylinderHigh(CommandPortBase);
DriveHead = IDEReadDriveHead(CommandPortBase);
SectorCount = IDEReadSectorCount(CommandPortBase);
SectorNum = IDEReadSectorNum(CommandPortBase);
DPRINT1("IDE Error: ERR:%02x CYLLO:%02x CYLHI:%02x SCNT:%02x SNUM:%02x\n",
ErrorReg,
CylinderLow,
CylinderHigh,
SectorCount,
SectorNum);
#endif
}
Srb->ScsiStatus = ScsiStatus;
DPRINT1("AtapiErrorToScsi() done\n");
return(SrbStatus);
}
/* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: cdrom.c,v 1.6 2002/03/22 23:05:44 ekohl Exp $
/* $Id: cdrom.c,v 1.7 2002/03/25 21:56:19 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -425,6 +425,23 @@ CdromClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
RtlZeroMemory(CdromData,
sizeof(CDROM_DATA));
DiskDeviceExtension->SenseData = ExAllocatePool(NonPagedPool,
sizeof(SENSE_DATA));
if (DiskDeviceExtension->SenseData == NULL)
{
DPRINT1("Failed to allocate sense data buffer!\n");
IoDeleteDevice(DiskDeviceObject);
/* Release (unclaim) the disk */
ScsiClassClaimDevice(PortDeviceObject,
InquiryData,
TRUE,
NULL);
return(STATUS_INSUFFICIENT_RESOURCES);
}
/* Get disk geometry */
DiskDeviceExtension->DiskGeometry = ExAllocatePool(NonPagedPool,
sizeof(DISK_GEOMETRY));

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: class2.c,v 1.13 2002/03/22 23:06:58 ekohl Exp $
/* $Id: class2.c,v 1.14 2002/03/25 21:55:51 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -145,13 +145,13 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
NextIrpStack = IoGetNextIrpStackLocation(Irp);
StartingOffset = CurrentIrpStack->Parameters.Read.ByteOffset;
/* calculate logical block address */
/* Calculate logical block address */
StartingBlock.QuadPart = StartingOffset.QuadPart >> DeviceExtension->SectorShift;
LogicalBlockAddress = (ULONG)StartingBlock.u.LowPart;
DPRINT("Logical block address: %lu\n", LogicalBlockAddress);
/* allocate and initialize an SRB */
/* Allocate and initialize an SRB */
/* FIXME: use lookaside list instead */
Srb = ExAllocatePool(NonPagedPool,
sizeof(SCSI_REQUEST_BLOCK));
@ -230,7 +230,7 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
}
#endif
/* or in the default flags from the device object. */
/* Update srb flags */
Srb->SrbFlags |= DeviceExtension->SrbFlags;
@ -238,10 +238,8 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
NextIrpStack->Parameters.Scsi.Srb = Srb;
NextIrpStack->DeviceObject = DeviceObject;
#if 0
/* save retry count in current IRP stack */
/* Save retry count in current IRP stack */
CurrentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
#endif
DPRINT("IoSetCompletionRoutine (Irp %p Srb %p)\n", Irp, Srb);
IoSetCompletionRoutine(Irp,
@ -724,7 +722,23 @@ ScsiClassInterpretSenseInfo(PDEVICE_OBJECT DeviceObject,
ULONG RetryCount,
NTSTATUS *Status)
{
UNIMPLEMENTED;
DPRINT1("ScsiClassInterpretSenseInfo() called\n");
DPRINT1("Srb->SrbStatus %lx\n", Srb->SrbStatus);
if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_PENDING)
{
*Status = STATUS_SUCCESS;
}
else
{
*Status = STATUS_UNSUCCESSFUL;
}
DPRINT1("ScsiClassInterpretSenseInfo() done\n");
return(FALSE);
}
@ -736,6 +750,7 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpStack;
PSCSI_REQUEST_BLOCK Srb;
BOOLEAN Retry;
NTSTATUS Status;
DPRINT("ScsiClassIoComplete(DeviceObject %p Irp %p Context %p) called\n",
@ -747,30 +762,36 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
IrpStack = IoGetCurrentIrpStackLocation(Irp);
#if 0
if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS)
{
Status = STATUS_SUCCESS;
}
else
{
/* FIXME: improve error handling */
DPRINT1("Srb->SrbStatus %lx\n", Srb->SrbStatus);
Retry = ScsiClassInterpretSenseInfo(DeviceObject,
Srb,
IrpStack->MajorFunction,
0,
MAXIMUM_RETRIES - ((ULONG)IrpStack->Parameters.Others.Argument4),
&Status);
#if 0
irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_PENDING)
{
Status = STATUS_SUCCESS;
}
else
Status = STATUS_UNSUCCESSFUL;
}
#endif
if (Retry == TRUE)
{
/* FIXME!! */
DPRINT1("Should try again!\n");
}
}
/* FIXME: use lookaside list instead */
DPRINT("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb);
ExFreePool(IrpStack->Parameters.Scsi.Srb);
// Irp->IoStatus.Status = Status;
Irp->IoStatus.Status = Status;
#if 0
if (!NT_SUCCESS(Status) &&
IoIsErrorUserInduced(Status))
@ -797,8 +818,7 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
DPRINT("ScsiClassIoComplete() done (Status %lx)\n", Status);
// return(Status);
return(STATUS_SUCCESS);
return(Status);
}
@ -958,6 +978,8 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION IoStack;
ULONG RequestType;
BOOLEAN Retry;
ULONG RetryCount;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
@ -965,8 +987,10 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
DPRINT("ScsiClassSendSrbSynchronous() called\n");
RetryCount = MAXIMUM_RETRIES;
DeviceExtension = DeviceObject->DeviceExtension;
Srb->Length = SCSI_REQUEST_BLOCK_SIZE;
Srb->PathId = DeviceExtension->PathId;
Srb->TargetId = DeviceExtension->TargetId;
Srb->Lun = DeviceExtension->Lun;
@ -974,6 +998,11 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
/* FIXME: more srb initialization required? */
Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
Srb->SenseInfoBuffer = ExAllocatePool(NonPagedPool,
SENSE_BUFFER_SIZE);
if (Srb->SenseInfoBuffer == NULL)
return(STATUS_INSUFFICIENT_RESOURCES);
if (BufferAddress == NULL)
{
@ -1015,6 +1044,7 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
if (Irp == NULL)
{
DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
ExFreePool(Srb->SenseInfoBuffer);
return(STATUS_INSUFFICIENT_RESOURCES);
}
@ -1041,15 +1071,26 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS)
{
/* FIXME!! */
DPRINT1("Fix return value!\n");
Status = STATUS_UNSUCCESSFUL;
Retry = ScsiClassInterpretSenseInfo(DeviceObject,
Srb,
IRP_MJ_SCSI,
0,
MAXIMUM_RETRIES - RetryCount,
&Status);
if (Retry == TRUE)
{
/* FIXME!! */
DPRINT1("Should try again!\n");
}
}
else
{
Status = STATUS_SUCCESS;
}
ExFreePool(Srb->SenseInfoBuffer);
DPRINT("ScsiClassSendSrbSynchronous() done\n");
return(Status);

View file

@ -1,4 +1,4 @@
/* $Id: class2.h,v 1.3 2002/01/31 14:58:34 ekohl Exp $
/* $Id: class2.h,v 1.4 2002/03/25 21:54:06 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -13,6 +13,8 @@
#include "ntddscsi.h"
#include "srb.h"
#define MAXIMUM_RETRIES 4
struct _CLASS_INIT_DATA;
typedef VOID STDCALL

View file

@ -1,4 +1,4 @@
/* $Id: iotypes.h,v 1.34 2002/03/17 17:53:34 hbirr Exp $
/* $Id: iotypes.h,v 1.35 2002/03/25 21:53:27 ekohl Exp $
*
*/
@ -305,6 +305,11 @@ typedef struct __attribute__((packed)) _IO_STACK_LOCATION
struct _VPB* Vpb;
struct _DEVICE_OBJECT* DeviceObject;
} Mount;
struct
{
struct _VPB* Vpb;
struct _DEVICE_OBJECT* DeviceObject;
} VerifyVolume;
struct
{
ULONG Length;
@ -415,12 +420,20 @@ typedef struct __attribute__((packed)) _IO_STACK_LOCATION
PCM_RESOURCE_LIST AllocatedResourcesTranslated;
} StartDevice;
// Parameters for IRP_MN_SCSI_CLASS
/* Parameters for IRP_MN_SCSI_CLASS */
struct
{
struct _SCSI_REQUEST_BLOCK *Srb;
} Scsi;
/* Paramters for other calls */
struct
{
PVOID Argument1;
PVOID Argument2;
PVOID Argument3;
PVOID Argument4;
} Others;
} Parameters;
struct _DEVICE_OBJECT* DeviceObject;