mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Added mapping of scsi error codes to status codes.
Retries are still disabled. svn path=/trunk/; revision=2816
This commit is contained in:
parent
6c88e069c4
commit
bcde238ede
1 changed files with 169 additions and 18 deletions
|
@ -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.14 2002/03/25 21:55:51 ekohl Exp $
|
/* $Id: class2.c,v 1.15 2002/04/01 23:51:09 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -39,6 +39,7 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
// #define ENABLE_RETRIES
|
||||||
|
|
||||||
#define VERSION "0.0.1"
|
#define VERSION "0.0.1"
|
||||||
|
|
||||||
|
@ -67,6 +68,10 @@ static NTSTATUS STDCALL
|
||||||
ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
|
ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp);
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
ScsiClassRetryRequest(PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp,
|
||||||
|
PSCSI_REQUEST_BLOCK Srb);
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
@ -213,33 +218,29 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
|
||||||
Cdb->CDB10.OperationCode = SCSIOP_WRITE;
|
Cdb->CDB10.OperationCode = SCSIOP_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* if this is not a write-through request, then allow caching */
|
/* if this is not a write-through request, then allow caching */
|
||||||
if (!(CurrentIrpStack->Flags & SL_WRITE_THROUGH))
|
if (!(CurrentIrpStack->Flags & SL_WRITE_THROUGH))
|
||||||
{
|
{
|
||||||
Srb->SrbFlags |= SRB_FLAGS_ADAPTER_CACHE_ENABLE;
|
Srb->SrbFlags |= SRB_FLAGS_ADAPTER_CACHE_ENABLE;
|
||||||
}
|
}
|
||||||
else
|
else if (DeviceExtension->DeviceFlags & DEV_WRITE_CACHE)
|
||||||
{
|
{
|
||||||
/* if write caching is enable then force media access in the cdb */
|
/* if write caching is enable then force media access in the cdb */
|
||||||
if (DeviceExtension->DeviceFlags & DEV_WRITE_CACHE)
|
Cdb->CDB10.ForceUnitAccess = TRUE;
|
||||||
{
|
|
||||||
Cdb->CDB10.ForceUnitAccess = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Update srb flags */
|
/* Update srb flags */
|
||||||
Srb->SrbFlags |= DeviceExtension->SrbFlags;
|
Srb->SrbFlags |= DeviceExtension->SrbFlags;
|
||||||
|
|
||||||
|
/* Initialize next stack location */
|
||||||
NextIrpStack->MajorFunction = IRP_MJ_SCSI;
|
NextIrpStack->MajorFunction = IRP_MJ_SCSI;
|
||||||
NextIrpStack->Parameters.Scsi.Srb = Srb;
|
NextIrpStack->Parameters.Scsi.Srb = Srb;
|
||||||
NextIrpStack->DeviceObject = DeviceObject;
|
NextIrpStack->DeviceObject = DeviceObject;
|
||||||
|
|
||||||
/* Save retry count in current IRP stack */
|
/* Set retry count */
|
||||||
CurrentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
|
NextIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
|
||||||
|
|
||||||
DPRINT("IoSetCompletionRoutine (Irp %p Srb %p)\n", Irp, Srb);
|
DPRINT("IoSetCompletionRoutine (Irp %p Srb %p)\n", Irp, Srb);
|
||||||
IoSetCompletionRoutine(Irp,
|
IoSetCompletionRoutine(Irp,
|
||||||
|
@ -722,6 +723,9 @@ ScsiClassInterpretSenseInfo(PDEVICE_OBJECT DeviceObject,
|
||||||
ULONG RetryCount,
|
ULONG RetryCount,
|
||||||
NTSTATUS *Status)
|
NTSTATUS *Status)
|
||||||
{
|
{
|
||||||
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
|
PSENSE_DATA SenseData;
|
||||||
|
BOOLEAN Retry;
|
||||||
|
|
||||||
DPRINT1("ScsiClassInterpretSenseInfo() called\n");
|
DPRINT1("ScsiClassInterpretSenseInfo() called\n");
|
||||||
|
|
||||||
|
@ -730,15 +734,92 @@ ScsiClassInterpretSenseInfo(PDEVICE_OBJECT DeviceObject,
|
||||||
if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_PENDING)
|
if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_PENDING)
|
||||||
{
|
{
|
||||||
*Status = STATUS_SUCCESS;
|
*Status = STATUS_SUCCESS;
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
|
SenseData = Srb->SenseInfoBuffer;
|
||||||
|
Retry = TRUE;
|
||||||
|
|
||||||
|
if ((Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID) &&
|
||||||
|
(Srb->SenseInfoBufferLength > 0))
|
||||||
|
{
|
||||||
|
/* Got valid sense data, interpret them */
|
||||||
|
|
||||||
|
DPRINT1("ErrorCode: %x\n", SenseData->ErrorCode);
|
||||||
|
DPRINT1("SenseKey: %x\n", SenseData->SenseKey);
|
||||||
|
DPRINT1("SenseCode: %x\n", SenseData->AdditionalSenseCode);
|
||||||
|
|
||||||
|
switch (SenseData->SenseKey & 0xf)
|
||||||
|
{
|
||||||
|
/* FIXME: add more sense key codes */
|
||||||
|
|
||||||
|
case SCSI_SENSE_NOT_READY:
|
||||||
|
DPRINT1("SCSI_SENSE_NOT_READY\n");
|
||||||
|
*Status = STATUS_DEVICE_NOT_READY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCSI_SENSE_UNIT_ATTENTION:
|
||||||
|
DPRINT1("SCSI_SENSE_UNIT_ATTENTION\n");
|
||||||
|
if ((DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
|
||||||
|
(DeviceObject->Vpb->Flags & VPB_MOUNTED))
|
||||||
|
{
|
||||||
|
DeviceObject->Flags |= DO_VERIFY_VOLUME;
|
||||||
|
*Status = STATUS_VERIFY_REQUIRED;
|
||||||
|
Retry = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*Status = STATUS_IO_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCSI_SENSE_ILLEGAL_REQUEST:
|
||||||
|
DPRINT1("SCSI_SENSE_ILLEGAL_REQUEST\n");
|
||||||
|
*Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
Retry = FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
DPRINT1("SCSI error (sense key: %x)\n",
|
||||||
|
SenseData->SenseKey & 0xf);
|
||||||
|
*Status = STATUS_IO_DEVICE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*Status = STATUS_UNSUCCESSFUL;
|
/* Got no/invalid sense data, return generic error codes */
|
||||||
|
switch (SRB_STATUS(Srb->SrbStatus))
|
||||||
|
{
|
||||||
|
/* FIXME: add more srb status codes */
|
||||||
|
|
||||||
|
case SRB_STATUS_DATA_OVERRUN:
|
||||||
|
*Status = STATUS_DATA_OVERRUN;
|
||||||
|
Retry = FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
*Status = STATUS_IO_DEVICE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Call the class driver specific error function */
|
||||||
|
if (DeviceExtension->ClassError != NULL)
|
||||||
|
{
|
||||||
|
DeviceExtension->ClassError(DeviceObject,
|
||||||
|
Srb,
|
||||||
|
Status,
|
||||||
|
&Retry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: log severe errors */
|
||||||
|
|
||||||
DPRINT1("ScsiClassInterpretSenseInfo() done\n");
|
DPRINT1("ScsiClassInterpretSenseInfo() done\n");
|
||||||
|
|
||||||
return(FALSE);
|
return(Retry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -774,16 +855,24 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
|
||||||
0,
|
0,
|
||||||
MAXIMUM_RETRIES - ((ULONG)IrpStack->Parameters.Others.Argument4),
|
MAXIMUM_RETRIES - ((ULONG)IrpStack->Parameters.Others.Argument4),
|
||||||
&Status);
|
&Status);
|
||||||
#if 0
|
|
||||||
irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
|
|
||||||
|
|
||||||
#endif
|
DPRINT1("Retry count: %lu\n", (ULONG)IrpStack->Parameters.Others.Argument4);
|
||||||
|
|
||||||
if (Retry == TRUE)
|
if ((Retry == TRUE) &&
|
||||||
|
((ULONG)IrpStack->Parameters.Others.Argument4 > 0))
|
||||||
{
|
{
|
||||||
/* FIXME!! */
|
((ULONG)IrpStack->Parameters.Others.Argument4)--;
|
||||||
DPRINT1("Should try again!\n");
|
DPRINT1("Retry count: %lu\n", (ULONG)IrpStack->Parameters.Others.Argument4);
|
||||||
|
|
||||||
|
DPRINT1("Should try again!\n");
|
||||||
|
#ifdef ENABLE_RETRY
|
||||||
|
ScsiClassRetryRequest(DeviceObject,
|
||||||
|
Irp,
|
||||||
|
Srb);
|
||||||
|
return(STATUS_MORE_PROCESSING_REQUIRED);
|
||||||
|
#else
|
||||||
|
return(Status);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1286,4 +1375,66 @@ ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
|
||||||
return(STATUS_INVALID_DEVICE_REQUEST);
|
return(STATUS_INVALID_DEVICE_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
ScsiClassRetryRequest(PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp,
|
||||||
|
PSCSI_REQUEST_BLOCK Srb)
|
||||||
|
{
|
||||||
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
|
PIO_STACK_LOCATION CurrentIrpStack;
|
||||||
|
PIO_STACK_LOCATION NextIrpStack;
|
||||||
|
ULONG TransferLength;
|
||||||
|
|
||||||
|
DPRINT1("ScsiPortRetryRequest() called\n");
|
||||||
|
|
||||||
|
DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
|
CurrentIrpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
NextIrpStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
if (CurrentIrpStack->MajorFunction == IRP_MJ_READ ||
|
||||||
|
CurrentIrpStack->MajorFunction == IRP_MJ_WRITE)
|
||||||
|
{
|
||||||
|
TransferLength = CurrentIrpStack->Parameters.Read.Length;
|
||||||
|
}
|
||||||
|
else if (Irp->MdlAddress != NULL)
|
||||||
|
{
|
||||||
|
TransferLength = Irp->MdlAddress->ByteCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TransferLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Srb->DataTransferLength = TransferLength;
|
||||||
|
Srb->SrbStatus = 0;
|
||||||
|
Srb->ScsiStatus = 0;
|
||||||
|
// Srb->QueueTag = SP_UNTAGGED;
|
||||||
|
|
||||||
|
/* Don't modify the flags */
|
||||||
|
// Srb->Flags =
|
||||||
|
|
||||||
|
// CurrentIrpStack->MajorFunction = IRP_MJ_SCSI;
|
||||||
|
// CurrentIrpStack->Parameters.Scsi.Srb = Srb;
|
||||||
|
|
||||||
|
// IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
*NextIrpStack = *CurrentIrpStack;
|
||||||
|
NextIrpStack->MajorFunction = IRP_MJ_SCSI;
|
||||||
|
NextIrpStack->Parameters.Scsi.Srb = Srb;
|
||||||
|
|
||||||
|
|
||||||
|
IoSetCompletionRoutine(Irp,
|
||||||
|
ScsiClassIoComplete,
|
||||||
|
Srb,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
DPRINT1("ScsiPortRetryRequest() done\n");
|
||||||
|
|
||||||
|
IoCallDriver(DeviceExtension->PortDeviceObject,
|
||||||
|
Irp);
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue