Silenced it.
[reactos.git] / reactos / drivers / storage / class2 / class2.c
index 0ea7816..2e0a4cf 100644 (file)
@@ -1,4 +1,22 @@
-/* $Id: class2.c,v 1.4 2002/01/31 14:57:58 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.10 2002/03/08 11:59:49 ekohl Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -110,193 +128,120 @@ VOID STDCALL
 ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
                      PIRP Irp)
 {
-  PDEVICE_EXTENSION   deviceExtension = DeviceObject->DeviceExtension;
-  PIO_STACK_LOCATION  currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
-  PIO_STACK_LOCATION  nextIrpStack = IoGetNextIrpStackLocation(Irp);
-  LARGE_INTEGER       startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
-  LARGE_INTEGER       startingBlock;
+  PDEVICE_EXTENSION DeviceExtension;
+  PIO_STACK_LOCATION CurrentIrpStack;
+  PIO_STACK_LOCATION NextIrpStack;
+  LARGE_INTEGER StartingOffset;
+  LARGE_INTEGER StartingBlock;
   PSCSI_REQUEST_BLOCK Srb;
-  PCDB                Cdb;
-  ULONG               logicalBlockAddress;
-  USHORT              transferBlocks;
-
-    //
-    // Calculate relative sector address.
-    //
+  PCDB Cdb;
+  ULONG LogicalBlockAddress;
+  USHORT TransferBlocks;
 
-//  logicalBlockAddress = (ULONG)(Int64ShrlMod32(startingOffset.QuadPart, deviceExtension->SectorShift));
+  DeviceExtension = DeviceObject->DeviceExtension;
+  CurrentIrpStack = IoGetCurrentIrpStackLocation(Irp);
+  NextIrpStack = IoGetNextIrpStackLocation(Irp);
+  StartingOffset = CurrentIrpStack->Parameters.Read.ByteOffset;
 
-  startingBlock.QuadPart = startingOffset.QuadPart >> deviceExtension->SectorShift;
-  logicalBlockAddress = (ULONG)startingBlock.u.LowPart;
+  /* calculate logical block address */
+  StartingBlock.QuadPart = StartingOffset.QuadPart / 512; // >> deviceExtension->SectorShift;
+  LogicalBlockAddress = (ULONG)StartingBlock.u.LowPart;
 
-    //
-    // Allocate an Srb.
-    //
+  DPRINT("Logical block address: %lu\n", LogicalBlockAddress);
 
-//    Srb = ExAllocateFromNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
+  /* allocate and initialize an SRB */
+  /* FIXME: use lookaside list instead */
   Srb = ExAllocatePool(NonPagedPool,
                       sizeof(SCSI_REQUEST_BLOCK));
 
-
   Srb->SrbFlags = 0;
-
-    //
-    // Write length to SRB.
-    //
-
   Srb->Length = sizeof(SCSI_REQUEST_BLOCK); //SCSI_REQUEST_BLOCK_SIZE;
+  Srb->OriginalRequest = Irp;
+  Srb->PathId = DeviceExtension->PathId;
+  Srb->TargetId = DeviceExtension->TargetId;
+  Srb->Lun = DeviceExtension->Lun;
+  Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
+  Srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
+  Srb->DataTransferLength = CurrentIrpStack->Parameters.Read.Length;
+  Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
+  Srb->QueueSortKey = LogicalBlockAddress;
 
-    //
-    // Set up IRP Address.
-    //
-
-    Srb->OriginalRequest = Irp;
-
-    //
-    // Set up target ID and logical unit number.
-    //
-
-    Srb->PathId = deviceExtension->PathId;
-    Srb->TargetId = deviceExtension->TargetId;
-    Srb->Lun = deviceExtension->Lun;
-    Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
-    Srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
-
-    //
-    // Save byte count of transfer in SRB Extension.
-    //
-
-    Srb->DataTransferLength = currentIrpStack->Parameters.Read.Length;
-
-    //
-    // Initialize the queue actions field.
-    //
-
-    Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
-
-    //
-    // Queue sort key is Relative Block Address.
-    //
-
-    Srb->QueueSortKey = logicalBlockAddress;
-
-    //
-    // Indicate auto request sense by specifying buffer and size.
-    //
-
-    Srb->SenseInfoBuffer = deviceExtension->SenseData;
-    Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
-
-    //
-    // Set timeout value of one unit per 64k bytes of data.
-    //
-
-    Srb->TimeOutValue = ((Srb->DataTransferLength + 0xFFFF) >> 16) *
-                        deviceExtension->TimeOutValue;
-
-    //
-    // Zero statuses.
-    //
-
-    Srb->SrbStatus = 0;
-    Srb->ScsiStatus = 0;
-    Srb->NextSrb = 0;
-
-    //
-    // Indicate that 10-byte CDB's will be used.
-    //
-
-    Srb->CdbLength = 10;
+  Srb->SenseInfoBuffer = DeviceExtension->SenseData;
+  Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
 
