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 * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS ATAPI miniport driver * PROJECT: ReactOS ATAPI miniport driver
@ -203,6 +203,11 @@ static ULONG
AtapiReadWrite(IN PATAPI_MINIPORT_EXTENSION DeviceExtension, AtapiReadWrite(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb); IN PSCSI_REQUEST_BLOCK Srb);
static UCHAR
AtapiErrorToScsi(PVOID DeviceExtension,
PSCSI_REQUEST_BLOCK Srb);
// ---------------------------------------------------------------- Inlines // ---------------------------------------------------------------- Inlines
void void
@ -685,29 +690,10 @@ AtapiInterrupt(IN PVOID DeviceExtension)
DeviceStatus = IDEReadStatus(CommandPortBase); 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; /* Report error condition */
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 */
Srb->SrbStatus = SRB_STATUS_ERROR; Srb->SrbStatus = SRB_STATUS_ERROR;
IsLastBlock = TRUE; IsLastBlock = TRUE;
} }
@ -823,11 +809,19 @@ AtapiInterrupt(IN PVOID DeviceExtension)
else else
{ {
DPRINT1("Unspecified transfer direction!\n"); DPRINT1("Unspecified transfer direction!\n");
Srb->SrbStatus = SRB_STATUS_ERROR; Srb->SrbStatus = SRB_STATUS_SUCCESS; // SRB_STATUS_ERROR;
IsLastBlock = TRUE; IsLastBlock = TRUE;
} }
} }
if (Srb->SrbStatus == SRB_STATUS_ERROR)
{
Srb->SrbStatus = AtapiErrorToScsi(DeviceExtension,
Srb);
}
/* complete this packet */ /* complete this packet */
if (IsLastBlock) if (IsLastBlock)
{ {
@ -1664,8 +1658,7 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
PSCSI_REQUEST_BLOCK Srb) PSCSI_REQUEST_BLOCK Srb)
{ {
PIDE_DRIVE_IDENTIFY DeviceParams; PIDE_DRIVE_IDENTIFY DeviceParams;
ULONG StartingSector;
ULONG StartingSector,i;
ULONG SectorCount; ULONG SectorCount;
UCHAR CylinderHigh; UCHAR CylinderHigh;
UCHAR CylinderLow; UCHAR CylinderLow;
@ -1675,7 +1668,6 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
ULONG Retries; ULONG Retries;
UCHAR Status; UCHAR Status;
DPRINT("AtapiReadWrite() called!\n"); DPRINT("AtapiReadWrite() called!\n");
if ((Srb->PathId != 0) || if ((Srb->PathId != 0) ||
@ -1914,4 +1906,130 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
return(SRB_STATUS_PENDING); 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 */ /* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -425,6 +425,23 @@ CdromClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
RtlZeroMemory(CdromData, RtlZeroMemory(CdromData,
sizeof(CDROM_DATA)); 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 */ /* Get disk geometry */
DiskDeviceExtension->DiskGeometry = ExAllocatePool(NonPagedPool, DiskDeviceExtension->DiskGeometry = ExAllocatePool(NonPagedPool,
sizeof(DISK_GEOMETRY)); sizeof(DISK_GEOMETRY));

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -145,13 +145,13 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
NextIrpStack = IoGetNextIrpStackLocation(Irp); NextIrpStack = IoGetNextIrpStackLocation(Irp);
StartingOffset = CurrentIrpStack->Parameters.Read.ByteOffset; StartingOffset = CurrentIrpStack->Parameters.Read.ByteOffset;
/* calculate logical block address */ /* Calculate logical block address */
StartingBlock.QuadPart = StartingOffset.QuadPart >> DeviceExtension->SectorShift; StartingBlock.QuadPart = StartingOffset.QuadPart >> DeviceExtension->SectorShift;
LogicalBlockAddress = (ULONG)StartingBlock.u.LowPart; LogicalBlockAddress = (ULONG)StartingBlock.u.LowPart;
DPRINT("Logical block address: %lu\n", LogicalBlockAddress); DPRINT("Logical block address: %lu\n", LogicalBlockAddress);
/* allocate and initialize an SRB */ /* Allocate and initialize an SRB */
/* FIXME: use lookaside list instead */ /* FIXME: use lookaside list instead */
Srb = ExAllocatePool(NonPagedPool, Srb = ExAllocatePool(NonPagedPool,
sizeof(SCSI_REQUEST_BLOCK)); sizeof(SCSI_REQUEST_BLOCK));
@ -230,7 +230,7 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
} }
#endif #endif
/* or in the default flags from the device object. */ /* Update srb flags */
Srb->SrbFlags |= DeviceExtension->SrbFlags; Srb->SrbFlags |= DeviceExtension->SrbFlags;
@ -238,10 +238,8 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
NextIrpStack->Parameters.Scsi.Srb = Srb; NextIrpStack->Parameters.Scsi.Srb = Srb;
NextIrpStack->DeviceObject = DeviceObject; 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; CurrentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
#endif
DPRINT("IoSetCompletionRoutine (Irp %p Srb %p)\n", Irp, Srb); DPRINT("IoSetCompletionRoutine (Irp %p Srb %p)\n", Irp, Srb);
IoSetCompletionRoutine(Irp, IoSetCompletionRoutine(Irp,
@ -724,7 +722,23 @@ ScsiClassInterpretSenseInfo(PDEVICE_OBJECT DeviceObject,
ULONG RetryCount, ULONG RetryCount,
NTSTATUS *Status) 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; PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpStack; PIO_STACK_LOCATION IrpStack;
PSCSI_REQUEST_BLOCK Srb; PSCSI_REQUEST_BLOCK Srb;
BOOLEAN Retry;
NTSTATUS Status; NTSTATUS Status;
DPRINT("ScsiClassIoComplete(DeviceObject %p Irp %p Context %p) called\n", DPRINT("ScsiClassIoComplete(DeviceObject %p Irp %p Context %p) called\n",
@ -747,30 +762,36 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
IrpStack = IoGetCurrentIrpStackLocation(Irp); IrpStack = IoGetCurrentIrpStackLocation(Irp);
#if 0
if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS) if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS)
{ {
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
else else
{ {
/* FIXME: improve error handling */ Retry = ScsiClassInterpretSenseInfo(DeviceObject,
DPRINT1("Srb->SrbStatus %lx\n", Srb->SrbStatus); 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 #endif
if (Retry == TRUE)
{
/* FIXME!! */
DPRINT1("Should try again!\n");
}
}
/* FIXME: use lookaside list instead */ /* FIXME: use lookaside list instead */
DPRINT("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb); DPRINT("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb);
ExFreePool(IrpStack->Parameters.Scsi.Srb); ExFreePool(IrpStack->Parameters.Scsi.Srb);
// Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
#if 0 #if 0
if (!NT_SUCCESS(Status) && if (!NT_SUCCESS(Status) &&
IoIsErrorUserInduced(Status)) IoIsErrorUserInduced(Status))
@ -797,8 +818,7 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
DPRINT("ScsiClassIoComplete() done (Status %lx)\n", Status); DPRINT("ScsiClassIoComplete() done (Status %lx)\n", Status);
// return(Status); return(Status);
return(STATUS_SUCCESS);
} }
@ -958,6 +978,8 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
ULONG RequestType; ULONG RequestType;
BOOLEAN Retry;
ULONG RetryCount;
KEVENT Event; KEVENT Event;
PIRP Irp; PIRP Irp;
NTSTATUS Status; NTSTATUS Status;
@ -965,8 +987,10 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
DPRINT("ScsiClassSendSrbSynchronous() called\n"); DPRINT("ScsiClassSendSrbSynchronous() called\n");
RetryCount = MAXIMUM_RETRIES;
DeviceExtension = DeviceObject->DeviceExtension; DeviceExtension = DeviceObject->DeviceExtension;
Srb->Length = SCSI_REQUEST_BLOCK_SIZE;
Srb->PathId = DeviceExtension->PathId; Srb->PathId = DeviceExtension->PathId;
Srb->TargetId = DeviceExtension->TargetId; Srb->TargetId = DeviceExtension->TargetId;
Srb->Lun = DeviceExtension->Lun; Srb->Lun = DeviceExtension->Lun;
@ -974,6 +998,11 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
/* FIXME: more srb initialization required? */ /* 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) if (BufferAddress == NULL)
{ {
@ -1015,6 +1044,7 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
if (Irp == NULL) if (Irp == NULL)
{ {
DPRINT1("IoBuildDeviceIoControlRequest() failed\n"); DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
ExFreePool(Srb->SenseInfoBuffer);
return(STATUS_INSUFFICIENT_RESOURCES); return(STATUS_INSUFFICIENT_RESOURCES);
} }
@ -1041,15 +1071,26 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS) if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS)
{ {
/* FIXME!! */ Retry = ScsiClassInterpretSenseInfo(DeviceObject,
DPRINT1("Fix return value!\n"); Srb,
Status = STATUS_UNSUCCESSFUL; IRP_MJ_SCSI,
0,
MAXIMUM_RETRIES - RetryCount,
&Status);
if (Retry == TRUE)
{
/* FIXME!! */
DPRINT1("Should try again!\n");
}
} }
else else
{ {
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
ExFreePool(Srb->SenseInfoBuffer);
DPRINT("ScsiClassSendSrbSynchronous() done\n"); DPRINT("ScsiClassSendSrbSynchronous() done\n");
return(Status); 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -13,6 +13,8 @@
#include "ntddscsi.h" #include "ntddscsi.h"
#include "srb.h" #include "srb.h"
#define MAXIMUM_RETRIES 4
struct _CLASS_INIT_DATA; struct _CLASS_INIT_DATA;
typedef VOID STDCALL 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 _VPB* Vpb;
struct _DEVICE_OBJECT* DeviceObject; struct _DEVICE_OBJECT* DeviceObject;
} Mount; } Mount;
struct
{
struct _VPB* Vpb;
struct _DEVICE_OBJECT* DeviceObject;
} VerifyVolume;
struct struct
{ {
ULONG Length; ULONG Length;
@ -415,12 +420,20 @@ typedef struct __attribute__((packed)) _IO_STACK_LOCATION
PCM_RESOURCE_LIST AllocatedResourcesTranslated; PCM_RESOURCE_LIST AllocatedResourcesTranslated;
} StartDevice; } StartDevice;
// Parameters for IRP_MN_SCSI_CLASS /* Parameters for IRP_MN_SCSI_CLASS */
struct struct
{ {
struct _SCSI_REQUEST_BLOCK *Srb; struct _SCSI_REQUEST_BLOCK *Srb;
} Scsi; } Scsi;
/* Paramters for other calls */
struct
{
PVOID Argument1;
PVOID Argument2;
PVOID Argument3;
PVOID Argument4;
} Others;
} Parameters; } Parameters;
struct _DEVICE_OBJECT* DeviceObject; struct _DEVICE_OBJECT* DeviceObject;