Commit in reactos/drivers/storage/scsiport on MAIN
scsiport.c+93-751.59 -> 1.60
scsiport_int.h+5-71.9 -> 1.10
+98-82
2 modified files
- 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.

reactos/drivers/storage/scsiport
scsiport.c 1.59 -> 1.60
diff -u -r1.59 -r1.60
--- scsiport.c	7 Jun 2004 20:03:00 -0000	1.59
+++ scsiport.c	10 Jun 2004 08:14:57 -0000	1.60
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  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
  * PROJECT:         ReactOS kernel
@@ -45,8 +45,6 @@
 #define IRP_FLAG_NEXT		0x00000002
 #define IRP_FLAG_NEXT_LU	0x00000004
 
-#define MAX_SRB_EXTENSIONS	32
-
 /* GLOBALS *******************************************************************/
 
 static VOID
@@ -257,7 +255,7 @@
 	  while (Irp)
 	    {
 	      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;
 		  ScsiPortNotification(RequestComplete,
@@ -623,16 +621,36 @@
 	  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 */
   DeviceExtension->CommonBufferLength =
-    NumberOfBytes + PAGE_ROUND_UP(DeviceExtension->SrbExtensionSize * MAX_SRB_EXTENSIONS);
+    NumberOfBytes + PAGE_ROUND_UP(DeviceExtension->SrbExtensionSize * DeviceExtension->MaxSrbExtensions);
   DeviceExtension->VirtualAddress =
     HalAllocateCommonBuffer(DeviceExtension->AdapterObject,
 			    DeviceExtension->CommonBufferLength,
 			    &DeviceExtension->PhysicalAddress,
 			    FALSE);
-  DeviceExtension->VirtualAddressMap = 0;
   if (DeviceExtension->VirtualAddress == NULL)
     {
       DPRINT1("HalAllocateCommonBuffer() failed!\n");
@@ -641,7 +659,7 @@
     }
 
   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 @@
   PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
 
   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,
 				      SCSI_PORT_DEVICE_EXTENSION,
@@ -1258,14 +1278,12 @@
 	  DPRINT("Notify: RequestComplete (Srb %p)\n", Srb);
 	  DeviceExtension->Flags |= IRP_FLAG_COMPLETE;
 	  Srb->SrbFlags &= ~SRB_FLAGS_IS_ACTIVE;
-	  InterlockedIncrement((PLONG)&DeviceExtension->CompleteRequestCount);
 	}
 	break;
 
       case NextRequest:
 	DPRINT("Notify: NextRequest\n");
 	DeviceExtension->Flags |= IRP_FLAG_NEXT;
-	InterlockedIncrement((PLONG)&DeviceExtension->NextRequestCount);
 	break;
 
       case NextLuRequest:
@@ -1289,8 +1307,7 @@
 	  if (LunExtension)
 	    {
 	      DeviceExtension->Flags |= IRP_FLAG_NEXT_LU;
-	      InterlockedIncrement((PLONG)&LunExtension->NextLuRequestCount);
-	      InterlockedIncrement((PLONG)&DeviceExtension->NextLuRequestCount);
+	      LunExtension->Flags |= IRP_FLAG_NEXT_LU;
 	    }
 	}
 	break;
@@ -1753,43 +1770,42 @@
 SpiAllocateSrbExtension(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
 			PSCSI_REQUEST_BLOCK Srb)
 {
-  ULONG i;
-  ULONG mask;
+  ULONG index;
 
   DPRINT("SpiAllocateSrbExtension\n");
 
   DPRINT("DeviceExtension->VirtualAddress %x, DeviceExtension->SrbExtensionSize %x\n", 
          DeviceExtension->VirtualAddress, DeviceExtension->SrbExtensionSize);
 
+  Srb->SrbExtension = NULL;
   if (DeviceExtension->VirtualAddress != NULL &&
       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->VirtualAddressMap |= mask;
-	      Srb->SrbExtension = DeviceExtension->VirtualAddress + i * DeviceExtension->SrbExtensionSize;
-              DPRINT("%x\n", Srb->SrbExtension);
-	      return;
-	    }
+	  DeviceExtension->CurrentSrbExtensions++;  
+          Srb->SrbExtension = DeviceExtension->VirtualAddress + index * DeviceExtension->SrbExtensionSize;
+//	  Srb->QueueTag = i;
+//	  Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
 	}
     }
