mirror of
https://github.com/reactos/reactos.git
synced 2024-10-08 02:13:56 +00:00
- Start putting all data, needed for ISR into a dedicated structure.
- Use DEVICE_QUEUEs. - Add a function to retrieve SRB information help structure (is a shared code between Notify(), and in future - ScsiPortGetSrb()). - Rework RequestComplete part of ScsiPortNotification(). - Rework ScsiPortDispatchScsi() a bit - shutdown/flush can share the same code as execute_scsi/ioctl requests, also added a few more DPRINTs in error conditions to help debugging. svn path=/trunk/; revision=26192
This commit is contained in:
parent
24387402f3
commit
ce0e0958b4
|
@ -41,9 +41,6 @@
|
|||
|
||||
#include "scsiport_int.h"
|
||||
|
||||
|
||||
/* #define USE_DEVICE_QUEUES */
|
||||
|
||||
/* TYPES *********************************************************************/
|
||||
|
||||
#define IRP_FLAG_COMPLETE 0x00000001
|
||||
|
@ -99,6 +96,13 @@ static NTSTATUS
|
|||
SpiGetInquiryData (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
||||
IN PIRP Irp);
|
||||
|
||||
static PSCSI_REQUEST_BLOCK_INFO
|
||||
SpiGetSrbData(IN PVOID DeviceExtension,
|
||||
IN UCHAR PathId,
|
||||
IN UCHAR TargetId,
|
||||
IN UCHAR Lun,
|
||||
IN UCHAR QueueTag);
|
||||
|
||||
static BOOLEAN STDCALL
|
||||
ScsiPortIsr(IN PKINTERRUPT Interrupt,
|
||||
IN PVOID ServiceContext);
|
||||
|
@ -1091,17 +1095,60 @@ ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
|
|||
case RequestComplete:
|
||||
{
|
||||
PSCSI_REQUEST_BLOCK Srb;
|
||||
PSCSI_REQUEST_BLOCK_INFO SrbData;
|
||||
|
||||
Srb = (PSCSI_REQUEST_BLOCK) va_arg (ap, PSCSI_REQUEST_BLOCK);
|
||||
|
||||
DPRINT("Notify: RequestComplete (Srb %p)\n", Srb);
|
||||
DeviceExtension->IrpFlags |= IRP_FLAG_COMPLETE;
|
||||
// DeviceExtension->IrpFlags |= IRP_FLAG_COMPLETE;
|
||||
|
||||
/* Make sure Srb is allright */
|
||||
ASSERT(Srb->SrbStatus != SRB_STATUS_PENDING);
|
||||
ASSERT(Srb->Function != SRB_FUNCTION_EXECUTE_SCSI || Srb->SrbStatus != SRB_STATUS_SUCCESS || Srb->ScsiStatus == SCSISTAT_GOOD);
|
||||
|
||||
if (!(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE))
|
||||
{
|
||||
/* It's been already completed */
|
||||
va_end(ap);
|
||||
return;
|
||||
}
|
||||
|
||||
/* It's not active anymore */
|
||||
Srb->SrbFlags &= ~SRB_FLAGS_IS_ACTIVE;
|
||||
|
||||
if (Srb->Function == SRB_FUNCTION_ABORT_COMMAND)
|
||||
{
|
||||
/* TODO: Treat it specially */
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the SRB data */
|
||||
SrbData = SpiGetSrbData(DeviceExtension,
|
||||
Srb->PathId,
|
||||
Srb->TargetId,
|
||||
Srb->Lun,
|
||||
Srb->QueueTag);
|
||||
|
||||
/* Make sure there are no CompletedRequests and there is a Srb */
|
||||
ASSERT(SrbData->CompletedRequests == NULL && SrbData->Srb != NULL);
|
||||
|
||||
/* If it's a read/write request, make sure it has data inside it */
|
||||
if ((Srb->SrbStatus == SRB_STATUS_SUCCESS) &&
|
||||
((Srb->Cdb[0] == SCSIOP_READ) || (Srb->Cdb[0] == SCSIOP_WRITE)))
|
||||
{
|
||||
ASSERT(Srb->DataTransferLength);
|
||||
}
|
||||
|
||||
SrbData->CompletedRequests = DeviceExtension->InterruptData.CompletedRequests;
|
||||
DeviceExtension->InterruptData.CompletedRequests = SrbData;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NextRequest:
|
||||
DPRINT("Notify: NextRequest\n");
|
||||
DeviceExtension->IrpFlags |= IRP_FLAG_NEXT;
|
||||
DeviceExtension->InterruptData.Flags |= SCSI_PORT_NEXT_REQUEST_READY;
|
||||
break;
|
||||
|
||||
case NextLuRequest:
|
||||
|
@ -1386,7 +1433,6 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
|
|||
PIO_STACK_LOCATION Stack;
|
||||
PSCSI_REQUEST_BLOCK Srb;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG DataSize = 0;
|
||||
|
||||
DPRINT("ScsiPortDispatchScsi(DeviceObject %p Irp %p)\n",
|
||||
DeviceObject, Irp);
|
||||
|
@ -1397,6 +1443,7 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
|
|||
Srb = Stack->Parameters.Scsi.Srb;
|
||||
if (Srb == NULL)
|
||||
{
|
||||
DPRINT1("ScsiPortDispatchScsi() called with Srb = NULL!\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
|
@ -1417,6 +1464,7 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
|
|||
Srb->Lun);
|
||||
if (LunExtension == NULL)
|
||||
{
|
||||
DPRINT("ScsiPortDispatchScsi() called with an invalid LUN\n");
|
||||
Status = STATUS_NO_SUCH_DEVICE;
|
||||
|
||||
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
|
||||
|
@ -1430,52 +1478,56 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
switch (Srb->Function)
|
||||
{
|
||||
case SRB_FUNCTION_SHUTDOWN:
|
||||
case SRB_FUNCTION_FLUSH:
|
||||
DPRINT (" SRB_FUNCTION_SHUTDOWN or FLUSH\n");
|
||||
if (DeviceExtension->PortConfig->CachesData == FALSE)
|
||||
{
|
||||
/* All success here */
|
||||
Srb->SrbStatus = SRB_STATUS_SUCCESS;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/* Fall through to a usual execute operation */
|
||||
|
||||
case SRB_FUNCTION_EXECUTE_SCSI:
|
||||
case SRB_FUNCTION_IO_CONTROL:
|
||||
#ifdef USE_DEVICE_QUEUES
|
||||
/* Mark IRP as pending in all cases */
|
||||
IoMarkIrpPending(Irp);
|
||||
|
||||
if (Srb->SrbFlags & SRB_FLAGS_BYPASS_FROZEN_QUEUE)
|
||||
{
|
||||
IoMarkIrpPending(Irp);
|
||||
/* Start IO directly */
|
||||
IoStartPacket(DeviceObject, Irp, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
|
||||
KeRaiseIrql (DISPATCH_LEVEL,
|
||||
&oldIrql);
|
||||
/* We need to be at DISPATCH_LEVEL */
|
||||
KeRaiseIrql (DISPATCH_LEVEL, &oldIrql);
|
||||
|
||||
/* Insert IRP into the queue */
|
||||
if (!KeInsertByKeyDeviceQueue (&LunExtension->DeviceQueue,
|
||||
&Irp->Tail.Overlay.DeviceQueueEntry,
|
||||
Srb->QueueSortKey))
|
||||
{
|
||||
Srb->SrbStatus = SRB_STATUS_SUCCESS;
|
||||
IoMarkIrpPending(Irp);
|
||||
/* It means queue is empty, and we just start this request */
|
||||
IoStartPacket(DeviceObject, Irp, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Back to the old IRQL */
|
||||
KeLowerIrql (oldIrql);
|
||||
}
|
||||
#else
|
||||
IoMarkIrpPending(Irp);
|
||||
IoStartPacket (DeviceObject, Irp, NULL, NULL);
|
||||
#endif
|
||||
return(STATUS_PENDING);
|
||||
|
||||
case SRB_FUNCTION_SHUTDOWN:
|
||||
case SRB_FUNCTION_FLUSH:
|
||||
if (DeviceExtension->PortConfig->CachesData == TRUE)
|
||||
{
|
||||
IoMarkIrpPending(Irp);
|
||||
IoStartPacket(DeviceObject, Irp, NULL, NULL);
|
||||
return(STATUS_PENDING);
|
||||
}
|
||||
break;
|
||||
return STATUS_PENDING;
|
||||
|
||||
case SRB_FUNCTION_CLAIM_DEVICE:
|
||||
DPRINT (" SRB_FUNCTION_CLAIM_DEVICE\n");
|
||||
case SRB_FUNCTION_ATTACH_DEVICE:
|
||||
DPRINT (" SRB_FUNCTION_CLAIM_DEVICE or ATTACH\n");
|
||||
|
||||
/* Reference device object and keep the device object */
|
||||
/* TODO: Check if it's OK */
|
||||
ObReferenceObject(DeviceObject);
|
||||
LunExtension->DeviceObject = DeviceObject;
|
||||
LunExtension->DeviceClaimed = TRUE;
|
||||
|
@ -1484,6 +1536,7 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
case SRB_FUNCTION_RELEASE_DEVICE:
|
||||
DPRINT (" SRB_FUNCTION_RELEASE_DEVICE\n");
|
||||
/* TODO: Check if it's OK */
|
||||
DPRINT ("PathId: %lu TargetId: %lu Lun: %lu\n",
|
||||
Srb->PathId, Srb->TargetId, Srb->Lun);
|
||||
|
||||
|
@ -1500,7 +1553,6 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = DataSize;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
|
@ -2304,6 +2356,37 @@ SpiGetInquiryData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static PSCSI_REQUEST_BLOCK_INFO
|
||||
SpiGetSrbData(IN PVOID DeviceExtension,
|
||||
IN UCHAR PathId,
|
||||
IN UCHAR TargetId,
|
||||
IN UCHAR Lun,
|
||||
IN UCHAR QueueTag)
|
||||
{
|
||||
PSCSI_PORT_LUN_EXTENSION LunExtension;
|
||||
|
||||
if (QueueTag == SP_UNTAGGED)
|
||||
{
|
||||
/* Untagged request, get LU and return pointer to SrbInfo */
|
||||
LunExtension = SpiGetLunExtension(DeviceExtension,
|
||||
PathId,
|
||||
TargetId,
|
||||
Lun);
|
||||
|
||||
/* Return NULL in case of error */
|
||||
if (!LunExtension)
|
||||
return(NULL);
|
||||
|
||||
/* Return the pointer to SrbInfo */
|
||||
return &LunExtension->SrbInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: Implement when we have it */
|
||||
ASSERT(FALSE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOLEAN STDCALL
|
||||
ScsiPortIsr(IN PKINTERRUPT Interrupt,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define LUS_NUMBER 8
|
||||
|
||||
/* Flags */
|
||||
#define SCSI_PORT_NEXT_REQUEST_READY 0x0008
|
||||
#define SCSI_PORT_SCAN_IN_PROGRESS 0x8000
|
||||
|
||||
typedef enum _SCSI_PORT_TIMER_STATES
|
||||
|
@ -44,6 +45,8 @@ typedef struct _SCSI_PORT_DEVICE_BASE
|
|||
typedef struct _SCSI_REQUEST_BLOCK_INFO
|
||||
{
|
||||
LIST_ENTRY Requests;
|
||||
PSCSI_REQUEST_BLOCK Srb;
|
||||
struct _SCSI_REQUEST_BLOCK_INFO *CompletedRequests;
|
||||
} SCSI_REQUEST_BLOCK_INFO, *PSCSI_REQUEST_BLOCK_INFO;
|
||||
|
||||
typedef struct _SCSI_PORT_LUN_EXTENSION
|
||||
|
@ -97,6 +100,15 @@ typedef struct _BUSES_CONFIGURATION_INFORMATION
|
|||
PSCSI_BUS_SCAN_INFO BusScanInfo[1];
|
||||
} BUSES_CONFIGURATION_INFORMATION, *PBUSES_CONFIGURATION_INFORMATION;
|
||||
|
||||
|
||||
typedef struct _SCSI_PORT_INTERRUPT_DATA
|
||||
{
|
||||
ULONG Flags; /* Interrupt-time flags */
|
||||
PSCSI_REQUEST_BLOCK_INFO CompletedRequests; /* Linked list of Srb info data */
|
||||
|
||||
} SCSI_PORT_INTERRUPT_DATA, *PSCSI_PORT_INTERRUPT_DATA;
|
||||
|
||||
|
||||
/*
|
||||
* SCSI_PORT_DEVICE_EXTENSION
|
||||
*
|
||||
|
@ -127,6 +139,8 @@ typedef struct _SCSI_PORT_DEVICE_EXTENSION
|
|||
ULONG LunExtensionSize;
|
||||
PSCSI_PORT_LUN_EXTENSION LunExtensionList[LUS_NUMBER];
|
||||
|
||||
SCSI_PORT_INTERRUPT_DATA InterruptData;
|
||||
|
||||
ULONG SrbExtensionSize;
|
||||
|
||||
PIO_SCSI_CAPABILITIES PortCapabilities;
|
||||
|
|
Loading…
Reference in a new issue