Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.4.13 /drivers/block/DAC960.c

Filename:/drivers/block/DAC960.c
Lines Added:529
Lines Deleted:123
Also changed in: (Previous) 2.4.13-pre6  2.4.13-pre5  2.4.13-pre4  2.4.12-ac6  2.4.12-ac4  2.4.12-ac5 
(Following) 2.4.14-pre2  2.4.14-pre3  2.4.14-pre4  2.4.14-pre5  2.4.14-pre6  2.4.14-pre7 

Location
[  2.4.13
  [  drivers
    [  block
       o  DAC960.c

Patch

diff -u --recursive --new-file v2.4.12/linux/drivers/block/DAC960.c linux/drivers/block/DAC960.c
--- v2.4.12/linux/drivers/block/DAC960.c   Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/DAC960.c   Wed Oct 17 14:46:29 2001
@@ -19,8 +19,8 @@
 */
 
 
-#define DAC960_DriverVersion         "2.4.10"
-#define DAC960_DriverDate         "23 July 2001"
+#define DAC960_DriverVersion         "2.4.11"
+#define DAC960_DriverDate         "11 October 2001"
 
 
 #include <linux/version.h>
@@ -42,6 +42,7 @@
 #include <linux/spinlock.h>
 #include <linux/timer.h>
 #include <linux/pci.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/segment.h>
 #include <asm/uaccess.h>
@@ -99,7 +100,7 @@
 */
 
 static NotifierBlock_T
-  DAC960_NotifierBlock =    { DAC960_Finalize, NULL, 0 };
+  DAC960_NotifierBlock =    { DAC960_Notifier, NULL, 0 };
 
 
 /*
@@ -269,7 +270,9 @@
 
 /*
   DAC960_AllocateCommand allocates a Command structure from Controller's
-  free list.
+  free list.  During driver initialization, a special initialization command
+  has been placed on the free list to guarantee that command allocation can
+  never fail.
 */
 
 static inline DAC960_Command_T *DAC960_AllocateCommand(DAC960_Controller_T
@@ -480,6 +483,52 @@
 
 
 /*
+  DAC960_P_QueueCommand queues Command for DAC960 P Series Controllers.
+*/
+
+static void DAC960_P_QueueCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  switch (CommandMailbox->Common.CommandOpcode)
+    {
+    case DAC960_V1_Enquiry:
+      CommandMailbox->Common.CommandOpcode = DAC960_V1_Enquiry_Old;
+      break;
+    case DAC960_V1_GetDeviceState:
+      CommandMailbox->Common.CommandOpcode = DAC960_V1_GetDeviceState_Old;
+      break;
+    case DAC960_V1_Read:
+      CommandMailbox->Common.CommandOpcode = DAC960_V1_Read_Old;
+      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+      break;
+    case DAC960_V1_Write:
+      CommandMailbox->Common.CommandOpcode = DAC960_V1_Write_Old;
+      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+      break;
+    case DAC960_V1_ReadWithScatterGather:
+      CommandMailbox->Common.CommandOpcode =
+   DAC960_V1_ReadWithScatterGather_Old;
+      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+      break;
+    case DAC960_V1_WriteWithScatterGather:
+      CommandMailbox->Common.CommandOpcode =
+   DAC960_V1_WriteWithScatterGather_Old;
+      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+      break;
+    default:
+      break;
+    }
+  while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
+    udelay(1);
+  DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
+  DAC960_PD_NewCommand(ControllerBaseAddress);
+}
+
+
+/*
   DAC960_ExecuteCommand executes Command and waits for completion.
 */
 
@@ -522,6 +571,32 @@
 
 
 /*
+  DAC960_V1_ExecuteTypeB executes a DAC960 V1 Firmware Controller Type 3B
+  Command and waits for completion.  It returns true on success and false
+  on failure.
+*/
+
+static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
+                   DAC960_V1_CommandOpcode_T CommandOpcode,
+                   unsigned char CommandOpcode2,
+                   void *DataPointer)
+{
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandStatus_T CommandStatus;
+  DAC960_V1_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->Type3B.CommandOpcode = CommandOpcode;
+  CommandMailbox->Type3B.CommandOpcode2 = CommandOpcode2;
+  CommandMailbox->Type3B.BusAddress = Virtual_to_Bus32(DataPointer);
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V1.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V1_NormalCompletion);
+}
+
+
+/*
   DAC960_V1_ExecuteType3D executes a DAC960 V1 Firmware Controller Type 3D
   Command and waits for completion.  It returns true on success and false
   on failure.
@@ -1055,7 +1130,17 @@
     DAC1164P          5.06 and above
     DAC960PTL/PRL/PJ/PG       4.06 and above
     DAC960PU/PD/PL       3.51 and above
+    DAC960PU/PD/PL/P       2.73 and above
   */
+  if (Enquiry2.FirmwareID.MajorVersion == 0)
+    {
+      Enquiry2.FirmwareID.MajorVersion =
+   Controller->V1.Enquiry.MajorFirmwareVersion;
+      Enquiry2.FirmwareID.MinorVersion =
+   Controller->V1.Enquiry.MinorFirmwareVersion;
+      Enquiry2.FirmwareID.FirmwareType = '0';
+      Enquiry2.FirmwareID.TurnID = 0;
+    }
   sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
      Enquiry2.FirmwareID.MajorVersion, Enquiry2.FirmwareID.MinorVersion,
      Enquiry2.FirmwareID.FirmwareType, Enquiry2.FirmwareID.TurnID);
