static VOID
ScsiClassRetryRequest(PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PSCSI_REQUEST_BLOCK Srb,
- BOOLEAN Associated);
+ PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated);
/* FUNCTIONS ****************************************************************/
DPRINT("Logical block address: %lu\n", LogicalBlockAddress);
/* Allocate and initialize an SRB */
- /* FIXME: use lookaside list instead */
- Srb = ExAllocatePool(NonPagedPool,
- sizeof(SCSI_REQUEST_BLOCK));
+ Srb = ExAllocateFromNPagedLookasideList(&DeviceExtension->SrbLookasideListHead);
Srb->SrbFlags = 0;
Srb->Length = sizeof(SCSI_REQUEST_BLOCK); //SCSI_REQUEST_BLOCK_SIZE;
Srb->TargetId = DeviceExtension->TargetId;
Srb->Lun = DeviceExtension->Lun;
Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
+ //FIXME: NT4 DDK sample uses MmGetMdlVirtualAddress! Why shouldn't we?
Srb->DataBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Srb->DataTransferLength = CurrentIrpStack->Parameters.Read.Length;
Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
/* Initialize next stack location */
NextIrpStack->MajorFunction = IRP_MJ_SCSI;
NextIrpStack->Parameters.Scsi.Srb = Srb;
- NextIrpStack->DeviceObject = DeviceObject;
/* Set retry count */
- NextIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
+ CurrentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
DPRINT("IoSetCompletionRoutine (Irp %p Srb %p)\n", Irp, Srb);
IoSetCompletionRoutine(Irp,
ULONG IoControlCode;
ULONG OutputBufferLength;
- DPRINT1("ScsiClassDeviceControl() called\n");
+ DPRINT("ScsiClassDeviceControl() called\n");
DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("ScsiClassInterpretSenseInfo() called\n");
DPRINT("Srb->SrbStatus %lx\n", Srb->SrbStatus);
-
+
if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_PENDING)
{
*Status = STATUS_SUCCESS;
DeviceObject, Irp, Context);
DeviceExtension = DeviceObject->DeviceExtension;
- Srb = (PSCSI_REQUEST_BLOCK)Context;
- DPRINT("Srb %p\n", Srb);
IrpStack = IoGetCurrentIrpStackLocation(Irp);
+
+ //BUGBUG -> Srb = IrpStack->Parameters.Scsi.Srb;
+ //Must pass Srb as Context arg!! See comment about Completion routines in
+ //IofCallDriver for more info.
+
+ Srb = (PSCSI_REQUEST_BLOCK)Context;
+
+ DPRINT("Srb %p\n", Srb);
if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS)
{
0,
MAXIMUM_RETRIES - ((ULONG)IrpStack->Parameters.Others.Argument4),
&Status);
- if ((Retry == TRUE) &&
+ if ((Retry) &&
((ULONG)IrpStack->Parameters.Others.Argument4 > 0))
{
((ULONG)IrpStack->Parameters.Others.Argument4)--;
- ScsiClassRetryRequest(DeviceObject,
- Irp,
- Srb,
- FALSE);
+ ScsiClassRetryRequest(
+ DeviceObject,
+ Irp,
+ Srb,
+ FALSE);
+
return(STATUS_MORE_PROCESSING_REQUIRED);
}
}
- /* FIXME: use lookaside list instead */
- DPRINT("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb);
- ExFreePool(IrpStack->Parameters.Scsi.Srb);
+ /* Free the SRB */
+ ExFreeToNPagedLookasideList(&DeviceExtension->SrbLookasideListHead,
+ Srb);
Irp->IoStatus.Status = Status;
if (!NT_SUCCESS(Status))
MasterIrp = Irp->AssociatedIrp.MasterIrp;
DeviceExtension = DeviceObject->DeviceExtension;
- Srb = (PSCSI_REQUEST_BLOCK)Context;
- DPRINT("Srb %p\n", Srb);
IrpStack = IoGetCurrentIrpStackLocation(Irp);
+ //BUGBUG -> Srb = Srb = IrpStack->Parameters.Scsi.Srb;
+ //Must pass Srb as Context arg!! See comment about Completion routines in
+ //IofCallDriver for more info.
+
+ Srb = (PSCSI_REQUEST_BLOCK)Context;
+
+ DPRINT("Srb %p\n", Srb);
+
if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS)
{
Status = STATUS_SUCCESS;
MAXIMUM_RETRIES - ((ULONG)IrpStack->Parameters.Others.Argument4),
&Status);
- DPRINT1("Retry count: %lu\n", (ULONG)IrpStack->Parameters.Others.Argument4);
-
- if ((Retry == TRUE) &&
+ if ((Retry) &&
((ULONG)IrpStack->Parameters.Others.Argument4 > 0))
{
((ULONG)IrpStack->Parameters.Others.Argument4)--;
- ScsiClassRetryRequest(DeviceObject,
- Irp,
- Srb,
- TRUE);
+ ScsiClassRetryRequest(
+ DeviceObject,
+ Irp,
+ Srb,
+ TRUE);
+
return(STATUS_MORE_PROCESSING_REQUIRED);
}
}
- /* FIXME: use lookaside list instead */
- DPRINT("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb);
- ExFreePool(IrpStack->Parameters.Scsi.Srb);
+ /* Free the SRB */
+ ExFreeToNPagedLookasideList(&DeviceExtension->SrbLookasideListHead,
+ Srb);
Irp->IoStatus.Status = Status;
static VOID
-ScsiClassRetryRequest(PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PSCSI_REQUEST_BLOCK Srb,
- BOOLEAN Associated)
+ScsiClassRetryRequest(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PSCSI_REQUEST_BLOCK Srb,
+ BOOLEAN Associated
+ )
{
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION CurrentIrpStack;
PIO_STACK_LOCATION NextIrpStack;
+
ULONG TransferLength;
DPRINT("ScsiPortRetryRequest() called\n");
CurrentIrpStack = IoGetCurrentIrpStackLocation(Irp);
NextIrpStack = IoGetNextIrpStackLocation(Irp);
- if (CurrentIrpStack->MajorFunction == IRP_MJ_READ ||
- CurrentIrpStack->MajorFunction == IRP_MJ_WRITE)
+ 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;
+ /* We shouldn't setup the buffer pointer and transfer length on read/write requests. */
+ if (Irp->MdlAddress != NULL)
+ {
+ TransferLength = Irp->MdlAddress->ByteCount;
+ }
+ else
+ {
+ TransferLength = 0;
+ }
+
+ Srb->DataBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+ Srb->DataTransferLength = TransferLength;
}
- Srb->DataTransferLength = TransferLength;
Srb->SrbStatus = 0;
Srb->ScsiStatus = 0;
NextIrpStack->Parameters.Scsi.Srb = Srb;
if (Associated == FALSE)
- {
- IoSetCompletionRoutine(Irp,
- ScsiClassIoComplete,
- Srb,
- TRUE,
- TRUE,
- TRUE);
- }
- else
- {
- IoSetCompletionRoutine(Irp,
- ScsiClassIoCompleteAssociated,
- Srb,
- TRUE,
- TRUE,
- TRUE);
- }
+ {
+ IoSetCompletionRoutine(Irp,
+ ScsiClassIoComplete,
+ Srb,
+ TRUE,
+ TRUE,
+ TRUE);
+ }
+ else
+ {
+ IoSetCompletionRoutine(Irp,
+ ScsiClassIoCompleteAssociated,
+ Srb,
+ TRUE,
+ TRUE,
+ TRUE);
+ }
+
IoCallDriver(DeviceExtension->PortDeviceObject,
Irp);