- Use a bitmap for managing the srb extensions.

- Removed the complete request and next request counter.
  The counters are always wrong, because some miniport drivers fires up
  to much notification requests.
- Enable the queues for the miniport driver, if they are supported.
- Fixed a bug in ScsiPortCompleteRequest.

svn path=/trunk/; revision=9651
This commit is contained in:
Hartmut Birr 2004-06-10 08:14:57 +00:00
parent b5273a652c
commit 5f843bef93
2 changed files with 97 additions and 81 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: scsiport.c,v 1.59 2004/06/07 20:03:00 hbirr Exp $ /* $Id: scsiport.c,v 1.60 2004/06/10 08:14:57 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -45,8 +45,6 @@
#define IRP_FLAG_NEXT 0x00000002 #define IRP_FLAG_NEXT 0x00000002
#define IRP_FLAG_NEXT_LU 0x00000004 #define IRP_FLAG_NEXT_LU 0x00000004
#define MAX_SRB_EXTENSIONS 32
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
static VOID static VOID
@ -257,7 +255,7 @@ ScsiPortCompleteRequest(IN PVOID HwDeviceExtension,
while (Irp) while (Irp)
{ {
Srb = (PSCSI_REQUEST_BLOCK)Irp->Tail.Overlay.DriverContext[3]; Srb = (PSCSI_REQUEST_BLOCK)Irp->Tail.Overlay.DriverContext[3];
if (Srb->SrbStatus & SRB_FLAGS_IS_ACTIVE) if (Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE)
{ {
Srb->SrbStatus = SrbStatus; Srb->SrbStatus = SrbStatus;
ScsiPortNotification(RequestComplete, ScsiPortNotification(RequestComplete,
@ -623,16 +621,36 @@ ScsiPortGetUncachedExtension(IN PVOID HwDeviceExtension,
return NULL; return NULL;
} }
} }
if (DeviceExtension->SrbExtensionSize > 0)
{
PVOID Buffer;
DeviceExtension->CurrentSrbExtensions = 0;
if (DeviceExtension->PortConfig->MultipleRequestPerLu)
{
DeviceExtension->MaxSrbExtensions = 1024;
}
else
{
DeviceExtension->MaxSrbExtensions = 32;
}
Buffer = ExAllocatePool(NonPagedPool, ROUND_UP(DeviceExtension->MaxSrbExtensions / 8, sizeof(ULONG)));
if (Buffer == NULL)
{
KEBUGCHECK(0);
return NULL;
}
RtlInitializeBitMap(&DeviceExtension->SrbExtensionAllocMap, Buffer, DeviceExtension->MaxSrbExtensions);
RtlClearAllBits(&DeviceExtension->SrbExtensionAllocMap);
}
/* Allocate a common DMA buffer */ /* Allocate a common DMA buffer */
DeviceExtension->CommonBufferLength = DeviceExtension->CommonBufferLength =
NumberOfBytes + PAGE_ROUND_UP(DeviceExtension->SrbExtensionSize * MAX_SRB_EXTENSIONS); NumberOfBytes + PAGE_ROUND_UP(DeviceExtension->SrbExtensionSize * DeviceExtension->MaxSrbExtensions);
DeviceExtension->VirtualAddress = DeviceExtension->VirtualAddress =
HalAllocateCommonBuffer(DeviceExtension->AdapterObject, HalAllocateCommonBuffer(DeviceExtension->AdapterObject,
DeviceExtension->CommonBufferLength, DeviceExtension->CommonBufferLength,
&DeviceExtension->PhysicalAddress, &DeviceExtension->PhysicalAddress,
FALSE); FALSE);
DeviceExtension->VirtualAddressMap = 0;
if (DeviceExtension->VirtualAddress == NULL) if (DeviceExtension->VirtualAddress == NULL)
{ {
DPRINT1("HalAllocateCommonBuffer() failed!\n"); DPRINT1("HalAllocateCommonBuffer() failed!\n");
@ -641,7 +659,7 @@ ScsiPortGetUncachedExtension(IN PVOID HwDeviceExtension,
} }
return (PVOID)((ULONG_PTR)DeviceExtension->VirtualAddress + return (PVOID)((ULONG_PTR)DeviceExtension->VirtualAddress +
PAGE_ROUND_UP(DeviceExtension->SrbExtensionSize * MAX_SRB_EXTENSIONS)); PAGE_ROUND_UP(DeviceExtension->SrbExtensionSize * DeviceExtension->MaxSrbExtensions));
} }
@ -1202,6 +1220,8 @@ ScsiPortLogError(IN PVOID HwDeviceExtension,
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension; PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
DPRINT1("ScsiPortLogError() called\n"); DPRINT1("ScsiPortLogError() called\n");
DPRINT1("Srb %x, PathId %d, TargetId %d, Lun %d, ErrorCode %x, UniqueId %x\n",
Srb, PathId, TargetId, Lun, ErrorCode, UniqueId);
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
SCSI_PORT_DEVICE_EXTENSION, SCSI_PORT_DEVICE_EXTENSION,
@ -1258,14 +1278,12 @@ ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
DPRINT("Notify: RequestComplete (Srb %p)\n", Srb); DPRINT("Notify: RequestComplete (Srb %p)\n", Srb);
DeviceExtension->Flags |= IRP_FLAG_COMPLETE; DeviceExtension->Flags |= IRP_FLAG_COMPLETE;
Srb->SrbFlags &= ~SRB_FLAGS_IS_ACTIVE; Srb->SrbFlags &= ~SRB_FLAGS_IS_ACTIVE;
InterlockedIncrement((PLONG)&DeviceExtension->CompleteRequestCount);
} }
break; break;
case NextRequest: case NextRequest:
DPRINT("Notify: NextRequest\n"); DPRINT("Notify: NextRequest\n");
DeviceExtension->Flags |= IRP_FLAG_NEXT; DeviceExtension->Flags |= IRP_FLAG_NEXT;
InterlockedIncrement((PLONG)&DeviceExtension->NextRequestCount);
break; break;
case NextLuRequest: case NextLuRequest:
@ -1289,8 +1307,7 @@ ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
if (LunExtension) if (LunExtension)
{ {
DeviceExtension->Flags |= IRP_FLAG_NEXT_LU; DeviceExtension->Flags |= IRP_FLAG_NEXT_LU;
InterlockedIncrement((PLONG)&LunExtension->NextLuRequestCount); LunExtension->Flags |= IRP_FLAG_NEXT_LU;
InterlockedIncrement((PLONG)&DeviceExtension->NextLuRequestCount);
} }
} }
break; break;
@ -1753,43 +1770,42 @@ static VOID
SpiAllocateSrbExtension(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, SpiAllocateSrbExtension(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
PSCSI_REQUEST_BLOCK Srb) PSCSI_REQUEST_BLOCK Srb)
{ {
ULONG i; ULONG index;
ULONG mask;
DPRINT("SpiAllocateSrbExtension\n"); DPRINT("SpiAllocateSrbExtension\n");
DPRINT("DeviceExtension->VirtualAddress %x, DeviceExtension->SrbExtensionSize %x\n", DPRINT("DeviceExtension->VirtualAddress %x, DeviceExtension->SrbExtensionSize %x\n",
DeviceExtension->VirtualAddress, DeviceExtension->SrbExtensionSize); DeviceExtension->VirtualAddress, DeviceExtension->SrbExtensionSize);
Srb->SrbExtension = NULL;
if (DeviceExtension->VirtualAddress != NULL && if (DeviceExtension->VirtualAddress != NULL &&
DeviceExtension->SrbExtensionSize > 0) DeviceExtension->SrbExtensionSize > 0)
{ {
for (i = 0, mask = 1; i < MAX_SRB_EXTENSIONS; i++, mask <<= 1) index = RtlFindClearBitsAndSet(&DeviceExtension->SrbExtensionAllocMap, 1, 0);
if (index != 0xffffffff)
{ {
if (!(DeviceExtension->VirtualAddressMap & mask)) DeviceExtension->CurrentSrbExtensions++;
{ Srb->SrbExtension = DeviceExtension->VirtualAddress + index * DeviceExtension->SrbExtensionSize;
DeviceExtension->VirtualAddressMap |= mask; // Srb->QueueTag = i;
Srb->SrbExtension = DeviceExtension->VirtualAddress + i * DeviceExtension->SrbExtensionSize; // Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
DPRINT("%x\n", Srb->SrbExtension);
return;
}
} }
} }
Srb->SrbExtension = NULL; DPRINT("%x\n", Srb->SrbExtension);
} }
static VOID static VOID
SpiFreeSrbExtension(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, SpiFreeSrbExtension(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
PSCSI_REQUEST_BLOCK Srb) PSCSI_REQUEST_BLOCK Srb)
{ {
ULONG i; ULONG index;
if (DeviceExtension->VirtualAddress != NULL && if (DeviceExtension->VirtualAddress != NULL &&
DeviceExtension->SrbExtensionSize > 0 && DeviceExtension->SrbExtensionSize > 0 &&
Srb->SrbExtension != NULL) Srb->SrbExtension != NULL)
{ {
i = ((ULONG_PTR)Srb->SrbExtension - (ULONG_PTR)DeviceExtension->VirtualAddress) / DeviceExtension->SrbExtensionSize; index = ((ULONG_PTR)Srb->SrbExtension - (ULONG_PTR)DeviceExtension->VirtualAddress) / DeviceExtension->SrbExtensionSize;
DeviceExtension->VirtualAddressMap &= ~(1 << i); RtlClearBits(&DeviceExtension->SrbExtensionAllocMap, index, 1);
DeviceExtension->CurrentSrbExtensions--;
} }
Srb->SrbExtension = NULL; Srb->SrbExtension = NULL;
} }
@ -1803,8 +1819,8 @@ ScsiPortStartPacket(IN OUT PVOID Context)
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION IrpStack; PIO_STACK_LOCATION IrpStack;
DPRINT("ScsiPortStartPacket() called\n"); DPRINT("ScsiPortStartPacket(Context %x) called\n", Context);
Srb = (PSCSI_REQUEST_BLOCK)Context; Srb = (PSCSI_REQUEST_BLOCK)Context;
Irp = (PIRP)Srb->OriginalRequest; Irp = (PIRP)Srb->OriginalRequest;
IrpStack = IoGetCurrentIrpStackLocation(Irp); IrpStack = IoGetCurrentIrpStackLocation(Irp);
@ -2023,8 +2039,9 @@ SpiScanAdapter (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
DPRINT ("DeviceTypeQualifier %x\n", ((PINQUIRYDATA)Srb->DataBuffer)->DeviceTypeQualifier); DPRINT ("DeviceTypeQualifier %x\n", ((PINQUIRYDATA)Srb->DataBuffer)->DeviceTypeQualifier);
if (NT_SUCCESS(ScanData->Status) && if (NT_SUCCESS(ScanData->Status) &&
(Srb->SrbStatus == SRB_STATUS_SUCCESS || (Srb->SrbStatus == SRB_STATUS_SUCCESS ||
Srb->SrbStatus == SRB_STATUS_DATA_OVERRUN) && (Srb->SrbStatus == SRB_STATUS_DATA_OVERRUN &&
Srb->DataTransferLength >= sizeof(INQUIRYDATA))) &&
((PINQUIRYDATA)Srb->DataBuffer)->DeviceTypeQualifier == 0) ((PINQUIRYDATA)Srb->DataBuffer)->DeviceTypeQualifier == 0)
{ {
/* Copy inquiry data */ /* Copy inquiry data */
@ -2032,12 +2049,12 @@ SpiScanAdapter (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Srb->DataBuffer, Srb->DataBuffer,
sizeof(INQUIRYDATA)); sizeof(INQUIRYDATA));
ScanData->Lun++; ScanData->Lun++;
} }
else else
{ {
SpiRemoveLunExtension (ScanData->LunExtension); SpiRemoveLunExtension (ScanData->LunExtension);
ScanData->Lun = SCSI_MAXIMUM_LOGICAL_UNITS; ScanData->Lun = SCSI_MAXIMUM_LOGICAL_UNITS;
} }
} }
if (ScanData->Lun >= SCSI_MAXIMUM_LOGICAL_UNITS) if (ScanData->Lun >= SCSI_MAXIMUM_LOGICAL_UNITS)
{ {
@ -2053,6 +2070,7 @@ SpiScanAdapter (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Srb->PathId = ScanData->Bus; Srb->PathId = ScanData->Bus;
Srb->TargetId = ScanData->Target; Srb->TargetId = ScanData->Target;
Srb->SrbStatus = SRB_STATUS_SUCCESS; Srb->SrbStatus = SRB_STATUS_SUCCESS;
Srb->TimeOutValue = 2;
Cdb = (PCDB) &Srb->Cdb; Cdb = (PCDB) &Srb->Cdb;
Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY; Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
@ -2715,8 +2733,8 @@ SpiRemoveActiveIrp(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
PSCSI_PORT_LUN_EXTENSION LunExtension; PSCSI_PORT_LUN_EXTENSION LunExtension;
PIRP CurrentIrp; PIRP CurrentIrp;
LunExtension = Irp->Tail.Overlay.DriverContext[2]; LunExtension = Irp->Tail.Overlay.DriverContext[2];
LunExtension->ActiveIrpCount--; InterlockedDecrement((PLONG)&LunExtension->ActiveIrpCount);
DeviceExtension->ActiveIrpCount--; InterlockedDecrement((PLONG)&DeviceExtension->ActiveIrpCount);
if (PrevIrp) if (PrevIrp)
{ {
InterlockedExchangePointer(&PrevIrp->Tail.Overlay.DriverContext[0], InterlockedExchangePointer(&PrevIrp->Tail.Overlay.DriverContext[0],
@ -2755,11 +2773,16 @@ SpiAddActiveIrp(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
PIRP Irp) PIRP Irp)
{ {
PSCSI_PORT_LUN_EXTENSION LunExtension; PSCSI_PORT_LUN_EXTENSION LunExtension;
PSCSI_REQUEST_BLOCK Srb;
LunExtension = Irp->Tail.Overlay.DriverContext[2]; LunExtension = Irp->Tail.Overlay.DriverContext[2];
Srb = Irp->Tail.Overlay.DriverContext[3];
Srb->SrbFlags |= SRB_FLAGS_IS_ACTIVE;
Irp->Tail.Overlay.DriverContext[0] = (PVOID)DeviceExtension->NextIrp; Irp->Tail.Overlay.DriverContext[0] = (PVOID)DeviceExtension->NextIrp;
InterlockedExchangePointer(&DeviceExtension->NextIrp, Irp); InterlockedExchangePointer(&DeviceExtension->NextIrp, Irp);
Irp->Tail.Overlay.DriverContext[1] = (PVOID)LunExtension->NextIrp; Irp->Tail.Overlay.DriverContext[1] = (PVOID)LunExtension->NextIrp;
InterlockedExchangePointer(&LunExtension->NextIrp, Irp); InterlockedExchangePointer(&LunExtension->NextIrp, Irp);
InterlockedIncrement((PLONG)&LunExtension->ActiveIrpCount);
InterlockedIncrement((PLONG)&DeviceExtension->ActiveIrpCount);
} }
static VOID static VOID
@ -2810,11 +2833,19 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
if (NextIrp) if (NextIrp)
{ {
Srb = NextIrp->Tail.Overlay.DriverContext[3]; Srb = NextIrp->Tail.Overlay.DriverContext[3];
/*
* FIXME:
* Is this the right place to set this flag ?
*/
if (DeviceExtension->PortConfig->MultipleRequestPerLu)
{
Srb->SrbFlags |= SRB_FLAGS_QUEUE_ACTION_ENABLE;
}
NextIrp->Tail.Overlay.DriverContext[2] = (PVOID)Srb->QueueSortKey; NextIrp->Tail.Overlay.DriverContext[2] = (PVOID)Srb->QueueSortKey;
LunExtension = Srb->OriginalRequest; LunExtension = Srb->OriginalRequest;
ListEntry = DeviceExtension->PendingIrpListHead.Flink; ListEntry = DeviceExtension->PendingIrpListHead.Flink;
while (ListEntry != DeviceExtension->PendingIrpListHead.Flink) while (ListEntry != &DeviceExtension->PendingIrpListHead)
{ {
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]); Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
if ((ULONG)Irp->Tail.Overlay.DriverContext[2] > Srb->QueueSortKey) if ((ULONG)Irp->Tail.Overlay.DriverContext[2] > Srb->QueueSortKey)
@ -2828,24 +2859,20 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
LunExtension->PendingIrpCount++; LunExtension->PendingIrpCount++;
} }
while (DeviceExtension->CompleteRequestCount || while (DeviceExtension->Flags & IRP_FLAG_COMPLETE ||
((DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->ActiveIrpCount < MAX_SRB_EXTENSIONS) && !IsListEmpty(&DeviceExtension->PendingIrpListHead) && (((DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->CurrentSrbExtensions < DeviceExtension->MaxSrbExtensions) &&
(DeviceExtension->NextRequestCount || DeviceExtension->NextLuRequestCount || DeviceExtension->NextIrp == NULL))) DeviceExtension->PendingIrpCount > 0 &&
(DeviceExtension->Flags & (IRP_FLAG_NEXT|IRP_FLAG_NEXT_LU) || DeviceExtension->NextIrp == NULL))))
{ {
DPRINT ("CompleteRequestCount %d, NextRequestCount %d, NextLuRequestCount %d, PendingIrpList is %s, ActiveIrpList is %s\n", DPRINT ("RequestComplete %d, NextRequest %d, NextLuRequest %d, PendingIrpCount %d, ActiveIrpCount %d\n",
DeviceExtension->CompleteRequestCount, DeviceExtension->Flags & IRP_FLAG_COMPLETE ? 1 : 0,
DeviceExtension->NextRequestCount, DeviceExtension->Flags & IRP_FLAG_NEXT ? 1 : 0,
DeviceExtension->NextLuRequestCount, DeviceExtension->Flags & IRP_FLAG_NEXT_LU ? 1 : 0,
IsListEmpty(&DeviceExtension->PendingIrpListHead) ? "EMPTY" : "NOT empty", DeviceExtension->PendingIrpCount,
DeviceExtension->NextIrp == NULL ? "EMPTY" : "NOT empty"); DeviceExtension->ActiveIrpCount);
if (DeviceExtension->ActiveIrpCount == 0 && DeviceExtension->CompleteRequestCount > 0)
{
DeviceExtension->CompleteRequestCount = 0;
continue;
}
if (DeviceExtension->CompleteRequestCount > 0) if (DeviceExtension->Flags & IRP_FLAG_COMPLETE)
{ {
DeviceExtension->Flags &= ~IRP_FLAG_COMPLETE; DeviceExtension->Flags &= ~IRP_FLAG_COMPLETE;
PrevIrp = NULL; PrevIrp = NULL;
@ -2857,7 +2884,6 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
if (!(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE)) if (!(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE))
{ {
BOOLEAN CompleteThisRequest; BOOLEAN CompleteThisRequest;
InterlockedDecrement((PLONG)&DeviceExtension->CompleteRequestCount);
LunExtension = Irp->Tail.Overlay.DriverContext[2]; LunExtension = Irp->Tail.Overlay.DriverContext[2];
IrpStack = IoGetCurrentIrpStackLocation(Irp); IrpStack = IoGetCurrentIrpStackLocation(Irp);
OriginalSrb = IrpStack->Parameters.Scsi.Srb; OriginalSrb = IrpStack->Parameters.Scsi.Srb;
@ -2954,16 +2980,14 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
{ {
ListEntry = RemoveTailList(&CompleteIrpListHead); ListEntry = RemoveTailList(&CompleteIrpListHead);
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]); Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
Srb = Irp->Tail.Overlay.DriverContext[3];
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
} }
KeAcquireSpinLockAtDpcLevel(&DeviceExtension->Lock); KeAcquireSpinLockAtDpcLevel(&DeviceExtension->Lock);
} }
if (DeviceExtension->NextLuRequestCount || if (DeviceExtension->Flags & (IRP_FLAG_NEXT|IRP_FLAG_NEXT_LU) &&
DeviceExtension->NextRequestCount) (DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->CurrentSrbExtensions < DeviceExtension->MaxSrbExtensions))
{ {
BOOLEAN StartThisRequest; BOOLEAN StartThisRequest;
DeviceExtension->Flags &= ~(IRP_FLAG_NEXT|IRP_FLAG_NEXT_LU);
ListEntry = DeviceExtension->PendingIrpListHead.Flink; ListEntry = DeviceExtension->PendingIrpListHead.Flink;
while (ListEntry != &DeviceExtension->PendingIrpListHead) while (ListEntry != &DeviceExtension->PendingIrpListHead)
{ {
@ -2972,21 +2996,21 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
Srb = Irp->Tail.Overlay.DriverContext[3]; Srb = Irp->Tail.Overlay.DriverContext[3];
LunExtension = Srb->OriginalRequest; LunExtension = Srb->OriginalRequest;
if (DeviceExtension->SrbExtensionSize > 0 && if (DeviceExtension->SrbExtensionSize > 0 &&
DeviceExtension->ActiveIrpCount >= MAX_SRB_EXTENSIONS) DeviceExtension->CurrentSrbExtensions >= DeviceExtension->MaxSrbExtensions)
{ {
break; break;
} }
if (LunExtension->NextLuRequestCount > 0) if (LunExtension->Flags & IRP_FLAG_NEXT_LU)
{ {
StartThisRequest = TRUE; StartThisRequest = TRUE;
InterlockedDecrement((PLONG)&LunExtension->NextLuRequestCount); LunExtension->Flags &= ~IRP_FLAG_NEXT_LU;
InterlockedDecrement((PLONG)&DeviceExtension->NextLuRequestCount); DeviceExtension->Flags &= ~IRP_FLAG_NEXT_LU;
} }
else if (DeviceExtension->NextRequestCount > 0 && else if (DeviceExtension->Flags & IRP_FLAG_NEXT &&
LunExtension->ActiveIrpCount == 0) LunExtension->ActiveIrpCount == 0)
{ {
InterlockedDecrement((PLONG)&DeviceExtension->NextRequestCount);
StartThisRequest = TRUE; StartThisRequest = TRUE;
DeviceExtension->Flags &= ~IRP_FLAG_NEXT;
} }
else else
{ {
@ -2997,12 +3021,9 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
LunExtension->PendingIrpCount--; LunExtension->PendingIrpCount--;
DeviceExtension->PendingIrpCount--; DeviceExtension->PendingIrpCount--;
RemoveEntryList((PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]); RemoveEntryList((PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
LunExtension->ActiveIrpCount++;
DeviceExtension->ActiveIrpCount++;
SpiAllocateSrbExtension(DeviceExtension, Srb);
Irp->Tail.Overlay.DriverContext[2] = LunExtension; Irp->Tail.Overlay.DriverContext[2] = LunExtension;
Srb->OriginalRequest = Irp; Srb->OriginalRequest = Irp;
SpiAllocateSrbExtension(DeviceExtension, Srb);
InsertHeadList(&NextIrpListHead, (PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]); InsertHeadList(&NextIrpListHead, (PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
} }
@ -3015,7 +3036,6 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
{ {
ListEntry = RemoveTailList(&NextIrpListHead); ListEntry = RemoveTailList(&NextIrpListHead);
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]); Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
SpiAddActiveIrp(DeviceExtension, Irp);
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->Lock); KeReleaseSpinLockFromDpcLevel(&DeviceExtension->Lock);
// Start this Irp // Start this Irp
@ -3026,7 +3046,7 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
if (!IsListEmpty(&DeviceExtension->PendingIrpListHead) && if (!IsListEmpty(&DeviceExtension->PendingIrpListHead) &&
DeviceExtension->NextIrp == NULL && DeviceExtension->NextIrp == NULL &&
(DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->ActiveIrpCount < MAX_SRB_EXTENSIONS)) (DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->CurrentSrbExtensions < DeviceExtension->MaxSrbExtensions))
{ {
ListEntry = RemoveHeadList(&DeviceExtension->PendingIrpListHead); ListEntry = RemoveHeadList(&DeviceExtension->PendingIrpListHead);
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]); Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
@ -3037,9 +3057,6 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
LunExtension->PendingIrpCount--; LunExtension->PendingIrpCount--;
DeviceExtension->PendingIrpCount--; DeviceExtension->PendingIrpCount--;
SpiAddActiveIrp(DeviceExtension, Irp);
LunExtension->ActiveIrpCount++;
DeviceExtension->ActiveIrpCount++;
SpiAllocateSrbExtension(DeviceExtension, Srb); SpiAllocateSrbExtension(DeviceExtension, Srb);
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->Lock); KeReleaseSpinLockFromDpcLevel(&DeviceExtension->Lock);
@ -3067,10 +3084,11 @@ SpiStartIo(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
Srb = Irp->Tail.Overlay.DriverContext[3]; Srb = Irp->Tail.Overlay.DriverContext[3];
LunExtension = Irp->Tail.Overlay.DriverContext[2]; LunExtension = Irp->Tail.Overlay.DriverContext[2];
Srb->SrbFlags |= SRB_FLAGS_IS_ACTIVE;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Srb->DataTransferLength; Irp->IoStatus.Information = Srb->DataTransferLength;
SpiAddActiveIrp(DeviceExtension, Irp);
if (!KeSynchronizeExecution(DeviceExtension->Interrupt, if (!KeSynchronizeExecution(DeviceExtension->Interrupt,
ScsiPortStartPacket, ScsiPortStartPacket,
Srb)) Srb))

View file

@ -5,7 +5,7 @@
* An enumeration containing the states in the timer DFA * An enumeration containing the states in the timer DFA
*/ */
#define VERSION "0.0.2" #define VERSION "0.0.3"
typedef enum _SCSI_PORT_TIMER_STATES typedef enum _SCSI_PORT_TIMER_STATES
{ {
@ -42,9 +42,9 @@ typedef struct _SCSI_PORT_LUN_EXTENSION
ULONG PendingIrpCount; ULONG PendingIrpCount;
ULONG ActiveIrpCount; ULONG ActiveIrpCount;
ULONG NextLuRequestCount;
PIRP NextIrp; PIRP NextIrp;
ULONG Flags;
/* More data? */ /* More data? */
@ -97,7 +97,9 @@ typedef struct _SCSI_PORT_DEVICE_EXTENSION
PHYSICAL_ADDRESS PhysicalAddress; PHYSICAL_ADDRESS PhysicalAddress;
PVOID VirtualAddress; PVOID VirtualAddress;
ULONG VirtualAddressMap; RTL_BITMAP SrbExtensionAllocMap;
ULONG MaxSrbExtensions;
ULONG CurrentSrbExtensions;
ULONG CommonBufferLength; ULONG CommonBufferLength;
LIST_ENTRY PendingIrpListHead; LIST_ENTRY PendingIrpListHead;
@ -105,10 +107,6 @@ typedef struct _SCSI_PORT_DEVICE_EXTENSION
ULONG PendingIrpCount; ULONG PendingIrpCount;
ULONG ActiveIrpCount; ULONG ActiveIrpCount;
ULONG CompleteRequestCount;
ULONG NextRequestCount;
ULONG NextLuRequestCount;
UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */ UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */
} SCSI_PORT_DEVICE_EXTENSION, *PSCSI_PORT_DEVICE_EXTENSION; } SCSI_PORT_DEVICE_EXTENSION, *PSCSI_PORT_DEVICE_EXTENSION;