@@ -1064,7 +1149,9 @@
    (Controller->FirmwareVersion[0] == '4' &&
     strcmp(Controller->FirmwareVersion, "4.06") >= 0) ||
    (Controller->FirmwareVersion[0] == '3' &&
-    strcmp(Controller->FirmwareVersion, "3.51") >= 0)))
+    strcmp(Controller->FirmwareVersion, "3.51") >= 0) ||
+   (Controller->FirmwareVersion[0] == '2' &&
+    strcmp(Controller->FirmwareVersion, "2.73") >= 0)))
     {
       DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
       DAC960_Error("Firmware Version = '%s'\n", Controller,
@@ -1120,6 +1207,20 @@
       return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
     }
   /*
+    Initialize the Background Initialization Status.
+  */
+  if ((Controller->FirmwareVersion[0] == '4' &&
+      strcmp(Controller->FirmwareVersion, "4.08") >= 0) ||
+      (Controller->FirmwareVersion[0] == '5' &&
+       strcmp(Controller->FirmwareVersion, "5.08") >= 0))
+    {
+      Controller->V1.BackgroundInitializationStatusSupported = true;
+      DAC960_V1_ExecuteType3B(Controller,
+               DAC960_V1_BackgroundInitializationControl, 0x20,
+               &Controller->
+                V1.LastBackgroundInitializationStatus);
+    }
+  /*
     Initialize the Logical Drive Initially Accessible flag.
   */
   for (LogicalDriveNumber = 0;
@@ -1573,7 +1674,7 @@
        DeviceState->DeviceType == DAC960_V1_DiskType)
      {
        if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0)
-         DAC960_Info("         Disk Status: %s, %d blocks, %d resets\n",
+         DAC960_Info("         Disk Status: %s, %u blocks, %d resets\n",
            Controller,
            (DeviceState->DeviceState == DAC960_V1_Device_Dead
             ? "Dead"
@@ -1586,7 +1687,7 @@
            DeviceState->DiskSize,
            Controller->V1.DeviceResetCount[Channel][TargetID]);
        else
-         DAC960_Info("         Disk Status: %s, %d blocks\n", Controller,
+         DAC960_Info("         Disk Status: %s, %u blocks\n", Controller,
            (DeviceState->DeviceState == DAC960_V1_Device_Dead
             ? "Dead"
             : DeviceState->DeviceState
@@ -1615,7 +1716,7 @@
     {
       DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation =
    &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
-      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %d blocks, %s\n",
+      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %u blocks, %s\n",
         Controller, Controller->ControllerNumber, LogicalDriveNumber,
         LogicalDriveInformation->RAIDLevel,
         (LogicalDriveInformation->LogicalDriveState
@@ -1681,18 +1782,32 @@
       if (PhysicalDeviceInfo->PhysicalDeviceState ==
      DAC960_V2_Device_Unconfigured)
    continue;
-      DAC960_Info("         Disk Status: %s, %d blocks\n", Controller,
+      DAC960_Info("         Disk Status: %s, %u blocks\n", Controller,
         (PhysicalDeviceInfo->PhysicalDeviceState
          == DAC960_V2_Device_Online
          ? "Online"
          : PhysicalDeviceInfo->PhysicalDeviceState
-           == DAC960_V2_Device_WriteOnly
-           ? "Write-Only"
+           == DAC960_V2_Device_Rebuild
+           ? "Rebuild"
            : PhysicalDeviceInfo->PhysicalDeviceState
-             == DAC960_V2_Device_Dead
-             ? "Dead" : "Standby"),
-        PhysicalDeviceInfo
-        ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+             == DAC960_V2_Device_Missing
+             ? "Missing"
+             : PhysicalDeviceInfo->PhysicalDeviceState
+          == DAC960_V2_Device_Critical
+          ? "Critical"
+          : PhysicalDeviceInfo->PhysicalDeviceState
+            == DAC960_V2_Device_Dead
+            ? "Dead"
+            : PhysicalDeviceInfo->PhysicalDeviceState
+              == DAC960_V2_Device_SuspectedDead
+              ? "Suspected-Dead"
+              : PhysicalDeviceInfo->PhysicalDeviceState
+                == DAC960_V2_Device_CommandedOffline
+                ? "Commanded-Offline"
+                : PhysicalDeviceInfo->PhysicalDeviceState
+             == DAC960_V2_Device_Standby
+             ? "Standby" : "Unknown"),
+        PhysicalDeviceInfo->ConfigurableDeviceSize);
       if (PhysicalDeviceInfo->ParityErrors == 0 &&
      PhysicalDeviceInfo->SoftErrors == 0 &&
      PhysicalDeviceInfo->HardErrors == 0 &&
@@ -1734,7 +1849,7 @@
                    "-", "-", "-", "-" };
       unsigned char *GeometryTranslation;
       if (LogicalDeviceInfo == NULL) continue;
-      switch(LogicalDeviceInfo->DriveGeometry)
+      switch (LogicalDeviceInfo->DriveGeometry)
    {
    case DAC960_V2_Geometry_128_32:
      GeometryTranslation = "128/32";
@@ -1748,7 +1863,7 @@
              Controller, LogicalDeviceInfo->DriveGeometry);
      break;
    }
-      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %d blocks\n",
+      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %u blocks\n",
         Controller, Controller->ControllerNumber, LogicalDriveNumber,
         LogicalDeviceInfo->RAIDLevel,
         (LogicalDeviceInfo->LogicalDeviceState
@@ -1757,7 +1872,7 @@
          : LogicalDeviceInfo->LogicalDeviceState
            == DAC960_V2_LogicalDevice_Critical
            ? "Critical" : "Offline"),
-        LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+        LogicalDeviceInfo->ConfigurableDeviceSize);
       DAC960_Info("                  Logical Device %s, BIOS Geometry: %s\n",
         Controller,
         (LogicalDeviceInfo->LogicalDeviceControl
@@ -1907,15 +2022,11 @@
   RequestQueue->queuedata = Controller;
   Controller->RequestQueue = RequestQueue;
   /*
-    Initialize the Disk Partitions array, Partition Sizes array, Block Sizes
-    array, and Max Sectors per Request array.
+    Initialize the Max Sectors per Request array.
   */
   for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++)
-    {
-      Controller->BlockSizes[MinorNumber] = BLOCK_SIZE;
-      Controller->MaxSectorsPerRequest[MinorNumber] =
-   Controller->MaxBlocksPerCommand;
-    }
+    Controller->MaxSectorsPerRequest[MinorNumber] =
+      Controller->MaxBlocksPerCommand;
   Controller->GenericDiskInfo.part = Controller->DiskPartitions;
   Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
   blksize_size[MajorNumber] = Controller->BlockSizes;
@@ -1931,7 +2042,8 @@
   Controller->GenericDiskInfo.major_name = "rd";
   Controller->GenericDiskInfo.minor_shift = DAC960_MaxPartitionsBits;
   Controller->GenericDiskInfo.max_p = DAC960_MaxPartitions;
-  Controller->GenericDiskInfo.nr_real = Controller->LogicalDriveCount;
+  Controller->GenericDiskInfo.nr_real = DAC960_MaxLogicalDrives;
+  Controller->GenericDiskInfo.real_devices = Controller;
   Controller->GenericDiskInfo.next = NULL;
   Controller->GenericDiskInfo.fops = &DAC960_BlockDeviceOperations;
   /*
@@ -1978,6 +2090,46 @@
 
 
 /*
+  DAC960_ComputeGenericDiskInfo computes the values for the Generic Disk
+  Information Partition Sector Counts and Block Sizes.
+*/
+
+static void DAC960_ComputeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
+{
+  DAC960_Controller_T *Controller =
+    (DAC960_Controller_T *) GenericDiskInfo->real_devices;
+  int LogicalDriveNumber, i;
+  for (LogicalDriveNumber = 0;
+       LogicalDriveNumber < DAC960_MaxLogicalDrives;
+       LogicalDriveNumber++)
+    {
+      int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber, 0);
+      if (Controller->FirmwareType == DAC960_V1_Controller)
+   {
+     if (LogicalDriveNumber < Controller->LogicalDriveCount)
+       GenericDiskInfo->part[MinorNumber].nr_sects =
+         Controller->V1.LogicalDriveInformation
+              [LogicalDriveNumber].LogicalDriveSize;
+     else GenericDiskInfo->part[MinorNumber].nr_sects = 0;
+   }
+      else
+   {
+     DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+       Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+     if (LogicalDeviceInfo != NULL)
+       GenericDiskInfo->part[MinorNumber].nr_sects =
+         LogicalDeviceInfo->ConfigurableDeviceSize;
+     else GenericDiskInfo->part[MinorNumber].nr_sects = 0;
+   }
+      for (i = 0; i < DAC960_MaxPartitions; i++)
+   if (GenericDiskInfo->part[MinorNumber].nr_sects > 0)
+     Controller->BlockSizes[MinorNumber + i] = BLOCK_SIZE;
+   else Controller->BlockSizes[MinorNumber + i] = 0;
+    }
+}
+
+
+/*
   DAC960_RegisterDisk registers the DAC960 Logical Disk Device for Logical
   Drive Number if it exists.
 */
@@ -1991,7 +2143,8 @@
       register_disk(&Controller->GenericDiskInfo,
           DAC960_KernelDevice(Controller->ControllerNumber,
                LogicalDriveNumber, 0),
-          DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
+          DAC960_MaxPartitions,
+          &DAC960_BlockDeviceOperations,
           Controller->V1.LogicalDriveInformation
                [LogicalDriveNumber].LogicalDriveSize);
     }
@@ -2003,9 +2156,9 @@
       register_disk(&Controller->GenericDiskInfo,
           DAC960_KernelDevice(Controller->ControllerNumber,
                LogicalDriveNumber, 0),
-          DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
-          LogicalDeviceInfo
-          ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+          DAC960_MaxPartitions,
+          &DAC960_BlockDeviceOperations,
+          LogicalDeviceInfo->ConfigurableDeviceSize);
     }
 }
 
@@ -2116,6 +2269,13 @@
       InterruptHandler = DAC960_PD_InterruptHandler;
       MemoryWindowSize = DAC960_PD_RegisterWindowSize;
       break;
+    case DAC960_P_Controller:
+      VendorID = PCI_VENDOR_ID_MYLEX;
+      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_P;
+      FirmwareType = DAC960_V1_Controller;
+      InterruptHandler = DAC960_P_InterruptHandler;
+      MemoryWindowSize = DAC960_PD_RegisterWindowSize;
+      break;
     }
   while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
     {
@@ -2151,6 +2311,10 @@
      IO_Address = pci_resource_start(PCI_Device, 0);
      PCI_Address = pci_resource_start(PCI_Device, 1);
      break;
+   case DAC960_P_Controller:
+     IO_Address = pci_resource_start(PCI_Device, 0);
+     PCI_Address = pci_resource_start(PCI_Device, 1);
+     break;
    }
       if (DAC960_ControllerCount == DAC960_MaxControllers)
    {
@@ -2348,6 +2512,32 @@
      Controller->QueueReadWriteCommand =
        DAC960_V1_QueueReadWriteCommand;
      break;
+   case DAC960_P_Controller:
+     request_region(Controller->IO_Address, 0x80,
+          Controller->FullModelName);
+     DAC960_PD_DisableInterrupts(BaseAddress);
+     DAC960_PD_AcknowledgeStatus(BaseAddress);
+     udelay(1000);
+     while (DAC960_PD_InitializationInProgressP(BaseAddress))
+       {
+         if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
+                   &Parameter0, &Parameter1) &&
+        DAC960_ReportErrorStatus(Controller, ErrorStatus,
+                  Parameter0, Parameter1))
+      goto Failure;
+         udelay(10);
+       }
+     DAC960_PD_EnableInterrupts(Controller->BaseAddress);
+     Controller->QueueCommand = DAC960_P_QueueCommand;
+     Controller->ReadControllerConfiguration =
+       DAC960_V1_ReadControllerConfiguration;
+     Controller->ReadDeviceConfiguration =
+       DAC960_V1_ReadDeviceConfiguration;
+     Controller->ReportDeviceConfiguration =
+       DAC960_V1_ReportDeviceConfiguration;
+     Controller->QueueReadWriteCommand =
+       DAC960_V1_QueueReadWriteCommand;
+     break;
    }
       /*
    Acquire shared access to the IRQ Channel.
@@ -2519,7 +2709,7 @@
   DAC960_Initialize initializes the DAC960 Driver.
 */
 
