summaryrefslogtreecommitdiffstats
path: root/drivers/block/DAC960.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/DAC960.c')
-rw-r--r--drivers/block/DAC960.c5751
1 files changed, 4248 insertions, 1503 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 41ec3e2f5..749b0d3da 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -1,8 +1,8 @@
/*
- Linux Driver for Mylex DAC960 and DAC1100 PCI RAID Controllers
+ Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
- Copyright 1998-1999 by Leonard N. Zubkoff <lnz@dandelion.com>
+ Copyright 1998-2000 by Leonard N. Zubkoff <lnz@dandelion.com>
This program is free software; you may redistribute and/or modify it under
the terms of the GNU General Public License Version 2 as published by the
@@ -19,9 +19,8 @@
*/
-#define DAC960_DriverVersion "2.3.5"
-#define DAC960_DriverDate "23 January 2000"
-
+#define DAC960_DriverVersion "2.4.7"
+#define DAC960_DriverDate "1 August 2000"
#include <linux/version.h>
@@ -38,11 +37,11 @@
#include <linux/malloc.h>
#include <linux/proc_fs.h>
#include <linux/reboot.h>
+#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/segment.h>
-#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include "DAC960.h"
@@ -56,7 +55,7 @@ static int
/*
- DAC960_ActiveControllerCount is the number of Active DAC960 Controllers
+ DAC960_ActiveControllerCount is the number of active DAC960 Controllers
detected.
*/
@@ -74,23 +73,23 @@ static DAC960_Controller_T
/*
- DAC960_FileOperations is the File Operations structure for DAC960 Logical
- Disk Devices.
- Leonard, no offence, but _where_ did this C dialect come from?
+ DAC960_BlockDeviceOperations is the Block Device Operations structure for
+ DAC960 Logical Disk Devices.
*/
-static struct block_device_operations DAC960_FileOperations = {
- open: DAC960_Open,
- release: DAC960_Release,
- ioctl: DAC960_IOCTL,
-};
+static BlockDeviceOperations_T
+ DAC960_BlockDeviceOperations =
+ { open: DAC960_Open,
+ release: DAC960_Release,
+ ioctl: DAC960_IOCTL };
+
/*
- DAC960_ProcDirectoryEntry is the DAC960 /proc/driver/rd directory entry.
+ DAC960_ProcDirectoryEntry is the DAC960 /proc/rd directory entry.
*/
-static PROC_DirectoryEntry_T *
- DAC960_ProcDirectoryEntry = NULL;
+static PROC_DirectoryEntry_T
+ *DAC960_ProcDirectoryEntry;
/*
@@ -121,7 +120,7 @@ static void DAC960_AnnounceDriver(DAC960_Controller_T *Controller)
*/
static boolean DAC960_Failure(DAC960_Controller_T *Controller,
- char *ErrorMessage)
+ unsigned char *ErrorMessage)
{
DAC960_Error("While configuring DAC960 PCI RAID Controller at\n",
Controller);
@@ -141,17 +140,128 @@ static boolean DAC960_Failure(DAC960_Controller_T *Controller,
/*
- DAC960_ClearCommand clears critical fields of Command.
+ DAC960_CreateAuxiliaryStructures allocates and initializes the auxiliary
+ data structures for Controller. It returns true on success and false on
+ failure.
*/
-static inline void DAC960_ClearCommand(DAC960_Command_T *Command)
+static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
{
- DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
- CommandMailbox->Words[0] = 0;
- CommandMailbox->Words[1] = 0;
- CommandMailbox->Words[2] = 0;
- CommandMailbox->Words[3] = 0;
- Command->CommandStatus = 0;
+ int CommandAllocationLength, CommandAllocationGroupSize;
+ int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount;
+ void *AllocationPointer = NULL;
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ {
+ CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker);
+ CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize;
+ }
+ else
+ {
+ CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker);
+ CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize;
+ }
+ Controller->CommandAllocationGroupSize = CommandAllocationGroupSize;
+ Controller->FreeCommands = NULL;
+ for (CommandIdentifier = 1;
+ CommandIdentifier <= Controller->DriverQueueDepth;
+ CommandIdentifier++)
+ {
+ DAC960_Command_T *Command;
+ if (--CommandsRemaining <= 0)
+ {
+ CommandsRemaining =
+ Controller->DriverQueueDepth - CommandIdentifier + 1;
+ if (CommandsRemaining > CommandAllocationGroupSize)
+ CommandsRemaining = CommandAllocationGroupSize;
+ CommandGroupByteCount =
+ CommandsRemaining * CommandAllocationLength;
+ AllocationPointer = kmalloc(CommandGroupByteCount, GFP_ATOMIC);
+ if (AllocationPointer == NULL)
+ return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
+ memset(AllocationPointer, 0, CommandGroupByteCount);
+ }
+ Command = (DAC960_Command_T *) AllocationPointer;
+ AllocationPointer += CommandAllocationLength;
+ Command->CommandIdentifier = CommandIdentifier;
+ Command->Controller = Controller;
+ Command->Next = Controller->FreeCommands;
+ Controller->FreeCommands = Command;
+ Controller->Commands[CommandIdentifier-1] = Command;
+ }
+ return true;
+}
+
+
+/*
+ DAC960_DestroyAuxiliaryStructures deallocates the auxiliary data
+ structures for Controller.
+*/
+
+static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
+{
+ int i;
+ Controller->FreeCommands = NULL;
+ for (i = 0; i < Controller->DriverQueueDepth; i++)
+ {
+ DAC960_Command_T *Command = Controller->Commands[i];
+ if (Command != NULL &&
+ (Command->CommandIdentifier
+ % Controller->CommandAllocationGroupSize) == 1)
+ kfree(Command);
+ Controller->Commands[i] = NULL;
+ }
+ if (Controller->CombinedStatusBuffer != NULL)
+ {
+ kfree(Controller->CombinedStatusBuffer);
+ Controller->CombinedStatusBuffer = NULL;
+ Controller->CurrentStatusBuffer = NULL;
+ }
+ if (Controller->FirmwareType == DAC960_V1_Controller) return;
+ for (i = 0; i < DAC960_MaxLogicalDrives; i++)
+ if (Controller->V2.LogicalDeviceInformation[i] != NULL)
+ {
+ kfree(Controller->V2.LogicalDeviceInformation[i]);
+ Controller->V2.LogicalDeviceInformation[i] = NULL;
+ }
+ for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)
+ {
+ if (Controller->V2.PhysicalDeviceInformation[i] != NULL)
+ {
+ kfree(Controller->V2.PhysicalDeviceInformation[i]);
+ Controller->V2.PhysicalDeviceInformation[i] = NULL;
+ }
+ if (Controller->V2.InquiryUnitSerialNumber[i] != NULL)
+ {
+ kfree(Controller->V2.InquiryUnitSerialNumber[i]);
+ Controller->V2.InquiryUnitSerialNumber[i] = NULL;
+ }
+ }
+}
+
+
+/*
+ DAC960_V1_ClearCommand clears critical fields of Command for DAC960 V1
+ Firmware Controllers.
+*/
+
+static inline void DAC960_V1_ClearCommand(DAC960_Command_T *Command)
+{
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ memset(CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T));
+ Command->V1.CommandStatus = 0;
+}
+
+
+/*
+ DAC960_V2_ClearCommand clears critical fields of Command for DAC960 V2
+ Firmware Controllers.
+*/
+
+static inline void DAC960_V2_ClearCommand(DAC960_Command_T *Command)
+{
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ memset(CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
+ Command->V2.CommandStatus = 0;
}
@@ -202,66 +312,181 @@ static void DAC960_WaitForCommand(DAC960_Controller_T *Controller)
/*
- DAC960_QueueCommand queues Command.
+ DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers.
*/
-static void DAC960_QueueCommand(DAC960_Command_T *Command)
+static void DAC960_BA_QueueCommand(DAC960_Command_T *Command)
{
DAC960_Controller_T *Controller = Command->Controller;
void *ControllerBaseAddress = Controller->BaseAddress;
- DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
- DAC960_CommandMailbox_T *NextCommandMailbox;
- CommandMailbox->Common.CommandIdentifier = Command - Controller->Commands;
- switch (Controller->ControllerType)
- {
- case DAC960_V5_Controller:
- NextCommandMailbox = Controller->NextCommandMailbox;
- DAC960_V5_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
- if (Controller->PreviousCommandMailbox1->Words[0] == 0 ||
- Controller->PreviousCommandMailbox2->Words[0] == 0)
- {
- if (Controller->DualModeMemoryMailboxInterface)
- DAC960_V5_MemoryMailboxNewCommand(ControllerBaseAddress);
- else DAC960_V5_HardwareMailboxNewCommand(ControllerBaseAddress);
- }
- Controller->PreviousCommandMailbox2 = Controller->PreviousCommandMailbox1;
- Controller->PreviousCommandMailbox1 = NextCommandMailbox;
- if (++NextCommandMailbox > Controller->LastCommandMailbox)
- NextCommandMailbox = Controller->FirstCommandMailbox;
- Controller->NextCommandMailbox = NextCommandMailbox;
- break;
- case DAC960_V4_Controller:
- NextCommandMailbox = Controller->NextCommandMailbox;
- DAC960_V4_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
- if (Controller->PreviousCommandMailbox1->Words[0] == 0 ||
- Controller->PreviousCommandMailbox2->Words[0] == 0)
- {
- if (Controller->DualModeMemoryMailboxInterface)
- DAC960_V4_MemoryMailboxNewCommand(ControllerBaseAddress);
- else DAC960_V4_HardwareMailboxNewCommand(ControllerBaseAddress);
- }
- Controller->PreviousCommandMailbox2 = Controller->PreviousCommandMailbox1;
- Controller->PreviousCommandMailbox1 = NextCommandMailbox;
- if (++NextCommandMailbox > Controller->LastCommandMailbox)
- NextCommandMailbox = Controller->FirstCommandMailbox;
- Controller->NextCommandMailbox = NextCommandMailbox;
- break;
- case DAC960_V3_Controller:
- while (DAC960_V3_MailboxFullP(ControllerBaseAddress))
- udelay(1);
- DAC960_V3_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
- DAC960_V3_NewCommand(ControllerBaseAddress);
- break;
- }
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_CommandMailbox_T *NextCommandMailbox =
+ Controller->V2.NextCommandMailbox;
+ CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+ DAC960_BA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+ if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
+ Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
+ DAC960_BA_MemoryMailboxNewCommand(ControllerBaseAddress);
+ Controller->V2.PreviousCommandMailbox2 =
+ Controller->V2.PreviousCommandMailbox1;
+ Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
+ if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
+ NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+ Controller->V2.NextCommandMailbox = NextCommandMailbox;
}
/*
- DAC960_ExecuteCommand executes Command and waits for completion. It
- returns true on success and false on failure.
+ DAC960_LP_QueueCommand queues Command for DAC960 LP Series Controllers.
*/
-static boolean DAC960_ExecuteCommand(DAC960_Command_T *Command)
+static void DAC960_LP_QueueCommand(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_CommandMailbox_T *NextCommandMailbox =
+ Controller->V2.NextCommandMailbox;
+ CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+ DAC960_LP_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+ if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
+ Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
+ DAC960_LP_MemoryMailboxNewCommand(ControllerBaseAddress);
+ Controller->V2.PreviousCommandMailbox2 =
+ Controller->V2.PreviousCommandMailbox1;
+ Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
+ if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
+ NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+ Controller->V2.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+ DAC960_LA_QueueCommandDualMode queues Command for DAC960 LA Series
+ Controllers with Dual Mode Firmware.
+*/
+
+static void DAC960_LA_QueueCommandDualMode(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+ Controller->V1.NextCommandMailbox;
+ CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+ DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+ if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+ Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+ DAC960_LA_MemoryMailboxNewCommand(ControllerBaseAddress);
+ Controller->V1.PreviousCommandMailbox2 =
+ Controller->V1.PreviousCommandMailbox1;
+ Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+ if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+ NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+ Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+ DAC960_LA_QueueCommandSingleMode queues Command for DAC960 LA Series
+ Controllers with Single Mode Firmware.
+*/
+
+static void DAC960_LA_QueueCommandSingleMode(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+ Controller->V1.NextCommandMailbox;
+ CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+ DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+ if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+ Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+ DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
+ Controller->V1.PreviousCommandMailbox2 =
+ Controller->V1.PreviousCommandMailbox1;
+ Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+ if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+ NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+ Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+ DAC960_PG_QueueCommandDualMode queues Command for DAC960 PG Series
+ Controllers with Dual Mode Firmware.
+*/
+
+static void DAC960_PG_QueueCommandDualMode(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+ Controller->V1.NextCommandMailbox;
+ CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+ DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+ if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+ Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+ DAC960_PG_MemoryMailboxNewCommand(ControllerBaseAddress);
+ Controller->V1.PreviousCommandMailbox2 =
+ Controller->V1.PreviousCommandMailbox1;
+ Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+ if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+ NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+ Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+ DAC960_PG_QueueCommandSingleMode queues Command for DAC960 PG Series
+ Controllers with Single Mode Firmware.
+*/
+
+static void DAC960_PG_QueueCommandSingleMode(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+ Controller->V1.NextCommandMailbox;
+ CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+ DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+ if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+ Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+ DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
+ Controller->V1.PreviousCommandMailbox2 =
+ Controller->V1.PreviousCommandMailbox1;
+ Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+ if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+ NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+ Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+ DAC960_PD_QueueCommand queues Command for DAC960 PD Series Controllers.
+*/
+
+static void DAC960_PD_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;
+ while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
+ udelay(1);
+ DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
+ DAC960_PD_NewCommand(ControllerBaseAddress);
+}
+
+
+/*
+ DAC960_ExecuteCommand executes Command and waits for completion.
+*/
+
+static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
{
DAC960_Controller_T *Controller = Command->Controller;
DECLARE_MUTEX_LOCKED(Semaphore);
@@ -270,227 +495,386 @@ static boolean DAC960_ExecuteCommand(DAC960_Command_T *Command)
DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
DAC960_QueueCommand(Command);
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- if (!in_interrupt())
- down(&Semaphore);
- return Command->CommandStatus == DAC960_NormalCompletion;
+ if (in_interrupt()) return;
+ down(&Semaphore);
}
/*
- DAC960_ExecuteType3 executes a DAC960 Type 3 Command and waits for
- completion. It returns true on success and false on failure.
+ DAC960_V1_ExecuteType3 executes a DAC960 V1 Firmware Controller Type 3
+ Command and waits for completion. It returns true on success and false
+ on failure.
*/
-static boolean DAC960_ExecuteType3(DAC960_Controller_T *Controller,
- DAC960_CommandOpcode_T CommandOpcode,
- void *DataPointer)
+static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
+ DAC960_V1_CommandOpcode_T CommandOpcode,
+ void *DataPointer)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
- DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
- boolean Result;
- DAC960_ClearCommand(Command);
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_CommandStatus_T CommandStatus;
+ DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
CommandMailbox->Type3.CommandOpcode = CommandOpcode;
CommandMailbox->Type3.BusAddress = Virtual_to_Bus(DataPointer);
- Result = DAC960_ExecuteCommand(Command);
+ DAC960_ExecuteCommand(Command);
+ CommandStatus = Command->V1.CommandStatus;
DAC960_DeallocateCommand(Command);
- return Result;
+ return (CommandStatus == DAC960_V1_NormalCompletion);
}
/*
- DAC960_ExecuteType3D executes a DAC960 Type 3D Command and waits for
- completion. It returns true on success and false on failure.
+ 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.
*/
-static boolean DAC960_ExecuteType3D(DAC960_Controller_T *Controller,
- DAC960_CommandOpcode_T CommandOpcode,
- unsigned char Channel,
- unsigned char TargetID,
- void *DataPointer)
+static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
+ DAC960_V1_CommandOpcode_T CommandOpcode,
+ unsigned char Channel,
+ unsigned char TargetID,
+ void *DataPointer)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
- DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
- boolean Result;
- DAC960_ClearCommand(Command);
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_CommandStatus_T CommandStatus;
+ DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
CommandMailbox->Type3D.CommandOpcode = CommandOpcode;
CommandMailbox->Type3D.Channel = Channel;
CommandMailbox->Type3D.TargetID = TargetID;
CommandMailbox->Type3D.BusAddress = Virtual_to_Bus(DataPointer);
- Result = DAC960_ExecuteCommand(Command);
+ DAC960_ExecuteCommand(Command);
+ CommandStatus = Command->V1.CommandStatus;
DAC960_DeallocateCommand(Command);
- return Result;
+ return (CommandStatus == DAC960_V1_NormalCompletion);
}
/*
- DAC960_ReportErrorStatus reports Controller BIOS Messages passed through
- the Error Status Register when the driver performs the BIOS handshaking.
- It returns true for fatal errors and false otherwise.
+ DAC960_V2_GeneralInfo executes a DAC960 V2 Firmware General Information
+ Reading IOCTL Command and waits for completion. It returns true on success
+ and false on failure.
*/
-static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
- unsigned char ErrorStatus,
- unsigned char Parameter0,
- unsigned char Parameter1)
+static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller,
+ DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
+ void *DataPointer,
+ unsigned int DataByteCount)
{
- switch (ErrorStatus)
- {
- case 0x00:
- DAC960_Notice("Physical Drive %d:%d Not Responding\n",
- Controller, Parameter1, Parameter0);
- break;
- case 0x08:
- if (Controller->DriveSpinUpMessageDisplayed) break;
- DAC960_Notice("Spinning Up Drives\n", Controller);
- Controller->DriveSpinUpMessageDisplayed = true;
- break;
- case 0x30:
- DAC960_Notice("Configuration Checksum Error\n", Controller);
- break;
- case 0x60:
- DAC960_Notice("Mirror Race Recovery Failed\n", Controller);
- break;
- case 0x70:
- DAC960_Notice("Mirror Race Recovery In Progress\n", Controller);
- break;
- case 0x90:
- DAC960_Notice("Physical Drive %d:%d COD Mismatch\n",
- Controller, Parameter1, Parameter0);
- break;
- case 0xA0:
- DAC960_Notice("Logical Drive Installation Aborted\n", Controller);
- break;
- case 0xB0:
- DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller);
- break;
- case 0xD0:
- DAC960_Notice("New Controller Configuration Found\n", Controller);
- break;
- case 0xF0:
- DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller);
- return true;
- default:
- DAC960_Error("Unknown Initialization Error %02X for Controller at\n",
- Controller, ErrorStatus);
- return true;
- }
- return false;
+ DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_CommandStatus_T CommandStatus;
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_ImmediateCommand;
+ CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->Common.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->Common.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->Common.DataTransferSize = DataByteCount;
+ CommandMailbox->Common.IOCTL_Opcode = IOCTL_Opcode;
+ CommandMailbox->Common.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(DataPointer);
+ CommandMailbox->Common.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->Common.DataTransferSize;
+ DAC960_ExecuteCommand(Command);
+ CommandStatus = Command->V2.CommandStatus;
+ DAC960_DeallocateCommand(Command);
+ return (CommandStatus == DAC960_V2_NormalCompletion);
}
/*
- DAC960_EnableMemoryMailboxInterface enables the Memory Mailbox Interface.
+ DAC960_V2_ControllerInfo executes a DAC960 V2 Firmware Controller
+ Information Reading IOCTL Command and waits for completion. It returns
+ true on success and false on failure.
*/
-static boolean DAC960_EnableMemoryMailboxInterface(DAC960_Controller_T
- *Controller)
+static boolean DAC960_V2_ControllerInfo(DAC960_Controller_T *Controller,
+ DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
+ void *DataPointer,
+ unsigned int DataByteCount)
+{
+ DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_CommandStatus_T CommandStatus;
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_ImmediateCommand;
+ CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->ControllerInfo.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->ControllerInfo.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->ControllerInfo.DataTransferSize = DataByteCount;
+ CommandMailbox->ControllerInfo.ControllerNumber = 0;
+ CommandMailbox->ControllerInfo.IOCTL_Opcode = IOCTL_Opcode;
+ CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(DataPointer);
+ CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->ControllerInfo.DataTransferSize;
+ DAC960_ExecuteCommand(Command);
+ CommandStatus = Command->V2.CommandStatus;
+ DAC960_DeallocateCommand(Command);
+ return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+ DAC960_V2_LogicalDeviceInfo executes a DAC960 V2 Firmware Controller Logical
+ Device Information Reading IOCTL Command and waits for completion. It
+ returns true on success and false on failure.
+*/
+
+static boolean DAC960_V2_LogicalDeviceInfo(DAC960_Controller_T *Controller,
+ DAC960_V2_IOCTL_Opcode_T
+ IOCTL_Opcode,
+ unsigned short
+ LogicalDeviceNumber,
+ void *DataPointer,
+ unsigned int DataByteCount)
+{
+ DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_CommandStatus_T CommandStatus;
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_ImmediateCommand;
+ CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->LogicalDeviceInfo.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->LogicalDeviceInfo.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->LogicalDeviceInfo.DataTransferSize = DataByteCount;
+ CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+ LogicalDeviceNumber;
+ CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
+ CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(DataPointer);
+ CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->LogicalDeviceInfo.DataTransferSize;
+ DAC960_ExecuteCommand(Command);
+ CommandStatus = Command->V2.CommandStatus;
+ DAC960_DeallocateCommand(Command);
+ return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+ DAC960_V2_PhysicalDeviceInfo executes a DAC960 V2 Firmware Controller Physical
+ Device Information Reading IOCTL Command and waits for completion. It
+ returns true on success and false on failure.
+*/
+
+static boolean DAC960_V2_PhysicalDeviceInfo(DAC960_Controller_T *Controller,
+ DAC960_V2_IOCTL_Opcode_T
+ IOCTL_Opcode,
+ unsigned char Channel,
+ unsigned char TargetID,
+ unsigned char LogicalUnit,
+ void *DataPointer,
+ unsigned int DataByteCount)
+{
+ DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_CommandStatus_T CommandStatus;
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_ImmediateCommand;
+ CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->PhysicalDeviceInfo.DataTransferSize = DataByteCount;
+ CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit = LogicalUnit;
+ CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
+ CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
+ CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
+ CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(DataPointer);
+ CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
+ DAC960_ExecuteCommand(Command);
+ CommandStatus = Command->V2.CommandStatus;
+ DAC960_DeallocateCommand(Command);
+ return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+ DAC960_V2_DeviceOperation executes a DAC960 V2 Firmware Controller Device
+ Operation IOCTL Command and waits for completion. It returns true on
+ success and false on failure.
+*/
+
+static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
+ DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
+ DAC960_V2_OperationDevice_T
+ OperationDevice)
+{
+ DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_CommandStatus_T CommandStatus;
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_ImmediateCommand;
+ CommandMailbox->DeviceOperation.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->DeviceOperation.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->DeviceOperation.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->DeviceOperation.IOCTL_Opcode = IOCTL_Opcode;
+ CommandMailbox->DeviceOperation.OperationDevice = OperationDevice;
+ DAC960_ExecuteCommand(Command);
+ CommandStatus = Command->V2.CommandStatus;
+ DAC960_DeallocateCommand(Command);
+ return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+ DAC960_V1_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
+ for DAC960 V1 Firmware Controllers.
+*/
+
+static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
+ *Controller)
{
void *ControllerBaseAddress = Controller->BaseAddress;
- DAC960_CommandMailbox_T *CommandMailboxesMemory;
- DAC960_StatusMailbox_T *StatusMailboxesMemory;
- DAC960_CommandMailbox_T CommandMailbox;
- DAC960_CommandStatus_T CommandStatus;
+ DAC960_V1_CommandMailbox_T *CommandMailboxesMemory;
+ DAC960_V1_StatusMailbox_T *StatusMailboxesMemory;
+ DAC960_V1_CommandMailbox_T CommandMailbox;
+ DAC960_V1_CommandStatus_T CommandStatus;
+ unsigned long MemoryMailboxPagesAddress;
+ unsigned long MemoryMailboxPagesOrder;
+ unsigned long MemoryMailboxPagesSize;
void *SavedMemoryMailboxesAddress = NULL;
short NextCommandMailboxIndex = 0;
short NextStatusMailboxIndex = 0;
int TimeoutCounter = 1000000, i;
- if (Controller->ControllerType == DAC960_V5_Controller)
- DAC960_V5_RestoreMemoryMailboxInfo(Controller,
+ MemoryMailboxPagesOrder = 0;
+ MemoryMailboxPagesSize =
+ DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T) +
+ DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T);
+ while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
+ MemoryMailboxPagesOrder++;
+ if (Controller->HardwareType == DAC960_LA_Controller)
+ DAC960_LA_RestoreMemoryMailboxInfo(Controller,
&SavedMemoryMailboxesAddress,
&NextCommandMailboxIndex,
&NextStatusMailboxIndex);
- else DAC960_V4_RestoreMemoryMailboxInfo(Controller,
+ else DAC960_PG_RestoreMemoryMailboxInfo(Controller,
&SavedMemoryMailboxesAddress,
&NextCommandMailboxIndex,
&NextStatusMailboxIndex);
if (SavedMemoryMailboxesAddress == NULL)
- CommandMailboxesMemory =
- (DAC960_CommandMailbox_T *) __get_free_pages(GFP_KERNEL, 1);
+ {
+ MemoryMailboxPagesAddress =
+ __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
+ Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
+ CommandMailboxesMemory =
+ (DAC960_V1_CommandMailbox_T *) MemoryMailboxPagesAddress;
+ }
else CommandMailboxesMemory = SavedMemoryMailboxesAddress;
- memset(CommandMailboxesMemory, 0, PAGE_SIZE << 1);
- Controller->FirstCommandMailbox = CommandMailboxesMemory;
- CommandMailboxesMemory += DAC960_CommandMailboxCount - 1;
- Controller->LastCommandMailbox = CommandMailboxesMemory;
- Controller->NextCommandMailbox =
- &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
+ if (CommandMailboxesMemory == NULL) return false;
+ Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
+ memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
+ Controller->V1.FirstCommandMailbox = CommandMailboxesMemory;
+ CommandMailboxesMemory += DAC960_V1_CommandMailboxCount - 1;
+ Controller->V1.LastCommandMailbox = CommandMailboxesMemory;
+ Controller->V1.NextCommandMailbox =
+ &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
if (--NextCommandMailboxIndex < 0)
- NextCommandMailboxIndex = DAC960_CommandMailboxCount - 1;
- Controller->PreviousCommandMailbox1 =
- &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
+ NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
+ Controller->V1.PreviousCommandMailbox1 =
+ &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
if (--NextCommandMailboxIndex < 0)
- NextCommandMailboxIndex = DAC960_CommandMailboxCount - 1;
- Controller->PreviousCommandMailbox2 =
- &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
+ NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
+ Controller->V1.PreviousCommandMailbox2 =
+ &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
StatusMailboxesMemory =
- (DAC960_StatusMailbox_T *) (CommandMailboxesMemory + 1);
- Controller->FirstStatusMailbox = StatusMailboxesMemory;
- StatusMailboxesMemory += DAC960_StatusMailboxCount - 1;
- Controller->LastStatusMailbox = StatusMailboxesMemory;
- Controller->NextStatusMailbox =
- &Controller->FirstStatusMailbox[NextStatusMailboxIndex];
+ (DAC960_V1_StatusMailbox_T *) (CommandMailboxesMemory + 1);
+ Controller->V1.FirstStatusMailbox = StatusMailboxesMemory;
+ StatusMailboxesMemory += DAC960_V1_StatusMailboxCount - 1;
+ Controller->V1.LastStatusMailbox = StatusMailboxesMemory;
+ Controller->V1.NextStatusMailbox =
+ &Controller->V1.FirstStatusMailbox[NextStatusMailboxIndex];
if (SavedMemoryMailboxesAddress != NULL) return true;
/* Enable the Memory Mailbox Interface. */
- Controller->DualModeMemoryMailboxInterface = true;
+ Controller->V1.DualModeMemoryMailboxInterface = true;
CommandMailbox.TypeX.CommandOpcode = 0x2B;
CommandMailbox.TypeX.CommandIdentifier = 0;
CommandMailbox.TypeX.CommandOpcode2 = 0x14;
CommandMailbox.TypeX.CommandMailboxesBusAddress =
- Virtual_to_Bus(Controller->FirstCommandMailbox);
+ Virtual_to_Bus(Controller->V1.FirstCommandMailbox);
CommandMailbox.TypeX.StatusMailboxesBusAddress =
- Virtual_to_Bus(Controller->FirstStatusMailbox);
+ Virtual_to_Bus(Controller->V1.FirstStatusMailbox);
for (i = 0; i < 2; i++)
- switch (Controller->ControllerType)
+ switch (Controller->HardwareType)
{
- case DAC960_V5_Controller:
+ case DAC960_LA_Controller:
while (--TimeoutCounter >= 0)
{
- if (!DAC960_V5_HardwareMailboxFullP(ControllerBaseAddress))
+ if (!DAC960_LA_HardwareMailboxFullP(ControllerBaseAddress))
break;
udelay(10);
}
if (TimeoutCounter < 0) return false;
- DAC960_V5_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
- DAC960_V5_HardwareMailboxNewCommand(ControllerBaseAddress);
+ DAC960_LA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+ DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
while (--TimeoutCounter >= 0)
{
- if (DAC960_V5_HardwareMailboxStatusAvailableP(
+ if (DAC960_LA_HardwareMailboxStatusAvailableP(
ControllerBaseAddress))
break;
udelay(10);
}
if (TimeoutCounter < 0) return false;
- CommandStatus = DAC960_V5_ReadStatusRegister(ControllerBaseAddress);
- DAC960_V5_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
- DAC960_V5_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
- if (CommandStatus == DAC960_NormalCompletion) return true;
- Controller->DualModeMemoryMailboxInterface = false;
+ CommandStatus = DAC960_LA_ReadStatusRegister(ControllerBaseAddress);
+ DAC960_LA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+ DAC960_LA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
+ if (CommandStatus == DAC960_V1_NormalCompletion) return true;
+ Controller->V1.DualModeMemoryMailboxInterface = false;
CommandMailbox.TypeX.CommandOpcode2 = 0x10;
break;
- case DAC960_V4_Controller:
+ case DAC960_PG_Controller:
while (--TimeoutCounter >= 0)
{
- if (!DAC960_V4_HardwareMailboxFullP(ControllerBaseAddress))
+ if (!DAC960_PG_HardwareMailboxFullP(ControllerBaseAddress))
break;
udelay(10);
}
if (TimeoutCounter < 0) return false;
- DAC960_V4_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
- DAC960_V4_HardwareMailboxNewCommand(ControllerBaseAddress);
+ DAC960_PG_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+ DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
while (--TimeoutCounter >= 0)
{
- if (DAC960_V4_HardwareMailboxStatusAvailableP(
+ if (DAC960_PG_HardwareMailboxStatusAvailableP(
ControllerBaseAddress))
break;
udelay(10);
}
if (TimeoutCounter < 0) return false;
- CommandStatus = DAC960_V4_ReadStatusRegister(ControllerBaseAddress);
- DAC960_V4_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
- DAC960_V4_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
- if (CommandStatus == DAC960_NormalCompletion) return true;
- Controller->DualModeMemoryMailboxInterface = false;
+ CommandStatus = DAC960_PG_ReadStatusRegister(ControllerBaseAddress);
+ DAC960_PG_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+ DAC960_PG_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
+ if (CommandStatus == DAC960_V1_NormalCompletion) return true;
+ Controller->V1.DualModeMemoryMailboxInterface = false;
CommandMailbox.TypeX.CommandOpcode2 = 0x10;
break;
default:
@@ -501,287 +885,165 @@ static boolean DAC960_EnableMemoryMailboxInterface(DAC960_Controller_T
/*
- DAC960_DetectControllers detects DAC960 PCI RAID Controllers by interrogating
- the PCI Configuration Space for Controller Type.
+ DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
+ for DAC960 V2 Firmware Controllers.
*/
-static void DAC960_DetectControllers(DAC960_ControllerType_T ControllerType)
+static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
+ *Controller)
{
- unsigned short VendorID = 0, DeviceID = 0;
- unsigned int MemoryWindowSize = 0;
- PCI_Device_T *PCI_Device = NULL;
- switch (ControllerType)
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V2_CommandMailbox_T *CommandMailboxesMemory;
+ DAC960_V2_StatusMailbox_T *StatusMailboxesMemory;
+ DAC960_V2_CommandMailbox_T CommandMailbox;
+ DAC960_V2_CommandStatus_T CommandStatus = 0;
+ unsigned long MemoryMailboxPagesAddress;
+ unsigned long MemoryMailboxPagesOrder;
+ unsigned long MemoryMailboxPagesSize;
+ MemoryMailboxPagesOrder = 0;
+ MemoryMailboxPagesSize =
+ DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T) +
+ DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T) +
+ sizeof(DAC960_V2_HealthStatusBuffer_T);
+ while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
+ MemoryMailboxPagesOrder++;
+ MemoryMailboxPagesAddress =
+ __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
+ Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
+ CommandMailboxesMemory =
+ (DAC960_V2_CommandMailbox_T *) MemoryMailboxPagesAddress;
+ if (CommandMailboxesMemory == NULL) return false;
+ Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
+ memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
+ Controller->V2.FirstCommandMailbox = CommandMailboxesMemory;
+ CommandMailboxesMemory += DAC960_V2_CommandMailboxCount - 1;
+ Controller->V2.LastCommandMailbox = CommandMailboxesMemory;
+ Controller->V2.NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+ Controller->V2.PreviousCommandMailbox1 = Controller->V2.LastCommandMailbox;
+ Controller->V2.PreviousCommandMailbox2 =
+ Controller->V2.LastCommandMailbox - 1;
+ StatusMailboxesMemory =
+ (DAC960_V2_StatusMailbox_T *) (CommandMailboxesMemory + 1);
+ Controller->V2.FirstStatusMailbox = StatusMailboxesMemory;
+ StatusMailboxesMemory += DAC960_V2_StatusMailboxCount - 1;
+ Controller->V2.LastStatusMailbox = StatusMailboxesMemory;
+ Controller->V2.NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+ Controller->V2.HealthStatusBuffer =
+ (DAC960_V2_HealthStatusBuffer_T *) (StatusMailboxesMemory + 1);
+ /* Enable the Memory Mailbox Interface. */
+ memset(&CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
+ CommandMailbox.SetMemoryMailbox.CommandIdentifier = 1;
+ CommandMailbox.SetMemoryMailbox.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox.SetMemoryMailbox.CommandControlBits.NoAutoRequestSense = true;
+ CommandMailbox.SetMemoryMailbox.FirstCommandMailboxSizeKB =
+ (DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T)) >> 10;
+ CommandMailbox.SetMemoryMailbox.FirstStatusMailboxSizeKB =
+ (DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T)) >> 10;
+ CommandMailbox.SetMemoryMailbox.SecondCommandMailboxSizeKB = 0;
+ CommandMailbox.SetMemoryMailbox.SecondStatusMailboxSizeKB = 0;
+ CommandMailbox.SetMemoryMailbox.RequestSenseSize = 0;
+ CommandMailbox.SetMemoryMailbox.IOCTL_Opcode = DAC960_V2_SetMemoryMailbox;
+ CommandMailbox.SetMemoryMailbox.HealthStatusBufferSizeKB = 1;
+ CommandMailbox.SetMemoryMailbox.HealthStatusBufferBusAddress =
+ Virtual_to_Bus(Controller->V2.HealthStatusBuffer);
+ CommandMailbox.SetMemoryMailbox.FirstCommandMailboxBusAddress =
+ Virtual_to_Bus(Controller->V2.FirstCommandMailbox);
+ CommandMailbox.SetMemoryMailbox.FirstStatusMailboxBusAddress =
+ Virtual_to_Bus(Controller->V2.FirstStatusMailbox);
+ switch (Controller->HardwareType)
{
- case DAC960_V5_Controller:
- VendorID = PCI_VENDOR_ID_DEC;
- DeviceID = PCI_DEVICE_ID_DEC_21285;
- MemoryWindowSize = DAC960_V5_RegisterWindowSize;
+ case DAC960_BA_Controller:
+ while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress))
+ udelay(1);
+ DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+ DAC960_BA_HardwareMailboxNewCommand(ControllerBaseAddress);
+ while (!DAC960_BA_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
+ udelay(1);
+ CommandStatus = DAC960_BA_ReadCommandStatus(ControllerBaseAddress);
+ DAC960_BA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+ DAC960_BA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
break;
- case DAC960_V4_Controller:
- VendorID = PCI_VENDOR_ID_MYLEX;
- DeviceID = PCI_DEVICE_ID_MYLEX_DAC960P_V4;
- MemoryWindowSize = DAC960_V4_RegisterWindowSize;
+ case DAC960_LP_Controller:
+ while (DAC960_LP_HardwareMailboxFullP(ControllerBaseAddress))
+ udelay(1);
+ DAC960_LP_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+ DAC960_LP_HardwareMailboxNewCommand(ControllerBaseAddress);
+ while (!DAC960_LP_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
+ udelay(1);
+ CommandStatus = DAC960_LP_ReadCommandStatus(ControllerBaseAddress);
+ DAC960_LP_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+ DAC960_LP_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
break;
- case DAC960_V3_Controller:
- VendorID = PCI_VENDOR_ID_MYLEX;
- DeviceID = PCI_DEVICE_ID_MYLEX_DAC960P_V3;
- MemoryWindowSize = DAC960_V3_RegisterWindowSize;
+ default:
break;
}
- while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *)
- kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
- DAC960_IO_Address_T IO_Address = 0;
- DAC960_PCI_Address_T PCI_Address = 0;
- unsigned char Bus = PCI_Device->bus->number;
- unsigned char DeviceFunction = PCI_Device->devfn;
- unsigned char Device = DeviceFunction >> 3;
- unsigned char Function = DeviceFunction & 0x7;
- unsigned int IRQ_Channel = PCI_Device->irq;
- unsigned long BaseAddress0 = pci_resource_start (PCI_Device, 0);
- unsigned long BaseAddress1 = pci_resource_start (PCI_Device, 1);
- unsigned short SubsystemVendorID, SubsystemDeviceID;
- int CommandIdentifier;
- unsigned char ErrorStatus, Parameter0, Parameter1;
- void *BaseAddress;
-
-
- if (pci_enable_device(PCI_Device))
- goto Ignore;
-
- SubsystemVendorID = PCI_Device->subsystem_vendor;
- SubsystemDeviceID = PCI_Device->subsystem_device;
- switch (ControllerType)
- {
- case DAC960_V5_Controller:
- if (!(SubsystemVendorID == PCI_VENDOR_ID_MYLEX &&
- SubsystemDeviceID == PCI_DEVICE_ID_MYLEX_DAC960P_V5))
- goto Ignore;
- PCI_Address = BaseAddress0;
- break;
- case DAC960_V4_Controller:
- PCI_Address = BaseAddress0;
- break;
- case DAC960_V3_Controller:
- IO_Address = BaseAddress0;
- PCI_Address = BaseAddress1;
- break;
- }
- if (DAC960_ControllerCount == DAC960_MaxControllers)
- {
- DAC960_Error("More than %d DAC960 Controllers detected - "
- "ignoring from Controller at\n",
- NULL, DAC960_MaxControllers);
- goto Ignore;
- }
- if (Controller == NULL)
- {
- DAC960_Error("Unable to allocate Controller structure for "
- "Controller at\n", NULL);
- goto Ignore;
- }
- memset(Controller, 0, sizeof(DAC960_Controller_T));
- init_waitqueue_head(&Controller->CommandWaitQueue);
- Controller->ControllerNumber = DAC960_ControllerCount;
- DAC960_Controllers[DAC960_ControllerCount++] = Controller;
- DAC960_AnnounceDriver(Controller);
- Controller->ControllerType = ControllerType;
- Controller->IO_Address = IO_Address;
- Controller->PCI_Address = PCI_Address;
- Controller->Bus = Bus;
- Controller->Device = Device;
- Controller->Function = Function;
- sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
- /*
- Map the Controller Register Window.
- */
- if (MemoryWindowSize < PAGE_SIZE)
- MemoryWindowSize = PAGE_SIZE;
- Controller->MemoryMappedAddress =
- ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
- Controller->BaseAddress =
- Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
- if (Controller->MemoryMappedAddress == NULL)
- {
- DAC960_Error("Unable to map Controller Register Window for "
- "Controller at\n", Controller);
- goto Failure;
- }
- BaseAddress = Controller->BaseAddress;
- switch (ControllerType)
- {
- case DAC960_V5_Controller:
- DAC960_V5_DisableInterrupts(BaseAddress);
- DAC960_V5_AcknowledgeHardwareMailboxStatus(BaseAddress);
- udelay(1000);
- while (DAC960_V5_InitializationInProgressP(BaseAddress))
- {
- if (DAC960_V5_ReadErrorStatus(BaseAddress, &ErrorStatus,
- &Parameter0, &Parameter1) &&
- DAC960_ReportErrorStatus(Controller, ErrorStatus,
- Parameter0, Parameter1))
- goto Failure;
- udelay(10);
- }
- if (!DAC960_EnableMemoryMailboxInterface(Controller))
- {
- DAC960_Error("Unable to Enable Memory Mailbox Interface "
- "for Controller at\n", Controller);
- goto Failure;
- }
- DAC960_V5_EnableInterrupts(BaseAddress);
- break;
- case DAC960_V4_Controller:
- DAC960_V4_DisableInterrupts(BaseAddress);
- DAC960_V4_AcknowledgeHardwareMailboxStatus(BaseAddress);
- udelay(1000);
- while (DAC960_V4_InitializationInProgressP(BaseAddress))
- {
- if (DAC960_V4_ReadErrorStatus(BaseAddress, &ErrorStatus,
- &Parameter0, &Parameter1) &&
- DAC960_ReportErrorStatus(Controller, ErrorStatus,
- Parameter0, Parameter1))
- goto Failure;
- udelay(10);
- }
- if (!DAC960_EnableMemoryMailboxInterface(Controller))
- {
- DAC960_Error("Unable to Enable Memory Mailbox Interface "
- "for Controller at\n", Controller);
- goto Failure;
- }
- DAC960_V4_EnableInterrupts(BaseAddress);
- break;
- case DAC960_V3_Controller:
- request_region(Controller->IO_Address, 0x80,
- Controller->FullModelName);
- DAC960_V3_DisableInterrupts(BaseAddress);
- DAC960_V3_AcknowledgeStatus(BaseAddress);
- udelay(1000);
- while (DAC960_V3_InitializationInProgressP(BaseAddress))
- {
- if (DAC960_V3_ReadErrorStatus(BaseAddress, &ErrorStatus,
- &Parameter0, &Parameter1) &&
- DAC960_ReportErrorStatus(Controller, ErrorStatus,
- Parameter0, Parameter1))
- goto Failure;
- udelay(10);
- }
- DAC960_V3_EnableInterrupts(BaseAddress);
- break;
- }
- /*
- Acquire shared access to the IRQ Channel.
- */
- if (IRQ_Channel == 0)
- {
- DAC960_Error("IRQ Channel %d illegal for Controller at\n",
- Controller, IRQ_Channel);
- goto Failure;
- }
- strcpy(Controller->FullModelName, "DAC960");
- if (request_irq(IRQ_Channel, DAC960_InterruptHandler,
- SA_SHIRQ, Controller->FullModelName, Controller) < 0)
- {
- DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
- Controller, IRQ_Channel);
- goto Failure;
- }
- Controller->IRQ_Channel = IRQ_Channel;
- DAC960_ActiveControllerCount++;
- for (CommandIdentifier = 0;
- CommandIdentifier < DAC960_MaxChannels;
- CommandIdentifier++)
- {
- Controller->Commands[CommandIdentifier].Controller = Controller;
- Controller->Commands[CommandIdentifier].Next =
- Controller->FreeCommands;
- Controller->FreeCommands = &Controller->Commands[CommandIdentifier];
- }
- continue;
- Failure:
- if (IO_Address == 0)
- DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
- "PCI Address 0x%X\n", Controller,
- Bus, Device, Function, PCI_Address);
- else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
- "0x%X PCI Address 0x%X\n", Controller,
- Bus, Device, Function, IO_Address, PCI_Address);
- if (Controller == NULL) break;
- if (Controller->MemoryMappedAddress != NULL)
- iounmap(Controller->MemoryMappedAddress);
- DAC960_Controllers[Controller->ControllerNumber] = NULL;
- if (Controller->IRQ_Channel > 0)
- free_irq(IRQ_Channel, Controller);
- Ignore:
- kfree(Controller);
- }
+ return (CommandStatus == DAC960_V2_NormalCompletion);
}
/*
- DAC960_ReadControllerConfiguration reads the Configuration Information
- from Controller and initializes the Controller structure.
+ DAC960_V1_ReadControllerConfiguration reads the Configuration Information
+ from DAC960 V1 Firmware Controllers and initializes the Controller structure.
*/
-static boolean DAC960_ReadControllerConfiguration(DAC960_Controller_T
- *Controller)
+static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
+ *Controller)
{
- DAC960_Enquiry2_T Enquiry2;
- DAC960_Config2_T Config2;
+ DAC960_V1_Enquiry2_T Enquiry2;
+ DAC960_V1_Config2_T Config2;
int LogicalDriveNumber, Channel, TargetID;
- if (!DAC960_ExecuteType3(Controller, DAC960_Enquiry,
- &Controller->Enquiry[0]))
+ if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry,
+ &Controller->V1.Enquiry))
return DAC960_Failure(Controller, "ENQUIRY");
- if (!DAC960_ExecuteType3(Controller, DAC960_Enquiry2, &Enquiry2))
+ if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, &Enquiry2))
return DAC960_Failure(Controller, "ENQUIRY2");
- if (!DAC960_ExecuteType3(Controller, DAC960_ReadConfig2, &Config2))
+ if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, &Config2))
return DAC960_Failure(Controller, "READ CONFIG2");
- if (!DAC960_ExecuteType3(Controller, DAC960_GetLogicalDriveInformation,
- &Controller->LogicalDriveInformation[0]))
+ if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_GetLogicalDriveInformation,
+ &Controller->V1.LogicalDriveInformation))
return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION");
for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++)
- for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
- if (!DAC960_ExecuteType3D(Controller, DAC960_GetDeviceState,
- Channel, TargetID,
- &Controller->DeviceState[0][Channel][TargetID]))
+ for (TargetID = 0; TargetID < Enquiry2.MaxTargets; TargetID++)
+ if (!DAC960_V1_ExecuteType3D(Controller, DAC960_V1_GetDeviceState,
+ Channel, TargetID,
+ &Controller->V1.DeviceState
+ [Channel][TargetID]))
return DAC960_Failure(Controller, "GET DEVICE STATE");
/*
Initialize the Controller Model Name and Full Model Name fields.
*/
switch (Enquiry2.HardwareID.SubModel)
{
- case DAC960_P_PD_PU:
- if (Enquiry2.SCSICapability.BusSpeed == DAC960_Ultra)
+ case DAC960_V1_P_PD_PU:
+ if (Enquiry2.SCSICapability.BusSpeed == DAC960_V1_Ultra)
strcpy(Controller->ModelName, "DAC960PU");
else strcpy(Controller->ModelName, "DAC960PD");
break;
- case DAC960_PL:
+ case DAC960_V1_PL:
strcpy(Controller->ModelName, "DAC960PL");
break;
- case DAC960_PG:
+ case DAC960_V1_PG:
strcpy(Controller->ModelName, "DAC960PG");
break;
- case DAC960_PJ:
+ case DAC960_V1_PJ:
strcpy(Controller->ModelName, "DAC960PJ");
break;
- case DAC960_PR:
+ case DAC960_V1_PR:
strcpy(Controller->ModelName, "DAC960PR");
break;
- case DAC960_PT:
+ case DAC960_V1_PT:
strcpy(Controller->ModelName, "DAC960PT");
break;
- case DAC960_PTL0:
+ case DAC960_V1_PTL0:
strcpy(Controller->ModelName, "DAC960PTL0");
break;
- case DAC960_PRL:
+ case DAC960_V1_PRL:
strcpy(Controller->ModelName, "DAC960PRL");
break;
- case DAC960_PTL1:
+ case DAC960_V1_PTL1:
strcpy(Controller->ModelName, "DAC960PTL1");
break;
- case DAC1164_P:
+ case DAC960_V1_1164P:
strcpy(Controller->ModelName, "DAC1164P");
break;
default:
@@ -813,61 +1075,197 @@ static boolean DAC960_ReadControllerConfiguration(DAC960_Controller_T
return false;
}
/*
- Initialize the Controller Channels, Memory Size, and SAF-TE Enclosure
- Management Enabled fields.
+ Initialize the Controller Channels, Targets, Memory Size, and SAF-TE
+ Enclosure Management Enabled fields.
*/
Controller->Channels = Enquiry2.ActualChannels;
+ Controller->Targets = Enquiry2.MaxTargets;
Controller->MemorySize = Enquiry2.MemorySize >> 20;
- Controller->SAFTE_EnclosureManagementEnabled =
- Enquiry2.FaultManagementType == DAC960_SAFTE;
+ Controller->V1.SAFTE_EnclosureManagementEnabled =
+ (Enquiry2.FaultManagementType == DAC960_V1_SAFTE);
/*
Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
- Count, Maximum Blocks per Command, and Maximum Scatter/Gather Segments.
- The Driver Queue Depth must be at most one less than the Controller Queue
- Depth to allow for an automatic drive rebuild operation.
+ Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
+ Driver Scatter/Gather Limit. The Driver Queue Depth must be at most one
+ less than the Controller Queue Depth to allow for an automatic drive
+ rebuild operation.
*/
- Controller->ControllerQueueDepth = Controller->Enquiry[0].MaxCommands;
+ Controller->ControllerQueueDepth = Controller->V1.Enquiry.MaxCommands;
Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
- Controller->LogicalDriveCount = Controller->Enquiry[0].NumberOfLogicalDrives;
+ if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
+ Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
+ Controller->LogicalDriveCount =
+ Controller->V1.Enquiry.NumberOfLogicalDrives;
Controller->MaxBlocksPerCommand = Enquiry2.MaxBlocksPerCommand;
- Controller->MaxScatterGatherSegments = Enquiry2.MaxScatterGatherEntries;
+ Controller->ControllerScatterGatherLimit = Enquiry2.MaxScatterGatherEntries;
+ Controller->DriverScatterGatherLimit =
+ Controller->ControllerScatterGatherLimit;
+ if (Controller->DriverScatterGatherLimit > DAC960_V1_ScatterGatherLimit)
+ Controller->DriverScatterGatherLimit = DAC960_V1_ScatterGatherLimit;
/*
Initialize the Stripe Size, Segment Size, and Geometry Translation.
*/
- Controller->StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
- >> (10 - DAC960_BlockSizeBits);
- Controller->SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
- >> (10 - DAC960_BlockSizeBits);
+ Controller->V1.StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
+ >> (10 - DAC960_BlockSizeBits);
+ Controller->V1.SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
+ >> (10 - DAC960_BlockSizeBits);
switch (Config2.DriveGeometry)
{
- case DAC960_Geometry_128_32:
- Controller->GeometryTranslationHeads = 128;
- Controller->GeometryTranslationSectors = 32;
+ case DAC960_V1_Geometry_128_32:
+ Controller->V1.GeometryTranslationHeads = 128;
+ Controller->V1.GeometryTranslationSectors = 32;
break;
- case DAC960_Geometry_255_63:
- Controller->GeometryTranslationHeads = 255;
- Controller->GeometryTranslationSectors = 63;
+ case DAC960_V1_Geometry_255_63:
+ Controller->V1.GeometryTranslationHeads = 255;
+ Controller->V1.GeometryTranslationSectors = 63;
break;
default:
return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
}
/*
- Initialize the Logical Drive Initial State.
+ Initialize the Logical Drive Initially Accessible flag.
*/
for (LogicalDriveNumber = 0;
LogicalDriveNumber < Controller->LogicalDriveCount;
LogicalDriveNumber++)
- Controller->LogicalDriveInitialState[LogicalDriveNumber] =
- Controller->LogicalDriveInformation[0]
- [LogicalDriveNumber].LogicalDriveState;
- Controller->LastRebuildStatus = DAC960_NoRebuildOrCheckInProgress;
+ if (Controller->V1.LogicalDriveInformation
+ [LogicalDriveNumber].LogicalDriveState !=
+ DAC960_V1_LogicalDrive_Offline)
+ Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
+ Controller->V1.LastRebuildStatus = DAC960_V1_NoRebuildOrCheckInProgress;
return true;
}
/*
- DAC960_ReportControllerConfiguration reports the Configuration Information of
- Controller.
+ DAC960_V2_ReadControllerConfiguration reads the Configuration Information
+ from DAC960 V2 Firmware Controllers and initializes the Controller structure.
+*/
+
+static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
+ *Controller)
+{
+ DAC960_V2_ControllerInfo_T *ControllerInfo =
+ &Controller->V2.ControllerInformation;
+ unsigned short LogicalDeviceNumber = 0;
+ int ModelNameLength;
+ if (!DAC960_V2_ControllerInfo(Controller, DAC960_V2_GetControllerInfo,
+ ControllerInfo,
+ sizeof(DAC960_V2_ControllerInfo_T)))
+ return DAC960_Failure(Controller, "GET CONTROLLER INFO");
+ if (!DAC960_V2_GeneralInfo(Controller, DAC960_V2_GetHealthStatus,
+ Controller->V2.HealthStatusBuffer,
+ sizeof(DAC960_V2_HealthStatusBuffer_T)))
+ return DAC960_Failure(Controller, "GET HEALTH STATUS");
+ /*
+ Initialize the Controller Model Name and Full Model Name fields.
+ */
+ ModelNameLength = sizeof(ControllerInfo->ControllerName);
+ if (ModelNameLength > sizeof(Controller->ModelName)-1)
+ ModelNameLength = sizeof(Controller->ModelName)-1;
+ memcpy(Controller->ModelName, ControllerInfo->ControllerName,
+ ModelNameLength);
+ ModelNameLength--;
+ while (Controller->ModelName[ModelNameLength] == ' ' ||
+ Controller->ModelName[ModelNameLength] == '\0')
+ ModelNameLength--;
+ Controller->ModelName[++ModelNameLength] = '\0';
+ strcpy(Controller->FullModelName, "Mylex ");
+ strcat(Controller->FullModelName, Controller->ModelName);
+ /*
+ Initialize the Controller Firmware Version field.
+ */
+ sprintf(Controller->FirmwareVersion, "%d.%02d-%02d",
+ ControllerInfo->FirmwareMajorVersion,
+ ControllerInfo->FirmwareMinorVersion,
+ ControllerInfo->FirmwareTurnNumber);
+ if (ControllerInfo->FirmwareMajorVersion == 6 &&
+ ControllerInfo->FirmwareMinorVersion == 0 &&
+ ControllerInfo->FirmwareTurnNumber < 1)
+ {
+ DAC960_Info("FIRMWARE VERSION %s DOES NOT PROVIDE THE CONTROLLER\n",
+ Controller, Controller->FirmwareVersion);
+ DAC960_Info("STATUS MONITORING FUNCTIONALITY NEEDED BY THIS DRIVER.\n",
+ Controller);
+ DAC960_Info("PLEASE UPGRADE TO VERSION 6.00-01 OR ABOVE.\n",
+ Controller);
+ }
+ /*
+ Initialize the Controller Channels, Targets, and Memory Size.
+ */
+ Controller->Channels = ControllerInfo->NumberOfPhysicalChannelsPresent;
+ Controller->Targets =
+ ControllerInfo->MaximumTargetsPerChannel
+ [ControllerInfo->NumberOfPhysicalChannelsPresent-1];
+ Controller->MemorySize = ControllerInfo->MemorySizeMB;
+ /*
+ Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
+ Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
+ Driver Scatter/Gather Limit. The Driver Queue Depth must be at most one
+ less than the Controller Queue Depth to allow for an automatic drive
+ rebuild operation.
+ */
+ Controller->ControllerQueueDepth = ControllerInfo->MaximumParallelCommands;
+ Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
+ if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
+ Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
+ Controller->LogicalDriveCount = ControllerInfo->LogicalDevicesPresent;
+ Controller->MaxBlocksPerCommand =
+ ControllerInfo->MaximumDataTransferSizeInBlocks;
+ Controller->ControllerScatterGatherLimit =
+ ControllerInfo->MaximumScatterGatherEntries;
+ Controller->DriverScatterGatherLimit =
+ Controller->ControllerScatterGatherLimit;
+ if (Controller->DriverScatterGatherLimit > DAC960_V2_ScatterGatherLimit)
+ Controller->DriverScatterGatherLimit = DAC960_V2_ScatterGatherLimit;
+ /*
+ Initialize the Logical Device Information.
+ */
+ while (true)
+ {
+ DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
+ &Controller->V2.NewLogicalDeviceInformation;
+ DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo;
+ DAC960_V2_PhysicalDevice_T PhysicalDevice;
+ if (!DAC960_V2_LogicalDeviceInfo(Controller,
+ DAC960_V2_GetLogicalDeviceInfoValid,
+ LogicalDeviceNumber,
+ NewLogicalDeviceInfo,
+ sizeof(DAC960_V2_LogicalDeviceInfo_T)))
+ break;
+ LogicalDeviceNumber = NewLogicalDeviceInfo->LogicalDeviceNumber;
+ if (LogicalDeviceNumber > DAC960_MaxLogicalDrives)
+ panic("DAC960: Logical Drive Number %d not supported\n",
+ LogicalDeviceNumber);
+ if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize)
+ panic("DAC960: Logical Drive Block Size %d not supported\n",
+ NewLogicalDeviceInfo->DeviceBlockSizeInBytes);
+ PhysicalDevice.Controller = 0;
+ PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
+ PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
+ PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
+ Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
+ PhysicalDevice;
+ if (NewLogicalDeviceInfo->LogicalDeviceState !=
+ DAC960_V2_LogicalDevice_Offline)
+ Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true;
+ LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
+ kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
+ if (LogicalDeviceInfo == NULL)
+ return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION");
+ Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
+ LogicalDeviceInfo;
+ memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
+ sizeof(DAC960_V2_LogicalDeviceInfo_T));
+ LogicalDeviceNumber++;
+ }
+ return true;
+}
+
+
+/*
+ DAC960_ReportControllerConfiguration reports the Configuration Information
+ for Controller.
*/
static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
@@ -893,54 +1291,60 @@ static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
Controller, Controller->ControllerQueueDepth,
Controller->MaxBlocksPerCommand);
DAC960_Info(" Driver Queue Depth: %d, "
- "Maximum Scatter/Gather Segments: %d\n",
+ "Scatter/Gather Limit: %d of %d Segments\n",
Controller, Controller->DriverQueueDepth,
- Controller->MaxScatterGatherSegments);
- DAC960_Info(" Stripe Size: %dKB, Segment Size: %dKB, "
- "BIOS Geometry: %d/%d\n", Controller,
- Controller->StripeSize,
- Controller->SegmentSize,
- Controller->GeometryTranslationHeads,
- Controller->GeometryTranslationSectors);
- if (Controller->SAFTE_EnclosureManagementEnabled)
- DAC960_Info(" SAF-TE Enclosure Management Enabled\n", Controller);
+ Controller->DriverScatterGatherLimit,
+ Controller->ControllerScatterGatherLimit);
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ {
+ DAC960_Info(" Stripe Size: %dKB, Segment Size: %dKB, "
+ "BIOS Geometry: %d/%d\n", Controller,
+ Controller->V1.StripeSize,
+ Controller->V1.SegmentSize,
+ Controller->V1.GeometryTranslationHeads,
+ Controller->V1.GeometryTranslationSectors);
+ if (Controller->V1.SAFTE_EnclosureManagementEnabled)
+ DAC960_Info(" SAF-TE Enclosure Management Enabled\n", Controller);
+ }
return true;
}
/*
- DAC960_ReadDeviceConfiguration reads the Device Configuration Information by
- requesting the SCSI Inquiry and SCSI Inquiry Unit Serial Number information
- for each device connected to Controller.
+ DAC960_V1_ReadDeviceConfiguration reads the Device Configuration Information
+ for DAC960 V1 Firmware Controllers by requesting the SCSI Inquiry and SCSI
+ Inquiry Unit Serial Number information for each device connected to
+ Controller.
*/
-static boolean DAC960_ReadDeviceConfiguration(DAC960_Controller_T *Controller)
+static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
+ *Controller)
{
- DAC960_DCDB_T DCDBs[DAC960_MaxChannels], *DCDB;
- Semaphore_T Semaphores[DAC960_MaxChannels], *Semaphore;
+ DAC960_V1_DCDB_T DCDBs[DAC960_V1_MaxChannels], *DCDB;
+ Semaphore_T Semaphores[DAC960_V1_MaxChannels], *Semaphore;
unsigned long ProcessorFlags;
int Channel, TargetID;
- for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
+ for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
{
for (Channel = 0; Channel < Controller->Channels; Channel++)
{
- DAC960_Command_T *Command = &Controller->Commands[Channel];
+ DAC960_Command_T *Command = Controller->Commands[Channel];
DAC960_SCSI_Inquiry_T *InquiryStandardData =
- &Controller->InquiryStandardData[Channel][TargetID];
+ &Controller->V1.InquiryStandardData[Channel][TargetID];
InquiryStandardData->PeripheralDeviceType = 0x1F;
Semaphore = &Semaphores[Channel];
init_MUTEX_LOCKED(Semaphore);
DCDB = &DCDBs[Channel];
- DAC960_ClearCommand(Command);
+ DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
Command->Semaphore = Semaphore;
- Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
- Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
+ Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
+ Command->V1.CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
DCDB->Channel = Channel;
DCDB->TargetID = TargetID;
- DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
+ DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
DCDB->EarlyStatus = false;
- DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
+ DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
DCDB->NoAutomaticRequestSense = false;
DCDB->DisconnectPermitted = true;
DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
@@ -960,13 +1364,14 @@ static boolean DAC960_ReadDeviceConfiguration(DAC960_Controller_T *Controller)
}
for (Channel = 0; Channel < Controller->Channels; Channel++)
{
- DAC960_Command_T *Command = &Controller->Commands[Channel];
+ DAC960_Command_T *Command = Controller->Commands[Channel];
DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
- &Controller->InquiryUnitSerialNumber[Channel][TargetID];
+ &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
Semaphore = &Semaphores[Channel];
down(Semaphore);
- if (Command->CommandStatus != DAC960_NormalCompletion) continue;
+ if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion)
+ continue;
Command->Semaphore = Semaphore;
DCDB = &DCDBs[Channel];
DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
@@ -984,107 +1389,215 @@ static boolean DAC960_ReadDeviceConfiguration(DAC960_Controller_T *Controller)
down(Semaphore);
}
}
- return true;
+ return true;
+}
+
+
+/*
+ DAC960_V2_ReadDeviceConfiguration reads the Device Configuration Information
+ for DAC960 V2 Firmware Controllers by requesting the Physical Device
+ Information and SCSI Inquiry Unit Serial Number information for each
+ device connected to Controller.
+*/
+
+static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
+ *Controller)
+{
+ unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0;
+ unsigned short PhysicalDeviceIndex = 0;
+ while (true)
+ {
+ DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
+ &Controller->V2.NewPhysicalDeviceInformation;
+ DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo;
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
+ DAC960_Command_T *Command;
+ DAC960_V2_CommandMailbox_T *CommandMailbox;
+ if (!DAC960_V2_PhysicalDeviceInfo(Controller,
+ DAC960_V2_GetPhysicalDeviceInfoValid,
+ Channel,
+ TargetID,
+ LogicalUnit,
+ NewPhysicalDeviceInfo,
+ sizeof(DAC960_V2_PhysicalDeviceInfo_T)))
+ break;
+ Channel = NewPhysicalDeviceInfo->Channel;
+ TargetID = NewPhysicalDeviceInfo->TargetID;
+ LogicalUnit = NewPhysicalDeviceInfo->LogicalUnit;
+ PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
+ kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
+ if (PhysicalDeviceInfo == NULL)
+ return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION");
+ Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] =
+ PhysicalDeviceInfo;
+ memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
+ sizeof(DAC960_V2_PhysicalDeviceInfo_T));
+ InquiryUnitSerialNumber = (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
+ kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
+ if (InquiryUnitSerialNumber == NULL)
+ return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION");
+ Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex] =
+ InquiryUnitSerialNumber;
+ memset(InquiryUnitSerialNumber, 0,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+ InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+ Command = DAC960_AllocateCommand(Controller);
+ CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_ImmediateCommand;
+ CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10_Passthru;
+ CommandMailbox->SCSI_10.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->SCSI_10.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->SCSI_10.DataTransferSize =
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+ CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit = LogicalUnit;
+ CommandMailbox->SCSI_10.PhysicalDevice.TargetID = TargetID;
+ CommandMailbox->SCSI_10.PhysicalDevice.Channel = Channel;
+ CommandMailbox->SCSI_10.CDBLength = 6;
+ CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
+ CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
+ CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
+ CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
+ CommandMailbox->SCSI_10.SCSI_CDB[4] =
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+ CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(InquiryUnitSerialNumber);
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->SCSI_10.DataTransferSize;
+ DAC960_ExecuteCommand(Command);
+ DAC960_DeallocateCommand(Command);
+ PhysicalDeviceIndex++;
+ LogicalUnit++;
+ }
+ return true;
+}
+
+
+/*
+ DAC960_SanitizeInquiryData sanitizes the Vendor, Model, Revision, and
+ Product Serial Number fields of the Inquiry Standard Data and Inquiry
+ Unit Serial Number structures.
+*/
+
+static void DAC960_SanitizeInquiryData(DAC960_SCSI_Inquiry_T
+ *InquiryStandardData,
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T
+ *InquiryUnitSerialNumber,
+ unsigned char *Vendor,
+ unsigned char *Model,
+ unsigned char *Revision,
+ unsigned char *SerialNumber)
+{
+ int SerialNumberLength, i;
+ if (InquiryStandardData->PeripheralDeviceType == 0x1F) return;
+ for (i = 0; i < sizeof(InquiryStandardData->VendorIdentification); i++)
+ {
+ unsigned char VendorCharacter =
+ InquiryStandardData->VendorIdentification[i];
+ Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~'
+ ? VendorCharacter : ' ');
+ }
+ Vendor[sizeof(InquiryStandardData->VendorIdentification)] = '\0';
+ for (i = 0; i < sizeof(InquiryStandardData->ProductIdentification); i++)
+ {
+ unsigned char ModelCharacter =
+ InquiryStandardData->ProductIdentification[i];
+ Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
+ ? ModelCharacter : ' ');
+ }
+ Model[sizeof(InquiryStandardData->ProductIdentification)] = '\0';
+ for (i = 0; i < sizeof(InquiryStandardData->ProductRevisionLevel); i++)
+ {
+ unsigned char RevisionCharacter =
+ InquiryStandardData->ProductRevisionLevel[i];
+ Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
+ ? RevisionCharacter : ' ');
+ }
+ Revision[sizeof(InquiryStandardData->ProductRevisionLevel)] = '\0';
+ if (InquiryUnitSerialNumber->PeripheralDeviceType == 0x1F) return;
+ SerialNumberLength = InquiryUnitSerialNumber->PageLength;
+ if (SerialNumberLength >
+ sizeof(InquiryUnitSerialNumber->ProductSerialNumber))
+ SerialNumberLength = sizeof(InquiryUnitSerialNumber->ProductSerialNumber);
+ for (i = 0; i < SerialNumberLength; i++)
+ {
+ unsigned char SerialNumberCharacter =
+ InquiryUnitSerialNumber->ProductSerialNumber[i];
+ SerialNumber[i] =
+ (SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~'
+ ? SerialNumberCharacter : ' ');
+ }
+ SerialNumber[SerialNumberLength] = '\0';
}
/*
- DAC960_ReportDeviceConfiguration reports the Device Configuration Information
- of Controller.
+ DAC960_V1_ReportDeviceConfiguration reports the Device Configuration
+ Information for DAC960 V1 Firmware Controllers.
*/
-static boolean DAC960_ReportDeviceConfiguration(DAC960_Controller_T *Controller)
+static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
+ *Controller)
{
int LogicalDriveNumber, Channel, TargetID;
DAC960_Info(" Physical Devices:\n", Controller);
for (Channel = 0; Channel < Controller->Channels; Channel++)
- for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
+ for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
{
DAC960_SCSI_Inquiry_T *InquiryStandardData =
- &Controller->InquiryStandardData[Channel][TargetID];
+ &Controller->V1.InquiryStandardData[Channel][TargetID];
DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
- &Controller->InquiryUnitSerialNumber[Channel][TargetID];
- DAC960_DeviceState_T *DeviceState =
- &Controller->DeviceState[Controller->DeviceStateIndex]
- [Channel][TargetID];
- DAC960_ErrorTable_T *ErrorTable =
- &Controller->ErrorTable[Controller->ErrorTableIndex];
- DAC960_ErrorTableEntry_T *ErrorEntry =
- &ErrorTable->ErrorTableEntries[Channel][TargetID];
+ &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
+ DAC960_V1_DeviceState_T *DeviceState =
+ &Controller->V1.DeviceState[Channel][TargetID];
+ DAC960_V1_ErrorTableEntry_T *ErrorEntry =
+ &Controller->V1.ErrorTable.ErrorTableEntries[Channel][TargetID];
char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
char SerialNumber[1+sizeof(InquiryUnitSerialNumber
->ProductSerialNumber)];
- int i;
if (InquiryStandardData->PeripheralDeviceType == 0x1F) continue;
- for (i = 0; i < sizeof(Vendor)-1; i++)
- {
- unsigned char VendorCharacter =
- InquiryStandardData->VendorIdentification[i];
- Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~'
- ? VendorCharacter : ' ');
- }
- Vendor[sizeof(Vendor)-1] = '\0';
- for (i = 0; i < sizeof(Model)-1; i++)
- {
- unsigned char ModelCharacter =
- InquiryStandardData->ProductIdentification[i];
- Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
- ? ModelCharacter : ' ');
- }
- Model[sizeof(Model)-1] = '\0';
- for (i = 0; i < sizeof(Revision)-1; i++)
- {
- unsigned char RevisionCharacter =
- InquiryStandardData->ProductRevisionLevel[i];
- Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
- ? RevisionCharacter : ' ');
- }
- Revision[sizeof(Revision)-1] = '\0';
+ DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
+ Vendor, Model, Revision, SerialNumber);
DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %s\n",
Controller, Channel, TargetID, (TargetID < 10 ? " " : ""),
Vendor, Model, Revision);
if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
+ DAC960_Info(" Serial Number: %s\n", Controller, SerialNumber);
+ if (DeviceState->Present &&
+ DeviceState->DeviceType == DAC960_V1_DiskType)
{
- int SerialNumberLength = InquiryUnitSerialNumber->PageLength;
- if (SerialNumberLength >
- sizeof(InquiryUnitSerialNumber->ProductSerialNumber))
- SerialNumberLength =
- sizeof(InquiryUnitSerialNumber->ProductSerialNumber);
- for (i = 0; i < SerialNumberLength; i++)
- {
- unsigned char SerialNumberCharacter =
- InquiryUnitSerialNumber->ProductSerialNumber[i];
- SerialNumber[i] =
- (SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~'
- ? SerialNumberCharacter : ' ');
- }
- SerialNumber[SerialNumberLength] = '\0';
- DAC960_Info(" Serial Number: %s\n",
- Controller, SerialNumber);
- }
- if (DeviceState->Present && DeviceState->DeviceType == DAC960_DiskType)
- {
- if (Controller->DeviceResetCount[Channel][TargetID] > 0)
+ if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0)
DAC960_Info(" Disk Status: %s, %d blocks, %d resets\n",
Controller,
- (DeviceState->DeviceState == DAC960_Device_Dead
+ (DeviceState->DeviceState == DAC960_V1_Device_Dead
? "Dead"
- : DeviceState->DeviceState == DAC960_Device_WriteOnly
- ? "Write-Only"
- : DeviceState->DeviceState == DAC960_Device_Online
- ? "Online" : "Standby"),
+ : DeviceState->DeviceState
+ == DAC960_V1_Device_WriteOnly
+ ? "Write-Only"
+ : DeviceState->DeviceState
+ == DAC960_V1_Device_Online
+ ? "Online" : "Standby"),
DeviceState->DiskSize,
- Controller->DeviceResetCount[Channel][TargetID]);
+ Controller->V1.DeviceResetCount[Channel][TargetID]);
else
DAC960_Info(" Disk Status: %s, %d blocks\n", Controller,
- (DeviceState->DeviceState == DAC960_Device_Dead
+ (DeviceState->DeviceState == DAC960_V1_Device_Dead
? "Dead"
- : DeviceState->DeviceState == DAC960_Device_WriteOnly
- ? "Write-Only"
- : DeviceState->DeviceState == DAC960_Device_Online
- ? "Online" : "Standby"),
+ : DeviceState->DeviceState
+ == DAC960_V1_Device_WriteOnly
+ ? "Write-Only"
+ : DeviceState->DeviceState
+ == DAC960_V1_Device_Online
+ ? "Online" : "Standby"),
DeviceState->DiskSize);
}
if (ErrorEntry->ParityErrorCount > 0 ||
@@ -1103,17 +1616,16 @@ static boolean DAC960_ReportDeviceConfiguration(DAC960_Controller_T *Controller)
LogicalDriveNumber < Controller->LogicalDriveCount;
LogicalDriveNumber++)
{
- DAC960_LogicalDriveInformation_T *LogicalDriveInformation =
- &Controller->LogicalDriveInformation
- [Controller->LogicalDriveInformationIndex][LogicalDriveNumber];
+ DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation =
+ &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %d blocks, %s\n",
Controller, Controller->ControllerNumber, LogicalDriveNumber,
LogicalDriveInformation->RAIDLevel,
- (LogicalDriveInformation->LogicalDriveState ==
- DAC960_LogicalDrive_Online
+ (LogicalDriveInformation->LogicalDriveState
+ == DAC960_V1_LogicalDrive_Online
? "Online"
- : LogicalDriveInformation->LogicalDriveState ==
- DAC960_LogicalDrive_Critical
+ : LogicalDriveInformation->LogicalDriveState
+ == DAC960_V1_LogicalDrive_Critical
? "Critical" : "Offline"),
LogicalDriveInformation->LogicalDriveSize,
(LogicalDriveInformation->WriteBack
@@ -1123,69 +1635,256 @@ static boolean DAC960_ReportDeviceConfiguration(DAC960_Controller_T *Controller)
}
-static inline int DAC_new_segment(request_queue_t *q, struct request *req,
- int __max_segments)
-{
- int max_segments;
- DAC960_Controller_T * Controller = q->queuedata;
-
- max_segments = Controller->MaxSegmentsPerRequest[MINOR(req->rq_dev)];
- if (__max_segments < max_segments)
- max_segments = __max_segments;
+/*
+ DAC960_V2_ReportDeviceConfiguration reports the Device Configuration
+ Information for DAC960 V2 Firmware Controllers.
+*/
- if (req->nr_segments < max_segments) {
- req->nr_segments++;
- q->elevator.nr_segments++;
- return 1;
+static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
+ *Controller)
+{
+ int PhysicalDeviceIndex, LogicalDriveNumber;
+ DAC960_Info(" Physical Devices:\n", Controller);
+ for (PhysicalDeviceIndex = 0;
+ PhysicalDeviceIndex < DAC960_V2_MaxPhysicalDevices;
+ PhysicalDeviceIndex++)
+ {
+ DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
+ Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
+ DAC960_SCSI_Inquiry_T *InquiryStandardData =
+ (DAC960_SCSI_Inquiry_T *) &PhysicalDeviceInfo->SCSI_InquiryData;
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
+ Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
+ char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
+ char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
+ char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
+ char SerialNumber[1+sizeof(InquiryUnitSerialNumber->ProductSerialNumber)];
+ if (PhysicalDeviceInfo == NULL) break;
+ DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
+ Vendor, Model, Revision, SerialNumber);
+ DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %s\n",
+ Controller,
+ PhysicalDeviceInfo->Channel,
+ PhysicalDeviceInfo->TargetID,
+ (PhysicalDeviceInfo->TargetID < 10 ? " " : ""),
+ Vendor, Model, Revision);
+ if (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers == 0)
+ DAC960_Info(" %sAsynchronous\n", Controller,
+ (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
+ ? "Wide " :""));
+ else
+ DAC960_Info(" %sSynchronous at %d MB/sec\n", Controller,
+ (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
+ ? "Wide " :""),
+ (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers
+ * (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
+ ? 2 : 1)));
+ if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
+ DAC960_Info(" Serial Number: %s\n", Controller, SerialNumber);
+ if (PhysicalDeviceInfo->PhysicalDeviceState ==
+ DAC960_V2_Device_Unconfigured)
+ continue;
+ DAC960_Info(" Disk Status: %s, %d blocks\n", Controller,
+ (PhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Online
+ ? "Online"
+ : PhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_WriteOnly
+ ? "Write-Only"
+ : PhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Dead
+ ? "Dead" : "Standby"),
+ PhysicalDeviceInfo
+ ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+ if (PhysicalDeviceInfo->ParityErrors == 0 &&
+ PhysicalDeviceInfo->SoftErrors == 0 &&
+ PhysicalDeviceInfo->HardErrors == 0 &&
+ PhysicalDeviceInfo->MiscellaneousErrors == 0 &&
+ PhysicalDeviceInfo->CommandTimeouts == 0 &&
+ PhysicalDeviceInfo->Retries == 0 &&
+ PhysicalDeviceInfo->Aborts == 0 &&
+ PhysicalDeviceInfo->PredictedFailuresDetected == 0)
+ continue;
+ DAC960_Info(" Errors - Parity: %d, Soft: %d, "
+ "Hard: %d, Misc: %d\n", Controller,
+ PhysicalDeviceInfo->ParityErrors,
+ PhysicalDeviceInfo->SoftErrors,
+ PhysicalDeviceInfo->HardErrors,
+ PhysicalDeviceInfo->MiscellaneousErrors);
+ DAC960_Info(" Timeouts: %d, Retries: %d, "
+ "Aborts: %d, Predicted: %d\n", Controller,
+ PhysicalDeviceInfo->CommandTimeouts,
+ PhysicalDeviceInfo->Retries,
+ PhysicalDeviceInfo->Aborts,
+ PhysicalDeviceInfo->PredictedFailuresDetected);
+ }
+ DAC960_Info(" Logical Drives:\n", Controller);
+ for (LogicalDriveNumber = 0;
+ LogicalDriveNumber < DAC960_MaxLogicalDrives;
+ LogicalDriveNumber++)
+ {
+ DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+ Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+ unsigned char *ReadCacheStatus[] = { "Read Cache Disabled",
+ "Read Cache Enabled",
+ "Read Ahead Enabled",
+ "Intelligent Read Ahead Enabled",
+ "-", "-", "-", "-" };
+ unsigned char *WriteCacheStatus[] = { "Write Cache Disabled",
+ "Logical Device Read Only",
+ "Write Cache Enabled",
+ "Intelligent Write Cache Enabled",
+ "-", "-", "-", "-" };
+ unsigned char *GeometryTranslation;
+ if (LogicalDeviceInfo == NULL) continue;
+ switch(LogicalDeviceInfo->DriveGeometry)
+ {
+ case DAC960_V2_Geometry_128_32:
+ GeometryTranslation = "128/32";
+ break;
+ case DAC960_V2_Geometry_255_63:
+ GeometryTranslation = "255/63";
+ break;
+ default:
+ GeometryTranslation = "Invalid";
+ DAC960_Error("Illegal Logical Device Geometry %d\n",
+ Controller, LogicalDeviceInfo->DriveGeometry);
+ break;
}
- return 0;
-}
+ DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %d blocks\n",
+ Controller, Controller->ControllerNumber, LogicalDriveNumber,
+ LogicalDeviceInfo->RAIDLevel,
+ (LogicalDeviceInfo->LogicalDeviceState
+ == DAC960_V2_LogicalDevice_Online
+ ? "Online"
+ : LogicalDeviceInfo->LogicalDeviceState
+ == DAC960_V2_LogicalDevice_Critical
+ ? "Critical" : "Offline"),
+ LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+ DAC960_Info(" Logical Device %s, BIOS Geometry: %s\n",
+ Controller,
+ (LogicalDeviceInfo->LogicalDeviceControl
+ .LogicalDeviceInitialized
+ ? "Initialized" : "Uninitialized"),
+ GeometryTranslation);
+ if (LogicalDeviceInfo->StripeSize == 0)
+ {
+ if (LogicalDeviceInfo->CacheLineSize == 0)
+ DAC960_Info(" Stripe Size: N/A, "
+ "Segment Size: N/A\n", Controller);
+ else
+ DAC960_Info(" Stripe Size: N/A, "
+ "Segment Size: %dKB\n", Controller,
+ 1 << (LogicalDeviceInfo->CacheLineSize - 2));
+ }
+ else
+ {
+ if (LogicalDeviceInfo->CacheLineSize == 0)
+ DAC960_Info(" Stripe Size: %dKB, "
+ "Segment Size: N/A\n", Controller,
+ 1 << (LogicalDeviceInfo->StripeSize - 2));
+ else
+ DAC960_Info(" Stripe Size: %dKB, "
+ "Segment Size: %dKB\n", Controller,
+ 1 << (LogicalDeviceInfo->StripeSize - 2),
+ 1 << (LogicalDeviceInfo->CacheLineSize - 2));
+ }
+ DAC960_Info(" %s, %s\n", Controller,
+ ReadCacheStatus[
+ LogicalDeviceInfo->LogicalDeviceControl.ReadCache],
+ WriteCacheStatus[
+ LogicalDeviceInfo->LogicalDeviceControl.WriteCache]);
+ if (LogicalDeviceInfo->SoftErrors > 0 ||
+ LogicalDeviceInfo->CommandsFailed > 0 ||
+ LogicalDeviceInfo->DeferredWriteErrors)
+ DAC960_Info(" Errors - Soft: %d, Failed: %d, "
+ "Deferred Write: %d\n", Controller,
+ LogicalDeviceInfo->SoftErrors,
+ LogicalDeviceInfo->CommandsFailed,
+ LogicalDeviceInfo->DeferredWriteErrors);
-static int DAC_back_merge_fn(request_queue_t *q, struct request *req,
- struct buffer_head *bh, int __max_segments)
-{
- if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
- return 1;
- return DAC_new_segment(q, req, __max_segments);
+ }
+ return true;
}
-static int DAC_front_merge_fn(request_queue_t *q, struct request *req,
- struct buffer_head *bh, int __max_segments)
+
+/*
+ DAC960_BackMergeFunction is the Back Merge Function for the DAC960 driver.
+*/
+
+static int DAC960_BackMergeFunction(RequestQueue_T *RequestQueue,
+ IO_Request_T *Request,
+ BufferHeader_T *BufferHeader,
+ int MaxSegments)
{
- if (bh->b_data + bh->b_size == req->bh->b_data)
- return 1;
- return DAC_new_segment(q, req, __max_segments);
+ DAC960_Controller_T *Controller =
+ (DAC960_Controller_T *) RequestQueue->queuedata;
+ if (Request->bhtail->b_data + Request->bhtail->b_size == BufferHeader->b_data)
+ return true;
+ if (Request->nr_segments < MaxSegments &&
+ Request->nr_segments < Controller->DriverScatterGatherLimit)
+ {
+ Request->nr_segments++;
+ RequestQueue->elevator.nr_segments++;
+ return true;
+ }
+ return false;
}
-static int DAC_merge_requests_fn(request_queue_t *q,
- struct request *req,
- struct request *next,
- int __max_segments)
+
+/*
+ DAC960_FrontMergeFunction is the Front Merge Function for the DAC960 driver.
+*/
+
+static int DAC960_FrontMergeFunction(RequestQueue_T *RequestQueue,
+ IO_Request_T *Request,
+ BufferHeader_T *BufferHeader,
+ int MaxSegments)
{
- int max_segments;
- DAC960_Controller_T * Controller = q->queuedata;
- int total_segments = req->nr_segments + next->nr_segments;
- int same_segment;
+ DAC960_Controller_T *Controller =
+ (DAC960_Controller_T *) RequestQueue->queuedata;
+ if (BufferHeader->b_data + BufferHeader->b_size == Request->bh->b_data)
+ return true;
+ if (Request->nr_segments < MaxSegments &&
+ Request->nr_segments < Controller->DriverScatterGatherLimit)
+ {
+ Request->nr_segments++;
+ RequestQueue->elevator.nr_segments++;
+ return true;
+ }
+ return false;
+}
- max_segments = Controller->MaxSegmentsPerRequest[MINOR(req->rq_dev)];
- if (__max_segments < max_segments)
- max_segments = __max_segments;
- same_segment = 0;
- if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
- {
- total_segments--;
- same_segment = 1;
- }
-
- if (total_segments > max_segments)
- return 0;
+/*
+ DAC960_MergeRequestsFunction is the Merge Requests Function for the
+ DAC960 driver.
+*/
- q->elevator.nr_segments -= same_segment;
- req->nr_segments = total_segments;
- return 1;
+static int DAC960_MergeRequestsFunction(RequestQueue_T *RequestQueue,
+ IO_Request_T *Request,
+ IO_Request_T *NextRequest,
+ int MaxSegments)
+{
+ DAC960_Controller_T *Controller =
+ (DAC960_Controller_T *) RequestQueue->queuedata;
+ int TotalSegments = Request->nr_segments + NextRequest->nr_segments;
+ int SameSegment = 0;
+ if (Request->bhtail->b_data + Request->bhtail->b_size
+ == NextRequest->bh->b_data)
+ {
+ TotalSegments--;
+ SameSegment = 1;
+ }
+ if (TotalSegments > MaxSegments ||
+ TotalSegments > Controller->DriverScatterGatherLimit)
+ return false;
+ RequestQueue->elevator.nr_segments -= SameSegment;
+ Request->nr_segments = TotalSegments;
+ return true;
}
+
/*
DAC960_RegisterBlockDevice registers the Block Device structures
associated with Controller.
@@ -1193,47 +1892,40 @@ static int DAC_merge_requests_fn(request_queue_t *q,
static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
{
- request_queue_t * q;
-
- static void (*RequestFunctions[DAC960_MaxControllers])(request_queue_t *) =
- { DAC960_RequestFunction0, DAC960_RequestFunction1,
- DAC960_RequestFunction2, DAC960_RequestFunction3,
- DAC960_RequestFunction4, DAC960_RequestFunction5,
- DAC960_RequestFunction6, DAC960_RequestFunction7 };
int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
GenericDiskInfo_T *GenericDiskInfo;
+ RequestQueue_T *RequestQueue;
int MinorNumber;
/*
Register the Block Device Major Number for this DAC960 Controller.
*/
- if (devfs_register_blkdev(MajorNumber, "dac960", &DAC960_FileOperations) < 0)
+ if (devfs_register_blkdev(MajorNumber, "dac960",
+ &DAC960_BlockDeviceOperations) < 0)
{
DAC960_Error("UNABLE TO ACQUIRE MAJOR NUMBER %d - DETACHING\n",
Controller, MajorNumber);
return false;
}
/*
- Initialize the I/O Request Function.
+ Initialize the I/O Request Queue.
*/
- q = BLK_DEFAULT_QUEUE(MajorNumber);
- blk_init_queue(q, RequestFunctions[Controller->ControllerNumber]);
- blk_queue_headactive(q, 0);
- q->back_merge_fn = DAC_back_merge_fn;
- q->front_merge_fn = DAC_front_merge_fn;
- q->merge_requests_fn = DAC_merge_requests_fn;
- q->queuedata = (void *) Controller;
-
+ RequestQueue = BLK_DEFAULT_QUEUE(MajorNumber);
+ blk_init_queue(RequestQueue, DAC960_RequestFunction);
+ blk_queue_headactive(RequestQueue, 0);
+ RequestQueue->back_merge_fn = DAC960_BackMergeFunction;
+ RequestQueue->front_merge_fn = DAC960_FrontMergeFunction;
+ RequestQueue->merge_requests_fn = DAC960_MergeRequestsFunction;
+ RequestQueue->queuedata = Controller;
+ Controller->RequestQueue = RequestQueue;
/*
Initialize the Disk Partitions array, Partition Sizes array, Block Sizes
- array, Max Sectors per Request array, and Max Segments per Request array.
+ array, and Max Sectors per Request array.
*/
for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++)
{
Controller->BlockSizes[MinorNumber] = BLOCK_SIZE;
Controller->MaxSectorsPerRequest[MinorNumber] =
Controller->MaxBlocksPerCommand;
- Controller->MaxSegmentsPerRequest[MinorNumber] =
- Controller->MaxScatterGatherSegments;
}
Controller->GenericDiskInfo.part = Controller->DiskPartitions;
Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
@@ -1247,13 +1939,12 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
Complete initialization of the Generic Disk Information structure.
*/
Controller->GenericDiskInfo.major = MajorNumber;
- Controller->GenericDiskInfo.major_name = "dac960";
+ 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.real_devices = Controller;
Controller->GenericDiskInfo.next = NULL;
- Controller->GenericDiskInfo.fops = &DAC960_FileOperations;
+ Controller->GenericDiskInfo.fops = &DAC960_BlockDeviceOperations;
/*
Install the Generic Disk Information structure at the end of the list.
*/
@@ -1284,7 +1975,7 @@ static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller)
*/
devfs_unregister_blkdev(MajorNumber, "dac960");
/*
- Remove the I/O Request Function.
+ Remove the I/O Request Queue.
*/
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MajorNumber));
/*
@@ -1313,6 +2004,463 @@ static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller)
/*
+ DAC960_RegisterDisk registers the DAC960 Logical Disk Device for Logical
+ Drive Number if it exists.
+*/
+
+static void DAC960_RegisterDisk(DAC960_Controller_T *Controller,
+ int LogicalDriveNumber)
+{
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ {
+ if (LogicalDriveNumber > Controller->LogicalDriveCount - 1) return;
+ register_disk(&Controller->GenericDiskInfo,
+ DAC960_KernelDevice(Controller->ControllerNumber,
+ LogicalDriveNumber, 0),
+ DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
+ Controller->V1.LogicalDriveInformation
+ [LogicalDriveNumber].LogicalDriveSize);
+ }
+ else
+ {
+ DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+ Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+ if (LogicalDeviceInfo == NULL) return;
+ register_disk(&Controller->GenericDiskInfo,
+ DAC960_KernelDevice(Controller->ControllerNumber,
+ LogicalDriveNumber, 0),
+ DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
+ LogicalDeviceInfo
+ ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+ }
+}
+
+
+/*
+ DAC960_ReportErrorStatus reports Controller BIOS Messages passed through
+ the Error Status Register when the driver performs the BIOS handshaking.
+ It returns true for fatal errors and false otherwise.
+*/
+
+static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
+ unsigned char ErrorStatus,
+ unsigned char Parameter0,
+ unsigned char Parameter1)
+{
+ switch (ErrorStatus)
+ {
+ case 0x00:
+ DAC960_Notice("Physical Device %d:%d Not Responding\n",
+ Controller, Parameter1, Parameter0);
+ break;
+ case 0x08:
+ if (Controller->DriveSpinUpMessageDisplayed) break;
+ DAC960_Notice("Spinning Up Drives\n", Controller);
+ Controller->DriveSpinUpMessageDisplayed = true;
+ break;
+ case 0x30:
+ DAC960_Notice("Configuration Checksum Error\n", Controller);
+ break;
+ case 0x60:
+ DAC960_Notice("Mirror Race Recovery Failed\n", Controller);
+ break;
+ case 0x70:
+ DAC960_Notice("Mirror Race Recovery In Progress\n", Controller);
+ break;
+ case 0x90:
+ DAC960_Notice("Physical Device %d:%d COD Mismatch\n",
+ Controller, Parameter1, Parameter0);
+ break;
+ case 0xA0:
+ DAC960_Notice("Logical Drive Installation Aborted\n", Controller);
+ break;
+ case 0xB0:
+ DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller);
+ break;
+ case 0xD0:
+ DAC960_Notice("New Controller Configuration Found\n", Controller);
+ break;
+ case 0xF0:
+ DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller);
+ return true;
+ default:
+ DAC960_Error("Unknown Initialization Error %02X for Controller at\n",
+ Controller, ErrorStatus);
+ return true;
+ }
+ return false;
+}
+
+
+/*
+ DAC960_DetectControllers detects Mylex DAC960/AcceleRAID/eXtremeRAID
+ PCI RAID Controllers by interrogating the PCI Configuration Space for
+ Controller Type.
+*/
+
+static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
+{
+ void (*InterruptHandler)(int, void *, Registers_T *) = NULL;
+ DAC960_FirmwareType_T FirmwareType = 0;
+ unsigned short VendorID = 0, DeviceID = 0;
+ unsigned int MemoryWindowSize = 0;
+ PCI_Device_T *PCI_Device = NULL;
+ switch (HardwareType)
+ {
+ case DAC960_BA_Controller:
+ VendorID = PCI_VENDOR_ID_MYLEX;
+ DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_BA;
+ FirmwareType = DAC960_V2_Controller;
+ InterruptHandler = DAC960_BA_InterruptHandler;
+ MemoryWindowSize = DAC960_BA_RegisterWindowSize;
+ break;
+ case DAC960_LP_Controller:
+ VendorID = PCI_VENDOR_ID_MYLEX;
+ DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_LP;
+ FirmwareType = DAC960_LP_Controller;
+ InterruptHandler = DAC960_LP_InterruptHandler;
+ MemoryWindowSize = DAC960_LP_RegisterWindowSize;
+ break;
+ case DAC960_LA_Controller:
+ VendorID = PCI_VENDOR_ID_DEC;
+ DeviceID = PCI_DEVICE_ID_DEC_21285;
+ FirmwareType = DAC960_V1_Controller;
+ InterruptHandler = DAC960_LA_InterruptHandler;
+ MemoryWindowSize = DAC960_LA_RegisterWindowSize;
+ break;
+ case DAC960_PG_Controller:
+ VendorID = PCI_VENDOR_ID_MYLEX;
+ DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PG;
+ FirmwareType = DAC960_V1_Controller;
+ InterruptHandler = DAC960_PG_InterruptHandler;
+ MemoryWindowSize = DAC960_PG_RegisterWindowSize;
+ break;
+ case DAC960_PD_Controller:
+ VendorID = PCI_VENDOR_ID_MYLEX;
+ DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PD;
+ FirmwareType = DAC960_V1_Controller;
+ InterruptHandler = DAC960_PD_InterruptHandler;
+ MemoryWindowSize = DAC960_PD_RegisterWindowSize;
+ break;
+ }
+ while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
+ {
+ DAC960_Controller_T *Controller = NULL;
+ DAC960_IO_Address_T IO_Address = 0;
+ DAC960_PCI_Address_T PCI_Address = 0;
+ unsigned char Bus = PCI_Device->bus->number;
+ unsigned char DeviceFunction = PCI_Device->devfn;
+ unsigned char Device = DeviceFunction >> 3;
+ unsigned char Function = DeviceFunction & 0x7;
+ unsigned char ErrorStatus, Parameter0, Parameter1;
+ unsigned int IRQ_Channel = PCI_Device->irq;
+ void *BaseAddress;
+ if (pci_enable_device(PCI_Device) != 0) continue;
+ switch (HardwareType)
+ {
+ case DAC960_BA_Controller:
+ PCI_Address = pci_resource_start(PCI_Device, 0);
+ break;
+ case DAC960_LP_Controller:
+ PCI_Address = pci_resource_start(PCI_Device, 0);
+ break;
+ case DAC960_LA_Controller:
+ if (!(PCI_Device->subsystem_vendor == PCI_VENDOR_ID_MYLEX &&
+ PCI_Device->subsystem_device == PCI_DEVICE_ID_MYLEX_DAC960_LA))
+ continue;
+ PCI_Address = pci_resource_start(PCI_Device, 0);
+ break;
+ case DAC960_PG_Controller:
+ PCI_Address = pci_resource_start(PCI_Device, 0);
+ break;
+ case DAC960_PD_Controller:
+ IO_Address = pci_resource_start(PCI_Device, 0);
+ PCI_Address = pci_resource_start(PCI_Device, 1);
+ break;
+ }
+ if (DAC960_ControllerCount == DAC960_MaxControllers)
+ {
+ DAC960_Error("More than %d DAC960 Controllers detected - "
+ "ignoring from Controller at\n",
+ NULL, DAC960_MaxControllers);
+ goto Failure;
+ }
+ Controller = (DAC960_Controller_T *)
+ kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
+ if (Controller == NULL)
+ {
+ DAC960_Error("Unable to allocate Controller structure for "
+ "Controller at\n", NULL);
+ goto Failure;
+ }
+ memset(Controller, 0, sizeof(DAC960_Controller_T));
+ Controller->ControllerNumber = DAC960_ControllerCount;
+ init_waitqueue_head(&Controller->CommandWaitQueue);
+ init_waitqueue_head(&Controller->HealthStatusWaitQueue);
+ DAC960_Controllers[DAC960_ControllerCount++] = Controller;
+ DAC960_AnnounceDriver(Controller);
+ Controller->FirmwareType = FirmwareType;
+ Controller->HardwareType = HardwareType;
+ Controller->IO_Address = IO_Address;
+ Controller->PCI_Address = PCI_Address;
+ Controller->Bus = Bus;
+ Controller->Device = Device;
+ Controller->Function = Function;
+ sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
+ /*
+ Map the Controller Register Window.
+ */
+ if (MemoryWindowSize < PAGE_SIZE)
+ MemoryWindowSize = PAGE_SIZE;
+ Controller->MemoryMappedAddress =
+ ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
+ Controller->BaseAddress =
+ Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
+ if (Controller->MemoryMappedAddress == NULL)
+ {
+ DAC960_Error("Unable to map Controller Register Window for "
+ "Controller at\n", Controller);
+ goto Failure;
+ }
+ BaseAddress = Controller->BaseAddress;
+ switch (HardwareType)
+ {
+ case DAC960_BA_Controller:
+ DAC960_BA_DisableInterrupts(Controller->BaseAddress);
+ DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
+ udelay(1000);
+ while (DAC960_BA_InitializationInProgressP(BaseAddress))
+ {
+ if (DAC960_BA_ReadErrorStatus(BaseAddress, &ErrorStatus,
+ &Parameter0, &Parameter1) &&
+ DAC960_ReportErrorStatus(Controller, ErrorStatus,
+ Parameter0, Parameter1))
+ goto Failure;
+ udelay(10);
+ }
+ if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
+ {
+ DAC960_Error("Unable to Enable Memory Mailbox Interface "
+ "for Controller at\n", Controller);
+ goto Failure;
+ }
+ DAC960_BA_EnableInterrupts(Controller->BaseAddress);
+ Controller->QueueCommand = DAC960_BA_QueueCommand;
+ Controller->ReadControllerConfiguration =
+ DAC960_V2_ReadControllerConfiguration;
+ Controller->ReadDeviceConfiguration =
+ DAC960_V2_ReadDeviceConfiguration;
+ Controller->ReportDeviceConfiguration =
+ DAC960_V2_ReportDeviceConfiguration;
+ Controller->QueueReadWriteCommand =
+ DAC960_V2_QueueReadWriteCommand;
+ break;
+ case DAC960_LP_Controller:
+ DAC960_LP_DisableInterrupts(Controller->BaseAddress);
+ DAC960_LP_AcknowledgeHardwareMailboxStatus(BaseAddress);
+ udelay(1000);
+ while (DAC960_LP_InitializationInProgressP(BaseAddress))
+ {
+ if (DAC960_LP_ReadErrorStatus(BaseAddress, &ErrorStatus,
+ &Parameter0, &Parameter1) &&
+ DAC960_ReportErrorStatus(Controller, ErrorStatus,
+ Parameter0, Parameter1))
+ goto Failure;
+ udelay(10);
+ }
+ if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
+ {
+ DAC960_Error("Unable to Enable Memory Mailbox Interface "
+ "for Controller at\n", Controller);
+ goto Failure;
+ }
+ DAC960_LP_EnableInterrupts(Controller->BaseAddress);
+ Controller->QueueCommand = DAC960_LP_QueueCommand;
+ Controller->ReadControllerConfiguration =
+ DAC960_V2_ReadControllerConfiguration;
+ Controller->ReadDeviceConfiguration =
+ DAC960_V2_ReadDeviceConfiguration;
+ Controller->ReportDeviceConfiguration =
+ DAC960_V2_ReportDeviceConfiguration;
+ Controller->QueueReadWriteCommand =
+ DAC960_V2_QueueReadWriteCommand;
+ break;
+ case DAC960_LA_Controller:
+ DAC960_LA_DisableInterrupts(Controller->BaseAddress);
+ DAC960_LA_AcknowledgeHardwareMailboxStatus(BaseAddress);
+ udelay(1000);
+ while (DAC960_LA_InitializationInProgressP(BaseAddress))
+ {
+ if (DAC960_LA_ReadErrorStatus(BaseAddress, &ErrorStatus,
+ &Parameter0, &Parameter1) &&
+ DAC960_ReportErrorStatus(Controller, ErrorStatus,
+ Parameter0, Parameter1))
+ goto Failure;
+ udelay(10);
+ }
+ if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
+ {
+ DAC960_Error("Unable to Enable Memory Mailbox Interface "
+ "for Controller at\n", Controller);
+ goto Failure;
+ }
+ DAC960_LA_EnableInterrupts(Controller->BaseAddress);
+ if (Controller->V1.DualModeMemoryMailboxInterface)
+ Controller->QueueCommand = DAC960_LA_QueueCommandDualMode;
+ else Controller->QueueCommand = DAC960_LA_QueueCommandSingleMode;
+ Controller->ReadControllerConfiguration =
+ DAC960_V1_ReadControllerConfiguration;
+ Controller->ReadDeviceConfiguration =
+ DAC960_V1_ReadDeviceConfiguration;
+ Controller->ReportDeviceConfiguration =
+ DAC960_V1_ReportDeviceConfiguration;
+ Controller->QueueReadWriteCommand =
+ DAC960_V1_QueueReadWriteCommand;
+ break;
+ case DAC960_PG_Controller:
+ DAC960_PG_DisableInterrupts(Controller->BaseAddress);
+ DAC960_PG_AcknowledgeHardwareMailboxStatus(BaseAddress);
+ udelay(1000);
+ while (DAC960_PG_InitializationInProgressP(BaseAddress))
+ {
+ if (DAC960_PG_ReadErrorStatus(BaseAddress, &ErrorStatus,
+ &Parameter0, &Parameter1) &&
+ DAC960_ReportErrorStatus(Controller, ErrorStatus,
+ Parameter0, Parameter1))
+ goto Failure;
+ udelay(10);
+ }
+ if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
+ {
+ DAC960_Error("Unable to Enable Memory Mailbox Interface "
+ "for Controller at\n", Controller);
+ goto Failure;
+ }
+ DAC960_PG_EnableInterrupts(Controller->BaseAddress);
+ if (Controller->V1.DualModeMemoryMailboxInterface)
+ Controller->QueueCommand = DAC960_PG_QueueCommandDualMode;
+ else Controller->QueueCommand = DAC960_PG_QueueCommandSingleMode;
+ Controller->ReadControllerConfiguration =
+ DAC960_V1_ReadControllerConfiguration;
+ Controller->ReadDeviceConfiguration =
+ DAC960_V1_ReadDeviceConfiguration;
+ Controller->ReportDeviceConfiguration =
+ DAC960_V1_ReportDeviceConfiguration;
+ Controller->QueueReadWriteCommand =
+ DAC960_V1_QueueReadWriteCommand;
+ break;
+ case DAC960_PD_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_PD_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.
+ */
+ if (IRQ_Channel == 0)
+ {
+ DAC960_Error("IRQ Channel %d illegal for Controller at\n",
+ Controller, IRQ_Channel);
+ goto Failure;
+ }
+ strcpy(Controller->FullModelName, "DAC960");
+ if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
+ Controller->FullModelName, Controller) < 0)
+ {
+ DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
+ Controller, IRQ_Channel);
+ goto Failure;
+ }
+ Controller->IRQ_Channel = IRQ_Channel;
+ DAC960_ActiveControllerCount++;
+ Controller->InitialCommand.CommandIdentifier = 1;
+ Controller->InitialCommand.Controller = Controller;
+ Controller->Commands[0] = &Controller->InitialCommand;
+ Controller->FreeCommands = &Controller->InitialCommand;
+ Controller->ControllerDetectionSuccessful = true;
+ continue;
+ Failure:
+ if (IO_Address == 0)
+ DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
+ "PCI Address 0x%X\n", Controller,
+ Bus, Device, Function, PCI_Address);
+ else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
+ "0x%X PCI Address 0x%X\n", Controller,
+ Bus, Device, Function, IO_Address, PCI_Address);
+ if (Controller == NULL) break;
+ if (Controller->MemoryMappedAddress != NULL)
+ iounmap(Controller->MemoryMappedAddress);
+ if (Controller->IRQ_Channel > 0)
+ free_irq(IRQ_Channel, Controller);
+ }
+}
+
+
+/*
+ DAC960_SortControllers sorts the Controllers by PCI Bus and Device Number.
+*/
+
+static void DAC960_SortControllers(void)
+{
+ int ControllerNumber, LastInterchange, Bound, j;
+ LastInterchange = DAC960_ControllerCount-1;
+ while (LastInterchange > 0)
+ {
+ Bound = LastInterchange;
+ LastInterchange = 0;
+ for (j = 0; j < Bound; j++)
+ {
+ DAC960_Controller_T *Controller1 = DAC960_Controllers[j];
+ DAC960_Controller_T *Controller2 = DAC960_Controllers[j+1];
+ if (Controller1->Bus > Controller2->Bus ||
+ (Controller1->Bus == Controller2->Bus &&
+ (Controller1->Device > Controller2->Device)))
+ {
+ Controller2->ControllerNumber = j;
+ DAC960_Controllers[j] = Controller2;
+ Controller1->ControllerNumber = j+1;
+ DAC960_Controllers[j+1] = Controller1;
+ LastInterchange = j;
+ }
+ }
+ }
+ for (ControllerNumber = 0;
+ ControllerNumber < DAC960_ControllerCount;
+ ControllerNumber++)
+ {
+ DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
+ if (!Controller->ControllerDetectionSuccessful)
+ {
+ DAC960_Controllers[ControllerNumber] = NULL;
+ kfree(Controller);
+ }
+ }
+}
+
+
+/*
DAC960_InitializeController initializes Controller.
*/
@@ -1320,25 +2468,12 @@ static void DAC960_InitializeController(DAC960_Controller_T *Controller)
{
if (DAC960_ReadControllerConfiguration(Controller) &&
DAC960_ReportControllerConfiguration(Controller) &&
+ DAC960_CreateAuxiliaryStructures(Controller) &&
DAC960_ReadDeviceConfiguration(Controller) &&
DAC960_ReportDeviceConfiguration(Controller) &&
DAC960_RegisterBlockDevice(Controller))
{
/*
- Initialize the Command structures.
- */
- DAC960_Command_T *Commands = Controller->Commands;
- int CommandIdentifier;
- Controller->FreeCommands = NULL;
- for (CommandIdentifier = 0;
- CommandIdentifier < Controller->DriverQueueDepth;
- CommandIdentifier++)
- {
- Commands[CommandIdentifier].Controller = Controller;
- Commands[CommandIdentifier].Next = Controller->FreeCommands;
- Controller->FreeCommands = &Commands[CommandIdentifier];
- }
- /*
Initialize the Monitoring Timer.
*/
init_timer(&Controller->MonitoringTimer);
@@ -1348,7 +2483,6 @@ static void DAC960_InitializeController(DAC960_Controller_T *Controller)
Controller->MonitoringTimer.function = DAC960_MonitoringTimerFunction;
add_timer(&Controller->MonitoringTimer);
Controller->ControllerInitialized = true;
- DAC960_InitializeGenericDiskInfo(&Controller->GenericDiskInfo);
}
else DAC960_FinalizeController(Controller);
}
@@ -1363,28 +2497,46 @@ static void DAC960_FinalizeController(DAC960_Controller_T *Controller)
if (Controller->ControllerInitialized)
{
del_timer(&Controller->MonitoringTimer);
- DAC960_Notice("Flushing Cache...", Controller);
- DAC960_ExecuteType3(Controller, DAC960_Flush, NULL);
- DAC960_Notice("done\n", Controller);
- switch (Controller->ControllerType)
- {
- case DAC960_V5_Controller:
- if (!Controller->DualModeMemoryMailboxInterface)
- DAC960_V5_SaveMemoryMailboxInfo(Controller);
- break;
- case DAC960_V4_Controller:
- if (!Controller->DualModeMemoryMailboxInterface)
- DAC960_V4_SaveMemoryMailboxInfo(Controller);
- break;
- case DAC960_V3_Controller:
- break;
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ {
+ DAC960_Notice("Flushing Cache...", Controller);
+ DAC960_V1_ExecuteType3(Controller, DAC960_V1_Flush, NULL);
+ DAC960_Notice("done\n", Controller);
+ switch (Controller->HardwareType)
+ {
+ case DAC960_LA_Controller:
+ if (Controller->V1.DualModeMemoryMailboxInterface)
+ free_pages(Controller->MemoryMailboxPagesAddress,
+ Controller->MemoryMailboxPagesOrder);
+ else DAC960_LA_SaveMemoryMailboxInfo(Controller);
+ break;
+ case DAC960_PG_Controller:
+ if (Controller->V1.DualModeMemoryMailboxInterface)
+ free_pages(Controller->MemoryMailboxPagesAddress,
+ Controller->MemoryMailboxPagesOrder);
+ else DAC960_PG_SaveMemoryMailboxInfo(Controller);
+ break;
+ case DAC960_PD_Controller:
+ release_region(Controller->IO_Address, 0x80);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ DAC960_Notice("Flushing Cache...", Controller);
+ DAC960_V2_DeviceOperation(Controller, DAC960_V2_PauseDevice,
+ DAC960_V2_RAID_Controller);
+ DAC960_Notice("done\n", Controller);
+ free_pages(Controller->MemoryMailboxPagesAddress,
+ Controller->MemoryMailboxPagesOrder);
}
}
free_irq(Controller->IRQ_Channel, Controller);
iounmap(Controller->MemoryMappedAddress);
- if (Controller->IO_Address > 0)
- release_region(Controller->IO_Address, 0x80);
DAC960_UnregisterBlockDevice(Controller);
+ DAC960_DestroyAuxiliaryStructures(Controller);
DAC960_Controllers[Controller->ControllerNumber] = NULL;
kfree(Controller);
}
@@ -1397,15 +2549,26 @@ static void DAC960_FinalizeController(DAC960_Controller_T *Controller)
void DAC960_Initialize(void)
{
int ControllerNumber;
- DAC960_DetectControllers(DAC960_V5_Controller);
- DAC960_DetectControllers(DAC960_V4_Controller);
- DAC960_DetectControllers(DAC960_V3_Controller);
+ DAC960_DetectControllers(DAC960_BA_Controller);
+ DAC960_DetectControllers(DAC960_LP_Controller);
+ DAC960_DetectControllers(DAC960_LA_Controller);
+ DAC960_DetectControllers(DAC960_PG_Controller);
+ DAC960_DetectControllers(DAC960_PD_Controller);
+ DAC960_SortControllers();
if (DAC960_ActiveControllerCount == 0) return;
for (ControllerNumber = 0;
ControllerNumber < DAC960_ControllerCount;
ControllerNumber++)
- if (DAC960_Controllers[ControllerNumber] != NULL)
- DAC960_InitializeController(DAC960_Controllers[ControllerNumber]);
+ {
+ DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
+ int LogicalDriveNumber;
+ if (Controller == NULL) continue;
+ DAC960_InitializeController(Controller);
+ for (LogicalDriveNumber = 0;
+ LogicalDriveNumber < DAC960_MaxLogicalDrives;
+ LogicalDriveNumber++)
+ DAC960_RegisterDisk(Controller, LogicalDriveNumber);
+ }
DAC960_CreateProcEntries();
register_reboot_notifier(&DAC960_NotifierBlock);
}
@@ -1435,69 +2598,38 @@ static int DAC960_Finalize(NotifierBlock_T *NotifierBlock,
/*
- DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
- I/O Request Queue and queues it to the Controller. WaitForCommand is true if
- this function should wait for a Command to become available if necessary.
- This function returns true if an I/O Request was queued and false otherwise.
+ DAC960_V1_QueueReadWriteCommand prepares and queues a Read/Write Command for
+ DAC960 V1 Firmware Controllers.
*/
-static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
- boolean WaitForCommand)
+static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command)
{
- struct list_head * queue_head;
- IO_Request_T *Request;
- DAC960_Command_T *Command;
- char *RequestBuffer;
-
- queue_head = &blk_dev[DAC960_MAJOR + Controller->ControllerNumber].request_queue.queue_head;
- while (true)
- {
- if (list_empty(queue_head)) return false;
- Request = blkdev_entry_next_request(queue_head);
- if (Request->rq_status == RQ_INACTIVE) return false;
- Command = DAC960_AllocateCommand(Controller);
- if (Command != NULL) break;
- if (!WaitForCommand) return false;
- DAC960_WaitForCommand(Controller);
- }
- DAC960_ClearCommand(Command);
- if (Request->cmd == READ)
- Command->CommandType = DAC960_ReadCommand;
- else Command->CommandType = DAC960_WriteCommand;
- Command->Semaphore = Request->sem;
- Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
- Command->BlockNumber =
- Request->sector
- + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
- Command->BlockCount = Request->nr_sectors;
- Command->SegmentCount = Request->nr_segments;
- Command->BufferHeader = Request->bh;
- RequestBuffer = Request->buffer;
- blkdev_dequeue_request(Request);
- blkdev_release_request(Request);
+ DAC960_Controller_T *Controller = Command->Controller;
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_ClearCommand(Command);
if (Command->SegmentCount == 1)
{
- DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
if (Command->CommandType == DAC960_ReadCommand)
- CommandMailbox->Type5.CommandOpcode = DAC960_Read;
- else CommandMailbox->Type5.CommandOpcode = DAC960_Write;
+ CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
+ else CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
- CommandMailbox->Type5.BusAddress = Virtual_to_Bus(RequestBuffer);
+ CommandMailbox->Type5.BusAddress = Virtual_to_Bus(Command->RequestBuffer);
}
else
{
- DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
- DAC960_ScatterGatherSegment_T
- *ScatterGatherList = Command->ScatterGatherList;
+ DAC960_V1_ScatterGatherSegment_T
+ *ScatterGatherList = Command->V1.ScatterGatherList;
BufferHeader_T *BufferHeader = Command->BufferHeader;
char *LastDataEndPointer = NULL;
int SegmentNumber = 0;
if (Command->CommandType == DAC960_ReadCommand)
- CommandMailbox->Type5.CommandOpcode = DAC960_ReadWithOldScatterGather;
+ CommandMailbox->Type5.CommandOpcode =
+ DAC960_V1_ReadWithOldScatterGather;
else
- CommandMailbox->Type5.CommandOpcode = DAC960_WriteWithOldScatterGather;
+ CommandMailbox->Type5.CommandOpcode =
+ DAC960_V1_WriteWithOldScatterGather;
CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
@@ -1518,7 +2650,7 @@ static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
ScatterGatherList[SegmentNumber].SegmentByteCount =
BufferHeader->b_size;
LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
- if (SegmentNumber++ > Controller->MaxScatterGatherSegments)
+ if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
panic("DAC960: Scatter/Gather Segment Overflow\n");
}
BufferHeader = BufferHeader->b_reqnext;
@@ -1527,167 +2659,163 @@ static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
panic("DAC960: SegmentNumber != SegmentCount\n");
}
DAC960_QueueCommand(Command);
- return true;
-}
-
-
-/*
- DAC960_ProcessRequests attempts to remove as many I/O Requests as possible
- from Controller's I/O Request Queue and queue them to the Controller.
-*/
-
-static inline void DAC960_ProcessRequests(DAC960_Controller_T *Controller)
-{
- int Counter = 0;
- while (DAC960_ProcessRequest(Controller, Counter++ == 0)) ;
-}
-
-
-/*
- DAC960_RequestFunction0 is the I/O Request Function for DAC960 Controller 0.
-*/
-
-static void DAC960_RequestFunction0(request_queue_t * q)
-{
- DAC960_Controller_T *Controller = DAC960_Controllers[0];
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
- /*
- Process I/O Requests for Controller.
- */
- DAC960_ProcessRequests(Controller);
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
-}
-
-
-/*
- DAC960_RequestFunction1 is the I/O Request Function for DAC960 Controller 1.
-*/
-
-static void DAC960_RequestFunction1(request_queue_t * q)
-{
- DAC960_Controller_T *Controller = DAC960_Controllers[1];
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
- /*
- Process I/O Requests for Controller.
- */
- DAC960_ProcessRequests(Controller);
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
-}
-
-
-/*
- DAC960_RequestFunction2 is the I/O Request Function for DAC960 Controller 2.
-*/
-
-static void DAC960_RequestFunction2(request_queue_t * q)
-{
- DAC960_Controller_T *Controller = DAC960_Controllers[2];
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
- /*
- Process I/O Requests for Controller.
- */
- DAC960_ProcessRequests(Controller);
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
}
/*
- DAC960_RequestFunction3 is the I/O Request Function for DAC960 Controller 3.
+ DAC960_V2_QueueReadWriteCommand prepares and queues a Read/Write Command for
+ DAC960 V2 Firmware Controllers.
*/
-static void DAC960_RequestFunction3(request_queue_t * q)
+static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
{
- DAC960_Controller_T *Controller = DAC960_Controllers[3];
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
- /*
- Process I/O Requests for Controller.
- */
- DAC960_ProcessRequests(Controller);
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
+ DAC960_Controller_T *Controller = Command->Controller;
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_ClearCommand(Command);
+ CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10;
+ CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost =
+ (Command->CommandType == DAC960_ReadCommand);
+ CommandMailbox->SCSI_10.DataTransferSize =
+ Command->BlockCount << DAC960_BlockSizeBits;
+ CommandMailbox->SCSI_10.RequestSenseBusAddress =
+ Virtual_to_Bus(&Command->V2.RequestSense);
+ CommandMailbox->SCSI_10.PhysicalDevice =
+ Controller->V2.LogicalDriveToVirtualDevice[Command->LogicalDriveNumber];
+ CommandMailbox->SCSI_10.RequestSenseSize =
+ sizeof(DAC960_SCSI_RequestSense_T);
+ CommandMailbox->SCSI_10.CDBLength = 10;
+ CommandMailbox->SCSI_10.SCSI_CDB[0] =
+ (Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A);
+ CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
+ CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
+ CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
+ CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
+ CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
+ CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
+ if (Command->SegmentCount == 1)
+ {
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(Command->RequestBuffer);
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->SCSI_10.DataTransferSize;
+ }
+ else
+ {
+ DAC960_V2_ScatterGatherSegment_T
+ *ScatterGatherList = Command->V2.ScatterGatherList;
+ BufferHeader_T *BufferHeader = Command->BufferHeader;
+ char *LastDataEndPointer = NULL;
+ int SegmentNumber = 0;
+ if (Command->SegmentCount > 2)
+ {
+ CommandMailbox->SCSI_10.CommandControlBits
+ .AdditionalScatterGatherListMemory = true;
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ExtendedScatterGather.ScatterGatherList0Length =
+ Command->SegmentCount;
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ExtendedScatterGather.ScatterGatherList0Address =
+ Virtual_to_Bus(ScatterGatherList);
+ }
+ else
+ ScatterGatherList =
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments;
+ while (BufferHeader != NULL)
+ {
+ if (BufferHeader->b_data == LastDataEndPointer)
+ {
+ ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
+ BufferHeader->b_size;
+ LastDataEndPointer += BufferHeader->b_size;
+ }
+ else
+ {
+ ScatterGatherList[SegmentNumber].SegmentDataPointer =
+ Virtual_to_Bus(BufferHeader->b_data);
+ ScatterGatherList[SegmentNumber].SegmentByteCount =
+ BufferHeader->b_size;
+ LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
+ if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
+ panic("DAC960: Scatter/Gather Segment Overflow\n");
+ }
+ BufferHeader = BufferHeader->b_reqnext;
+ }
+ if (SegmentNumber != Command->SegmentCount)
+ panic("DAC960: SegmentNumber != SegmentCount\n");
+ }
+ DAC960_QueueCommand(Command);
}
/*
- DAC960_RequestFunction4 is the I/O Request Function for DAC960 Controller 4.
+ DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
+ I/O Request Queue and queues it to the Controller. WaitForCommand is true if
+ this function should wait for a Command to become available if necessary.
+ This function returns true if an I/O Request was queued and false otherwise.
*/
-static void DAC960_RequestFunction4(request_queue_t * q)
+static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
+ boolean WaitForCommand)
{
- DAC960_Controller_T *Controller = DAC960_Controllers[4];
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
- /*
- Process I/O Requests for Controller.
- */
- DAC960_ProcessRequests(Controller);
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
+ RequestQueue_T *RequestQueue = Controller->RequestQueue;
+ ListHead_T *RequestQueueHead;
+ IO_Request_T *Request;
+ DAC960_Command_T *Command;
+ if (RequestQueue == NULL) return false;
+ RequestQueueHead = &RequestQueue->queue_head;
+ while (true)
+ {
+ if (list_empty(RequestQueueHead)) return false;
+ Request = blkdev_entry_next_request(RequestQueueHead);
+ Command = DAC960_AllocateCommand(Controller);
+ if (Command != NULL) break;
+ if (!WaitForCommand) return false;
+ DAC960_WaitForCommand(Controller);
+ }
+ if (Request->cmd == READ)
+ Command->CommandType = DAC960_ReadCommand;
+ else Command->CommandType = DAC960_WriteCommand;
+ Command->Semaphore = Request->sem;
+ Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
+ Command->BlockNumber =
+ Request->sector
+ + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
+ Command->BlockCount = Request->nr_sectors;
+ Command->SegmentCount = Request->nr_segments;
+ Command->BufferHeader = Request->bh;
+ Command->RequestBuffer = Request->buffer;
+ blkdev_dequeue_request(Request);
+ blkdev_release_request(Request);
+ DAC960_QueueReadWriteCommand(Command);
+ return true;
}
/*
- DAC960_RequestFunction5 is the I/O Request Function for DAC960 Controller 5.
+ DAC960_ProcessRequests attempts to remove as many I/O Requests as possible
+ from Controller's I/O Request Queue and queue them to the Controller.
*/
-static void DAC960_RequestFunction5(request_queue_t * q)
+static inline void DAC960_ProcessRequests(DAC960_Controller_T *Controller)
{
- DAC960_Controller_T *Controller = DAC960_Controllers[5];
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
- /*
- Process I/O Requests for Controller.
- */
- DAC960_ProcessRequests(Controller);
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
+ int Counter = 0;
+ while (DAC960_ProcessRequest(Controller, Counter++ == 0)) ;
}
/*
- DAC960_RequestFunction6 is the I/O Request Function for DAC960 Controller 6.
+ DAC960_RequestFunction is the I/O Request Function for DAC960 Controllers.
*/
-static void DAC960_RequestFunction6(request_queue_t * q)
+static void DAC960_RequestFunction(RequestQueue_T *RequestQueue)
{
- DAC960_Controller_T *Controller = DAC960_Controllers[6];
+ DAC960_Controller_T *Controller =
+ (DAC960_Controller_T *) RequestQueue->queuedata;
ProcessorFlags_T ProcessorFlags;
/*
Acquire exclusive access to Controller.
@@ -1705,37 +2833,26 @@ static void DAC960_RequestFunction6(request_queue_t * q)
/*
- DAC960_RequestFunction7 is the I/O Request Function for DAC960 Controller 7.
+ DAC960_ProcessCompletedBuffer performs completion processing for an
+ individual Buffer.
*/
-static void DAC960_RequestFunction7(request_queue_t * q)
+static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
+ boolean SuccessfulIO)
{
- DAC960_Controller_T *Controller = DAC960_Controllers[7];
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
- /*
- Process I/O Requests for Controller.
- */
- DAC960_ProcessRequests(Controller);
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
+ BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
}
/*
- DAC960_ReadWriteError prints an appropriate error message for Command when
- an error occurs on a Read or Write operation.
+ DAC960_V1_ReadWriteError prints an appropriate error message for Command
+ when an error occurs on a Read or Write operation.
*/
-static void DAC960_ReadWriteError(DAC960_Command_T *Command)
+static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command)
{
DAC960_Controller_T *Controller = Command->Controller;
- char *CommandName = "UNKNOWN";
+ unsigned char *CommandName = "UNKNOWN";
switch (Command->CommandType)
{
case DAC960_ReadCommand:
@@ -1751,26 +2868,26 @@ static void DAC960_ReadWriteError(DAC960_Command_T *Command)
case DAC960_QueuedCommand:
break;
}
- switch (Command->CommandStatus)
+ switch (Command->V1.CommandStatus)
{
- case DAC960_IrrecoverableDataError:
+ case DAC960_V1_IrrecoverableDataError:
DAC960_Error("Irrecoverable Data Error on %s:\n",
Controller, CommandName);
break;
- case DAC960_LogicalDriveNonexistentOrOffline:
+ case DAC960_V1_LogicalDriveNonexistentOrOffline:
DAC960_Error("Logical Drive Nonexistent or Offline on %s:\n",
Controller, CommandName);
break;
- case DAC960_AccessBeyondEndOfLogicalDrive:
+ case DAC960_V1_AccessBeyondEndOfLogicalDrive:
DAC960_Error("Attempt to Access Beyond End of Logical Drive "
"on %s:\n", Controller, CommandName);
break;
- case DAC960_BadDataEncountered:
+ case DAC960_V1_BadDataEncountered:
DAC960_Error("Bad Data Encountered on %s:\n", Controller, CommandName);
break;
default:
DAC960_Error("Unexpected Error Status %04X on %s:\n",
- Controller, Command->CommandStatus, CommandName);
+ Controller, Command->V1.CommandStatus, CommandName);
break;
}
DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %d..%d\n",
@@ -1788,33 +2905,22 @@ static void DAC960_ReadWriteError(DAC960_Command_T *Command)
/*
- DAC960_ProcessCompletedBuffer performs completion processing for an
- individual Buffer.
-*/
-
-static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
- boolean SuccessfulIO)
-{
- BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
-}
-
-
-/*
- DAC960_ProcessCompletedCommand performs completion processing for Command.
+ DAC960_V1_ProcessCompletedCommand performs completion processing for Command
+ for DAC960 V1 Firmware Controllers.
*/
-static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
+static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
{
DAC960_Controller_T *Controller = Command->Controller;
DAC960_CommandType_T CommandType = Command->CommandType;
- DAC960_CommandOpcode_T CommandOpcode =
- Command->CommandMailbox.Common.CommandOpcode;
- DAC960_CommandStatus_T CommandStatus = Command->CommandStatus;
+ DAC960_V1_CommandOpcode_T CommandOpcode =
+ Command->V1.CommandMailbox.Common.CommandOpcode;
+ DAC960_V1_CommandStatus_T CommandStatus = Command->V1.CommandStatus;
BufferHeader_T *BufferHeader = Command->BufferHeader;
if (CommandType == DAC960_ReadCommand ||
CommandType == DAC960_WriteCommand)
{
- if (CommandStatus == DAC960_NormalCompletion)
+ if (CommandStatus == DAC960_V1_NormalCompletion)
{
/*
Perform completion processing for all buffers in this I/O Request.
@@ -1836,21 +2942,22 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
}
add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
}
- else if ((CommandStatus == DAC960_IrrecoverableDataError ||
- CommandStatus == DAC960_BadDataEncountered) &&
+ else if ((CommandStatus == DAC960_V1_IrrecoverableDataError ||
+ CommandStatus == DAC960_V1_BadDataEncountered) &&
BufferHeader != NULL &&
BufferHeader->b_reqnext != NULL)
{
- DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
+ DAC960_V1_CommandMailbox_T *CommandMailbox =
+ &Command->V1.CommandMailbox;
if (CommandType == DAC960_ReadCommand)
{
Command->CommandType = DAC960_ReadRetryCommand;
- CommandMailbox->Type5.CommandOpcode = DAC960_Read;
+ CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
}
else
{
Command->CommandType = DAC960_WriteRetryCommand;
- CommandMailbox->Type5.CommandOpcode = DAC960_Write;
+ CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
}
Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
@@ -1861,8 +2968,8 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
}
else
{
- if (CommandStatus != DAC960_LogicalDriveNonexistentOrOffline)
- DAC960_ReadWriteError(Command);
+ if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
+ DAC960_V1_ReadWriteError(Command);
/*
Perform completion processing for all buffers in this I/O Request.
*/
@@ -1891,17 +2998,18 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
/*
Perform completion processing for this single buffer.
*/
- if (CommandStatus == DAC960_NormalCompletion)
+ if (CommandStatus == DAC960_V1_NormalCompletion)
DAC960_ProcessCompletedBuffer(BufferHeader, true);
else
{
- if (CommandStatus != DAC960_LogicalDriveNonexistentOrOffline)
- DAC960_ReadWriteError(Command);
+ if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
+ DAC960_V1_ReadWriteError(Command);
DAC960_ProcessCompletedBuffer(BufferHeader, false);
}
if (NextBufferHeader != NULL)
{
- DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
+ DAC960_V1_CommandMailbox_T *CommandMailbox =
+ &Command->V1.CommandMailbox;
Command->BlockNumber +=
BufferHeader->b_size >> DAC960_BlockSizeBits;
Command->BlockCount =
@@ -1916,30 +3024,43 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
}
}
else if (CommandType == DAC960_MonitoringCommand ||
- CommandOpcode == DAC960_Enquiry ||
- CommandOpcode == DAC960_GetRebuildProgress)
+ CommandOpcode == DAC960_V1_Enquiry ||
+ CommandOpcode == DAC960_V1_GetRebuildProgress)
{
if (CommandType != DAC960_MonitoringCommand)
{
- if (CommandOpcode == DAC960_Enquiry)
- memcpy(&Controller->Enquiry[Controller->EnquiryIndex ^ 1],
- Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress),
- sizeof(DAC960_Enquiry_T));
- else if (CommandOpcode == DAC960_GetRebuildProgress)
- memcpy(&Controller->RebuildProgress,
- Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress),
- sizeof(DAC960_RebuildProgress_T));
- }
- if (CommandOpcode == DAC960_Enquiry)
- {
- DAC960_Enquiry_T *OldEnquiry =
- &Controller->Enquiry[Controller->EnquiryIndex];
- DAC960_Enquiry_T *NewEnquiry =
- &Controller->Enquiry[Controller->EnquiryIndex ^= 1];
+ if (CommandOpcode == DAC960_V1_Enquiry)
+ memcpy(&Controller->V1.NewEnquiry,
+ Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress),
+ sizeof(DAC960_V1_Enquiry_T));
+ else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
+ memcpy(&Controller->V1.RebuildProgress,
+ Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress),
+ sizeof(DAC960_V1_RebuildProgress_T));
+ }
+ if (CommandOpcode == DAC960_V1_Enquiry &&
+ Controller->ControllerInitialized)
+ {
+ DAC960_V1_Enquiry_T *OldEnquiry = &Controller->V1.Enquiry;
+ DAC960_V1_Enquiry_T *NewEnquiry = &Controller->V1.NewEnquiry;
unsigned int OldCriticalLogicalDriveCount =
OldEnquiry->CriticalLogicalDriveCount;
unsigned int NewCriticalLogicalDriveCount =
NewEnquiry->CriticalLogicalDriveCount;
+ if (NewEnquiry->NumberOfLogicalDrives > Controller->LogicalDriveCount)
+ {
+ int LogicalDriveNumber = Controller->LogicalDriveCount;
+ while (LogicalDriveNumber < NewEnquiry->NumberOfLogicalDrives)
+ {
+ DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
+ "Now Exists\n", Controller,
+ LogicalDriveNumber,
+ Controller->ControllerNumber,
+ LogicalDriveNumber);
+ LogicalDriveNumber++;
+ }
+ Controller->LogicalDriveCount = LogicalDriveNumber;
+ }
if (NewEnquiry->StatusFlags.DeferredWriteError !=
OldEnquiry->StatusFlags.DeferredWriteError)
DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
@@ -1959,72 +3080,86 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
(jiffies - Controller->SecondaryMonitoringTime
>= DAC960_SecondaryMonitoringInterval))
{
- Controller->NeedLogicalDriveInformation = true;
- Controller->NewEventLogSequenceNumber =
+ Controller->V1.NeedLogicalDriveInformation = true;
+ Controller->V1.NewEventLogSequenceNumber =
NewEnquiry->EventLogSequenceNumber;
- Controller->NeedErrorTableInformation = true;
- Controller->NeedDeviceStateInformation = true;
- Controller->DeviceStateChannel = 0;
- Controller->DeviceStateTargetID = -1;
+ Controller->V1.NeedErrorTableInformation = true;
+ Controller->V1.NeedDeviceStateInformation = true;
+ Controller->V1.DeviceStateChannel = 0;
+ Controller->V1.DeviceStateTargetID = -1;
Controller->SecondaryMonitoringTime = jiffies;
}
- if (NewEnquiry->RebuildFlag == DAC960_StandbyRebuildInProgress ||
- NewEnquiry->RebuildFlag == DAC960_BackgroundRebuildInProgress ||
- OldEnquiry->RebuildFlag == DAC960_StandbyRebuildInProgress ||
- OldEnquiry->RebuildFlag == DAC960_BackgroundRebuildInProgress)
- Controller->NeedRebuildProgress = true;
- if (OldEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
+ if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
+ NewEnquiry->RebuildFlag
+ == DAC960_V1_BackgroundRebuildInProgress ||
+ OldEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
+ OldEnquiry->RebuildFlag == DAC960_V1_BackgroundRebuildInProgress)
+ {
+ Controller->V1.NeedRebuildProgress = true;
+ Controller->V1.RebuildProgressFirst =
+ (NewEnquiry->CriticalLogicalDriveCount <
+ OldEnquiry->CriticalLogicalDriveCount);
+ }
+ if (OldEnquiry->RebuildFlag == DAC960_V1_BackgroundCheckInProgress)
switch (NewEnquiry->RebuildFlag)
{
- case DAC960_NoStandbyRebuildOrCheckInProgress:
+ case DAC960_V1_NoStandbyRebuildOrCheckInProgress:
DAC960_Progress("Consistency Check Completed Successfully\n",
Controller);
break;
- case DAC960_StandbyRebuildInProgress:
- case DAC960_BackgroundRebuildInProgress:
+ case DAC960_V1_StandbyRebuildInProgress:
+ case DAC960_V1_BackgroundRebuildInProgress:
break;
- case DAC960_BackgroundCheckInProgress:
- Controller->NeedConsistencyCheckProgress = true;
+ case DAC960_V1_BackgroundCheckInProgress:
+ Controller->V1.NeedConsistencyCheckProgress = true;
break;
- case DAC960_StandbyRebuildCompletedWithError:
+ case DAC960_V1_StandbyRebuildCompletedWithError:
DAC960_Progress("Consistency Check Completed with Error\n",
Controller);
break;
- case DAC960_BackgroundRebuildOrCheckFailed_DriveFailed:
+ case DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed:
DAC960_Progress("Consistency Check Failed - "
- "Physical Drive Failed\n", Controller);
+ "Physical Device Failed\n", Controller);
break;
- case DAC960_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
+ case DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
DAC960_Progress("Consistency Check Failed - "
"Logical Drive Failed\n", Controller);
break;
- case DAC960_BackgroundRebuildOrCheckFailed_OtherCauses:
+ case DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses:
DAC960_Progress("Consistency Check Failed - Other Causes\n",
Controller);
break;
- case DAC960_BackgroundRebuildOrCheckSuccessfullyTerminated:
+ case DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated:
DAC960_Progress("Consistency Check Successfully Terminated\n",
Controller);
break;
}
- else if (NewEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
- Controller->NeedConsistencyCheckProgress = true;
+ else if (NewEnquiry->RebuildFlag
+ == DAC960_V1_BackgroundCheckInProgress)
+ Controller->V1.NeedConsistencyCheckProgress = true;
+ Controller->MonitoringAlertMode =
+ (NewEnquiry->CriticalLogicalDriveCount > 0 ||
+ NewEnquiry->OfflineLogicalDriveCount > 0 ||
+ NewEnquiry->DeadDriveCount > 0);
if (CommandType != DAC960_MonitoringCommand &&
- Controller->RebuildFlagPending)
+ Controller->V1.RebuildFlagPending)
{
- DAC960_Enquiry_T *Enquiry = (DAC960_Enquiry_T *)
- Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress);
- Enquiry->RebuildFlag = Controller->PendingRebuildFlag;
- Controller->RebuildFlagPending = false;
+ DAC960_V1_Enquiry_T *Enquiry = (DAC960_V1_Enquiry_T *)
+ Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress);
+ Enquiry->RebuildFlag = Controller->V1.PendingRebuildFlag;
+ Controller->V1.RebuildFlagPending = false;
}
else if (CommandType == DAC960_MonitoringCommand &&
- NewEnquiry->RebuildFlag > DAC960_BackgroundCheckInProgress)
+ NewEnquiry->RebuildFlag >
+ DAC960_V1_BackgroundCheckInProgress)
{
- Controller->PendingRebuildFlag = NewEnquiry->RebuildFlag;
- Controller->RebuildFlagPending = true;
+ Controller->V1.PendingRebuildFlag = NewEnquiry->RebuildFlag;
+ Controller->V1.RebuildFlagPending = true;
}
+ memcpy(&Controller->V1.Enquiry, &Controller->V1.NewEnquiry,
+ sizeof(DAC960_V1_Enquiry_T));
}
- else if (CommandOpcode == DAC960_PerformEventLogOperation)
+ else if (CommandOpcode == DAC960_V1_PerformEventLogOperation)
{
static char
*DAC960_EventMessages[] =
@@ -2041,37 +3176,39 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
"killed because of selection timeout",
"killed due to SCSI phase sequence error",
"killed due to unknown status" };
- DAC960_EventLogEntry_T *EventLogEntry = &Controller->EventLogEntry;
+ DAC960_V1_EventLogEntry_T *EventLogEntry =
+ &Controller->V1.EventLogEntry;
if (EventLogEntry->SequenceNumber ==
- Controller->OldEventLogSequenceNumber)
+ Controller->V1.OldEventLogSequenceNumber)
{
unsigned char SenseKey = EventLogEntry->SenseKey;
unsigned char AdditionalSenseCode =
EventLogEntry->AdditionalSenseCode;
unsigned char AdditionalSenseCodeQualifier =
EventLogEntry->AdditionalSenseCodeQualifier;
- if (SenseKey == 9 &&
+ if (SenseKey == DAC960_SenseKey_VendorSpecific &&
AdditionalSenseCode == 0x80 &&
AdditionalSenseCodeQualifier <
sizeof(DAC960_EventMessages) / sizeof(char *))
- DAC960_Critical("Physical Drive %d:%d %s\n", Controller,
+ DAC960_Critical("Physical Device %d:%d %s\n", Controller,
EventLogEntry->Channel,
EventLogEntry->TargetID,
DAC960_EventMessages[
AdditionalSenseCodeQualifier]);
- else if (SenseKey == 6 && AdditionalSenseCode == 0x29)
+ else if (SenseKey == DAC960_SenseKey_UnitAttention &&
+ AdditionalSenseCode == 0x29)
{
if (Controller->MonitoringTimerCount > 0)
- Controller->DeviceResetCount[EventLogEntry->Channel]
- [EventLogEntry->TargetID]++;
+ Controller->V1.DeviceResetCount[EventLogEntry->Channel]
+ [EventLogEntry->TargetID]++;
}
- else if (!(SenseKey == 0 ||
- (SenseKey == 2 &&
+ else if (!(SenseKey == DAC960_SenseKey_NoSense ||
+ (SenseKey == DAC960_SenseKey_NotReady &&
AdditionalSenseCode == 0x04 &&
(AdditionalSenseCodeQualifier == 0x01 ||
AdditionalSenseCodeQualifier == 0x02))))
{
- DAC960_Critical("Physical Drive %d:%d Error Log: "
+ DAC960_Critical("Physical Device %d:%d Error Log: "
"Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
Controller,
EventLogEntry->Channel,
@@ -2079,7 +3216,7 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
SenseKey,
AdditionalSenseCode,
AdditionalSenseCodeQualifier);
- DAC960_Critical("Physical Drive %d:%d Error Log: "
+ DAC960_Critical("Physical Device %d:%d Error Log: "
"Information = %02X%02X%02X%02X "
"%02X%02X%02X%02X\n",
Controller,
@@ -2095,21 +3232,19 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
EventLogEntry->CommandSpecificInformation[3]);
}
}
- Controller->OldEventLogSequenceNumber++;
+ Controller->V1.OldEventLogSequenceNumber++;
}
- else if (CommandOpcode == DAC960_GetErrorTable)
+ else if (CommandOpcode == DAC960_V1_GetErrorTable)
{
- DAC960_ErrorTable_T *OldErrorTable =
- &Controller->ErrorTable[Controller->ErrorTableIndex];
- DAC960_ErrorTable_T *NewErrorTable =
- &Controller->ErrorTable[Controller->ErrorTableIndex ^= 1];
+ DAC960_V1_ErrorTable_T *OldErrorTable = &Controller->V1.ErrorTable;
+ DAC960_V1_ErrorTable_T *NewErrorTable = &Controller->V1.NewErrorTable;
int Channel, TargetID;
for (Channel = 0; Channel < Controller->Channels; Channel++)
- for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
+ for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
{
- DAC960_ErrorTableEntry_T *NewErrorEntry =
+ DAC960_V1_ErrorTableEntry_T *NewErrorEntry =
&NewErrorTable->ErrorTableEntries[Channel][TargetID];
- DAC960_ErrorTableEntry_T *OldErrorEntry =
+ DAC960_V1_ErrorTableEntry_T *OldErrorEntry =
&OldErrorTable->ErrorTableEntries[Channel][TargetID];
if ((NewErrorEntry->ParityErrorCount !=
OldErrorEntry->ParityErrorCount) ||
@@ -2119,7 +3254,7 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
OldErrorEntry->HardErrorCount) ||
(NewErrorEntry->MiscErrorCount !=
OldErrorEntry->MiscErrorCount))
- DAC960_Critical("Physical Drive %d:%d Errors: "
+ DAC960_Critical("Physical Device %d:%d Errors: "
"Parity = %d, Soft = %d, "
"Hard = %d, Misc = %d\n",
Controller, Channel, TargetID,
@@ -2128,51 +3263,49 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
NewErrorEntry->HardErrorCount,
NewErrorEntry->MiscErrorCount);
}
+ memcpy(&Controller->V1.ErrorTable, &Controller->V1.NewErrorTable,
+ sizeof(DAC960_V1_ErrorTable_T));
}
- else if (CommandOpcode == DAC960_GetDeviceState)
+ else if (CommandOpcode == DAC960_V1_GetDeviceState)
{
- DAC960_DeviceState_T *OldDeviceState =
- &Controller->DeviceState[Controller->DeviceStateIndex]
- [Controller->DeviceStateChannel]
- [Controller->DeviceStateTargetID];
- DAC960_DeviceState_T *NewDeviceState =
- &Controller->DeviceState[Controller->DeviceStateIndex ^ 1]
- [Controller->DeviceStateChannel]
- [Controller->DeviceStateTargetID];
+ DAC960_V1_DeviceState_T *OldDeviceState =
+ &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
+ [Controller->V1.DeviceStateTargetID];
+ DAC960_V1_DeviceState_T *NewDeviceState =
+ &Controller->V1.NewDeviceState;
if (NewDeviceState->DeviceState != OldDeviceState->DeviceState)
- DAC960_Critical("Physical Drive %d:%d is now %s\n", Controller,
- Controller->DeviceStateChannel,
- Controller->DeviceStateTargetID,
- (NewDeviceState->DeviceState == DAC960_Device_Dead
+ DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
+ Controller->V1.DeviceStateChannel,
+ Controller->V1.DeviceStateTargetID,
+ (NewDeviceState->DeviceState
+ == DAC960_V1_Device_Dead
? "DEAD"
: NewDeviceState->DeviceState
- == DAC960_Device_WriteOnly
+ == DAC960_V1_Device_WriteOnly
? "WRITE-ONLY"
: NewDeviceState->DeviceState
- == DAC960_Device_Online
+ == DAC960_V1_Device_Online
? "ONLINE" : "STANDBY"));
- if (OldDeviceState->DeviceState == DAC960_Device_Dead &&
- NewDeviceState->DeviceState != DAC960_Device_Dead)
+ if (OldDeviceState->DeviceState == DAC960_V1_Device_Dead &&
+ NewDeviceState->DeviceState != DAC960_V1_Device_Dead)
{
- Controller->NeedDeviceInquiryInformation = true;
- Controller->NeedDeviceSerialNumberInformation = true;
+ Controller->V1.NeedDeviceInquiryInformation = true;
+ Controller->V1.NeedDeviceSerialNumberInformation = true;
}
+ memcpy(OldDeviceState, NewDeviceState,
+ sizeof(DAC960_V1_DeviceState_T));
}
- else if (CommandOpcode == DAC960_GetLogicalDriveInformation)
+ else if (CommandOpcode == DAC960_V1_GetLogicalDriveInformation)
{
int LogicalDriveNumber;
for (LogicalDriveNumber = 0;
LogicalDriveNumber < Controller->LogicalDriveCount;
LogicalDriveNumber++)
{
- DAC960_LogicalDriveInformation_T *OldLogicalDriveInformation =
- &Controller->LogicalDriveInformation
- [Controller->LogicalDriveInformationIndex]
- [LogicalDriveNumber];
- DAC960_LogicalDriveInformation_T *NewLogicalDriveInformation =
- &Controller->LogicalDriveInformation
- [Controller->LogicalDriveInformationIndex ^ 1]
- [LogicalDriveNumber];
+ DAC960_V1_LogicalDriveInformation_T *OldLogicalDriveInformation =
+ &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
+ DAC960_V1_LogicalDriveInformation_T *NewLogicalDriveInformation =
+ &Controller->V1.NewLogicalDriveInformation[LogicalDriveNumber];
if (NewLogicalDriveInformation->LogicalDriveState !=
OldLogicalDriveInformation->LogicalDriveState)
DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -2181,11 +3314,11 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
Controller->ControllerNumber,
LogicalDriveNumber,
(NewLogicalDriveInformation->LogicalDriveState
- == DAC960_LogicalDrive_Online
+ == DAC960_V1_LogicalDrive_Online
? "ONLINE"
: NewLogicalDriveInformation->LogicalDriveState
- == DAC960_LogicalDrive_Critical
- ? "CRITICAL" : "OFFLINE"));
+ == DAC960_V1_LogicalDrive_Critical
+ ? "CRITICAL" : "OFFLINE"));
if (NewLogicalDriveInformation->WriteBack !=
OldLogicalDriveInformation->WriteBack)
DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -2196,22 +3329,24 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
(NewLogicalDriveInformation->WriteBack
? "WRITE BACK" : "WRITE THRU"));
}
- Controller->LogicalDriveInformationIndex ^= 1;
+ memcpy(&Controller->V1.LogicalDriveInformation,
+ &Controller->V1.NewLogicalDriveInformation,
+ sizeof(DAC960_V1_LogicalDriveInformationArray_T));
}
- else if (CommandOpcode == DAC960_GetRebuildProgress)
+ else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
{
unsigned int LogicalDriveNumber =
- Controller->RebuildProgress.LogicalDriveNumber;
+ Controller->V1.RebuildProgress.LogicalDriveNumber;
unsigned int LogicalDriveSize =
- Controller->RebuildProgress.LogicalDriveSize;
+ Controller->V1.RebuildProgress.LogicalDriveSize;
unsigned int BlocksCompleted =
- LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
- if (CommandStatus == DAC960_NoRebuildOrCheckInProgress &&
- Controller->LastRebuildStatus == DAC960_NormalCompletion)
- CommandStatus = DAC960_RebuildSuccessful;
+ LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
+ if (CommandStatus == DAC960_V1_NoRebuildOrCheckInProgress &&
+ Controller->V1.LastRebuildStatus == DAC960_V1_NormalCompletion)
+ CommandStatus = DAC960_V1_RebuildSuccessful;
switch (CommandStatus)
{
- case DAC960_NormalCompletion:
+ case DAC960_V1_NormalCompletion:
Controller->EphemeralProgressMessage = true;
DAC960_Progress("Rebuild in Progress: "
"Logical Drive %d (/dev/rd/c%dd%d) "
@@ -2223,51 +3358,51 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
/ (LogicalDriveSize >> 7));
Controller->EphemeralProgressMessage = false;
break;
- case DAC960_RebuildFailed_LogicalDriveFailure:
+ case DAC960_V1_RebuildFailed_LogicalDriveFailure:
DAC960_Progress("Rebuild Failed due to "
"Logical Drive Failure\n", Controller);
break;
- case DAC960_RebuildFailed_BadBlocksOnOther:
+ case DAC960_V1_RebuildFailed_BadBlocksOnOther:
DAC960_Progress("Rebuild Failed due to "
"Bad Blocks on Other Drives\n", Controller);
break;
- case DAC960_RebuildFailed_NewDriveFailed:
+ case DAC960_V1_RebuildFailed_NewDriveFailed:
DAC960_Progress("Rebuild Failed due to "
"Failure of Drive Being Rebuilt\n", Controller);
break;
- case DAC960_NoRebuildOrCheckInProgress:
+ case DAC960_V1_NoRebuildOrCheckInProgress:
break;
- case DAC960_RebuildSuccessful:
+ case DAC960_V1_RebuildSuccessful:
DAC960_Progress("Rebuild Completed Successfully\n", Controller);
break;
- case DAC960_RebuildSuccessfullyTerminated:
+ case DAC960_V1_RebuildSuccessfullyTerminated:
DAC960_Progress("Rebuild Successfully Terminated\n", Controller);
break;
}
- Controller->LastRebuildStatus = CommandStatus;
+ Controller->V1.LastRebuildStatus = CommandStatus;
if (CommandType != DAC960_MonitoringCommand &&
- Controller->RebuildStatusPending)
+ Controller->V1.RebuildStatusPending)
{
- Command->CommandStatus = Controller->PendingRebuildStatus;
- Controller->RebuildStatusPending = false;
+ Command->V1.CommandStatus = Controller->V1.PendingRebuildStatus;
+ Controller->V1.RebuildStatusPending = false;
}
else if (CommandType == DAC960_MonitoringCommand &&
- CommandStatus != DAC960_NormalCompletion &&
- CommandStatus != DAC960_NoRebuildOrCheckInProgress)
+ CommandStatus != DAC960_V1_NormalCompletion &&
+ CommandStatus != DAC960_V1_NoRebuildOrCheckInProgress)
{
- Controller->PendingRebuildStatus = CommandStatus;
- Controller->RebuildStatusPending = true;
+ Controller->V1.PendingRebuildStatus = CommandStatus;
+ Controller->V1.RebuildStatusPending = true;
}
}
- else if (CommandOpcode == DAC960_RebuildStat)
+ else if (CommandOpcode == DAC960_V1_RebuildStat)
{
unsigned int LogicalDriveNumber =
- Controller->RebuildProgress.LogicalDriveNumber;
+ Controller->V1.RebuildProgress.LogicalDriveNumber;
unsigned int LogicalDriveSize =
- Controller->RebuildProgress.LogicalDriveSize;
+ Controller->V1.RebuildProgress.LogicalDriveSize;
unsigned int BlocksCompleted =
- LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
- if (CommandStatus == DAC960_NormalCompletion)
+ LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
+ if (CommandStatus == DAC960_V1_NormalCompletion)
{
Controller->EphemeralProgressMessage = true;
DAC960_Progress("Consistency Check in Progress: "
@@ -2284,62 +3419,60 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
}
if (CommandType == DAC960_MonitoringCommand)
{
- if (Controller->NewEventLogSequenceNumber
- - Controller->OldEventLogSequenceNumber > 0)
- {
- Command->CommandMailbox.Type3E.CommandOpcode =
- DAC960_PerformEventLogOperation;
- Command->CommandMailbox.Type3E.OperationType =
- DAC960_GetEventLogEntry;
- Command->CommandMailbox.Type3E.OperationQualifier = 1;
- Command->CommandMailbox.Type3E.SequenceNumber =
- Controller->OldEventLogSequenceNumber;
- Command->CommandMailbox.Type3E.BusAddress =
- Virtual_to_Bus(&Controller->EventLogEntry);
+ if (Controller->V1.NewEventLogSequenceNumber
+ - Controller->V1.OldEventLogSequenceNumber > 0)
+ {
+ Command->V1.CommandMailbox.Type3E.CommandOpcode =
+ DAC960_V1_PerformEventLogOperation;
+ Command->V1.CommandMailbox.Type3E.OperationType =
+ DAC960_V1_GetEventLogEntry;
+ Command->V1.CommandMailbox.Type3E.OperationQualifier = 1;
+ Command->V1.CommandMailbox.Type3E.SequenceNumber =
+ Controller->V1.OldEventLogSequenceNumber;
+ Command->V1.CommandMailbox.Type3E.BusAddress =
+ Virtual_to_Bus(&Controller->V1.EventLogEntry);
DAC960_QueueCommand(Command);
return;
}
- if (Controller->NeedErrorTableInformation)
+ if (Controller->V1.NeedErrorTableInformation)
{
- Controller->NeedErrorTableInformation = false;
- Command->CommandMailbox.Type3.CommandOpcode = DAC960_GetErrorTable;
- Command->CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus(
- &Controller->ErrorTable[Controller->ErrorTableIndex ^ 1]);
+ Controller->V1.NeedErrorTableInformation = false;
+ Command->V1.CommandMailbox.Type3.CommandOpcode =
+ DAC960_V1_GetErrorTable;
+ Command->V1.CommandMailbox.Type3.BusAddress =
+ Virtual_to_Bus(&Controller->V1.NewErrorTable);
DAC960_QueueCommand(Command);
return;
}
- if (Controller->NeedRebuildProgress &&
- Controller->Enquiry[Controller->EnquiryIndex]
- .CriticalLogicalDriveCount <
- Controller->Enquiry[Controller->EnquiryIndex ^ 1]
- .CriticalLogicalDriveCount)
- {
- Controller->NeedRebuildProgress = false;
- Command->CommandMailbox.Type3.CommandOpcode =
- DAC960_GetRebuildProgress;
- Command->CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus(&Controller->RebuildProgress);
+ if (Controller->V1.NeedRebuildProgress &&
+ Controller->V1.RebuildProgressFirst)
+ {
+ Controller->V1.NeedRebuildProgress = false;
+ Command->V1.CommandMailbox.Type3.CommandOpcode =
+ DAC960_V1_GetRebuildProgress;
+ Command->V1.CommandMailbox.Type3.BusAddress =
+ Virtual_to_Bus(&Controller->V1.RebuildProgress);
DAC960_QueueCommand(Command);
return;
}
- if (Controller->NeedDeviceStateInformation)
+ if (Controller->V1.NeedDeviceStateInformation)
{
- if (Controller->NeedDeviceInquiryInformation)
+ if (Controller->V1.NeedDeviceInquiryInformation)
{
- DAC960_DCDB_T *DCDB = &Controller->MonitoringDCDB;
+ DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
DAC960_SCSI_Inquiry_T *InquiryStandardData =
- &Controller->InquiryStandardData
- [Controller->DeviceStateChannel]
- [Controller->DeviceStateTargetID];
+ &Controller->V1.InquiryStandardData
+ [Controller->V1.DeviceStateChannel]
+ [Controller->V1.DeviceStateTargetID];
InquiryStandardData->PeripheralDeviceType = 0x1F;
- Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
- Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
- DCDB->Channel = Controller->DeviceStateChannel;
- DCDB->TargetID = Controller->DeviceStateTargetID;
- DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
+ Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
+ Command->V1.CommandMailbox.Type3.BusAddress =
+ Virtual_to_Bus(DCDB);
+ DCDB->Channel = Controller->V1.DeviceStateChannel;
+ DCDB->TargetID = Controller->V1.DeviceStateTargetID;
+ DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
DCDB->EarlyStatus = false;
- DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
+ DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
DCDB->NoAutomaticRequestSense = false;
DCDB->DisconnectPermitted = true;
DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
@@ -2354,24 +3487,25 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
DCDB->CDB[5] = 0; /* Control */
DAC960_QueueCommand(Command);
- Controller->NeedDeviceInquiryInformation = false;
+ Controller->V1.NeedDeviceInquiryInformation = false;
return;
}
- if (Controller->NeedDeviceSerialNumberInformation)
+ if (Controller->V1.NeedDeviceSerialNumberInformation)
{
- DAC960_DCDB_T *DCDB = &Controller->MonitoringDCDB;
+ DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
- &Controller->InquiryUnitSerialNumber
- [Controller->DeviceStateChannel]
- [Controller->DeviceStateTargetID];
+ &Controller->V1.InquiryUnitSerialNumber
+ [Controller->V1.DeviceStateChannel]
+ [Controller->V1.DeviceStateTargetID];
InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
- Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
- Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
- DCDB->Channel = Controller->DeviceStateChannel;
- DCDB->TargetID = Controller->DeviceStateTargetID;
- DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
+ Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
+ Command->V1.CommandMailbox.Type3.BusAddress =
+ Virtual_to_Bus(DCDB);
+ DCDB->Channel = Controller->V1.DeviceStateChannel;
+ DCDB->TargetID = Controller->V1.DeviceStateTargetID;
+ DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
DCDB->EarlyStatus = false;
- DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
+ DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
DCDB->NoAutomaticRequestSense = false;
DCDB->DisconnectPermitted = true;
DCDB->TransferLength =
@@ -2387,74 +3521,68 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
DCDB->CDB[5] = 0; /* Control */
DAC960_QueueCommand(Command);
- Controller->NeedDeviceSerialNumberInformation = false;
+ Controller->V1.NeedDeviceSerialNumberInformation = false;
return;
}
- if (++Controller->DeviceStateTargetID == DAC960_MaxTargets)
+ if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
{
- Controller->DeviceStateChannel++;
- Controller->DeviceStateTargetID = 0;
+ Controller->V1.DeviceStateChannel++;
+ Controller->V1.DeviceStateTargetID = 0;
}
- while (Controller->DeviceStateChannel < Controller->Channels)
+ while (Controller->V1.DeviceStateChannel < Controller->Channels)
{
- DAC960_DeviceState_T *OldDeviceState =
- &Controller->DeviceState[Controller->DeviceStateIndex]
- [Controller->DeviceStateChannel]
- [Controller->DeviceStateTargetID];
+ DAC960_V1_DeviceState_T *OldDeviceState =
+ &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
+ [Controller->V1.DeviceStateTargetID];
if (OldDeviceState->Present &&
- OldDeviceState->DeviceType == DAC960_DiskType)
+ OldDeviceState->DeviceType == DAC960_V1_DiskType)
{
- Command->CommandMailbox.Type3D.CommandOpcode =
- DAC960_GetDeviceState;
- Command->CommandMailbox.Type3D.Channel =
- Controller->DeviceStateChannel;
- Command->CommandMailbox.Type3D.TargetID =
- Controller->DeviceStateTargetID;
- Command->CommandMailbox.Type3D.BusAddress =
- Virtual_to_Bus(&Controller->DeviceState
- [Controller->DeviceStateIndex ^ 1]
- [Controller->DeviceStateChannel]
- [Controller->DeviceStateTargetID]);
+ Command->V1.CommandMailbox.Type3D.CommandOpcode =
+ DAC960_V1_GetDeviceState;
+ Command->V1.CommandMailbox.Type3D.Channel =
+ Controller->V1.DeviceStateChannel;
+ Command->V1.CommandMailbox.Type3D.TargetID =
+ Controller->V1.DeviceStateTargetID;
+ Command->V1.CommandMailbox.Type3D.BusAddress =
+ Virtual_to_Bus(&Controller->V1.NewDeviceState);
DAC960_QueueCommand(Command);
return;
}
- if (++Controller->DeviceStateTargetID == DAC960_MaxTargets)
+ if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
{
- Controller->DeviceStateChannel++;
- Controller->DeviceStateTargetID = 0;
+ Controller->V1.DeviceStateChannel++;
+ Controller->V1.DeviceStateTargetID = 0;
}
}
- Controller->NeedDeviceStateInformation = false;
- Controller->DeviceStateIndex ^= 1;
- }
- if (Controller->NeedLogicalDriveInformation)
- {
- Controller->NeedLogicalDriveInformation = false;
- Command->CommandMailbox.Type3.CommandOpcode =
- DAC960_GetLogicalDriveInformation;
- Command->CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus(
- &Controller->LogicalDriveInformation
- [Controller->LogicalDriveInformationIndex ^ 1]);
+ Controller->V1.NeedDeviceStateInformation = false;
+ }
+ if (Controller->V1.NeedLogicalDriveInformation)
+ {
+ Controller->V1.NeedLogicalDriveInformation = false;
+ Command->V1.CommandMailbox.Type3.CommandOpcode =
+ DAC960_V1_GetLogicalDriveInformation;
+ Command->V1.CommandMailbox.Type3.BusAddress =
+ Virtual_to_Bus(&Controller->V1.NewLogicalDriveInformation);
DAC960_QueueCommand(Command);
return;
}
- if (Controller->NeedRebuildProgress)
+ if (Controller->V1.NeedRebuildProgress)
{
- Controller->NeedRebuildProgress = false;
- Command->CommandMailbox.Type3.CommandOpcode =
- DAC960_GetRebuildProgress;
- Command->CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus(&Controller->RebuildProgress);
+ Controller->V1.NeedRebuildProgress = false;
+ Command->V1.CommandMailbox.Type3.CommandOpcode =
+ DAC960_V1_GetRebuildProgress;
+ Command->V1.CommandMailbox.Type3.BusAddress =
+ Virtual_to_Bus(&Controller->V1.RebuildProgress);
DAC960_QueueCommand(Command);
return;
}
- if (Controller->NeedConsistencyCheckProgress)
+ if (Controller->V1.NeedConsistencyCheckProgress)
{
- Controller->NeedConsistencyCheckProgress = false;
- Command->CommandMailbox.Type3.CommandOpcode = DAC960_RebuildStat;
- Command->CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus(&Controller->RebuildProgress);
+ Controller->V1.NeedConsistencyCheckProgress = false;
+ Command->V1.CommandMailbox.Type3.CommandOpcode =
+ DAC960_V1_RebuildStat;
+ Command->V1.CommandMailbox.Type3.BusAddress =
+ Virtual_to_Bus(&Controller->V1.RebuildProgress);
DAC960_QueueCommand(Command);
return;
}
@@ -2471,12 +3599,835 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
}
if (CommandType == DAC960_QueuedCommand)
{
- DAC960_KernelCommand_T *KernelCommand = Command->KernelCommand;
- KernelCommand->CommandStatus = Command->CommandStatus;
- Command->KernelCommand = NULL;
- if (CommandOpcode == DAC960_DCDB)
- Controller->DirectCommandActive[KernelCommand->DCDB->Channel]
- [KernelCommand->DCDB->TargetID] = false;
+ DAC960_V1_KernelCommand_T *KernelCommand = Command->V1.KernelCommand;
+ KernelCommand->CommandStatus = Command->V1.CommandStatus;
+ Command->V1.KernelCommand = NULL;
+ if (CommandOpcode == DAC960_V1_DCDB)
+ Controller->V1.DirectCommandActive[KernelCommand->DCDB->Channel]
+ [KernelCommand->DCDB->TargetID] =
+ false;
+ DAC960_DeallocateCommand(Command);
+ KernelCommand->CompletionFunction(KernelCommand);
+ return;
+ }
+ /*
+ Queue a Status Monitoring Command to the Controller using the just
+ completed Command if one was deferred previously due to lack of a
+ free Command when the Monitoring Timer Function was called.
+ */
+ if (Controller->MonitoringCommandDeferred)
+ {
+ Controller->MonitoringCommandDeferred = false;
+ DAC960_V1_QueueMonitoringCommand(Command);
+ return;
+ }
+ /*
+ Deallocate the Command.
+ */
+ DAC960_DeallocateCommand(Command);
+ /*
+ Wake up any processes waiting on a free Command.
+ */
+ wake_up(&Controller->CommandWaitQueue);
+}
+
+
+/*
+ DAC960_V2_ReadWriteError prints an appropriate error message for Command
+ when an error occurs on a Read or Write operation.
+*/
+
+static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ unsigned char *SenseErrors[] = { "NO SENSE", "RECOVERED ERROR",
+ "NOT READY", "MEDIUM ERROR",
+ "HARDWARE ERROR", "ILLEGAL REQUEST",
+ "UNIT ATTENTION", "DATA PROTECT",
+ "BLANK CHECK", "VENDOR-SPECIFIC",
+ "COPY ABORTED", "ABORTED COMMAND",
+ "EQUAL", "VOLUME OVERFLOW",
+ "MISCOMPARE", "RESERVED" };
+ unsigned char *CommandName = "UNKNOWN";
+ switch (Command->CommandType)
+ {
+ case DAC960_ReadCommand:
+ case DAC960_ReadRetryCommand:
+ CommandName = "READ";
+ break;
+ case DAC960_WriteCommand:
+ case DAC960_WriteRetryCommand:
+ CommandName = "WRITE";
+ break;
+ case DAC960_MonitoringCommand:
+ case DAC960_ImmediateCommand:
+ case DAC960_QueuedCommand:
+ break;
+ }
+ 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",
+ 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",
+ Controller, Controller->ControllerNumber,
+ Command->LogicalDriveNumber,
+ DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
+ Command->BufferHeader->b_rsector,
+ Command->BufferHeader->b_rsector + Command->BlockCount - 1);
+}
+
+
+/*
+ DAC960_V2_ReportEvent prints an appropriate message when a Controller Event
+ occurs.
+*/
+
+static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
+ DAC960_V2_Event_T *Event)
+{
+ DAC960_SCSI_RequestSense_T *RequestSense =
+ (DAC960_SCSI_RequestSense_T *) &Event->RequestSenseData;
+ unsigned char MessageBuffer[DAC960_LineBufferSize];
+ static struct { int EventCode; unsigned char *EventMessage; } EventList[] =
+ { /* Physical Device Events (0x0000 - 0x007F) */
+ { 0x0001, "P Online" },
+ { 0x0002, "P Standby" },
+ { 0x0005, "P Automatic Rebuild Started" },
+ { 0x0006, "P Manual Rebuild Started" },
+ { 0x0007, "P Rebuild Completed" },
+ { 0x0008, "P Rebuild Cancelled" },
+ { 0x0009, "P Rebuild Failed for Unknown Reasons" },
+ { 0x000A, "P Rebuild Failed due to New Physical Device" },
+ { 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
+ { 0x000C, "S Offline" },
+ { 0x000D, "P Found" },
+ { 0x000E, "P Gone" },
+ { 0x000F, "P Unconfigured" },
+ { 0x0010, "P Expand Capacity Started" },
+ { 0x0011, "P Expand Capacity Completed" },
+ { 0x0012, "P Expand Capacity Failed" },
+ { 0x0016, "P Parity Error" },
+ { 0x0017, "P Soft Error" },
+ { 0x0018, "P Miscellaneous Error" },
+ { 0x0019, "P Reset" },
+ { 0x001A, "P Active Spare Found" },
+ { 0x001B, "P Warm Spare Found" },
+ { 0x001C, "S Sense Data Received" },
+ { 0x001D, "P Initialization Started" },
+ { 0x001E, "P Initialization Completed" },
+ { 0x001F, "P Initialization Failed" },
+ { 0x0020, "P Initialization Cancelled" },
+ { 0x0021, "P Failed because Write Recovery Failed" },
+ { 0x0022, "P Failed because SCSI Bus Reset Failed" },
+ { 0x0023, "P Failed because of Double Check Condition" },
+ { 0x0024, "P Failed because Device Cannot Be Accessed" },
+ { 0x0025, "P Failed because of Gross Error on SCSI Processor" },
+ { 0x0026, "P Failed because of Bad Tag from Device" },
+ { 0x0027, "P Failed because of Command Timeout" },
+ { 0x0028, "P Failed because of System Reset" },
+ { 0x0029, "P Failed because of Busy Status or Parity Error" },
+ { 0x002A, "P Failed because Host Set Device to Failed State" },
+ { 0x002B, "P Failed because of Selection Timeout" },
+ { 0x002C, "P Failed because of SCSI Bus Phase Error" },
+ { 0x002D, "P Failed because Device Returned Unknown Status" },
+ { 0x002E, "P Failed because Device Not Ready" },
+ { 0x002F, "P Failed because Device Not Found at Startup" },
+ { 0x0030, "P Failed because COD Write Operation Failed" },
+ { 0x0031, "P Failed because BDT Write Operation Failed" },
+ { 0x0039, "P Missing at Startup" },
+ { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
+ /* Logical Device Events (0x0080 - 0x00FF) */
+ { 0x0080, "M Consistency Check Started" },
+ { 0x0081, "M Consistency Check Completed" },
+ { 0x0082, "M Consistency Check Cancelled" },
+ { 0x0083, "M Consistency Check Completed With Errors" },
+ { 0x0084, "M Consistency Check Failed due to Logical Drive Failure" },
+ { 0x0085, "M Consistency Check Failed due to Physical Device Failure" },
+ { 0x0086, "L Offline" },
+ { 0x0087, "L Critical" },
+ { 0x0088, "L Online" },
+ { 0x0089, "M Automatic Rebuild Started" },
+ { 0x008A, "M Manual Rebuild Started" },
+ { 0x008B, "M Rebuild Completed" },
+ { 0x008C, "M Rebuild Cancelled" },
+ { 0x008D, "M Rebuild Failed for Unknown Reasons" },
+ { 0x008E, "M Rebuild Failed due to New Physical Device" },
+ { 0x008F, "M Rebuild Failed due to Logical Drive Failure" },
+ { 0x0090, "L Initialization Started" },
+ { 0x0091, "L Initialization Completed" },
+ { 0x0092, "L Initialization Cancelled" },
+ { 0x0093, "L Initialization Failed" },
+ { 0x0094, "L Found" },
+ { 0x0095, "L Gone" },
+ { 0x0096, "L Expand Capacity Started" },
+ { 0x0097, "L Expand Capacity Completed" },
+ { 0x0098, "L Expand Capacity Failed" },
+ { 0x0099, "L Bad Block Found" },
+ { 0x009A, "L Size Changed" },
+ { 0x009B, "L Type Changed" },
+ { 0x009C, "L Bad Data Block Found" },
+ { 0x009E, "L Read of Data Block in BDT" },
+ { 0x009F, "L Write Back Data for Disk Block Lost" },
+ /* Fault Management Events (0x0100 - 0x017F) */
+ { 0x0140, "E Fan %d Failed" },
+ { 0x0141, "E Fan %d OK" },
+ { 0x0142, "E Fan %d Not Present" },
+ { 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" },
+ { 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" },
+ /* 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" },
+ { 0x01A2, "C Battery Backup Unit Failed" },
+ { 0, "" } };
+ int EventListIndex = 0, EventCode;
+ unsigned char EventType, *EventMessage;
+ while (true)
+ {
+ EventCode = EventList[EventListIndex].EventCode;
+ if (EventCode == Event->EventCode || EventCode == 0) break;
+ EventListIndex++;
+ }
+ EventType = EventList[EventListIndex].EventMessage[0];
+ EventMessage = &EventList[EventListIndex].EventMessage[2];
+ if (EventCode == 0)
+ {
+ DAC960_Critical("Unknown Controller Event Code %04X\n",
+ Controller, Event->EventCode);
+ return;
+ }
+ switch (EventType)
+ {
+ case 'P':
+ DAC960_Critical("Physical Device %d:%d %s\n", Controller,
+ Event->Channel, Event->TargetID, EventMessage);
+ break;
+ case 'L':
+ DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller,
+ Event->LogicalUnit, Controller->ControllerNumber,
+ Event->LogicalUnit, EventMessage);
+ break;
+ case 'M':
+ DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller,
+ Event->LogicalUnit, Controller->ControllerNumber,
+ Event->LogicalUnit, EventMessage);
+ break;
+ case 'S':
+ if (RequestSense->SenseKey == DAC960_SenseKey_NoSense ||
+ (RequestSense->SenseKey == DAC960_SenseKey_NotReady &&
+ RequestSense->AdditionalSenseCode == 0x04 &&
+ (RequestSense->AdditionalSenseCodeQualifier == 0x01 ||
+ RequestSense->AdditionalSenseCodeQualifier == 0x02)))
+ break;
+ 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",
+ Controller,
+ Event->Channel,
+ Event->TargetID,
+ RequestSense->SenseKey,
+ RequestSense->AdditionalSenseCode,
+ RequestSense->AdditionalSenseCodeQualifier);
+ DAC960_Critical("Physical Device %d:%d Request Sense: "
+ "Information = %02X%02X%02X%02X "
+ "%02X%02X%02X%02X\n",
+ Controller,
+ Event->Channel,
+ Event->TargetID,
+ RequestSense->Information[0],
+ RequestSense->Information[1],
+ RequestSense->Information[2],
+ RequestSense->Information[3],
+ RequestSense->CommandSpecificInformation[0],
+ RequestSense->CommandSpecificInformation[1],
+ RequestSense->CommandSpecificInformation[2],
+ RequestSense->CommandSpecificInformation[3]);
+ break;
+ case 'E':
+ sprintf(MessageBuffer, EventMessage, Event->LogicalUnit);
+ DAC960_Critical("Enclosure %d %s\n", Controller,
+ Event->TargetID, MessageBuffer);
+ break;
+ case 'C':
+ DAC960_Critical("Controller %s\n", Controller, EventMessage);
+ break;
+ default:
+ DAC960_Critical("Unknown Controller Event Code %04X\n",
+ Controller, Event->EventCode);
+ break;
+ }
+}
+
+
+/*
+ DAC960_V2_ReportProgress prints an appropriate progress message for
+ Logical Device Long Operations.
+*/
+
+static void DAC960_V2_ReportProgress(DAC960_Controller_T *Controller,
+ unsigned char *MessageString,
+ unsigned int LogicalDeviceNumber,
+ unsigned long BlocksCompleted,
+ unsigned long LogicalDeviceSize)
+{
+ Controller->EphemeralProgressMessage = true;
+ DAC960_Progress("%s in Progress: Logical Drive %d (/dev/rd/c%dd%d) "
+ "%d%% completed\n", Controller,
+ MessageString,
+ LogicalDeviceNumber,
+ Controller->ControllerNumber,
+ LogicalDeviceNumber,
+ (100 * (BlocksCompleted >> 7)) / (LogicalDeviceSize >> 7));
+ Controller->EphemeralProgressMessage = false;
+}
+
+
+/*
+ DAC960_V2_ProcessCompletedCommand performs completion processing for Command
+ for DAC960 V2 Firmware Controllers.
+*/
+
+static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ DAC960_CommandType_T CommandType = Command->CommandType;
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode;
+ DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus;
+ BufferHeader_T *BufferHeader = Command->BufferHeader;
+ if (CommandType == DAC960_ReadCommand ||
+ CommandType == DAC960_WriteCommand)
+ {
+ if (CommandStatus == DAC960_V2_NormalCompletion)
+ {
+ /*
+ Perform completion processing for all buffers in this I/O Request.
+ */
+ while (BufferHeader != NULL)
+ {
+ BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
+ BufferHeader->b_reqnext = NULL;
+ DAC960_ProcessCompletedBuffer(BufferHeader, true);
+ BufferHeader = NextBufferHeader;
+ }
+ /*
+ Wake up requestor for swap file paging requests.
+ */
+ if (Command->Semaphore != NULL)
+ {
+ up(Command->Semaphore);
+ Command->Semaphore = NULL;
+ }
+ add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
+ }
+ else if (Command->V2.RequestSense.SenseKey
+ == DAC960_SenseKey_MediumError &&
+ BufferHeader != NULL &&
+ BufferHeader->b_reqnext != NULL)
+ {
+ if (CommandType == DAC960_ReadCommand)
+ Command->CommandType = DAC960_ReadRetryCommand;
+ else Command->CommandType = DAC960_WriteRetryCommand;
+ Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
+ CommandMailbox->SCSI_10.CommandControlBits
+ .AdditionalScatterGatherListMemory = false;
+ CommandMailbox->SCSI_10.DataTransferSize =
+ Command->BlockCount << DAC960_BlockSizeBits;
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0].SegmentDataPointer =
+ Virtual_to_Bus(BufferHeader->b_data);
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0].SegmentByteCount =
+ CommandMailbox->SCSI_10.DataTransferSize;
+ CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
+ CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
+ DAC960_QueueCommand(Command);
+ return;
+ }
+ else
+ {
+ if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
+ DAC960_V2_ReadWriteError(Command);
+ /*
+ Perform completion processing for all buffers in this I/O Request.
+ */
+ while (BufferHeader != NULL)
+ {
+ BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
+ BufferHeader->b_reqnext = NULL;
+ DAC960_ProcessCompletedBuffer(BufferHeader, false);
+ BufferHeader = NextBufferHeader;
+ }
+ /*
+ Wake up requestor for swap file paging requests.
+ */
+ if (Command->Semaphore != NULL)
+ {
+ up(Command->Semaphore);
+ Command->Semaphore = NULL;
+ }
+ }
+ }
+ else if (CommandType == DAC960_ReadRetryCommand ||
+ CommandType == DAC960_WriteRetryCommand)
+ {
+ BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
+ BufferHeader->b_reqnext = NULL;
+ /*
+ Perform completion processing for this single buffer.
+ */
+ if (CommandStatus == DAC960_V2_NormalCompletion)
+ DAC960_ProcessCompletedBuffer(BufferHeader, true);
+ else
+ {
+ if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
+ DAC960_V2_ReadWriteError(Command);
+ DAC960_ProcessCompletedBuffer(BufferHeader, false);
+ }
+ if (NextBufferHeader != NULL)
+ {
+ Command->BlockNumber +=
+ BufferHeader->b_size >> DAC960_BlockSizeBits;
+ Command->BlockCount =
+ NextBufferHeader->b_size >> DAC960_BlockSizeBits;
+ Command->BufferHeader = NextBufferHeader;
+ CommandMailbox->SCSI_10.DataTransferSize =
+ Command->BlockCount << DAC960_BlockSizeBits;
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(NextBufferHeader->b_data);
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->SCSI_10.DataTransferSize;
+ CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
+ CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
+ CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
+ CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
+ CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
+ CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
+ DAC960_QueueCommand(Command);
+ return;
+ }
+ }
+ else if (CommandType == DAC960_MonitoringCommand)
+ {
+ if (CommandOpcode == DAC960_V2_GetControllerInfo)
+ {
+ DAC960_V2_ControllerInfo_T *NewControllerInfo =
+ &Controller->V2.NewControllerInformation;
+ DAC960_V2_ControllerInfo_T *ControllerInfo =
+ &Controller->V2.ControllerInformation;
+ Controller->LogicalDriveCount =
+ NewControllerInfo->LogicalDevicesPresent;
+ Controller->V2.NeedLogicalDeviceInformation = true;
+ Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber = 0;
+ Controller->V2.NeedPhysicalDeviceInformation = true;
+ Controller->V2.PhysicalDeviceIndex = 0;
+ Controller->V2.NewPhysicalDeviceInformation.Channel = 0;
+ Controller->V2.NewPhysicalDeviceInformation.TargetID = 0;
+ Controller->V2.NewPhysicalDeviceInformation.LogicalUnit = 0;
+ Controller->MonitoringAlertMode =
+ (NewControllerInfo->LogicalDevicesCritical > 0 ||
+ NewControllerInfo->LogicalDevicesOffline > 0 ||
+ NewControllerInfo->PhysicalDisksCritical > 0 ||
+ NewControllerInfo->PhysicalDisksOffline > 0);
+ memcpy(ControllerInfo, NewControllerInfo,
+ sizeof(DAC960_V2_ControllerInfo_T));
+ }
+ else if (CommandOpcode == DAC960_V2_GetEvent)
+ {
+ if (CommandStatus == DAC960_V2_NormalCompletion)
+ DAC960_V2_ReportEvent(Controller, &Controller->V2.Event);
+ Controller->V2.NextEventSequenceNumber++;
+ }
+ else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
+ CommandStatus == DAC960_V2_NormalCompletion)
+ {
+ DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
+ &Controller->V2.NewPhysicalDeviceInformation;
+ unsigned int PhysicalDeviceIndex = Controller->V2.PhysicalDeviceIndex;
+ DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
+ Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
+ if (PhysicalDeviceInfo == NULL ||
+ (NewPhysicalDeviceInfo->Channel !=
+ PhysicalDeviceInfo->Channel) ||
+ (NewPhysicalDeviceInfo->TargetID !=
+ PhysicalDeviceInfo->TargetID) ||
+ (NewPhysicalDeviceInfo->LogicalUnit !=
+ PhysicalDeviceInfo->LogicalUnit))
+ {
+ unsigned int DeviceIndex;
+ PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
+ kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
+ InquiryUnitSerialNumber =
+ (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
+ kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
+ GFP_ATOMIC);
+ if (InquiryUnitSerialNumber == NULL)
+ {
+ kfree(PhysicalDeviceInfo);
+ PhysicalDeviceInfo = NULL;
+ }
+ DAC960_Critical("Physical Device %d:%d Now Exists%s\n",
+ Controller,
+ NewPhysicalDeviceInfo->Channel,
+ NewPhysicalDeviceInfo->TargetID,
+ (PhysicalDeviceInfo != NULL
+ ? "" : " - Allocation Failed"));
+ if (PhysicalDeviceInfo != NULL)
+ {
+ for (DeviceIndex = PhysicalDeviceIndex;
+ DeviceIndex < DAC960_V2_MaxPhysicalDevices - 1;
+ DeviceIndex++)
+ {
+ Controller->V2.PhysicalDeviceInformation[DeviceIndex+1] =
+ Controller->V2.PhysicalDeviceInformation[DeviceIndex];
+ Controller->V2.InquiryUnitSerialNumber[DeviceIndex+1] =
+ Controller->V2.InquiryUnitSerialNumber[DeviceIndex];
+ Controller->V2.PhysicalDeviceInformation
+ [PhysicalDeviceIndex] =
+ PhysicalDeviceInfo;
+ Controller->V2.InquiryUnitSerialNumber
+ [PhysicalDeviceIndex] =
+ InquiryUnitSerialNumber;
+ }
+ memset(PhysicalDeviceInfo, 0,
+ sizeof(DAC960_V2_PhysicalDeviceInfo_T));
+ PhysicalDeviceInfo->PhysicalDeviceState =
+ DAC960_V2_Device_InvalidState;
+ memset(InquiryUnitSerialNumber, 0,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+ InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+ Controller->V2.NeedDeviceSerialNumberInformation = true;
+ }
+ }
+ if (PhysicalDeviceInfo != NULL)
+ {
+ 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"));
+ if ((NewPhysicalDeviceInfo->ParityErrors !=
+ PhysicalDeviceInfo->ParityErrors) ||
+ (NewPhysicalDeviceInfo->SoftErrors !=
+ PhysicalDeviceInfo->SoftErrors) ||
+ (NewPhysicalDeviceInfo->HardErrors !=
+ PhysicalDeviceInfo->HardErrors) ||
+ (NewPhysicalDeviceInfo->MiscellaneousErrors !=
+ PhysicalDeviceInfo->MiscellaneousErrors) ||
+ (NewPhysicalDeviceInfo->CommandTimeouts !=
+ PhysicalDeviceInfo->CommandTimeouts) ||
+ (NewPhysicalDeviceInfo->Retries !=
+ PhysicalDeviceInfo->Retries) ||
+ (NewPhysicalDeviceInfo->Aborts !=
+ PhysicalDeviceInfo->Aborts) ||
+ (NewPhysicalDeviceInfo->PredictedFailuresDetected !=
+ PhysicalDeviceInfo->PredictedFailuresDetected))
+ {
+ DAC960_Critical("Physical Device %d:%d Errors: "
+ "Parity = %d, Soft = %d, "
+ "Hard = %d, Misc = %d\n",
+ Controller,
+ NewPhysicalDeviceInfo->Channel,
+ NewPhysicalDeviceInfo->TargetID,
+ NewPhysicalDeviceInfo->ParityErrors,
+ NewPhysicalDeviceInfo->SoftErrors,
+ NewPhysicalDeviceInfo->HardErrors,
+ NewPhysicalDeviceInfo->MiscellaneousErrors);
+ DAC960_Critical("Physical Device %d:%d Errors: "
+ "Timeouts = %d, Retries = %d, "
+ "Aborts = %d, Predicted = %d\n",
+ Controller,
+ NewPhysicalDeviceInfo->Channel,
+ NewPhysicalDeviceInfo->TargetID,
+ NewPhysicalDeviceInfo->CommandTimeouts,
+ NewPhysicalDeviceInfo->Retries,
+ NewPhysicalDeviceInfo->Aborts,
+ NewPhysicalDeviceInfo
+ ->PredictedFailuresDetected);
+ }
+ if (PhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Dead &&
+ NewPhysicalDeviceInfo->PhysicalDeviceState
+ != DAC960_V2_Device_Dead)
+ Controller->V2.NeedDeviceSerialNumberInformation = true;
+ memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
+ sizeof(DAC960_V2_PhysicalDeviceInfo_T));
+ }
+ NewPhysicalDeviceInfo->LogicalUnit++;
+ Controller->V2.PhysicalDeviceIndex++;
+ }
+ else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
+ Controller->V2.NeedPhysicalDeviceInformation = false;
+ else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
+ CommandStatus == DAC960_V2_NormalCompletion)
+ {
+ DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
+ &Controller->V2.NewLogicalDeviceInformation;
+ unsigned short LogicalDeviceNumber =
+ NewLogicalDeviceInfo->LogicalDeviceNumber;
+ DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+ Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber];
+ if (LogicalDeviceInfo == NULL)
+ {
+ DAC960_V2_PhysicalDevice_T PhysicalDevice;
+ PhysicalDevice.Controller = 0;
+ PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
+ PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
+ PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
+ Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
+ PhysicalDevice;
+ LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
+ kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
+ Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
+ LogicalDeviceInfo;
+ DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
+ "Now Exists%s\n", Controller,
+ LogicalDeviceNumber,
+ Controller->ControllerNumber,
+ LogicalDeviceNumber,
+ (LogicalDeviceInfo != NULL
+ ? "" : " - Allocation Failed"));
+ if (LogicalDeviceInfo != NULL)
+ memset(LogicalDeviceInfo, 0,
+ sizeof(DAC960_V2_LogicalDeviceInfo_T));
+ }
+ if (LogicalDeviceInfo != NULL)
+ {
+ unsigned long LogicalDeviceSize =
+ NewLogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB;
+ if (NewLogicalDeviceInfo->LogicalDeviceState !=
+ LogicalDeviceInfo->LogicalDeviceState)
+ DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
+ "is now %s\n", Controller,
+ LogicalDeviceNumber,
+ Controller->ControllerNumber,
+ LogicalDeviceNumber,
+ (NewLogicalDeviceInfo->LogicalDeviceState
+ == DAC960_V2_LogicalDevice_Online
+ ? "ONLINE"
+ : NewLogicalDeviceInfo->LogicalDeviceState
+ == DAC960_V2_LogicalDevice_Critical
+ ? "CRITICAL" : "OFFLINE"));
+ if ((NewLogicalDeviceInfo->SoftErrors !=
+ LogicalDeviceInfo->SoftErrors) ||
+ (NewLogicalDeviceInfo->CommandsFailed !=
+ LogicalDeviceInfo->CommandsFailed) ||
+ (NewLogicalDeviceInfo->DeferredWriteErrors !=
+ LogicalDeviceInfo->DeferredWriteErrors))
+ DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) Errors: "
+ "Soft = %d, Failed = %d, Deferred Write = %d\n",
+ Controller, LogicalDeviceNumber,
+ Controller->ControllerNumber,
+ LogicalDeviceNumber,
+ NewLogicalDeviceInfo->SoftErrors,
+ NewLogicalDeviceInfo->CommandsFailed,
+ NewLogicalDeviceInfo->DeferredWriteErrors);
+ if (NewLogicalDeviceInfo->ConsistencyCheckInProgress)
+ DAC960_V2_ReportProgress(Controller,
+ "Consistency Check",
+ LogicalDeviceNumber,
+ NewLogicalDeviceInfo
+ ->ConsistencyCheckBlockNumber,
+ LogicalDeviceSize);
+ else if (NewLogicalDeviceInfo->RebuildInProgress)
+ DAC960_V2_ReportProgress(Controller,
+ "Rebuild",
+ LogicalDeviceNumber,
+ NewLogicalDeviceInfo
+ ->RebuildBlockNumber,
+ LogicalDeviceSize);
+ else if (NewLogicalDeviceInfo->BackgroundInitializationInProgress)
+ DAC960_V2_ReportProgress(Controller,
+ "BackgroundInitialization",
+ LogicalDeviceNumber,
+ NewLogicalDeviceInfo
+ ->BackgroundInitializationBlockNumber,
+ LogicalDeviceSize);
+ else if (NewLogicalDeviceInfo->ForegroundInitializationInProgress)
+ DAC960_V2_ReportProgress(Controller,
+ "Foreground Initialization",
+ LogicalDeviceNumber,
+ NewLogicalDeviceInfo
+ ->ForegroundInitializationBlockNumber,
+ LogicalDeviceSize);
+ else if (NewLogicalDeviceInfo->DataMigrationInProgress)
+ DAC960_V2_ReportProgress(Controller,
+ "Data Migration",
+ LogicalDeviceNumber,
+ NewLogicalDeviceInfo
+ ->DataMigrationBlockNumber,
+ LogicalDeviceSize);
+ else if (NewLogicalDeviceInfo->PatrolOperationInProgress)
+ DAC960_V2_ReportProgress(Controller,
+ "Patrol Operation",
+ LogicalDeviceNumber,
+ NewLogicalDeviceInfo
+ ->PatrolOperationBlockNumber,
+ LogicalDeviceSize);
+ memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
+ sizeof(DAC960_V2_LogicalDeviceInfo_T));
+ }
+ NewLogicalDeviceInfo->LogicalDeviceNumber++;
+ }
+ else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
+ Controller->V2.NeedLogicalDeviceInformation = false;
+ if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
+ - Controller->V2.NextEventSequenceNumber > 0)
+ {
+ CommandMailbox->GetEvent.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->GetEvent.DataTransferSize = sizeof(DAC960_V2_Event_T);
+ CommandMailbox->GetEvent.EventSequenceNumberHigh16 =
+ Controller->V2.NextEventSequenceNumber >> 16;
+ CommandMailbox->GetEvent.ControllerNumber = 0;
+ CommandMailbox->GetEvent.IOCTL_Opcode =
+ DAC960_V2_GetEvent;
+ CommandMailbox->GetEvent.EventSequenceNumberLow16 =
+ Controller->V2.NextEventSequenceNumber & 0xFFFF;
+ CommandMailbox->GetEvent.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(&Controller->V2.Event);
+ CommandMailbox->GetEvent.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->GetEvent.DataTransferSize;
+ DAC960_QueueCommand(Command);
+ return;
+ }
+ if (Controller->V2.NeedPhysicalDeviceInformation)
+ {
+ if (Controller->V2.NeedDeviceSerialNumberInformation)
+ {
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
+ Controller->V2.InquiryUnitSerialNumber
+ [Controller->V2.PhysicalDeviceIndex - 1];
+ InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+ CommandMailbox->SCSI_10.CommandOpcode =
+ DAC960_V2_SCSI_10_Passthru;
+ CommandMailbox->SCSI_10.DataTransferSize =
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+ CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit =
+ Controller->V2.NewPhysicalDeviceInformation.LogicalUnit - 1;
+ CommandMailbox->SCSI_10.PhysicalDevice.TargetID =
+ Controller->V2.NewPhysicalDeviceInformation.TargetID;
+ CommandMailbox->SCSI_10.PhysicalDevice.Channel =
+ Controller->V2.NewPhysicalDeviceInformation.Channel;
+ CommandMailbox->SCSI_10.CDBLength = 6;
+ CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
+ CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
+ CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
+ CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
+ CommandMailbox->SCSI_10.SCSI_CDB[4] =
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+ CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(InquiryUnitSerialNumber);
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->SCSI_10.DataTransferSize;
+ DAC960_QueueCommand(Command);
+ Controller->V2.NeedDeviceSerialNumberInformation = false;
+ return;
+ }
+ CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
+ sizeof(DAC960_V2_PhysicalDeviceInfo_T);
+ CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit =
+ Controller->V2.NewPhysicalDeviceInformation.LogicalUnit;
+ CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID =
+ Controller->V2.NewPhysicalDeviceInformation.TargetID;
+ CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel =
+ Controller->V2.NewPhysicalDeviceInformation.Channel;
+ CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
+ DAC960_V2_GetPhysicalDeviceInfoValid;
+ CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(&Controller->V2.NewPhysicalDeviceInformation);
+ CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
+ DAC960_QueueCommand(Command);
+ return;
+ }
+ if (Controller->V2.NeedLogicalDeviceInformation)
+ {
+ CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->LogicalDeviceInfo.DataTransferSize =
+ sizeof(DAC960_V2_LogicalDeviceInfo_T);
+ CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+ Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber;
+ CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
+ DAC960_V2_GetLogicalDeviceInfoValid;
+ CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(&Controller->V2.NewLogicalDeviceInformation);
+ CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->LogicalDeviceInfo.DataTransferSize;
+ DAC960_QueueCommand(Command);
+ return;
+ }
+ Controller->MonitoringTimerCount++;
+ Controller->MonitoringTimer.expires =
+ jiffies + DAC960_HealthStatusMonitoringInterval;
+ add_timer(&Controller->MonitoringTimer);
+ }
+ if (CommandType == DAC960_ImmediateCommand)
+ {
+ up(Command->Semaphore);
+ Command->Semaphore = NULL;
+ return;
+ }
+ if (CommandType == DAC960_QueuedCommand)
+ {
+ DAC960_V2_KernelCommand_T *KernelCommand = Command->V2.KernelCommand;
+ KernelCommand->CommandStatus = CommandStatus;
+ KernelCommand->RequestSenseLength = Command->V2.RequestSenseLength;
+ KernelCommand->DataTransferLength = Command->V2.DataTransferResidue;
+ Command->V2.KernelCommand = NULL;
DAC960_DeallocateCommand(Command);
KernelCommand->CompletionFunction(KernelCommand);
return;
@@ -2489,7 +4440,7 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
if (Controller->MonitoringCommandDeferred)
{
Controller->MonitoringCommandDeferred = false;
- DAC960_QueueMonitoringCommand(Command);
+ DAC960_V2_QueueMonitoringCommand(Command);
return;
}
/*
@@ -2504,16 +4455,17 @@ static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
/*
- DAC960_InterruptHandler handles hardware interrupts from DAC960 Controllers.
+ DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
+ Controllers.
*/
-static void DAC960_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- Registers_T *InterruptRegisters)
+static void DAC960_BA_InterruptHandler(int IRQ_Channel,
+ void *DeviceIdentifier,
+ Registers_T *InterruptRegisters)
{
DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
void *ControllerBaseAddress = Controller->BaseAddress;
- DAC960_StatusMailbox_T *NextStatusMailbox;
+ DAC960_V2_StatusMailbox_T *NextStatusMailbox;
ProcessorFlags_T ProcessorFlags;
/*
Acquire exclusive access to Controller.
@@ -2522,54 +4474,24 @@ static void DAC960_InterruptHandler(int IRQ_Channel,
/*
Process Hardware Interrupts for Controller.
*/
- switch (Controller->ControllerType)
- {
- case DAC960_V5_Controller:
- DAC960_V5_AcknowledgeInterrupt(ControllerBaseAddress);
- NextStatusMailbox = Controller->NextStatusMailbox;
- while (NextStatusMailbox->Fields.Valid)
- {
- DAC960_CommandIdentifier_T CommandIdentifier =
- NextStatusMailbox->Fields.CommandIdentifier;
- DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
- Command->CommandStatus = NextStatusMailbox->Fields.CommandStatus;
- NextStatusMailbox->Word = 0;
- if (++NextStatusMailbox > Controller->LastStatusMailbox)
- NextStatusMailbox = Controller->FirstStatusMailbox;
- DAC960_ProcessCompletedCommand(Command);
- }
- Controller->NextStatusMailbox = NextStatusMailbox;
- break;
- case DAC960_V4_Controller:
- DAC960_V4_AcknowledgeInterrupt(ControllerBaseAddress);
- NextStatusMailbox = Controller->NextStatusMailbox;
- while (NextStatusMailbox->Fields.Valid)
- {
- DAC960_CommandIdentifier_T CommandIdentifier =
- NextStatusMailbox->Fields.CommandIdentifier;
- DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
- Command->CommandStatus = NextStatusMailbox->Fields.CommandStatus;
- NextStatusMailbox->Word = 0;
- if (++NextStatusMailbox > Controller->LastStatusMailbox)
- NextStatusMailbox = Controller->FirstStatusMailbox;
- DAC960_ProcessCompletedCommand(Command);
- }
- Controller->NextStatusMailbox = NextStatusMailbox;
- break;
- case DAC960_V3_Controller:
- while (DAC960_V3_StatusAvailableP(ControllerBaseAddress))
- {
- DAC960_CommandIdentifier_T CommandIdentifier =
- DAC960_V3_ReadStatusCommandIdentifier(ControllerBaseAddress);
- DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
- Command->CommandStatus =
- DAC960_V3_ReadStatusRegister(ControllerBaseAddress);
- DAC960_V3_AcknowledgeInterrupt(ControllerBaseAddress);
- DAC960_V3_AcknowledgeStatus(ControllerBaseAddress);
- DAC960_ProcessCompletedCommand(Command);
- }
- break;
+ DAC960_BA_AcknowledgeInterrupt(ControllerBaseAddress);
+ NextStatusMailbox = Controller->V2.NextStatusMailbox;
+ while (NextStatusMailbox->Fields.CommandIdentifier > 0)
+ {
+ DAC960_V2_CommandIdentifier_T CommandIdentifier =
+ NextStatusMailbox->Fields.CommandIdentifier;
+ DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+ Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+ Command->V2.RequestSenseLength =
+ NextStatusMailbox->Fields.RequestSenseLength;
+ Command->V2.DataTransferResidue =
+ NextStatusMailbox->Fields.DataTransferResidue;
+ NextStatusMailbox->Words[0] = 0;
+ if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
+ NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+ DAC960_V2_ProcessCompletedCommand(Command);
}
+ Controller->V2.NextStatusMailbox = NextStatusMailbox;
/*
Attempt to remove additional I/O Requests from the Controller's
I/O Request Queue and queue them to the Controller.
@@ -2583,47 +4505,311 @@ static void DAC960_InterruptHandler(int IRQ_Channel,
/*
- DAC960_QueueMonitoringCommand queues a Monitoring Command to Controller.
+ DAC960_LP_InterruptHandler handles hardware interrupts from DAC960 LP Series
+ Controllers.
*/
-static void DAC960_QueueMonitoringCommand(DAC960_Command_T *Command)
+static void DAC960_LP_InterruptHandler(int IRQ_Channel,
+ void *DeviceIdentifier,
+ Registers_T *InterruptRegisters)
{
- DAC960_Controller_T *Controller = Command->Controller;
- DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
- DAC960_ClearCommand(Command);
- Command->CommandType = DAC960_MonitoringCommand;
- CommandMailbox->Type3.CommandOpcode = DAC960_Enquiry;
- CommandMailbox->Type3.BusAddress =
- Virtual_to_Bus(&Controller->Enquiry[Controller->EnquiryIndex ^ 1]);
- DAC960_QueueCommand(Command);
+ DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+ ProcessorFlags_T ProcessorFlags;
+ /*
+ Acquire exclusive access to Controller.
+ */
+ DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+ /*
+ Process Hardware Interrupts for Controller.
+ */
+ DAC960_LP_AcknowledgeInterrupt(ControllerBaseAddress);
+ NextStatusMailbox = Controller->V2.NextStatusMailbox;
+ while (NextStatusMailbox->Fields.CommandIdentifier > 0)
+ {
+ DAC960_V2_CommandIdentifier_T CommandIdentifier =
+ NextStatusMailbox->Fields.CommandIdentifier;
+ DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+ Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+ Command->V2.RequestSenseLength =
+ NextStatusMailbox->Fields.RequestSenseLength;
+ Command->V2.DataTransferResidue =
+ NextStatusMailbox->Fields.DataTransferResidue;
+ NextStatusMailbox->Words[0] = 0;
+ if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
+ NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+ DAC960_V2_ProcessCompletedCommand(Command);
+ }
+ Controller->V2.NextStatusMailbox = NextStatusMailbox;
+ /*
+ 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_MonitoringTimerFunction is the timer function for monitoring
- the status of DAC960 Controllers.
+ DAC960_LA_InterruptHandler handles hardware interrupts from DAC960 LA Series
+ Controllers.
*/
-static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
+static void DAC960_LA_InterruptHandler(int IRQ_Channel,
+ void *DeviceIdentifier,
+ Registers_T *InterruptRegisters)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) TimerData;
- DAC960_Command_T *Command;
+ DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V1_StatusMailbox_T *NextStatusMailbox;
ProcessorFlags_T ProcessorFlags;
/*
Acquire exclusive access to Controller.
*/
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
/*
- Queue a Status Monitoring Command to Controller.
+ Process Hardware Interrupts for Controller.
*/
- Command = DAC960_AllocateCommand(Controller);
- if (Command != NULL)
- DAC960_QueueMonitoringCommand(Command);
- else Controller->MonitoringCommandDeferred = true;
+ DAC960_LA_AcknowledgeInterrupt(ControllerBaseAddress);
+ NextStatusMailbox = Controller->V1.NextStatusMailbox;
+ while (NextStatusMailbox->Fields.Valid)
+ {
+ DAC960_V1_CommandIdentifier_T CommandIdentifier =
+ NextStatusMailbox->Fields.CommandIdentifier;
+ DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+ Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+ NextStatusMailbox->Word = 0;
+ if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
+ NextStatusMailbox = Controller->V1.FirstStatusMailbox;
+ DAC960_V1_ProcessCompletedCommand(Command);
+ }
+ Controller->V1.NextStatusMailbox = NextStatusMailbox;
+ /*
+ 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_ReleaseControllerLock(Controller, &ProcessorFlags);
+ DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
+ DAC960_PG_InterruptHandler handles hardware interrupts from DAC960 PG Series
+ Controllers.
+*/
+
+static void DAC960_PG_InterruptHandler(int IRQ_Channel,
+ void *DeviceIdentifier,
+ Registers_T *InterruptRegisters)
+{
+ DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V1_StatusMailbox_T *NextStatusMailbox;
+ ProcessorFlags_T ProcessorFlags;
+ /*
+ Acquire exclusive access to Controller.
+ */
+ DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+ /*
+ Process Hardware Interrupts for Controller.
+ */
+ DAC960_PG_AcknowledgeInterrupt(ControllerBaseAddress);
+ NextStatusMailbox = Controller->V1.NextStatusMailbox;
+ while (NextStatusMailbox->Fields.Valid)
+ {
+ DAC960_V1_CommandIdentifier_T CommandIdentifier =
+ NextStatusMailbox->Fields.CommandIdentifier;
+ DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+ Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+ NextStatusMailbox->Word = 0;
+ if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
+ NextStatusMailbox = Controller->V1.FirstStatusMailbox;
+ DAC960_V1_ProcessCompletedCommand(Command);
+ }
+ Controller->V1.NextStatusMailbox = NextStatusMailbox;
+ /*
+ 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_PD_InterruptHandler handles hardware interrupts from DAC960 PD Series
+ Controllers.
+*/
+
+static void DAC960_PD_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];
+ Command->V1.CommandStatus =
+ DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
+ DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
+ DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
+ 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.
+*/
+
+static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_ClearCommand(Command);
+ Command->CommandType = DAC960_MonitoringCommand;
+ CommandMailbox->Type3.CommandOpcode = DAC960_V1_Enquiry;
+ CommandMailbox->Type3.BusAddress = Virtual_to_Bus(&Controller->V1.NewEnquiry);
+ DAC960_QueueCommand(Command);
+}
+
+
+/*
+ DAC960_V2_QueueMonitoringCommand queues a Monitoring Command to DAC960 V2
+ Firmware Controllers.
+*/
+
+static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_MonitoringCommand;
+ 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_Bus(&Controller->V2.NewControllerInformation);
+ CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->ControllerInfo.DataTransferSize;
+ DAC960_QueueCommand(Command);
+}
+
+
+/*
+ DAC960_MonitoringTimerFunction is the timer function for monitoring
+ the status of DAC960 Controllers.
+*/
+
+static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
+{
+ DAC960_Controller_T *Controller = (DAC960_Controller_T *) TimerData;
+ DAC960_Command_T *Command;
+ ProcessorFlags_T ProcessorFlags;
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ {
+ /*
+ Acquire exclusive access to Controller.
+ */
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ /*
+ Queue a Status Monitoring Command to Controller.
+ */
+ Command = DAC960_AllocateCommand(Controller);
+ if (Command != NULL)
+ DAC960_V1_QueueMonitoringCommand(Command);
+ else Controller->MonitoringCommandDeferred = true;
+ /*
+ Release exclusive access to Controller.
+ */
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+ }
+ else
+ {
+ DAC960_V2_ControllerInfo_T *ControllerInfo =
+ &Controller->V2.ControllerInformation;
+ unsigned int StatusChangeCounter =
+ Controller->V2.HealthStatusBuffer->StatusChangeCounter;
+ if (StatusChangeCounter == Controller->V2.StatusChangeCounter &&
+ Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
+ == Controller->V2.NextEventSequenceNumber &&
+ (ControllerInfo->BackgroundInitializationsActive +
+ ControllerInfo->LogicalDeviceInitializationsActive +
+ ControllerInfo->PhysicalDeviceInitializationsActive +
+ ControllerInfo->ConsistencyChecksActive +
+ ControllerInfo->RebuildsActive +
+ ControllerInfo->OnlineExpansionsActive == 0 ||
+ jiffies - Controller->PrimaryMonitoringTime
+ < DAC960_MonitoringTimerInterval))
+ {
+ Controller->MonitoringTimer.expires =
+ jiffies + DAC960_HealthStatusMonitoringInterval;
+ add_timer(&Controller->MonitoringTimer);
+ return;
+ }
+ Controller->V2.StatusChangeCounter = StatusChangeCounter;
+ Controller->PrimaryMonitoringTime = jiffies;
+ /*
+ Acquire exclusive access to Controller.
+ */
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ /*
+ Queue a Status Monitoring Command to Controller.
+ */
+ Command = DAC960_AllocateCommand(Controller);
+ if (Command != NULL)
+ DAC960_V2_QueueMonitoringCommand(Command);
+ else Controller->MonitoringCommandDeferred = true;
+ /*
+ Release exclusive access to Controller.
+ */
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+ /*
+ Wake up any processes waiting on a Health Status Buffer change.
+ */
+ wake_up(&Controller->HealthStatusWaitQueue);
+ }
}
@@ -2642,20 +4828,29 @@ static int DAC960_Open(Inode_T *Inode, File_T *File)
if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
return -ENXIO;
Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL ||
- LogicalDriveNumber > Controller->LogicalDriveCount - 1)
- return -ENXIO;
- if (Controller->LogicalDriveInformation
- [Controller->LogicalDriveInformationIndex]
- [LogicalDriveNumber].LogicalDriveState
- == DAC960_LogicalDrive_Offline)
- return -ENXIO;
- if (Controller->LogicalDriveInitialState[LogicalDriveNumber]
- == DAC960_LogicalDrive_Offline)
+ if (Controller == NULL) return -ENXIO;
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ {
+ if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
+ return -ENXIO;
+ if (Controller->V1.LogicalDriveInformation
+ [LogicalDriveNumber].LogicalDriveState
+ == DAC960_V1_LogicalDrive_Offline)
+ return -ENXIO;
+ }
+ else
+ {
+ DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+ Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+ if (LogicalDeviceInfo == NULL ||
+ LogicalDeviceInfo->LogicalDeviceState
+ == DAC960_V2_LogicalDevice_Offline)
+ return -ENXIO;
+ }
+ if (!Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber])
{
- Controller->LogicalDriveInitialState[LogicalDriveNumber] =
- DAC960_LogicalDrive_Online;
- DAC960_InitializeGenericDiskInfo(&Controller->GenericDiskInfo);
+ Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
+ DAC960_RegisterDisk(Controller, LogicalDriveNumber);
}
if (Controller->GenericDiskInfo.sizes[MINOR(Inode->i_rdev)] == 0)
return -ENXIO;
@@ -2710,25 +4905,51 @@ static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
return -ENXIO;
Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL ||
- LogicalDriveNumber > Controller->LogicalDriveCount - 1)
- return -ENXIO;
+ if (Controller == NULL) return -ENXIO;
switch (Request)
{
case HDIO_GETGEO:
/* Get BIOS Disk Geometry. */
UserGeometry = (DiskGeometry_T *) Argument;
if (UserGeometry == NULL) return -EINVAL;
- Geometry.heads = Controller->GeometryTranslationHeads;
- Geometry.sectors = Controller->GeometryTranslationSectors;
- Geometry.cylinders =
- Controller->LogicalDriveInformation
- [Controller->LogicalDriveInformationIndex]
- [LogicalDriveNumber].LogicalDriveSize
- / (Controller->GeometryTranslationHeads *
- Controller->GeometryTranslationSectors);
- Geometry.start = Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
- .start_sect;
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ {
+ if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
+ return -ENXIO;
+ Geometry.heads = Controller->V1.GeometryTranslationHeads;
+ Geometry.sectors = Controller->V1.GeometryTranslationSectors;
+ Geometry.cylinders =
+ Controller->V1.LogicalDriveInformation[LogicalDriveNumber]
+ .LogicalDriveSize
+ / (Geometry.heads * Geometry.sectors);
+ }
+ else
+ {
+ DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+ Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+ if (LogicalDeviceInfo == NULL)
+ return -EINVAL;
+ switch(LogicalDeviceInfo->DriveGeometry)
+ {
+ case DAC960_V2_Geometry_128_32:
+ Geometry.heads = 128;
+ Geometry.sectors = 32;
+ break;
+ case DAC960_V2_Geometry_255_63:
+ Geometry.heads = 255;
+ Geometry.sectors = 63;
+ break;
+ default:
+ DAC960_Error("Illegal Logical Device Geometry %d\n",
+ Controller, LogicalDeviceInfo->DriveGeometry);
+ return -EINVAL;
+ }
+ Geometry.cylinders =
+ LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB
+ / (Geometry.heads * Geometry.sectors);
+ }
+ Geometry.start =
+ Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].start_sect;
return copy_to_user(UserGeometry, &Geometry, sizeof(DiskGeometry_T));
case BLKGETSIZE:
/* Get Device Size. */
@@ -2789,13 +5010,20 @@ static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
*/
set_blocksize(Device, BLOCK_SIZE);
}
- /*
- * Leonard, I'll tie you, draw around you a pentagram
- * and read this file. Aloud.
- */
- grok_partitions(
- &Controller->GenericDiskInfo, LogicalDriveNumber, DAC960_MaxPartitions,
- Controller->LogicalDriveInformation[Controller->LogicalDriveInformationIndex][LogicalDriveNumber].LogicalDriveSize);
+ 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);
return 0;
}
return -EINVAL;
@@ -2830,59 +5058,63 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
ControllerNumber > DAC960_ControllerCount - 1)
return -ENXIO;
Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL)
- return -ENXIO;
+ if (Controller == NULL) return -ENXIO;
memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
ControllerInfo.ControllerNumber = ControllerNumber;
+ ControllerInfo.FirmwareType = Controller->FirmwareType;
+ ControllerInfo.Channels = Controller->Channels;
+ ControllerInfo.Targets = Controller->Targets;
ControllerInfo.PCI_Bus = Controller->Bus;
ControllerInfo.PCI_Device = Controller->Device;
ControllerInfo.PCI_Function = Controller->Function;
ControllerInfo.IRQ_Channel = Controller->IRQ_Channel;
- ControllerInfo.Channels = Controller->Channels;
ControllerInfo.PCI_Address = Controller->PCI_Address;
strcpy(ControllerInfo.ModelName, Controller->ModelName);
strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
return copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
sizeof(DAC960_ControllerInfo_T));
}
- case DAC960_IOCTL_EXECUTE_COMMAND:
+ case DAC960_IOCTL_V1_EXECUTE_COMMAND:
{
- DAC960_UserCommand_T *UserSpaceUserCommand =
- (DAC960_UserCommand_T *) Argument;
- DAC960_UserCommand_T UserCommand;
+ DAC960_V1_UserCommand_T *UserSpaceUserCommand =
+ (DAC960_V1_UserCommand_T *) Argument;
+ DAC960_V1_UserCommand_T UserCommand;
DAC960_Controller_T *Controller;
DAC960_Command_T *Command = NULL;
- DAC960_CommandOpcode_T CommandOpcode;
- DAC960_CommandStatus_T CommandStatus;
- DAC960_DCDB_T DCDB;
+ DAC960_V1_CommandOpcode_T CommandOpcode;
+ DAC960_V1_CommandStatus_T CommandStatus;
+ DAC960_V1_DCDB_T DCDB;
ProcessorFlags_T ProcessorFlags;
int ControllerNumber, DataTransferLength;
unsigned char *DataTransferBuffer = NULL;
if (UserSpaceUserCommand == NULL) return -EINVAL;
ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
- sizeof(DAC960_UserCommand_T));
- if (ErrorCode != 0) goto Failure;
+ sizeof(DAC960_V1_UserCommand_T));
+ if (ErrorCode != 0) goto Failure1;
ControllerNumber = UserCommand.ControllerNumber;
if (ControllerNumber < 0 ||
ControllerNumber > DAC960_ControllerCount - 1)
return -ENXIO;
Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL)
- return -ENXIO;
+ if (Controller == NULL) return -ENXIO;
+ if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
DataTransferLength = UserCommand.DataTransferLength;
if (CommandOpcode & 0x80) return -EINVAL;
- if (CommandOpcode == DAC960_DCDB)
+ if (CommandOpcode == DAC960_V1_DCDB)
{
ErrorCode =
- copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_DCDB_T));
- if (ErrorCode != 0) goto Failure;
+ copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_V1_DCDB_T));
+ if (ErrorCode != 0) goto Failure1;
if (!((DataTransferLength == 0 &&
- DCDB.Direction == DAC960_DCDB_NoDataTransfer) ||
+ DCDB.Direction
+ == DAC960_V1_DCDB_NoDataTransfer) ||
(DataTransferLength > 0 &&
- DCDB.Direction == DAC960_DCDB_DataTransferDeviceToSystem) ||
+ DCDB.Direction
+ == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
(DataTransferLength < 0 &&
- DCDB.Direction == DAC960_DCDB_DataTransferSystemToDevice)))
+ DCDB.Direction
+ == DAC960_V1_DCDB_DataTransferSystemToDevice)))
return -EINVAL;
if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
!= abs(DataTransferLength))
@@ -2901,23 +5133,24 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
ErrorCode = copy_from_user(DataTransferBuffer,
UserCommand.DataTransferBuffer,
-DataTransferLength);
- if (ErrorCode != 0) goto Failure;
+ if (ErrorCode != 0) goto Failure1;
}
- if (CommandOpcode == DAC960_DCDB)
+ if (CommandOpcode == DAC960_V1_DCDB)
{
DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- while (Controller->DirectCommandActive[DCDB.Channel]
- [DCDB.TargetID] ||
+ while (Controller->V1.DirectCommandActive[DCDB.Channel]
+ [DCDB.TargetID] ||
(Command = DAC960_AllocateCommand(Controller)) == NULL)
DAC960_WaitForCommand(Controller);
- Controller->DirectCommandActive[DCDB.Channel]
- [DCDB.TargetID] = true;
+ Controller->V1.DirectCommandActive[DCDB.Channel]
+ [DCDB.TargetID] = true;
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- DAC960_ClearCommand(Command);
+ DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
- memcpy(&Command->CommandMailbox, &UserCommand.CommandMailbox,
- sizeof(DAC960_CommandMailbox_T));
- Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(&DCDB);
+ memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
+ sizeof(DAC960_V1_CommandMailbox_T));
+ Command->V1.CommandMailbox.Type3.BusAddress =
+ Virtual_to_Bus(&DCDB);
DCDB.BusAddress = Virtual_to_Bus(DataTransferBuffer);
}
else
@@ -2926,38 +5159,211 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
DAC960_WaitForCommand(Controller);
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- DAC960_ClearCommand(Command);
+ DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
- memcpy(&Command->CommandMailbox, &UserCommand.CommandMailbox,
- sizeof(DAC960_CommandMailbox_T));
+ memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
+ sizeof(DAC960_V1_CommandMailbox_T));
if (DataTransferBuffer != NULL)
- Command->CommandMailbox.Type3.BusAddress =
+ Command->V1.CommandMailbox.Type3.BusAddress =
Virtual_to_Bus(DataTransferBuffer);
}
DAC960_ExecuteCommand(Command);
- CommandStatus = Command->CommandStatus;
+ CommandStatus = Command->V1.CommandStatus;
DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
DAC960_DeallocateCommand(Command);
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- if (CommandStatus == DAC960_NormalCompletion &&
- DataTransferLength > 0)
+ if (DataTransferLength > 0)
{
ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
DataTransferBuffer, DataTransferLength);
- if (ErrorCode != 0) goto Failure;
+ if (ErrorCode != 0) goto Failure1;
}
- if (CommandOpcode == DAC960_DCDB)
+ if (CommandOpcode == DAC960_V1_DCDB)
{
- Controller->DirectCommandActive[DCDB.Channel]
- [DCDB.TargetID] = false;
+ Controller->V1.DirectCommandActive[DCDB.Channel]
+ [DCDB.TargetID] = false;
ErrorCode =
- copy_to_user(UserCommand.DCDB, &DCDB, sizeof(DAC960_DCDB_T));
- if (ErrorCode != 0) goto Failure;
+ copy_to_user(UserCommand.DCDB, &DCDB, sizeof(DAC960_V1_DCDB_T));
+ if (ErrorCode != 0) goto Failure1;
+ }
+ ErrorCode = CommandStatus;
+ Failure1:
+ if (DataTransferBuffer != NULL)
+ kfree(DataTransferBuffer);
+ return ErrorCode;
+ }
+ case DAC960_IOCTL_V2_EXECUTE_COMMAND:
+ {
+ DAC960_V2_UserCommand_T *UserSpaceUserCommand =
+ (DAC960_V2_UserCommand_T *) Argument;
+ DAC960_V2_UserCommand_T UserCommand;
+ DAC960_Controller_T *Controller;
+ DAC960_Command_T *Command = NULL;
+ DAC960_V2_CommandMailbox_T *CommandMailbox;
+ DAC960_V2_CommandStatus_T CommandStatus;
+ ProcessorFlags_T ProcessorFlags;
+ int ControllerNumber, DataTransferLength;
+ int DataTransferResidue, RequestSenseLength;
+ unsigned char *DataTransferBuffer = NULL;
+ unsigned char *RequestSenseBuffer = NULL;
+ if (UserSpaceUserCommand == NULL) return -EINVAL;
+ ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
+ sizeof(DAC960_V2_UserCommand_T));
+ if (ErrorCode != 0) goto Failure2;
+ ControllerNumber = UserCommand.ControllerNumber;
+ if (ControllerNumber < 0 ||
+ ControllerNumber > DAC960_ControllerCount - 1)
+ return -ENXIO;
+ Controller = DAC960_Controllers[ControllerNumber];
+ if (Controller == NULL) return -ENXIO;
+ if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+ DataTransferLength = UserCommand.DataTransferLength;
+ if (DataTransferLength > 0)
+ {
+ DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
+ if (DataTransferBuffer == NULL) return -ENOMEM;
+ memset(DataTransferBuffer, 0, DataTransferLength);
+ }
+ else if (DataTransferLength < 0)
+ {
+ DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
+ if (DataTransferBuffer == NULL) return -ENOMEM;
+ ErrorCode = copy_from_user(DataTransferBuffer,
+ UserCommand.DataTransferBuffer,
+ -DataTransferLength);
+ if (ErrorCode != 0) goto Failure2;
+ }
+ RequestSenseLength = UserCommand.RequestSenseLength;
+ if (RequestSenseLength > 0)
+ {
+ RequestSenseBuffer = kmalloc(RequestSenseLength, GFP_KERNEL);
+ if (RequestSenseBuffer == NULL)
+ {
+ ErrorCode = -ENOMEM;
+ goto Failure2;
+ }
+ memset(RequestSenseBuffer, 0, RequestSenseLength);
+ }
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
+ DAC960_WaitForCommand(Controller);
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_ImmediateCommand;
+ CommandMailbox = &Command->V2.CommandMailbox;
+ memcpy(CommandMailbox, &UserCommand.CommandMailbox,
+ sizeof(DAC960_V2_CommandMailbox_T));
+ CommandMailbox->Common.CommandControlBits
+ .AdditionalScatterGatherListMemory = false;
+ CommandMailbox->Common.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->Common.DataTransferSize = 0;
+ CommandMailbox->Common.DataTransferPageNumber = 0;
+ memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
+ sizeof(DAC960_V2_DataTransferMemoryAddress_T));
+ if (DataTransferLength != 0)
+ {
+ if (DataTransferLength > 0)
+ {
+ CommandMailbox->Common.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->Common.DataTransferSize = DataTransferLength;
+ }
+ else
+ {
+ CommandMailbox->Common.CommandControlBits
+ .DataTransferControllerToHost = false;
+ CommandMailbox->Common.DataTransferSize = -DataTransferLength;
+ }
+ CommandMailbox->Common.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(DataTransferBuffer);
+ CommandMailbox->Common.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->Common.DataTransferSize;
+ }
+ if (RequestSenseLength > 0)
+ {
+ CommandMailbox->Common.CommandControlBits
+ .NoAutoRequestSense = false;
+ CommandMailbox->Common.RequestSenseSize = RequestSenseLength;
+ CommandMailbox->Common.RequestSenseBusAddress =
+ Virtual_to_Bus(RequestSenseBuffer);
+ }
+ DAC960_ExecuteCommand(Command);
+ CommandStatus = Command->V2.CommandStatus;
+ RequestSenseLength = Command->V2.RequestSenseLength;
+ DataTransferResidue = Command->V2.DataTransferResidue;
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ DAC960_DeallocateCommand(Command);
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+ if (RequestSenseLength > UserCommand.RequestSenseLength)
+ RequestSenseLength = UserCommand.RequestSenseLength;
+ ErrorCode = copy_to_user(&UserSpaceUserCommand->DataTransferLength,
+ &DataTransferResidue,
+ sizeof(DataTransferResidue));
+ if (ErrorCode != 0) goto Failure2;
+ ErrorCode = copy_to_user(&UserSpaceUserCommand->RequestSenseLength,
+ &RequestSenseLength,
+ sizeof(RequestSenseLength));
+ if (ErrorCode != 0) goto Failure2;
+ if (DataTransferLength > 0)
+ {
+ ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
+ DataTransferBuffer, DataTransferLength);
+ if (ErrorCode != 0) goto Failure2;
+ }
+ if (RequestSenseLength > 0)
+ {
+ ErrorCode = copy_to_user(UserCommand.RequestSenseBuffer,
+ RequestSenseBuffer, RequestSenseLength);
+ if (ErrorCode != 0) goto Failure2;
}
ErrorCode = CommandStatus;
- Failure:
+ Failure2:
if (DataTransferBuffer != NULL)
kfree(DataTransferBuffer);
+ if (RequestSenseBuffer != NULL)
+ kfree(RequestSenseBuffer);
+ return ErrorCode;
+ }
+ case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
+ {
+ DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus =
+ (DAC960_V2_GetHealthStatus_T *) Argument;
+ DAC960_V2_GetHealthStatus_T GetHealthStatus;
+ DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
+ DAC960_Controller_T *Controller;
+ int ControllerNumber;
+ if (UserSpaceGetHealthStatus == NULL) return -EINVAL;
+ ErrorCode = copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
+ sizeof(DAC960_V2_GetHealthStatus_T));
+ if (ErrorCode != 0) return ErrorCode;
+ ControllerNumber = GetHealthStatus.ControllerNumber;
+ if (ControllerNumber < 0 ||
+ ControllerNumber > DAC960_ControllerCount - 1)
+ return -ENXIO;
+ Controller = DAC960_Controllers[ControllerNumber];
+ if (Controller == NULL) return -ENXIO;
+ if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+ ErrorCode = copy_from_user(&HealthStatusBuffer,
+ GetHealthStatus.HealthStatusBuffer,
+ sizeof(DAC960_V2_HealthStatusBuffer_T));
+ if (ErrorCode != 0) return ErrorCode;
+ while (Controller->V2.HealthStatusBuffer->StatusChangeCounter
+ == HealthStatusBuffer.StatusChangeCounter &&
+ Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
+ == HealthStatusBuffer.NextEventSequenceNumber)
+ {
+ interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue,
+ DAC960_MonitoringTimerInterval);
+ if (signal_pending(current)) return -EINTR;
+ }
+ ErrorCode = copy_to_user(GetHealthStatus.HealthStatusBuffer,
+ Controller->V2.HealthStatusBuffer,
+ sizeof(DAC960_V2_HealthStatusBuffer_T));
return ErrorCode;
}
}
@@ -2987,28 +5393,29 @@ int DAC960_KernelIOCTL(unsigned int Request, void *Argument)
ControllerNumber > DAC960_ControllerCount - 1)
return -ENXIO;
Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL)
- return -ENXIO;
+ if (Controller == NULL) return -ENXIO;
memset(ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
ControllerInfo->ControllerNumber = ControllerNumber;
+ ControllerInfo->FirmwareType = Controller->FirmwareType;
+ ControllerInfo->Channels = Controller->Channels;
+ ControllerInfo->Targets = Controller->Targets;
ControllerInfo->PCI_Bus = Controller->Bus;
ControllerInfo->PCI_Device = Controller->Device;
ControllerInfo->PCI_Function = Controller->Function;
ControllerInfo->IRQ_Channel = Controller->IRQ_Channel;
- ControllerInfo->Channels = Controller->Channels;
ControllerInfo->PCI_Address = Controller->PCI_Address;
strcpy(ControllerInfo->ModelName, Controller->ModelName);
strcpy(ControllerInfo->FirmwareVersion, Controller->FirmwareVersion);
return 0;
}
- case DAC960_IOCTL_EXECUTE_COMMAND:
+ case DAC960_IOCTL_V1_EXECUTE_COMMAND:
{
- DAC960_KernelCommand_T *KernelCommand =
- (DAC960_KernelCommand_T *) Argument;
+ DAC960_V1_KernelCommand_T *KernelCommand =
+ (DAC960_V1_KernelCommand_T *) Argument;
DAC960_Controller_T *Controller;
DAC960_Command_T *Command = NULL;
- DAC960_CommandOpcode_T CommandOpcode;
- DAC960_DCDB_T *DCDB = NULL;
+ DAC960_V1_CommandOpcode_T CommandOpcode;
+ DAC960_V1_DCDB_T *DCDB = NULL;
ProcessorFlags_T ProcessorFlags;
int ControllerNumber, DataTransferLength;
unsigned char *DataTransferBuffer = NULL;
@@ -3018,21 +5425,23 @@ int DAC960_KernelIOCTL(unsigned int Request, void *Argument)
ControllerNumber > DAC960_ControllerCount - 1)
return -ENXIO;
Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL)
- return -ENXIO;
+ if (Controller == NULL) return -ENXIO;
+ if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
CommandOpcode = KernelCommand->CommandMailbox.Common.CommandOpcode;
DataTransferLength = KernelCommand->DataTransferLength;
DataTransferBuffer = KernelCommand->DataTransferBuffer;
if (CommandOpcode & 0x80) return -EINVAL;
- if (CommandOpcode == DAC960_DCDB)
+ if (CommandOpcode == DAC960_V1_DCDB)
{
DCDB = KernelCommand->DCDB;
if (!((DataTransferLength == 0 &&
- DCDB->Direction == DAC960_DCDB_NoDataTransfer) ||
+ DCDB->Direction == DAC960_V1_DCDB_NoDataTransfer) ||
(DataTransferLength > 0 &&
- DCDB->Direction == DAC960_DCDB_DataTransferDeviceToSystem) ||
+ DCDB->Direction
+ == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
(DataTransferLength < 0 &&
- DCDB->Direction == DAC960_DCDB_DataTransferSystemToDevice)))
+ DCDB->Direction
+ == DAC960_V1_DCDB_DataTransferSystemToDevice)))
return -EINVAL;
if (((DCDB->TransferLengthHigh4 << 16) | DCDB->TransferLength)
!= abs(DataTransferLength))
@@ -3042,25 +5451,26 @@ int DAC960_KernelIOCTL(unsigned int Request, void *Argument)
return -EINVAL;
if (DataTransferLength > 0)
memset(DataTransferBuffer, 0, DataTransferLength);
- if (CommandOpcode == DAC960_DCDB)
+ if (CommandOpcode == DAC960_V1_DCDB)
{
DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- if (!Controller->DirectCommandActive[DCDB->Channel]
- [DCDB->TargetID])
+ if (!Controller->V1.DirectCommandActive[DCDB->Channel]
+ [DCDB->TargetID])
Command = DAC960_AllocateCommand(Controller);
if (Command == NULL)
{
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
return -EBUSY;
}
- else Controller->DirectCommandActive[DCDB->Channel]
- [DCDB->TargetID] = true;
- DAC960_ClearCommand(Command);
+ else Controller->V1.DirectCommandActive[DCDB->Channel]
+ [DCDB->TargetID] = true;
+ DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_QueuedCommand;
- memcpy(&Command->CommandMailbox, &KernelCommand->CommandMailbox,
- sizeof(DAC960_CommandMailbox_T));
- Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
- Command->KernelCommand = KernelCommand;
+ memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
+ sizeof(DAC960_V1_CommandMailbox_T));
+ Command->V1.CommandMailbox.Type3.BusAddress =
+ Virtual_to_Bus(DCDB);
+ Command->V1.KernelCommand = KernelCommand;
DCDB->BusAddress = Virtual_to_Bus(DataTransferBuffer);
DAC960_QueueCommand(Command);
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
@@ -3074,44 +5484,153 @@ int DAC960_KernelIOCTL(unsigned int Request, void *Argument)
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
return -EBUSY;
}
- DAC960_ClearCommand(Command);
+ DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_QueuedCommand;
- memcpy(&Command->CommandMailbox, &KernelCommand->CommandMailbox,
- sizeof(DAC960_CommandMailbox_T));
+ memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
+ sizeof(DAC960_V1_CommandMailbox_T));
if (DataTransferBuffer != NULL)
- Command->CommandMailbox.Type3.BusAddress =
+ Command->V1.CommandMailbox.Type3.BusAddress =
Virtual_to_Bus(DataTransferBuffer);
- Command->KernelCommand = KernelCommand;
+ Command->V1.KernelCommand = KernelCommand;
DAC960_QueueCommand(Command);
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
}
return 0;
}
+ case DAC960_IOCTL_V2_EXECUTE_COMMAND:
+ {
+ DAC960_V2_KernelCommand_T *KernelCommand =
+ (DAC960_V2_KernelCommand_T *) Argument;
+ DAC960_Controller_T *Controller;
+ DAC960_Command_T *Command = NULL;
+ DAC960_V2_CommandMailbox_T *CommandMailbox;
+ ProcessorFlags_T ProcessorFlags;
+ int ControllerNumber, DataTransferLength, RequestSenseLength;
+ unsigned char *DataTransferBuffer = NULL;
+ unsigned char *RequestSenseBuffer = NULL;
+ if (KernelCommand == NULL) return -EINVAL;
+ ControllerNumber = KernelCommand->ControllerNumber;
+ if (ControllerNumber < 0 ||
+ ControllerNumber > DAC960_ControllerCount - 1)
+ return -ENXIO;
+ Controller = DAC960_Controllers[ControllerNumber];
+ if (Controller == NULL) return -ENXIO;
+ if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+ DataTransferLength = KernelCommand->DataTransferLength;
+ RequestSenseLength = KernelCommand->RequestSenseLength;
+ DataTransferBuffer = KernelCommand->DataTransferBuffer;
+ RequestSenseBuffer = KernelCommand->RequestSenseBuffer;
+ if (DataTransferLength != 0 && DataTransferBuffer == NULL)
+ return -EINVAL;
+ if (RequestSenseLength < 0)
+ return -EINVAL;
+ if (RequestSenseLength > 0 && RequestSenseBuffer == NULL)
+ return -EINVAL;
+ if (DataTransferLength > 0)
+ memset(DataTransferBuffer, 0, DataTransferLength);
+ if (RequestSenseLength > 0)
+ memset(RequestSenseBuffer, 0, RequestSenseLength);
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ Command = DAC960_AllocateCommand(Controller);
+ if (Command == NULL)
+ {
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+ return -EBUSY;
+ }
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_QueuedCommand;
+ CommandMailbox = &Command->V2.CommandMailbox;
+ memcpy(CommandMailbox, &KernelCommand->CommandMailbox,
+ sizeof(DAC960_V2_CommandMailbox_T));
+ CommandMailbox->Common.CommandControlBits
+ .AdditionalScatterGatherListMemory = false;
+ CommandMailbox->Common.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->Common.DataTransferSize = 0;
+ CommandMailbox->Common.DataTransferPageNumber = 0;
+ memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
+ sizeof(DAC960_V2_DataTransferMemoryAddress_T));
+ if (DataTransferLength != 0)
+ {
+ if (DataTransferLength > 0)
+ {
+ CommandMailbox->Common.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->Common.DataTransferSize = DataTransferLength;
+ }
+ else
+ {
+ CommandMailbox->Common.CommandControlBits
+ .DataTransferControllerToHost = false;
+ CommandMailbox->Common.DataTransferSize = -DataTransferLength;
+ }
+ CommandMailbox->Common.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(DataTransferBuffer);
+ CommandMailbox->Common.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->Common.DataTransferSize;
+ }
+ if (RequestSenseLength > 0)
+ {
+ CommandMailbox->Common.CommandControlBits
+ .NoAutoRequestSense = false;
+ CommandMailbox->Common.RequestSenseBusAddress =
+ Virtual_to_Bus(RequestSenseBuffer);
+ }
+ Command->V2.KernelCommand = KernelCommand;
+ DAC960_QueueCommand(Command);
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+ return 0;
+ }
}
return -EINVAL;
}
/*
- DAC960_GenericDiskInit is the Generic Disk Information Initialization
- Function for the DAC960 Driver.
+ DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount
+ additional bytes in the Combined Status Buffer and grows the buffer if
+ necessary. It returns true if there is enough room and false otherwise.
*/
-static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
+static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
+ unsigned int ByteCount)
{
- DAC960_Controller_T *Controller =
- (DAC960_Controller_T *) GenericDiskInfo->real_devices;
- DAC960_LogicalDriveInformation_T *LogicalDriveInformation =
- Controller->LogicalDriveInformation
- [Controller->LogicalDriveInformationIndex];
- int LogicalDriveNumber;
- for (LogicalDriveNumber = 0;
- LogicalDriveNumber < Controller->LogicalDriveCount;
- LogicalDriveNumber++)
- register_disk(GenericDiskInfo, MKDEV(GenericDiskInfo->major,
- LogicalDriveNumber*DAC960_MaxPartitions),
- DAC960_MaxPartitions, &DAC960_FileOperations,
- LogicalDriveInformation[LogicalDriveNumber].LogicalDriveSize);
+ unsigned char *NewStatusBuffer;
+ if (Controller->InitialStatusLength + 1 +
+ Controller->CurrentStatusLength + ByteCount + 1 <=
+ Controller->CombinedStatusBufferLength)
+ return true;
+ if (Controller->CombinedStatusBufferLength == 0)
+ {
+ unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize;
+ while (NewStatusBufferLength < ByteCount)
+ NewStatusBufferLength *= 2;
+ Controller->CombinedStatusBuffer =
+ (unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC);
+ if (Controller->CombinedStatusBuffer == NULL) return false;
+ Controller->CombinedStatusBufferLength = NewStatusBufferLength;
+ return true;
+ }
+ NewStatusBuffer = (unsigned char *)
+ kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC);
+ if (NewStatusBuffer == NULL)
+ {
+ DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n",
+ Controller);
+ return false;
+ }
+ memcpy(NewStatusBuffer, Controller->CombinedStatusBuffer,
+ Controller->CombinedStatusBufferLength);
+ kfree(Controller->CombinedStatusBuffer);
+ Controller->CombinedStatusBuffer = NewStatusBuffer;
+ Controller->CombinedStatusBufferLength *= 2;
+ Controller->CurrentStatusBuffer =
+ &NewStatusBuffer[Controller->InitialStatusLength + 1];
+ return true;
}
@@ -3120,11 +5639,11 @@ static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
*/
static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
- char *Format,
+ unsigned char *Format,
DAC960_Controller_T *Controller,
...)
{
- static char Buffer[DAC960_LineBufferSize];
+ static unsigned char Buffer[DAC960_LineBufferSize];
static boolean BeginningOfLine = true;
va_list Arguments;
int Length = 0;
@@ -3139,9 +5658,16 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
{
if (!Controller->ControllerInitialized)
{
- strcpy(&Controller->InitialStatusBuffer[
- Controller->InitialStatusLength], Buffer);
- Controller->InitialStatusLength += Length;
+ if (DAC960_CheckStatusBuffer(Controller, Length))
+ {
+ strcpy(&Controller->CombinedStatusBuffer
+ [Controller->InitialStatusLength],
+ Buffer);
+ Controller->InitialStatusLength += Length;
+ Controller->CurrentStatusBuffer =
+ &Controller->CombinedStatusBuffer
+ [Controller->InitialStatusLength + 1];
+ }
if (MessageLevel == DAC960_AnnounceLevel)
{
static int AnnouncementLines = 0;
@@ -3161,7 +5687,7 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
else printk("%s", Buffer);
}
}
- else
+ else if (DAC960_CheckStatusBuffer(Controller, Length))
{
strcpy(&Controller->CurrentStatusBuffer[
Controller->CurrentStatusLength], Buffer);
@@ -3170,8 +5696,8 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
}
else if (MessageLevel == DAC960_ProgressLevel)
{
- strcpy(Controller->RebuildProgressBuffer, Buffer);
- Controller->RebuildProgressLength = Length;
+ strcpy(Controller->ProgressBuffer, Buffer);
+ Controller->ProgressBufferLength = Length;
if (Controller->EphemeralProgressMessage)
{
if (jiffies - Controller->LastProgressReportTime
@@ -3206,15 +5732,15 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
/*
- DAC960_ParsePhysicalDrive parses spaces followed by a Physical Drive
+ DAC960_ParsePhysicalDevice parses spaces followed by a Physical Device
Channel:TargetID specification from a User Command string. It updates
- Channel and TargetID and returns true on success and returns false otherwise.
+ Channel and TargetID and returns true on success and false on failure.
*/
-static boolean DAC960_ParsePhysicalDrive(DAC960_Controller_T *Controller,
- char *UserCommandString,
- unsigned char *Channel,
- unsigned char *TargetID)
+static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
+ char *UserCommandString,
+ unsigned char *Channel,
+ unsigned char *TargetID)
{
char *NewUserCommandString = UserCommandString;
unsigned long XChannel, XTargetID;
@@ -3230,7 +5756,7 @@ static boolean DAC960_ParsePhysicalDrive(DAC960_Controller_T *Controller,
XTargetID = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
if (NewUserCommandString == UserCommandString ||
*NewUserCommandString != '\0' ||
- XTargetID >= DAC960_MaxTargets)
+ XTargetID >= Controller->Targets)
return false;
*Channel = XChannel;
*TargetID = XTargetID;
@@ -3241,7 +5767,7 @@ static boolean DAC960_ParsePhysicalDrive(DAC960_Controller_T *Controller,
/*
DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number
specification from a User Command string. It updates LogicalDriveNumber and
- returns true on success and returns false otherwise.
+ returns true on success and false on failure.
*/
static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
@@ -3257,7 +5783,7 @@ static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
simple_strtoul(UserCommandString, &NewUserCommandString, 10);
if (NewUserCommandString == UserCommandString ||
*NewUserCommandString != '\0' ||
- XLogicalDriveNumber >= Controller->LogicalDriveCount)
+ XLogicalDriveNumber > DAC960_MaxLogicalDrives - 1)
return false;
*LogicalDriveNumber = XLogicalDriveNumber;
return true;
@@ -3265,68 +5791,71 @@ static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
/*
- DAC960_SetDeviceState sets the Device State for a Physical Drive.
+ DAC960_V1_SetDeviceState sets the Device State for a Physical Device for
+ DAC960 V1 Firmware Controllers.
*/
-static void DAC960_SetDeviceState(DAC960_Controller_T *Controller,
- DAC960_Command_T *Command,
- unsigned char Channel,
- unsigned char TargetID,
- DAC960_PhysicalDeviceState_T DeviceState,
- const char *DeviceStateString)
+static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller,
+ DAC960_Command_T *Command,
+ unsigned char Channel,
+ unsigned char TargetID,
+ DAC960_V1_PhysicalDeviceState_T
+ DeviceState,
+ const unsigned char *DeviceStateString)
{
- DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
- CommandMailbox->Type3D.CommandOpcode = DAC960_StartDevice;
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ CommandMailbox->Type3D.CommandOpcode = DAC960_V1_StartDevice;
CommandMailbox->Type3D.Channel = Channel;
CommandMailbox->Type3D.TargetID = TargetID;
CommandMailbox->Type3D.DeviceState = DeviceState;
CommandMailbox->Type3D.Modifier = 0;
DAC960_ExecuteCommand(Command);
- switch (Command->CommandStatus)
+ switch (Command->V1.CommandStatus)
{
- case DAC960_NormalCompletion:
- DAC960_UserCritical("%s of Physical Drive %d:%d Succeeded\n", Controller,
+ case DAC960_V1_NormalCompletion:
+ DAC960_UserCritical("%s of Physical Device %d:%d Succeeded\n", Controller,
DeviceStateString, Channel, TargetID);
break;
- case DAC960_UnableToStartDevice:
- DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+ case DAC960_V1_UnableToStartDevice:
+ DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
"Unable to Start Device\n", Controller,
DeviceStateString, Channel, TargetID);
break;
- case DAC960_NoDeviceAtAddress:
- DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+ case DAC960_V1_NoDeviceAtAddress:
+ DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
"No Device at Address\n", Controller,
DeviceStateString, Channel, TargetID);
break;
- case DAC960_InvalidChannelOrTargetOrModifier:
- DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+ case DAC960_V1_InvalidChannelOrTargetOrModifier:
+ DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
"Invalid Channel or Target or Modifier\n",
Controller, DeviceStateString, Channel, TargetID);
break;
- case DAC960_ChannelBusy:
- DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+ case DAC960_V1_ChannelBusy:
+ DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
"Channel Busy\n", Controller,
DeviceStateString, Channel, TargetID);
break;
default:
- DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+ DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
"Unexpected Status %04X\n", Controller,
DeviceStateString, Channel, TargetID,
- Command->CommandStatus);
+ Command->V1.CommandStatus);
break;
}
}
/*
- DAC960_ExecuteUserCommand executes a User Command.
+ DAC960_V1_ExecuteUserCommand executes a User Command for DAC960 V1 Firmware
+ Controllers.
*/
-static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
- char *UserCommand)
+static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
+ unsigned char *UserCommand)
{
DAC960_Command_T *Command;
- DAC960_CommandMailbox_T *CommandMailbox;
+ DAC960_V1_CommandMailbox_T *CommandMailbox;
ProcessorFlags_T ProcessorFlags;
unsigned char Channel, TargetID, LogicalDriveNumber;
DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
@@ -3334,100 +5863,98 @@ static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
DAC960_WaitForCommand(Controller);
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
Controller->UserStatusLength = 0;
- DAC960_ClearCommand(Command);
+ DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
- CommandMailbox = &Command->CommandMailbox;
+ CommandMailbox = &Command->V1.CommandMailbox;
if (strcmp(UserCommand, "flush-cache") == 0)
{
- CommandMailbox->Type3.CommandOpcode = DAC960_Flush;
+ CommandMailbox->Type3.CommandOpcode = DAC960_V1_Flush;
DAC960_ExecuteCommand(Command);
DAC960_UserCritical("Cache Flush Completed\n", Controller);
}
else if (strncmp(UserCommand, "kill", 4) == 0 &&
- DAC960_ParsePhysicalDrive(Controller, &UserCommand[4],
- &Channel, &TargetID))
+ DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
+ &Channel, &TargetID))
{
- DAC960_DeviceState_T *DeviceState =
- &Controller->DeviceState[Controller->DeviceStateIndex]
- [Channel][TargetID];
+ DAC960_V1_DeviceState_T *DeviceState =
+ &Controller->V1.DeviceState[Channel][TargetID];
if (DeviceState->Present &&
- DeviceState->DeviceType == DAC960_DiskType &&
- DeviceState->DeviceState != DAC960_Device_Dead)
- DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
- DAC960_Device_Dead, "Kill");
- else DAC960_UserCritical("Kill of Physical Drive %d:%d Illegal\n",
+ DeviceState->DeviceType == DAC960_V1_DiskType &&
+ DeviceState->DeviceState != DAC960_V1_Device_Dead)
+ DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
+ DAC960_V1_Device_Dead, "Kill");
+ else DAC960_UserCritical("Kill of Physical Device %d:%d Illegal\n",
Controller, Channel, TargetID);
}
else if (strncmp(UserCommand, "make-online", 11) == 0 &&
- DAC960_ParsePhysicalDrive(Controller, &UserCommand[11],
- &Channel, &TargetID))
+ DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
+ &Channel, &TargetID))
{
- DAC960_DeviceState_T *DeviceState =
- &Controller->DeviceState[Controller->DeviceStateIndex]
- [Channel][TargetID];
+ DAC960_V1_DeviceState_T *DeviceState =
+ &Controller->V1.DeviceState[Channel][TargetID];
if (DeviceState->Present &&
- DeviceState->DeviceType == DAC960_DiskType &&
- DeviceState->DeviceState == DAC960_Device_Dead)
- DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
- DAC960_Device_Online, "Make Online");
- else DAC960_UserCritical("Make Online of Physical Drive %d:%d Illegal\n",
+ DeviceState->DeviceType == DAC960_V1_DiskType &&
+ DeviceState->DeviceState == DAC960_V1_Device_Dead)
+ DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
+ DAC960_V1_Device_Online, "Make Online");
+ else DAC960_UserCritical("Make Online of Physical Device %d:%d Illegal\n",
Controller, Channel, TargetID);
}
else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
- DAC960_ParsePhysicalDrive(Controller, &UserCommand[12],
- &Channel, &TargetID))
+ DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
+ &Channel, &TargetID))
{
- DAC960_DeviceState_T *DeviceState =
- &Controller->DeviceState[Controller->DeviceStateIndex]
- [Channel][TargetID];
+ DAC960_V1_DeviceState_T *DeviceState =
+ &Controller->V1.DeviceState[Channel][TargetID];
if (DeviceState->Present &&
- DeviceState->DeviceType == DAC960_DiskType &&
- DeviceState->DeviceState == DAC960_Device_Dead)
- DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
- DAC960_Device_Standby, "Make Standby");
- else DAC960_UserCritical("Make Standby of Physical Drive %d:%d Illegal\n",
+ DeviceState->DeviceType == DAC960_V1_DiskType &&
+ DeviceState->DeviceState == DAC960_V1_Device_Dead)
+ DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
+ DAC960_V1_Device_Standby, "Make Standby");
+ else DAC960_UserCritical("Make Standby of Physical "
+ "Device %d:%d Illegal\n",
Controller, Channel, TargetID);
}
else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
- DAC960_ParsePhysicalDrive(Controller, &UserCommand[7],
- &Channel, &TargetID))
+ DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
+ &Channel, &TargetID))
{
- CommandMailbox->Type3D.CommandOpcode = DAC960_RebuildAsync;
+ CommandMailbox->Type3D.CommandOpcode = DAC960_V1_RebuildAsync;
CommandMailbox->Type3D.Channel = Channel;
CommandMailbox->Type3D.TargetID = TargetID;
DAC960_ExecuteCommand(Command);
- switch (Command->CommandStatus)
+ switch (Command->V1.CommandStatus)
{
- case DAC960_NormalCompletion:
- DAC960_UserCritical("Rebuild of Physical Drive %d:%d Initiated\n",
+ case DAC960_V1_NormalCompletion:
+ DAC960_UserCritical("Rebuild of Physical Device %d:%d Initiated\n",
Controller, Channel, TargetID);
break;
- case DAC960_AttemptToRebuildOnlineDrive:
- DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+ case DAC960_V1_AttemptToRebuildOnlineDrive:
+ DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
"Attempt to Rebuild Online or "
"Unresponsive Drive\n",
Controller, Channel, TargetID);
break;
- case DAC960_NewDiskFailedDuringRebuild:
- DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+ case DAC960_V1_NewDiskFailedDuringRebuild:
+ DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
"New Disk Failed During Rebuild\n",
Controller, Channel, TargetID);
break;
- case DAC960_InvalidDeviceAddress:
- DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+ case DAC960_V1_InvalidDeviceAddress:
+ DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
"Invalid Device Address\n",
Controller, Channel, TargetID);
break;
- case DAC960_RebuildOrCheckAlreadyInProgress:
- DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+ case DAC960_V1_RebuildOrCheckAlreadyInProgress:
+ DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
"Rebuild or Consistency Check Already "
"in Progress\n", Controller, Channel, TargetID);
break;
default:
- DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+ DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
"Unexpected Status %04X\n", Controller,
- Channel, TargetID, Command->CommandStatus);
+ Channel, TargetID, Command->V1.CommandStatus);
break;
}
}
@@ -3435,28 +5962,28 @@ static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
&LogicalDriveNumber))
{
- CommandMailbox->Type3C.CommandOpcode = DAC960_CheckConsistencyAsync;
+ CommandMailbox->Type3C.CommandOpcode = DAC960_V1_CheckConsistencyAsync;
CommandMailbox->Type3C.LogicalDriveNumber = LogicalDriveNumber;
CommandMailbox->Type3C.AutoRestore = true;
DAC960_ExecuteCommand(Command);
- switch (Command->CommandStatus)
+ switch (Command->V1.CommandStatus)
{
- case DAC960_NormalCompletion:
+ case DAC960_V1_NormalCompletion:
DAC960_UserCritical("Consistency Check of Logical Drive %d "
"(/dev/rd/c%dd%d) Initiated\n",
Controller, LogicalDriveNumber,
Controller->ControllerNumber,
LogicalDriveNumber);
break;
- case DAC960_DependentDiskIsDead:
+ case DAC960_V1_DependentDiskIsDead:
DAC960_UserCritical("Consistency Check of Logical Drive %d "
"(/dev/rd/c%dd%d) Failed - "
- "Dependent Physical Drive is DEAD\n",
+ "Dependent Physical Device is DEAD\n",
Controller, LogicalDriveNumber,
Controller->ControllerNumber,
LogicalDriveNumber);
break;
- case DAC960_InvalidOrNonredundantLogicalDrive:
+ case DAC960_V1_InvalidOrNonredundantLogicalDrive:
DAC960_UserCritical("Consistency Check of Logical Drive %d "
"(/dev/rd/c%dd%d) Failed - "
"Invalid or Nonredundant Logical Drive\n",
@@ -3464,7 +5991,7 @@ static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
Controller->ControllerNumber,
LogicalDriveNumber);
break;
- case DAC960_RebuildOrCheckAlreadyInProgress:
+ case DAC960_V1_RebuildOrCheckAlreadyInProgress:
DAC960_UserCritical("Consistency Check of Logical Drive %d "
"(/dev/rd/c%dd%d) Failed - Rebuild or "
"Consistency Check Already in Progress\n",
@@ -3478,7 +6005,7 @@ static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
"Unexpected Status %04X\n",
Controller, LogicalDriveNumber,
Controller->ControllerNumber,
- LogicalDriveNumber, Command->CommandStatus);
+ LogicalDriveNumber, Command->V1.CommandStatus);
break;
}
}
@@ -3486,14 +6013,14 @@ static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
strcmp(UserCommand, "cancel-consistency-check") == 0)
{
unsigned char OldRebuildRateConstant;
- CommandMailbox->Type3R.CommandOpcode = DAC960_RebuildControl;
+ CommandMailbox->Type3R.CommandOpcode = DAC960_V1_RebuildControl;
CommandMailbox->Type3R.RebuildRateConstant = 0xFF;
CommandMailbox->Type3R.BusAddress =
Virtual_to_Bus(&OldRebuildRateConstant);
DAC960_ExecuteCommand(Command);
- switch (Command->CommandStatus)
+ switch (Command->V1.CommandStatus)
{
- case DAC960_NormalCompletion:
+ case DAC960_V1_NormalCompletion:
DAC960_UserCritical("Rebuild or Consistency Check Cancelled\n",
Controller);
break;
@@ -3501,7 +6028,7 @@ static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
DAC960_UserCritical("Cancellation of Rebuild or "
"Consistency Check Failed - "
"Unexpected Status %04X\n",
- Controller, Command->CommandStatus);
+ Controller, Command->V1.CommandStatus);
break;
}
}
@@ -3515,25 +6042,235 @@ static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
/*
+ DAC960_V2_TranslatePhysicalDevice translates a Physical Device Channel and
+ TargetID into a Logical Device. It returns true on success and false
+ on failure.
+*/
+
+static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
+ unsigned char Channel,
+ unsigned char TargetID,
+ unsigned short
+ *LogicalDeviceNumber)
+{
+ DAC960_V2_CommandMailbox_T SavedCommandMailbox, *CommandMailbox;
+ DAC960_V2_PhysicalToLogicalDevice_T PhysicalToLogicalDevice;
+ CommandMailbox = &Command->V2.CommandMailbox;
+ memcpy(&SavedCommandMailbox, CommandMailbox,
+ sizeof(DAC960_V2_CommandMailbox_T));
+ CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
+ sizeof(DAC960_V2_PhysicalToLogicalDevice_T);
+ CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
+ CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
+ CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
+ DAC960_V2_TranslatePhysicalToLogicalDevice;
+ CommandMailbox->Common.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus(&PhysicalToLogicalDevice);
+ CommandMailbox->Common.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->Common.DataTransferSize;
+ DAC960_ExecuteCommand(Command);
+ memcpy(CommandMailbox, &SavedCommandMailbox,
+ sizeof(DAC960_V2_CommandMailbox_T));
+ *LogicalDeviceNumber = PhysicalToLogicalDevice.LogicalDeviceNumber;
+ return (Command->V2.CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+ DAC960_V2_ExecuteUserCommand executes a User Command for DAC960 V2 Firmware
+ Controllers.
+*/
+
+static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
+ unsigned char *UserCommand)
+{
+ DAC960_Command_T *Command;
+ DAC960_V2_CommandMailbox_T *CommandMailbox;
+ ProcessorFlags_T ProcessorFlags;
+ unsigned char Channel, TargetID, LogicalDriveNumber;
+ unsigned short LogicalDeviceNumber;
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
+ DAC960_WaitForCommand(Controller);
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+ Controller->UserStatusLength = 0;
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_ImmediateCommand;
+ CommandMailbox = &Command->V2.CommandMailbox;
+ CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->Common.CommandControlBits.DataTransferControllerToHost = true;
+ CommandMailbox->Common.CommandControlBits.NoAutoRequestSense = true;
+ if (strcmp(UserCommand, "flush-cache") == 0)
+ {
+ CommandMailbox->DeviceOperation.IOCTL_Opcode = DAC960_V2_PauseDevice;
+ CommandMailbox->DeviceOperation.OperationDevice =
+ DAC960_V2_RAID_Controller;
+ DAC960_ExecuteCommand(Command);
+ DAC960_UserCritical("Cache Flush Completed\n", Controller);
+ }
+ else if (strncmp(UserCommand, "kill", 4) == 0 &&
+ DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
+ &Channel, &TargetID) &&
+ DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+ &LogicalDeviceNumber))
+ {
+ CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
+ LogicalDeviceNumber;
+ CommandMailbox->SetDeviceState.IOCTL_Opcode =
+ DAC960_V2_SetDeviceState;
+ CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
+ DAC960_V2_Device_Dead;
+ DAC960_ExecuteCommand(Command);
+ DAC960_UserCritical("Kill of Physical Device %d:%d %s\n",
+ Controller, Channel, TargetID,
+ (Command->V2.CommandStatus
+ == DAC960_V2_NormalCompletion
+ ? "Succeeded" : "Failed"));
+ }
+ else if (strncmp(UserCommand, "make-online", 11) == 0 &&
+ DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
+ &Channel, &TargetID) &&
+ DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+ &LogicalDeviceNumber))
+ {
+ CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
+ LogicalDeviceNumber;
+ CommandMailbox->SetDeviceState.IOCTL_Opcode =
+ DAC960_V2_SetDeviceState;
+ CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
+ DAC960_V2_Device_Online;
+ DAC960_ExecuteCommand(Command);
+ DAC960_UserCritical("Make Online of Physical Device %d:%d %s\n",
+ Controller, Channel, TargetID,
+ (Command->V2.CommandStatus
+ == DAC960_V2_NormalCompletion
+ ? "Succeeded" : "Failed"));
+ }
+ else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
+ DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
+ &Channel, &TargetID) &&
+ DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+ &LogicalDeviceNumber))
+ {
+ CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
+ LogicalDeviceNumber;
+ CommandMailbox->SetDeviceState.IOCTL_Opcode =
+ DAC960_V2_SetDeviceState;
+ CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
+ DAC960_V2_Device_Standby;
+ DAC960_ExecuteCommand(Command);
+ DAC960_UserCritical("Make Standby of Physical Device %d:%d %s\n",
+ Controller, Channel, TargetID,
+ (Command->V2.CommandStatus
+ == DAC960_V2_NormalCompletion
+ ? "Succeeded" : "Failed"));
+ }
+ else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
+ DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
+ &Channel, &TargetID) &&
+ DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+ &LogicalDeviceNumber))
+ {
+ CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+ LogicalDeviceNumber;
+ CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
+ DAC960_V2_RebuildDeviceStart;
+ DAC960_ExecuteCommand(Command);
+ DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
+ Controller, Channel, TargetID,
+ (Command->V2.CommandStatus
+ == DAC960_V2_NormalCompletion
+ ? "Initiated" : "Not Initiated"));
+ }
+ else if (strncmp(UserCommand, "cancel-rebuild", 14) == 0 &&
+ DAC960_ParsePhysicalDevice(Controller, &UserCommand[14],
+ &Channel, &TargetID) &&
+ DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+ &LogicalDeviceNumber))
+ {
+ CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+ LogicalDeviceNumber;
+ CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
+ DAC960_V2_RebuildDeviceStop;
+ DAC960_ExecuteCommand(Command);
+ DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
+ Controller, Channel, TargetID,
+ (Command->V2.CommandStatus
+ == DAC960_V2_NormalCompletion
+ ? "Cancelled" : "Not Cancelled"));
+ }
+ else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
+ DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
+ &LogicalDriveNumber))
+ {
+ CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
+ LogicalDriveNumber;
+ CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
+ DAC960_V2_ConsistencyCheckStart;
+ CommandMailbox->ConsistencyCheck.RestoreConsistency = true;
+ CommandMailbox->ConsistencyCheck.InitializedAreaOnly = false;
+ DAC960_ExecuteCommand(Command);
+ DAC960_UserCritical("Consistency Check of Logical Drive %d "
+ "(/dev/rd/c%dd%d) %s\n",
+ Controller, LogicalDriveNumber,
+ Controller->ControllerNumber,
+ LogicalDriveNumber,
+ (Command->V2.CommandStatus
+ == DAC960_V2_NormalCompletion
+ ? "Initiated" : "Not Initiated"));
+ }
+ else if (strncmp(UserCommand, "cancel-consistency-check", 24) == 0 &&
+ DAC960_ParseLogicalDrive(Controller, &UserCommand[24],
+ &LogicalDriveNumber))
+ {
+ CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
+ LogicalDriveNumber;
+ CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
+ DAC960_V2_ConsistencyCheckStop;
+ DAC960_ExecuteCommand(Command);
+ DAC960_UserCritical("Consistency Check of Logical Drive %d "
+ "(/dev/rd/c%dd%d) %s\n",
+ Controller, LogicalDriveNumber,
+ Controller->ControllerNumber,
+ LogicalDriveNumber,
+ (Command->V2.CommandStatus
+ == DAC960_V2_NormalCompletion
+ ? "Cancelled" : "Not Cancelled"));
+ }
+ else DAC960_UserCritical("Illegal User Command: '%s'\n",
+ Controller, UserCommand);
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ DAC960_DeallocateCommand(Command);
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+ return true;
+}
+
+
+/*
DAC960_ProcReadStatus implements reading /proc/rd/status.
*/
static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
int Count, int *EOF, void *Data)
{
- char *StatusMessage = "OK\n";
+ unsigned char *StatusMessage = "OK\n";
int ControllerNumber, BytesAvailable;
for (ControllerNumber = 0;
ControllerNumber < DAC960_ControllerCount;
ControllerNumber++)
{
DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
- DAC960_Enquiry_T *Enquiry;
if (Controller == NULL) continue;
- Enquiry = &Controller->Enquiry[Controller->EnquiryIndex];
- if (Enquiry->CriticalLogicalDriveCount > 0 ||
- Enquiry->OfflineLogicalDriveCount > 0 ||
- Enquiry->DeadDriveCount > 0)
+ if (Controller->MonitoringAlertMode)
{
StatusMessage = "ALERT\n";
break;
@@ -3568,7 +6305,7 @@ static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset,
}
if (Count <= 0) return 0;
*Start = Page;
- memcpy(Page, &Controller->InitialStatusBuffer[Offset], Count);
+ memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
return Count;
}
@@ -3581,6 +6318,9 @@ static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
int Count, int *EOF, void *Data)
{
DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
+ unsigned char *StatusMessage =
+ "No Rebuild or Consistency Check in Progress\n";
+ int ProgressMessageLength = strlen(StatusMessage);
int BytesAvailable;
if (jiffies != Controller->LastCurrentStatusTime)
{
@@ -3588,22 +6328,20 @@ static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
DAC960_AnnounceDriver(Controller);
DAC960_ReportControllerConfiguration(Controller);
DAC960_ReportDeviceConfiguration(Controller);
- Controller->CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
- Controller->CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
- if (Controller->RebuildProgressLength > 0)
- {
- strcpy(&Controller->CurrentStatusBuffer
- [Controller->CurrentStatusLength],
- Controller->RebuildProgressBuffer);
- Controller->CurrentStatusLength += Controller->RebuildProgressLength;
- }
- else
+ if (Controller->ProgressBufferLength > 0)
+ ProgressMessageLength = Controller->ProgressBufferLength;
+ if (DAC960_CheckStatusBuffer(Controller, 2 + ProgressMessageLength))
{
- char *StatusMessage = "No Rebuild or Consistency Check in Progress\n";
- strcpy(&Controller->CurrentStatusBuffer
- [Controller->CurrentStatusLength],
- StatusMessage);
- Controller->CurrentStatusLength += strlen(StatusMessage);
+ unsigned char *CurrentStatusBuffer = Controller->CurrentStatusBuffer;
+ CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
+ CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
+ if (Controller->ProgressBufferLength > 0)
+ strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
+ Controller->ProgressBuffer);
+ else
+ strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
+ StatusMessage);
+ Controller->CurrentStatusLength += ProgressMessageLength;
}
Controller->LastCurrentStatusTime = jiffies;
}
@@ -3649,7 +6387,7 @@ static int DAC960_ProcWriteUserCommand(File_T *File, const char *Buffer,
unsigned long Count, void *Data)
{
DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
- char CommandBuffer[80];
+ unsigned char CommandBuffer[80];
int Length;
if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
copy_from_user(CommandBuffer, Buffer, Count);
@@ -3657,21 +6395,25 @@ static int DAC960_ProcWriteUserCommand(File_T *File, const char *Buffer,
Length = strlen(CommandBuffer);
if (CommandBuffer[Length-1] == '\n')
CommandBuffer[--Length] = '\0';
- return (DAC960_ExecuteUserCommand(Controller, CommandBuffer)
- ? Count : -EBUSY);
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer)
+ ? Count : -EBUSY);
+ else
+ return (DAC960_V2_ExecuteUserCommand(Controller, CommandBuffer)
+ ? Count : -EBUSY);
}
/*
- DAC960_CreateProcEntries creates the /proc/driver/rd/... entries
- for the DAC960 Driver.
+ DAC960_CreateProcEntries creates the /proc/rd/... entries for the
+ DAC960 Driver.
*/
static void DAC960_CreateProcEntries(void)
{
- static PROC_DirectoryEntry_T *StatusProcEntry;
+ PROC_DirectoryEntry_T *StatusProcEntry;
int ControllerNumber;
- DAC960_ProcDirectoryEntry = proc_mkdir("driver/rd", NULL);
+ DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
StatusProcEntry = create_proc_read_entry("status", 0,
DAC960_ProcDirectoryEntry,
DAC960_ProcReadStatus, NULL);
@@ -3684,29 +6426,42 @@ static void DAC960_CreateProcEntries(void)
PROC_DirectoryEntry_T *UserCommandProcEntry;
if (Controller == NULL) continue;
ControllerProcEntry = proc_mkdir(Controller->ControllerName,
- DAC960_ProcDirectoryEntry);
- create_proc_read_entry("initial_status",0,ControllerProcEntry,
+ DAC960_ProcDirectoryEntry);
+ create_proc_read_entry("initial_status", 0, ControllerProcEntry,
DAC960_ProcReadInitialStatus, Controller);
- create_proc_read_entry("current_status",0,ControllerProcEntry,
+ create_proc_read_entry("current_status", 0, ControllerProcEntry,
DAC960_ProcReadCurrentStatus, Controller);
UserCommandProcEntry =
- create_proc_read_entry("user_command", S_IWUSR|S_IRUSR,
- ControllerProcEntry,
- DAC960_ProcReadUserCommand, Controller);
+ create_proc_read_entry("user_command", S_IWUSR | S_IRUSR,
+ ControllerProcEntry, DAC960_ProcReadUserCommand,
+ Controller);
UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
+ Controller->ControllerProcEntry = ControllerProcEntry;
}
}
/*
- DAC960_DestroyProcEntries destroys the /proc/rd/... entries for the DAC960
- Driver.
+ DAC960_DestroyProcEntries destroys the /proc/rd/... entries for the
+ DAC960 Driver.
*/
static void DAC960_DestroyProcEntries(void)
{
- /* FIXME */
- remove_proc_entry("driver/rd", NULL);
+ int ControllerNumber;
+ for (ControllerNumber = 0;
+ ControllerNumber < DAC960_ControllerCount;
+ ControllerNumber++)
+ {
+ DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
+ if (Controller == NULL) continue;
+ remove_proc_entry("initial_status", Controller->ControllerProcEntry);
+ remove_proc_entry("current_status", Controller->ControllerProcEntry);
+ remove_proc_entry("user_command", Controller->ControllerProcEntry);
+ remove_proc_entry(Controller->ControllerName, DAC960_ProcDirectoryEntry);
+ }
+ remove_proc_entry("rd/status", NULL);
+ remove_proc_entry("rd", NULL);
}
@@ -3719,18 +6474,8 @@ static void DAC960_DestroyProcEntries(void)
int init_module(void)
{
- int ControllerNumber;
DAC960_Initialize();
- if (DAC960_ActiveControllerCount == 0) return -1;
- for (ControllerNumber = 0;
- ControllerNumber < DAC960_ControllerCount;
- ControllerNumber++)
- {
- DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) continue;
- DAC960_InitializeGenericDiskInfo(&Controller->GenericDiskInfo);
- }
- return 0;
+ return (DAC960_ActiveControllerCount > 0 ? 0 : -1);
}