Started using lookaside lists for SRBs.
[reactos.git] / reactos / drivers / storage / class2 / class2.c
index 2b9b4f3..6815b41 100644 (file)
@@ -1,4 +1,22 @@
-/* $Id: class2.c,v 1.9 2002/03/04 22:31:22 ekohl Exp $
+/*
+ *  ReactOS kernel
+ *  Copyright (C) 2001, 2002 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: class2.c,v 1.13 2002/03/22 23:06:58 ekohl Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -24,6 +42,8 @@
 
 #define VERSION "0.0.1"
 
+#define TAG_SRBT  TAG('S', 'r', 'b', 'T')
+
 #define INQUIRY_DATA_SIZE 2048
 
 
@@ -126,10 +146,10 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
   StartingOffset = CurrentIrpStack->Parameters.Read.ByteOffset;
 
   /* calculate logical block address */
-  StartingBlock.QuadPart = StartingOffset.QuadPart / 512; // >> deviceExtension->SectorShift;
+  StartingBlock.QuadPart = StartingOffset.QuadPart >> DeviceExtension->SectorShift;
   LogicalBlockAddress = (ULONG)StartingBlock.u.LowPart;
 
-  DPRINT1("Logical block address: %lu\n", LogicalBlockAddress);
+  DPRINT("Logical block address: %lu\n", LogicalBlockAddress);
 
   /* allocate and initialize an SRB */
   /* FIXME: use lookaside list instead */
@@ -143,7 +163,7 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
   Srb->TargetId = DeviceExtension->TargetId;
   Srb->Lun = DeviceExtension->Lun;
   Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
-  Srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
+  Srb->DataBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
   Srb->DataTransferLength = CurrentIrpStack->Parameters.Read.Length;
   Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
   Srb->QueueSortKey = LogicalBlockAddress;