-void DAC960_Initialize(void)
+static int DAC960_Initialize(void)
 {
   int ControllerNumber;
   DAC960_DetectControllers(DAC960_BA_Controller);
@@ -2527,8 +2717,9 @@
   DAC960_DetectControllers(DAC960_LA_Controller);
   DAC960_DetectControllers(DAC960_PG_Controller);
   DAC960_DetectControllers(DAC960_PD_Controller);
+  DAC960_DetectControllers(DAC960_P_Controller);
   DAC960_SortControllers();
-  if (DAC960_ActiveControllerCount == 0) return;
+  if (DAC960_ActiveControllerCount == 0) return -ENODEV;
   for (ControllerNumber = 0;
        ControllerNumber < DAC960_ControllerCount;
        ControllerNumber++)
@@ -2537,6 +2728,7 @@
       int LogicalDriveNumber;
       if (Controller == NULL) continue;
       DAC960_InitializeController(Controller);
+      DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
       for (LogicalDriveNumber = 0;
       LogicalDriveNumber < DAC960_MaxLogicalDrives;
       LogicalDriveNumber++)
@@ -2544,6 +2736,7 @@
     }
   DAC960_CreateProcEntries();
   register_reboot_notifier(&DAC960_NotifierBlock);
+  return 0;
 }
 
 