-  Srb->SrbExtension = NULL;
+  DPRINT("%x\n", Srb->SrbExtension);
 }
 
 static VOID
 SpiFreeSrbExtension(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
 		    PSCSI_REQUEST_BLOCK Srb)
 {
-  ULONG i;
+  ULONG index;
 
   if (DeviceExtension->VirtualAddress != NULL &&
       DeviceExtension->SrbExtensionSize > 0 &&
       Srb->SrbExtension != NULL)
     {
-      i = ((ULONG_PTR)Srb->SrbExtension - (ULONG_PTR)DeviceExtension->VirtualAddress) / DeviceExtension->SrbExtensionSize;
-      DeviceExtension->VirtualAddressMap &= ~(1 << i);
+      index = ((ULONG_PTR)Srb->SrbExtension - (ULONG_PTR)DeviceExtension->VirtualAddress) / DeviceExtension->SrbExtensionSize;
+      RtlClearBits(&DeviceExtension->SrbExtensionAllocMap, index, 1);
+      DeviceExtension->CurrentSrbExtensions--;
     }
   Srb->SrbExtension = NULL;
 }
@@ -1803,8 +1819,8 @@
   PIRP Irp;
   PIO_STACK_LOCATION IrpStack;
 
-  DPRINT("ScsiPortStartPacket() called\n");
-  
+  DPRINT("ScsiPortStartPacket(Context %x) called\n", Context);
+    
   Srb = (PSCSI_REQUEST_BLOCK)Context;
   Irp = (PIRP)Srb->OriginalRequest;
   IrpStack = IoGetCurrentIrpStackLocation(Irp);
@@ -2023,8 +2039,9 @@
 	      DPRINT ("DeviceTypeQualifier %x\n", ((PINQUIRYDATA)Srb->DataBuffer)->DeviceTypeQualifier);
 
 	      if (NT_SUCCESS(ScanData->Status) &&
-		  (Srb->SrbStatus == SRB_STATUS_SUCCESS ||
-		  Srb->SrbStatus == SRB_STATUS_DATA_OVERRUN) &&
+		  (Srb->SrbStatus == SRB_STATUS_SUCCESS || 
+		   (Srb->SrbStatus == SRB_STATUS_DATA_OVERRUN && 
+		    Srb->DataTransferLength >= sizeof(INQUIRYDATA))) &&
 		  ((PINQUIRYDATA)Srb->DataBuffer)->DeviceTypeQualifier == 0)
 		{
 		  /* Copy inquiry data */
@@ -2032,12 +2049,12 @@
 				 Srb->DataBuffer,
 				 sizeof(INQUIRYDATA));
 	          ScanData->Lun++;
