DAC960.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:257k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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