Enscript Output

extractedLnx/linux/drivers/block/DAC960.c_DAC960_ProcessCompletedCommand.c

static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
{
  DAC960_Controller_T *Controller = Command->Controller;
  DAC960_CommandType_T CommandType = Command->CommandType;
  DAC960_CommandOpcode_T CommandOpcode =
    Command->CommandMailbox.Common.CommandOpcode;
  DAC960_CommandStatus_T CommandStatus = Command->CommandStatus;
  BufferHeader_T *BufferHeader = Command->BufferHeader;
  if (CommandType == DAC960_ReadCommand ||
      CommandType == DAC960_WriteCommand)
    {
      if (CommandStatus == DAC960_NormalCompletion)
	{
	  /*
	    Perform completion processing for all buffers in this I/O Request.
	  */
	  while (BufferHeader != NULL)
	    {
	      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
	      BufferHeader->b_reqnext = NULL;
	      DAC960_ProcessCompletedBuffer(BufferHeader, true);
	      BufferHeader = NextBufferHeader;
	    }
	  /*
	    Wake up requestor for swap file paging requests.
	  */
	  if (Command->Semaphore != NULL)
	    {
	      up(Command->Semaphore);
	      Command->Semaphore = NULL;
	    }
	  add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
	}
      else if ((CommandStatus == DAC960_IrrecoverableDataError ||
		CommandStatus == DAC960_BadDataEncountered) &&
	       BufferHeader != NULL &&
	       BufferHeader->b_reqnext != NULL)
	{
	  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
	  if (CommandType == DAC960_ReadCommand)
	    {
	      Command->CommandType = DAC960_ReadRetryCommand;
	      CommandMailbox->Type5.CommandOpcode = DAC960_Read;
	    }
	  else
	    {
	      Command->CommandType = DAC960_WriteRetryCommand;
	      CommandMailbox->Type5.CommandOpcode = DAC960_Write;
	    }
	  Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
	  CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
	  CommandMailbox->Type5.BusAddress =
	    Virtual_to_Bus(BufferHeader->b_data);
	  DAC960_QueueCommand(Command);
	  return;
	}
      else
	{
	  if (CommandStatus != DAC960_LogicalDriveNonexistentOrOffline)
	    DAC960_ReadWriteError(Command);
	  /*
	    Perform completion processing for all buffers in this I/O Request.
	  */
	  while (BufferHeader != NULL)
	    {
	      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
	      BufferHeader->b_reqnext = NULL;
	      DAC960_ProcessCompletedBuffer(BufferHeader, false);
	      BufferHeader = NextBufferHeader;
	    }
	  /*
	    Wake up requestor for swap file paging requests.
	  */
	  if (Command->Semaphore != NULL)
	    {
	      up(Command->Semaphore);
	      Command->Semaphore = NULL;
	    }
	}
    }
  else if (CommandType == DAC960_ReadRetryCommand ||
	   CommandType == DAC960_WriteRetryCommand)
    {
      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
      BufferHeader->b_reqnext = NULL;
      /*
	Perform completion processing for this single buffer.
      */
      if (CommandStatus == DAC960_NormalCompletion)
	DAC960_ProcessCompletedBuffer(BufferHeader, true);
      else
	{
	  if (CommandStatus != DAC960_LogicalDriveNonexistentOrOffline)
	    DAC960_ReadWriteError(Command);
	  DAC960_ProcessCompletedBuffer(BufferHeader, false);
	}
      if (NextBufferHeader != NULL)
	{
	  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
	  Command->BlockNumber +=
	    BufferHeader->b_size >> DAC960_BlockSizeBits;
	  Command->BlockCount =
	    NextBufferHeader->b_size >> DAC960_BlockSizeBits;
	  Command->BufferHeader = NextBufferHeader;
	  CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
	  CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
	  CommandMailbox->Type5.BusAddress =
	    Virtual_to_Bus(NextBufferHeader->b_data);
	  DAC960_QueueCommand(Command);
	  return;
	}
    }
  else if (CommandType == DAC960_MonitoringCommand ||
	   CommandOpcode == DAC960_Enquiry ||
	   CommandOpcode == DAC960_GetRebuildProgress)
    {
      if (CommandType != DAC960_MonitoringCommand)
	{
	  if (CommandOpcode == DAC960_Enquiry)
	    memcpy(&Controller->Enquiry[Controller->EnquiryIndex ^ 1],
		   Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress),
		   sizeof(DAC960_Enquiry_T));
	  else if (CommandOpcode == DAC960_GetRebuildProgress)
	    memcpy(&Controller->RebuildProgress,
		   Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress),
		   sizeof(DAC960_RebuildProgress_T));
	}
      if (CommandOpcode == DAC960_Enquiry)
	{
	  DAC960_Enquiry_T *OldEnquiry =
	    &Controller->Enquiry[Controller->EnquiryIndex];
	  DAC960_Enquiry_T *NewEnquiry =
	    &Controller->Enquiry[Controller->EnquiryIndex ^= 1];
	  unsigned int OldCriticalLogicalDriveCount =
	    OldEnquiry->CriticalLogicalDriveCount;
	  unsigned int NewCriticalLogicalDriveCount =
	    NewEnquiry->CriticalLogicalDriveCount;
	  if (NewEnquiry->StatusFlags.DeferredWriteError !=
	      OldEnquiry->StatusFlags.DeferredWriteError)
	    DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
			    (NewEnquiry->StatusFlags.DeferredWriteError
			     ? "TRUE" : "FALSE"));
	  if ((NewCriticalLogicalDriveCount > 0 ||
	       NewCriticalLogicalDriveCount != OldCriticalLogicalDriveCount) ||
	      (NewEnquiry->OfflineLogicalDriveCount > 0 ||
	       NewEnquiry->OfflineLogicalDriveCount !=
	       OldEnquiry->OfflineLogicalDriveCount) ||
	      (NewEnquiry->DeadDriveCount > 0 ||
	       NewEnquiry->DeadDriveCount !=
	       OldEnquiry->DeadDriveCount) ||
	      (NewEnquiry->EventLogSequenceNumber !=
	       OldEnquiry->EventLogSequenceNumber) ||
	      Controller->MonitoringTimerCount == 0 ||
	      (jiffies - Controller->SecondaryMonitoringTime
	       >= DAC960_SecondaryMonitoringInterval))
	    {
	      Controller->NeedLogicalDriveInformation = true;
	      Controller->NewEventLogSequenceNumber =
		NewEnquiry->EventLogSequenceNumber;
	      Controller->NeedErrorTableInformation = true;
	      Controller->NeedDeviceStateInformation = true;
	      Controller->DeviceStateChannel = 0;
	      Controller->DeviceStateTargetID = -1;
	      Controller->SecondaryMonitoringTime = jiffies;
	    }
	  if (NewEnquiry->RebuildFlag == DAC960_StandbyRebuildInProgress ||
	      NewEnquiry->RebuildFlag == DAC960_BackgroundRebuildInProgress ||
	      OldEnquiry->RebuildFlag == DAC960_StandbyRebuildInProgress ||
	      OldEnquiry->RebuildFlag == DAC960_BackgroundRebuildInProgress)
	    Controller->NeedRebuildProgress = true;
	  if (OldEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
	    switch (NewEnquiry->RebuildFlag)
	      {
	      case DAC960_NoStandbyRebuildOrCheckInProgress:
		DAC960_Progress("Consistency Check Completed Successfully\n",
				Controller);
		break;
	      case DAC960_StandbyRebuildInProgress:
	      case DAC960_BackgroundRebuildInProgress:
		break;
	      case DAC960_BackgroundCheckInProgress:
		Controller->NeedConsistencyCheckProgress = true;
		break;
	      case DAC960_StandbyRebuildCompletedWithError:
		DAC960_Progress("Consistency Check Completed with Error\n",
				Controller);
		break;
	      case DAC960_BackgroundRebuildOrCheckFailed_DriveFailed:
		DAC960_Progress("Consistency Check Failed - "
				"Physical Drive Failed\n", Controller);
		break;
	      case DAC960_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
		DAC960_Progress("Consistency Check Failed - "
				"Logical Drive Failed\n", Controller);
		break;
	      case DAC960_BackgroundRebuildOrCheckFailed_OtherCauses:
		DAC960_Progress("Consistency Check Failed - Other Causes\n",
				Controller);
		break;
	      case DAC960_BackgroundRebuildOrCheckSuccessfullyTerminated:
		DAC960_Progress("Consistency Check Successfully Terminated\n",
				Controller);
		break;
	      }
	  else if (NewEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
	    Controller->NeedConsistencyCheckProgress = true;
	  if (CommandType != DAC960_MonitoringCommand &&
	      Controller->RebuildFlagPending)
	    {
	      DAC960_Enquiry_T *Enquiry = (DAC960_Enquiry_T *)
		Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress);
	      Enquiry->RebuildFlag = Controller->PendingRebuildFlag;
	      Controller->RebuildFlagPending = false;
	    }
	  else if (CommandType == DAC960_MonitoringCommand &&
		   NewEnquiry->RebuildFlag > DAC960_BackgroundCheckInProgress)
	    {
	      Controller->PendingRebuildFlag = NewEnquiry->RebuildFlag;
	      Controller->RebuildFlagPending = true;
	    }
	}
      else if (CommandOpcode == DAC960_PerformEventLogOperation)
	{
	  static char
	    *DAC960_EventMessages[] =
	       { "killed because write recovery failed",
		 "killed because of SCSI bus reset failure",
		 "killed because of double check condition",
		 "killed because it was removed",
		 "killed because of gross error on SCSI chip",
		 "killed because of bad tag returned from drive",
		 "killed because of timeout on SCSI command",
		 "killed because of reset SCSI command issued from system",
		 "killed because busy or parity error count exceeded limit",
		 "killed because of 'kill drive' command from system",
		 "killed because of selection timeout",
		 "killed due to SCSI phase sequence error",
		 "killed due to unknown status" };
	  DAC960_EventLogEntry_T *EventLogEntry = &Controller->EventLogEntry;
	  if (EventLogEntry->SequenceNumber ==
	      Controller->OldEventLogSequenceNumber)
	    {
	      unsigned char SenseKey = EventLogEntry->SenseKey;
	      unsigned char AdditionalSenseCode =
		EventLogEntry->AdditionalSenseCode;
	      unsigned char AdditionalSenseCodeQualifier =
		EventLogEntry->AdditionalSenseCodeQualifier;
	      if (SenseKey == 9 &&
		  AdditionalSenseCode == 0x80 &&
		  AdditionalSenseCodeQualifier <
		  sizeof(DAC960_EventMessages) / sizeof(char *))
		DAC960_Critical("Physical Drive %d:%d %s\n", Controller,
				EventLogEntry->Channel,
				EventLogEntry->TargetID,
				DAC960_EventMessages[
				  AdditionalSenseCodeQualifier]);
	      else if (SenseKey == 6 && AdditionalSenseCode == 0x29)
		{
		  if (Controller->MonitoringTimerCount > 0)
		    Controller->DeviceResetCount[EventLogEntry->Channel]
						[EventLogEntry->TargetID]++;
		}
	      else if (!(SenseKey == 0 ||
			 (SenseKey == 2 &&
			  AdditionalSenseCode == 0x04 &&
			  (AdditionalSenseCodeQualifier == 0x01 ||
			   AdditionalSenseCodeQualifier == 0x02))))
		{
		  DAC960_Critical("Physical Drive %d:%d Error Log: "
				  "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
				  Controller,
				  EventLogEntry->Channel,
				  EventLogEntry->TargetID,
				  SenseKey,
				  AdditionalSenseCode,
				  AdditionalSenseCodeQualifier);
		  DAC960_Critical("Physical Drive %d:%d Error Log: "
				  "Information = %02X%02X%02X%02X "
				  "%02X%02X%02X%02X\n",
				  Controller,
				  EventLogEntry->Channel,
				  EventLogEntry->TargetID,
				  EventLogEntry->Information[0],
				  EventLogEntry->Information[1],
				  EventLogEntry->Information[2],
				  EventLogEntry->Information[3],
				  EventLogEntry->CommandSpecificInformation[0],
				  EventLogEntry->CommandSpecificInformation[1],
				  EventLogEntry->CommandSpecificInformation[2],
				  EventLogEntry->CommandSpecificInformation[3]);
		}
	    }
	  Controller->OldEventLogSequenceNumber++;
	}
      else if (CommandOpcode == DAC960_GetErrorTable)
	{
	  DAC960_ErrorTable_T *OldErrorTable =
	    &Controller->ErrorTable[Controller->ErrorTableIndex];
	  DAC960_ErrorTable_T *NewErrorTable =
	    &Controller->ErrorTable[Controller->ErrorTableIndex ^= 1];
	  int Channel, TargetID;
	  for (Channel = 0; Channel < Controller->Channels; Channel++)
	    for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
	      {
		DAC960_ErrorTableEntry_T *NewErrorEntry =
		  &NewErrorTable->ErrorTableEntries[Channel][TargetID];
		DAC960_ErrorTableEntry_T *OldErrorEntry =
		  &OldErrorTable->ErrorTableEntries[Channel][TargetID];
		if ((NewErrorEntry->ParityErrorCount !=
		     OldErrorEntry->ParityErrorCount) ||
		    (NewErrorEntry->SoftErrorCount !=
		     OldErrorEntry->SoftErrorCount) ||
		    (NewErrorEntry->HardErrorCount !=
		     OldErrorEntry->HardErrorCount) ||
		    (NewErrorEntry->MiscErrorCount !=
		     OldErrorEntry->MiscErrorCount))
		  DAC960_Critical("Physical Drive %d:%d Errors: "
				  "Parity = %d, Soft = %d, "
				  "Hard = %d, Misc = %d\n",
				  Controller, Channel, TargetID,
				  NewErrorEntry->ParityErrorCount,
				  NewErrorEntry->SoftErrorCount,
				  NewErrorEntry->HardErrorCount,
				  NewErrorEntry->MiscErrorCount);
	      }
	}
      else if (CommandOpcode == DAC960_GetDeviceState)
	{
	  DAC960_DeviceState_T *OldDeviceState =
	    &Controller->DeviceState[Controller->DeviceStateIndex]
				    [Controller->DeviceStateChannel]
				    [Controller->DeviceStateTargetID];
	  DAC960_DeviceState_T *NewDeviceState =
	    &Controller->DeviceState[Controller->DeviceStateIndex ^ 1]
				    [Controller->DeviceStateChannel]
				    [Controller->DeviceStateTargetID];
	  if (NewDeviceState->DeviceState != OldDeviceState->DeviceState)
	    DAC960_Critical("Physical Drive %d:%d is now %s\n", Controller,
			    Controller->DeviceStateChannel,
			    Controller->DeviceStateTargetID,
			    (NewDeviceState->DeviceState == DAC960_Device_Dead
			     ? "DEAD"
			     : NewDeviceState->DeviceState
			       == DAC960_Device_WriteOnly
			       ? "WRITE-ONLY"
			       : NewDeviceState->DeviceState
				 == DAC960_Device_Online
				 ? "ONLINE" : "STANDBY"));
	  if (OldDeviceState->DeviceState == DAC960_Device_Dead &&
	      NewDeviceState->DeviceState != DAC960_Device_Dead)
	    {
	      Controller->NeedDeviceInquiryInformation = true;
	      Controller->NeedDeviceSerialNumberInformation = true;
	    }
	}
      else if (CommandOpcode == DAC960_GetLogicalDriveInformation)
	{
	  int LogicalDriveNumber;
	  for (LogicalDriveNumber = 0;
	       LogicalDriveNumber < Controller->LogicalDriveCount;
	       LogicalDriveNumber++)
	    {
	      DAC960_LogicalDriveInformation_T *OldLogicalDriveInformation =
		&Controller->LogicalDriveInformation
			     [Controller->LogicalDriveInformationIndex]
			     [LogicalDriveNumber];
	      DAC960_LogicalDriveInformation_T *NewLogicalDriveInformation =
		&Controller->LogicalDriveInformation
			     [Controller->LogicalDriveInformationIndex ^ 1]
			     [LogicalDriveNumber];
	      if (NewLogicalDriveInformation->LogicalDriveState !=
		  OldLogicalDriveInformation->LogicalDriveState)
		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
				"is now %s\n", Controller,
				LogicalDriveNumber,
				Controller->ControllerNumber,
				LogicalDriveNumber,
				(NewLogicalDriveInformation->LogicalDriveState
				 == DAC960_LogicalDrive_Online
				 ? "ONLINE"
				 : NewLogicalDriveInformation->LogicalDriveState
				 == DAC960_LogicalDrive_Critical
				 ? "CRITICAL" : "OFFLINE"));
	      if (NewLogicalDriveInformation->WriteBack !=
		  OldLogicalDriveInformation->WriteBack)
		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
				"is now %s\n", Controller,
				LogicalDriveNumber,
				Controller->ControllerNumber,
				LogicalDriveNumber,
				(NewLogicalDriveInformation->WriteBack
				 ? "WRITE BACK" : "WRITE THRU"));
	    }
	  Controller->LogicalDriveInformationIndex ^= 1;
	}
      else if (CommandOpcode == DAC960_GetRebuildProgress)
	{
	  unsigned int LogicalDriveNumber =
	    Controller->RebuildProgress.LogicalDriveNumber;
	  unsigned int LogicalDriveSize =
	    Controller->RebuildProgress.LogicalDriveSize;
	  unsigned int BlocksCompleted =
	    LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
	  if (CommandStatus == DAC960_NoRebuildOrCheckInProgress &&
	      Controller->LastRebuildStatus == DAC960_NormalCompletion)
	    CommandStatus = DAC960_RebuildSuccessful;
	  switch (CommandStatus)
	    {
	    case DAC960_NormalCompletion:
	      Controller->EphemeralProgressMessage = true;
	      DAC960_Progress("Rebuild in Progress: "
			      "Logical Drive %d (/dev/rd/c%dd%d) "
			      "%d%% completed\n",
			      Controller, LogicalDriveNumber,
			      Controller->ControllerNumber,
			      LogicalDriveNumber,
			      (100 * (BlocksCompleted >> 7))
			      / (LogicalDriveSize >> 7));
	      Controller->EphemeralProgressMessage = false;
	      break;
	    case DAC960_RebuildFailed_LogicalDriveFailure:
	      DAC960_Progress("Rebuild Failed due to "
			      "Logical Drive Failure\n", Controller);
	      break;
	    case DAC960_RebuildFailed_BadBlocksOnOther:
	      DAC960_Progress("Rebuild Failed due to "
			      "Bad Blocks on Other Drives\n", Controller);
	      break;
	    case DAC960_RebuildFailed_NewDriveFailed:
	      DAC960_Progress("Rebuild Failed due to "
			      "Failure of Drive Being Rebuilt\n", Controller);
	      break;
	    case DAC960_NoRebuildOrCheckInProgress:
	      break;
	    case DAC960_RebuildSuccessful:
	      DAC960_Progress("Rebuild Completed Successfully\n", Controller);
	      break;
	    case DAC960_RebuildSuccessfullyTerminated:
	      DAC960_Progress("Rebuild Successfully Terminated\n", Controller);
	      break;
	    }
	  Controller->LastRebuildStatus = CommandStatus;
	  if (CommandType != DAC960_MonitoringCommand &&
	      Controller->RebuildStatusPending)
	    {
	      Command->CommandStatus = Controller->PendingRebuildStatus;
	      Controller->RebuildStatusPending = false;
	    }
	  else if (CommandType == DAC960_MonitoringCommand &&
		   CommandStatus != DAC960_NormalCompletion &&
		   CommandStatus != DAC960_NoRebuildOrCheckInProgress)
	    {
	      Controller->PendingRebuildStatus = CommandStatus;
	      Controller->RebuildStatusPending = true;
	    }
	}
      else if (CommandOpcode == DAC960_RebuildStat)
	{
	  unsigned int LogicalDriveNumber =
	    Controller->RebuildProgress.LogicalDriveNumber;
	  unsigned int LogicalDriveSize =
	    Controller->RebuildProgress.LogicalDriveSize;
	  unsigned int BlocksCompleted =
	    LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
	  if (CommandStatus == DAC960_NormalCompletion)
	    {
	      Controller->EphemeralProgressMessage = true;
	      DAC960_Progress("Consistency Check in Progress: "
			      "Logical Drive %d (/dev/rd/c%dd%d) "
			      "%d%% completed\n",
			      Controller, LogicalDriveNumber,
			      Controller->ControllerNumber,
			      LogicalDriveNumber,
			      (100 * (BlocksCompleted >> 7))
			      / (LogicalDriveSize >> 7));
	      Controller->EphemeralProgressMessage = false;
	    }
	}
    }
  if (CommandType == DAC960_MonitoringCommand)
    {
      if (Controller->NewEventLogSequenceNumber
	  - Controller->OldEventLogSequenceNumber > 0)
	{
	  Command->CommandMailbox.Type3E.CommandOpcode =
	    DAC960_PerformEventLogOperation;
	  Command->CommandMailbox.Type3E.OperationType =
	    DAC960_GetEventLogEntry;
	  Command->CommandMailbox.Type3E.OperationQualifier = 1;
	  Command->CommandMailbox.Type3E.SequenceNumber =
	    Controller->OldEventLogSequenceNumber;
	  Command->CommandMailbox.Type3E.BusAddress =
	    Virtual_to_Bus(&Controller->EventLogEntry);
	  DAC960_QueueCommand(Command);
	  return;
	}
      if (Controller->NeedErrorTableInformation)
	{
	  Controller->NeedErrorTableInformation = false;
	  Command->CommandMailbox.Type3.CommandOpcode = DAC960_GetErrorTable;
	  Command->CommandMailbox.Type3.BusAddress =
	    Virtual_to_Bus(
	      &Controller->ErrorTable[Controller->ErrorTableIndex ^ 1]);
	  DAC960_QueueCommand(Command);
	  return;
	}
      if (Controller->NeedRebuildProgress && 
	  Controller->Enquiry[Controller->EnquiryIndex]
		      .CriticalLogicalDriveCount <
	  Controller->Enquiry[Controller->EnquiryIndex ^ 1]
		      .CriticalLogicalDriveCount)
	{
	  Controller->NeedRebuildProgress = false;
	  Command->CommandMailbox.Type3.CommandOpcode =
	    DAC960_GetRebuildProgress;
	  Command->CommandMailbox.Type3.BusAddress =
	    Virtual_to_Bus(&Controller->RebuildProgress);
	  DAC960_QueueCommand(Command);
	  return;
	}
      if (Controller->NeedDeviceStateInformation)
	{
	  if (Controller->NeedDeviceInquiryInformation)
	    {
	      DAC960_DCDB_T *DCDB = &Controller->MonitoringDCDB;
	      DAC960_SCSI_Inquiry_T *InquiryStandardData =
		&Controller->InquiryStandardData
			       [Controller->DeviceStateChannel]
			       [Controller->DeviceStateTargetID];
	      InquiryStandardData->PeripheralDeviceType = 0x1F;
	      Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
	      Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
	      DCDB->Channel = Controller->DeviceStateChannel;
	      DCDB->TargetID = Controller->DeviceStateTargetID;
	      DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
	      DCDB->EarlyStatus = false;
	      DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
	      DCDB->NoAutomaticRequestSense = false;
	      DCDB->DisconnectPermitted = true;
	      DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
	      DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
	      DCDB->CDBLength = 6;
	      DCDB->TransferLengthHigh4 = 0;
	      DCDB->SenseLength = sizeof(DCDB->SenseData);
	      DCDB->CDB[0] = 0x12; /* INQUIRY */
	      DCDB->CDB[1] = 0; /* EVPD = 0 */
	      DCDB->CDB[2] = 0; /* Page Code */
	      DCDB->CDB[3] = 0; /* Reserved */
	      DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
	      DCDB->CDB[5] = 0; /* Control */
	      DAC960_QueueCommand(Command);
	      Controller->NeedDeviceInquiryInformation = false;
	      return;
	    }
	  if (Controller->NeedDeviceSerialNumberInformation)
	    {
	      DAC960_DCDB_T *DCDB = &Controller->MonitoringDCDB;
	      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
		&Controller->InquiryUnitSerialNumber
			       [Controller->DeviceStateChannel]
			       [Controller->DeviceStateTargetID];
	      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
	      Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
	      Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
	      DCDB->Channel = Controller->DeviceStateChannel;
	      DCDB->TargetID = Controller->DeviceStateTargetID;
	      DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
	      DCDB->EarlyStatus = false;
	      DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
	      DCDB->NoAutomaticRequestSense = false;
	      DCDB->DisconnectPermitted = true;
	      DCDB->TransferLength =
		sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
	      DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
	      DCDB->CDBLength = 6;
	      DCDB->TransferLengthHigh4 = 0;
	      DCDB->SenseLength = sizeof(DCDB->SenseData);
	      DCDB->CDB[0] = 0x12; /* INQUIRY */
	      DCDB->CDB[1] = 1; /* EVPD = 1 */
	      DCDB->CDB[2] = 0x80; /* Page Code */
	      DCDB->CDB[3] = 0; /* Reserved */
	      DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
	      DCDB->CDB[5] = 0; /* Control */
	      DAC960_QueueCommand(Command);
	      Controller->NeedDeviceSerialNumberInformation = false;
	      return;
	    }
	  if (++Controller->DeviceStateTargetID == DAC960_MaxTargets)
	    {
	      Controller->DeviceStateChannel++;
	      Controller->DeviceStateTargetID = 0;
	    }
	  while (Controller->DeviceStateChannel < Controller->Channels)
	    {
	      DAC960_DeviceState_T *OldDeviceState =
		&Controller->DeviceState[Controller->DeviceStateIndex]
					[Controller->DeviceStateChannel]
					[Controller->DeviceStateTargetID];
	      if (OldDeviceState->Present &&
		  OldDeviceState->DeviceType == DAC960_DiskType)
		{
		  Command->CommandMailbox.Type3D.CommandOpcode =
		    DAC960_GetDeviceState;
		  Command->CommandMailbox.Type3D.Channel =
		    Controller->DeviceStateChannel;
		  Command->CommandMailbox.Type3D.TargetID =
		    Controller->DeviceStateTargetID;
		  Command->CommandMailbox.Type3D.BusAddress =
		    Virtual_to_Bus(&Controller->DeviceState
				      [Controller->DeviceStateIndex ^ 1]
				      [Controller->DeviceStateChannel]
				      [Controller->DeviceStateTargetID]);
		  DAC960_QueueCommand(Command);
		  return;
		}
	      if (++Controller->DeviceStateTargetID == DAC960_MaxTargets)
		{
		  Controller->DeviceStateChannel++;
		  Controller->DeviceStateTargetID = 0;
		}
	    }
	  Controller->NeedDeviceStateInformation = false;
	  Controller->DeviceStateIndex ^= 1;
	}
      if (Controller->NeedLogicalDriveInformation)
	{
	  Controller->NeedLogicalDriveInformation = false;
	  Command->CommandMailbox.Type3.CommandOpcode =
	    DAC960_GetLogicalDriveInformation;
	  Command->CommandMailbox.Type3.BusAddress =
	    Virtual_to_Bus(
	      &Controller->LogicalDriveInformation
			   [Controller->LogicalDriveInformationIndex ^ 1]);
	  DAC960_QueueCommand(Command);
	  return;
	}
      if (Controller->NeedRebuildProgress)
	{
	  Controller->NeedRebuildProgress = false;
	  Command->CommandMailbox.Type3.CommandOpcode =
	    DAC960_GetRebuildProgress;
	  Command->CommandMailbox.Type3.BusAddress =
	    Virtual_to_Bus(&Controller->RebuildProgress);
	  DAC960_QueueCommand(Command);
	  return;
	}
      if (Controller->NeedConsistencyCheckProgress)
	{
	  Controller->NeedConsistencyCheckProgress = false;
	  Command->CommandMailbox.Type3.CommandOpcode = DAC960_RebuildStat;
	  Command->CommandMailbox.Type3.BusAddress =
	    Virtual_to_Bus(&Controller->RebuildProgress);
	  DAC960_QueueCommand(Command);
	  return;
	}
      Controller->MonitoringTimerCount++;
      Controller->MonitoringTimer.expires =
	jiffies + DAC960_MonitoringTimerInterval;
      add_timer(&Controller->MonitoringTimer);
    }
  if (CommandType == DAC960_ImmediateCommand)
    {
      up(Command->Semaphore);
      Command->Semaphore = NULL;
      return;
    }
  if (CommandType == DAC960_QueuedCommand)
    {
      DAC960_KernelCommand_T *KernelCommand = Command->KernelCommand;
      KernelCommand->CommandStatus = Command->CommandStatus;
      Command->KernelCommand = NULL;
      if (CommandOpcode == DAC960_DCDB)
	Controller->DirectCommandActive[KernelCommand->DCDB->Channel]
				       [KernelCommand->DCDB->TargetID] = false;
      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_QueueMonitoringCommand(Command);
      return;
    }
  /*
    Deallocate the Command.
  */
  DAC960_DeallocateCommand(Command);
  /*
    Wake up any processes waiting on a free Command.
  */
  wake_up(&Controller->CommandWaitQueue);
}

Generated by GNU enscript 1.6.4.