-    //
-    // Fill in CDB fields.
-    //
+  Srb->TimeOutValue =
+    ((Srb->DataTransferLength + 0xFFFF) >> 16) * DeviceExtension->TimeOutValue;
 
-    Cdb = (PCDB)Srb->Cdb;
+  Srb->SrbStatus = SRB_STATUS_SUCCESS;
+  Srb->ScsiStatus = 0;
+  Srb->NextSrb = 0;
 
-    //
-    // Zero 12 bytes for Atapi Packets
-    //
+  Srb->CdbLength = 10;
+  Cdb = (PCDB)Srb->Cdb;
 
+  /* Initialize ATAPI packet (12 bytes) */
   RtlZeroMemory(Cdb,
                MAXIMUM_CDB_SIZE);
 
-  Cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
-    transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >> deviceExtension->SectorShift);
-
-    //
-    // Move little endian values into CDB in big endian format.
-    //
+  Cdb->CDB10.LogicalUnitNumber = DeviceExtension->Lun;
+  TransferBlocks = (USHORT)(CurrentIrpStack->Parameters.Read.Length >> DeviceExtension->SectorShift);
 
-  Cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte3;
-  Cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte2;
-  Cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte1;
-  Cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte0;
+  /* Copy little endian values into CDB in big endian format */
+  Cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte3;
+  Cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte2;
+  Cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte1;
+  Cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte0;
 
-  Cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&transferBlocks)->Byte1;
-  Cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&transferBlocks)->Byte0;
+  Cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&TransferBlocks)->Byte1;
+  Cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&TransferBlocks)->Byte0;
 
-    //
-    // Set transfer direction flag and Cdb command.
-    //
 
-  if (currentIrpStack->MajorFunction == IRP_MJ_READ)
+  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;
+      Srb->SrbFlags |= SRB_FLAGS_DATA_IN;
+      Cdb->CDB10.OperationCode = SCSIOP_READ;
     }
   else
     {
-        DPRINT("ScsiClassBuildRequest: Write Command\n");
+      DPRINT("ScsiClassBuildRequest: Write Command\n");
 
-        Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
-        Cdb->CDB10.OperationCode = SCSIOP_WRITE;
+      Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
+      Cdb->CDB10.OperationCode = SCSIOP_WRITE;
     }
 
-    //
-    // If this is not a write-through request, then allow caching.
-    //
 
 #if 0
-  if (!(currentIrpStack->Flags & SL_WRITE_THROUGH))
+  /* if this is not a write-through request, then allow caching */
+  if (!(CurrentIrpStack->Flags & SL_WRITE_THROUGH))
     {
-        Srb->SrbFlags |= SRB_FLAGS_ADAPTER_CACHE_ENABLE;
+      Srb->SrbFlags |= SRB_FLAGS_ADAPTER_CACHE_ENABLE;
     }
   else
     {
-      /* If write caching is enable then force media access in the cdb. */
-      if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE)
+      /* if write caching is enable then force media access in the cdb */
+      if (DeviceExtension->DeviceFlags & DEV_WRITE_CACHE)
        {
          Cdb->CDB10.ForceUnitAccess = TRUE;
        }
     }
 #endif
 
-  /* Or in the default flags from the device object. */
-  Srb->SrbFlags |= deviceExtension->SrbFlags;
-
-    //
-    // Set up major SCSI function.
-    //
+  /* or in the default flags from the device object. */
+  Srb->SrbFlags |= DeviceExtension->SrbFlags;
 
