DAC960.c
上传用户:ajay2009
上传日期:2009-05-22
资源大小:495k
文件大小:260k
源码类别:

驱动编程

开发平台:

Unix_Linux

  1.   PhysicalDeviceInfo->PhysicalDeviceState =
  2.     DAC960_V2_Device_InvalidState;
  3.   memset(InquiryUnitSerialNumber, 0,
  4.  sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
  5.   InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
  6.   for (DeviceIndex = DAC960_V2_MaxPhysicalDevices - 1;
  7.        DeviceIndex > PhysicalDeviceIndex;
  8.        DeviceIndex--)
  9.     {
  10.       Controller->V2.PhysicalDeviceInformation[DeviceIndex] =
  11. Controller->V2.PhysicalDeviceInformation[DeviceIndex-1];
  12.       Controller->V2.InquiryUnitSerialNumber[DeviceIndex] =
  13. Controller->V2.InquiryUnitSerialNumber[DeviceIndex-1];
  14.     }
  15.   Controller->V2.PhysicalDeviceInformation
  16.  [PhysicalDeviceIndex] =
  17.     PhysicalDeviceInfo;
  18.   Controller->V2.InquiryUnitSerialNumber
  19.  [PhysicalDeviceIndex] =
  20.     InquiryUnitSerialNumber;
  21.   Controller->V2.NeedDeviceSerialNumberInformation = true;
  22. }
  23.     }
  24.   if (PhysicalDeviceInfo != NULL)
  25.     {
  26.       if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
  27.   PhysicalDeviceInfo->PhysicalDeviceState)
  28. DAC960_Critical(
  29.   "Physical Device %d:%d is now %sn", Controller,
  30.   NewPhysicalDeviceInfo->Channel,
  31.   NewPhysicalDeviceInfo->TargetID,
  32.   (NewPhysicalDeviceInfo->PhysicalDeviceState
  33.    == DAC960_V2_Device_Online
  34.    ? "ONLINE"
  35.    : NewPhysicalDeviceInfo->PhysicalDeviceState
  36.      == DAC960_V2_Device_Rebuild
  37.      ? "REBUILD"
  38.      : NewPhysicalDeviceInfo->PhysicalDeviceState
  39.        == DAC960_V2_Device_Missing
  40.        ? "MISSING"
  41.        : NewPhysicalDeviceInfo->PhysicalDeviceState
  42.  == DAC960_V2_Device_Critical
  43.  ? "CRITICAL"
  44.  : NewPhysicalDeviceInfo->PhysicalDeviceState
  45.    == DAC960_V2_Device_Dead
  46.    ? "DEAD"
  47.    : NewPhysicalDeviceInfo->PhysicalDeviceState
  48.      == DAC960_V2_Device_SuspectedDead
  49.      ? "SUSPECTED-DEAD"
  50.      : NewPhysicalDeviceInfo->PhysicalDeviceState
  51.        == DAC960_V2_Device_CommandedOffline
  52.        ? "COMMANDED-OFFLINE"
  53.        : NewPhysicalDeviceInfo->PhysicalDeviceState
  54.  == DAC960_V2_Device_Standby
  55.  ? "STANDBY" : "UNKNOWN"));
  56.       if ((NewPhysicalDeviceInfo->ParityErrors !=
  57.    PhysicalDeviceInfo->ParityErrors) ||
  58.   (NewPhysicalDeviceInfo->SoftErrors !=
  59.    PhysicalDeviceInfo->SoftErrors) ||
  60.   (NewPhysicalDeviceInfo->HardErrors !=
  61.    PhysicalDeviceInfo->HardErrors) ||
  62.   (NewPhysicalDeviceInfo->MiscellaneousErrors !=
  63.    PhysicalDeviceInfo->MiscellaneousErrors) ||
  64.   (NewPhysicalDeviceInfo->CommandTimeouts !=
  65.    PhysicalDeviceInfo->CommandTimeouts) ||
  66.   (NewPhysicalDeviceInfo->Retries !=
  67.    PhysicalDeviceInfo->Retries) ||
  68.   (NewPhysicalDeviceInfo->Aborts !=
  69.    PhysicalDeviceInfo->Aborts) ||
  70.   (NewPhysicalDeviceInfo->PredictedFailuresDetected !=
  71.    PhysicalDeviceInfo->PredictedFailuresDetected))
  72. {
  73.   DAC960_Critical("Physical Device %d:%d Errors: "
  74.   "Parity = %d, Soft = %d, "
  75.   "Hard = %d, Misc = %dn",
  76.   Controller,
  77.   NewPhysicalDeviceInfo->Channel,
  78.   NewPhysicalDeviceInfo->TargetID,
  79.   NewPhysicalDeviceInfo->ParityErrors,
  80.   NewPhysicalDeviceInfo->SoftErrors,
  81.   NewPhysicalDeviceInfo->HardErrors,
  82.   NewPhysicalDeviceInfo->MiscellaneousErrors);
  83.   DAC960_Critical("Physical Device %d:%d Errors: "
  84.   "Timeouts = %d, Retries = %d, "
  85.   "Aborts = %d, Predicted = %dn",
  86.   Controller,
  87.   NewPhysicalDeviceInfo->Channel,
  88.   NewPhysicalDeviceInfo->TargetID,
  89.   NewPhysicalDeviceInfo->CommandTimeouts,
  90.   NewPhysicalDeviceInfo->Retries,
  91.   NewPhysicalDeviceInfo->Aborts,
  92.   NewPhysicalDeviceInfo
  93.   ->PredictedFailuresDetected);
  94. }
  95.       if ((PhysicalDeviceInfo->PhysicalDeviceState
  96.    == DAC960_V2_Device_Dead ||
  97.    PhysicalDeviceInfo->PhysicalDeviceState
  98.    == DAC960_V2_Device_InvalidState) &&
  99.   NewPhysicalDeviceInfo->PhysicalDeviceState
  100.   != DAC960_V2_Device_Dead)
  101. Controller->V2.NeedDeviceSerialNumberInformation = true;
  102.       memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
  103.      sizeof(DAC960_V2_PhysicalDeviceInfo_T));
  104.     }
  105.   NewPhysicalDeviceInfo->LogicalUnit++;
  106.   Controller->V2.PhysicalDeviceIndex++;
  107. }
  108.       else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
  109. {
  110.   unsigned int DeviceIndex;
  111.   for (DeviceIndex = Controller->V2.PhysicalDeviceIndex;
  112.        DeviceIndex < DAC960_V2_MaxPhysicalDevices;
  113.        DeviceIndex++)
  114.     {
  115.       DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
  116. Controller->V2.PhysicalDeviceInformation[DeviceIndex];
  117.       DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
  118. Controller->V2.InquiryUnitSerialNumber[DeviceIndex];
  119.       if (PhysicalDeviceInfo == NULL) break;
  120.       DAC960_Critical("Physical Device %d:%d No Longer Existsn",
  121.       Controller,
  122.       PhysicalDeviceInfo->Channel,
  123.       PhysicalDeviceInfo->TargetID);
  124.       Controller->V2.PhysicalDeviceInformation[DeviceIndex] = NULL;
  125.       Controller->V2.InquiryUnitSerialNumber[DeviceIndex] = NULL;
  126.       kfree(PhysicalDeviceInfo);
  127.       kfree(InquiryUnitSerialNumber);
  128.     }
  129.   Controller->V2.NeedPhysicalDeviceInformation = false;
  130. }
  131.       else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
  132.        CommandStatus == DAC960_V2_NormalCompletion)
  133. {
  134.   DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
  135.     Controller->V2.NewLogicalDeviceInformation;
  136.   unsigned short LogicalDeviceNumber =
  137.     NewLogicalDeviceInfo->LogicalDeviceNumber;
  138.   DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
  139.     Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber];
  140.   if (LogicalDeviceInfo == NULL)
  141.     {
  142.       DAC960_V2_PhysicalDevice_T PhysicalDevice;
  143.       PhysicalDevice.Controller = 0;
  144.       PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
  145.       PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
  146.       PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
  147.       Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
  148. PhysicalDevice;
  149.       LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
  150. kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
  151.       Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
  152. LogicalDeviceInfo;
  153.       DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
  154.       "Now Exists%sn", Controller,
  155.       LogicalDeviceNumber,
  156.       Controller->ControllerNumber,
  157.       LogicalDeviceNumber,
  158.       (LogicalDeviceInfo != NULL
  159.        ? "" : " - Allocation Failed"));
  160.       if (LogicalDeviceInfo != NULL)
  161. {
  162.   memset(LogicalDeviceInfo, 0,
  163.  sizeof(DAC960_V2_LogicalDeviceInfo_T));
  164.   DAC960_ComputeGenericDiskInfo(Controller);
  165. }
  166.     }
  167.   if (LogicalDeviceInfo != NULL)
  168.     {
  169.       unsigned long LogicalDeviceSize =
  170. NewLogicalDeviceInfo->ConfigurableDeviceSize;
  171.       if (NewLogicalDeviceInfo->LogicalDeviceState !=
  172.   LogicalDeviceInfo->LogicalDeviceState)
  173. DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
  174. "is now %sn", Controller,
  175. LogicalDeviceNumber,
  176. Controller->ControllerNumber,
  177. LogicalDeviceNumber,
  178. (NewLogicalDeviceInfo->LogicalDeviceState
  179.  == DAC960_V2_LogicalDevice_Online
  180.  ? "ONLINE"
  181.  : NewLogicalDeviceInfo->LogicalDeviceState
  182.    == DAC960_V2_LogicalDevice_Critical
  183.    ? "CRITICAL" : "OFFLINE"));
  184.       if ((NewLogicalDeviceInfo->SoftErrors !=
  185.    LogicalDeviceInfo->SoftErrors) ||
  186.   (NewLogicalDeviceInfo->CommandsFailed !=
  187.    LogicalDeviceInfo->CommandsFailed) ||
  188.   (NewLogicalDeviceInfo->DeferredWriteErrors !=
  189.    LogicalDeviceInfo->DeferredWriteErrors))
  190. DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) Errors: "
  191. "Soft = %d, Failed = %d, Deferred Write = %dn",
  192. Controller, LogicalDeviceNumber,
  193. Controller->ControllerNumber,
  194. LogicalDeviceNumber,
  195. NewLogicalDeviceInfo->SoftErrors,
  196. NewLogicalDeviceInfo->CommandsFailed,
  197. NewLogicalDeviceInfo->DeferredWriteErrors);
  198.       if (NewLogicalDeviceInfo->ConsistencyCheckInProgress)
  199. DAC960_V2_ReportProgress(Controller,
  200.  "Consistency Check",
  201.  LogicalDeviceNumber,
  202.  NewLogicalDeviceInfo
  203.  ->ConsistencyCheckBlockNumber,
  204.  LogicalDeviceSize);
  205.       else if (NewLogicalDeviceInfo->RebuildInProgress)
  206. DAC960_V2_ReportProgress(Controller,
  207.  "Rebuild",
  208.  LogicalDeviceNumber,
  209.  NewLogicalDeviceInfo
  210.  ->RebuildBlockNumber,
  211.  LogicalDeviceSize);
  212.       else if (NewLogicalDeviceInfo->BackgroundInitializationInProgress)
  213. DAC960_V2_ReportProgress(Controller,
  214.  "Background Initialization",
  215.  LogicalDeviceNumber,
  216.  NewLogicalDeviceInfo
  217.  ->BackgroundInitializationBlockNumber,
  218.  LogicalDeviceSize);
  219.       else if (NewLogicalDeviceInfo->ForegroundInitializationInProgress)
  220. DAC960_V2_ReportProgress(Controller,
  221.  "Foreground Initialization",
  222.  LogicalDeviceNumber,
  223.  NewLogicalDeviceInfo
  224.  ->ForegroundInitializationBlockNumber,
  225.  LogicalDeviceSize);
  226.       else if (NewLogicalDeviceInfo->DataMigrationInProgress)
  227. DAC960_V2_ReportProgress(Controller,
  228.  "Data Migration",
  229.  LogicalDeviceNumber,
  230.  NewLogicalDeviceInfo
  231.  ->DataMigrationBlockNumber,
  232.  LogicalDeviceSize);
  233.       else if (NewLogicalDeviceInfo->PatrolOperationInProgress)
  234. DAC960_V2_ReportProgress(Controller,
  235.  "Patrol Operation",
  236.  LogicalDeviceNumber,
  237.  NewLogicalDeviceInfo
  238.  ->PatrolOperationBlockNumber,
  239.  LogicalDeviceSize);
  240.       if (LogicalDeviceInfo->BackgroundInitializationInProgress &&
  241.   !NewLogicalDeviceInfo->BackgroundInitializationInProgress)
  242. DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) "
  243. "Background Initialization %sn",
  244. Controller,
  245. LogicalDeviceNumber,
  246. Controller->ControllerNumber,
  247. LogicalDeviceNumber,
  248. (NewLogicalDeviceInfo->LogicalDeviceControl
  249.       .LogicalDeviceInitialized
  250.  ? "Completed" : "Failed"));
  251.       memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
  252.      sizeof(DAC960_V2_LogicalDeviceInfo_T));
  253.     }
  254.   Controller->V2.LogicalDriveFoundDuringScan
  255.  [LogicalDeviceNumber] = true;
  256.   NewLogicalDeviceInfo->LogicalDeviceNumber++;
  257. }
  258.       else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
  259. {
  260.   int LogicalDriveNumber;
  261.   for (LogicalDriveNumber = 0;
  262.        LogicalDriveNumber < DAC960_MaxLogicalDrives;
  263.        LogicalDriveNumber++)
  264.     {
  265.       DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
  266. Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
  267.       if (LogicalDeviceInfo == NULL ||
  268.   Controller->V2.LogicalDriveFoundDuringScan
  269.  [LogicalDriveNumber])
  270. continue;
  271.       DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
  272.       "No Longer Existsn", Controller,
  273.       LogicalDriveNumber,
  274.       Controller->ControllerNumber,
  275.       LogicalDriveNumber);
  276.       Controller->V2.LogicalDeviceInformation
  277.      [LogicalDriveNumber] = NULL;
  278.       kfree(LogicalDeviceInfo);
  279.       Controller->LogicalDriveInitiallyAccessible
  280.   [LogicalDriveNumber] = false;
  281.       DAC960_ComputeGenericDiskInfo(Controller);
  282.     }
  283.   Controller->V2.NeedLogicalDeviceInformation = false;
  284. }
  285.       else if (CommandOpcode == DAC960_V2_SCSI_10_Passthru)
  286.         {
  287.     DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
  288. Controller->V2.InquiryUnitSerialNumber[Controller->V2.PhysicalDeviceIndex - 1];
  289.     if (CommandStatus != DAC960_V2_NormalCompletion) {
  290. memset(InquiryUnitSerialNumber,
  291. 0, sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
  292. InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
  293.     } else
  294.    memcpy(InquiryUnitSerialNumber,
  295. Controller->V2.NewInquiryUnitSerialNumber,
  296. sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
  297.      Controller->V2.NeedDeviceSerialNumberInformation = false;
  298.         }
  299.       if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
  300.   - Controller->V2.NextEventSequenceNumber > 0)
  301. {
  302.   CommandMailbox->GetEvent.CommandOpcode = DAC960_V2_IOCTL;
  303.   CommandMailbox->GetEvent.DataTransferSize = sizeof(DAC960_V2_Event_T);
  304.   CommandMailbox->GetEvent.EventSequenceNumberHigh16 =
  305.     Controller->V2.NextEventSequenceNumber >> 16;
  306.   CommandMailbox->GetEvent.ControllerNumber = 0;
  307.   CommandMailbox->GetEvent.IOCTL_Opcode =
  308.     DAC960_V2_GetEvent;
  309.   CommandMailbox->GetEvent.EventSequenceNumberLow16 =
  310.     Controller->V2.NextEventSequenceNumber & 0xFFFF;
  311.   CommandMailbox->GetEvent.DataTransferMemoryAddress
  312.   .ScatterGatherSegments[0]
  313.   .SegmentDataPointer =
  314.     Controller->V2.EventDMA;
  315.   CommandMailbox->GetEvent.DataTransferMemoryAddress
  316.   .ScatterGatherSegments[0]
  317.   .SegmentByteCount =
  318.     CommandMailbox->GetEvent.DataTransferSize;
  319.   DAC960_QueueCommand(Command);
  320.   return;
  321. }
  322.       if (Controller->V2.NeedPhysicalDeviceInformation)
  323. {
  324.   if (Controller->V2.NeedDeviceSerialNumberInformation)
  325.     {
  326.       DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
  327.                 Controller->V2.NewInquiryUnitSerialNumber;
  328.       InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
  329.       DAC960_V2_ConstructNewUnitSerialNumber(Controller, CommandMailbox,
  330. Controller->V2.NewPhysicalDeviceInformation->Channel,
  331. Controller->V2.NewPhysicalDeviceInformation->TargetID,
  332. Controller->V2.NewPhysicalDeviceInformation->LogicalUnit - 1);
  333.       DAC960_QueueCommand(Command);
  334.       return;
  335.     }
  336.   if (Controller->V2.StartPhysicalDeviceInformationScan)
  337.     {
  338.       Controller->V2.PhysicalDeviceIndex = 0;
  339.       Controller->V2.NewPhysicalDeviceInformation->Channel = 0;
  340.       Controller->V2.NewPhysicalDeviceInformation->TargetID = 0;
  341.       Controller->V2.NewPhysicalDeviceInformation->LogicalUnit = 0;
  342.       Controller->V2.StartPhysicalDeviceInformationScan = false;
  343.     }
  344.   CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
  345.   CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
  346.     sizeof(DAC960_V2_PhysicalDeviceInfo_T);
  347.   CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit =
  348.     Controller->V2.NewPhysicalDeviceInformation->LogicalUnit;
  349.   CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID =
  350.     Controller->V2.NewPhysicalDeviceInformation->TargetID;
  351.   CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel =
  352.     Controller->V2.NewPhysicalDeviceInformation->Channel;
  353.   CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
  354.     DAC960_V2_GetPhysicalDeviceInfoValid;
  355.   CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
  356.     .ScatterGatherSegments[0]
  357.     .SegmentDataPointer =
  358.     Controller->V2.NewPhysicalDeviceInformationDMA;
  359.   CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
  360.     .ScatterGatherSegments[0]
  361.     .SegmentByteCount =
  362.     CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
  363.   DAC960_QueueCommand(Command);
  364.   return;
  365. }
  366.       if (Controller->V2.NeedLogicalDeviceInformation)
  367. {
  368.   if (Controller->V2.StartLogicalDeviceInformationScan)
  369.     {
  370.       int LogicalDriveNumber;
  371.       for (LogicalDriveNumber = 0;
  372.    LogicalDriveNumber < DAC960_MaxLogicalDrives;
  373.    LogicalDriveNumber++)
  374. Controller->V2.LogicalDriveFoundDuringScan
  375.        [LogicalDriveNumber] = false;
  376.       Controller->V2.NewLogicalDeviceInformation->LogicalDeviceNumber = 0;
  377.       Controller->V2.StartLogicalDeviceInformationScan = false;
  378.     }
  379.   CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
  380.   CommandMailbox->LogicalDeviceInfo.DataTransferSize =
  381.     sizeof(DAC960_V2_LogicalDeviceInfo_T);
  382.   CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
  383.     Controller->V2.NewLogicalDeviceInformation->LogicalDeviceNumber;
  384.   CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
  385.     DAC960_V2_GetLogicalDeviceInfoValid;
  386.   CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
  387.    .ScatterGatherSegments[0]
  388.    .SegmentDataPointer =
  389.     Controller->V2.NewLogicalDeviceInformationDMA;
  390.   CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
  391.    .ScatterGatherSegments[0]
  392.    .SegmentByteCount =
  393.     CommandMailbox->LogicalDeviceInfo.DataTransferSize;
  394.   DAC960_QueueCommand(Command);
  395.   return;
  396. }
  397.       Controller->MonitoringTimerCount++;
  398.       Controller->MonitoringTimer.expires =
  399. jiffies + DAC960_HealthStatusMonitoringInterval;
  400.        add_timer(&Controller->MonitoringTimer);
  401.     }
  402.   if (CommandType == DAC960_ImmediateCommand)
  403.     {
  404.       complete(Command->Completion);
  405.       Command->Completion = NULL;
  406.       return;
  407.     }
  408.   if (CommandType == DAC960_QueuedCommand)
  409.     {
  410.       DAC960_V2_KernelCommand_T *KernelCommand = Command->V2.KernelCommand;
  411.       KernelCommand->CommandStatus = CommandStatus;
  412.       KernelCommand->RequestSenseLength = Command->V2.RequestSenseLength;
  413.       KernelCommand->DataTransferLength = Command->V2.DataTransferResidue;
  414.       Command->V2.KernelCommand = NULL;
  415.       DAC960_DeallocateCommand(Command);
  416.       KernelCommand->CompletionFunction(KernelCommand);
  417.       return;
  418.     }
  419.   /*
  420.     Queue a Status Monitoring Command to the Controller using the just
  421.     completed Command if one was deferred previously due to lack of a
  422.     free Command when the Monitoring Timer Function was called.
  423.   */
  424.   if (Controller->MonitoringCommandDeferred)
  425.     {
  426.       Controller->MonitoringCommandDeferred = false;
  427.       DAC960_V2_QueueMonitoringCommand(Command);
  428.       return;
  429.     }
  430.   /*
  431.     Deallocate the Command.
  432.   */
  433.   DAC960_DeallocateCommand(Command);
  434.   /*
  435.     Wake up any processes waiting on a free Command.
  436.   */
  437.   wake_up(&Controller->CommandWaitQueue);
  438. }
  439. /*
  440.   DAC960_GEM_InterruptHandler handles hardware interrupts from DAC960 GEM Series
  441.   Controllers.
  442. */
  443. static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel,
  444.        void *DeviceIdentifier,
  445.        struct pt_regs *InterruptRegisters)
  446. {
  447.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
  448.   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
  449.   DAC960_V2_StatusMailbox_T *NextStatusMailbox;
  450.   unsigned long flags;
  451.   spin_lock_irqsave(&Controller->queue_lock, flags);
  452.   DAC960_GEM_AcknowledgeInterrupt(ControllerBaseAddress);
  453.   NextStatusMailbox = Controller->V2.NextStatusMailbox;
  454.   while (NextStatusMailbox->Fields.CommandIdentifier > 0)
  455.     {
  456.        DAC960_V2_CommandIdentifier_T CommandIdentifier =
  457.            NextStatusMailbox->Fields.CommandIdentifier;
  458.        DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
  459.        Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
  460.        Command->V2.RequestSenseLength =
  461.            NextStatusMailbox->Fields.RequestSenseLength;
  462.        Command->V2.DataTransferResidue =
  463.            NextStatusMailbox->Fields.DataTransferResidue;
  464.        NextStatusMailbox->Words[0] = 0;
  465.        if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
  466.            NextStatusMailbox = Controller->V2.FirstStatusMailbox;
  467.        DAC960_V2_ProcessCompletedCommand(Command);
  468.     }
  469.   Controller->V2.NextStatusMailbox = NextStatusMailbox;
  470.   /*
  471.     Attempt to remove additional I/O Requests from the Controller's
  472.     I/O Request Queue and queue them to the Controller.
  473.   */
  474.   DAC960_ProcessRequest(Controller);
  475.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  476.   return IRQ_HANDLED;
  477. }
  478. /*
  479.   DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
  480.   Controllers.
  481. */
  482. static irqreturn_t DAC960_BA_InterruptHandler(int IRQ_Channel,
  483.        void *DeviceIdentifier,
  484.        struct pt_regs *InterruptRegisters)
  485. {
  486.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
  487.   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
  488.   DAC960_V2_StatusMailbox_T *NextStatusMailbox;
  489.   unsigned long flags;
  490.   spin_lock_irqsave(&Controller->queue_lock, flags);
  491.   DAC960_BA_AcknowledgeInterrupt(ControllerBaseAddress);
  492.   NextStatusMailbox = Controller->V2.NextStatusMailbox;
  493.   while (NextStatusMailbox->Fields.CommandIdentifier > 0)
  494.     {
  495.       DAC960_V2_CommandIdentifier_T CommandIdentifier =
  496. NextStatusMailbox->Fields.CommandIdentifier;
  497.       DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
  498.       Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
  499.       Command->V2.RequestSenseLength =
  500. NextStatusMailbox->Fields.RequestSenseLength;
  501.       Command->V2.DataTransferResidue =
  502. NextStatusMailbox->Fields.DataTransferResidue;
  503.       NextStatusMailbox->Words[0] = 0;
  504.       if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
  505. NextStatusMailbox = Controller->V2.FirstStatusMailbox;
  506.       DAC960_V2_ProcessCompletedCommand(Command);
  507.     }
  508.   Controller->V2.NextStatusMailbox = NextStatusMailbox;
  509.   /*
  510.     Attempt to remove additional I/O Requests from the Controller's
  511.     I/O Request Queue and queue them to the Controller.
  512.   */
  513.   DAC960_ProcessRequest(Controller);
  514.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  515.   return IRQ_HANDLED;
  516. }
  517. /*
  518.   DAC960_LP_InterruptHandler handles hardware interrupts from DAC960 LP Series
  519.   Controllers.
  520. */
  521. static irqreturn_t DAC960_LP_InterruptHandler(int IRQ_Channel,
  522.        void *DeviceIdentifier,
  523.        struct pt_regs *InterruptRegisters)
  524. {
  525.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
  526.   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
  527.   DAC960_V2_StatusMailbox_T *NextStatusMailbox;
  528.   unsigned long flags;
  529.   spin_lock_irqsave(&Controller->queue_lock, flags);
  530.   DAC960_LP_AcknowledgeInterrupt(ControllerBaseAddress);
  531.   NextStatusMailbox = Controller->V2.NextStatusMailbox;
  532.   while (NextStatusMailbox->Fields.CommandIdentifier > 0)
  533.     {
  534.       DAC960_V2_CommandIdentifier_T CommandIdentifier =
  535. NextStatusMailbox->Fields.CommandIdentifier;
  536.       DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
  537.       Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
  538.       Command->V2.RequestSenseLength =
  539. NextStatusMailbox->Fields.RequestSenseLength;
  540.       Command->V2.DataTransferResidue =
  541. NextStatusMailbox->Fields.DataTransferResidue;
  542.       NextStatusMailbox->Words[0] = 0;
  543.       if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
  544. NextStatusMailbox = Controller->V2.FirstStatusMailbox;
  545.       DAC960_V2_ProcessCompletedCommand(Command);
  546.     }
  547.   Controller->V2.NextStatusMailbox = NextStatusMailbox;
  548.   /*
  549.     Attempt to remove additional I/O Requests from the Controller's
  550.     I/O Request Queue and queue them to the Controller.
  551.   */
  552.   DAC960_ProcessRequest(Controller);
  553.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  554.   return IRQ_HANDLED;
  555. }
  556. /*
  557.   DAC960_LA_InterruptHandler handles hardware interrupts from DAC960 LA Series
  558.   Controllers.
  559. */
  560. static irqreturn_t DAC960_LA_InterruptHandler(int IRQ_Channel,
  561.        void *DeviceIdentifier,
  562.        struct pt_regs *InterruptRegisters)
  563. {
  564.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
  565.   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
  566.   DAC960_V1_StatusMailbox_T *NextStatusMailbox;
  567.   unsigned long flags;
  568.   spin_lock_irqsave(&Controller->queue_lock, flags);
  569.   DAC960_LA_AcknowledgeInterrupt(ControllerBaseAddress);
  570.   NextStatusMailbox = Controller->V1.NextStatusMailbox;
  571.   while (NextStatusMailbox->Fields.Valid)
  572.     {
  573.       DAC960_V1_CommandIdentifier_T CommandIdentifier =
  574. NextStatusMailbox->Fields.CommandIdentifier;
  575.       DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
  576.       Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
  577.       NextStatusMailbox->Word = 0;
  578.       if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
  579. NextStatusMailbox = Controller->V1.FirstStatusMailbox;
  580.       DAC960_V1_ProcessCompletedCommand(Command);
  581.     }
  582.   Controller->V1.NextStatusMailbox = NextStatusMailbox;
  583.   /*
  584.     Attempt to remove additional I/O Requests from the Controller's
  585.     I/O Request Queue and queue them to the Controller.
  586.   */
  587.   DAC960_ProcessRequest(Controller);
  588.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  589.   return IRQ_HANDLED;
  590. }
  591. /*
  592.   DAC960_PG_InterruptHandler handles hardware interrupts from DAC960 PG Series
  593.   Controllers.
  594. */
  595. static irqreturn_t DAC960_PG_InterruptHandler(int IRQ_Channel,
  596.        void *DeviceIdentifier,
  597.        struct pt_regs *InterruptRegisters)
  598. {
  599.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
  600.   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
  601.   DAC960_V1_StatusMailbox_T *NextStatusMailbox;
  602.   unsigned long flags;
  603.   spin_lock_irqsave(&Controller->queue_lock, flags);
  604.   DAC960_PG_AcknowledgeInterrupt(ControllerBaseAddress);
  605.   NextStatusMailbox = Controller->V1.NextStatusMailbox;
  606.   while (NextStatusMailbox->Fields.Valid)
  607.     {
  608.       DAC960_V1_CommandIdentifier_T CommandIdentifier =
  609. NextStatusMailbox->Fields.CommandIdentifier;
  610.       DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
  611.       Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
  612.       NextStatusMailbox->Word = 0;
  613.       if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
  614. NextStatusMailbox = Controller->V1.FirstStatusMailbox;
  615.       DAC960_V1_ProcessCompletedCommand(Command);
  616.     }
  617.   Controller->V1.NextStatusMailbox = NextStatusMailbox;
  618.   /*
  619.     Attempt to remove additional I/O Requests from the Controller's
  620.     I/O Request Queue and queue them to the Controller.
  621.   */
  622.   DAC960_ProcessRequest(Controller);
  623.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  624.   return IRQ_HANDLED;
  625. }
  626. /*
  627.   DAC960_PD_InterruptHandler handles hardware interrupts from DAC960 PD Series
  628.   Controllers.
  629. */
  630. static irqreturn_t DAC960_PD_InterruptHandler(int IRQ_Channel,
  631.        void *DeviceIdentifier,
  632.        struct pt_regs *InterruptRegisters)
  633. {
  634.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
  635.   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
  636.   unsigned long flags;
  637.   spin_lock_irqsave(&Controller->queue_lock, flags);
  638.   while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
  639.     {
  640.       DAC960_V1_CommandIdentifier_T CommandIdentifier =
  641. DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
  642.       DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
  643.       Command->V1.CommandStatus =
  644. DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
  645.       DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
  646.       DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
  647.       DAC960_V1_ProcessCompletedCommand(Command);
  648.     }
  649.   /*
  650.     Attempt to remove additional I/O Requests from the Controller's
  651.     I/O Request Queue and queue them to the Controller.
  652.   */
  653.   DAC960_ProcessRequest(Controller);
  654.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  655.   return IRQ_HANDLED;
  656. }
  657. /*
  658.   DAC960_P_InterruptHandler handles hardware interrupts from DAC960 P Series
  659.   Controllers.
  660.   Translations of DAC960_V1_Enquiry and DAC960_V1_GetDeviceState rely
  661.   on the data having been placed into DAC960_Controller_T, rather than
  662.   an arbitrary buffer.
  663. */
  664. static irqreturn_t DAC960_P_InterruptHandler(int IRQ_Channel,
  665.       void *DeviceIdentifier,
  666.       struct pt_regs *InterruptRegisters)
  667. {
  668.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
  669.   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
  670.   unsigned long flags;
  671.   spin_lock_irqsave(&Controller->queue_lock, flags);
  672.   while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
  673.     {
  674.       DAC960_V1_CommandIdentifier_T CommandIdentifier =
  675. DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
  676.       DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
  677.       DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
  678.       DAC960_V1_CommandOpcode_T CommandOpcode =
  679. CommandMailbox->Common.CommandOpcode;
  680.       Command->V1.CommandStatus =
  681. DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
  682.       DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
  683.       DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
  684.       switch (CommandOpcode)
  685. {
  686. case DAC960_V1_Enquiry_Old:
  687.   Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Enquiry;
  688.   DAC960_P_To_PD_TranslateEnquiry(Controller->V1.NewEnquiry);
  689.   break;
  690. case DAC960_V1_GetDeviceState_Old:
  691.   Command->V1.CommandMailbox.Common.CommandOpcode =
  692.      DAC960_V1_GetDeviceState;
  693.   DAC960_P_To_PD_TranslateDeviceState(Controller->V1.NewDeviceState);
  694.   break;
  695. case DAC960_V1_Read_Old:
  696.   Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Read;
  697.   DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
  698.   break;
  699. case DAC960_V1_Write_Old:
  700.   Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Write;
  701.   DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
  702.   break;
  703. case DAC960_V1_ReadWithScatterGather_Old:
  704.   Command->V1.CommandMailbox.Common.CommandOpcode =
  705.     DAC960_V1_ReadWithScatterGather;
  706.   DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
  707.   break;
  708. case DAC960_V1_WriteWithScatterGather_Old:
  709.   Command->V1.CommandMailbox.Common.CommandOpcode =
  710.     DAC960_V1_WriteWithScatterGather;
  711.   DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
  712.   break;
  713. default:
  714.   break;
  715. }
  716.       DAC960_V1_ProcessCompletedCommand(Command);
  717.     }
  718.   /*
  719.     Attempt to remove additional I/O Requests from the Controller's
  720.     I/O Request Queue and queue them to the Controller.
  721.   */
  722.   DAC960_ProcessRequest(Controller);
  723.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  724.   return IRQ_HANDLED;
  725. }
  726. /*
  727.   DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1
  728.   Firmware Controllers.
  729. */
  730. static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *Command)
  731. {
  732.   DAC960_Controller_T *Controller = Command->Controller;
  733.   DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
  734.   DAC960_V1_ClearCommand(Command);
  735.   Command->CommandType = DAC960_MonitoringCommand;
  736.   CommandMailbox->Type3.CommandOpcode = DAC960_V1_Enquiry;
  737.   CommandMailbox->Type3.BusAddress = Controller->V1.NewEnquiryDMA;
  738.   DAC960_QueueCommand(Command);
  739. }
  740. /*
  741.   DAC960_V2_QueueMonitoringCommand queues a Monitoring Command to DAC960 V2
  742.   Firmware Controllers.
  743. */
  744. static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *Command)
  745. {
  746.   DAC960_Controller_T *Controller = Command->Controller;
  747.   DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
  748.   DAC960_V2_ClearCommand(Command);
  749.   Command->CommandType = DAC960_MonitoringCommand;
  750.   CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
  751.   CommandMailbox->ControllerInfo.CommandControlBits
  752. .DataTransferControllerToHost = true;
  753.   CommandMailbox->ControllerInfo.CommandControlBits
  754. .NoAutoRequestSense = true;
  755.   CommandMailbox->ControllerInfo.DataTransferSize =
  756.     sizeof(DAC960_V2_ControllerInfo_T);
  757.   CommandMailbox->ControllerInfo.ControllerNumber = 0;
  758.   CommandMailbox->ControllerInfo.IOCTL_Opcode = DAC960_V2_GetControllerInfo;
  759.   CommandMailbox->ControllerInfo.DataTransferMemoryAddress
  760. .ScatterGatherSegments[0]
  761. .SegmentDataPointer =
  762.     Controller->V2.NewControllerInformationDMA;
  763.   CommandMailbox->ControllerInfo.DataTransferMemoryAddress
  764. .ScatterGatherSegments[0]
  765. .SegmentByteCount =
  766.     CommandMailbox->ControllerInfo.DataTransferSize;
  767.   DAC960_QueueCommand(Command);
  768. }
  769. /*
  770.   DAC960_MonitoringTimerFunction is the timer function for monitoring
  771.   the status of DAC960 Controllers.
  772. */
  773. static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
  774. {
  775.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) TimerData;
  776.   DAC960_Command_T *Command;
  777.   unsigned long flags;
  778.   if (Controller->FirmwareType == DAC960_V1_Controller)
  779.     {
  780.       spin_lock_irqsave(&Controller->queue_lock, flags);
  781.       /*
  782. Queue a Status Monitoring Command to Controller.
  783.       */
  784.       Command = DAC960_AllocateCommand(Controller);
  785.       if (Command != NULL)
  786. DAC960_V1_QueueMonitoringCommand(Command);
  787.       else Controller->MonitoringCommandDeferred = true;
  788.       spin_unlock_irqrestore(&Controller->queue_lock, flags);
  789.     }
  790.   else
  791.     {
  792.       DAC960_V2_ControllerInfo_T *ControllerInfo =
  793. &Controller->V2.ControllerInformation;
  794.       unsigned int StatusChangeCounter =
  795. Controller->V2.HealthStatusBuffer->StatusChangeCounter;
  796.       boolean ForceMonitoringCommand = false;
  797.       if (jiffies - Controller->SecondaryMonitoringTime
  798.   > DAC960_SecondaryMonitoringInterval)
  799. {
  800.   int LogicalDriveNumber;
  801.   for (LogicalDriveNumber = 0;
  802.        LogicalDriveNumber < DAC960_MaxLogicalDrives;
  803.        LogicalDriveNumber++)
  804.     {
  805.       DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
  806. Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
  807.       if (LogicalDeviceInfo == NULL) continue;
  808.       if (!LogicalDeviceInfo->LogicalDeviceControl
  809.      .LogicalDeviceInitialized)
  810. {
  811.   ForceMonitoringCommand = true;
  812.   break;
  813. }
  814.     }
  815.   Controller->SecondaryMonitoringTime = jiffies;
  816. }
  817.       if (StatusChangeCounter == Controller->V2.StatusChangeCounter &&
  818.   Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
  819.   == Controller->V2.NextEventSequenceNumber &&
  820.   (ControllerInfo->BackgroundInitializationsActive +
  821.    ControllerInfo->LogicalDeviceInitializationsActive +
  822.    ControllerInfo->PhysicalDeviceInitializationsActive +
  823.    ControllerInfo->ConsistencyChecksActive +
  824.    ControllerInfo->RebuildsActive +
  825.    ControllerInfo->OnlineExpansionsActive == 0 ||
  826.    jiffies - Controller->PrimaryMonitoringTime
  827.    < DAC960_MonitoringTimerInterval) &&
  828.   !ForceMonitoringCommand)
  829. {
  830.   Controller->MonitoringTimer.expires =
  831.     jiffies + DAC960_HealthStatusMonitoringInterval;
  832.     add_timer(&Controller->MonitoringTimer);
  833.   return;
  834. }
  835.       Controller->V2.StatusChangeCounter = StatusChangeCounter;
  836.       Controller->PrimaryMonitoringTime = jiffies;
  837.       spin_lock_irqsave(&Controller->queue_lock, flags);
  838.       /*
  839. Queue a Status Monitoring Command to Controller.
  840.       */
  841.       Command = DAC960_AllocateCommand(Controller);
  842.       if (Command != NULL)
  843. DAC960_V2_QueueMonitoringCommand(Command);
  844.       else Controller->MonitoringCommandDeferred = true;
  845.       spin_unlock_irqrestore(&Controller->queue_lock, flags);
  846.       /*
  847. Wake up any processes waiting on a Health Status Buffer change.
  848.       */
  849.       wake_up(&Controller->HealthStatusWaitQueue);
  850.     }
  851. }
  852. /*
  853.   DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount
  854.   additional bytes in the Combined Status Buffer and grows the buffer if
  855.   necessary.  It returns true if there is enough room and false otherwise.
  856. */
  857. static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
  858. unsigned int ByteCount)
  859. {
  860.   unsigned char *NewStatusBuffer;
  861.   if (Controller->InitialStatusLength + 1 +
  862.       Controller->CurrentStatusLength + ByteCount + 1 <=
  863.       Controller->CombinedStatusBufferLength)
  864.     return true;
  865.   if (Controller->CombinedStatusBufferLength == 0)
  866.     {
  867.       unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize;
  868.       while (NewStatusBufferLength < ByteCount)
  869. NewStatusBufferLength *= 2;
  870.       Controller->CombinedStatusBuffer =
  871. (unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC);
  872.       if (Controller->CombinedStatusBuffer == NULL) return false;
  873.       Controller->CombinedStatusBufferLength = NewStatusBufferLength;
  874.       return true;
  875.     }
  876.   NewStatusBuffer = (unsigned char *)
  877.     kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC);
  878.   if (NewStatusBuffer == NULL)
  879.     {
  880.       DAC960_Warning("Unable to expand Combined Status Buffer - Truncatingn",
  881.      Controller);
  882.       return false;
  883.     }
  884.   memcpy(NewStatusBuffer, Controller->CombinedStatusBuffer,
  885.  Controller->CombinedStatusBufferLength);
  886.   kfree(Controller->CombinedStatusBuffer);
  887.   Controller->CombinedStatusBuffer = NewStatusBuffer;
  888.   Controller->CombinedStatusBufferLength *= 2;
  889.   Controller->CurrentStatusBuffer =
  890.     &NewStatusBuffer[Controller->InitialStatusLength + 1];
  891.   return true;
  892. }
  893. /*
  894.   DAC960_Message prints Driver Messages.
  895. */
  896. static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
  897.    unsigned char *Format,
  898.    DAC960_Controller_T *Controller,
  899.    ...)
  900. {
  901.   static unsigned char Buffer[DAC960_LineBufferSize];
  902.   static boolean BeginningOfLine = true;
  903.   va_list Arguments;
  904.   int Length = 0;
  905.   va_start(Arguments, Controller);
  906.   Length = vsprintf(Buffer, Format, Arguments);
  907.   va_end(Arguments);
  908.   if (Controller == NULL)
  909.     printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
  910.    DAC960_ControllerCount, Buffer);
  911.   else if (MessageLevel == DAC960_AnnounceLevel ||
  912.    MessageLevel == DAC960_InfoLevel)
  913.     {
  914.       if (!Controller->ControllerInitialized)
  915. {
  916.   if (DAC960_CheckStatusBuffer(Controller, Length))
  917.     {
  918.       strcpy(&Controller->CombinedStatusBuffer
  919.   [Controller->InitialStatusLength],
  920.      Buffer);
  921.       Controller->InitialStatusLength += Length;
  922.       Controller->CurrentStatusBuffer =
  923. &Controller->CombinedStatusBuffer
  924.      [Controller->InitialStatusLength + 1];
  925.     }
  926.   if (MessageLevel == DAC960_AnnounceLevel)
  927.     {
  928.       static int AnnouncementLines = 0;
  929.       if (++AnnouncementLines <= 2)
  930. printk("%sDAC960: %s", DAC960_MessageLevelMap[MessageLevel],
  931.        Buffer);
  932.     }
  933.   else
  934.     {
  935.       if (BeginningOfLine)
  936. {
  937.   if (Buffer[0] != 'n' || Length > 1)
  938.     printk("%sDAC960#%d: %s",
  939.    DAC960_MessageLevelMap[MessageLevel],
  940.    Controller->ControllerNumber, Buffer);
  941. }
  942.       else printk("%s", Buffer);
  943.     }
  944. }
  945.       else if (DAC960_CheckStatusBuffer(Controller, Length))
  946. {
  947.   strcpy(&Controller->CurrentStatusBuffer[
  948.     Controller->CurrentStatusLength], Buffer);
  949.   Controller->CurrentStatusLength += Length;
  950. }
  951.     }
  952.   else if (MessageLevel == DAC960_ProgressLevel)
  953.     {
  954.       strcpy(Controller->ProgressBuffer, Buffer);
  955.       Controller->ProgressBufferLength = Length;
  956.       if (Controller->EphemeralProgressMessage)
  957. {
  958.   if (jiffies - Controller->LastProgressReportTime
  959.       >= DAC960_ProgressReportingInterval)
  960.     {
  961.       printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
  962.      Controller->ControllerNumber, Buffer);
  963.       Controller->LastProgressReportTime = jiffies;
  964.     }
  965. }
  966.       else printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
  967.   Controller->ControllerNumber, Buffer);
  968.     }
  969.   else if (MessageLevel == DAC960_UserCriticalLevel)
  970.     {
  971.       strcpy(&Controller->UserStatusBuffer[Controller->UserStatusLength],
  972.      Buffer);
  973.       Controller->UserStatusLength += Length;
  974.       if (Buffer[0] != 'n' || Length > 1)
  975. printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
  976.        Controller->ControllerNumber, Buffer);
  977.     }
  978.   else
  979.     {
  980.       if (BeginningOfLine)
  981. printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
  982.        Controller->ControllerNumber, Buffer);
  983.       else printk("%s", Buffer);
  984.     }
  985.   BeginningOfLine = (Buffer[Length-1] == 'n');
  986. }
  987. /*
  988.   DAC960_ParsePhysicalDevice parses spaces followed by a Physical Device
  989.   Channel:TargetID specification from a User Command string.  It updates
  990.   Channel and TargetID and returns true on success and false on failure.
  991. */
  992. static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
  993.   char *UserCommandString,
  994.   unsigned char *Channel,
  995.   unsigned char *TargetID)
  996. {
  997.   char *NewUserCommandString = UserCommandString;
  998.   unsigned long XChannel, XTargetID;
  999.   while (*UserCommandString == ' ') UserCommandString++;
  1000.   if (UserCommandString == NewUserCommandString)
  1001.     return false;
  1002.   XChannel = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
  1003.   if (NewUserCommandString == UserCommandString ||
  1004.       *NewUserCommandString != ':' ||
  1005.       XChannel >= Controller->Channels)
  1006.     return false;
  1007.   UserCommandString = ++NewUserCommandString;
  1008.   XTargetID = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
  1009.   if (NewUserCommandString == UserCommandString ||
  1010.       *NewUserCommandString != '' ||
  1011.       XTargetID >= Controller->Targets)
  1012.     return false;
  1013.   *Channel = XChannel;
  1014.   *TargetID = XTargetID;
  1015.   return true;
  1016. }
  1017. /*
  1018.   DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number
  1019.   specification from a User Command string.  It updates LogicalDriveNumber and
  1020.   returns true on success and false on failure.
  1021. */
  1022. static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
  1023. char *UserCommandString,
  1024. unsigned char *LogicalDriveNumber)
  1025. {
  1026.   char *NewUserCommandString = UserCommandString;
  1027.   unsigned long XLogicalDriveNumber;
  1028.   while (*UserCommandString == ' ') UserCommandString++;
  1029.   if (UserCommandString == NewUserCommandString)
  1030.     return false;
  1031.   XLogicalDriveNumber =
  1032.     simple_strtoul(UserCommandString, &NewUserCommandString, 10);
  1033.   if (NewUserCommandString == UserCommandString ||
  1034.       *NewUserCommandString != '' ||
  1035.       XLogicalDriveNumber > DAC960_MaxLogicalDrives - 1)
  1036.     return false;
  1037.   *LogicalDriveNumber = XLogicalDriveNumber;
  1038.   return true;
  1039. }
  1040. /*
  1041.   DAC960_V1_SetDeviceState sets the Device State for a Physical Device for
  1042.   DAC960 V1 Firmware Controllers.
  1043. */
  1044. static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller,
  1045.      DAC960_Command_T *Command,
  1046.      unsigned char Channel,
  1047.      unsigned char TargetID,
  1048.      DAC960_V1_PhysicalDeviceState_T
  1049.        DeviceState,
  1050.      const unsigned char *DeviceStateString)
  1051. {
  1052.   DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
  1053.   CommandMailbox->Type3D.CommandOpcode = DAC960_V1_StartDevice;
  1054.   CommandMailbox->Type3D.Channel = Channel;
  1055.   CommandMailbox->Type3D.TargetID = TargetID;
  1056.   CommandMailbox->Type3D.DeviceState = DeviceState;
  1057.   CommandMailbox->Type3D.Modifier = 0;
  1058.   DAC960_ExecuteCommand(Command);
  1059.   switch (Command->V1.CommandStatus)
  1060.     {
  1061.     case DAC960_V1_NormalCompletion:
  1062.       DAC960_UserCritical("%s of Physical Device %d:%d Succeededn", Controller,
  1063.   DeviceStateString, Channel, TargetID);
  1064.       break;
  1065.     case DAC960_V1_UnableToStartDevice:
  1066.       DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
  1067.   "Unable to Start Devicen", Controller,
  1068.   DeviceStateString, Channel, TargetID);
  1069.       break;
  1070.     case DAC960_V1_NoDeviceAtAddress:
  1071.       DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
  1072.   "No Device at Addressn", Controller,
  1073.   DeviceStateString, Channel, TargetID);
  1074.       break;
  1075.     case DAC960_V1_InvalidChannelOrTargetOrModifier:
  1076.       DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
  1077.   "Invalid Channel or Target or Modifiern",
  1078.   Controller, DeviceStateString, Channel, TargetID);
  1079.       break;
  1080.     case DAC960_V1_ChannelBusy:
  1081.       DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
  1082.   "Channel Busyn", Controller,
  1083.   DeviceStateString, Channel, TargetID);
  1084.       break;
  1085.     default:
  1086.       DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
  1087.   "Unexpected Status %04Xn", Controller,
  1088.   DeviceStateString, Channel, TargetID,
  1089.   Command->V1.CommandStatus);
  1090.       break;
  1091.     }
  1092. }
  1093. /*
  1094.   DAC960_V1_ExecuteUserCommand executes a User Command for DAC960 V1 Firmware
  1095.   Controllers.
  1096. */
  1097. static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
  1098.     unsigned char *UserCommand)
  1099. {
  1100.   DAC960_Command_T *Command;
  1101.   DAC960_V1_CommandMailbox_T *CommandMailbox;
  1102.   unsigned long flags;
  1103.   unsigned char Channel, TargetID, LogicalDriveNumber;
  1104.   spin_lock_irqsave(&Controller->queue_lock, flags);
  1105.   while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
  1106.     DAC960_WaitForCommand(Controller);
  1107.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  1108.   Controller->UserStatusLength = 0;
  1109.   DAC960_V1_ClearCommand(Command);
  1110.   Command->CommandType = DAC960_ImmediateCommand;
  1111.   CommandMailbox = &Command->V1.CommandMailbox;
  1112.   if (strcmp(UserCommand, "flush-cache") == 0)
  1113.     {
  1114.       CommandMailbox->Type3.CommandOpcode = DAC960_V1_Flush;
  1115.       DAC960_ExecuteCommand(Command);
  1116.       DAC960_UserCritical("Cache Flush Completedn", Controller);
  1117.     }
  1118.   else if (strncmp(UserCommand, "kill", 4) == 0 &&
  1119.    DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
  1120.       &Channel, &TargetID))
  1121.     {
  1122.       DAC960_V1_DeviceState_T *DeviceState =
  1123. &Controller->V1.DeviceState[Channel][TargetID];
  1124.       if (DeviceState->Present &&
  1125.   DeviceState->DeviceType == DAC960_V1_DiskType &&
  1126.   DeviceState->DeviceState != DAC960_V1_Device_Dead)
  1127. DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
  1128.  DAC960_V1_Device_Dead, "Kill");
  1129.       else DAC960_UserCritical("Kill of Physical Device %d:%d Illegaln",
  1130.        Controller, Channel, TargetID);
  1131.     }
  1132.   else if (strncmp(UserCommand, "make-online", 11) == 0 &&
  1133.    DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
  1134.       &Channel, &TargetID))
  1135.     {
  1136.       DAC960_V1_DeviceState_T *DeviceState =
  1137. &Controller->V1.DeviceState[Channel][TargetID];
  1138.       if (DeviceState->Present &&
  1139.   DeviceState->DeviceType == DAC960_V1_DiskType &&
  1140.   DeviceState->DeviceState == DAC960_V1_Device_Dead)
  1141. DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
  1142.  DAC960_V1_Device_Online, "Make Online");
  1143.       else DAC960_UserCritical("Make Online of Physical Device %d:%d Illegaln",
  1144.        Controller, Channel, TargetID);
  1145.     }
  1146.   else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
  1147.    DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
  1148.       &Channel, &TargetID))
  1149.     {
  1150.       DAC960_V1_DeviceState_T *DeviceState =
  1151. &Controller->V1.DeviceState[Channel][TargetID];
  1152.       if (DeviceState->Present &&
  1153.   DeviceState->DeviceType == DAC960_V1_DiskType &&
  1154.   DeviceState->DeviceState == DAC960_V1_Device_Dead)
  1155. DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
  1156.  DAC960_V1_Device_Standby, "Make Standby");
  1157.       else DAC960_UserCritical("Make Standby of Physical "
  1158.        "Device %d:%d Illegaln",
  1159.        Controller, Channel, TargetID);
  1160.     }
  1161.   else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
  1162.    DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
  1163.       &Channel, &TargetID))
  1164.     {
  1165.       CommandMailbox->Type3D.CommandOpcode = DAC960_V1_RebuildAsync;
  1166.       CommandMailbox->Type3D.Channel = Channel;
  1167.       CommandMailbox->Type3D.TargetID = TargetID;
  1168.       DAC960_ExecuteCommand(Command);
  1169.       switch (Command->V1.CommandStatus)
  1170. {
  1171. case DAC960_V1_NormalCompletion:
  1172.   DAC960_UserCritical("Rebuild of Physical Device %d:%d Initiatedn",
  1173.       Controller, Channel, TargetID);
  1174.   break;
  1175. case DAC960_V1_AttemptToRebuildOnlineDrive:
  1176.   DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
  1177.       "Attempt to Rebuild Online or "
  1178.       "Unresponsive Driven",
  1179.       Controller, Channel, TargetID);
  1180.   break;
  1181. case DAC960_V1_NewDiskFailedDuringRebuild:
  1182.   DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
  1183.       "New Disk Failed During Rebuildn",
  1184.       Controller, Channel, TargetID);
  1185.   break;
  1186. case DAC960_V1_InvalidDeviceAddress:
  1187.   DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
  1188.       "Invalid Device Addressn",
  1189.       Controller, Channel, TargetID);
  1190.   break;
  1191. case DAC960_V1_RebuildOrCheckAlreadyInProgress:
  1192.   DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
  1193.       "Rebuild or Consistency Check Already "
  1194.       "in Progressn", Controller, Channel, TargetID);
  1195.   break;
  1196. default:
  1197.   DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
  1198.       "Unexpected Status %04Xn", Controller,
  1199.       Channel, TargetID, Command->V1.CommandStatus);
  1200.   break;
  1201. }
  1202.     }
  1203.   else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
  1204.    DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
  1205.     &LogicalDriveNumber))
  1206.     {
  1207.       CommandMailbox->Type3C.CommandOpcode = DAC960_V1_CheckConsistencyAsync;
  1208.       CommandMailbox->Type3C.LogicalDriveNumber = LogicalDriveNumber;
  1209.       CommandMailbox->Type3C.AutoRestore = true;
  1210.       DAC960_ExecuteCommand(Command);
  1211.       switch (Command->V1.CommandStatus)
  1212. {
  1213. case DAC960_V1_NormalCompletion:
  1214.   DAC960_UserCritical("Consistency Check of Logical Drive %d "
  1215.       "(/dev/rd/c%dd%d) Initiatedn",
  1216.       Controller, LogicalDriveNumber,
  1217.       Controller->ControllerNumber,
  1218.       LogicalDriveNumber);
  1219.   break;
  1220. case DAC960_V1_DependentDiskIsDead:
  1221.   DAC960_UserCritical("Consistency Check of Logical Drive %d "
  1222.       "(/dev/rd/c%dd%d) Failed - "
  1223.       "Dependent Physical Device is DEADn",
  1224.       Controller, LogicalDriveNumber,
  1225.       Controller->ControllerNumber,
  1226.       LogicalDriveNumber);
  1227.   break;
  1228. case DAC960_V1_InvalidOrNonredundantLogicalDrive:
  1229.   DAC960_UserCritical("Consistency Check of Logical Drive %d "
  1230.       "(/dev/rd/c%dd%d) Failed - "
  1231.       "Invalid or Nonredundant Logical Driven",
  1232.       Controller, LogicalDriveNumber,
  1233.       Controller->ControllerNumber,
  1234.       LogicalDriveNumber);
  1235.   break;
  1236. case DAC960_V1_RebuildOrCheckAlreadyInProgress:
  1237.   DAC960_UserCritical("Consistency Check of Logical Drive %d "
  1238.       "(/dev/rd/c%dd%d) Failed - Rebuild or "
  1239.       "Consistency Check Already in Progressn",
  1240.       Controller, LogicalDriveNumber,
  1241.       Controller->ControllerNumber,
  1242.       LogicalDriveNumber);
  1243.   break;
  1244. default:
  1245.   DAC960_UserCritical("Consistency Check of Logical Drive %d "
  1246.       "(/dev/rd/c%dd%d) Failed - "
  1247.       "Unexpected Status %04Xn",
  1248.       Controller, LogicalDriveNumber,
  1249.       Controller->ControllerNumber,
  1250.       LogicalDriveNumber, Command->V1.CommandStatus);
  1251.   break;
  1252. }
  1253.     }
  1254.   else if (strcmp(UserCommand, "cancel-rebuild") == 0 ||
  1255.    strcmp(UserCommand, "cancel-consistency-check") == 0)
  1256.     {
  1257.       /*
  1258.         the OldRebuildRateConstant is never actually used
  1259.         once its value is retrieved from the controller.
  1260.        */
  1261.       unsigned char *OldRebuildRateConstant;
  1262.       dma_addr_t OldRebuildRateConstantDMA;
  1263.       OldRebuildRateConstant = pci_alloc_consistent( Controller->PCIDevice,
  1264. sizeof(char), &OldRebuildRateConstantDMA);
  1265.       if (OldRebuildRateConstant == NULL) {
  1266.          DAC960_UserCritical("Cancellation of Rebuild or "
  1267.      "Consistency Check Failed - "
  1268.      "Out of Memory",
  1269.                              Controller);
  1270.  goto failure;
  1271.       }
  1272.       CommandMailbox->Type3R.CommandOpcode = DAC960_V1_RebuildControl;
  1273.       CommandMailbox->Type3R.RebuildRateConstant = 0xFF;
  1274.       CommandMailbox->Type3R.BusAddress = OldRebuildRateConstantDMA;
  1275.       DAC960_ExecuteCommand(Command);
  1276.       switch (Command->V1.CommandStatus)
  1277. {
  1278. case DAC960_V1_NormalCompletion:
  1279.   DAC960_UserCritical("Rebuild or Consistency Check Cancelledn",
  1280.       Controller);
  1281.   break;
  1282. default:
  1283.   DAC960_UserCritical("Cancellation of Rebuild or "
  1284.       "Consistency Check Failed - "
  1285.       "Unexpected Status %04Xn",
  1286.       Controller, Command->V1.CommandStatus);
  1287.   break;
  1288. }
  1289. failure:
  1290.    pci_free_consistent(Controller->PCIDevice, sizeof(char),
  1291. OldRebuildRateConstant, OldRebuildRateConstantDMA);
  1292.     }
  1293.   else DAC960_UserCritical("Illegal User Command: '%s'n",
  1294.    Controller, UserCommand);
  1295.   spin_lock_irqsave(&Controller->queue_lock, flags);
  1296.   DAC960_DeallocateCommand(Command);
  1297.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  1298.   return true;
  1299. }
  1300. /*
  1301.   DAC960_V2_TranslatePhysicalDevice translates a Physical Device Channel and
  1302.   TargetID into a Logical Device.  It returns true on success and false
  1303.   on failure.
  1304. */
  1305. static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
  1306.  unsigned char Channel,
  1307.  unsigned char TargetID,
  1308.  unsigned short
  1309.    *LogicalDeviceNumber)
  1310. {
  1311.   DAC960_V2_CommandMailbox_T SavedCommandMailbox, *CommandMailbox;
  1312.   DAC960_Controller_T *Controller =  Command->Controller;
  1313.   CommandMailbox = &Command->V2.CommandMailbox;
  1314.   memcpy(&SavedCommandMailbox, CommandMailbox,
  1315.  sizeof(DAC960_V2_CommandMailbox_T));
  1316.   CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
  1317.   CommandMailbox->PhysicalDeviceInfo.CommandControlBits
  1318.     .DataTransferControllerToHost = true;
  1319.   CommandMailbox->PhysicalDeviceInfo.CommandControlBits
  1320.     .NoAutoRequestSense = true;
  1321.   CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
  1322.     sizeof(DAC960_V2_PhysicalToLogicalDevice_T);
  1323.   CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
  1324.   CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
  1325.   CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
  1326.     DAC960_V2_TranslatePhysicalToLogicalDevice;
  1327.   CommandMailbox->Common.DataTransferMemoryAddress
  1328. .ScatterGatherSegments[0]
  1329. .SegmentDataPointer =
  1330.      Controller->V2.PhysicalToLogicalDeviceDMA;
  1331.   CommandMailbox->Common.DataTransferMemoryAddress
  1332. .ScatterGatherSegments[0]
  1333. .SegmentByteCount =
  1334.      CommandMailbox->Common.DataTransferSize;
  1335.   DAC960_ExecuteCommand(Command);
  1336.   *LogicalDeviceNumber = Controller->V2.PhysicalToLogicalDevice->LogicalDeviceNumber;
  1337.   memcpy(CommandMailbox, &SavedCommandMailbox,
  1338.  sizeof(DAC960_V2_CommandMailbox_T));
  1339.   return (Command->V2.CommandStatus == DAC960_V2_NormalCompletion);
  1340. }
  1341. /*
  1342.   DAC960_V2_ExecuteUserCommand executes a User Command for DAC960 V2 Firmware
  1343.   Controllers.
  1344. */
  1345. static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
  1346.     unsigned char *UserCommand)
  1347. {
  1348.   DAC960_Command_T *Command;
  1349.   DAC960_V2_CommandMailbox_T *CommandMailbox;
  1350.   unsigned long flags;
  1351.   unsigned char Channel, TargetID, LogicalDriveNumber;
  1352.   unsigned short LogicalDeviceNumber;
  1353.   spin_lock_irqsave(&Controller->queue_lock, flags);
  1354.   while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
  1355.     DAC960_WaitForCommand(Controller);
  1356.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  1357.   Controller->UserStatusLength = 0;
  1358.   DAC960_V2_ClearCommand(Command);
  1359.   Command->CommandType = DAC960_ImmediateCommand;
  1360.   CommandMailbox = &Command->V2.CommandMailbox;
  1361.   CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
  1362.   CommandMailbox->Common.CommandControlBits.DataTransferControllerToHost = true;
  1363.   CommandMailbox->Common.CommandControlBits.NoAutoRequestSense = true;
  1364.   if (strcmp(UserCommand, "flush-cache") == 0)
  1365.     {
  1366.       CommandMailbox->DeviceOperation.IOCTL_Opcode = DAC960_V2_PauseDevice;
  1367.       CommandMailbox->DeviceOperation.OperationDevice =
  1368. DAC960_V2_RAID_Controller;
  1369.       DAC960_ExecuteCommand(Command);
  1370.       DAC960_UserCritical("Cache Flush Completedn", Controller);
  1371.     }
  1372.   else if (strncmp(UserCommand, "kill", 4) == 0 &&
  1373.    DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
  1374.       &Channel, &TargetID) &&
  1375.    DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
  1376.      &LogicalDeviceNumber))
  1377.     {
  1378.       CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
  1379. LogicalDeviceNumber;
  1380.       CommandMailbox->SetDeviceState.IOCTL_Opcode =
  1381. DAC960_V2_SetDeviceState;
  1382.       CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
  1383. DAC960_V2_Device_Dead;
  1384.       DAC960_ExecuteCommand(Command);
  1385.       DAC960_UserCritical("Kill of Physical Device %d:%d %sn",
  1386.   Controller, Channel, TargetID,
  1387.   (Command->V2.CommandStatus
  1388.    == DAC960_V2_NormalCompletion
  1389.    ? "Succeeded" : "Failed"));
  1390.     }
  1391.   else if (strncmp(UserCommand, "make-online", 11) == 0 &&
  1392.    DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
  1393.       &Channel, &TargetID) &&
  1394.    DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
  1395.      &LogicalDeviceNumber))
  1396.     {
  1397.       CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
  1398. LogicalDeviceNumber;
  1399.       CommandMailbox->SetDeviceState.IOCTL_Opcode =
  1400. DAC960_V2_SetDeviceState;
  1401.       CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
  1402. DAC960_V2_Device_Online;
  1403.       DAC960_ExecuteCommand(Command);
  1404.       DAC960_UserCritical("Make Online of Physical Device %d:%d %sn",
  1405.   Controller, Channel, TargetID,
  1406.   (Command->V2.CommandStatus
  1407.    == DAC960_V2_NormalCompletion
  1408.    ? "Succeeded" : "Failed"));
  1409.     }
  1410.   else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
  1411.    DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
  1412.       &Channel, &TargetID) &&
  1413.    DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
  1414.      &LogicalDeviceNumber))
  1415.     {
  1416.       CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
  1417. LogicalDeviceNumber;
  1418.       CommandMailbox->SetDeviceState.IOCTL_Opcode =
  1419. DAC960_V2_SetDeviceState;
  1420.       CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
  1421. DAC960_V2_Device_Standby;
  1422.       DAC960_ExecuteCommand(Command);
  1423.       DAC960_UserCritical("Make Standby of Physical Device %d:%d %sn",
  1424.   Controller, Channel, TargetID,
  1425.   (Command->V2.CommandStatus
  1426.    == DAC960_V2_NormalCompletion
  1427.    ? "Succeeded" : "Failed"));
  1428.     }
  1429.   else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
  1430.    DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
  1431.       &Channel, &TargetID) &&
  1432.    DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
  1433.      &LogicalDeviceNumber))
  1434.     {
  1435.       CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
  1436. LogicalDeviceNumber;
  1437.       CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
  1438. DAC960_V2_RebuildDeviceStart;
  1439.       DAC960_ExecuteCommand(Command);
  1440.       DAC960_UserCritical("Rebuild of Physical Device %d:%d %sn",
  1441.   Controller, Channel, TargetID,
  1442.   (Command->V2.CommandStatus
  1443.    == DAC960_V2_NormalCompletion
  1444.    ? "Initiated" : "Not Initiated"));
  1445.     }
  1446.   else if (strncmp(UserCommand, "cancel-rebuild", 14) == 0 &&
  1447.    DAC960_ParsePhysicalDevice(Controller, &UserCommand[14],
  1448.       &Channel, &TargetID) &&
  1449.    DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
  1450.      &LogicalDeviceNumber))
  1451.     {
  1452.       CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
  1453. LogicalDeviceNumber;
  1454.       CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
  1455. DAC960_V2_RebuildDeviceStop;
  1456.       DAC960_ExecuteCommand(Command);
  1457.       DAC960_UserCritical("Rebuild of Physical Device %d:%d %sn",
  1458.   Controller, Channel, TargetID,
  1459.   (Command->V2.CommandStatus
  1460.    == DAC960_V2_NormalCompletion
  1461.    ? "Cancelled" : "Not Cancelled"));
  1462.     }
  1463.   else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
  1464.    DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
  1465.     &LogicalDriveNumber))
  1466.     {
  1467.       CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
  1468. LogicalDriveNumber;
  1469.       CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
  1470. DAC960_V2_ConsistencyCheckStart;
  1471.       CommandMailbox->ConsistencyCheck.RestoreConsistency = true;
  1472.       CommandMailbox->ConsistencyCheck.InitializedAreaOnly = false;
  1473.       DAC960_ExecuteCommand(Command);
  1474.       DAC960_UserCritical("Consistency Check of Logical Drive %d "
  1475.   "(/dev/rd/c%dd%d) %sn",
  1476.   Controller, LogicalDriveNumber,
  1477.   Controller->ControllerNumber,
  1478.   LogicalDriveNumber,
  1479.   (Command->V2.CommandStatus
  1480.    == DAC960_V2_NormalCompletion
  1481.    ? "Initiated" : "Not Initiated"));
  1482.     }
  1483.   else if (strncmp(UserCommand, "cancel-consistency-check", 24) == 0 &&
  1484.    DAC960_ParseLogicalDrive(Controller, &UserCommand[24],
  1485.     &LogicalDriveNumber))
  1486.     {
  1487.       CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
  1488. LogicalDriveNumber;
  1489.       CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
  1490. DAC960_V2_ConsistencyCheckStop;
  1491.       DAC960_ExecuteCommand(Command);
  1492.       DAC960_UserCritical("Consistency Check of Logical Drive %d "
  1493.   "(/dev/rd/c%dd%d) %sn",
  1494.   Controller, LogicalDriveNumber,
  1495.   Controller->ControllerNumber,
  1496.   LogicalDriveNumber,
  1497.   (Command->V2.CommandStatus
  1498.    == DAC960_V2_NormalCompletion
  1499.    ? "Cancelled" : "Not Cancelled"));
  1500.     }
  1501.   else if (strcmp(UserCommand, "perform-discovery") == 0)
  1502.     {
  1503.       CommandMailbox->Common.IOCTL_Opcode = DAC960_V2_StartDiscovery;
  1504.       DAC960_ExecuteCommand(Command);
  1505.       DAC960_UserCritical("Discovery %sn", Controller,
  1506.   (Command->V2.CommandStatus
  1507.    == DAC960_V2_NormalCompletion
  1508.    ? "Initiated" : "Not Initiated"));
  1509.       if (Command->V2.CommandStatus == DAC960_V2_NormalCompletion)
  1510. {
  1511.   CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
  1512.   CommandMailbox->ControllerInfo.CommandControlBits
  1513. .DataTransferControllerToHost = true;
  1514.   CommandMailbox->ControllerInfo.CommandControlBits
  1515. .NoAutoRequestSense = true;
  1516.   CommandMailbox->ControllerInfo.DataTransferSize =
  1517.     sizeof(DAC960_V2_ControllerInfo_T);
  1518.   CommandMailbox->ControllerInfo.ControllerNumber = 0;
  1519.   CommandMailbox->ControllerInfo.IOCTL_Opcode =
  1520.     DAC960_V2_GetControllerInfo;
  1521.   /*
  1522.    * How does this NOT race with the queued Monitoring
  1523.    * usage of this structure?
  1524.    */
  1525.   CommandMailbox->ControllerInfo.DataTransferMemoryAddress
  1526. .ScatterGatherSegments[0]
  1527. .SegmentDataPointer =
  1528.     Controller->V2.NewControllerInformationDMA;
  1529.   CommandMailbox->ControllerInfo.DataTransferMemoryAddress
  1530. .ScatterGatherSegments[0]
  1531. .SegmentByteCount =
  1532.     CommandMailbox->ControllerInfo.DataTransferSize;
  1533.   DAC960_ExecuteCommand(Command);
  1534.   while (Controller->V2.NewControllerInformation->PhysicalScanActive)
  1535.     {
  1536.       DAC960_ExecuteCommand(Command);
  1537.       sleep_on_timeout(&Controller->CommandWaitQueue, HZ);
  1538.     }
  1539.   DAC960_UserCritical("Discovery Completedn", Controller);
  1540.   }
  1541.     }
  1542.   else if (strcmp(UserCommand, "suppress-enclosure-messages") == 0)
  1543.     Controller->SuppressEnclosureMessages = true;
  1544.   else DAC960_UserCritical("Illegal User Command: '%s'n",
  1545.    Controller, UserCommand);
  1546.   spin_lock_irqsave(&Controller->queue_lock, flags);
  1547.   DAC960_DeallocateCommand(Command);
  1548.   spin_unlock_irqrestore(&Controller->queue_lock, flags);
  1549.   return true;
  1550. }
  1551. /*
  1552.   DAC960_ProcReadStatus implements reading /proc/rd/status.
  1553. */
  1554. static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
  1555.  int Count, int *EOF, void *Data)
  1556. {
  1557.   unsigned char *StatusMessage = "OKn";
  1558.   int ControllerNumber, BytesAvailable;
  1559.   for (ControllerNumber = 0;
  1560.        ControllerNumber < DAC960_ControllerCount;
  1561.        ControllerNumber++)
  1562.     {
  1563.       DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
  1564.       if (Controller == NULL) continue;
  1565.       if (Controller->MonitoringAlertMode)
  1566. {
  1567.   StatusMessage = "ALERTn";
  1568.   break;
  1569. }
  1570.     }
  1571.   BytesAvailable = strlen(StatusMessage) - Offset;
  1572.   if (Count >= BytesAvailable)
  1573.     {
  1574.       Count = BytesAvailable;
  1575.       *EOF = true;
  1576.     }
  1577.   if (Count <= 0) return 0;
  1578.   *Start = Page;
  1579.   memcpy(Page, &StatusMessage[Offset], Count);
  1580.   return Count;
  1581. }
  1582. /*
  1583.   DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status.
  1584. */
  1585. static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset,
  1586. int Count, int *EOF, void *Data)
  1587. {
  1588.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
  1589.   int BytesAvailable = Controller->InitialStatusLength - Offset;
  1590.   if (Count >= BytesAvailable)
  1591.     {
  1592.       Count = BytesAvailable;
  1593.       *EOF = true;
  1594.     }
  1595.   if (Count <= 0) return 0;
  1596.   *Start = Page;
  1597.   memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
  1598.   return Count;
  1599. }
  1600. /*
  1601.   DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status.
  1602. */
  1603. static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
  1604. int Count, int *EOF, void *Data)
  1605. {
  1606.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
  1607.   unsigned char *StatusMessage =
  1608.     "No Rebuild or Consistency Check in Progressn";
  1609.   int ProgressMessageLength = strlen(StatusMessage);
  1610.   int BytesAvailable;
  1611.   if (jiffies != Controller->LastCurrentStatusTime)
  1612.     {
  1613.       Controller->CurrentStatusLength = 0;
  1614.       DAC960_AnnounceDriver(Controller);
  1615.       DAC960_ReportControllerConfiguration(Controller);
  1616.       DAC960_ReportDeviceConfiguration(Controller);
  1617.       if (Controller->ProgressBufferLength > 0)
  1618. ProgressMessageLength = Controller->ProgressBufferLength;
  1619.       if (DAC960_CheckStatusBuffer(Controller, 2 + ProgressMessageLength))
  1620. {
  1621.   unsigned char *CurrentStatusBuffer = Controller->CurrentStatusBuffer;
  1622.   CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
  1623.   CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
  1624.   if (Controller->ProgressBufferLength > 0)
  1625.     strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
  1626.    Controller->ProgressBuffer);
  1627.   else
  1628.     strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
  1629.    StatusMessage);
  1630.   Controller->CurrentStatusLength += ProgressMessageLength;
  1631. }
  1632.       Controller->LastCurrentStatusTime = jiffies;
  1633.     }
  1634.   BytesAvailable = Controller->CurrentStatusLength - Offset;
  1635.   if (Count >= BytesAvailable)
  1636.     {
  1637.       Count = BytesAvailable;
  1638.       *EOF = true;
  1639.     }
  1640.   if (Count <= 0) return 0;
  1641.   *Start = Page;
  1642.   memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count);
  1643.   return Count;
  1644. }
  1645. /*
  1646.   DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command.
  1647. */
  1648. static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset,
  1649.       int Count, int *EOF, void *Data)
  1650. {
  1651.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
  1652.   int BytesAvailable = Controller->UserStatusLength - Offset;
  1653.   if (Count >= BytesAvailable)
  1654.     {
  1655.       Count = BytesAvailable;
  1656.       *EOF = true;
  1657.     }
  1658.   if (Count <= 0) return 0;
  1659.   *Start = Page;
  1660.   memcpy(Page, &Controller->UserStatusBuffer[Offset], Count);
  1661.   return Count;
  1662. }
  1663. /*
  1664.   DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
  1665. */
  1666. static int DAC960_ProcWriteUserCommand(struct file *file,
  1667.        const char __user *Buffer,
  1668.        unsigned long Count, void *Data)
  1669. {
  1670.   DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
  1671.   unsigned char CommandBuffer[80];
  1672.   int Length;
  1673.   if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
  1674.   if (copy_from_user(CommandBuffer, Buffer, Count)) return -EFAULT;
  1675.   CommandBuffer[Count] = '';
  1676.   Length = strlen(CommandBuffer);
  1677.   if (CommandBuffer[Length-1] == 'n')
  1678.     CommandBuffer[--Length] = '';
  1679.   if (Controller->FirmwareType == DAC960_V1_Controller)
  1680.     return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer)
  1681.     ? Count : -EBUSY);
  1682.   else
  1683.     return (DAC960_V2_ExecuteUserCommand(Controller, CommandBuffer)
  1684.     ? Count : -EBUSY);
  1685. }
  1686. /*
  1687.   DAC960_CreateProcEntries creates the /proc/rd/... entries for the
  1688.   DAC960 Driver.
  1689. */
  1690. static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller)
  1691. {
  1692. struct proc_dir_entry *StatusProcEntry;
  1693. struct proc_dir_entry *ControllerProcEntry;
  1694. struct proc_dir_entry *UserCommandProcEntry;
  1695. if (DAC960_ProcDirectoryEntry == NULL) {
  1696.    DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
  1697.    StatusProcEntry = create_proc_read_entry("status", 0,
  1698.    DAC960_ProcDirectoryEntry,
  1699.    DAC960_ProcReadStatus, NULL);
  1700. }
  1701.       sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
  1702.       ControllerProcEntry = proc_mkdir(Controller->ControllerName,
  1703.        DAC960_ProcDirectoryEntry);
  1704.       create_proc_read_entry("initial_status", 0, ControllerProcEntry,
  1705.      DAC960_ProcReadInitialStatus, Controller);
  1706.       create_proc_read_entry("current_status", 0, ControllerProcEntry,
  1707.      DAC960_ProcReadCurrentStatus, Controller);
  1708.       UserCommandProcEntry =
  1709. create_proc_read_entry("user_command", S_IWUSR | S_IRUSR,
  1710.        ControllerProcEntry, DAC960_ProcReadUserCommand,
  1711.        Controller);
  1712.       UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
  1713.       Controller->ControllerProcEntry = ControllerProcEntry;
  1714. }
  1715. /*
  1716.   DAC960_DestroyProcEntries destroys the /proc/rd/... entries for the
  1717.   DAC960 Driver.
  1718. */
  1719. static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller)
  1720. {
  1721.       if (Controller->ControllerProcEntry == NULL)
  1722.       return;
  1723.       remove_proc_entry("initial_status", Controller->ControllerProcEntry);
  1724.       remove_proc_entry("current_status", Controller->ControllerProcEntry);
  1725.       remove_proc_entry("user_command", Controller->ControllerProcEntry);
  1726.       remove_proc_entry(Controller->ControllerName, DAC960_ProcDirectoryEntry);
  1727.       Controller->ControllerProcEntry = NULL;
  1728. }
  1729. #ifdef DAC960_GAM_MINOR
  1730. /*
  1731.  * DAC960_gam_ioctl is the ioctl function for performing RAID operations.
  1732. */
  1733. static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
  1734.     unsigned int Request, unsigned long Argument)
  1735. {
  1736.   int ErrorCode = 0;
  1737.   if (!capable(CAP_SYS_ADMIN)) return -EACCES;
  1738.   switch (Request)
  1739.     {
  1740.     case DAC960_IOCTL_GET_CONTROLLER_COUNT:
  1741.       return DAC960_ControllerCount;
  1742.     case DAC960_IOCTL_GET_CONTROLLER_INFO:
  1743.       {
  1744. DAC960_ControllerInfo_T __user *UserSpaceControllerInfo =
  1745.   (DAC960_ControllerInfo_T __user *) Argument;
  1746. DAC960_ControllerInfo_T ControllerInfo;
  1747. DAC960_Controller_T *Controller;
  1748. int ControllerNumber;
  1749. if (UserSpaceControllerInfo == NULL) return -EINVAL;
  1750. ErrorCode = get_user(ControllerNumber,
  1751.      &UserSpaceControllerInfo->ControllerNumber);
  1752. if (ErrorCode != 0) return ErrorCode;
  1753. if (ControllerNumber < 0 ||
  1754.     ControllerNumber > DAC960_ControllerCount - 1)
  1755.   return -ENXIO;
  1756. Controller = DAC960_Controllers[ControllerNumber];
  1757. if (Controller == NULL) return -ENXIO;
  1758. memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
  1759. ControllerInfo.ControllerNumber = ControllerNumber;
  1760. ControllerInfo.FirmwareType = Controller->FirmwareType;
  1761. ControllerInfo.Channels = Controller->Channels;
  1762. ControllerInfo.Targets = Controller->Targets;
  1763. ControllerInfo.PCI_Bus = Controller->Bus;
  1764. ControllerInfo.PCI_Device = Controller->Device;
  1765. ControllerInfo.PCI_Function = Controller->Function;
  1766. ControllerInfo.IRQ_Channel = Controller->IRQ_Channel;
  1767. ControllerInfo.PCI_Address = Controller->PCI_Address;
  1768. strcpy(ControllerInfo.ModelName, Controller->ModelName);
  1769. strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
  1770. return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
  1771.      sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0);
  1772.       }
  1773.     case DAC960_IOCTL_V1_EXECUTE_COMMAND:
  1774.       {
  1775. DAC960_V1_UserCommand_T __user *UserSpaceUserCommand =
  1776.   (DAC960_V1_UserCommand_T __user *) Argument;
  1777. DAC960_V1_UserCommand_T UserCommand;
  1778. DAC960_Controller_T *Controller;
  1779. DAC960_Command_T *Command = NULL;
  1780. DAC960_V1_CommandOpcode_T CommandOpcode;
  1781. DAC960_V1_CommandStatus_T CommandStatus;
  1782. DAC960_V1_DCDB_T DCDB;
  1783. DAC960_V1_DCDB_T *DCDB_IOBUF = NULL;
  1784. dma_addr_t DCDB_IOBUFDMA;
  1785. unsigned long flags;
  1786. int ControllerNumber, DataTransferLength;
  1787. unsigned char *DataTransferBuffer = NULL;
  1788. dma_addr_t DataTransferBufferDMA;
  1789. if (UserSpaceUserCommand == NULL) return -EINVAL;
  1790. if (copy_from_user(&UserCommand, UserSpaceUserCommand,
  1791.    sizeof(DAC960_V1_UserCommand_T))) {
  1792. ErrorCode = -EFAULT;
  1793. goto Failure1a;
  1794. }
  1795. ControllerNumber = UserCommand.ControllerNumber;
  1796. if (ControllerNumber < 0 ||
  1797.     ControllerNumber > DAC960_ControllerCount - 1)
  1798.   return -ENXIO;
  1799. Controller = DAC960_Controllers[ControllerNumber];
  1800. if (Controller == NULL) return -ENXIO;
  1801. if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
  1802. CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
  1803. DataTransferLength = UserCommand.DataTransferLength;
  1804. if (CommandOpcode & 0x80) return -EINVAL;
  1805. if (CommandOpcode == DAC960_V1_DCDB)
  1806.   {
  1807.     if (copy_from_user(&DCDB, UserCommand.DCDB,
  1808.        sizeof(DAC960_V1_DCDB_T))) {
  1809. ErrorCode = -EFAULT;
  1810. goto Failure1a;
  1811.     }
  1812.     if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL;
  1813.     if (!((DataTransferLength == 0 &&
  1814.    DCDB.Direction
  1815.    == DAC960_V1_DCDB_NoDataTransfer) ||
  1816.   (DataTransferLength > 0 &&
  1817.    DCDB.Direction
  1818.    == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
  1819.   (DataTransferLength < 0 &&
  1820.    DCDB.Direction
  1821.    == DAC960_V1_DCDB_DataTransferSystemToDevice)))
  1822.       return -EINVAL;
  1823.     if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
  1824. != abs(DataTransferLength))
  1825.       return -EINVAL;
  1826.     DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice,
  1827. sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA);
  1828.     if (DCDB_IOBUF == NULL)
  1829. return -ENOMEM;
  1830.   }
  1831. if (DataTransferLength > 0)
  1832.   {
  1833.     DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
  1834. DataTransferLength, &DataTransferBufferDMA);
  1835.     if (DataTransferBuffer == NULL) {
  1836. ErrorCode = -ENOMEM;
  1837. goto Failure1;
  1838.     }
  1839.     memset(DataTransferBuffer, 0, DataTransferLength);
  1840.   }
  1841. else if (DataTransferLength < 0)
  1842.   {
  1843.     DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
  1844. -DataTransferLength, &DataTransferBufferDMA);
  1845.     if (DataTransferBuffer == NULL) {
  1846. ErrorCode = -ENOMEM;
  1847. goto Failure1;
  1848.     }
  1849.     if (copy_from_user(DataTransferBuffer,
  1850.        UserCommand.DataTransferBuffer,
  1851.        -DataTransferLength)) {
  1852. ErrorCode = -EFAULT;
  1853. goto Failure1;
  1854.     }
  1855.   }
  1856. if (CommandOpcode == DAC960_V1_DCDB)
  1857.   {
  1858.     spin_lock_irqsave(&Controller->queue_lock, flags);
  1859.     while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
  1860.       DAC960_WaitForCommand(Controller);
  1861.     while (Controller->V1.DirectCommandActive[DCDB.Channel]
  1862.      [DCDB.TargetID])
  1863.       {
  1864. spin_unlock_irq(&Controller->queue_lock);
  1865. __wait_event(Controller->CommandWaitQueue,
  1866.      !Controller->V1.DirectCommandActive
  1867.      [DCDB.Channel][DCDB.TargetID]);
  1868. spin_lock_irq(&Controller->queue_lock);
  1869.       }
  1870.     Controller->V1.DirectCommandActive[DCDB.Channel]
  1871.       [DCDB.TargetID] = true;
  1872.     spin_unlock_irqrestore(&Controller->queue_lock, flags);
  1873.     DAC960_V1_ClearCommand(Command);
  1874.     Command->CommandType = DAC960_ImmediateCommand;
  1875.     memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
  1876.    sizeof(DAC960_V1_CommandMailbox_T));
  1877.     Command->V1.CommandMailbox.Type3.BusAddress = DCDB_IOBUFDMA;
  1878.     DCDB.BusAddress = DataTransferBufferDMA;
  1879.     memcpy(DCDB_IOBUF, &DCDB, sizeof(DAC960_V1_DCDB_T));
  1880.   }
  1881. else
  1882.   {
  1883.     spin_lock_irqsave(&Controller->queue_lock, flags);
  1884.     while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
  1885.       DAC960_WaitForCommand(Controller);
  1886.     spin_unlock_irqrestore(&Controller->queue_lock, flags);
  1887.     DAC960_V1_ClearCommand(Command);
  1888.     Command->CommandType = DAC960_ImmediateCommand;
  1889.     memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
  1890.    sizeof(DAC960_V1_CommandMailbox_T));
  1891.     if (DataTransferBuffer != NULL)
  1892.       Command->V1.CommandMailbox.Type3.BusAddress =
  1893. DataTransferBufferDMA;
  1894.   }
  1895. DAC960_ExecuteCommand(Command);
  1896. CommandStatus = Command->V1.CommandStatus;
  1897. spin_lock_irqsave(&Controller->queue_lock, flags);
  1898. DAC960_DeallocateCommand(Command);
  1899. spin_unlock_irqrestore(&Controller->queue_lock, flags);
  1900. if (DataTransferLength > 0)
  1901.   {
  1902.     if (copy_to_user(UserCommand.DataTransferBuffer,
  1903.      DataTransferBuffer, DataTransferLength)) {
  1904. ErrorCode = -EFAULT;
  1905. goto Failure1;
  1906.             }
  1907.   }
  1908. if (CommandOpcode == DAC960_V1_DCDB)
  1909.   {
  1910.     /*
  1911.       I don't believe Target or Channel in the DCDB_IOBUF
  1912.       should be any different from the contents of DCDB.
  1913.      */
  1914.     Controller->V1.DirectCommandActive[DCDB.Channel]
  1915.       [DCDB.TargetID] = false;
  1916.     if (copy_to_user(UserCommand.DCDB, DCDB_IOBUF,
  1917.      sizeof(DAC960_V1_DCDB_T))) {
  1918. ErrorCode = -EFAULT;
  1919. goto Failure1;
  1920.     }
  1921.   }
  1922. ErrorCode = CommandStatus;
  1923.       Failure1:
  1924. if (DataTransferBuffer != NULL)
  1925.   pci_free_consistent(Controller->PCIDevice, abs(DataTransferLength),
  1926. DataTransferBuffer, DataTransferBufferDMA);
  1927. if (DCDB_IOBUF != NULL)
  1928.   pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T),
  1929. DCDB_IOBUF, DCDB_IOBUFDMA);
  1930.       Failure1a:
  1931. return ErrorCode;
  1932.       }
  1933.     case DAC960_IOCTL_V2_EXECUTE_COMMAND:
  1934.       {
  1935. DAC960_V2_UserCommand_T __user *UserSpaceUserCommand =
  1936.   (DAC960_V2_UserCommand_T __user *) Argument;
  1937. DAC960_V2_UserCommand_T UserCommand;
  1938. DAC960_Controller_T *Controller;
  1939. DAC960_Command_T *Command = NULL;
  1940. DAC960_V2_CommandMailbox_T *CommandMailbox;
  1941. DAC960_V2_CommandStatus_T CommandStatus;
  1942. unsigned long flags;
  1943. int ControllerNumber, DataTransferLength;
  1944. int DataTransferResidue, RequestSenseLength;
  1945. unsigned char *DataTransferBuffer = NULL;
  1946. dma_addr_t DataTransferBufferDMA;
  1947. unsigned char *RequestSenseBuffer = NULL;
  1948. dma_addr_t RequestSenseBufferDMA;
  1949. if (UserSpaceUserCommand == NULL) return -EINVAL;
  1950. if (copy_from_user(&UserCommand, UserSpaceUserCommand,
  1951.    sizeof(DAC960_V2_UserCommand_T))) {
  1952. ErrorCode = -EFAULT;
  1953. goto Failure2a;
  1954. }
  1955. ControllerNumber = UserCommand.ControllerNumber;
  1956. if (ControllerNumber < 0 ||
  1957.     ControllerNumber > DAC960_ControllerCount - 1)
  1958.   return -ENXIO;
  1959. Controller = DAC960_Controllers[ControllerNumber];
  1960. if (Controller == NULL) return -ENXIO;
  1961. if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
  1962. DataTransferLength = UserCommand.DataTransferLength;
  1963. if (DataTransferLength > 0)
  1964.   {
  1965.     DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
  1966. DataTransferLength, &DataTransferBufferDMA);
  1967.     if (DataTransferBuffer == NULL) return -ENOMEM;
  1968.     memset(DataTransferBuffer, 0, DataTransferLength);
  1969.   }
  1970. else if (DataTransferLength < 0)
  1971.   {
  1972.     DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
  1973. -DataTransferLength, &DataTransferBufferDMA);
  1974.     if (DataTransferBuffer == NULL) return -ENOMEM;
  1975.     if (copy_from_user(DataTransferBuffer,
  1976.        UserCommand.DataTransferBuffer,
  1977.        -DataTransferLength)) {
  1978. ErrorCode = -EFAULT;
  1979. goto Failure2;
  1980.     }
  1981.   }
  1982. RequestSenseLength = UserCommand.RequestSenseLength;
  1983. if (RequestSenseLength > 0)
  1984.   {
  1985.     RequestSenseBuffer = pci_alloc_consistent(Controller->PCIDevice,
  1986. RequestSenseLength, &RequestSenseBufferDMA);
  1987.     if (RequestSenseBuffer == NULL)
  1988.       {
  1989. ErrorCode = -ENOMEM;
  1990. goto Failure2;
  1991.       }
  1992.     memset(RequestSenseBuffer, 0, RequestSenseLength);
  1993.   }
  1994. spin_lock_irqsave(&Controller->queue_lock, flags);
  1995. while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
  1996.   DAC960_WaitForCommand(Controller);
  1997. spin_unlock_irqrestore(&Controller->queue_lock, flags);
  1998. DAC960_V2_ClearCommand(Command);
  1999. Command->CommandType = DAC960_ImmediateCommand;
  2000. CommandMailbox = &Command->V2.CommandMailbox;
  2001. memcpy(CommandMailbox, &UserCommand.CommandMailbox,
  2002.        sizeof(DAC960_V2_CommandMailbox_T));
  2003. CommandMailbox->Common.CommandControlBits
  2004.       .AdditionalScatterGatherListMemory = false;
  2005. CommandMailbox->Common.CommandControlBits
  2006.       .NoAutoRequestSense = true;
  2007. CommandMailbox->Common.DataTransferSize = 0;
  2008. CommandMailbox->Common.DataTransferPageNumber = 0;
  2009. memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
  2010.        sizeof(DAC960_V2_DataTransferMemoryAddress_T));
  2011. if (DataTransferLength != 0)
  2012.   {
  2013.     if (DataTransferLength > 0)
  2014.       {
  2015. CommandMailbox->Common.CommandControlBits
  2016.       .DataTransferControllerToHost = true;
  2017. CommandMailbox->Common.DataTransferSize = DataTransferLength;
  2018.       }
  2019.     else
  2020.       {
  2021. CommandMailbox->Common.CommandControlBits
  2022.       .DataTransferControllerToHost = false;
  2023. CommandMailbox->Common.DataTransferSize = -DataTransferLength;
  2024.       }
  2025.     CommandMailbox->Common.DataTransferMemoryAddress
  2026.   .ScatterGatherSegments[0]
  2027.   .SegmentDataPointer = DataTransferBufferDMA;
  2028.     CommandMailbox->Common.DataTransferMemoryAddress
  2029.   .ScatterGatherSegments[0]
  2030.   .SegmentByteCount =
  2031.       CommandMailbox->Common.DataTransferSize;
  2032.   }
  2033. if (RequestSenseLength > 0)
  2034.   {
  2035.     CommandMailbox->Common.CommandControlBits
  2036.   .NoAutoRequestSense = false;
  2037.     CommandMailbox->Common.RequestSenseSize = RequestSenseLength;
  2038.     CommandMailbox->Common.RequestSenseBusAddress =
  2039.        RequestSenseBufferDMA;
  2040.   }
  2041. DAC960_ExecuteCommand(Command);
  2042. CommandStatus = Command->V2.CommandStatus;
  2043. RequestSenseLength = Command->V2.RequestSenseLength;
  2044. DataTransferResidue = Command->V2.DataTransferResidue;
  2045. spin_lock_irqsave(&Controller->queue_lock, flags);
  2046. DAC960_DeallocateCommand(Command);
  2047. spin_unlock_irqrestore(&Controller->queue_lock, flags);
  2048. if (RequestSenseLength > UserCommand.RequestSenseLength)
  2049.   RequestSenseLength = UserCommand.RequestSenseLength;
  2050. if (copy_to_user(&UserSpaceUserCommand->DataTransferLength,
  2051.  &DataTransferResidue,
  2052.  sizeof(DataTransferResidue))) {
  2053. ErrorCode = -EFAULT;
  2054. goto Failure2;
  2055. }
  2056. if (copy_to_user(&UserSpaceUserCommand->RequestSenseLength,
  2057.  &RequestSenseLength, sizeof(RequestSenseLength))) {
  2058. ErrorCode = -EFAULT;
  2059. goto Failure2;
  2060. }
  2061. if (DataTransferLength > 0)
  2062.   {
  2063.     if (copy_to_user(UserCommand.DataTransferBuffer,
  2064.      DataTransferBuffer, DataTransferLength)) {
  2065. ErrorCode = -EFAULT;
  2066. goto Failure2;
  2067.     }
  2068.   }
  2069. if (RequestSenseLength > 0)
  2070.   {
  2071.     if (copy_to_user(UserCommand.RequestSenseBuffer,
  2072.      RequestSenseBuffer, RequestSenseLength)) {
  2073. ErrorCode = -EFAULT;
  2074. goto Failure2;
  2075.     }
  2076.   }
  2077. ErrorCode = CommandStatus;
  2078.       Failure2:
  2079.   pci_free_consistent(Controller->PCIDevice, abs(DataTransferLength),
  2080. DataTransferBuffer, DataTransferBufferDMA);
  2081. if (RequestSenseBuffer != NULL)
  2082.   pci_free_consistent(Controller->PCIDevice, RequestSenseLength,
  2083. RequestSenseBuffer, RequestSenseBufferDMA);
  2084.       Failure2a:
  2085. return ErrorCode;
  2086.       }
  2087.     case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
  2088.       {
  2089. DAC960_V2_GetHealthStatus_T __user *UserSpaceGetHealthStatus =
  2090.   (DAC960_V2_GetHealthStatus_T __user *) Argument;
  2091. DAC960_V2_GetHealthStatus_T GetHealthStatus;
  2092. DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
  2093. DAC960_Controller_T *Controller;
  2094. int ControllerNumber;
  2095. if (UserSpaceGetHealthStatus == NULL) return -EINVAL;
  2096. if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
  2097.    sizeof(DAC960_V2_GetHealthStatus_T)))
  2098. return -EFAULT;
  2099. ControllerNumber = GetHealthStatus.ControllerNumber;
  2100. if (ControllerNumber < 0 ||
  2101.     ControllerNumber > DAC960_ControllerCount - 1)
  2102.   return -ENXIO;
  2103. Controller = DAC960_Controllers[ControllerNumber];
  2104. if (Controller == NULL) return -ENXIO;
  2105. if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
  2106. if (copy_from_user(&HealthStatusBuffer,
  2107.    GetHealthStatus.HealthStatusBuffer,
  2108.    sizeof(DAC960_V2_HealthStatusBuffer_T)))
  2109. return -EFAULT;
  2110. while (Controller->V2.HealthStatusBuffer->StatusChangeCounter
  2111.        == HealthStatusBuffer.StatusChangeCounter &&
  2112.        Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
  2113.        == HealthStatusBuffer.NextEventSequenceNumber)
  2114.   {
  2115.     interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue,
  2116.    DAC960_MonitoringTimerInterval);
  2117.     if (signal_pending(current)) return -EINTR;
  2118.   }
  2119. if (copy_to_user(GetHealthStatus.HealthStatusBuffer,
  2120.  Controller->V2.HealthStatusBuffer,
  2121.  sizeof(DAC960_V2_HealthStatusBuffer_T)))
  2122. return -EFAULT;
  2123. return 0;
  2124.       }
  2125.     }
  2126.   return -EINVAL;
  2127. }
  2128. static struct file_operations DAC960_gam_fops = {
  2129. .owner = THIS_MODULE,
  2130. .ioctl = DAC960_gam_ioctl
  2131. };
  2132. static struct miscdevice DAC960_gam_dev = {
  2133. DAC960_GAM_MINOR,
  2134. "dac960_gam",
  2135. &DAC960_gam_fops
  2136. };
  2137. static int DAC960_gam_init(void)
  2138. {
  2139. int ret;
  2140. ret = misc_register(&DAC960_gam_dev);
  2141. if (ret)
  2142. printk(KERN_ERR "DAC960_gam: can't misc_register on minor %dn", DAC960_GAM_MINOR);
  2143. return ret;
  2144. }
  2145. static void DAC960_gam_cleanup(void)
  2146. {
  2147. misc_deregister(&DAC960_gam_dev);
  2148. }
  2149. #endif /* DAC960_GAM_MINOR */
  2150. static struct DAC960_privdata DAC960_GEM_privdata = {
  2151. .HardwareType = DAC960_GEM_Controller,
  2152. .FirmwareType  = DAC960_V2_Controller,
  2153. .InterruptHandler = DAC960_GEM_InterruptHandler,
  2154. .MemoryWindowSize = DAC960_GEM_RegisterWindowSize,
  2155. };
  2156. static struct DAC960_privdata DAC960_BA_privdata = {
  2157. .HardwareType = DAC960_BA_Controller,
  2158. .FirmwareType  = DAC960_V2_Controller,
  2159. .InterruptHandler = DAC960_BA_InterruptHandler,
  2160. .MemoryWindowSize = DAC960_BA_RegisterWindowSize,
  2161. };
  2162. static struct DAC960_privdata DAC960_LP_privdata = {
  2163. .HardwareType = DAC960_LP_Controller,
  2164. .FirmwareType  = DAC960_LP_Controller,
  2165. .InterruptHandler = DAC960_LP_InterruptHandler,
  2166. .MemoryWindowSize = DAC960_LP_RegisterWindowSize,
  2167. };
  2168. static struct DAC960_privdata DAC960_LA_privdata = {
  2169. .HardwareType = DAC960_LA_Controller,
  2170. .FirmwareType  = DAC960_V1_Controller,
  2171. .InterruptHandler = DAC960_LA_InterruptHandler,
  2172. .MemoryWindowSize = DAC960_LA_RegisterWindowSize,
  2173. };
  2174. static struct DAC960_privdata DAC960_PG_privdata = {
  2175. .HardwareType = DAC960_PG_Controller,
  2176. .FirmwareType  = DAC960_V1_Controller,
  2177. .InterruptHandler = DAC960_PG_InterruptHandler,
  2178. .MemoryWindowSize = DAC960_PG_RegisterWindowSize,
  2179. };
  2180. static struct DAC960_privdata DAC960_PD_privdata = {
  2181. .HardwareType = DAC960_PD_Controller,
  2182. .FirmwareType  = DAC960_V1_Controller,
  2183. .InterruptHandler = DAC960_PD_InterruptHandler,
  2184. .MemoryWindowSize = DAC960_PD_RegisterWindowSize,
  2185. };
  2186. static struct DAC960_privdata DAC960_P_privdata = {
  2187. .HardwareType = DAC960_P_Controller,
  2188. .FirmwareType  = DAC960_V1_Controller,
  2189. .InterruptHandler = DAC960_P_InterruptHandler,
  2190. .MemoryWindowSize = DAC960_PD_RegisterWindowSize,
  2191. };
  2192. static struct pci_device_id DAC960_id_table[] = {
  2193. {
  2194. .vendor  = PCI_VENDOR_ID_MYLEX,
  2195. .device = PCI_DEVICE_ID_MYLEX_DAC960_GEM,
  2196. .subvendor = PCI_ANY_ID,
  2197. .subdevice = PCI_ANY_ID,
  2198. .driver_data = (unsigned long) &DAC960_GEM_privdata,
  2199. },
  2200. {
  2201. .vendor  = PCI_VENDOR_ID_MYLEX,
  2202. .device = PCI_DEVICE_ID_MYLEX_DAC960_BA,
  2203. .subvendor = PCI_ANY_ID,
  2204. .subdevice = PCI_ANY_ID,
  2205. .driver_data = (unsigned long) &DAC960_BA_privdata,
  2206. },
  2207. {
  2208. .vendor  = PCI_VENDOR_ID_MYLEX,
  2209. .device = PCI_DEVICE_ID_MYLEX_DAC960_LP,
  2210. .subvendor = PCI_ANY_ID,
  2211. .subdevice = PCI_ANY_ID,
  2212. .driver_data = (unsigned long) &DAC960_LP_privdata,
  2213. },
  2214. {
  2215. .vendor  = PCI_VENDOR_ID_DEC,
  2216. .device = PCI_DEVICE_ID_DEC_21285,
  2217. .subvendor = PCI_VENDOR_ID_MYLEX,
  2218. .subdevice = PCI_DEVICE_ID_MYLEX_DAC960_LA,
  2219. .driver_data = (unsigned long) &DAC960_LA_privdata,
  2220. },
  2221. {
  2222. .vendor  = PCI_VENDOR_ID_MYLEX,
  2223. .device = PCI_DEVICE_ID_MYLEX_DAC960_PG,
  2224. .subvendor = PCI_ANY_ID,
  2225. .subdevice = PCI_ANY_ID,
  2226. .driver_data = (unsigned long) &DAC960_PG_privdata,
  2227. },
  2228. {
  2229. .vendor  = PCI_VENDOR_ID_MYLEX,
  2230. .device = PCI_DEVICE_ID_MYLEX_DAC960_PD,
  2231. .subvendor = PCI_ANY_ID,
  2232. .subdevice = PCI_ANY_ID,
  2233. .driver_data = (unsigned long) &DAC960_PD_privdata,
  2234. },
  2235. {
  2236. .vendor  = PCI_VENDOR_ID_MYLEX,
  2237. .device = PCI_DEVICE_ID_MYLEX_DAC960_P,
  2238. .subvendor = PCI_ANY_ID,
  2239. .subdevice = PCI_ANY_ID,
  2240. .driver_data = (unsigned long) &DAC960_P_privdata,
  2241. },
  2242. {0, },
  2243. };
  2244. MODULE_DEVICE_TABLE(pci, DAC960_id_table);
  2245. static struct pci_driver DAC960_pci_driver = {
  2246. .name = "DAC960",
  2247. .id_table = DAC960_id_table,
  2248. .probe = DAC960_Probe,
  2249. .remove = DAC960_Remove,
  2250. };
  2251. static int DAC960_init_module(void)
  2252. {
  2253. int ret;
  2254. ret =  pci_module_init(&DAC960_pci_driver);
  2255. #ifdef DAC960_GAM_MINOR
  2256. if (!ret)
  2257. DAC960_gam_init();
  2258. #endif
  2259. return ret;
  2260. }
  2261. static void DAC960_cleanup_module(void)
  2262. {
  2263. int i;
  2264. #ifdef DAC960_GAM_MINOR
  2265. DAC960_gam_cleanup();
  2266. #endif
  2267. for (i = 0; i < DAC960_ControllerCount; i++) {
  2268. DAC960_Controller_T *Controller = DAC960_Controllers[i];
  2269. if (Controller == NULL)
  2270. continue;
  2271. DAC960_FinalizeController(Controller);
  2272. }
  2273. if (DAC960_ProcDirectoryEntry != NULL) {
  2274.    remove_proc_entry("rd/status", NULL);
  2275.    remove_proc_entry("rd", NULL);
  2276. }
  2277. DAC960_ControllerCount = 0;
  2278. pci_unregister_driver(&DAC960_pci_driver);
  2279. }
  2280. module_init(DAC960_init_module);
  2281. module_exit(DAC960_cleanup_module);
  2282. MODULE_LICENSE("GPL");