Implemented ScsiClassAsynchronousCompletion() and ScsiClassReleaseQueue().

svn path=/trunk/; revision=6492
This commit is contained in:
Eric Kohl 2003-11-01 16:33:39 +00:00
parent 9ecaadc7e6
commit 06a85f7e81
2 changed files with 131 additions and 12 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: class2.c,v 1.42 2003/11/01 10:42:32 hbirr Exp $ /* $Id: class2.c,v 1.43 2003/11/01 16:33:39 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -40,12 +40,12 @@
#include <debug.h> #include <debug.h>
#define VERSION "0.0.1" #define VERSION "0.0.2"
#define TAG_SRBT TAG('S', 'r', 'b', 'T') #define TAG_SRBT TAG('S', 'r', 'b', 'T')
#define INQUIRY_DATA_SIZE 2048 #define INQUIRY_DATA_SIZE 2048
#define START_UNIT_TIMEOUT 30
static NTSTATUS STDCALL static NTSTATUS STDCALL
ScsiClassCreateClose(IN PDEVICE_OBJECT DeviceObject, ScsiClassCreateClose(IN PDEVICE_OBJECT DeviceObject,
@ -120,14 +120,37 @@ ScsiClassDebugPrint(IN ULONG DebugPrintLevel,
/* /*
* @unimplemented * @implemented
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
ScsiClassAsynchronousCompletion(IN PDEVICE_OBJECT DeviceObject, ScsiClassAsynchronousCompletion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp, IN PIRP Irp,
IN PVOID Context) IN PVOID Context)
{ {
UNIMPLEMENTED; PCOMPLETION_CONTEXT CompletionContext;
PSCSI_REQUEST_BLOCK Srb;
CompletionContext = (PCOMPLETION_CONTEXT) Context;
Srb = &CompletionContext->Srb;
/* Release the queue if it is frozen */
if (Srb->Function == SRB_FUNCTION_EXECUTE_SCSI &&
Srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN)
{
ScsiClassReleaseQueue (CompletionContext->DeviceObject);
}
/* Release the completion context and the IRP */
if (Irp->MdlAddress != NULL)
{
MmUnlockPages (Irp->MdlAddress);
IoFreeMdl (Irp->MdlAddress);
Irp->MdlAddress = NULL;
}
ExFreePool (CompletionContext);
IoFreeIrp (Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
} }
@ -1230,6 +1253,13 @@ ScsiClassIoComplete(IN PDEVICE_OBJECT DeviceObject,
} }
else else
{ {
/* Release the queue if it is frozen */
if (Srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN)
{
ScsiClassReleaseQueue (DeviceObject);
}
/* Get more detailed status information */
Retry = ScsiClassInterpretSenseInfo(DeviceObject, Retry = ScsiClassInterpretSenseInfo(DeviceObject,
Srb, Srb,
IrpStack->MajorFunction, IrpStack->MajorFunction,
@ -1330,6 +1360,12 @@ ScsiClassIoCompleteAssociated(IN PDEVICE_OBJECT DeviceObject,
} }
else else
{ {
/* Release the queue if it is frozen */
if (Srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN)
{
ScsiClassReleaseQueue (DeviceObject);
}
/* Get more detailed status information */ /* Get more detailed status information */
Retry = ScsiClassInterpretSenseInfo(DeviceObject, Retry = ScsiClassInterpretSenseInfo(DeviceObject,
Srb, Srb,
@ -1644,12 +1680,78 @@ ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
/* /*
* @unimplemented * @implemented
*/ */
VOID STDCALL VOID STDCALL
ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject) ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
{ {
UNIMPLEMENTED; PDEVICE_EXTENSION DeviceExtension;
PCOMPLETION_CONTEXT Context;
PIO_STACK_LOCATION Stack;
PSCSI_REQUEST_BLOCK Srb;
KIRQL Irql;
PCDB Cdb;
PIRP Irp;
DPRINT("ScsiClassReleaseQueue() called\n");
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* Allocate and initialize the completion context */
Context = ExAllocatePool (NonPagedPoolMustSucceed,
sizeof (COMPLETION_CONTEXT));
Context->DeviceObject = DeviceObject;
/* Initialize the SRB */
Srb = &Context->Srb;
RtlZeroMemory (Srb,
sizeof (SCSI_REQUEST_BLOCK));
Srb->Length = sizeof (SCSI_REQUEST_BLOCK);
Srb->PathId = DeviceExtension->PathId;
Srb->TargetId = DeviceExtension->TargetId;
Srb->Lun = DeviceExtension->Lun;
Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
Srb->TimeOutValue = START_UNIT_TIMEOUT;
Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER |
SRB_FLAGS_DISABLE_AUTOSENSE |
SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
Srb->CdbLength = 6;
/* Initialize the CDB */
Cdb = (PCDB)&Srb->Cdb;
Cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
Cdb->START_STOP.Start = 1;
Cdb->START_STOP.LogicalUnitNumber = Srb->Lun;
/* Build the IRP */
Irp = IoAllocateIrp (DeviceObject->StackSize, FALSE);
IoSetCompletionRoutine (Irp,
(PIO_COMPLETION_ROUTINE)ScsiClassAsynchronousCompletion,
Context,
NULL,
NULL,
NULL);
/* Attach SRB to the IRP */
Stack = IoGetNextIrpStackLocation(Irp);
Stack->MajorFunction = IRP_MJ_SCSI;
Stack->Parameters.Scsi.Srb = Srb;
Srb->OriginalRequest = Irp;
/* Call the port driver */
Irql = KeGetCurrentIrql ();
if (Irql < DISPATCH_LEVEL)
{
KeRaiseIrql (DISPATCH_LEVEL, &Irql);
IoCallDriver (DeviceExtension->PortDeviceObject, Irp);
KeLowerIrql (Irql);
}
else
{
IoCallDriver (DeviceExtension->PortDeviceObject, Irp);
}
DPRINT("ScsiClassReleaseQueue() done\n");
} }
@ -1843,6 +1945,13 @@ TryAgain:
if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS) if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS)
{ {
/* Release the queue if it is frozen */
if (Srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN)
{
ScsiClassReleaseQueue (DeviceObject);
}
/* Get more detailed status information */
Retry = ScsiClassInterpretSenseInfo(DeviceObject, Retry = ScsiClassInterpretSenseInfo(DeviceObject,
Srb, Srb,
IRP_MJ_SCSI, IRP_MJ_SCSI,

View file

@ -1,4 +1,4 @@
/* $Id: class2.h,v 1.3 2003/07/11 14:07:30 ekohl Exp $ /* $Id: class2.h,v 1.4 2003/11/01 16:32:47 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -7,8 +7,8 @@
* PROGRAMMER: Eric Kohl (ekohl@rz-online.de) * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
*/ */
#ifndef __STORAGE_INCLUDE_CLASS2_H #ifndef __INCLUDE_DDK_CLASS2_H
#define __STORAGE_INCLUDE_CLASS2_H #define __INCLUDE_DDK_CLASS2_H
#include "ntddscsi.h" #include "ntddscsi.h"
#include "srb.h" #include "srb.h"
@ -108,6 +108,13 @@ typedef struct _DEVICE_EXTENSION
} DEVICE_EXTENSION, *PDEVICE_EXTENSION; } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct _COMPLETION_CONTEXT
{
PDEVICE_OBJECT DeviceObject;
SCSI_REQUEST_BLOCK Srb;
} COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS STDCALL NTSTATUS STDCALL
@ -197,6 +204,9 @@ ScsiClassQueryTimeOutRegistryValue(IN PUNICODE_STRING RegistryPath);
NTSTATUS STDCALL NTSTATUS STDCALL
ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject); ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject);
VOID STDCALL
ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject);
NTSTATUS STDCALL NTSTATUS STDCALL
ScsiClassSendSrbAsynchronous(PDEVICE_OBJECT DeviceObject, ScsiClassSendSrbAsynchronous(PDEVICE_OBJECT DeviceObject,
PSCSI_REQUEST_BLOCK Srb, PSCSI_REQUEST_BLOCK Srb,
@ -217,6 +227,6 @@ ScsiClassSplitRequest(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp, IN PIRP Irp,
IN ULONG MaximumBytes); IN ULONG MaximumBytes);
#endif /* __STORAGE_INCLUDE_CLASS2_H */ #endif /* __INCLUDE_DDK_CLASS2_H */
/* EOF */ /* EOF */