-  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
 
-    //
-    // Save SRB address in next stack for port driver.
-    //
+  NextIrpStack->MajorFunction = IRP_MJ_SCSI;
+  NextIrpStack->Parameters.Scsi.Srb = Srb;
+  NextIrpStack->DeviceObject = DeviceObject;
 
-  nextIrpStack->Parameters.Scsi.Srb = Srb;
-
-    //
-    // Save retry count in current IRP stack.
-    //
 #if 0
-  currentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
+  /* save retry count in current IRP stack */
+  CurrentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
 #endif
 
-  /* Set up IoCompletion routine address. */
+  DPRINT("IoSetCompletionRoutine (Irp %p  Srb %p)\n", Irp, Srb);
   IoSetCompletionRoutine(Irp,
                         ScsiClassIoComplete,
                         Srb,
@@ -319,12 +264,12 @@ ScsiClassClaimDevice(PDEVICE_OBJECT PortDeviceObject,
   PIRP Irp;
   NTSTATUS Status;
 
-  DPRINT1("ScsiClassClaimDevice() called\n");
+  DPRINT("ScsiClassClaimDevice() called\n");
 
   if (NewPortDeviceObject != NULL)
     *NewPortDeviceObject = NULL;
 
-  /* Initialize an SRB */
+  /* initialize an SRB */
   RtlZeroMemory(&Srb,
                sizeof(SCSI_REQUEST_BLOCK));
   Srb.Length = SCSI_REQUEST_BLOCK_SIZE;
@@ -406,7 +351,7 @@ ScsiClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
   UNICODE_STRING DeviceName;
   NTSTATUS Status;
 
-  DPRINT1("ScsiClassCreateDeviceObject() called\n");
+  DPRINT("ScsiClassCreateDeviceObject() called\n");
 
   *DeviceObject = NULL;
 
@@ -421,7 +366,7 @@ ScsiClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
       return(Status);
     }
 
-  DPRINT1("Device name: '%wZ'\n", &DeviceName);
+  DPRINT("Device name: '%wZ'\n", &DeviceName);
 
   Status = IoCreateDevice(DriverObject,
                          InitializationData->DeviceExtensionSize,
@@ -432,7 +377,7 @@ ScsiClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
                          &InternalDeviceObject);
   if (NT_SUCCESS(Status))
     {
-      PDEVICE_EXTENSION deviceExtension = InternalDeviceObject->DeviceExtension;
+      DeviceExtension = InternalDeviceObject->DeviceExtension;
 
       DeviceExtension->ClassError = InitializationData->ClassError;
       DeviceExtension->ClassReadWriteVerification = InitializationData->ClassReadWriteVerification;
@@ -596,6 +541,8 @@ ScsiClassGetInquiryData(PDEVICE_OBJECT PortDeviceObject,
   KEVENT Event;
   PIRP Irp;
 
+  DPRINT1("ScsiClassGetInquiryData() called\n");
+
   *ConfigInfo = NULL;
   Buffer = ExAllocatePool(NonPagedPool,
                          INQUIRY_DATA_SIZE);
@@ -644,6 +591,8 @@ ScsiClassGetInquiryData(PDEVICE_OBJECT PortDeviceObject,
       *ConfigInfo = Buffer;
     }
 
+  DPRINT1("ScsiClassGetInquiryData() done\n");
+
   return(Status);
 }
 
@@ -680,6 +629,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++)
     {
@@ -696,9 +647,9 @@ ScsiClassInitialize(PVOID Argument1,
       DPRINT("Status 0x%08lX\n", Status);
       if (NT_SUCCESS(Status))
        {
-         DPRINT1("ScsiPort%lu found.\n", PortNumber);
+         DPRINT("ScsiPort%lu found.\n", PortNumber);
 
-         /* Check scsi port for attached disk drives */
+         /* check scsi port for attached disk drives */
          if (InitializationData->ClassFindDevices(DriverObject,
                                                   Argument2,
                                                   InitializationData,
@@ -708,10 +659,13 @@ ScsiClassInitialize(PVOID Argument1,
              DiskFound = TRUE;
            }
        }
+      else
+       {
+         DbgPrint("Couldn't find ScsiPort%lu (Status %lx)\n", PortNumber, Status);
+       }
     }
 
   DPRINT("ScsiClassInitialize() done!\n");
-for(;;);
 
   return((DiskFound == TRUE) ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE);
 }
@@ -750,14 +704,72 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
                    PIRP Irp,
                    PVOID Context)
 {
-  DPRINT1("ScsiClassIoComplete() called\n");
+  PDEVICE_EXTENSION DeviceExtension;
+  PIO_STACK_LOCATION IrpStack;
+  PSCSI_REQUEST_BLOCK Srb;
+  NTSTATUS Status;
+
+  DPRINT("ScsiClassIoComplete(DeviceObject %p  Irp %p  Context %p) called\n",
+         DeviceObject, Irp, Context);
+
+  DeviceExtension = DeviceObject->DeviceExtension;
+  Srb = (PSCSI_REQUEST_BLOCK)Context;
+  DPRINT("Srb %p\n", Srb);
+
+  IrpStack = IoGetCurrentIrpStackLocation(Irp);
+
+#if 0
+  if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS)
+    {
+      Status = STATUS_SUCCESS;
+    }
+  else
+    {
+      /* FIXME: improve error handling */
+      DPRINT1("Srb->SrbStatus %lx\n", Srb->SrbStatus);
+
+      if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_PENDING)
+       {
+         Status = STATUS_SUCCESS;
+       }
+      else
+      Status = STATUS_UNSUCCESSFUL;
+    }
+#endif
+
+  /* FIXME: use lookaside list instead */
+  DPRINT("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb);
+  ExFreePool(IrpStack->Parameters.Scsi.Srb);
+
+//  Irp->IoStatus.Status = Status;
+#if 0
+  if (!NT_SUCCESS(Status) &&
+      IoIsErrorUserInduced(Status))
+    {
+      IoSetHardErrorOrVerifyDevice(Irp,
+                                  DeviceObject);
+      Irp->IoStatus.Information = 0;
+    }
 
   if (Irp->PendingReturned)
     {
       IoMarkIrpPending(Irp);
     }
+#endif
 
-  return(Irp->IoStatus.Status);
+  if (DeviceExtension->ClassStartIo != NULL)
+    {
+      if (IrpStack->MajorFunction != IRP_MJ_DEVICE_CONTROL)
+       {
+         IoStartNextPacket(DeviceObject,
+                           FALSE);
+       }
+    }
+
+  DPRINT("ScsiClassIoComplete() done (Status %lx)\n", Status);
+
+//  return(Status);
+  return(STATUS_SUCCESS);
 }
 
 
@@ -798,7 +810,7 @@ ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
   ULONG LastSector;
   ULONG SectorSize;
 
-  DPRINT1("ScsiClassReadDriveCapacity() called\n");
+  DPRINT("ScsiClassReadDriveCapacity() called\n");
 
   DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
@@ -841,7 +853,8 @@ ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
        DeviceExtension->DiskGeometry->BytesPerSector = SectorSize;
 
        DeviceExtension->PartitionLength.QuadPart = (LONGLONG)(LastSector + 1);
-       WHICH_BIT(DeviceExtension->DiskGeometry->BytesPerSector, DeviceExtension->SectorShift);
+       WHICH_BIT(DeviceExtension->DiskGeometry->BytesPerSector,
+                 DeviceExtension->SectorShift);
        DeviceExtension->PartitionLength.QuadPart =
          (DeviceExtension->PartitionLength.QuadPart << DeviceExtension->SectorShift);
 
@@ -857,12 +870,12 @@ ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
        DeviceExtension->DiskGeometry->SectorsPerTrack = 32;
        DeviceExtension->DiskGeometry->TracksPerCylinder = 64;
 
-       DPRINT1("SectorSize: %lu  SectorCount: %lu\n", SectorSize, LastSector + 1);
+       DPRINT("SectorSize: %lu  SectorCount: %lu\n", SectorSize, LastSector + 1);
     }
 
   ExFreePool(CapacityBuffer);
 