@@ -2551,14 +2744,10 @@
   DAC960_Finalize finalizes the DAC960 Driver.
 */
 
-static int DAC960_Finalize(NotifierBlock_T *NotifierBlock,
-            unsigned long Event,
-            void *Buffer)
+static void DAC960_Finalize(void)
 {
   int ControllerNumber;
-  if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
-    return NOTIFY_DONE;
-  if (DAC960_ActiveControllerCount == 0) return NOTIFY_OK;
+  if (DAC960_ActiveControllerCount == 0) return;
   for (ControllerNumber = 0;
        ControllerNumber < DAC960_ControllerCount;
        ControllerNumber++)
@@ -2566,6 +2755,20 @@
       DAC960_FinalizeController(DAC960_Controllers[ControllerNumber]);
   DAC960_DestroyProcEntries();
   unregister_reboot_notifier(&DAC960_NotifierBlock);
+}
+
+
+/*
+  DAC960_Notifier is the notifier for the DAC960 Driver.
+*/
+
+static int DAC960_Notifier(NotifierBlock_T *NotifierBlock,
+            unsigned long Event,
+            void *Buffer)
+{
+  if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
+    return NOTIFY_DONE;
+  DAC960_Finalize();
   return NOTIFY_OK;
 }
 
@@ -2599,11 +2802,9 @@
       char *LastDataEndPointer = NULL;
       int SegmentNumber = 0;
       if (Command->CommandType == DAC960_ReadCommand)
-   CommandMailbox->Type5.CommandOpcode =
-     DAC960_V1_ReadWithOldScatterGather;
+   CommandMailbox->Type5.CommandOpcode = DAC960_V1_ReadWithScatterGather;
       else
-   CommandMailbox->Type5.CommandOpcode =
-     DAC960_V1_WriteWithOldScatterGather;
+   CommandMailbox->Type5.CommandOpcode = DAC960_V1_WriteWithScatterGather;
       CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
       CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
       CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
@@ -2865,12 +3066,12 @@
          Controller, Command->V1.CommandStatus, CommandName);
       break;
     }
-  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %d..%d\n",
+  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %u..%u\n",
           Controller, Controller->ControllerNumber,
           Command->LogicalDriveNumber, Command->BlockNumber,
           Command->BlockNumber + Command->BlockCount - 1);
   if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
-    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
+    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
        Controller, Controller->ControllerNumber,
        Command->LogicalDriveNumber,
        DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
@@ -3027,6 +3228,8 @@
             LogicalDriveNumber,
             Controller->ControllerNumber,
             LogicalDriveNumber);
+         Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
+         DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
        }
      if (NewEnquiry->NumberOfLogicalDrives < Controller->LogicalDriveCount)
        {
@@ -3037,8 +3240,9 @@
             LogicalDriveNumber,
             Controller->ControllerNumber,
             LogicalDriveNumber);
+         Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
+         DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
        }
-     Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
      if (NewEnquiry->StatusFlags.DeferredWriteError !=
          OldEnquiry->StatusFlags.DeferredWriteError)
        DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
@@ -3064,6 +3268,8 @@
          Controller->V1.NeedErrorTableInformation = true;
          Controller->V1.NeedDeviceStateInformation = true;
          Controller->V1.StartDeviceStateScan = true;
