static void DAC960_V2_ProcessCompletedCommand()

in drivers/block/DAC960.c [4626:5256]


static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
{
  DAC960_Controller_T *Controller = Command->Controller;
  DAC960_CommandType_T CommandType = Command->CommandType;
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
  DAC960_V2_IOCTL_Opcode_T IOCTLOpcode = CommandMailbox->Common.IOCTL_Opcode;
  DAC960_V2_CommandOpcode_T CommandOpcode = CommandMailbox->SCSI_10.CommandOpcode;
  DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus;

  if (CommandType == DAC960_ReadCommand ||
      CommandType == DAC960_WriteCommand)
    {

#ifdef FORCE_RETRY_DEBUG
      CommandStatus = DAC960_V2_AbormalCompletion;
#endif
      Command->V2.RequestSense->SenseKey = DAC960_SenseKey_MediumError;

      if (CommandStatus == DAC960_V2_NormalCompletion) {

		if (!DAC960_ProcessCompletedRequest(Command, true))
			BUG();

      } else if (Command->V2.RequestSense->SenseKey == DAC960_SenseKey_MediumError)
	{
	  /*
	   * break the command down into pieces and resubmit each
	   * piece, hoping that some of them will succeed.
	   */
	   DAC960_queue_partial_rw(Command);
	   return;
	}
      else
	{
	  if (Command->V2.RequestSense->SenseKey != DAC960_SenseKey_NotReady)
	    DAC960_V2_ReadWriteError(Command);
	  /*
	    Perform completion processing for all buffers in this I/O Request.
	  */
          (void)DAC960_ProcessCompletedRequest(Command, false);
	}
    }
  else if (CommandType == DAC960_ReadRetryCommand ||
	   CommandType == DAC960_WriteRetryCommand)
    {
      bool normal_completion;

#ifdef FORCE_RETRY_FAILURE_DEBUG
      static int retry_count = 1;
#endif
      /*
        Perform completion processing for the portion that was
	retried, and submit the next portion, if any.
      */
      normal_completion = true;
      if (CommandStatus != DAC960_V2_NormalCompletion) {
	normal_completion = false;
	if (Command->V2.RequestSense->SenseKey != DAC960_SenseKey_NotReady)
	    DAC960_V2_ReadWriteError(Command);
      }

#ifdef FORCE_RETRY_FAILURE_DEBUG
      if (!(++retry_count % 10000)) {
	      printk("V2 error retry failure test\n");
	      normal_completion = false;
	      DAC960_V2_ReadWriteError(Command);
      }
#endif

      if (!DAC960_ProcessCompletedRequest(Command, normal_completion)) {
		DAC960_queue_partial_rw(Command);
        	return;
      }
    }
  else if (CommandType == DAC960_MonitoringCommand)
    {
      if (Controller->ShutdownMonitoringTimer)
	      return;
      if (IOCTLOpcode == DAC960_V2_GetControllerInfo)
	{
	  DAC960_V2_ControllerInfo_T *NewControllerInfo =
	    Controller->V2.NewControllerInformation;
	  DAC960_V2_ControllerInfo_T *ControllerInfo =
	    &Controller->V2.ControllerInformation;
	  Controller->LogicalDriveCount =
	    NewControllerInfo->LogicalDevicesPresent;
	  Controller->V2.NeedLogicalDeviceInformation = true;
	  Controller->V2.NeedPhysicalDeviceInformation = true;
	  Controller->V2.StartLogicalDeviceInformationScan = true;
	  Controller->V2.StartPhysicalDeviceInformationScan = true;
	  Controller->MonitoringAlertMode =
	    (NewControllerInfo->LogicalDevicesCritical > 0 ||
	     NewControllerInfo->LogicalDevicesOffline > 0 ||
	     NewControllerInfo->PhysicalDisksCritical > 0 ||
	     NewControllerInfo->PhysicalDisksOffline > 0);
	  memcpy(ControllerInfo, NewControllerInfo,
		 sizeof(DAC960_V2_ControllerInfo_T));
	}
      else if (IOCTLOpcode == DAC960_V2_GetEvent)
	{
	  if (CommandStatus == DAC960_V2_NormalCompletion) {
	    DAC960_V2_ReportEvent(Controller, Controller->V2.Event);
	  }
	  Controller->V2.NextEventSequenceNumber++;
	}
      else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
	       CommandStatus == DAC960_V2_NormalCompletion)
	{
	  DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
	    Controller->V2.NewPhysicalDeviceInformation;
	  unsigned int PhysicalDeviceIndex = Controller->V2.PhysicalDeviceIndex;
	  DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
	    Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
	  DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
	    Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
	  unsigned int DeviceIndex;
	  while (PhysicalDeviceInfo != NULL &&
		 (NewPhysicalDeviceInfo->Channel >
		  PhysicalDeviceInfo->Channel ||
		  (NewPhysicalDeviceInfo->Channel ==
		   PhysicalDeviceInfo->Channel &&
		   (NewPhysicalDeviceInfo->TargetID >
		    PhysicalDeviceInfo->TargetID ||
		   (NewPhysicalDeviceInfo->TargetID ==
		    PhysicalDeviceInfo->TargetID &&
		    NewPhysicalDeviceInfo->LogicalUnit >
		    PhysicalDeviceInfo->LogicalUnit)))))
	    {
	      DAC960_Critical("Physical Device %d:%d No Longer Exists\n",
			      Controller,
			      PhysicalDeviceInfo->Channel,
			      PhysicalDeviceInfo->TargetID);
	      Controller->V2.PhysicalDeviceInformation
			     [PhysicalDeviceIndex] = NULL;
	      Controller->V2.InquiryUnitSerialNumber
			     [PhysicalDeviceIndex] = NULL;
	      kfree(PhysicalDeviceInfo);
	      kfree(InquiryUnitSerialNumber);
	      for (DeviceIndex = PhysicalDeviceIndex;
		   DeviceIndex < DAC960_V2_MaxPhysicalDevices - 1;
		   DeviceIndex++)
		{
		  Controller->V2.PhysicalDeviceInformation[DeviceIndex] =
		    Controller->V2.PhysicalDeviceInformation[DeviceIndex+1];
		  Controller->V2.InquiryUnitSerialNumber[DeviceIndex] =
		    Controller->V2.InquiryUnitSerialNumber[DeviceIndex+1];
		}
	      Controller->V2.PhysicalDeviceInformation
			     [DAC960_V2_MaxPhysicalDevices-1] = NULL;
	      Controller->V2.InquiryUnitSerialNumber
			     [DAC960_V2_MaxPhysicalDevices-1] = NULL;
	      PhysicalDeviceInfo =
		Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
	      InquiryUnitSerialNumber =
		Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
	    }
	  if (PhysicalDeviceInfo == NULL ||
	      (NewPhysicalDeviceInfo->Channel !=
	       PhysicalDeviceInfo->Channel) ||
	      (NewPhysicalDeviceInfo->TargetID !=
	       PhysicalDeviceInfo->TargetID) ||
	      (NewPhysicalDeviceInfo->LogicalUnit !=
	       PhysicalDeviceInfo->LogicalUnit))
	    {
	      PhysicalDeviceInfo =
		kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
	      InquiryUnitSerialNumber =
		  kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
			  GFP_ATOMIC);
	      if (InquiryUnitSerialNumber == NULL ||
		  PhysicalDeviceInfo == NULL)
		{
		  kfree(InquiryUnitSerialNumber);
		  InquiryUnitSerialNumber = NULL;
		  kfree(PhysicalDeviceInfo);
		  PhysicalDeviceInfo = NULL;
		}
	      DAC960_Critical("Physical Device %d:%d Now Exists%s\n",
			      Controller,
			      NewPhysicalDeviceInfo->Channel,
			      NewPhysicalDeviceInfo->TargetID,
			      (PhysicalDeviceInfo != NULL
			       ? "" : " - Allocation Failed"));
	      if (PhysicalDeviceInfo != NULL)
		{
		  memset(PhysicalDeviceInfo, 0,
			 sizeof(DAC960_V2_PhysicalDeviceInfo_T));
		  PhysicalDeviceInfo->PhysicalDeviceState =
		    DAC960_V2_Device_InvalidState;
		  memset(InquiryUnitSerialNumber, 0,
			 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
		  InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
		  for (DeviceIndex = DAC960_V2_MaxPhysicalDevices - 1;
		       DeviceIndex > PhysicalDeviceIndex;
		       DeviceIndex--)
		    {
		      Controller->V2.PhysicalDeviceInformation[DeviceIndex] =
			Controller->V2.PhysicalDeviceInformation[DeviceIndex-1];
		      Controller->V2.InquiryUnitSerialNumber[DeviceIndex] =
			Controller->V2.InquiryUnitSerialNumber[DeviceIndex-1];
		    }
		  Controller->V2.PhysicalDeviceInformation
				 [PhysicalDeviceIndex] =
		    PhysicalDeviceInfo;
		  Controller->V2.InquiryUnitSerialNumber
				 [PhysicalDeviceIndex] =
		    InquiryUnitSerialNumber;
		  Controller->V2.NeedDeviceSerialNumberInformation = true;
		}
	    }
	  if (PhysicalDeviceInfo != NULL)
	    {
	      if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
		  PhysicalDeviceInfo->PhysicalDeviceState)
		DAC960_Critical(
		  "Physical Device %d:%d is now %s\n", Controller,
		  NewPhysicalDeviceInfo->Channel,
		  NewPhysicalDeviceInfo->TargetID,
		  (NewPhysicalDeviceInfo->PhysicalDeviceState
		   == DAC960_V2_Device_Online
		   ? "ONLINE"
		   : NewPhysicalDeviceInfo->PhysicalDeviceState
		     == DAC960_V2_Device_Rebuild
		     ? "REBUILD"
		     : NewPhysicalDeviceInfo->PhysicalDeviceState
		       == DAC960_V2_Device_Missing
		       ? "MISSING"
		       : NewPhysicalDeviceInfo->PhysicalDeviceState
			 == DAC960_V2_Device_Critical
			 ? "CRITICAL"
			 : NewPhysicalDeviceInfo->PhysicalDeviceState
			   == DAC960_V2_Device_Dead
			   ? "DEAD"
			   : NewPhysicalDeviceInfo->PhysicalDeviceState
			     == DAC960_V2_Device_SuspectedDead
			     ? "SUSPECTED-DEAD"
			     : NewPhysicalDeviceInfo->PhysicalDeviceState
			       == DAC960_V2_Device_CommandedOffline
			       ? "COMMANDED-OFFLINE"
			       : NewPhysicalDeviceInfo->PhysicalDeviceState
				 == DAC960_V2_Device_Standby
				 ? "STANDBY" : "UNKNOWN"));
	      if ((NewPhysicalDeviceInfo->ParityErrors !=
		   PhysicalDeviceInfo->ParityErrors) ||
		  (NewPhysicalDeviceInfo->SoftErrors !=
		   PhysicalDeviceInfo->SoftErrors) ||
		  (NewPhysicalDeviceInfo->HardErrors !=
		   PhysicalDeviceInfo->HardErrors) ||
		  (NewPhysicalDeviceInfo->MiscellaneousErrors !=
		   PhysicalDeviceInfo->MiscellaneousErrors) ||
		  (NewPhysicalDeviceInfo->CommandTimeouts !=
		   PhysicalDeviceInfo->CommandTimeouts) ||
		  (NewPhysicalDeviceInfo->Retries !=
		   PhysicalDeviceInfo->Retries) ||
		  (NewPhysicalDeviceInfo->Aborts !=
		   PhysicalDeviceInfo->Aborts) ||
		  (NewPhysicalDeviceInfo->PredictedFailuresDetected !=
		   PhysicalDeviceInfo->PredictedFailuresDetected))
		{
		  DAC960_Critical("Physical Device %d:%d Errors: "
				  "Parity = %d, Soft = %d, "
				  "Hard = %d, Misc = %d\n",
				  Controller,
				  NewPhysicalDeviceInfo->Channel,
				  NewPhysicalDeviceInfo->TargetID,
				  NewPhysicalDeviceInfo->ParityErrors,
				  NewPhysicalDeviceInfo->SoftErrors,
				  NewPhysicalDeviceInfo->HardErrors,
				  NewPhysicalDeviceInfo->MiscellaneousErrors);
		  DAC960_Critical("Physical Device %d:%d Errors: "
				  "Timeouts = %d, Retries = %d, "
				  "Aborts = %d, Predicted = %d\n",
				  Controller,
				  NewPhysicalDeviceInfo->Channel,
				  NewPhysicalDeviceInfo->TargetID,
				  NewPhysicalDeviceInfo->CommandTimeouts,
				  NewPhysicalDeviceInfo->Retries,
				  NewPhysicalDeviceInfo->Aborts,
				  NewPhysicalDeviceInfo
				  ->PredictedFailuresDetected);
		}
	      if ((PhysicalDeviceInfo->PhysicalDeviceState
		   == DAC960_V2_Device_Dead ||
		   PhysicalDeviceInfo->PhysicalDeviceState
		   == DAC960_V2_Device_InvalidState) &&
		  NewPhysicalDeviceInfo->PhysicalDeviceState
		  != DAC960_V2_Device_Dead)
		Controller->V2.NeedDeviceSerialNumberInformation = true;
	      memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
		     sizeof(DAC960_V2_PhysicalDeviceInfo_T));
	    }
	  NewPhysicalDeviceInfo->LogicalUnit++;
	  Controller->V2.PhysicalDeviceIndex++;
	}
      else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
	{
	  unsigned int DeviceIndex;
	  for (DeviceIndex = Controller->V2.PhysicalDeviceIndex;
	       DeviceIndex < DAC960_V2_MaxPhysicalDevices;
	       DeviceIndex++)
	    {
	      DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
		Controller->V2.PhysicalDeviceInformation[DeviceIndex];
	      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
		Controller->V2.InquiryUnitSerialNumber[DeviceIndex];
	      if (PhysicalDeviceInfo == NULL) break;
	      DAC960_Critical("Physical Device %d:%d No Longer Exists\n",
			      Controller,
			      PhysicalDeviceInfo->Channel,
			      PhysicalDeviceInfo->TargetID);
	      Controller->V2.PhysicalDeviceInformation[DeviceIndex] = NULL;
	      Controller->V2.InquiryUnitSerialNumber[DeviceIndex] = NULL;
	      kfree(PhysicalDeviceInfo);
	      kfree(InquiryUnitSerialNumber);
	    }
	  Controller->V2.NeedPhysicalDeviceInformation = false;
	}
      else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
	       CommandStatus == DAC960_V2_NormalCompletion)
	{
	  DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
	    Controller->V2.NewLogicalDeviceInformation;
	  unsigned short LogicalDeviceNumber =
	    NewLogicalDeviceInfo->LogicalDeviceNumber;
	  DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
	    Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber];
	  if (LogicalDeviceInfo == NULL)
	    {
	      DAC960_V2_PhysicalDevice_T PhysicalDevice;
	      PhysicalDevice.Controller = 0;
	      PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
	      PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
	      PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
	      Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
		PhysicalDevice;
	      LogicalDeviceInfo = kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T),
					  GFP_ATOMIC);
	      Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
		LogicalDeviceInfo;
	      DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
			      "Now Exists%s\n", Controller,
			      LogicalDeviceNumber,
			      Controller->ControllerNumber,
			      LogicalDeviceNumber,
			      (LogicalDeviceInfo != NULL
			       ? "" : " - Allocation Failed"));
	      if (LogicalDeviceInfo != NULL)
		{
		  memset(LogicalDeviceInfo, 0,
			 sizeof(DAC960_V2_LogicalDeviceInfo_T));
		  DAC960_ComputeGenericDiskInfo(Controller);
		}
	    }
	  if (LogicalDeviceInfo != NULL)
	    {
	      unsigned long LogicalDeviceSize =
		NewLogicalDeviceInfo->ConfigurableDeviceSize;
	      if (NewLogicalDeviceInfo->LogicalDeviceState !=
		  LogicalDeviceInfo->LogicalDeviceState)
		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
				"is now %s\n", Controller,
				LogicalDeviceNumber,
				Controller->ControllerNumber,
				LogicalDeviceNumber,
				(NewLogicalDeviceInfo->LogicalDeviceState
				 == DAC960_V2_LogicalDevice_Online
				 ? "ONLINE"
				 : NewLogicalDeviceInfo->LogicalDeviceState
				   == DAC960_V2_LogicalDevice_Critical
				   ? "CRITICAL" : "OFFLINE"));
	      if ((NewLogicalDeviceInfo->SoftErrors !=
		   LogicalDeviceInfo->SoftErrors) ||
		  (NewLogicalDeviceInfo->CommandsFailed !=
		   LogicalDeviceInfo->CommandsFailed) ||
		  (NewLogicalDeviceInfo->DeferredWriteErrors !=
		   LogicalDeviceInfo->DeferredWriteErrors))
		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) Errors: "
				"Soft = %d, Failed = %d, Deferred Write = %d\n",
				Controller, LogicalDeviceNumber,
				Controller->ControllerNumber,
				LogicalDeviceNumber,
				NewLogicalDeviceInfo->SoftErrors,
				NewLogicalDeviceInfo->CommandsFailed,
				NewLogicalDeviceInfo->DeferredWriteErrors);
	      if (NewLogicalDeviceInfo->ConsistencyCheckInProgress)
		DAC960_V2_ReportProgress(Controller,
					 "Consistency Check",
					 LogicalDeviceNumber,
					 NewLogicalDeviceInfo
					 ->ConsistencyCheckBlockNumber,
					 LogicalDeviceSize);
	      else if (NewLogicalDeviceInfo->RebuildInProgress)
		DAC960_V2_ReportProgress(Controller,
					 "Rebuild",
					 LogicalDeviceNumber,
					 NewLogicalDeviceInfo
					 ->RebuildBlockNumber,
					 LogicalDeviceSize);
	      else if (NewLogicalDeviceInfo->BackgroundInitializationInProgress)
		DAC960_V2_ReportProgress(Controller,
					 "Background Initialization",
					 LogicalDeviceNumber,
					 NewLogicalDeviceInfo
					 ->BackgroundInitializationBlockNumber,
					 LogicalDeviceSize);
	      else if (NewLogicalDeviceInfo->ForegroundInitializationInProgress)
		DAC960_V2_ReportProgress(Controller,
					 "Foreground Initialization",
					 LogicalDeviceNumber,
					 NewLogicalDeviceInfo
					 ->ForegroundInitializationBlockNumber,
					 LogicalDeviceSize);
	      else if (NewLogicalDeviceInfo->DataMigrationInProgress)
		DAC960_V2_ReportProgress(Controller,
					 "Data Migration",
					 LogicalDeviceNumber,
					 NewLogicalDeviceInfo
					 ->DataMigrationBlockNumber,
					 LogicalDeviceSize);
	      else if (NewLogicalDeviceInfo->PatrolOperationInProgress)
		DAC960_V2_ReportProgress(Controller,
					 "Patrol Operation",
					 LogicalDeviceNumber,
					 NewLogicalDeviceInfo
					 ->PatrolOperationBlockNumber,
					 LogicalDeviceSize);
	      if (LogicalDeviceInfo->BackgroundInitializationInProgress &&
		  !NewLogicalDeviceInfo->BackgroundInitializationInProgress)
		DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) "
				"Background Initialization %s\n",
				Controller,
				LogicalDeviceNumber,
				Controller->ControllerNumber,
				LogicalDeviceNumber,
				(NewLogicalDeviceInfo->LogicalDeviceControl
						      .LogicalDeviceInitialized
				 ? "Completed" : "Failed"));
	      memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
		     sizeof(DAC960_V2_LogicalDeviceInfo_T));
	    }
	  Controller->V2.LogicalDriveFoundDuringScan
			 [LogicalDeviceNumber] = true;
	  NewLogicalDeviceInfo->LogicalDeviceNumber++;
	}
      else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
	{
	  int LogicalDriveNumber;
	  for (LogicalDriveNumber = 0;
	       LogicalDriveNumber < DAC960_MaxLogicalDrives;
	       LogicalDriveNumber++)
	    {
	      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
		Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
	      if (LogicalDeviceInfo == NULL ||
		  Controller->V2.LogicalDriveFoundDuringScan
				 [LogicalDriveNumber])
		continue;
	      DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
			      "No Longer Exists\n", Controller,
			      LogicalDriveNumber,
			      Controller->ControllerNumber,
			      LogicalDriveNumber);
	      Controller->V2.LogicalDeviceInformation
			     [LogicalDriveNumber] = NULL;
	      kfree(LogicalDeviceInfo);
	      Controller->LogicalDriveInitiallyAccessible
			  [LogicalDriveNumber] = false;
	      DAC960_ComputeGenericDiskInfo(Controller);
	    }
	  Controller->V2.NeedLogicalDeviceInformation = false;
	}
      else if (CommandOpcode == DAC960_V2_SCSI_10_Passthru)
        {
	    DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
		Controller->V2.InquiryUnitSerialNumber[Controller->V2.PhysicalDeviceIndex - 1];

	    if (CommandStatus != DAC960_V2_NormalCompletion) {
		memset(InquiryUnitSerialNumber,
			0, sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
		InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
	    } else
	  	memcpy(InquiryUnitSerialNumber,
			Controller->V2.NewInquiryUnitSerialNumber,
			sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));

	     Controller->V2.NeedDeviceSerialNumberInformation = false;
        }

      if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
	  - Controller->V2.NextEventSequenceNumber > 0)
	{
	  CommandMailbox->GetEvent.CommandOpcode = DAC960_V2_IOCTL;
	  CommandMailbox->GetEvent.DataTransferSize = sizeof(DAC960_V2_Event_T);
	  CommandMailbox->GetEvent.EventSequenceNumberHigh16 =
	    Controller->V2.NextEventSequenceNumber >> 16;
	  CommandMailbox->GetEvent.ControllerNumber = 0;
	  CommandMailbox->GetEvent.IOCTL_Opcode =
	    DAC960_V2_GetEvent;
	  CommandMailbox->GetEvent.EventSequenceNumberLow16 =
	    Controller->V2.NextEventSequenceNumber & 0xFFFF;
	  CommandMailbox->GetEvent.DataTransferMemoryAddress
				  .ScatterGatherSegments[0]
				  .SegmentDataPointer =
	    Controller->V2.EventDMA;
	  CommandMailbox->GetEvent.DataTransferMemoryAddress
				  .ScatterGatherSegments[0]
				  .SegmentByteCount =
	    CommandMailbox->GetEvent.DataTransferSize;
	  DAC960_QueueCommand(Command);
	  return;
	}
      if (Controller->V2.NeedPhysicalDeviceInformation)
	{
	  if (Controller->V2.NeedDeviceSerialNumberInformation)
	    {
	      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
                Controller->V2.NewInquiryUnitSerialNumber;
	      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;

	      DAC960_V2_ConstructNewUnitSerialNumber(Controller, CommandMailbox,
			Controller->V2.NewPhysicalDeviceInformation->Channel,
			Controller->V2.NewPhysicalDeviceInformation->TargetID,
		Controller->V2.NewPhysicalDeviceInformation->LogicalUnit - 1);


	      DAC960_QueueCommand(Command);
	      return;
	    }
	  if (Controller->V2.StartPhysicalDeviceInformationScan)
	    {
	      Controller->V2.PhysicalDeviceIndex = 0;
	      Controller->V2.NewPhysicalDeviceInformation->Channel = 0;
	      Controller->V2.NewPhysicalDeviceInformation->TargetID = 0;
	      Controller->V2.NewPhysicalDeviceInformation->LogicalUnit = 0;
	      Controller->V2.StartPhysicalDeviceInformationScan = false;
	    }
	  CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
	  CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
	    sizeof(DAC960_V2_PhysicalDeviceInfo_T);
	  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit =
	    Controller->V2.NewPhysicalDeviceInformation->LogicalUnit;
	  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID =
	    Controller->V2.NewPhysicalDeviceInformation->TargetID;
	  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel =
	    Controller->V2.NewPhysicalDeviceInformation->Channel;
	  CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
	    DAC960_V2_GetPhysicalDeviceInfoValid;
	  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
					    .ScatterGatherSegments[0]
					    .SegmentDataPointer =
	    Controller->V2.NewPhysicalDeviceInformationDMA;
	  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
					    .ScatterGatherSegments[0]
					    .SegmentByteCount =
	    CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
	  DAC960_QueueCommand(Command);
	  return;
	}
      if (Controller->V2.NeedLogicalDeviceInformation)
	{
	  if (Controller->V2.StartLogicalDeviceInformationScan)
	    {
	      int LogicalDriveNumber;
	      for (LogicalDriveNumber = 0;
		   LogicalDriveNumber < DAC960_MaxLogicalDrives;
		   LogicalDriveNumber++)
		Controller->V2.LogicalDriveFoundDuringScan
			       [LogicalDriveNumber] = false;
	      Controller->V2.NewLogicalDeviceInformation->LogicalDeviceNumber = 0;
	      Controller->V2.StartLogicalDeviceInformationScan = false;
	    }
	  CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
	  CommandMailbox->LogicalDeviceInfo.DataTransferSize =
	    sizeof(DAC960_V2_LogicalDeviceInfo_T);
	  CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
	    Controller->V2.NewLogicalDeviceInformation->LogicalDeviceNumber;
	  CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
	    DAC960_V2_GetLogicalDeviceInfoValid;
	  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
					   .ScatterGatherSegments[0]
					   .SegmentDataPointer =
	    Controller->V2.NewLogicalDeviceInformationDMA;
	  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
					   .ScatterGatherSegments[0]
					   .SegmentByteCount =
	    CommandMailbox->LogicalDeviceInfo.DataTransferSize;
	  DAC960_QueueCommand(Command);
	  return;
	}
      Controller->MonitoringTimerCount++;
      Controller->MonitoringTimer.expires =
	jiffies + DAC960_HealthStatusMonitoringInterval;
      	add_timer(&Controller->MonitoringTimer);
    }
  if (CommandType == DAC960_ImmediateCommand)
    {
      complete(Command->Completion);
      Command->Completion = NULL;
      return;
    }
  if (CommandType == DAC960_QueuedCommand)
    {
      DAC960_V2_KernelCommand_T *KernelCommand = Command->V2.KernelCommand;
      KernelCommand->CommandStatus = CommandStatus;
      KernelCommand->RequestSenseLength = Command->V2.RequestSenseLength;
      KernelCommand->DataTransferLength = Command->V2.DataTransferResidue;
      Command->V2.KernelCommand = NULL;
      DAC960_DeallocateCommand(Command);
      KernelCommand->CompletionFunction(KernelCommand);
      return;
    }
  /*
    Queue a Status Monitoring Command to the Controller using the just
    completed Command if one was deferred previously due to lack of a
    free Command when the Monitoring Timer Function was called.
  */
  if (Controller->MonitoringCommandDeferred)
    {
      Controller->MonitoringCommandDeferred = false;
      DAC960_V2_QueueMonitoringCommand(Command);
      return;
    }
  /*
    Deallocate the Command.
  */
  DAC960_DeallocateCommand(Command);
  /*
    Wake up any processes waiting on a free Command.
  */
  wake_up(&Controller->CommandWaitQueue);
}