-  DPRINT1("ScsiClassReadDriveCapacity() done\n");
+  DPRINT("ScsiClassReadDriveCapacity() done\n");
 
   return(Status);
 }
@@ -903,7 +916,7 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
   NTSTATUS Status;
 
 
-  DPRINT1("ScsiClassSendSrbSynchronous() called\n");
+  DPRINT("ScsiClassSendSrbSynchronous() called\n");
 
   DeviceExtension = DeviceObject->DeviceExtension;
 
@@ -954,7 +967,7 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
                                      &IoStatusBlock);
   if (Irp == NULL)
     {
-      DPRINT("IoBuildDeviceIoControlRequest() failed\n");
+      DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
       return(STATUS_INSUFFICIENT_RESOURCES);
     }
 
@@ -981,14 +994,16 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
 
   if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS)
     {
-
+      /* FIXME!! */
+      DPRINT1("Fix return value!\n");
+      Status = STATUS_UNSUCCESSFUL;
     }
   else
     {
       Status = STATUS_SUCCESS;
     }
 
-  DPRINT1("ScsiClassSendSrbSynchronous() done\n");
+  DPRINT("ScsiClassSendSrbSynchronous() done\n");
 
   return(Status);
 }
@@ -1037,11 +1052,15 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
   ULONG TransferPages;
   NTSTATUS Status;
 