+         Controller->V1.NeedBackgroundInitializationStatus =
+      Controller->V1.BackgroundInitializationStatusSupported;
          Controller->SecondaryMonitoringTime = jiffies;
        }
      if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
@@ -3186,7 +3392,7 @@
             AdditionalSenseCodeQualifier == 0x02))))
       {
         DAC960_Critical("Physical Device %d:%d Error Log: "
-              "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
+              "Sense Key = %X, ASC = %02X, ASCQ = %02X\n",
               Controller,
               EventLogEntry->Channel,
               EventLogEntry->TargetID,
@@ -3396,6 +3602,77 @@
          Controller->EphemeralProgressMessage = false;
        }
    }
+      else if (CommandOpcode == DAC960_V1_BackgroundInitializationControl)
+   {
+     unsigned int LogicalDriveNumber =
+       Controller->V1.BackgroundInitializationStatus.LogicalDriveNumber;
+     unsigned int LogicalDriveSize =
+       Controller->V1.BackgroundInitializationStatus.LogicalDriveSize;
+     unsigned int BlocksCompleted =
+       Controller->V1.BackgroundInitializationStatus.BlocksCompleted;
+     switch (CommandStatus)
+       {
+       case DAC960_V1_NormalCompletion:
+         switch (Controller->V1.BackgroundInitializationStatus.Status)
+      {
+      case DAC960_V1_BackgroundInitializationInvalid:
+        break;
+      case DAC960_V1_BackgroundInitializationStarted:
+        DAC960_Progress("Background Initialization Started\n",
+              Controller);
+        break;
+      case DAC960_V1_BackgroundInitializationInProgress:
+        if (BlocksCompleted ==
+            Controller->V1.LastBackgroundInitializationStatus
+                .BlocksCompleted &&
+            LogicalDriveNumber ==
+            Controller->V1.LastBackgroundInitializationStatus
+                .LogicalDriveNumber)
+          break;
+        Controller->EphemeralProgressMessage = true;
+        DAC960_Progress("Background Initialization in Progress: "
+              "Logical Drive %d (/dev/rd/c%dd%d) "
+              "%d%% completed\n",
+              Controller, LogicalDriveNumber,
+              Controller->ControllerNumber,
+              LogicalDriveNumber,
+              (100 * (BlocksCompleted >> 7))
+              / (LogicalDriveSize >> 7));
+        Controller->EphemeralProgressMessage = false;
+        break;
+      case DAC960_V1_BackgroundInitializationSuspended:
+        DAC960_Progress("Background Initialization Suspended\n",
+              Controller);
+        break;
+      case DAC960_V1_BackgroundInitializationCancelled:
+        DAC960_Progress("Background Initialization Cancelled\n",
+              Controller);
+        break;
+      }
+         memcpy(&Controller->V1.LastBackgroundInitializationStatus,
+           &Controller->V1.BackgroundInitializationStatus,
+           sizeof(DAC960_V1_BackgroundInitializationStatus_T));
+         break;
+       case DAC960_V1_BackgroundInitSuccessful:
+         if (Controller->V1.BackgroundInitializationStatus.Status ==
+        DAC960_V1_BackgroundInitializationInProgress)
+      DAC960_Progress("Background Initialization "
+            "Completed Successfully\n", Controller);
+         Controller->V1.BackgroundInitializationStatus.Status =
+      DAC960_V1_BackgroundInitializationInvalid;
+         break;
+       case DAC960_V1_BackgroundInitAborted:
+         if (Controller->V1.BackgroundInitializationStatus.Status ==
+        DAC960_V1_BackgroundInitializationInProgress)
+      DAC960_Progress("Background Initialization Aborted\n",
+            Controller);
+         Controller->V1.BackgroundInitializationStatus.Status =
+      DAC960_V1_BackgroundInitializationInvalid;
+         break;
+       case DAC960_V1_NoBackgroundInitInProgress:
+         break;
+       }
+   }
     }
   if (CommandType == DAC960_MonitoringCommand)
     {
@@ -3562,6 +3839,17 @@
      DAC960_QueueCommand(Command);
      return;
    }
+      if (Controller->V1.NeedBackgroundInitializationStatus)
+   {
+     Controller->V1.NeedBackgroundInitializationStatus = false;
+     Command->V1.CommandMailbox.Type3B.CommandOpcode =
+       DAC960_V1_BackgroundInitializationControl;
+     Command->V1.CommandMailbox.Type3B.CommandOpcode2 = 0x20;
+     Command->V1.CommandMailbox.Type3B.BusAddress =
+       Virtual_to_Bus32(&Controller->V1.BackgroundInitializationStatus);
+     DAC960_QueueCommand(Command);
+     return;
+   }
       Controller->MonitoringTimerCount++;
       Controller->MonitoringTimer.expires =
    jiffies + DAC960_MonitoringTimerInterval;
@@ -3642,12 +3930,12 @@
     }
   DAC960_Error("Error Condition %s on %s:\n", Controller,
           SenseErrors[Command->V2.RequestSense.SenseKey], CommandName);
-  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %d..%d\n",
+  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %u..%u\n",
           Controller, Controller->ControllerNumber,
           Command->LogicalDriveNumber, Command->BlockNumber,
           Command->BlockNumber + Command->BlockCount - 1);
   if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
-    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
+    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
        Controller, Controller->ControllerNumber,
        Command->LogicalDriveNumber,
        DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
