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

嵌入式Linux

开发平台:

Unix_Linux

  1.       DAC960_AnnounceDriver(Controller);
  2.       Controller->FirmwareType = FirmwareType;
  3.       Controller->HardwareType = HardwareType;
  4.       Controller->IO_Address = IO_Address;
  5.       Controller->PCI_Address = PCI_Address;
  6.       Controller->Bus = Bus;
  7.       Controller->Device = Device;
  8.       Controller->Function = Function;
  9.       /*
  10. Map the Controller Register Window.
  11.       */
  12.       if (MemoryWindowSize < PAGE_SIZE)
  13. MemoryWindowSize = PAGE_SIZE;
  14.       Controller->MemoryMappedAddress =
  15. ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
  16.       Controller->BaseAddress =
  17. Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
  18.       if (Controller->MemoryMappedAddress == NULL)
  19. {
  20.   DAC960_Error("Unable to map Controller Register Window for "
  21.        "Controller atn", Controller);
  22.   goto Failure;
  23. }
  24.       BaseAddress = Controller->BaseAddress;
  25.       switch (HardwareType)
  26. {
  27. case DAC960_BA_Controller:
  28.   DAC960_BA_DisableInterrupts(Controller->BaseAddress);
  29.   DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
  30.   udelay(1000);
  31.   while (DAC960_BA_InitializationInProgressP(BaseAddress))
  32.     {
  33.       if (DAC960_BA_ReadErrorStatus(BaseAddress, &ErrorStatus,
  34.     &Parameter0, &Parameter1) &&
  35.   DAC960_ReportErrorStatus(Controller, ErrorStatus,
  36.    Parameter0, Parameter1))
  37. goto Failure;
  38.       udelay(10);
  39.     }
  40.   if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
  41.     {
  42.       DAC960_Error("Unable to Enable Memory Mailbox Interface "
  43.    "for Controller atn", Controller);
  44.       goto Failure;
  45.     }
  46.   DAC960_BA_EnableInterrupts(Controller->BaseAddress);
  47.   Controller->QueueCommand = DAC960_BA_QueueCommand;
  48.   Controller->ReadControllerConfiguration =
  49.     DAC960_V2_ReadControllerConfiguration;
  50.   Controller->ReadDeviceConfiguration =
  51.     DAC960_V2_ReadDeviceConfiguration;
  52.   Controller->ReportDeviceConfiguration =
  53.     DAC960_V2_ReportDeviceConfiguration;
  54.   Controller->QueueReadWriteCommand =
  55.     DAC960_V2_QueueReadWriteCommand;
  56.   break;
  57. case DAC960_LP_Controller:
  58.   DAC960_LP_DisableInterrupts(Controller->BaseAddress);
  59.   DAC960_LP_AcknowledgeHardwareMailboxStatus(BaseAddress);
  60.   udelay(1000);
  61.   while (DAC960_LP_InitializationInProgressP(BaseAddress))
  62.     {
  63.       if (DAC960_LP_ReadErrorStatus(BaseAddress, &ErrorStatus,
  64.     &Parameter0, &Parameter1) &&
  65.   DAC960_ReportErrorStatus(Controller, ErrorStatus,
  66.    Parameter0, Parameter1))
  67. goto Failure;
  68.       udelay(10);
  69.     }
  70.   if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
  71.     {
  72.       DAC960_Error("Unable to Enable Memory Mailbox Interface "
  73.    "for Controller atn", Controller);
  74.       goto Failure;
  75.     }
  76.   DAC960_LP_EnableInterrupts(Controller->BaseAddress);
  77.   Controller->QueueCommand = DAC960_LP_QueueCommand;
  78.   Controller->ReadControllerConfiguration =
  79.     DAC960_V2_ReadControllerConfiguration;
  80.   Controller->ReadDeviceConfiguration =
  81.     DAC960_V2_ReadDeviceConfiguration;
  82.   Controller->ReportDeviceConfiguration =
  83.     DAC960_V2_ReportDeviceConfiguration;
  84.   Controller->QueueReadWriteCommand =
  85.     DAC960_V2_QueueReadWriteCommand;
  86.   break;
  87. case DAC960_LA_Controller:
  88.   DAC960_LA_DisableInterrupts(Controller->BaseAddress);
  89.   DAC960_LA_AcknowledgeHardwareMailboxStatus(BaseAddress);
  90.   udelay(1000);
  91.   while (DAC960_LA_InitializationInProgressP(BaseAddress))
  92.     {
  93.       if (DAC960_LA_ReadErrorStatus(BaseAddress, &ErrorStatus,
  94.     &Parameter0, &Parameter1) &&
  95.   DAC960_ReportErrorStatus(Controller, ErrorStatus,
  96.    Parameter0, Parameter1))
  97. goto Failure;
  98.       udelay(10);
  99.     }
  100.   if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
  101.     {
  102.       DAC960_Error("Unable to Enable Memory Mailbox Interface "
  103.    "for Controller atn", Controller);
  104.       goto Failure;
  105.     }
  106.   DAC960_LA_EnableInterrupts(Controller->BaseAddress);
  107.   if (Controller->V1.DualModeMemoryMailboxInterface)
  108.     Controller->QueueCommand = DAC960_LA_QueueCommandDualMode;
  109.   else Controller->QueueCommand = DAC960_LA_QueueCommandSingleMode;
  110.   Controller->ReadControllerConfiguration =
  111.     DAC960_V1_ReadControllerConfiguration;
  112.   Controller->ReadDeviceConfiguration =
  113.     DAC960_V1_ReadDeviceConfiguration;
  114.   Controller->ReportDeviceConfiguration =
  115.     DAC960_V1_ReportDeviceConfiguration;
  116.   Controller->QueueReadWriteCommand =
  117.     DAC960_V1_QueueReadWriteCommand;
  118.   break;
  119. case DAC960_PG_Controller:
  120.   DAC960_PG_DisableInterrupts(Controller->BaseAddress);
  121.   DAC960_PG_AcknowledgeHardwareMailboxStatus(BaseAddress);
  122.   udelay(1000);
  123.   while (DAC960_PG_InitializationInProgressP(BaseAddress))
  124.     {
  125.       if (DAC960_PG_ReadErrorStatus(BaseAddress, &ErrorStatus,
  126.     &Parameter0, &Parameter1) &&
  127.   DAC960_ReportErrorStatus(Controller, ErrorStatus,
  128.    Parameter0, Parameter1))
  129. goto Failure;
  130.       udelay(10);
  131.     }
  132.   if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
  133.     {
  134.       DAC960_Error("Unable to Enable Memory Mailbox Interface "
  135.    "for Controller atn", Controller);
  136.       goto Failure;
  137.     }
  138.   DAC960_PG_EnableInterrupts(Controller->BaseAddress);
  139.   if (Controller->V1.DualModeMemoryMailboxInterface)
  140.     Controller->QueueCommand = DAC960_PG_QueueCommandDualMode;
  141.   else Controller->QueueCommand = DAC960_PG_QueueCommandSingleMode;
  142.   Controller->ReadControllerConfiguration =
  143.     DAC960_V1_ReadControllerConfiguration;
  144.   Controller->ReadDeviceConfiguration =
  145.     DAC960_V1_ReadDeviceConfiguration;
  146.   Controller->ReportDeviceConfiguration =
  147.     DAC960_V1_ReportDeviceConfiguration;
  148.   Controller->QueueReadWriteCommand =
  149.     DAC960_V1_QueueReadWriteCommand;
  150.   break;
  151. case DAC960_PD_Controller:
  152.   request_region(Controller->IO_Address, 0x80,
  153.  Controller->FullModelName);
  154.   DAC960_PD_DisableInterrupts(BaseAddress);
  155.   DAC960_PD_AcknowledgeStatus(BaseAddress);
  156.   udelay(1000);
  157.   while (DAC960_PD_InitializationInProgressP(BaseAddress))
  158.     {
  159.       if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
  160.     &Parameter0, &Parameter1) &&
  161.   DAC960_ReportErrorStatus(Controller, ErrorStatus,
  162.    Parameter0, Parameter1))
  163. goto Failure;
  164.       udelay(10);
  165.     }
  166.   DAC960_PD_EnableInterrupts(Controller->BaseAddress);
  167.   Controller->QueueCommand = DAC960_PD_QueueCommand;
  168.   Controller->ReadControllerConfiguration =
  169.     DAC960_V1_ReadControllerConfiguration;
  170.   Controller->ReadDeviceConfiguration =
  171.     DAC960_V1_ReadDeviceConfiguration;
  172.   Controller->ReportDeviceConfiguration =
  173.     DAC960_V1_ReportDeviceConfiguration;
  174.   Controller->QueueReadWriteCommand =
  175.     DAC960_V1_QueueReadWriteCommand;
  176.   break;
  177. case DAC960_P_Controller:
  178.   request_region(Controller->IO_Address, 0x80,
  179.  Controller->FullModelName);
  180.   DAC960_PD_DisableInterrupts(BaseAddress);
  181.   DAC960_PD_AcknowledgeStatus(BaseAddress);
  182.   udelay(1000);
  183.   while (DAC960_PD_InitializationInProgressP(BaseAddress))
  184.     {
  185.       if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
  186.     &Parameter0, &Parameter1) &&
  187.   DAC960_ReportErrorStatus(Controller, ErrorStatus,
  188.    Parameter0, Parameter1))
  189. goto Failure;
  190.       udelay(10);
  191.     }
  192.   DAC960_PD_EnableInterrupts(Controller->BaseAddress);
  193.   Controller->QueueCommand = DAC960_P_QueueCommand;
  194.   Controller->ReadControllerConfiguration =
  195.     DAC960_V1_ReadControllerConfiguration;
  196.   Controller->ReadDeviceConfiguration =
  197.     DAC960_V1_ReadDeviceConfiguration;
  198.   Controller->ReportDeviceConfiguration =
  199.     DAC960_V1_ReportDeviceConfiguration;
  200.   Controller->QueueReadWriteCommand =
  201.     DAC960_V1_QueueReadWriteCommand;
  202.   break;
  203. }
  204.       /*
  205. Acquire shared access to the IRQ Channel.
  206.       */
  207.       if (IRQ_Channel == 0)
  208. {
  209.   DAC960_Error("IRQ Channel %d illegal for Controller atn",
  210.        Controller, IRQ_Channel);
  211.   goto Failure;
  212. }
  213.       strcpy(Controller->FullModelName, "DAC960");
  214.       if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
  215.       Controller->FullModelName, Controller) < 0)
  216. {
  217.   DAC960_Error("Unable to acquire IRQ Channel %d for Controller atn",
  218.        Controller, IRQ_Channel);
  219.   goto Failure;
  220. }
  221.       Controller->IRQ_Channel = IRQ_Channel;
  222.       DAC960_ActiveControllerCount++;
  223.       Controller->InitialCommand.CommandIdentifier = 1;
  224.       Controller->InitialCommand.Controller = Controller;
  225.       Controller->Commands[0] = &Controller->InitialCommand;
  226.       Controller->FreeCommands = &Controller->InitialCommand;
  227.       Controller->ControllerDetectionSuccessful = true;
  228.       continue;
  229.     Failure:
  230.       if (IO_Address == 0)
  231. DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
  232.      "PCI Address 0x%Xn", Controller,
  233.      Bus, Device, Function, PCI_Address);
  234.       else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
  235. "0x%X PCI Address 0x%Xn", Controller,
  236. Bus, Device, Function, IO_Address, PCI_Address);
  237.       if (Controller == NULL) break;
  238.       if (Controller->MemoryMappedAddress != NULL)
  239. iounmap(Controller->MemoryMappedAddress);
  240.       if (Controller->IRQ_Channel > 0)
  241. free_irq(IRQ_Channel, Controller);
  242.     }
  243. }
  244. /*
  245.   DAC960_SortControllers sorts the Controllers by PCI Bus and Device Number.
  246. */
  247. static void DAC960_SortControllers(void)
  248. {
  249.   int ControllerNumber, LastInterchange, Bound, j;
  250.   LastInterchange = DAC960_ControllerCount-1;
  251.   while (LastInterchange > 0)
  252.     {
  253.       Bound = LastInterchange;
  254.       LastInterchange = 0;
  255.       for (j = 0; j < Bound; j++)
  256. {
  257.   DAC960_Controller_T *Controller1 = DAC960_Controllers[j];
  258.   DAC960_Controller_T *Controller2 = DAC960_Controllers[j+1];
  259.   if (Controller1->Bus > Controller2->Bus ||
  260.       (Controller1->Bus == Controller2->Bus &&
  261.        (Controller1->Device > Controller2->Device)))
  262.     {
  263.       Controller2->ControllerNumber = j;
  264.       DAC960_Controllers[j] = Controller2;
  265.       Controller1->ControllerNumber = j+1;
  266.       DAC960_Controllers[j+1] = Controller1;
  267.       LastInterchange = j;
  268.     }
  269. }
  270.     }
  271.   for (ControllerNumber = 0;
  272.        ControllerNumber < DAC960_ControllerCount;
  273.        ControllerNumber++)
  274.     {
  275.       DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
  276.       if (!Controller->ControllerDetectionSuccessful)
  277. {
  278.   DAC960_Controllers[ControllerNumber] = NULL;
  279.   kfree(Controller);
  280. }
  281.     }
  282. }
  283. /*
  284.   DAC960_InitializeController initializes Controller.
  285. */
  286. static void DAC960_InitializeController(DAC960_Controller_T *Controller)
  287. {
  288.   if (DAC960_ReadControllerConfiguration(Controller) &&
  289.       DAC960_ReportControllerConfiguration(Controller) &&
  290.       DAC960_CreateAuxiliaryStructures(Controller) &&
  291.       DAC960_ReadDeviceConfiguration(Controller) &&
  292.       DAC960_ReportDeviceConfiguration(Controller) &&
  293.       DAC960_RegisterBlockDevice(Controller))
  294.     {
  295.       /*
  296. Initialize the Monitoring Timer.
  297.       */
  298.       init_timer(&Controller->MonitoringTimer);
  299.       Controller->MonitoringTimer.expires =
  300. jiffies + DAC960_MonitoringTimerInterval;
  301.       Controller->MonitoringTimer.data = (unsigned long) Controller;
  302.       Controller->MonitoringTimer.function = DAC960_MonitoringTimerFunction;
  303.       add_timer(&Controller->MonitoringTimer);
  304.       Controller->ControllerInitialized = true;
  305.     }
  306.   else DAC960_FinalizeController(Controller);
  307. }
  308. /*
  309.   DAC960_FinalizeController finalizes Controller.
  310. */
  311. static void DAC960_FinalizeController(DAC960_Controller_T *Controller)
  312. {
  313.   if (Controller->ControllerInitialized)
  314.     {
  315.       del_timer(&Controller->MonitoringTimer);
  316.       if (Controller->FirmwareType == DAC960_V1_Controller)
  317. {
  318.   DAC960_Notice("Flushing Cache...", Controller);
  319.   DAC960_V1_ExecuteType3(Controller, DAC960_V1_Flush, NULL);
  320.   DAC960_Notice("donen", Controller);
  321.   switch (Controller->HardwareType)
  322.     {
  323.     case DAC960_LA_Controller:
  324.       if (Controller->V1.DualModeMemoryMailboxInterface)
  325. free_pages(Controller->MemoryMailboxPagesAddress,
  326.    Controller->MemoryMailboxPagesOrder);
  327.       else DAC960_LA_SaveMemoryMailboxInfo(Controller);
  328.       break;
  329.     case DAC960_PG_Controller:
  330.       if (Controller->V1.DualModeMemoryMailboxInterface)
  331. free_pages(Controller->MemoryMailboxPagesAddress,
  332.    Controller->MemoryMailboxPagesOrder);
  333.       else DAC960_PG_SaveMemoryMailboxInfo(Controller);
  334.       break;
  335.     case DAC960_PD_Controller:
  336.       release_region(Controller->IO_Address, 0x80);
  337.       break;
  338.     default:
  339.       break;
  340.     }
  341. }
  342.       else
  343. {
  344.   DAC960_Notice("Flushing Cache...", Controller);
  345.   DAC960_V2_DeviceOperation(Controller, DAC960_V2_PauseDevice,
  346.     DAC960_V2_RAID_Controller);
  347.   DAC960_Notice("donen", Controller);
  348.   free_pages(Controller->MemoryMailboxPagesAddress,
  349.      Controller->MemoryMailboxPagesOrder);
  350. }
  351.     }
  352.   free_irq(Controller->IRQ_Channel, Controller);
  353.   iounmap(Controller->MemoryMappedAddress);
  354.   DAC960_UnregisterBlockDevice(Controller);
  355.   DAC960_DestroyAuxiliaryStructures(Controller);
  356.   DAC960_Controllers[Controller->ControllerNumber] = NULL;
  357.   kfree(Controller);
  358. }
  359. /*
  360.   DAC960_Initialize initializes the DAC960 Driver.
  361. */
  362. static int DAC960_Initialize(void)
  363. {
  364.   int ControllerNumber;
  365.   DAC960_DetectControllers(DAC960_BA_Controller);
  366.   DAC960_DetectControllers(DAC960_LP_Controller);
  367.   DAC960_DetectControllers(DAC960_LA_Controller);
  368.   DAC960_DetectControllers(DAC960_PG_Controller);
  369.   DAC960_DetectControllers(DAC960_PD_Controller);
  370.   DAC960_DetectControllers(DAC960_P_Controller);
  371.   DAC960_SortControllers();
  372.   if (DAC960_ActiveControllerCount == 0) return -ENODEV;
  373.   for (ControllerNumber = 0;
  374.        ControllerNumber < DAC960_ControllerCount;
  375.        ControllerNumber++)
  376.     {
  377.       DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
  378.       int LogicalDriveNumber;
  379.       if (Controller == NULL) continue;
  380.       DAC960_InitializeController(Controller);
  381.       DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
  382.       for (LogicalDriveNumber = 0;
  383.    LogicalDriveNumber < DAC960_MaxLogicalDrives;
  384.    LogicalDriveNumber++)
  385. DAC960_RegisterDisk(Controller, LogicalDriveNumber);
  386.     }
  387.   DAC960_CreateProcEntries();
  388.   register_reboot_notifier(&DAC960_NotifierBlock);
  389.   return 0;
  390. }
  391. /*
  392.   DAC960_Finalize finalizes the DAC960 Driver.
  393. */
  394. static void DAC960_Finalize(void)
  395. {
  396.   int ControllerNumber;
  397.   if (DAC960_ActiveControllerCount == 0) return;
  398.   for (ControllerNumber = 0;
  399.        ControllerNumber < DAC960_ControllerCount;
  400.        ControllerNumber++)
  401.     if (DAC960_Controllers[ControllerNumber] != NULL)
  402.       DAC960_FinalizeController(DAC960_Controllers[ControllerNumber]);
  403.   DAC960_DestroyProcEntries();
  404.   unregister_reboot_notifier(&DAC960_NotifierBlock);
  405. }
  406. /*
  407.   DAC960_Notifier is the notifier for the DAC960 Driver.
  408. */
  409. static int DAC960_Notifier(NotifierBlock_T *NotifierBlock,
  410.    unsigned long Event,
  411.    void *Buffer)
  412. {
  413.   if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
  414.     return NOTIFY_DONE;
  415.   DAC960_Finalize();
  416.   return NOTIFY_OK;
  417. }
  418. /*
  419.   DAC960_V1_QueueReadWriteCommand prepares and queues a Read/Write Command for
  420.   DAC960 V1 Firmware Controllers.
  421. */
  422. static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command)
  423. {
  424.   DAC960_Controller_T *Controller = Command->Controller;
  425.   DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
  426.   DAC960_V1_ClearCommand(Command);
  427.   if (Command->SegmentCount == 1)
  428.     {
  429.       if (Command->CommandType == DAC960_ReadCommand)
  430. CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
  431.       else CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
  432.       CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
  433.       CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
  434.       CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
  435.       CommandMailbox->Type5.BusAddress =
  436. Virtual_to_Bus32(Command->RequestBuffer);
  437.     }
  438.   else
  439.     {
  440.       DAC960_V1_ScatterGatherSegment_T
  441. *ScatterGatherList = Command->V1.ScatterGatherList;
  442.       BufferHeader_T *BufferHeader = Command->BufferHeader;
  443.       char *LastDataEndPointer = NULL;
  444.       int SegmentNumber = 0;
  445.       if (Command->CommandType == DAC960_ReadCommand)
  446. CommandMailbox->Type5.CommandOpcode = DAC960_V1_ReadWithScatterGather;
  447.       else
  448. CommandMailbox->Type5.CommandOpcode = DAC960_V1_WriteWithScatterGather;
  449.       CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
  450.       CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
  451.       CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
  452.       CommandMailbox->Type5.BusAddress = Virtual_to_Bus32(ScatterGatherList);
  453.       CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount;
  454.       while (BufferHeader != NULL)
  455. {
  456.   if (BufferHeader->b_data == LastDataEndPointer)
  457.     {
  458.       ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
  459. BufferHeader->b_size;
  460.       LastDataEndPointer += BufferHeader->b_size;
  461.     }
  462.   else
  463.     {
  464.       ScatterGatherList[SegmentNumber].SegmentDataPointer =
  465. Virtual_to_Bus32(BufferHeader->b_data);
  466.       ScatterGatherList[SegmentNumber].SegmentByteCount =
  467. BufferHeader->b_size;
  468.       LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
  469.       if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
  470. panic("DAC960: Scatter/Gather Segment Overflown");
  471.     }
  472.   BufferHeader = BufferHeader->b_reqnext;
  473. }
  474.       if (SegmentNumber != Command->SegmentCount)
  475. panic("DAC960: SegmentNumber != SegmentCountn");
  476.     }
  477.   DAC960_QueueCommand(Command);
  478. }
  479. /*
  480.   DAC960_V2_QueueReadWriteCommand prepares and queues a Read/Write Command for
  481.   DAC960 V2 Firmware Controllers.
  482. */
  483. static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
  484. {
  485.   DAC960_Controller_T *Controller = Command->Controller;
  486.   DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
  487.   DAC960_V2_ClearCommand(Command);
  488.   CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10;
  489.   CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost =
  490.     (Command->CommandType == DAC960_ReadCommand);
  491.   CommandMailbox->SCSI_10.DataTransferSize =
  492.     Command->BlockCount << DAC960_BlockSizeBits;
  493.   CommandMailbox->SCSI_10.RequestSenseBusAddress =
  494.     Virtual_to_Bus64(&Command->V2.RequestSense);
  495.   CommandMailbox->SCSI_10.PhysicalDevice =
  496.     Controller->V2.LogicalDriveToVirtualDevice[Command->LogicalDriveNumber];
  497.   CommandMailbox->SCSI_10.RequestSenseSize =
  498.     sizeof(DAC960_SCSI_RequestSense_T);
  499.   CommandMailbox->SCSI_10.CDBLength = 10;
  500.   CommandMailbox->SCSI_10.SCSI_CDB[0] =
  501.     (Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A);
  502.   CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
  503.   CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
  504.   CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
  505.   CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
  506.   CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
  507.   CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
  508.   if (Command->SegmentCount == 1)
  509.     {
  510.       CommandMailbox->SCSI_10.DataTransferMemoryAddress
  511.      .ScatterGatherSegments[0]
  512.      .SegmentDataPointer =
  513. Virtual_to_Bus64(Command->RequestBuffer);
  514.       CommandMailbox->SCSI_10.DataTransferMemoryAddress
  515.      .ScatterGatherSegments[0]
  516.      .SegmentByteCount =
  517. CommandMailbox->SCSI_10.DataTransferSize;
  518.     }
  519.   else
  520.     {
  521.       DAC960_V2_ScatterGatherSegment_T
  522. *ScatterGatherList = Command->V2.ScatterGatherList;
  523.       BufferHeader_T *BufferHeader = Command->BufferHeader;
  524.       char *LastDataEndPointer = NULL;
  525.       int SegmentNumber = 0;
  526.       if (Command->SegmentCount > 2)
  527. {
  528.   CommandMailbox->SCSI_10.CommandControlBits
  529.  .AdditionalScatterGatherListMemory = true;
  530.   CommandMailbox->SCSI_10.DataTransferMemoryAddress
  531.  .ExtendedScatterGather.ScatterGatherList0Length =
  532.     Command->SegmentCount;
  533.   CommandMailbox->SCSI_10.DataTransferMemoryAddress
  534.  .ExtendedScatterGather.ScatterGatherList0Address =
  535.     Virtual_to_Bus64(ScatterGatherList);
  536. }
  537.       else
  538. ScatterGatherList =
  539.   CommandMailbox->SCSI_10.DataTransferMemoryAddress
  540.  .ScatterGatherSegments;
  541.       while (BufferHeader != NULL)
  542. {
  543.   if (BufferHeader->b_data == LastDataEndPointer)
  544.     {
  545.       ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
  546. BufferHeader->b_size;
  547.       LastDataEndPointer += BufferHeader->b_size;
  548.     }
  549.   else
  550.     {
  551.       ScatterGatherList[SegmentNumber].SegmentDataPointer =
  552. Virtual_to_Bus64(BufferHeader->b_data);
  553.       ScatterGatherList[SegmentNumber].SegmentByteCount =
  554. BufferHeader->b_size;
  555.       LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
  556.       if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
  557. panic("DAC960: Scatter/Gather Segment Overflown");
  558.     }
  559.   BufferHeader = BufferHeader->b_reqnext;
  560. }
  561.       if (SegmentNumber != Command->SegmentCount)
  562. panic("DAC960: SegmentNumber != SegmentCountn");
  563.     }
  564.   DAC960_QueueCommand(Command);
  565. }
  566. /*
  567.   DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
  568.   I/O Request Queue and queues it to the Controller.  WaitForCommand is true if
  569.   this function should wait for a Command to become available if necessary.
  570.   This function returns true if an I/O Request was queued and false otherwise.
  571. */
  572. static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
  573.      boolean WaitForCommand)
  574. {
  575.   RequestQueue_T *RequestQueue = Controller->RequestQueue;
  576.   ListHead_T *RequestQueueHead;
  577.   IO_Request_T *Request;
  578.   DAC960_Command_T *Command;
  579.   if (RequestQueue == NULL) return false;
  580.   RequestQueueHead = &RequestQueue->queue_head;
  581.   while (true)
  582.     {
  583.       if (list_empty(RequestQueueHead)) return false;
  584.       Request = blkdev_entry_next_request(RequestQueueHead);
  585.       Command = DAC960_AllocateCommand(Controller);
  586.       if (Command != NULL) break;
  587.       if (!WaitForCommand) return false;
  588.       DAC960_WaitForCommand(Controller);
  589.     }
  590.   if (Request->cmd == READ)
  591.     Command->CommandType = DAC960_ReadCommand;
  592.   else Command->CommandType = DAC960_WriteCommand;
  593.   Command->Completion = Request->waiting;
  594.   Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
  595.   Command->BlockNumber =
  596.     Request->sector
  597.     + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
  598.   Command->BlockCount = Request->nr_sectors;
  599.   Command->SegmentCount = Request->nr_segments;
  600.   Command->BufferHeader = Request->bh;
  601.   Command->RequestBuffer = Request->buffer;
  602.   blkdev_dequeue_request(Request);
  603.   blkdev_release_request(Request);
  604.   DAC960_QueueReadWriteCommand(Command);
  605.   return true;
  606. }
  607. /*
  608.   DAC960_ProcessRequests attempts to remove as many I/O Requests as possible
  609.   from Controller's I/O Request Queue and queue them to the Controller.
  610. */
  611. static inline void DAC960_ProcessRequests(DAC960_Controller_T *Controller)
  612. {
  613.   int Counter = 0;
  614.   while (DAC960_ProcessRequest(Controller, Counter++ == 0)) ;
  615. }
  616. /*
  617.   DAC960_RequestFunction is the I/O Request Function for DAC960 Controllers.
  618. */
  619. static void DAC960_RequestFunction(RequestQueue_T *RequestQueue)
  620. {
  621.   DAC960_Controller_T *Controller =
  622.     (DAC960_Controller_T *) RequestQueue->queuedata;
  623.   ProcessorFlags_T ProcessorFlags;
  624.   /*
  625.     Acquire exclusive access to Controller.
  626.   */
  627.   DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
  628.   /*
  629.     Process I/O Requests for Controller.
  630.   */
  631.   DAC960_ProcessRequests(Controller);
  632.   /*
  633.     Release exclusive access to Controller.
  634.   */
  635.   DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
  636. }
  637. /*
  638.   DAC960_ProcessCompletedBuffer performs completion processing for an
  639.   individual Buffer.
  640. */
  641. static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
  642.  boolean SuccessfulIO)
  643. {
  644.   blk_finished_io(BufferHeader->b_size >> 9);
  645.   BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
  646. }
  647. /*
  648.   DAC960_V1_ReadWriteError prints an appropriate error message for Command
  649.   when an error occurs on a Read or Write operation.
  650. */
  651. static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command)
  652. {
  653.   DAC960_Controller_T *Controller = Command->Controller;
  654.   unsigned char *CommandName = "UNKNOWN";
  655.   switch (Command->CommandType)
  656.     {
  657.     case DAC960_ReadCommand:
  658.     case DAC960_ReadRetryCommand:
  659.       CommandName = "READ";
  660.       break;
  661.     case DAC960_WriteCommand:
  662.     case DAC960_WriteRetryCommand:
  663.       CommandName = "WRITE";
  664.       break;
  665.     case DAC960_MonitoringCommand:
  666.     case DAC960_ImmediateCommand:
  667.     case DAC960_QueuedCommand:
  668.       break;
  669.     }
  670.   switch (Command->V1.CommandStatus)
  671.     {
  672.     case DAC960_V1_IrrecoverableDataError:
  673.       DAC960_Error("Irrecoverable Data Error on %s:n",
  674.    Controller, CommandName);
  675.       break;
  676.     case DAC960_V1_LogicalDriveNonexistentOrOffline:
  677.       DAC960_Error("Logical Drive Nonexistent or Offline on %s:n",
  678.    Controller, CommandName);
  679.       break;
  680.     case DAC960_V1_AccessBeyondEndOfLogicalDrive:
  681.       DAC960_Error("Attempt to Access Beyond End of Logical Drive "
  682.    "on %s:n", Controller, CommandName);
  683.       break;
  684.     case DAC960_V1_BadDataEncountered:
  685.       DAC960_Error("Bad Data Encountered on %s:n", Controller, CommandName);
  686.       break;
  687.     default:
  688.       DAC960_Error("Unexpected Error Status %04X on %s:n",
  689.    Controller, Command->V1.CommandStatus, CommandName);
  690.       break;
  691.     }
  692.   DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %u..%un",
  693.        Controller, Controller->ControllerNumber,
  694.        Command->LogicalDriveNumber, Command->BlockNumber,
  695.        Command->BlockNumber + Command->BlockCount - 1);
  696.   if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
  697.     DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %u..%un",
  698.  Controller, Controller->ControllerNumber,
  699.  Command->LogicalDriveNumber,
  700.  DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
  701.  Command->BufferHeader->b_rsector,
  702.  Command->BufferHeader->b_rsector + Command->BlockCount - 1);
  703. }
  704. /*
  705.   DAC960_V1_ProcessCompletedCommand performs completion processing for Command
  706.   for DAC960 V1 Firmware Controllers.
  707. */
  708. static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
  709. {
  710.   DAC960_Controller_T *Controller = Command->Controller;
  711.   DAC960_CommandType_T CommandType = Command->CommandType;
  712.   DAC960_V1_CommandOpcode_T CommandOpcode =
  713.     Command->V1.CommandMailbox.Common.CommandOpcode;
  714.   DAC960_V1_CommandStatus_T CommandStatus = Command->V1.CommandStatus;
  715.   BufferHeader_T *BufferHeader = Command->BufferHeader;
  716.   if (CommandType == DAC960_ReadCommand ||
  717.       CommandType == DAC960_WriteCommand)
  718.     {
  719.       if (CommandStatus == DAC960_V1_NormalCompletion)
  720. {
  721.   /*
  722.     Perform completion processing for all buffers in this I/O Request.
  723.   */
  724.   while (BufferHeader != NULL)
  725.     {
  726.       BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
  727.       BufferHeader->b_reqnext = NULL;
  728.       DAC960_ProcessCompletedBuffer(BufferHeader, true);
  729.       BufferHeader = NextBufferHeader;
  730.     }
  731.   if (Command->Completion != NULL)
  732.     {
  733.       complete(Command->Completion);
  734.       Command->Completion = NULL;
  735.     }
  736.   add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
  737. }
  738.       else if ((CommandStatus == DAC960_V1_IrrecoverableDataError ||
  739. CommandStatus == DAC960_V1_BadDataEncountered) &&
  740.        BufferHeader != NULL &&
  741.        BufferHeader->b_reqnext != NULL)
  742. {
  743.   DAC960_V1_CommandMailbox_T *CommandMailbox =
  744.     &Command->V1.CommandMailbox;
  745.   if (CommandType == DAC960_ReadCommand)
  746.     {
  747.       Command->CommandType = DAC960_ReadRetryCommand;
  748.       CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
  749.     }
  750.   else
  751.     {
  752.       Command->CommandType = DAC960_WriteRetryCommand;
  753.       CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
  754.     }
  755.   Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
  756.   CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
  757.   CommandMailbox->Type5.BusAddress =
  758.     Virtual_to_Bus32(BufferHeader->b_data);
  759.   DAC960_QueueCommand(Command);
  760.   return;
  761. }
  762.       else
  763. {
  764.   if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
  765.     DAC960_V1_ReadWriteError(Command);
  766.   /*
  767.     Perform completion processing for all buffers in this I/O Request.
  768.   */
  769.   while (BufferHeader != NULL)
  770.     {
  771.       BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
  772.       BufferHeader->b_reqnext = NULL;
  773.       DAC960_ProcessCompletedBuffer(BufferHeader, false);
  774.       BufferHeader = NextBufferHeader;
  775.     }
  776.   if (Command->Completion != NULL)
  777.     {
  778.       complete(Command->Completion);
  779.       Command->Completion = NULL;
  780.     }
  781. }
  782.     }
  783.   else if (CommandType == DAC960_ReadRetryCommand ||
  784.    CommandType == DAC960_WriteRetryCommand)
  785.     {
  786.       BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
  787.       BufferHeader->b_reqnext = NULL;
  788.       /*
  789. Perform completion processing for this single buffer.
  790.       */
  791.       if (CommandStatus == DAC960_V1_NormalCompletion)
  792. DAC960_ProcessCompletedBuffer(BufferHeader, true);
  793.       else
  794. {
  795.   if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
  796.     DAC960_V1_ReadWriteError(Command);
  797.   DAC960_ProcessCompletedBuffer(BufferHeader, false);
  798. }
  799.       if (NextBufferHeader != NULL)
  800. {
  801.   DAC960_V1_CommandMailbox_T *CommandMailbox =
  802.     &Command->V1.CommandMailbox;
  803.   Command->BlockNumber +=
  804.     BufferHeader->b_size >> DAC960_BlockSizeBits;
  805.   Command->BlockCount =
  806.     NextBufferHeader->b_size >> DAC960_BlockSizeBits;
  807.   Command->BufferHeader = NextBufferHeader;
  808.   CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
  809.   CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
  810.   CommandMailbox->Type5.BusAddress =
  811.     Virtual_to_Bus32(NextBufferHeader->b_data);
  812.   DAC960_QueueCommand(Command);
  813.   return;
  814. }
  815.     }
  816.   else if (CommandType == DAC960_MonitoringCommand ||
  817.    CommandOpcode == DAC960_V1_Enquiry ||
  818.    CommandOpcode == DAC960_V1_GetRebuildProgress)
  819.     {
  820.       if (CommandType != DAC960_MonitoringCommand)
  821. {
  822.   if (CommandOpcode == DAC960_V1_Enquiry)
  823.     memcpy(&Controller->V1.NewEnquiry,
  824.    Bus32_to_Virtual(Command->V1.CommandMailbox
  825.        .Type3.BusAddress),
  826.    sizeof(DAC960_V1_Enquiry_T));
  827.   else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
  828.     memcpy(&Controller->V1.RebuildProgress,
  829.    Bus32_to_Virtual(Command->V1.CommandMailbox
  830.        .Type3.BusAddress),
  831.    sizeof(DAC960_V1_RebuildProgress_T));
  832. }
  833.       if (CommandOpcode == DAC960_V1_Enquiry &&
  834.   Controller->ControllerInitialized)
  835. {
  836.   DAC960_V1_Enquiry_T *OldEnquiry = &Controller->V1.Enquiry;
  837.   DAC960_V1_Enquiry_T *NewEnquiry = &Controller->V1.NewEnquiry;
  838.   unsigned int OldCriticalLogicalDriveCount =
  839.     OldEnquiry->CriticalLogicalDriveCount;
  840.   unsigned int NewCriticalLogicalDriveCount =
  841.     NewEnquiry->CriticalLogicalDriveCount;
  842.   if (NewEnquiry->NumberOfLogicalDrives > Controller->LogicalDriveCount)
  843.     {
  844.       int LogicalDriveNumber = Controller->LogicalDriveCount - 1;
  845.       while (++LogicalDriveNumber < NewEnquiry->NumberOfLogicalDrives)
  846. DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
  847. "Now Existsn", Controller,
  848. LogicalDriveNumber,
  849. Controller->ControllerNumber,
  850. LogicalDriveNumber);
  851.       Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
  852.       DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
  853.     }
  854.   if (NewEnquiry->NumberOfLogicalDrives < Controller->LogicalDriveCount)
  855.     {
  856.       int LogicalDriveNumber = NewEnquiry->NumberOfLogicalDrives - 1;
  857.       while (++LogicalDriveNumber < Controller->LogicalDriveCount)
  858. DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
  859. "No Longer Existsn", Controller,
  860. LogicalDriveNumber,
  861. Controller->ControllerNumber,
  862. LogicalDriveNumber);
  863.       Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
  864.       DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
  865.     }
  866.   if (NewEnquiry->StatusFlags.DeferredWriteError !=
  867.       OldEnquiry->StatusFlags.DeferredWriteError)
  868.     DAC960_Critical("Deferred Write Error Flag is now %sn", Controller,
  869.     (NewEnquiry->StatusFlags.DeferredWriteError
  870.      ? "TRUE" : "FALSE"));
  871.   if ((NewCriticalLogicalDriveCount > 0 ||
  872.        NewCriticalLogicalDriveCount != OldCriticalLogicalDriveCount) ||
  873.       (NewEnquiry->OfflineLogicalDriveCount > 0 ||
  874.        NewEnquiry->OfflineLogicalDriveCount !=
  875.        OldEnquiry->OfflineLogicalDriveCount) ||
  876.       (NewEnquiry->DeadDriveCount > 0 ||
  877.        NewEnquiry->DeadDriveCount !=
  878.        OldEnquiry->DeadDriveCount) ||
  879.       (NewEnquiry->EventLogSequenceNumber !=
  880.        OldEnquiry->EventLogSequenceNumber) ||
  881.       Controller->MonitoringTimerCount == 0 ||
  882.       (jiffies - Controller->SecondaryMonitoringTime
  883.        >= DAC960_SecondaryMonitoringInterval))
  884.     {
  885.       Controller->V1.NeedLogicalDriveInformation = true;
  886.       Controller->V1.NewEventLogSequenceNumber =
  887. NewEnquiry->EventLogSequenceNumber;
  888.       Controller->V1.NeedErrorTableInformation = true;
  889.       Controller->V1.NeedDeviceStateInformation = true;
  890.       Controller->V1.StartDeviceStateScan = true;
  891.       Controller->V1.NeedBackgroundInitializationStatus =
  892. Controller->V1.BackgroundInitializationStatusSupported;
  893.       Controller->SecondaryMonitoringTime = jiffies;
  894.     }
  895.   if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
  896.       NewEnquiry->RebuildFlag
  897.       == DAC960_V1_BackgroundRebuildInProgress ||
  898.       OldEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
  899.       OldEnquiry->RebuildFlag == DAC960_V1_BackgroundRebuildInProgress)
  900.     {
  901.       Controller->V1.NeedRebuildProgress = true;
  902.       Controller->V1.RebuildProgressFirst =
  903. (NewEnquiry->CriticalLogicalDriveCount <
  904.  OldEnquiry->CriticalLogicalDriveCount);
  905.     }
  906.   if (OldEnquiry->RebuildFlag == DAC960_V1_BackgroundCheckInProgress)
  907.     switch (NewEnquiry->RebuildFlag)
  908.       {
  909.       case DAC960_V1_NoStandbyRebuildOrCheckInProgress:
  910. DAC960_Progress("Consistency Check Completed Successfullyn",
  911. Controller);
  912. break;
  913.       case DAC960_V1_StandbyRebuildInProgress:
  914.       case DAC960_V1_BackgroundRebuildInProgress:
  915. break;
  916.       case DAC960_V1_BackgroundCheckInProgress:
  917. Controller->V1.NeedConsistencyCheckProgress = true;
  918. break;
  919.       case DAC960_V1_StandbyRebuildCompletedWithError:
  920. DAC960_Progress("Consistency Check Completed with Errorn",
  921. Controller);
  922. break;
  923.       case DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed:
  924. DAC960_Progress("Consistency Check Failed - "
  925. "Physical Device Failedn", Controller);
  926. break;
  927.       case DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
  928. DAC960_Progress("Consistency Check Failed - "
  929. "Logical Drive Failedn", Controller);
  930. break;
  931.       case DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses:
  932. DAC960_Progress("Consistency Check Failed - Other Causesn",
  933. Controller);
  934. break;
  935.       case DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated:
  936. DAC960_Progress("Consistency Check Successfully Terminatedn",
  937. Controller);
  938. break;
  939.       }
  940.   else if (NewEnquiry->RebuildFlag
  941.    == DAC960_V1_BackgroundCheckInProgress)
  942.     Controller->V1.NeedConsistencyCheckProgress = true;
  943.   Controller->MonitoringAlertMode =
  944.     (NewEnquiry->CriticalLogicalDriveCount > 0 ||
  945.      NewEnquiry->OfflineLogicalDriveCount > 0 ||
  946.      NewEnquiry->DeadDriveCount > 0);
  947.   if (CommandType != DAC960_MonitoringCommand &&
  948.       Controller->V1.RebuildFlagPending)
  949.     {
  950.       DAC960_V1_Enquiry_T *Enquiry = (DAC960_V1_Enquiry_T *)
  951. Bus32_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress);
  952.       Enquiry->RebuildFlag = Controller->V1.PendingRebuildFlag;
  953.       Controller->V1.RebuildFlagPending = false;
  954.     }
  955.   else if (CommandType == DAC960_MonitoringCommand &&
  956.    NewEnquiry->RebuildFlag >
  957.    DAC960_V1_BackgroundCheckInProgress)
  958.     {
  959.       Controller->V1.PendingRebuildFlag = NewEnquiry->RebuildFlag;
  960.       Controller->V1.RebuildFlagPending = true;
  961.     }
  962.   memcpy(&Controller->V1.Enquiry, &Controller->V1.NewEnquiry,
  963.  sizeof(DAC960_V1_Enquiry_T));
  964. }
  965.       else if (CommandOpcode == DAC960_V1_PerformEventLogOperation)
  966. {
  967.   static char
  968.     *DAC960_EventMessages[] =
  969.        { "killed because write recovery failed",
  970.  "killed because of SCSI bus reset failure",
  971.  "killed because of double check condition",
  972.  "killed because it was removed",
  973.  "killed because of gross error on SCSI chip",
  974.  "killed because of bad tag returned from drive",
  975.  "killed because of timeout on SCSI command",
  976.  "killed because of reset SCSI command issued from system",
  977.  "killed because busy or parity error count exceeded limit",
  978.  "killed because of 'kill drive' command from system",
  979.  "killed because of selection timeout",
  980.  "killed due to SCSI phase sequence error",
  981.  "killed due to unknown status" };
  982.   DAC960_V1_EventLogEntry_T *EventLogEntry =
  983.     &Controller->V1.EventLogEntry;
  984.   if (EventLogEntry->SequenceNumber ==
  985.       Controller->V1.OldEventLogSequenceNumber)
  986.     {
  987.       unsigned char SenseKey = EventLogEntry->SenseKey;
  988.       unsigned char AdditionalSenseCode =
  989. EventLogEntry->AdditionalSenseCode;
  990.       unsigned char AdditionalSenseCodeQualifier =
  991. EventLogEntry->AdditionalSenseCodeQualifier;
  992.       if (SenseKey == DAC960_SenseKey_VendorSpecific &&
  993.   AdditionalSenseCode == 0x80 &&
  994.   AdditionalSenseCodeQualifier <
  995.   sizeof(DAC960_EventMessages) / sizeof(char *))
  996. DAC960_Critical("Physical Device %d:%d %sn", Controller,
  997. EventLogEntry->Channel,
  998. EventLogEntry->TargetID,
  999. DAC960_EventMessages[
  1000.   AdditionalSenseCodeQualifier]);
  1001.       else if (SenseKey == DAC960_SenseKey_UnitAttention &&
  1002.        AdditionalSenseCode == 0x29)
  1003. {
  1004.   if (Controller->MonitoringTimerCount > 0)
  1005.     Controller->V1.DeviceResetCount[EventLogEntry->Channel]
  1006.    [EventLogEntry->TargetID]++;
  1007. }
  1008.       else if (!(SenseKey == DAC960_SenseKey_NoSense ||
  1009.  (SenseKey == DAC960_SenseKey_NotReady &&
  1010.   AdditionalSenseCode == 0x04 &&
  1011.   (AdditionalSenseCodeQualifier == 0x01 ||
  1012.    AdditionalSenseCodeQualifier == 0x02))))
  1013. {
  1014.   DAC960_Critical("Physical Device %d:%d Error Log: "
  1015.   "Sense Key = %X, ASC = %02X, ASCQ = %02Xn",
  1016.   Controller,
  1017.   EventLogEntry->Channel,
  1018.   EventLogEntry->TargetID,
  1019.   SenseKey,
  1020.   AdditionalSenseCode,
  1021.   AdditionalSenseCodeQualifier);
  1022.   DAC960_Critical("Physical Device %d:%d Error Log: "
  1023.   "Information = %02X%02X%02X%02X "
  1024.   "%02X%02X%02X%02Xn",
  1025.   Controller,
  1026.   EventLogEntry->Channel,
  1027.   EventLogEntry->TargetID,
  1028.   EventLogEntry->Information[0],
  1029.   EventLogEntry->Information[1],
  1030.   EventLogEntry->Information[2],
  1031.   EventLogEntry->Information[3],
  1032.   EventLogEntry->CommandSpecificInformation[0],
  1033.   EventLogEntry->CommandSpecificInformation[1],
  1034.   EventLogEntry->CommandSpecificInformation[2],
  1035.   EventLogEntry->CommandSpecificInformation[3]);
  1036. }
  1037.     }
  1038.   Controller->V1.OldEventLogSequenceNumber++;
  1039. }
  1040.       else if (CommandOpcode == DAC960_V1_GetErrorTable)
  1041. {
  1042.   DAC960_V1_ErrorTable_T *OldErrorTable = &Controller->V1.ErrorTable;
  1043.   DAC960_V1_ErrorTable_T *NewErrorTable = &Controller->V1.NewErrorTable;
  1044.   int Channel, TargetID;
  1045.   for (Channel = 0; Channel < Controller->Channels; Channel++)
  1046.     for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
  1047.       {
  1048. DAC960_V1_ErrorTableEntry_T *NewErrorEntry =
  1049.   &NewErrorTable->ErrorTableEntries[Channel][TargetID];
  1050. DAC960_V1_ErrorTableEntry_T *OldErrorEntry =
  1051.   &OldErrorTable->ErrorTableEntries[Channel][TargetID];
  1052. if ((NewErrorEntry->ParityErrorCount !=
  1053.      OldErrorEntry->ParityErrorCount) ||
  1054.     (NewErrorEntry->SoftErrorCount !=
  1055.      OldErrorEntry->SoftErrorCount) ||
  1056.     (NewErrorEntry->HardErrorCount !=
  1057.      OldErrorEntry->HardErrorCount) ||
  1058.     (NewErrorEntry->MiscErrorCount !=
  1059.      OldErrorEntry->MiscErrorCount))
  1060.   DAC960_Critical("Physical Device %d:%d Errors: "
  1061.   "Parity = %d, Soft = %d, "
  1062.   "Hard = %d, Misc = %dn",
  1063.   Controller, Channel, TargetID,
  1064.   NewErrorEntry->ParityErrorCount,
  1065.   NewErrorEntry->SoftErrorCount,
  1066.   NewErrorEntry->HardErrorCount,
  1067.   NewErrorEntry->MiscErrorCount);
  1068.       }
  1069.   memcpy(&Controller->V1.ErrorTable, &Controller->V1.NewErrorTable,
  1070.  sizeof(DAC960_V1_ErrorTable_T));
  1071. }
  1072.       else if (CommandOpcode == DAC960_V1_GetDeviceState)
  1073. {
  1074.   DAC960_V1_DeviceState_T *OldDeviceState =
  1075.     &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
  1076.        [Controller->V1.DeviceStateTargetID];
  1077.   DAC960_V1_DeviceState_T *NewDeviceState =
  1078.     &Controller->V1.NewDeviceState;
  1079.   if (NewDeviceState->DeviceState != OldDeviceState->DeviceState)
  1080.     DAC960_Critical("Physical Device %d:%d is now %sn", Controller,
  1081.     Controller->V1.DeviceStateChannel,
  1082.     Controller->V1.DeviceStateTargetID,
  1083.     (NewDeviceState->DeviceState
  1084.      == DAC960_V1_Device_Dead
  1085.      ? "DEAD"
  1086.      : NewDeviceState->DeviceState
  1087.        == DAC960_V1_Device_WriteOnly
  1088.        ? "WRITE-ONLY"
  1089.        : NewDeviceState->DeviceState
  1090.  == DAC960_V1_Device_Online
  1091.  ? "ONLINE" : "STANDBY"));
  1092.   if (OldDeviceState->DeviceState == DAC960_V1_Device_Dead &&
  1093.       NewDeviceState->DeviceState != DAC960_V1_Device_Dead)
  1094.     {
  1095.       Controller->V1.NeedDeviceInquiryInformation = true;
  1096.       Controller->V1.NeedDeviceSerialNumberInformation = true;
  1097.       Controller->V1.DeviceResetCount
  1098.      [Controller->V1.DeviceStateChannel]
  1099.      [Controller->V1.DeviceStateTargetID] = 0;
  1100.     }
  1101.   memcpy(OldDeviceState, NewDeviceState,
  1102.  sizeof(DAC960_V1_DeviceState_T));
  1103. }
  1104.       else if (CommandOpcode == DAC960_V1_GetLogicalDriveInformation)
  1105. {
  1106.   int LogicalDriveNumber;
  1107.   for (LogicalDriveNumber = 0;
  1108.        LogicalDriveNumber < Controller->LogicalDriveCount;
  1109.        LogicalDriveNumber++)
  1110.     {
  1111.       DAC960_V1_LogicalDriveInformation_T *OldLogicalDriveInformation =
  1112. &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
  1113.       DAC960_V1_LogicalDriveInformation_T *NewLogicalDriveInformation =
  1114. &Controller->V1.NewLogicalDriveInformation[LogicalDriveNumber];
  1115.       if (NewLogicalDriveInformation->LogicalDriveState !=
  1116.   OldLogicalDriveInformation->LogicalDriveState)
  1117. DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
  1118. "is now %sn", Controller,
  1119. LogicalDriveNumber,
  1120. Controller->ControllerNumber,
  1121. LogicalDriveNumber,
  1122. (NewLogicalDriveInformation->LogicalDriveState
  1123.  == DAC960_V1_LogicalDrive_Online
  1124.  ? "ONLINE"
  1125.  : NewLogicalDriveInformation->LogicalDriveState
  1126.    == DAC960_V1_LogicalDrive_Critical
  1127.    ? "CRITICAL" : "OFFLINE"));
  1128.       if (NewLogicalDriveInformation->WriteBack !=
  1129.   OldLogicalDriveInformation->WriteBack)
  1130. DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
  1131. "is now %sn", Controller,
  1132. LogicalDriveNumber,
  1133. Controller->ControllerNumber,
  1134. LogicalDriveNumber,
  1135. (NewLogicalDriveInformation->WriteBack
  1136.  ? "WRITE BACK" : "WRITE THRU"));
  1137.     }
  1138.   memcpy(&Controller->V1.LogicalDriveInformation,
  1139.  &Controller->V1.NewLogicalDriveInformation,
  1140.  sizeof(DAC960_V1_LogicalDriveInformationArray_T));
  1141. }
  1142.       else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
  1143. {
  1144.   unsigned int LogicalDriveNumber =
  1145.     Controller->V1.RebuildProgress.LogicalDriveNumber;
  1146.   unsigned int LogicalDriveSize =
  1147.     Controller->V1.RebuildProgress.LogicalDriveSize;
  1148.   unsigned int BlocksCompleted =
  1149.     LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
  1150.   if (CommandStatus == DAC960_V1_NoRebuildOrCheckInProgress &&
  1151.       Controller->V1.LastRebuildStatus == DAC960_V1_NormalCompletion)
  1152.     CommandStatus = DAC960_V1_RebuildSuccessful;
  1153.   switch (CommandStatus)
  1154.     {
  1155.     case DAC960_V1_NormalCompletion:
  1156.       Controller->EphemeralProgressMessage = true;
  1157.       DAC960_Progress("Rebuild in Progress: "
  1158.       "Logical Drive %d (/dev/rd/c%dd%d) "
  1159.       "%d%% completedn",
  1160.       Controller, LogicalDriveNumber,
  1161.       Controller->ControllerNumber,
  1162.       LogicalDriveNumber,
  1163.       (100 * (BlocksCompleted >> 7))
  1164.       / (LogicalDriveSize >> 7));
  1165.       Controller->EphemeralProgressMessage = false;
  1166.       break;
  1167.     case DAC960_V1_RebuildFailed_LogicalDriveFailure:
  1168.       DAC960_Progress("Rebuild Failed due to "
  1169.       "Logical Drive Failuren", Controller);
  1170.       break;
  1171.     case DAC960_V1_RebuildFailed_BadBlocksOnOther:
  1172.       DAC960_Progress("Rebuild Failed due to "
  1173.       "Bad Blocks on Other Drivesn", Controller);
  1174.       break;
  1175.     case DAC960_V1_RebuildFailed_NewDriveFailed:
  1176.       DAC960_Progress("Rebuild Failed due to "
  1177.       "Failure of Drive Being Rebuiltn", Controller);
  1178.       break;
  1179.     case DAC960_V1_NoRebuildOrCheckInProgress:
  1180.       break;
  1181.     case DAC960_V1_RebuildSuccessful:
  1182.       DAC960_Progress("Rebuild Completed Successfullyn", Controller);
  1183.       break;
  1184.     case DAC960_V1_RebuildSuccessfullyTerminated:
  1185.       DAC960_Progress("Rebuild Successfully Terminatedn", Controller);
  1186.       break;
  1187.     }
  1188.   Controller->V1.LastRebuildStatus = CommandStatus;
  1189.   if (CommandType != DAC960_MonitoringCommand &&
  1190.       Controller->V1.RebuildStatusPending)
  1191.     {
  1192.       Command->V1.CommandStatus = Controller->V1.PendingRebuildStatus;
  1193.       Controller->V1.RebuildStatusPending = false;
  1194.     }
  1195.   else if (CommandType == DAC960_MonitoringCommand &&
  1196.    CommandStatus != DAC960_V1_NormalCompletion &&
  1197.    CommandStatus != DAC960_V1_NoRebuildOrCheckInProgress)
  1198.     {
  1199.       Controller->V1.PendingRebuildStatus = CommandStatus;
  1200.       Controller->V1.RebuildStatusPending = true;
  1201.     }
  1202. }
  1203.       else if (CommandOpcode == DAC960_V1_RebuildStat)
  1204. {
  1205.   unsigned int LogicalDriveNumber =
  1206.     Controller->V1.RebuildProgress.LogicalDriveNumber;
  1207.   unsigned int LogicalDriveSize =
  1208.     Controller->V1.RebuildProgress.LogicalDriveSize;
  1209.   unsigned int BlocksCompleted =
  1210.     LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
  1211.   if (CommandStatus == DAC960_V1_NormalCompletion)
  1212.     {
  1213.       Controller->EphemeralProgressMessage = true;
  1214.       DAC960_Progress("Consistency Check in Progress: "
  1215.       "Logical Drive %d (/dev/rd/c%dd%d) "
  1216.       "%d%% completedn",
  1217.       Controller, LogicalDriveNumber,
  1218.       Controller->ControllerNumber,
  1219.       LogicalDriveNumber,
  1220.       (100 * (BlocksCompleted >> 7))
  1221.       / (LogicalDriveSize >> 7));
  1222.       Controller->EphemeralProgressMessage = false;
  1223.     }
  1224. }
  1225.       else if (CommandOpcode == DAC960_V1_BackgroundInitializationControl)
  1226. {
  1227.   unsigned int LogicalDriveNumber =
  1228.     Controller->V1.BackgroundInitializationStatus.LogicalDriveNumber;
  1229.   unsigned int LogicalDriveSize =
  1230.     Controller->V1.BackgroundInitializationStatus.LogicalDriveSize;
  1231.   unsigned int BlocksCompleted =
  1232.     Controller->V1.BackgroundInitializationStatus.BlocksCompleted;
  1233.   switch (CommandStatus)
  1234.     {
  1235.     case DAC960_V1_NormalCompletion:
  1236.       switch (Controller->V1.BackgroundInitializationStatus.Status)
  1237. {
  1238. case DAC960_V1_BackgroundInitializationInvalid:
  1239.   break;
  1240. case DAC960_V1_BackgroundInitializationStarted:
  1241.   DAC960_Progress("Background Initialization Startedn",
  1242.   Controller);
  1243.   break;
  1244. case DAC960_V1_BackgroundInitializationInProgress:
  1245.   if (BlocksCompleted ==
  1246.       Controller->V1.LastBackgroundInitializationStatus
  1247.     .BlocksCompleted &&
  1248.       LogicalDriveNumber ==
  1249.       Controller->V1.LastBackgroundInitializationStatus
  1250.     .LogicalDriveNumber)
  1251.     break;
  1252.   Controller->EphemeralProgressMessage = true;
  1253.   DAC960_Progress("Background Initialization in Progress: "
  1254.   "Logical Drive %d (/dev/rd/c%dd%d) "
  1255.   "%d%% completedn",
  1256.   Controller, LogicalDriveNumber,
  1257.   Controller->ControllerNumber,
  1258.   LogicalDriveNumber,
  1259.   (100 * (BlocksCompleted >> 7))
  1260.   / (LogicalDriveSize >> 7));
  1261.   Controller->EphemeralProgressMessage = false;
  1262.   break;
  1263. case DAC960_V1_BackgroundInitializationSuspended:
  1264.   DAC960_Progress("Background Initialization Suspendedn",
  1265.   Controller);
  1266.   break;
  1267. case DAC960_V1_BackgroundInitializationCancelled:
  1268.   DAC960_Progress("Background Initialization Cancelledn",
  1269.   Controller);
  1270.   break;
  1271. }
  1272.       memcpy(&Controller->V1.LastBackgroundInitializationStatus,
  1273.      &Controller->V1.BackgroundInitializationStatus,
  1274.      sizeof(DAC960_V1_BackgroundInitializationStatus_T));
  1275.       break;
  1276.     case DAC960_V1_BackgroundInitSuccessful:
  1277.       if (Controller->V1.BackgroundInitializationStatus.Status ==
  1278.   DAC960_V1_BackgroundInitializationInProgress)
  1279. DAC960_Progress("Background Initialization "
  1280. "Completed Successfullyn", Controller);
  1281.       Controller->V1.BackgroundInitializationStatus.Status =
  1282. DAC960_V1_BackgroundInitializationInvalid;
  1283.       break;
  1284.     case DAC960_V1_BackgroundInitAborted:
  1285.       if (Controller->V1.BackgroundInitializationStatus.Status ==
  1286.   DAC960_V1_BackgroundInitializationInProgress)
  1287. DAC960_Progress("Background Initialization Abortedn",
  1288. Controller);
  1289.       Controller->V1.BackgroundInitializationStatus.Status =
  1290. DAC960_V1_BackgroundInitializationInvalid;
  1291.       break;
  1292.     case DAC960_V1_NoBackgroundInitInProgress:
  1293.       break;
  1294.     }
  1295. }
  1296.     }
  1297.   if (CommandType == DAC960_MonitoringCommand)
  1298.     {
  1299.       if (Controller->V1.NewEventLogSequenceNumber
  1300.   - Controller->V1.OldEventLogSequenceNumber > 0)
  1301. {
  1302.   Command->V1.CommandMailbox.Type3E.CommandOpcode =
  1303.     DAC960_V1_PerformEventLogOperation;
  1304.   Command->V1.CommandMailbox.Type3E.OperationType =
  1305.     DAC960_V1_GetEventLogEntry;
  1306.   Command->V1.CommandMailbox.Type3E.OperationQualifier = 1;
  1307.   Command->V1.CommandMailbox.Type3E.SequenceNumber =
  1308.     Controller->V1.OldEventLogSequenceNumber;
  1309.   Command->V1.CommandMailbox.Type3E.BusAddress =
  1310.     Virtual_to_Bus32(&Controller->V1.EventLogEntry);
  1311.   DAC960_QueueCommand(Command);
  1312.   return;
  1313. }
  1314.       if (Controller->V1.NeedErrorTableInformation)
  1315. {
  1316.   Controller->V1.NeedErrorTableInformation = false;
  1317.   Command->V1.CommandMailbox.Type3.CommandOpcode =
  1318.     DAC960_V1_GetErrorTable;
  1319.   Command->V1.CommandMailbox.Type3.BusAddress =
  1320.     Virtual_to_Bus32(&Controller->V1.NewErrorTable);
  1321.   DAC960_QueueCommand(Command);
  1322.   return;
  1323. }
  1324.       if (Controller->V1.NeedRebuildProgress &&
  1325.   Controller->V1.RebuildProgressFirst)
  1326. {
  1327.   Controller->V1.NeedRebuildProgress = false;
  1328.   Command->V1.CommandMailbox.Type3.CommandOpcode =
  1329.     DAC960_V1_GetRebuildProgress;
  1330.   Command->V1.CommandMailbox.Type3.BusAddress =
  1331.     Virtual_to_Bus32(&Controller->V1.RebuildProgress);
  1332.   DAC960_QueueCommand(Command);
  1333.   return;
  1334. }
  1335.       if (Controller->V1.NeedDeviceStateInformation)
  1336. {
  1337.   if (Controller->V1.NeedDeviceInquiryInformation)
  1338.     {
  1339.       DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
  1340.       DAC960_SCSI_Inquiry_T *InquiryStandardData =
  1341. &Controller->V1.InquiryStandardData
  1342. [Controller->V1.DeviceStateChannel]
  1343. [Controller->V1.DeviceStateTargetID];
  1344.       InquiryStandardData->PeripheralDeviceType = 0x1F;
  1345.       Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
  1346.       Command->V1.CommandMailbox.Type3.BusAddress =
  1347. Virtual_to_Bus32(DCDB);
  1348.       DCDB->Channel = Controller->V1.DeviceStateChannel;
  1349.       DCDB->TargetID = Controller->V1.DeviceStateTargetID;
  1350.       DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
  1351.       DCDB->EarlyStatus = false;
  1352.       DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
  1353.       DCDB->NoAutomaticRequestSense = false;
  1354.       DCDB->DisconnectPermitted = true;
  1355.       DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
  1356.       DCDB->BusAddress = Virtual_to_Bus32(InquiryStandardData);
  1357.       DCDB->CDBLength = 6;
  1358.       DCDB->TransferLengthHigh4 = 0;
  1359.       DCDB->SenseLength = sizeof(DCDB->SenseData);
  1360.       DCDB->CDB[0] = 0x12; /* INQUIRY */
  1361.       DCDB->CDB[1] = 0; /* EVPD = 0 */
  1362.       DCDB->CDB[2] = 0; /* Page Code */
  1363.       DCDB->CDB[3] = 0; /* Reserved */
  1364.       DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
  1365.       DCDB->CDB[5] = 0; /* Control */
  1366.       DAC960_QueueCommand(Command);
  1367.       Controller->V1.NeedDeviceInquiryInformation = false;
  1368.       return;
  1369.     }
  1370.   if (Controller->V1.NeedDeviceSerialNumberInformation)
  1371.     {
  1372.       DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
  1373.       DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
  1374. &Controller->V1.InquiryUnitSerialNumber
  1375. [Controller->V1.DeviceStateChannel]
  1376. [Controller->V1.DeviceStateTargetID];
  1377.       InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
  1378.       Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
  1379.       Command->V1.CommandMailbox.Type3.BusAddress =
  1380. Virtual_to_Bus32(DCDB);
  1381.       DCDB->Channel = Controller->V1.DeviceStateChannel;
  1382.       DCDB->TargetID = Controller->V1.DeviceStateTargetID;
  1383.       DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
  1384.       DCDB->EarlyStatus = false;
  1385.       DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
  1386.       DCDB->NoAutomaticRequestSense = false;
  1387.       DCDB->DisconnectPermitted = true;
  1388.       DCDB->TransferLength =
  1389. sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
  1390.       DCDB->BusAddress = Virtual_to_Bus32(InquiryUnitSerialNumber);
  1391.       DCDB->CDBLength = 6;
  1392.       DCDB->TransferLengthHigh4 = 0;
  1393.       DCDB->SenseLength = sizeof(DCDB->SenseData);
  1394.       DCDB->CDB[0] = 0x12; /* INQUIRY */
  1395.       DCDB->CDB[1] = 1; /* EVPD = 1 */
  1396.       DCDB->CDB[2] = 0x80; /* Page Code */
  1397.       DCDB->CDB[3] = 0; /* Reserved */
  1398.       DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
  1399.       DCDB->CDB[5] = 0; /* Control */
  1400.       DAC960_QueueCommand(Command);
  1401.       Controller->V1.NeedDeviceSerialNumberInformation = false;
  1402.       return;
  1403.     }
  1404.   if (Controller->V1.StartDeviceStateScan)
  1405.     {
  1406.       Controller->V1.DeviceStateChannel = 0;
  1407.       Controller->V1.DeviceStateTargetID = 0;
  1408.       Controller->V1.StartDeviceStateScan = false;
  1409.     }
  1410.   else if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
  1411.     {
  1412.       Controller->V1.DeviceStateChannel++;
  1413.       Controller->V1.DeviceStateTargetID = 0;
  1414.     }
  1415.   if (Controller->V1.DeviceStateChannel < Controller->Channels)
  1416.     {
  1417.       Controller->V1.NewDeviceState.DeviceState =
  1418. DAC960_V1_Device_Dead;
  1419.       Command->V1.CommandMailbox.Type3D.CommandOpcode =
  1420. DAC960_V1_GetDeviceState;
  1421.       Command->V1.CommandMailbox.Type3D.Channel =
  1422. Controller->V1.DeviceStateChannel;
  1423.       Command->V1.CommandMailbox.Type3D.TargetID =
  1424. Controller->V1.DeviceStateTargetID;
  1425.       Command->V1.CommandMailbox.Type3D.BusAddress =
  1426. Virtual_to_Bus32(&Controller->V1.NewDeviceState);
  1427.       DAC960_QueueCommand(Command);
  1428.       return;
  1429.     }
  1430.   Controller->V1.NeedDeviceStateInformation = false;
  1431. }
  1432.       if (Controller->V1.NeedLogicalDriveInformation)
  1433. {
  1434.   Controller->V1.NeedLogicalDriveInformation = false;
  1435.   Command->V1.CommandMailbox.Type3.CommandOpcode =
  1436.     DAC960_V1_GetLogicalDriveInformation;
  1437.   Command->V1.CommandMailbox.Type3.BusAddress =
  1438.     Virtual_to_Bus32(&Controller->V1.NewLogicalDriveInformation);
  1439.   DAC960_QueueCommand(Command);
  1440.   return;
  1441. }
  1442.       if (Controller->V1.NeedRebuildProgress)
  1443. {
  1444.   Controller->V1.NeedRebuildProgress = false;
  1445.   Command->V1.CommandMailbox.Type3.CommandOpcode =
  1446.     DAC960_V1_GetRebuildProgress;
  1447.   Command->V1.CommandMailbox.Type3.BusAddress =
  1448.     Virtual_to_Bus32(&Controller->V1.RebuildProgress);
  1449.   DAC960_QueueCommand(Command);
  1450.   return;
  1451. }
  1452.       if (Controller->V1.NeedConsistencyCheckProgress)
  1453. {
  1454.   Controller->V1.NeedConsistencyCheckProgress = false;
  1455.   Command->V1.CommandMailbox.Type3.CommandOpcode =
  1456.     DAC960_V1_RebuildStat;
  1457.   Command->V1.CommandMailbox.Type3.BusAddress =
  1458.     Virtual_to_Bus32(&Controller->V1.RebuildProgress);
  1459.   DAC960_QueueCommand(Command);
  1460.   return;
  1461. }
  1462.       if (Controller->V1.NeedBackgroundInitializationStatus)
  1463. {
  1464.   Controller->V1.NeedBackgroundInitializationStatus = false;
  1465.   Command->V1.CommandMailbox.Type3B.CommandOpcode =
  1466.     DAC960_V1_BackgroundInitializationControl;
  1467.   Command->V1.CommandMailbox.Type3B.CommandOpcode2 = 0x20;
  1468.   Command->V1.CommandMailbox.Type3B.BusAddress =
  1469.     Virtual_to_Bus32(&Controller->V1.BackgroundInitializationStatus);
  1470.   DAC960_QueueCommand(Command);
  1471.   return;
  1472. }
  1473.       Controller->MonitoringTimerCount++;
  1474.       Controller->MonitoringTimer.expires =
  1475. jiffies + DAC960_MonitoringTimerInterval;
  1476.       add_timer(&Controller->MonitoringTimer);
  1477.     }
  1478.   if (CommandType == DAC960_ImmediateCommand)
  1479.     {
  1480.       complete(Command->Completion);
  1481.       Command->Completion = NULL;
  1482.       return;
  1483.     }
  1484.   if (CommandType == DAC960_QueuedCommand)
  1485.     {
  1486.       DAC960_V1_KernelCommand_T *KernelCommand = Command->V1.KernelCommand;
  1487.       KernelCommand->CommandStatus = Command->V1.CommandStatus;
  1488.       Command->V1.KernelCommand = NULL;
  1489.       if (CommandOpcode == DAC960_V1_DCDB)
  1490. Controller->V1.DirectCommandActive[KernelCommand->DCDB->Channel]
  1491.   [KernelCommand->DCDB->TargetID] =
  1492.   false;
  1493.       DAC960_DeallocateCommand(Command);
  1494.       KernelCommand->CompletionFunction(KernelCommand);
  1495.       return;
  1496.     }
  1497.   /*
  1498.     Queue a Status Monitoring Command to the Controller using the just
  1499.     completed Command if one was deferred previously due to lack of a
  1500.     free Command when the Monitoring Timer Function was called.
  1501.   */
  1502.   if (Controller->MonitoringCommandDeferred)
  1503.     {
  1504.       Controller->MonitoringCommandDeferred = false;
  1505.       DAC960_V1_QueueMonitoringCommand(Command);
  1506.       return;
  1507.     }
  1508.   /*
  1509.     Deallocate the Command.
  1510.   */
  1511.   DAC960_DeallocateCommand(Command);
  1512.   /*
  1513.     Wake up any processes waiting on a free Command.
  1514.   */
  1515.   wake_up(&Controller->CommandWaitQueue);
  1516. }
  1517. /*
  1518.   DAC960_V2_ReadWriteError prints an appropriate error message for Command
  1519.   when an error occurs on a Read or Write operation.
  1520. */
  1521. static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
  1522. {
  1523.   DAC960_Controller_T *Controller = Command->Controller;
  1524.   unsigned char *SenseErrors[] = { "NO SENSE", "RECOVERED ERROR",
  1525.    "NOT READY", "MEDIUM ERROR",
  1526.    "HARDWARE ERROR", "ILLEGAL REQUEST",
  1527.    "UNIT ATTENTION", "DATA PROTECT",
  1528.    "BLANK CHECK", "VENDOR-SPECIFIC",
  1529.    "COPY ABORTED", "ABORTED COMMAND",
  1530.    "EQUAL", "VOLUME OVERFLOW",
  1531.    "MISCOMPARE", "RESERVED" };
  1532.   unsigned char *CommandName = "UNKNOWN";
  1533.   switch (Command->CommandType)
  1534.     {
  1535.     case DAC960_ReadCommand:
  1536.     case DAC960_ReadRetryCommand:
  1537.       CommandName = "READ";
  1538.       break;
  1539.     case DAC960_WriteCommand:
  1540.     case DAC960_WriteRetryCommand:
  1541.       CommandName = "WRITE";
  1542.       break;
  1543.     case DAC960_MonitoringCommand:
  1544.     case DAC960_ImmediateCommand:
  1545.     case DAC960_QueuedCommand:
  1546.       break;
  1547.     }
  1548.   DAC960_Error("Error Condition %s on %s:n", Controller,
  1549.        SenseErrors[Command->V2.RequestSense.SenseKey], CommandName);
  1550.   DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %u..%un",
  1551.        Controller, Controller->ControllerNumber,
  1552.        Command->LogicalDriveNumber, Command->BlockNumber,
  1553.        Command->BlockNumber + Command->BlockCount - 1);
  1554.   if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
  1555.     DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %u..%un",
  1556.  Controller, Controller->ControllerNumber,
  1557.  Command->LogicalDriveNumber,
  1558.  DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
  1559.  Command->BufferHeader->b_rsector,
  1560.  Command->BufferHeader->b_rsector + Command->BlockCount - 1);
  1561. }
  1562. /*
  1563.   DAC960_V2_ReportEvent prints an appropriate message when a Controller Event
  1564.   occurs.
  1565. */
  1566. static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
  1567.   DAC960_V2_Event_T *Event)
  1568. {
  1569.   DAC960_SCSI_RequestSense_T *RequestSense =
  1570.     (DAC960_SCSI_RequestSense_T *) &Event->RequestSenseData;
  1571.   unsigned char MessageBuffer[DAC960_LineBufferSize];
  1572.   static struct { int EventCode; unsigned char *EventMessage; } EventList[] =
  1573.     { /* Physical Device Events (0x0000 - 0x007F) */
  1574.       { 0x0001, "P Online" },
  1575.       { 0x0002, "P Standby" },
  1576.       { 0x0005, "P Automatic Rebuild Started" },
  1577.       { 0x0006, "P Manual Rebuild Started" },
  1578.       { 0x0007, "P Rebuild Completed" },
  1579.       { 0x0008, "P Rebuild Cancelled" },
  1580.       { 0x0009, "P Rebuild Failed for Unknown Reasons" },
  1581.       { 0x000A, "P Rebuild Failed due to New Physical Device" },
  1582.       { 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
  1583.       { 0x000C, "S Offline" },
  1584.       { 0x000D, "P Found" },
  1585.       { 0x000E, "P Removed" },
  1586.       { 0x000F, "P Unconfigured" },
  1587.       { 0x0010, "P Expand Capacity Started" },
  1588.       { 0x0011, "P Expand Capacity Completed" },
  1589.       { 0x0012, "P Expand Capacity Failed" },
  1590.       { 0x0013, "P Command Timed Out" },
  1591.       { 0x0014, "P Command Aborted" },
  1592.       { 0x0015, "P Command Retried" },
  1593.       { 0x0016, "P Parity Error" },
  1594.       { 0x0017, "P Soft Error" },
  1595.       { 0x0018, "P Miscellaneous Error" },
  1596.       { 0x0019, "P Reset" },
  1597.       { 0x001A, "P Active Spare Found" },
  1598.       { 0x001B, "P Warm Spare Found" },
  1599.       { 0x001C, "S Sense Data Received" },
  1600.       { 0x001D, "P Initialization Started" },
  1601.       { 0x001E, "P Initialization Completed" },
  1602.       { 0x001F, "P Initialization Failed" },
  1603.       { 0x0020, "P Initialization Cancelled" },
  1604.       { 0x0021, "P Failed because Write Recovery Failed" },
  1605.       { 0x0022, "P Failed because SCSI Bus Reset Failed" },
  1606.       { 0x0023, "P Failed because of Double Check Condition" },
  1607.       { 0x0024, "P Failed because Device Cannot Be Accessed" },
  1608.       { 0x0025, "P Failed because of Gross Error on SCSI Processor" },
  1609.       { 0x0026, "P Failed because of Bad Tag from Device" },
  1610.       { 0x0027, "P Failed because of Command Timeout" },
  1611.       { 0x0028, "P Failed because of System Reset" },
  1612.       { 0x0029, "P Failed because of Busy Status or Parity Error" },
  1613.       { 0x002A, "P Failed because Host Set Device to Failed State" },
  1614.       { 0x002B, "P Failed because of Selection Timeout" },
  1615.       { 0x002C, "P Failed because of SCSI Bus Phase Error" },
  1616.       { 0x002D, "P Failed because Device Returned Unknown Status" },
  1617.       { 0x002E, "P Failed because Device Not Ready" },
  1618.       { 0x002F, "P Failed because Device Not Found at Startup" },
  1619.       { 0x0030, "P Failed because COD Write Operation Failed" },
  1620.       { 0x0031, "P Failed because BDT Write Operation Failed" },
  1621.       { 0x0039, "P Missing at Startup" },
  1622.       { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
  1623.       { 0x003C, "P Temporarily Offline Device Automatically Made Online" },
  1624.       { 0x003D, "P Standby Rebuild Started" },
  1625.       /* Logical Device Events (0x0080 - 0x00FF) */
  1626.       { 0x0080, "M Consistency Check Started" },
  1627.       { 0x0081, "M Consistency Check Completed" },
  1628.       { 0x0082, "M Consistency Check Cancelled" },
  1629.       { 0x0083, "M Consistency Check Completed With Errors" },
  1630.       { 0x0084, "M Consistency Check Failed due to Logical Drive Failure" },
  1631.       { 0x0085, "M Consistency Check Failed due to Physical Device Failure" },
  1632.       { 0x0086, "L Offline" },
  1633.       { 0x0087, "L Critical" },
  1634.       { 0x0088, "L Online" },
  1635.       { 0x0089, "M Automatic Rebuild Started" },
  1636.       { 0x008A, "M Manual Rebuild Started" },
  1637.       { 0x008B, "M Rebuild Completed" },
  1638.       { 0x008C, "M Rebuild Cancelled" },
  1639.       { 0x008D, "M Rebuild Failed for Unknown Reasons" },
  1640.       { 0x008E, "M Rebuild Failed due to New Physical Device" },
  1641.       { 0x008F, "M Rebuild Failed due to Logical Drive Failure" },
  1642.       { 0x0090, "M Initialization Started" },
  1643.       { 0x0091, "M Initialization Completed" },
  1644.       { 0x0092, "M Initialization Cancelled" },
  1645.       { 0x0093, "M Initialization Failed" },
  1646.       { 0x0094, "L Found" },
  1647.       { 0x0095, "L Deleted" },
  1648.       { 0x0096, "M Expand Capacity Started" },
  1649.       { 0x0097, "M Expand Capacity Completed" },
  1650.       { 0x0098, "M Expand Capacity Failed" },
  1651.       { 0x0099, "L Bad Block Found" },
  1652.       { 0x009A, "L Size Changed" },
  1653.       { 0x009B, "L Type Changed" },
  1654.       { 0x009C, "L Bad Data Block Found" },
  1655.       { 0x009E, "L Read of Data Block in BDT" },
  1656.       { 0x009F, "L Write Back Data for Disk Block Lost" },
  1657.       { 0x00A0, "L Temporarily Offline RAID-5/3 Drive Made Online" },
  1658.       { 0x00A1, "L Temporarily Offline RAID-6/1/0/7 Drive Made Online" },
  1659.       { 0x00A2, "L Standby Rebuild Started" },
  1660.       /* Fault Management Events (0x0100 - 0x017F) */
  1661.       { 0x0140, "E Fan %d Failed" },
  1662.       { 0x0141, "E Fan %d OK" },
  1663.       { 0x0142, "E Fan %d Not Present" },
  1664.       { 0x0143, "E Power Supply %d Failed" },
  1665.       { 0x0144, "E Power Supply %d OK" },
  1666.       { 0x0145, "E Power Supply %d Not Present" },
  1667.       { 0x0146, "E Temperature Sensor %d Temperature Exceeds Safe Limit" },
  1668.       { 0x0147, "E Temperature Sensor %d Temperature Exceeds Working Limit" },
  1669.       { 0x0148, "E Temperature Sensor %d Temperature Normal" },
  1670.       { 0x0149, "E Temperature Sensor %d Not Present" },
  1671.       { 0x014A, "E Enclosure Management Unit %d Access Critical" },
  1672.       { 0x014B, "E Enclosure Management Unit %d Access OK" },
  1673.       { 0x014C, "E Enclosure Management Unit %d Access Offline" },
  1674.       /* Controller Events (0x0180 - 0x01FF) */
  1675.       { 0x0181, "C Cache Write Back Error" },
  1676.       { 0x0188, "C Battery Backup Unit Found" },
  1677.       { 0x0189, "C Battery Backup Unit Charge Level Low" },
  1678.       { 0x018A, "C Battery Backup Unit Charge Level OK" },
  1679.       { 0x0193, "C Installation Aborted" },
  1680.       { 0x0195, "C Battery Backup Unit Physically Removed" },
  1681.       { 0x0196, "C Memory Error During Warm Boot" },
  1682.       { 0x019E, "C Memory Soft ECC Error Corrected" },
  1683.       { 0x019F, "C Memory Hard ECC Error Corrected" },
  1684.       { 0x01A2, "C Battery Backup Unit Failed" },
  1685.       { 0x01AB, "C Mirror Race Recovery Failed" },
  1686.       { 0x01AC, "C Mirror Race on Critical Drive" },
  1687.       /* Controller Internal Processor Events */
  1688.       { 0x0380, "C Internal Controller Hung" },
  1689.       { 0x0381, "C Internal Controller Firmware Breakpoint" },
  1690.       { 0x0390, "C Internal Controller i960 Processor Specific Error" },
  1691.       { 0x03A0, "C Internal Controller StrongARM Processor Specific Error" },
  1692.       { 0, "" } };
  1693.   int EventListIndex = 0, EventCode;
  1694.   unsigned char EventType, *EventMessage;
  1695.   if (Event->EventCode == 0x1C &&
  1696.       RequestSense->SenseKey == DAC960_SenseKey_VendorSpecific &&
  1697.       (RequestSense->AdditionalSenseCode == 0x80 ||
  1698.        RequestSense->AdditionalSenseCode == 0x81))
  1699.     Event->EventCode = ((RequestSense->AdditionalSenseCode - 0x80) << 8) |
  1700.        RequestSense->AdditionalSenseCodeQualifier;
  1701.   while (true)
  1702.     {
  1703.       EventCode = EventList[EventListIndex].EventCode;
  1704.       if (EventCode == Event->EventCode || EventCode == 0) break;
  1705.       EventListIndex++;
  1706.     }
  1707.   EventType = EventList[EventListIndex].EventMessage[0];
  1708.   EventMessage = &EventList[EventListIndex].EventMessage[2];
  1709.   if (EventCode == 0)
  1710.     {
  1711.       DAC960_Critical("Unknown Controller Event Code %04Xn",
  1712.       Controller, Event->EventCode);
  1713.       return;
  1714.     }
  1715.   switch (EventType)
  1716.     {
  1717.     case 'P':
  1718.       DAC960_Critical("Physical Device %d:%d %sn", Controller,
  1719.       Event->Channel, Event->TargetID, EventMessage);
  1720.       break;
  1721.     case 'L':
  1722.       DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) %sn", Controller,
  1723.       Event->LogicalUnit, Controller->ControllerNumber,
  1724.       Event->LogicalUnit, EventMessage);
  1725.       break;
  1726.     case 'M':
  1727.       DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) %sn", Controller,
  1728.       Event->LogicalUnit, Controller->ControllerNumber,
  1729.       Event->LogicalUnit, EventMessage);
  1730.       break;
  1731.     case 'S':
  1732.       if (RequestSense->SenseKey == DAC960_SenseKey_NoSense ||
  1733.   (RequestSense->SenseKey == DAC960_SenseKey_NotReady &&
  1734.    RequestSense->AdditionalSenseCode == 0x04 &&
  1735.    (RequestSense->AdditionalSenseCodeQualifier == 0x01 ||
  1736.     RequestSense->AdditionalSenseCodeQualifier == 0x02)))
  1737. break;
  1738.       DAC960_Critical("Physical Device %d:%d %sn", Controller,
  1739.       Event->Channel, Event->TargetID, EventMessage);
  1740.       DAC960_Critical("Physical Device %d:%d Request Sense: "
  1741.       "Sense Key = %X, ASC = %02X, ASCQ = %02Xn",
  1742.       Controller,
  1743.       Event->Channel,
  1744.       Event->TargetID,
  1745.       RequestSense->SenseKey,
  1746.       RequestSense->AdditionalSenseCode,
  1747.       RequestSense->AdditionalSenseCodeQualifier);
  1748.       DAC960_Critical("Physical Device %d:%d Request Sense: "
  1749.       "Information = %02X%02X%02X%02X "
  1750.       "%02X%02X%02X%02Xn",
  1751.       Controller,
  1752.       Event->Channel,
  1753.       Event->TargetID,
  1754.       RequestSense->Information[0],
  1755.       RequestSense->Information[1],
  1756.       RequestSense->Information[2],
  1757.       RequestSense->Information[3],
  1758.       RequestSense->CommandSpecificInformation[0],
  1759.       RequestSense->CommandSpecificInformation[1],
  1760.       RequestSense->CommandSpecificInformation[2],
  1761.       RequestSense->CommandSpecificInformation[3]);
  1762.       break;
  1763.     case 'E':
  1764.       if (Controller->SuppressEnclosureMessages) break;
  1765.       sprintf(MessageBuffer, EventMessage, Event->LogicalUnit);
  1766.       DAC960_Critical("Enclosure %d %sn", Controller,
  1767.       Event->TargetID, MessageBuffer);
  1768.       break;
  1769.     case 'C':
  1770.       DAC960_Critical("Controller %sn", Controller, EventMessage);
  1771.       break;
  1772.     default:
  1773.       DAC960_Critical("Unknown Controller Event Code %04Xn",
  1774.       Controller, Event->EventCode);
  1775.       break;
  1776.     }
  1777. }
  1778. /*
  1779.   DAC960_V2_ReportProgress prints an appropriate progress message for
  1780.   Logical Device Long Operations.
  1781. */
  1782. static void DAC960_V2_ReportProgress(DAC960_Controller_T *Controller,
  1783.      unsigned char *MessageString,
  1784.      unsigned int LogicalDeviceNumber,
  1785.      unsigned long BlocksCompleted,
  1786.      unsigned long LogicalDeviceSize)
  1787. {
  1788.   Controller->EphemeralProgressMessage = true;
  1789.   DAC960_Progress("%s in Progress: Logical Drive %d (/dev/rd/c%dd%d) "
  1790.   "%d%% completedn", Controller,
  1791.   MessageString,
  1792.   LogicalDeviceNumber,
  1793.   Controller->ControllerNumber,
  1794.   LogicalDeviceNumber,
  1795.   (100 * (BlocksCompleted >> 7)) / (LogicalDeviceSize >> 7));
  1796.   Controller->EphemeralProgressMessage = false;
  1797. }
  1798. /*
  1799.   DAC960_V2_ProcessCompletedCommand performs completion processing for Command
  1800.   for DAC960 V2 Firmware Controllers.
  1801. */
  1802. static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
  1803. {
  1804.   DAC960_Controller_T *Controller = Command->Controller;
  1805.   DAC960_CommandType_T CommandType = Command->CommandType;
  1806.   DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
  1807.   DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode;
  1808.   DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus;
  1809.   BufferHeader_T *BufferHeader = Command->BufferHeader;
  1810.   if (CommandType == DAC960_ReadCommand ||
  1811.       CommandType == DAC960_WriteCommand)
  1812.     {
  1813.       if (CommandStatus == DAC960_V2_NormalCompletion)
  1814. {
  1815.   /*
  1816.     Perform completion processing for all buffers in this I/O Request.
  1817.   */
  1818.   while (BufferHeader != NULL)
  1819.     {
  1820.       BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
  1821.       BufferHeader->b_reqnext = NULL;
  1822.       DAC960_ProcessCompletedBuffer(BufferHeader, true);
  1823.       BufferHeader = NextBufferHeader;
  1824.     }
  1825.   if (Command->Completion != NULL)
  1826.     {
  1827.       complete(Command->Completion);
  1828.       Command->Completion = NULL;
  1829.     }
  1830.   add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
  1831. }
  1832.       else if (Command->V2.RequestSense.SenseKey
  1833.        == DAC960_SenseKey_MediumError &&
  1834.        BufferHeader != NULL &&
  1835.        BufferHeader->b_reqnext != NULL)
  1836. {
  1837.   if (CommandType == DAC960_ReadCommand)
  1838.     Command->CommandType = DAC960_ReadRetryCommand;
  1839.   else Command->CommandType = DAC960_WriteRetryCommand;
  1840.   Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
  1841.   CommandMailbox->SCSI_10.CommandControlBits
  1842.  .AdditionalScatterGatherListMemory = false;
  1843.   CommandMailbox->SCSI_10.DataTransferSize =
  1844.     Command->BlockCount << DAC960_BlockSizeBits;
  1845.   CommandMailbox->SCSI_10.DataTransferMemoryAddress
  1846.  .ScatterGatherSegments[0].SegmentDataPointer =
  1847.     Virtual_to_Bus64(BufferHeader->b_data);
  1848.   CommandMailbox->SCSI_10.DataTransferMemoryAddress
  1849.  .ScatterGatherSegments[0].SegmentByteCount =
  1850.     CommandMailbox->SCSI_10.DataTransferSize;
  1851.   CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
  1852.   CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
  1853.   DAC960_QueueCommand(Command);
  1854.   return;
  1855. }
  1856.       else
  1857. {
  1858.   if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
  1859.     DAC960_V2_ReadWriteError(Command);
  1860.   /*
  1861.     Perform completion processing for all buffers in this I/O Request.
  1862.   */
  1863.   while (BufferHeader != NULL)
  1864.     {
  1865.       BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
  1866.       BufferHeader->b_reqnext = NULL;
  1867.       DAC960_ProcessCompletedBuffer(BufferHeader, false);
  1868.       BufferHeader = NextBufferHeader;
  1869.     }
  1870.   if (Command->Completion != NULL)
  1871.     {
  1872.       complete(Command->Completion);
  1873.       Command->Completion = NULL;
  1874.     }
  1875. }
  1876.     }
  1877.   else if (CommandType == DAC960_ReadRetryCommand ||
  1878.    CommandType == DAC960_WriteRetryCommand)
  1879.     {
  1880.       BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
  1881.       BufferHeader->b_reqnext = NULL;
  1882.       /*
  1883. Perform completion processing for this single buffer.
  1884.       */
  1885.       if (CommandStatus == DAC960_V2_NormalCompletion)
  1886. DAC960_ProcessCompletedBuffer(BufferHeader, true);
  1887.       else
  1888. {
  1889.   if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
  1890.     DAC960_V2_ReadWriteError(Command);
  1891.   DAC960_ProcessCompletedBuffer(BufferHeader, false);
  1892. }
  1893.       if (NextBufferHeader != NULL)
  1894. {
  1895.   Command->BlockNumber +=
  1896.     BufferHeader->b_size >> DAC960_BlockSizeBits;
  1897.   Command->BlockCount =
  1898.     NextBufferHeader->b_size >> DAC960_BlockSizeBits;
  1899.   Command->BufferHeader = NextBufferHeader;
  1900.   CommandMailbox->SCSI_10.DataTransferSize =
  1901.     Command->BlockCount << DAC960_BlockSizeBits;
  1902.   CommandMailbox->SCSI_10.DataTransferMemoryAddress
  1903.  .ScatterGatherSegments[0]
  1904.  .SegmentDataPointer =
  1905.     Virtual_to_Bus64(NextBufferHeader->b_data);
  1906.   CommandMailbox->SCSI_10.DataTransferMemoryAddress
  1907.  .ScatterGatherSegments[0]
  1908.  .SegmentByteCount =
  1909.     CommandMailbox->SCSI_10.DataTransferSize;
  1910.   CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
  1911.   CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
  1912.   CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
  1913.   CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
  1914.   CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
  1915.   CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
  1916.   DAC960_QueueCommand(Command);
  1917.   return;
  1918. }
  1919.     }
  1920.   else if (CommandType == DAC960_MonitoringCommand)
  1921.     {
  1922.       if (CommandOpcode == DAC960_V2_GetControllerInfo)
  1923. {
  1924.   DAC960_V2_ControllerInfo_T *NewControllerInfo =
  1925.     &Controller->V2.NewControllerInformation;
  1926.   DAC960_V2_ControllerInfo_T *ControllerInfo =
  1927.     &Controller->V2.ControllerInformation;
  1928.   Controller->LogicalDriveCount =
  1929.     NewControllerInfo->LogicalDevicesPresent;
  1930.   Controller->V2.NeedLogicalDeviceInformation = true;
  1931.   Controller->V2.NeedPhysicalDeviceInformation = true;
  1932.   Controller->V2.StartLogicalDeviceInformationScan = true;
  1933.   Controller->V2.StartPhysicalDeviceInformationScan = true;
  1934.   Controller->MonitoringAlertMode =
  1935.     (NewControllerInfo->LogicalDevicesCritical > 0 ||
  1936.      NewControllerInfo->LogicalDevicesOffline > 0 ||
  1937.      NewControllerInfo->PhysicalDisksCritical > 0 ||
  1938.      NewControllerInfo->PhysicalDisksOffline > 0);
  1939.   memcpy(ControllerInfo, NewControllerInfo,
  1940.  sizeof(DAC960_V2_ControllerInfo_T));
  1941. }
  1942.       else if (CommandOpcode == DAC960_V2_GetEvent)
  1943. {
  1944.   if (CommandStatus == DAC960_V2_NormalCompletion)
  1945.     DAC960_V2_ReportEvent(Controller, &Controller->V2.Event);
  1946.   Controller->V2.NextEventSequenceNumber++;
  1947. }
  1948.       else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
  1949.        CommandStatus == DAC960_V2_NormalCompletion)
  1950. {
  1951.   DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
  1952.     &Controller->V2.NewPhysicalDeviceInformation;
  1953.   unsigned int PhysicalDeviceIndex = Controller->V2.PhysicalDeviceIndex;
  1954.   DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
  1955.     Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
  1956.   DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
  1957.     Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
  1958.   unsigned int DeviceIndex;
  1959.   while (PhysicalDeviceInfo != NULL &&
  1960.  (NewPhysicalDeviceInfo->Channel >
  1961.   PhysicalDeviceInfo->Channel ||
  1962.   (NewPhysicalDeviceInfo->Channel ==
  1963.    PhysicalDeviceInfo->Channel &&
  1964.    (NewPhysicalDeviceInfo->TargetID >
  1965.     PhysicalDeviceInfo->TargetID ||
  1966.    (NewPhysicalDeviceInfo->TargetID ==
  1967.     PhysicalDeviceInfo->TargetID &&
  1968.     NewPhysicalDeviceInfo->LogicalUnit >
  1969.     PhysicalDeviceInfo->LogicalUnit)))))
  1970.     {
  1971.       DAC960_Critical("Physical Device %d:%d No Longer Existsn",
  1972.       Controller,
  1973.       PhysicalDeviceInfo->Channel,
  1974.       PhysicalDeviceInfo->TargetID);
  1975.       Controller->V2.PhysicalDeviceInformation
  1976.      [PhysicalDeviceIndex] = NULL;
  1977.       Controller->V2.InquiryUnitSerialNumber
  1978.      [PhysicalDeviceIndex] = NULL;
  1979.       kfree(PhysicalDeviceInfo);
  1980.       kfree(InquiryUnitSerialNumber);
  1981.       for (DeviceIndex = PhysicalDeviceIndex;
  1982.    DeviceIndex < DAC960_V2_MaxPhysicalDevices - 1;
  1983.    DeviceIndex++)
  1984. {
  1985.   Controller->V2.PhysicalDeviceInformation[DeviceIndex] =
  1986.     Controller->V2.PhysicalDeviceInformation[DeviceIndex+1];
  1987.   Controller->V2.InquiryUnitSerialNumber[DeviceIndex] =
  1988.     Controller->V2.InquiryUnitSerialNumber[DeviceIndex+1];
  1989. }
  1990.       Controller->V2.PhysicalDeviceInformation
  1991.      [DAC960_V2_MaxPhysicalDevices-1] = NULL;
  1992.       Controller->V2.InquiryUnitSerialNumber
  1993.      [DAC960_V2_MaxPhysicalDevices-1] = NULL;
  1994.       PhysicalDeviceInfo =
  1995. Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
  1996.       InquiryUnitSerialNumber =
  1997. Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
  1998.     }
  1999.   if (PhysicalDeviceInfo == NULL ||
  2000.       (NewPhysicalDeviceInfo->Channel !=
  2001.        PhysicalDeviceInfo->Channel) ||
  2002.       (NewPhysicalDeviceInfo->TargetID !=
  2003.        PhysicalDeviceInfo->TargetID) ||
  2004.       (NewPhysicalDeviceInfo->LogicalUnit !=
  2005.        PhysicalDeviceInfo->LogicalUnit))
  2006.     {
  2007.       PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
  2008. kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
  2009.       InquiryUnitSerialNumber =
  2010. (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
  2011.   kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
  2012.   GFP_ATOMIC);
  2013.       if (InquiryUnitSerialNumber == NULL &&
  2014.   PhysicalDeviceInfo != NULL)
  2015. {
  2016.   kfree(PhysicalDeviceInfo);
  2017.   PhysicalDeviceInfo = NULL;
  2018. }
  2019.       DAC960_Critical("Physical Device %d:%d Now Exists%sn",
  2020.       Controller,
  2021.       NewPhysicalDeviceInfo->Channel,
  2022.       NewPhysicalDeviceInfo->TargetID,
  2023.       (PhysicalDeviceInfo != NULL
  2024.        ? "" : " - Allocation Failed"));
  2025.       if (PhysicalDeviceInfo != NULL)
  2026. {
  2027.   memset(PhysicalDeviceInfo, 0,
  2028.  sizeof(DAC960_V2_PhysicalDeviceInfo_T));
  2029.   PhysicalDeviceInfo->PhysicalDeviceState =
  2030.     DAC960_V2_Device_InvalidState;
  2031.   memset(InquiryUnitSerialNumber, 0,
  2032.  sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
  2033.   InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
  2034.   for (DeviceIndex = DAC960_V2_MaxPhysicalDevices - 1;
  2035.        DeviceIndex > PhysicalDeviceIndex;
  2036.        DeviceIndex--)
  2037.     {
  2038.       Controller->V2.PhysicalDeviceInformation[DeviceIndex] =
  2039. Controller->V2.PhysicalDeviceInformation[DeviceIndex-1];
  2040.       Controller->V2.InquiryUnitSerialNumber[DeviceIndex] =
  2041. Controller->V2.InquiryUnitSerialNumber[DeviceIndex-1];
  2042.     }
  2043.   Controller->V2.PhysicalDeviceInformation
  2044.  [PhysicalDeviceIndex] =
  2045.     PhysicalDeviceInfo;
  2046.   Controller->V2.InquiryUnitSerialNumber
  2047.  [PhysicalDeviceIndex] =
  2048.     InquiryUnitSerialNumber;
  2049.   Controller->V2.NeedDeviceSerialNumberInformation = true;
  2050. }
  2051.     }
  2052.   if (PhysicalDeviceInfo != NULL)
  2053.     {
  2054.       if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
  2055.   PhysicalDeviceInfo->PhysicalDeviceState)
  2056. DAC960_Critical(
  2057.   "Physical Device %d:%d is now %sn", Controller,
  2058.   NewPhysicalDeviceInfo->Channel,
  2059.   NewPhysicalDeviceInfo->TargetID,
  2060.   (NewPhysicalDeviceInfo->PhysicalDeviceState
  2061.    == DAC960_V2_Device_Online
  2062.    ? "ONLINE"
  2063.    : NewPhysicalDeviceInfo->PhysicalDeviceState
  2064.      == DAC960_V2_Device_Rebuild
  2065.      ? "REBUILD"
  2066.      : NewPhysicalDeviceInfo->PhysicalDeviceState
  2067.        == DAC960_V2_Device_Missing
  2068.        ? "MISSING"
  2069.        : NewPhysicalDeviceInfo->PhysicalDeviceState
  2070.  == DAC960_V2_Device_Critical
  2071.  ? "CRITICAL"
  2072.  : NewPhysicalDeviceInfo->PhysicalDeviceState
  2073.    == DAC960_V2_Device_Dead
  2074.    ? "DEAD"
  2075.    : NewPhysicalDeviceInfo->PhysicalDeviceState
  2076.      == DAC960_V2_Device_SuspectedDead
  2077.      ? "SUSPECTED-DEAD"
  2078.      : NewPhysicalDeviceInfo->PhysicalDeviceState
  2079.        == DAC960_V2_Device_CommandedOffline
  2080.        ? "COMMANDED-OFFLINE"
  2081.        : NewPhysicalDeviceInfo->PhysicalDeviceState
  2082.  == DAC960_V2_Device_Standby
  2083.  ? "STANDBY" : "UNKNOWN"));
  2084.       if ((NewPhysicalDeviceInfo->ParityErrors !=
  2085.    PhysicalDeviceInfo->ParityErrors) ||
  2086.   (NewPhysicalDeviceInfo->SoftErrors !=
  2087.    PhysicalDeviceInfo->SoftErrors) ||
  2088.   (NewPhysicalDeviceInfo->HardErrors !=
  2089.    PhysicalDeviceInfo->HardErrors) ||
  2090.   (NewPhysicalDeviceInfo->MiscellaneousErrors !=
  2091.    PhysicalDeviceInfo->MiscellaneousErrors) ||
  2092.   (NewPhysicalDeviceInfo->CommandTimeouts !=
  2093.    PhysicalDeviceInfo->CommandTimeouts) ||
  2094.   (NewPhysicalDeviceInfo->Retries !=
  2095.    PhysicalDeviceInfo->Retries) ||
  2096.   (NewPhysicalDeviceInfo->Aborts !=
  2097.    PhysicalDeviceInfo->Aborts) ||
  2098.   (NewPhysicalDeviceInfo->PredictedFailuresDetected !=
  2099.    PhysicalDeviceInfo->PredictedFailuresDetected))
  2100. {
  2101.   DAC960_Critical("Physical Device %d:%d Errors: "
  2102.   "Parity = %d, Soft = %d, "
  2103.   "Hard = %d, Misc = %dn",
  2104.   Controller,
  2105.   NewPhysicalDeviceInfo->Channel,
  2106.   NewPhysicalDeviceInfo->TargetID,
  2107.   NewPhysicalDeviceInfo->ParityErrors,
  2108.   NewPhysicalDeviceInfo->SoftErrors,
  2109.   NewPhysicalDeviceInfo->HardErrors,
  2110.   NewPhysicalDeviceInfo->MiscellaneousErrors);
  2111.   DAC960_Critical("Physical Device %d:%d Errors: "
  2112.   "Timeouts = %d, Retries = %d, "
  2113.   "Aborts = %d, Predicted = %dn",
  2114.   Controller,
  2115.   NewPhysicalDeviceInfo->Channel,
  2116.   NewPhysicalDeviceInfo->TargetID,
  2117.   NewPhysicalDeviceInfo->CommandTimeouts,
  2118.   NewPhysicalDeviceInfo->Retries,
  2119.   NewPhysicalDeviceInfo->Aborts,
  2120.   NewPhysicalDeviceInfo
  2121.   ->PredictedFailuresDetected);
  2122. }
  2123.       if ((PhysicalDeviceInfo->PhysicalDeviceState
  2124.    == DAC960_V2_Device_Dead ||
  2125.    PhysicalDeviceInfo->PhysicalDeviceState
  2126.    == DAC960_V2_Device_InvalidState) &&
  2127.   NewPhysicalDeviceInfo->PhysicalDeviceState
  2128.   != DAC960_V2_Device_Dead)
  2129. Controller->V2.NeedDeviceSerialNumberInformation = true;
  2130.       memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
  2131.      sizeof(DAC960_V2_PhysicalDeviceInfo_T));
  2132.     }
  2133.   NewPhysicalDeviceInfo->LogicalUnit++;
  2134.   Controller->V2.PhysicalDeviceIndex++;
  2135. }
  2136.       else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
  2137. {
  2138.   unsigned int DeviceIndex;
  2139.   for (DeviceIndex = Controller->V2.PhysicalDeviceIndex;
  2140.        DeviceIndex < DAC960_V2_MaxPhysicalDevices;
  2141.        DeviceIndex++)
  2142.     {
  2143.       DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
  2144. Controller->V2.PhysicalDeviceInformation[DeviceIndex];
  2145.       DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
  2146. Controller->V2.InquiryUnitSerialNumber[DeviceIndex];
  2147.       if (PhysicalDeviceInfo == NULL) break;
  2148.       DAC960_Critical("Physical Device %d:%d No Longer Existsn",
  2149.       Controller,
  2150.       PhysicalDeviceInfo->Channel,
  2151.       PhysicalDeviceInfo->TargetID);
  2152.       Controller->V2.PhysicalDeviceInformation[DeviceIndex] = NULL;
  2153.       Controller->V2.InquiryUnitSerialNumber[DeviceIndex] = NULL;
  2154.       kfree(PhysicalDeviceInfo);
  2155.       kfree(InquiryUnitSerialNumber);
  2156.     }
  2157.   Controller->V2.NeedPhysicalDeviceInformation = false;
  2158. }
  2159.       else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
  2160.        CommandStatus == DAC960_V2_NormalCompletion)
  2161. {
  2162.   DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
  2163.     &Controller->V2.NewLogicalDeviceInformation;
  2164.   unsigned short LogicalDeviceNumber =
  2165.     NewLogicalDeviceInfo->LogicalDeviceNumber;
  2166.   DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
  2167.     Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber];
  2168.   if (LogicalDeviceInfo == NULL)
  2169.     {
  2170.       DAC960_V2_PhysicalDevice_T PhysicalDevice;
  2171.       PhysicalDevice.Controller = 0;
  2172.       PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
  2173.       PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
  2174.       PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
  2175.       Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
  2176. PhysicalDevice;
  2177.       LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
  2178. kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
  2179.       Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
  2180. LogicalDeviceInfo;
  2181.       DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
  2182.       "Now Exists%sn", Controller,
  2183.       LogicalDeviceNumber,
  2184.       Controller->ControllerNumber,
  2185.       LogicalDeviceNumber,
  2186.       (LogicalDeviceInfo != NULL
  2187.        ? "" : " - Allocation Failed"));
  2188.       if (LogicalDeviceInfo != NULL)
  2189. {
  2190.   memset(LogicalDeviceInfo, 0,
  2191.  sizeof(DAC960_V2_LogicalDeviceInfo_T));
  2192.   DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
  2193. }
  2194.     }
  2195.   if (LogicalDeviceInfo != NULL)
  2196.     {
  2197.       unsigned long LogicalDeviceSize =
  2198. NewLogicalDeviceInfo->ConfigurableDeviceSize;
  2199.       if (NewLogicalDeviceInfo->LogicalDeviceState !=
  2200.   LogicalDeviceInfo->LogicalDeviceState)
  2201. DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
  2202. "is now %sn", Controller,
  2203. LogicalDeviceNumber,
  2204. Controller->ControllerNumber,
  2205. LogicalDeviceNumber,
  2206. (NewLogicalDeviceInfo->LogicalDeviceState
  2207.  == DAC960_V2_LogicalDevice_Online
  2208.  ? "ONLINE"
  2209.  : NewLogicalDeviceInfo->LogicalDeviceState
  2210.    == DAC960_V2_LogicalDevice_Critical
  2211.    ? "CRITICAL" : "OFFLINE"));
  2212.       if ((NewLogicalDeviceInfo->SoftErrors !=
  2213.    LogicalDeviceInfo->SoftErrors) ||
  2214.   (NewLogicalDeviceInfo->CommandsFailed !=
  2215.    LogicalDeviceInfo->CommandsFailed) ||
  2216.   (NewLogicalDeviceInfo->DeferredWriteErrors !=
  2217.    LogicalDeviceInfo->DeferredWriteErrors))
  2218. DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) Errors: "
  2219. "Soft = %d, Failed = %d, Deferred Write = %dn",
  2220. Controller, LogicalDeviceNumber,
  2221. Controller->ControllerNumber,
  2222. LogicalDeviceNumber,
  2223. NewLogicalDeviceInfo->SoftErrors,
  2224. NewLogicalDeviceInfo->CommandsFailed,
  2225. NewLogicalDeviceInfo->DeferredWriteErrors);
  2226.       if (NewLogicalDeviceInfo->ConsistencyCheckInProgress)
  2227. DAC960_V2_ReportProgress(Controller,
  2228.  "Consistency Check",
  2229.  LogicalDeviceNumber,
  2230.  NewLogicalDeviceInfo
  2231.  ->ConsistencyCheckBlockNumber,
  2232.  LogicalDeviceSize);
  2233.       else if (NewLogicalDeviceInfo->RebuildInProgress)
  2234. DAC960_V2_ReportProgress(Controller,
  2235.  "Rebuild",
  2236.  LogicalDeviceNumber,
  2237.  NewLogicalDeviceInfo
  2238.  ->RebuildBlockNumber,
  2239.  LogicalDeviceSize);
  2240.       else if (NewLogicalDeviceInfo->BackgroundInitializationInProgress)
  2241. DAC960_V2_ReportProgress(Controller,
  2242.  "Background Initialization",
  2243.  LogicalDeviceNumber,
  2244.  NewLogicalDeviceInfo
  2245.  ->BackgroundInitializationBlockNumber,
  2246.  LogicalDeviceSize);
  2247.       else if (NewLogicalDeviceInfo->ForegroundInitializationInProgress)
  2248. DAC960_V2_ReportProgress(Controller,
  2249.  "Foreground Initialization",
  2250.  LogicalDeviceNumber,
  2251.  NewLogicalDeviceInfo
  2252.  ->ForegroundInitializationBlockNumber,
  2253.  LogicalDeviceSize);
  2254.       else if (NewLogicalDeviceInfo->DataMigrationInProgress)
  2255. DAC960_V2_ReportProgress(Controller,
  2256.  "Data Migration",
  2257.  LogicalDeviceNumber,
  2258.  NewLogicalDeviceInfo
  2259.  ->DataMigrationBlockNumber,
  2260.  LogicalDeviceSize);
  2261.       else if (NewLogicalDeviceInfo->PatrolOperationInProgress)
  2262. DAC960_V2_ReportProgress(Controller,
  2263.  "Patrol Operation",
  2264.  LogicalDeviceNumber,
  2265.  NewLogicalDeviceInfo
  2266.  ->PatrolOperationBlockNumber,
  2267.  LogicalDeviceSize);
  2268.       if (LogicalDeviceInfo->BackgroundInitializationInProgress &&
  2269.   !NewLogicalDeviceInfo->BackgroundInitializationInProgress)
  2270. DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) "
  2271. "Background Initialization %sn",
  2272. Controller,
  2273. LogicalDeviceNumber,
  2274. Controller->ControllerNumber,
  2275. LogicalDeviceNumber,
  2276. (NewLogicalDeviceInfo->LogicalDeviceControl
  2277.       .LogicalDeviceInitialized
  2278.  ? "Completed" : "Failed"));
  2279.       memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
  2280.      sizeof(DAC960_V2_LogicalDeviceInfo_T));
  2281.     }
  2282.   Controller->V2.LogicalDriveFoundDuringScan
  2283.  [LogicalDeviceNumber] = true;
  2284.   NewLogicalDeviceInfo->LogicalDeviceNumber++;
  2285. }