-		 }
-	       else
-		 {
-		   SpiRemoveLunExtension (ScanData->LunExtension);
-		   ScanData->Lun = SCSI_MAXIMUM_LOGICAL_UNITS;
-		 }
+		}
+	      else
+		{
+		  SpiRemoveLunExtension (ScanData->LunExtension);
+		  ScanData->Lun = SCSI_MAXIMUM_LOGICAL_UNITS;
+		}
 	    }
           if (ScanData->Lun >= SCSI_MAXIMUM_LOGICAL_UNITS)
             {
@@ -2053,6 +2070,7 @@
           Srb->PathId = ScanData->Bus;
           Srb->TargetId = ScanData->Target;
           Srb->SrbStatus = SRB_STATUS_SUCCESS;
+	  Srb->TimeOutValue = 2;
           Cdb = (PCDB) &Srb->Cdb;
 
           Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
@@ -2715,8 +2733,8 @@
   PSCSI_PORT_LUN_EXTENSION LunExtension;
   PIRP CurrentIrp;
   LunExtension = Irp->Tail.Overlay.DriverContext[2];
-  LunExtension->ActiveIrpCount--;
-  DeviceExtension->ActiveIrpCount--;
+  InterlockedDecrement((PLONG)&LunExtension->ActiveIrpCount);
+  InterlockedDecrement((PLONG)&DeviceExtension->ActiveIrpCount);
   if (PrevIrp)
     {
       InterlockedExchangePointer(&PrevIrp->Tail.Overlay.DriverContext[0], 
@@ -2755,11 +2773,16 @@
 		PIRP Irp)
 {
   PSCSI_PORT_LUN_EXTENSION LunExtension;
+  PSCSI_REQUEST_BLOCK Srb;
   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;
   InterlockedExchangePointer(&DeviceExtension->NextIrp, Irp);
   Irp->Tail.Overlay.DriverContext[1] = (PVOID)LunExtension->NextIrp;
   InterlockedExchangePointer(&LunExtension->NextIrp, Irp);
+  InterlockedIncrement((PLONG)&LunExtension->ActiveIrpCount);
+  InterlockedIncrement((PLONG)&DeviceExtension->ActiveIrpCount);
 }
 
 static VOID
@@ -2810,11 +2833,19 @@
   if (NextIrp)
     {
       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;
       LunExtension = Srb->OriginalRequest;
 
       ListEntry = DeviceExtension->PendingIrpListHead.Flink;
-      while (ListEntry != DeviceExtension->PendingIrpListHead.Flink)
+      while (ListEntry != &DeviceExtension->PendingIrpListHead)
         {
           Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
           if ((ULONG)Irp->Tail.Overlay.DriverContext[2] > Srb->QueueSortKey)
@@ -2828,24 +2859,20 @@
       LunExtension->PendingIrpCount++;
     }
 
-  while (DeviceExtension->CompleteRequestCount ||
-         ((DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->ActiveIrpCount < MAX_SRB_EXTENSIONS) && !IsListEmpty(&DeviceExtension->PendingIrpListHead) &&
-	 (DeviceExtension->NextRequestCount || DeviceExtension->NextLuRequestCount || DeviceExtension->NextIrp == NULL)))
-    {
-      DPRINT ("CompleteRequestCount %d, NextRequestCount %d, NextLuRequestCount %d, PendingIrpList is %s, ActiveIrpList is %s\n", 
-	      DeviceExtension->CompleteRequestCount, 
-	      DeviceExtension->NextRequestCount,
-	      DeviceExtension->NextLuRequestCount, 
-	      IsListEmpty(&DeviceExtension->PendingIrpListHead) ? "EMPTY" : "NOT empty", 
-	      DeviceExtension->NextIrp == NULL ? "EMPTY" : "NOT empty");
+  while (DeviceExtension->Flags & IRP_FLAG_COMPLETE ||
+         (((DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->CurrentSrbExtensions < DeviceExtension->MaxSrbExtensions) && 
+	  DeviceExtension->PendingIrpCount > 0 &&
+	  (DeviceExtension->Flags & (IRP_FLAG_NEXT|IRP_FLAG_NEXT_LU) || DeviceExtension->NextIrp == NULL))))
+    {
+      DPRINT ("RequestComplete %d, NextRequest %d, NextLuRequest %d, PendingIrpCount %d, ActiveIrpCount %d\n", 
+	      DeviceExtension->Flags & IRP_FLAG_COMPLETE ? 1 : 0, 
+	      DeviceExtension->Flags & IRP_FLAG_NEXT ? 1 : 0,
+	      DeviceExtension->Flags & IRP_FLAG_NEXT_LU ? 1 : 0, 
+	      DeviceExtension->PendingIrpCount, 
+	      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;
 	  PrevIrp = NULL;
@@ -2857,7 +2884,6 @@
               if (!(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE))
 	        {
                   BOOLEAN CompleteThisRequest;
-		  InterlockedDecrement((PLONG)&DeviceExtension->CompleteRequestCount);
                   LunExtension = Irp->Tail.Overlay.DriverContext[2];
 		  IrpStack = IoGetCurrentIrpStackLocation(Irp);
 		  OriginalSrb = IrpStack->Parameters.Scsi.Srb;
@@ -2954,16 +2980,14 @@
 	    {
 	      ListEntry = RemoveTailList(&CompleteIrpListHead);
 	      Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
-	      Srb = Irp->Tail.Overlay.DriverContext[3];
 	      IoCompleteRequest(Irp, IO_NO_INCREMENT);
 	    }
 	  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->Lock);
         }
-      if (DeviceExtension->NextLuRequestCount ||
-	  DeviceExtension->NextRequestCount)
+      if (DeviceExtension->Flags & (IRP_FLAG_NEXT|IRP_FLAG_NEXT_LU) &&
+          (DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->CurrentSrbExtensions < DeviceExtension->MaxSrbExtensions)) 
         {
 	  BOOLEAN StartThisRequest;
-	  DeviceExtension->Flags &= ~(IRP_FLAG_NEXT|IRP_FLAG_NEXT_LU);
 	  ListEntry = DeviceExtension->PendingIrpListHead.Flink;
 	  while (ListEntry != &DeviceExtension->PendingIrpListHead)
 	    {
@@ -2972,21 +2996,21 @@
 	      Srb = Irp->Tail.Overlay.DriverContext[3];
 	      LunExtension = Srb->OriginalRequest;
 	      if (DeviceExtension->SrbExtensionSize > 0 &&
-		  DeviceExtension->ActiveIrpCount >= MAX_SRB_EXTENSIONS)
+		  DeviceExtension->CurrentSrbExtensions >= DeviceExtension->MaxSrbExtensions)
 	        {
 		  break;
 		}
-	      if (LunExtension->NextLuRequestCount > 0)
+	      if (LunExtension->Flags & IRP_FLAG_NEXT_LU)
                 {
 		  StartThisRequest = TRUE;
-		  InterlockedDecrement((PLONG)&LunExtension->NextLuRequestCount);
-		  InterlockedDecrement((PLONG)&DeviceExtension->NextLuRequestCount);
+		  LunExtension->Flags &= ~IRP_FLAG_NEXT_LU;
+                  DeviceExtension->Flags &= ~IRP_FLAG_NEXT_LU;
 		}
-	      else if (DeviceExtension->NextRequestCount > 0 &&
+	      else if (DeviceExtension->Flags & IRP_FLAG_NEXT && 
 		       LunExtension->ActiveIrpCount == 0)
 	        {
-		  InterlockedDecrement((PLONG)&DeviceExtension->NextRequestCount);
 		  StartThisRequest = TRUE;
+                  DeviceExtension->Flags &= ~IRP_FLAG_NEXT;
 		}
 	      else
 	        {
@@ -2997,12 +3021,9 @@
 		  LunExtension->PendingIrpCount--;
 		  DeviceExtension->PendingIrpCount--;
                   RemoveEntryList((PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
-                  LunExtension->ActiveIrpCount++;
-                  DeviceExtension->ActiveIrpCount++;
-		  SpiAllocateSrbExtension(DeviceExtension, Srb);
-
 		  Irp->Tail.Overlay.DriverContext[2] = LunExtension;
 		  Srb->OriginalRequest = Irp;
+		  SpiAllocateSrbExtension(DeviceExtension, Srb);
 
                   InsertHeadList(&NextIrpListHead, (PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);		   
 		}
@@ -3015,7 +3036,6 @@
 	    {
 	      ListEntry = RemoveTailList(&NextIrpListHead);
 	      Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
-	      SpiAddActiveIrp(DeviceExtension, Irp);
 	      KeReleaseSpinLockFromDpcLevel(&DeviceExtension->Lock);
 
 	      // Start this Irp
@@ -3026,7 +3046,7 @@
 
       if (!IsListEmpty(&DeviceExtension->PendingIrpListHead) &&
 	  DeviceExtension->NextIrp == NULL &&
-	  (DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->ActiveIrpCount < MAX_SRB_EXTENSIONS))
+	  (DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->CurrentSrbExtensions < DeviceExtension->MaxSrbExtensions))
         {
 	  ListEntry = RemoveHeadList(&DeviceExtension->PendingIrpListHead);
           Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
@@ -3037,9 +3057,6 @@
 
 	  LunExtension->PendingIrpCount--;
 	  DeviceExtension->PendingIrpCount--;
-	  SpiAddActiveIrp(DeviceExtension, Irp);
-          LunExtension->ActiveIrpCount++;
-          DeviceExtension->ActiveIrpCount++;
 	  SpiAllocateSrbExtension(DeviceExtension, Srb);
           KeReleaseSpinLockFromDpcLevel(&DeviceExtension->Lock);
 
@@ -3067,10 +3084,11 @@
   Srb = Irp->Tail.Overlay.DriverContext[3];
   LunExtension = Irp->Tail.Overlay.DriverContext[2];
 
-  Srb->SrbFlags |= SRB_FLAGS_IS_ACTIVE;
   Irp->IoStatus.Status = STATUS_SUCCESS;
   Irp->IoStatus.Information = Srb->DataTransferLength;
 
+  SpiAddActiveIrp(DeviceExtension, Irp);
+
   if (!KeSynchronizeExecution(DeviceExtension->Interrupt,
 			      ScsiPortStartPacket,
                               Srb))

reactos/drivers/storage/scsiport
scsiport_int.h 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- scsiport_int.h	7 Jun 2004 16:37:07 -0000	1.9
+++ scsiport_int.h	10 Jun 2004 08:14:57 -0000	1.10
@@ -5,7 +5,7 @@
  *	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
 {
@@ -42,9 +42,9 @@
 
   ULONG PendingIrpCount;
   ULONG ActiveIrpCount;
-  ULONG NextLuRequestCount;
 
   PIRP NextIrp;
+  ULONG Flags;
 
   /* More data? */
 
@@ -97,7 +97,9 @@
 
   PHYSICAL_ADDRESS PhysicalAddress;
   PVOID VirtualAddress;
-  ULONG VirtualAddressMap;
+  RTL_BITMAP SrbExtensionAllocMap;
+  ULONG MaxSrbExtensions;
+  ULONG CurrentSrbExtensions;
   ULONG CommonBufferLength;
 
   LIST_ENTRY PendingIrpListHead;
@@ -105,10 +107,6 @@
   ULONG PendingIrpCount;
   ULONG ActiveIrpCount;
 
-  ULONG CompleteRequestCount;
-  ULONG NextRequestCount;
-  ULONG NextLuRequestCount;
-
   UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */
 } SCSI_PORT_DEVICE_EXTENSION, *PSCSI_PORT_DEVICE_EXTENSION;
 
CVSspam 0.2.8