@@ -3680,11 +3968,14 @@
       { 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
       { 0x000C, "S Offline" },
       { 0x000D, "P Found" },
-      { 0x000E, "P Gone" },
+      { 0x000E, "P Removed" },
       { 0x000F, "P Unconfigured" },
       { 0x0010, "P Expand Capacity Started" },
       { 0x0011, "P Expand Capacity Completed" },
       { 0x0012, "P Expand Capacity Failed" },
+      { 0x0013, "P Command Timed Out" },
+      { 0x0014, "P Command Aborted" },
+      { 0x0015, "P Command Retried" },
       { 0x0016, "P Parity Error" },
       { 0x0017, "P Soft Error" },
       { 0x0018, "P Miscellaneous Error" },
@@ -3715,6 +4006,8 @@
       { 0x0031, "P Failed because BDT Write Operation Failed" },
       { 0x0039, "P Missing at Startup" },
       { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
+      { 0x003C, "P Temporarily Offline Device Automatically Made Online" },
+      { 0x003D, "P Standby Rebuild Started" },
       /* Logical Device Events (0x0080 - 0x00FF) */
       { 0x0080, "M Consistency Check Started" },
       { 0x0081, "M Consistency Check Completed" },
@@ -3737,7 +4030,7 @@
       { 0x0092, "M Initialization Cancelled" },
       { 0x0093, "M Initialization Failed" },
       { 0x0094, "L Found" },
-      { 0x0095, "L Gone" },
+      { 0x0095, "L Deleted" },
       { 0x0096, "M Expand Capacity Started" },
       { 0x0097, "M Expand Capacity Completed" },
       { 0x0098, "M Expand Capacity Failed" },
@@ -3747,6 +4040,9 @@
       { 0x009C, "L Bad Data Block Found" },
       { 0x009E, "L Read of Data Block in BDT" },
       { 0x009F, "L Write Back Data for Disk Block Lost" },
+      { 0x00A0, "L Temporarily Offline RAID-5/3 Drive Made Online" },
+      { 0x00A1, "L Temporarily Offline RAID-6/1/0/7 Drive Made Online" },
+      { 0x00A2, "L Standby Rebuild Started" },
       /* Fault Management Events (0x0100 - 0x017F) */
       { 0x0140, "E Fan %d Failed" },
       { 0x0141, "E Fan %d OK" },
@@ -3754,24 +4050,31 @@
       { 0x0143, "E Power Supply %d Failed" },
       { 0x0144, "E Power Supply %d OK" },
       { 0x0145, "E Power Supply %d Not Present" },
-      { 0x0146, "E Temperature Sensor %d Failed" },
-      { 0x0147, "E Temperature Sensor %d Critical" },
-      { 0x0148, "E Temperature Sensor %d OK" },
+      { 0x0146, "E Temperature Sensor %d Temperature Exceeds Safe Limit" },
+      { 0x0147, "E Temperature Sensor %d Temperature Exceeds Working Limit" },
+      { 0x0148, "E Temperature Sensor %d Temperature Normal" },
       { 0x0149, "E Temperature Sensor %d Not Present" },
-      { 0x014A, "E Unit %d Access Critical" },
-      { 0x014B, "E Unit %d Access OK" },
-      { 0x014C, "E Unit %d Access Offline" },
+      { 0x014A, "E Enclosure Management Unit %d Access Critical" },
+      { 0x014B, "E Enclosure Management Unit %d Access OK" },
+      { 0x014C, "E Enclosure Management Unit %d Access Offline" },
       /* Controller Events (0x0180 - 0x01FF) */
       { 0x0181, "C Cache Write Back Error" },
       { 0x0188, "C Battery Backup Unit Found" },
       { 0x0189, "C Battery Backup Unit Charge Level Low" },
       { 0x018A, "C Battery Backup Unit Charge Level OK" },
       { 0x0193, "C Installation Aborted" },
-      { 0x0195, "C Mirror Race Recovery In Progress" },
-      { 0x0196, "C Mirror Race on Critical Drive" },
-      { 0x019E, "C Memory Soft ECC Error" },
-      { 0x019F, "C Memory Hard ECC Error" },
+      { 0x0195, "C Battery Backup Unit Physically Removed" },
+      { 0x0196, "C Memory Error During Warm Boot" },
+      { 0x019E, "C Memory Soft ECC Error Corrected" },
+      { 0x019F, "C Memory Hard ECC Error Corrected" },
       { 0x01A2, "C Battery Backup Unit Failed" },
+      { 0x01AB, "C Mirror Race Recovery Failed" },
+      { 0x01AC, "C Mirror Race on Critical Drive" },
+      /* Controller Internal Processor Events */
+      { 0x0380, "C Internal Controller Hung" },
+      { 0x0381, "C Internal Controller Firmware Breakpoint" },
+      { 0x0390, "C Internal Controller i960 Processor Specific Error" },
+      { 0x03A0, "C Internal Controller StrongARM Processor Specific Error" },
       { 0, "" } };
   int EventListIndex = 0, EventCode;
   unsigned char EventType, *EventMessage;
@@ -3821,7 +4124,7 @@
       DAC960_Critical("Physical Device %d:%d %s\n", Controller,
             Event->Channel, Event->TargetID, EventMessage);
       DAC960_Critical("Physical Device %d:%d Request Sense: "
-            "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
+            "Sense Key = %X, ASC = %02X, ASCQ = %02X\n",
             Controller,
             Event->Channel,
             Event->TargetID,
@@ -4142,22 +4445,34 @@
        {
          if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
         PhysicalDeviceInfo->PhysicalDeviceState)
-      DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
-            NewPhysicalDeviceInfo->Channel,
-            NewPhysicalDeviceInfo->TargetID,
-            (NewPhysicalDeviceInfo->PhysicalDeviceState
-             == DAC960_V2_Device_Unconfigured
-             ? "UNCONFIGURED"
-             : NewPhysicalDeviceInfo->PhysicalDeviceState
-               == DAC960_V2_Device_Online
-               ? "ONLINE"
-               : NewPhysicalDeviceInfo->PhysicalDeviceState
-                 == DAC960_V2_Device_WriteOnly
-                 ? "WRITE-ONLY"
-                 : NewPhysicalDeviceInfo
-                   ->PhysicalDeviceState
-                   == DAC960_V2_Device_Dead
-                   ? "DEAD" : "STANDBY"));
+      DAC960_Critical(
+        "Physical Device %d:%d is now %s\n", Controller,
+        NewPhysicalDeviceInfo->Channel,
+        NewPhysicalDeviceInfo->TargetID,
+        (NewPhysicalDeviceInfo->PhysicalDeviceState
+         == DAC960_V2_Device_Online
+         ? "ONLINE"
+         : NewPhysicalDeviceInfo->PhysicalDeviceState
+           == DAC960_V2_Device_Rebuild
+           ? "REBUILD"
+           : NewPhysicalDeviceInfo->PhysicalDeviceState
+             == DAC960_V2_Device_Missing
+             ? "MISSING"
+             : NewPhysicalDeviceInfo->PhysicalDeviceState
+          == DAC960_V2_Device_Critical
+          ? "CRITICAL"
+          : NewPhysicalDeviceInfo->PhysicalDeviceState
+            == DAC960_V2_Device_Dead
+            ? "DEAD"
+            : NewPhysicalDeviceInfo->PhysicalDeviceState
+              == DAC960_V2_Device_SuspectedDead
+              ? "SUSPECTED-DEAD"
+              : NewPhysicalDeviceInfo->PhysicalDeviceState
+                == DAC960_V2_Device_CommandedOffline
+                ? "COMMANDED-OFFLINE"
+                : NewPhysicalDeviceInfo->PhysicalDeviceState
+             == DAC960_V2_Device_Standby
+             ? "STANDBY" : "UNKNOWN"));
          if ((NewPhysicalDeviceInfo->ParityErrors !=
          PhysicalDeviceInfo->ParityErrors) ||
         (NewPhysicalDeviceInfo->SoftErrors !=
@@ -4263,13 +4578,16 @@
                (LogicalDeviceInfo != NULL
                 ? "" : " - Allocation Failed"));
          if (LogicalDeviceInfo != NULL)
-      memset(LogicalDeviceInfo, 0,
-             sizeof(DAC960_V2_LogicalDeviceInfo_T));
+      {
+        memset(LogicalDeviceInfo, 0,
+          sizeof(DAC960_V2_LogicalDeviceInfo_T));
+        DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
+      }
        }
      if (LogicalDeviceInfo != NULL)
        {
          unsigned long LogicalDeviceSize =
-      NewLogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB;
+      NewLogicalDeviceInfo->ConfigurableDeviceSize;
          if (NewLogicalDeviceInfo->LogicalDeviceState !=
         LogicalDeviceInfo->LogicalDeviceState)
       DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -4380,6 +4698,7 @@
          kfree(LogicalDeviceInfo);
          Controller->LogicalDriveInitiallyAccessible
            [LogicalDriveNumber] = false;
+         DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
        }
      Controller->V2.NeedLogicalDeviceInformation = false;
    }