@@ -180,14 +200,14 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
 
   if (CurrentIrpStack->MajorFunction == IRP_MJ_READ)
     {
-      DPRINT1("ScsiClassBuildRequest: Read Command\n");
+      DPRINT("ScsiClassBuildRequest: Read Command\n");
 
       Srb->SrbFlags |= SRB_FLAGS_DATA_IN;
       Cdb->CDB10.OperationCode = SCSIOP_READ;
     }
   else
     {
-      DPRINT1("ScsiClassBuildRequest: Write Command\n");
+      DPRINT("ScsiClassBuildRequest: Write Command\n");
 
       Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
       Cdb->CDB10.OperationCode = SCSIOP_WRITE;
@@ -223,7 +243,7 @@ ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
   CurrentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
 #endif
 
-  DPRINT1("IoSetCompletionRoutine (Irp %p  Srb %p)\n", Irp, Srb);
+  DPRINT("IoSetCompletionRoutine (Irp %p  Srb %p)\n", Irp, Srb);
   IoSetCompletionRoutine(Irp,
                         ScsiClassIoComplete,
                         Srb,
@@ -462,7 +482,7 @@ ScsiClassGetCapabilities(PDEVICE_OBJECT PortDeviceObject,
   PIRP Irp;
 
   *PortCapabilities = NULL;
-  Buffer = ExAllocatePool(NonPagedPool, /* FIXME: use paged pool */
+  Buffer = ExAllocatePool(NonPagedPool,
                          sizeof(IO_SCSI_CAPABILITIES));
   if (Buffer == NULL)
     {
@@ -523,6 +543,8 @@ ScsiClassGetInquiryData(PDEVICE_OBJECT PortDeviceObject,
   KEVENT Event;
   PIRP Irp;
 
+  DPRINT("ScsiClassGetInquiryData() called\n");
+
   *ConfigInfo = NULL;
   Buffer = ExAllocatePool(NonPagedPool,
                          INQUIRY_DATA_SIZE);
@@ -571,6 +593,8 @@ ScsiClassGetInquiryData(PDEVICE_OBJECT PortDeviceObject,
       *ConfigInfo = Buffer;
     }
 
+  DPRINT("ScsiClassGetInquiryData() done\n");
+
   return(Status);
 }
 
@@ -607,6 +631,8 @@ ScsiClassInitialize(PVOID Argument1,
 
   ConfigInfo = IoGetConfigurationInformation();
 
+  DPRINT("ScsiPorts: %lu\n", ConfigInfo->ScsiPortCount);
+
   /* look for ScsiPortX scsi port devices */
   for (PortNumber = 0; PortNumber < ConfigInfo->ScsiPortCount; PortNumber++)
     {
@@ -635,19 +661,50 @@ ScsiClassInitialize(PVOID Argument1,
              DiskFound = TRUE;
            }
        }
+      else
+       {
+         DbgPrint("Couldn't find ScsiPort%lu (Status %lx)\n", PortNumber, Status);
+       }
     }
 
-  DPRINT1("ScsiClassInitialize() done!\n");
+  DPRINT("ScsiClassInitialize() done!\n");
 
   return((DiskFound == TRUE) ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE);
 }
 
 
+/**********************************************************************
+ * NAME                                                        EXPORTED
+ *     ScsiClassInitializeSrbLookasideList
+ *
+ * DESCRIPTION
+ *     Initializes a lookaside list for SRBs.
+ *
+ * RUN LEVEL
+ *     PASSIVE_LEVEL
+ *
+ * ARGUMENTS
+ *     DeviceExtension
+ *             Class specific device extension.
+ *
+ *     NumberElements
+ *             Maximum number of elements of the lookaside list.
+ *
+ * RETURN VALUE
+ *     None.
+ */
+
 VOID STDCALL
 ScsiClassInitializeSrbLookasideList(PDEVICE_EXTENSION DeviceExtension,
                                    ULONG NumberElements)
 {
-  UNIMPLEMENTED;
+  ExInitializeNPagedLookasideList(&DeviceExtension->SrbLookasideListHead,
+                                 NULL,
+                                 NULL,
+                                 NonPagedPool,
+                                 sizeof(SCSI_REQUEST_BLOCK),
+                                 TAG_SRBT,
+                                 (USHORT)NumberElements);
 }
 
 
@@ -681,12 +738,12 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
   PSCSI_REQUEST_BLOCK Srb;
   NTSTATUS Status;
 
-  DPRINT1("ScsiClassIoComplete(DeviceObject %p  Irp %p  Context %p) called\n",
+  DPRINT("ScsiClassIoComplete(DeviceObject %p  Irp %p  Context %p) called\n",
          DeviceObject, Irp, Context);
 
   DeviceExtension = DeviceObject->DeviceExtension;
   Srb = (PSCSI_REQUEST_BLOCK)Context;
-  DPRINT1("Srb %p\n", Srb);
+  DPRINT("Srb %p\n", Srb);
 
   IrpStack = IoGetCurrentIrpStackLocation(Irp);
 
@@ -710,7 +767,7 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
 #endif
 
   /* FIXME: use lookaside list instead */
-  DPRINT1("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb);
+  DPRINT("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb);
   ExFreePool(IrpStack->Parameters.Scsi.Srb);
 
 //  Irp->IoStatus.Status = Status;
@@ -738,7 +795,7 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
        }
     }
 
-  DPRINT1("ScsiClassIoComplete() done (Status %lx)\n", Status);
+  DPRINT("ScsiClassIoComplete() done (Status %lx)\n", Status);
 
 //  return(Status);
   return(STATUS_SUCCESS);
@@ -786,7 +843,7 @@ ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
 
   DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-  CapacityBuffer = ExAllocatePool(NonPagedPool, //NonPagedPoolCacheAligned,
+  CapacityBuffer = ExAllocatePool(NonPagedPool,
                                  sizeof(READ_CAPACITY_DATA));
   if (CapacityBuffer == NULL)
     {
@@ -811,42 +868,61 @@ ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
   DPRINT("Srb: %p\n", &Srb);
   if (NT_SUCCESS(Status))
     {
-       SectorSize = (((PUCHAR)&CapacityBuffer->BytesPerBlock)[0] << 24) |
-                    (((PUCHAR)&CapacityBuffer->BytesPerBlock)[1] << 16) |
-                    (((PUCHAR)&CapacityBuffer->BytesPerBlock)[2] << 8) |
-                     ((PUCHAR)&CapacityBuffer->BytesPerBlock)[3];
-
-
-       LastSector = (((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[0] << 24) |
-                    (((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[1] << 16) |
-                    (((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[2] << 8) |
-                     ((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[3];
-
-       DeviceExtension->DiskGeometry->BytesPerSector = SectorSize;
-
-       DeviceExtension->PartitionLength.QuadPart = (LONGLONG)(LastSector + 1);
-       WHICH_BIT(DeviceExtension->DiskGeometry->BytesPerSector, DeviceExtension->SectorShift);
-       DeviceExtension->PartitionLength.QuadPart =
-         (DeviceExtension->PartitionLength.QuadPart << DeviceExtension->SectorShift);
-
-       if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
-         {
-           DeviceExtension->DiskGeometry->MediaType = RemovableMedia;
-         }
-       else
-         {
-           DeviceExtension->DiskGeometry->MediaType = FixedMedia;
-         }
-       DeviceExtension->DiskGeometry->Cylinders.QuadPart = (LONGLONG)((LastSector + 1)/(32 * 64));
-       DeviceExtension->DiskGeometry->SectorsPerTrack = 32;
-       DeviceExtension->DiskGeometry->TracksPerCylinder = 64;
-
-       DPRINT1("SectorSize: %lu  SectorCount: %lu\n", SectorSize, LastSector + 1);
+      SectorSize = (((PUCHAR)&CapacityBuffer->BytesPerBlock)[0] << 24) |
+                  (((PUCHAR)&CapacityBuffer->BytesPerBlock)[1] << 16) |
+                  (((PUCHAR)&CapacityBuffer->BytesPerBlock)[2] << 8) |
+                   ((PUCHAR)&CapacityBuffer->BytesPerBlock)[3];
+
+
+      LastSector = (((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[0] << 24) |
+                  (((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[1] << 16) |
+                  (((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[2] << 8) |
+                   ((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[3];
+
+      DeviceExtension->DiskGeometry->BytesPerSector = SectorSize;
+
+      DeviceExtension->PartitionLength.QuadPart = (LONGLONG)(LastSector + 1);
+      WHICH_BIT(DeviceExtension->DiskGeometry->BytesPerSector,
+               DeviceExtension->SectorShift);
+      DeviceExtension->PartitionLength.QuadPart =
+       (DeviceExtension->PartitionLength.QuadPart << DeviceExtension->SectorShift);
+
+      if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
+       {
+         DeviceExtension->DiskGeometry->MediaType = RemovableMedia;
+       }
+      else
+       {
+         DeviceExtension->DiskGeometry->MediaType = FixedMedia;
+       }
+      DeviceExtension->DiskGeometry->Cylinders.QuadPart = (LONGLONG)((LastSector + 1)/(32 * 64));
+      DeviceExtension->DiskGeometry->SectorsPerTrack = 32;
+      DeviceExtension->DiskGeometry->TracksPerCylinder = 64;
+
+      DPRINT("SectorSize: %lu  SectorCount: %lu\n", SectorSize, LastSector + 1);
+    }
+  else
+    {
+      /* Use default values if disk geometry cannot be read */
+      RtlZeroMemory(&DeviceExtension->DiskGeometry,
+                   sizeof(DISK_GEOMETRY));
+      DeviceExtension->DiskGeometry->BytesPerSector = 512;
+      DeviceExtension->SectorShift = 9;
+      DeviceExtension->PartitionLength.QuadPart = 0;
+
+      if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
+       {
+         DeviceExtension->DiskGeometry->MediaType = RemovableMedia;
+       }
+      else
+       {
+         DeviceExtension->DiskGeometry->MediaType = FixedMedia;
+       }
     }
 
   ExFreePool(CapacityBuffer);
 
-  DPRINT1("ScsiClassReadDriveCapacity() done\n");
+  DPRINT("ScsiClassReadDriveCapacity() done\n");
 
   return(Status);
 }
@@ -938,7 +1014,7 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
                                      &IoStatusBlock);
   if (Irp == NULL)
     {
-      DPRINT("IoBuildDeviceIoControlRequest() failed\n");
+      DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
       return(STATUS_INSUFFICIENT_RESOURCES);
     }
 
@@ -974,7 +1050,7 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
       Status = STATUS_SUCCESS;
     }
 
-  DPRINT1("ScsiClassSendSrbSynchronous() done\n");
+  DPRINT("ScsiClassSendSrbSynchronous() done\n");
 
   return(Status);
 }
@@ -1023,19 +1099,17 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
   ULONG TransferPages;
   NTSTATUS Status;
 
-  DPRINT1("ScsiClassReadWrite() called\n");
+  DPRINT("ScsiClassReadWrite() called\n");
 
   DeviceExtension = DeviceObject->DeviceExtension;
   IrpStack  = IoGetCurrentIrpStackLocation(Irp);
 
-  DPRINT1("Relative Offset: %I64u  Length: %lu\n",
+  DPRINT("Relative Offset: %I64u  Length: %lu\n",
         IrpStack->Parameters.Read.ByteOffset.QuadPart,
         IrpStack->Parameters.Read.Length);
 
   TransferLength = IrpStack->Parameters.Read.Length;
 
-
-
   if ((DeviceObject->Flags & DO_VERIFY_VOLUME) &&
       !(IrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME))
     {
@@ -1050,8 +1124,7 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
       return(STATUS_VERIFY_REQUIRED);
     }
 
-#if 0
-  /* let the class driver perform its verification */
+  /* Class driver verifies the IRP */
   Status = DeviceExtension->ClassReadWriteVerification(DeviceObject,
                                                       Irp);
   if (!NT_SUCCESS(Status))
@@ -1065,9 +1138,8 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
       IoMarkIrpPending(Irp);
       return(STATUS_PENDING);
     }
-#endif
 
-  /* Finish a zero-byte transfer. */
+  /* Finish a zero-byte transfer */
   if (TransferLength == 0)
     {
       Irp->IoStatus.Status = STATUS_SUCCESS;
@@ -1079,7 +1151,7 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
 
   if (DeviceExtension->ClassStartIo != NULL)
     {
-      DPRINT1("ScsiClassReadWrite() starting packet\n");
+      DPRINT("ScsiClassReadWrite() starting packet\n");
 
       IoMarkIrpPending(Irp);
       IoStartPacket(DeviceObject,
@@ -1095,22 +1167,22 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
   /* Adjust partition-relative starting offset to absolute offset */
   IrpStack->Parameters.Read.ByteOffset.QuadPart += DeviceExtension->StartingOffset.QuadPart;
 
-  /* Calculate number of pages in this transfer. */
+  /* Calculate number of pages in this transfer */
   TransferPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Irp->MdlAddress),
                                                 IrpStack->Parameters.Read.Length);
 
 #if 0
-  if (IrpStack->Parameters.Read.Length > maximumTransferLength ||
+  if (TransferLength > maximumTransferLength ||
       TransferPages > DeviceExtension->PortCapabilities->MaximumPhysicalPages)
     {
-
+      /* FIXME: split request */
     }
 #endif
 
   ScsiClassBuildRequest(DeviceObject,
                        Irp);
 
-  DPRINT1("ScsiClassReadWrite() done\n");
+  DPRINT("ScsiClassReadWrite() done\n");
 
   /* Call the port driver */
   return(IoCallDriver(DeviceExtension->PortDeviceObject,