-  DPRINT1("ScsiClassReadWrite() called\n");
+  DPRINT("ScsiClassReadWrite() called\n");
 
   DeviceExtension = DeviceObject->DeviceExtension;
   IrpStack  = IoGetCurrentIrpStackLocation(Irp);
 
+  DPRINT("Relative Offset: %I64u  Length: %lu\n",
+        IrpStack->Parameters.Read.ByteOffset.QuadPart,
+        IrpStack->Parameters.Read.Length);
+
   TransferLength = IrpStack->Parameters.Read.Length;
 
 
@@ -1089,6 +1108,8 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
 
   if (DeviceExtension->ClassStartIo != NULL)
     {
+      DPRINT("ScsiClassReadWrite() starting packet\n");
+
       IoMarkIrpPending(Irp);
       IoStartPacket(DeviceObject,
                    Irp,
@@ -1118,7 +1139,7 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
   ScsiClassBuildRequest(DeviceObject,
                        Irp);
 
-  DPRINT1("ScsiClassReadWrite() done\n");
+  DPRINT("ScsiClassReadWrite() done\n");
 
   /* Call the port driver */
   return(IoCallDriver(DeviceExtension->PortDeviceObject,
@@ -1144,13 +1165,20 @@ static NTSTATUS STDCALL
 ScsiClassDeviceDispatch(IN PDEVICE_OBJECT DeviceObject,
                        IN PIRP Irp)
 {
-  DPRINT1("ScsiClassDeviceDispatch() called\n");
+  PDEVICE_EXTENSION DeviceExtension;
 
-  Irp->IoStatus.Status = STATUS_SUCCESS;
-  Irp->IoStatus.Information = 0;
+  DPRINT("ScsiClassDeviceDispatch() called\n");
+
+  DeviceExtension = DeviceObject->DeviceExtension;
+  if (DeviceExtension->ClassDeviceControl)
+    {
+      return(DeviceExtension->ClassDeviceControl(DeviceObject, Irp));
+    }
+
+  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
   IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-  return(STATUS_SUCCESS);
+  return(STATUS_INVALID_DEVICE_REQUEST);
 }
 
 
@@ -1158,13 +1186,20 @@ static NTSTATUS STDCALL
 ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
                       IN PIRP Irp)
 {
-  DPRINT1("ScsiClassShutdownFlush() called\n");
+  PDEVICE_EXTENSION DeviceExtension;
 
-  Irp->IoStatus.Status = STATUS_SUCCESS;
-  Irp->IoStatus.Information = 0;
+  DPRINT("ScsiClassShutdownFlush() called\n");
+
+  DeviceExtension = DeviceObject->DeviceExtension;
+  if (DeviceExtension->ClassShutdownFlush)
+    {
+      return(DeviceExtension->ClassShutdownFlush(DeviceObject, Irp));
+    }
+
+  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
   IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-  return(STATUS_SUCCESS);
+  return(STATUS_INVALID_DEVICE_REQUEST);
 }
 
 /* EOF */