@@ -4785,6 +5104,85 @@
 
 
 /*
+  DAC960_P_InterruptHandler handles hardware interrupts from DAC960 P Series
+  Controllers.
+*/
+
+static void DAC960_P_InterruptHandler(int IRQ_Channel,
+                  void *DeviceIdentifier,
+                  Registers_T *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  ProcessorFlags_T ProcessorFlags;
+  /*
+    Acquire exclusive access to Controller.
+  */
+  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+  /*
+    Process Hardware Interrupts for Controller.
+  */
+  while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
+    {
+      DAC960_V1_CommandIdentifier_T CommandIdentifier =
+   DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+      DAC960_V1_CommandOpcode_T CommandOpcode =
+   CommandMailbox->Common.CommandOpcode;
+      Command->V1.CommandStatus =
+   DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
+      DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
+      DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
+      switch (CommandOpcode)
+   {
+   case DAC960_V1_Enquiry_Old:
+     Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Enquiry;
+     DAC960_P_To_PD_TranslateEnquiry(
+       Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
+     break;
+   case DAC960_V1_GetDeviceState_Old:
+     Command->V1.CommandMailbox.Common.CommandOpcode =
+       DAC960_V1_GetDeviceState;
+     DAC960_P_To_PD_TranslateDeviceState(
+       Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
+     break;
+   case DAC960_V1_Read_Old:
+     Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Read;
+     DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+     break;
+   case DAC960_V1_Write_Old:
+     Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Write;
+     DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+     break;
+   case DAC960_V1_ReadWithScatterGather_Old:
+     Command->V1.CommandMailbox.Common.CommandOpcode =
+       DAC960_V1_ReadWithScatterGather;
+     DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+     break;
+   case DAC960_V1_WriteWithScatterGather_Old:
+     Command->V1.CommandMailbox.Common.CommandOpcode =
+       DAC960_V1_WriteWithScatterGather;
+     DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+     break;
+   default:
+     break;
+   }
+      DAC960_V1_ProcessCompletedCommand(Command);
+    }
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  while (DAC960_ProcessRequest(Controller, false)) ;
+  /*
+    Release exclusive access to Controller.
+  */
+  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
   DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1
   Firmware Controllers.
 */
@@ -4881,8 +5279,7 @@
       Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
          if (LogicalDeviceInfo == NULL) continue;
          if (!LogicalDeviceInfo->LogicalDeviceControl
-                 .LogicalDeviceInitialized &&
-        Controller->LogicalDriveUsageCount[LogicalDriveNumber] > 0)
+                 .LogicalDeviceInitialized)
       {
         ForceMonitoringCommand = true;
         break;
@@ -4970,6 +5367,7 @@
   if (!Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber])
     {
       Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
+      DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
       DAC960_RegisterDisk(Controller, LogicalDriveNumber);
     }
   if (Controller->GenericDiskInfo.sizes[MINOR(Inode->i_rdev)] == 0)
@@ -5049,7 +5447,7 @@
        Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
      if (LogicalDeviceInfo == NULL)
        return -EINVAL;
-     switch(LogicalDeviceInfo->DriveGeometry)
+     switch (LogicalDeviceInfo->DriveGeometry)
        {
        case DAC960_V2_Geometry_128_32:
          Geometry.heads = 128;
@@ -5065,7 +5463,7 @@
          return -EINVAL;
        }
      Geometry.cylinders =
-       LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB
+       LogicalDeviceInfo->ConfigurableDeviceSize
        / (Geometry.heads * Geometry.sectors);
    }
       Geometry.start =
@@ -5074,19 +5472,22 @@
             sizeof(DiskGeometry_T)) ? -EFAULT : 0);
     case BLKGETSIZE:
       /* Get Device Size. */
