* 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
AtapiReadWrite(IN PATAPI_MINIPORT_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb);
+
+static UCHAR
+AtapiErrorToScsi(PVOID DeviceExtension,
+ PSCSI_REQUEST_BLOCK Srb);
+
// ---------------------------------------------------------------- Inlines
void
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;
}
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)
{
PSCSI_REQUEST_BLOCK Srb)
{
PIDE_DRIVE_IDENTIFY DeviceParams;
-
- ULONG StartingSector,i;
+ ULONG StartingSector;
ULONG SectorCount;
UCHAR CylinderHigh;
UCHAR CylinderLow;
ULONG Retries;
UCHAR Status;
-
DPRINT("AtapiReadWrite() called!\n");
if ((Srb->PathId != 0) ||
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 */
* 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
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));
* 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
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));
}
#endif
- /* or in the default flags from the device object. */
+ /* Update srb flags */
Srb->SrbFlags |= DeviceExtension->SrbFlags;
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,
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);
}
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",
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,
+
+#endif
- if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_PENDING)
+ if (Retry == TRUE)
{
- Status = STATUS_SUCCESS;
+ /* FIXME!! */
+ DPRINT1("Should try again!\n");
+
}
- else
- Status = STATUS_UNSUCCESSFUL;
}
-#endif
/* 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))
DPRINT("ScsiClassIoComplete() done (Status %lx)\n", Status);
-// return(Status);
- return(STATUS_SUCCESS);
+ return(Status);
}
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION IoStack;
ULONG RequestType;
+ BOOLEAN Retry;
+ ULONG RetryCount;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
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;
/* 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 (Irp == NULL)
{
DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
+ ExFreePool(Srb->SenseInfoBuffer);
return(STATUS_INSUFFICIENT_RESOURCES);
}
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);
-/* $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
#include "ntddscsi.h"
#include "srb.h"
+#define MAXIMUM_RETRIES 4
+
struct _CLASS_INIT_DATA;
typedef VOID STDCALL
-/* $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 $
*
*/
struct _VPB* Vpb;
struct _DEVICE_OBJECT* DeviceObject;
} Mount;
+ struct
+ {
+ struct _VPB* Vpb;
+ struct _DEVICE_OBJECT* DeviceObject;
+ } VerifyVolume;
struct
{
ULONG Length;
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;