+      if ((unsigned long *) Argument == NULL) return -EINVAL;
       return put_user(Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
                    .nr_sects,
-            (long *) Argument);
+            (unsigned long *) Argument);
     case BLKGETSIZE64:
-      return put_user((u64)Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].nr_sects << 9,
+      if ((u64 *) Argument == NULL) return -EINVAL;
+      return put_user((u64) Controller->GenericDiskInfo
+                   .part[MINOR(Inode->i_rdev)]
+                   .nr_sects << 9,
             (u64 *) Argument);
     case BLKRAGET:
     case BLKRASET:
     case BLKFLSBUF:
     case BLKBSZGET:
     case BLKBSZSET:
-      return blk_ioctl (Inode->i_rdev, Request, Argument);
-
+      return blk_ioctl(Inode->i_rdev, Request, Argument);
     case BLKRRPART:
       /* Re-Read Partition Table. */
       if (!capable(CAP_SYS_ADMIN)) return -EACCES;
@@ -5120,20 +5521,7 @@
      */
      set_blocksize(Device, BLOCK_SIZE);
    }
-      if (Controller->FirmwareType == DAC960_V1_Controller)
-   grok_partitions(&Controller->GenericDiskInfo,
-         LogicalDriveNumber,
-         DAC960_MaxPartitions,
-         Controller->V1.LogicalDriveInformation
-                   [LogicalDriveNumber]
-                   .LogicalDriveSize);
-      else
-   grok_partitions(
-     &Controller->GenericDiskInfo,
-     LogicalDriveNumber,
-     DAC960_MaxPartitions,
-     Controller->V2.LogicalDeviceInformation[LogicalDriveNumber]
-          ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+      DAC960_RegisterDisk(Controller, LogicalDriveNumber);
       return 0;
     }
   return -EINVAL;
@@ -6365,6 +6753,43 @@
             == DAC960_V2_NormalCompletion
             ? "Cancelled" : "Not Cancelled"));
     }
+  else if (strcmp(UserCommand, "perform-discovery") == 0)
+    {
+      CommandMailbox->Common.IOCTL_Opcode = DAC960_V2_StartDiscovery;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Discovery %s\n", Controller,
+           (Command->V2.CommandStatus
+            == DAC960_V2_NormalCompletion
+            ? "Initiated" : "Not Initiated"));
+      if (Command->V2.CommandStatus == DAC960_V2_NormalCompletion)
+   {
+     CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
+     CommandMailbox->ControllerInfo.CommandControlBits
+               .DataTransferControllerToHost = true;
+     CommandMailbox->ControllerInfo.CommandControlBits
+               .NoAutoRequestSense = true;
+     CommandMailbox->ControllerInfo.DataTransferSize =
+       sizeof(DAC960_V2_ControllerInfo_T);
+     CommandMailbox->ControllerInfo.ControllerNumber = 0;
+     CommandMailbox->ControllerInfo.IOCTL_Opcode =
+       DAC960_V2_GetControllerInfo;
+     CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+               .ScatterGatherSegments[0]
+               .SegmentDataPointer =
+       Virtual_to_Bus64(&Controller->V2.NewControllerInformation);
+     CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+               .ScatterGatherSegments[0]
+               .SegmentByteCount =
+       CommandMailbox->ControllerInfo.DataTransferSize;
+     DAC960_ExecuteCommand(Command);
+     while (Controller->V2.NewControllerInformation.PhysicalScanActive)
+       {
+         DAC960_ExecuteCommand(Command);
+         sleep_on_timeout(&Controller->CommandWaitQueue, HZ);
+       }
+     DAC960_UserCritical("Discovery Completed\n", Controller);
+    }
+    }
   else if (strcmp(UserCommand, "suppress-enclosure-messages") == 0)
     Controller->SuppressEnclosureMessages = true;
   else DAC960_UserCritical("Illegal User Command: '%s'\n",
@@ -6587,24 +7012,5 @@
 }
 
 
-/*
-  Include Module support if requested.
-*/
-
-#ifdef MODULE
-
-
-int init_module(void)
-{
-  DAC960_Initialize();
-  return (DAC960_ActiveControllerCount > 0 ? 0 : -1);
-}
-
-
-void cleanup_module(void)
-{
-  DAC960_Finalize(&DAC960_NotifierBlock, SYS_RESTART, NULL);
-}
-
-
-#endif
+module_init(DAC960_Initialize);
+module_exit(DAC960_Finalize);


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.