DAC960.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:257k
- /*
- Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
- Copyright 1998-2001 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
- Free Software Foundation.
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for complete details.
- The author respectfully requests that any modifications to this software be
- sent directly to him for evaluation and testing.
- */
- #define DAC960_DriverVersion "2.4.11"
- #define DAC960_DriverDate "11 October 2001"
- #include <linux/version.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/completion.h>
- #include <linux/delay.h>
- #include <linux/hdreg.h>
- #include <linux/blkpg.h>
- #include <linux/interrupt.h>
- #include <linux/ioport.h>
- #include <linux/locks.h>
- #include <linux/mm.h>
- #include <linux/slab.h>
- #include <linux/proc_fs.h>
- #include <linux/reboot.h>
- #include <linux/spinlock.h>
- #include <linux/timer.h>
- #include <linux/pci.h>
- #include <linux/init.h>
- #include <asm/io.h>
- #include <asm/segment.h>
- #include <asm/uaccess.h>
- #include "DAC960.h"
- /*
- DAC960_ControllerCount is the number of DAC960 Controllers detected.
- */
- static int
- DAC960_ControllerCount = 0;
- /*
- DAC960_ActiveControllerCount is the number of active DAC960 Controllers
- detected.
- */
- static int
- DAC960_ActiveControllerCount = 0;
- /*
- DAC960_Controllers is an array of pointers to the DAC960 Controller
- structures.
- */
- static DAC960_Controller_T
- *DAC960_Controllers[DAC960_MaxControllers] = { NULL };
- /*
- DAC960_BlockDeviceOperations is the Block Device Operations structure for
- DAC960 Logical Disk Devices.
- */
- static BlockDeviceOperations_T
- DAC960_BlockDeviceOperations =
- { owner: THIS_MODULE,
- open: DAC960_Open,
- release: DAC960_Release,
- ioctl: DAC960_IOCTL };
- /*
- DAC960_ProcDirectoryEntry is the DAC960 /proc/rd directory entry.
- */
- static PROC_DirectoryEntry_T
- *DAC960_ProcDirectoryEntry;
- /*
- DAC960_NotifierBlock is the Notifier Block structure for DAC960 Driver.
- */
- static NotifierBlock_T
- DAC960_NotifierBlock = { DAC960_Notifier, NULL, 0 };
- /*
- DAC960_AnnounceDriver announces the Driver Version and Date, Author's Name,
- Copyright Notice, and Electronic Mail Address.
- */
- static void DAC960_AnnounceDriver(DAC960_Controller_T *Controller)
- {
- DAC960_Announce("***** DAC960 RAID Driver Version "
- DAC960_DriverVersion " of "
- DAC960_DriverDate " *****n", Controller);
- DAC960_Announce("Copyright 1998-2001 by Leonard N. Zubkoff "
- "<lnz@dandelion.com>n", Controller);
- }
- /*
- DAC960_Failure prints a standardized error message, and then returns false.
- */
- static boolean DAC960_Failure(DAC960_Controller_T *Controller,
- unsigned char *ErrorMessage)
- {
- DAC960_Error("While configuring DAC960 PCI RAID Controller atn",
- Controller);
- if (Controller->IO_Address == 0)
- DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
- "PCI Address 0x%Xn", Controller,
- Controller->Bus, Controller->Device,
- Controller->Function, Controller->PCI_Address);
- else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
- "0x%X PCI Address 0x%Xn", Controller,
- Controller->Bus, Controller->Device,
- Controller->Function, Controller->IO_Address,
- Controller->PCI_Address);
- DAC960_Error("%s FAILED - DETACHINGn", Controller, ErrorMessage);
- return false;
- }
- /*
- DAC960_CreateAuxiliaryStructures allocates and initializes the auxiliary
- data structures for Controller. It returns true on success and false on
- failure.
- */
- static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
- {
- 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;
- }
- /*
- DAC960_AllocateCommand allocates a Command structure from Controller's
- free list. During driver initialization, a special initialization command
- has been placed on the free list to guarantee that command allocation can
- never fail.
- */
- static inline DAC960_Command_T *DAC960_AllocateCommand(DAC960_Controller_T
- *Controller)
- {
- DAC960_Command_T *Command = Controller->FreeCommands;
- if (Command == NULL) return NULL;
- Controller->FreeCommands = Command->Next;
- Command->Next = NULL;
- return Command;
- }
- /*
- DAC960_DeallocateCommand deallocates Command, returning it to Controller's
- free list.
- */
- static inline void DAC960_DeallocateCommand(DAC960_Command_T *Command)
- {
- DAC960_Controller_T *Controller = Command->Controller;
- Command->Next = Controller->FreeCommands;
- Controller->FreeCommands = Command;
- }
- /*
- DAC960_WaitForCommand waits for a wake_up on Controller's Command Wait Queue.
- */
- static void DAC960_WaitForCommand(DAC960_Controller_T *Controller)
- {
- spin_unlock_irq(&io_request_lock);
- __wait_event(Controller->CommandWaitQueue, Controller->FreeCommands);
- spin_lock_irq(&io_request_lock);
- }
- /*
- DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers.
- */
- static void DAC960_BA_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_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_LP_QueueCommand queues Command for DAC960 LP Series Controllers.
- */
- 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_P_QueueCommand queues Command for DAC960 P Series Controllers.
- */
- static void DAC960_P_QueueCommand(DAC960_Command_T *Command)
- {
- DAC960_Controller_T *Controller = Command->Controller;
- void *ControllerBaseAddress = Controller->BaseAddress;
- DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
- CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
- switch (CommandMailbox->Common.CommandOpcode)
- {
- case DAC960_V1_Enquiry:
- CommandMailbox->Common.CommandOpcode = DAC960_V1_Enquiry_Old;
- break;
- case DAC960_V1_GetDeviceState:
- CommandMailbox->Common.CommandOpcode = DAC960_V1_GetDeviceState_Old;
- break;
- case DAC960_V1_Read:
- CommandMailbox->Common.CommandOpcode = DAC960_V1_Read_Old;
- DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
- break;
- case DAC960_V1_Write:
- CommandMailbox->Common.CommandOpcode = DAC960_V1_Write_Old;
- DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
- break;
- case DAC960_V1_ReadWithScatterGather:
- CommandMailbox->Common.CommandOpcode =
- DAC960_V1_ReadWithScatterGather_Old;
- DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
- break;
- case DAC960_V1_WriteWithScatterGather:
- CommandMailbox->Common.CommandOpcode =
- DAC960_V1_WriteWithScatterGather_Old;
- DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
- break;
- default:
- break;
- }
- while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
- udelay(1);
- DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
- DAC960_PD_NewCommand(ControllerBaseAddress);
- }
- /*
- DAC960_ExecuteCommand executes Command and waits for completion.
- */
- static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
- {
- DAC960_Controller_T *Controller = Command->Controller;
- DECLARE_COMPLETION(Completion);
- unsigned long ProcessorFlags;
- Command->Completion = &Completion;
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- DAC960_QueueCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- if (in_interrupt()) return;
- wait_for_completion(&Completion);
- }
- /*
- 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_V1_ExecuteType3(DAC960_Controller_T *Controller,
- DAC960_V1_CommandOpcode_T CommandOpcode,
- void *DataPointer)
- {
- DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
- DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
- DAC960_V1_CommandStatus_T CommandStatus;
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_ImmediateCommand;
- CommandMailbox->Type3.CommandOpcode = CommandOpcode;
- CommandMailbox->Type3.BusAddress = Virtual_to_Bus32(DataPointer);
- DAC960_ExecuteCommand(Command);
- CommandStatus = Command->V1.CommandStatus;
- DAC960_DeallocateCommand(Command);
- return (CommandStatus == DAC960_V1_NormalCompletion);
- }
- /*
- DAC960_V1_ExecuteTypeB executes a DAC960 V1 Firmware Controller Type 3B
- Command and waits for completion. It returns true on success and false
- on failure.
- */
- static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
- DAC960_V1_CommandOpcode_T CommandOpcode,
- unsigned char CommandOpcode2,
- void *DataPointer)
- {
- DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
- DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
- DAC960_V1_CommandStatus_T CommandStatus;
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_ImmediateCommand;
- CommandMailbox->Type3B.CommandOpcode = CommandOpcode;
- CommandMailbox->Type3B.CommandOpcode2 = CommandOpcode2;
- CommandMailbox->Type3B.BusAddress = Virtual_to_Bus32(DataPointer);
- DAC960_ExecuteCommand(Command);
- CommandStatus = Command->V1.CommandStatus;
- DAC960_DeallocateCommand(Command);
- return (CommandStatus == DAC960_V1_NormalCompletion);
- }
- /*
- DAC960_V1_ExecuteType3D executes a DAC960 V1 Firmware Controller Type 3D
- Command and waits for completion. It returns true on success and false
- on failure.
- */
- 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_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_Bus32(DataPointer);
- DAC960_ExecuteCommand(Command);
- CommandStatus = Command->V1.CommandStatus;
- DAC960_DeallocateCommand(Command);
- return (CommandStatus == DAC960_V1_NormalCompletion);
- }
- /*
- 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_V2_GeneralInfo(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->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_Bus64(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_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_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_Bus64(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_Bus64(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_Bus64(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_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;
- 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_PG_RestoreMemoryMailboxInfo(Controller,
- &SavedMemoryMailboxesAddress,
- &NextCommandMailboxIndex,
- &NextStatusMailboxIndex);
- if (SavedMemoryMailboxesAddress == NULL)
- {
- MemoryMailboxPagesAddress =
- __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
- Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
- CommandMailboxesMemory =
- (DAC960_V1_CommandMailbox_T *) MemoryMailboxPagesAddress;
- }
- else CommandMailboxesMemory = SavedMemoryMailboxesAddress;
- 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_V1_CommandMailboxCount - 1;
- Controller->V1.PreviousCommandMailbox1 =
- &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
- if (--NextCommandMailboxIndex < 0)
- NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
- Controller->V1.PreviousCommandMailbox2 =
- &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
- StatusMailboxesMemory =
- (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->V1.DualModeMemoryMailboxInterface = true;
- CommandMailbox.TypeX.CommandOpcode = 0x2B;
- CommandMailbox.TypeX.CommandIdentifier = 0;
- CommandMailbox.TypeX.CommandOpcode2 = 0x14;
- CommandMailbox.TypeX.CommandMailboxesBusAddress =
- Virtual_to_Bus32(Controller->V1.FirstCommandMailbox);
- CommandMailbox.TypeX.StatusMailboxesBusAddress =
- Virtual_to_Bus32(Controller->V1.FirstStatusMailbox);
- for (i = 0; i < 2; i++)
- switch (Controller->HardwareType)
- {
- case DAC960_LA_Controller:
- while (--TimeoutCounter >= 0)
- {
- if (!DAC960_LA_HardwareMailboxFullP(ControllerBaseAddress))
- break;
- udelay(10);
- }
- if (TimeoutCounter < 0) return false;
- DAC960_LA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
- DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
- while (--TimeoutCounter >= 0)
- {
- if (DAC960_LA_HardwareMailboxStatusAvailableP(
- ControllerBaseAddress))
- break;
- udelay(10);
- }
- if (TimeoutCounter < 0) return 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_PG_Controller:
- while (--TimeoutCounter >= 0)
- {
- if (!DAC960_PG_HardwareMailboxFullP(ControllerBaseAddress))
- break;
- udelay(10);
- }
- if (TimeoutCounter < 0) return false;
- DAC960_PG_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
- DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
- while (--TimeoutCounter >= 0)
- {
- if (DAC960_PG_HardwareMailboxStatusAvailableP(
- ControllerBaseAddress))
- break;
- udelay(10);
- }
- if (TimeoutCounter < 0) return 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:
- break;
- }
- return false;
- }
- /*
- DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
- for DAC960 V2 Firmware Controllers.
- */
- static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
- *Controller)
- {
- 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_Bus64(Controller->V2.HealthStatusBuffer);
- CommandMailbox.SetMemoryMailbox.FirstCommandMailboxBusAddress =
- Virtual_to_Bus64(Controller->V2.FirstCommandMailbox);
- CommandMailbox.SetMemoryMailbox.FirstStatusMailboxBusAddress =
- Virtual_to_Bus64(Controller->V2.FirstStatusMailbox);
- switch (Controller->HardwareType)
- {
- 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_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;
- default:
- break;
- }
- return (CommandStatus == DAC960_V2_NormalCompletion);
- }
- /*
- DAC960_V1_ReadControllerConfiguration reads the Configuration Information
- from DAC960 V1 Firmware Controllers and initializes the Controller structure.
- */
- static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
- *Controller)
- {
- DAC960_V1_Enquiry2_T Enquiry2;
- DAC960_V1_Config2_T Config2;
- int LogicalDriveNumber, Channel, TargetID;
- if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry,
- &Controller->V1.Enquiry))
- return DAC960_Failure(Controller, "ENQUIRY");
- if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, &Enquiry2))
- return DAC960_Failure(Controller, "ENQUIRY2");
- if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, &Config2))
- return DAC960_Failure(Controller, "READ CONFIG2");
- 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 < 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_V1_P_PD_PU:
- if (Enquiry2.SCSICapability.BusSpeed == DAC960_V1_Ultra)
- strcpy(Controller->ModelName, "DAC960PU");
- else strcpy(Controller->ModelName, "DAC960PD");
- break;
- case DAC960_V1_PL:
- strcpy(Controller->ModelName, "DAC960PL");
- break;
- case DAC960_V1_PG:
- strcpy(Controller->ModelName, "DAC960PG");
- break;
- case DAC960_V1_PJ:
- strcpy(Controller->ModelName, "DAC960PJ");
- break;
- case DAC960_V1_PR:
- strcpy(Controller->ModelName, "DAC960PR");
- break;
- case DAC960_V1_PT:
- strcpy(Controller->ModelName, "DAC960PT");
- break;
- case DAC960_V1_PTL0:
- strcpy(Controller->ModelName, "DAC960PTL0");
- break;
- case DAC960_V1_PRL:
- strcpy(Controller->ModelName, "DAC960PRL");
- break;
- case DAC960_V1_PTL1:
- strcpy(Controller->ModelName, "DAC960PTL1");
- break;
- case DAC960_V1_1164P:
- strcpy(Controller->ModelName, "DAC1164P");
- break;
- default:
- return DAC960_Failure(Controller, "MODEL VERIFICATION");
- }
- strcpy(Controller->FullModelName, "Mylex ");
- strcat(Controller->FullModelName, Controller->ModelName);
- /*
- Initialize the Controller Firmware Version field and verify that it
- is a supported firmware version. The supported firmware versions are:
- DAC1164P 5.06 and above
- DAC960PTL/PRL/PJ/PG 4.06 and above
- DAC960PU/PD/PL 3.51 and above
- DAC960PU/PD/PL/P 2.73 and above
- */
- if (Enquiry2.FirmwareID.MajorVersion == 0)
- {
- Enquiry2.FirmwareID.MajorVersion =
- Controller->V1.Enquiry.MajorFirmwareVersion;
- Enquiry2.FirmwareID.MinorVersion =
- Controller->V1.Enquiry.MinorFirmwareVersion;
- Enquiry2.FirmwareID.FirmwareType = '0';
- Enquiry2.FirmwareID.TurnID = 0;
- }
- sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
- Enquiry2.FirmwareID.MajorVersion, Enquiry2.FirmwareID.MinorVersion,
- Enquiry2.FirmwareID.FirmwareType, Enquiry2.FirmwareID.TurnID);
- if (!((Controller->FirmwareVersion[0] == '5' &&
- strcmp(Controller->FirmwareVersion, "5.06") >= 0) ||
- (Controller->FirmwareVersion[0] == '4' &&
- strcmp(Controller->FirmwareVersion, "4.06") >= 0) ||
- (Controller->FirmwareVersion[0] == '3' &&
- strcmp(Controller->FirmwareVersion, "3.51") >= 0) ||
- (Controller->FirmwareVersion[0] == '2' &&
- strcmp(Controller->FirmwareVersion, "2.73") >= 0)))
- {
- DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
- DAC960_Error("Firmware Version = '%s'n", Controller,
- Controller->FirmwareVersion);
- return false;
- }
- /*
- 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->V1.SAFTE_EnclosureManagementEnabled =
- (Enquiry2.FaultManagementType == DAC960_V1_SAFTE);
- /*
- 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 = Controller->V1.Enquiry.MaxCommands;
- Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
- if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
- Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
- Controller->LogicalDriveCount =
- Controller->V1.Enquiry.NumberOfLogicalDrives;
- Controller->MaxBlocksPerCommand = Enquiry2.MaxBlocksPerCommand;
- 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->V1.StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
- >> (10 - DAC960_BlockSizeBits);
- Controller->V1.SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
- >> (10 - DAC960_BlockSizeBits);
- switch (Config2.DriveGeometry)
- {
- case DAC960_V1_Geometry_128_32:
- Controller->V1.GeometryTranslationHeads = 128;
- Controller->V1.GeometryTranslationSectors = 32;
- break;
- 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 Background Initialization Status.
- */
- if ((Controller->FirmwareVersion[0] == '4' &&
- strcmp(Controller->FirmwareVersion, "4.08") >= 0) ||
- (Controller->FirmwareVersion[0] == '5' &&
- strcmp(Controller->FirmwareVersion, "5.08") >= 0))
- {
- Controller->V1.BackgroundInitializationStatusSupported = true;
- DAC960_V1_ExecuteType3B(Controller,
- DAC960_V1_BackgroundInitializationControl, 0x20,
- &Controller->
- V1.LastBackgroundInitializationStatus);
- }
- /*
- Initialize the Logical Drive Initially Accessible flag.
- */
- for (LogicalDriveNumber = 0;
- LogicalDriveNumber < Controller->LogicalDriveCount;
- LogicalDriveNumber++)
- if (Controller->V1.LogicalDriveInformation
- [LogicalDriveNumber].LogicalDriveState !=
- DAC960_V1_LogicalDrive_Offline)
- Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
- Controller->V1.LastRebuildStatus = DAC960_V1_NoRebuildOrCheckInProgress;
- return true;
- }
- /*
- 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] == ' ')
- ModelNameLength--;
- Controller->ModelName[++ModelNameLength] = ' ';
- 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 CONTROLLERn",
- 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 supportedn",
- LogicalDeviceNumber);
- if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize)
- panic("DAC960: Logical Drive Block Size %d not supportedn",
- 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
- *Controller)
- {
- DAC960_Info("Configuring Mylex %s PCI RAID Controllern",
- Controller, Controller->ModelName);
- DAC960_Info(" Firmware Version: %s, Channels: %d, Memory Size: %dMBn",
- Controller, Controller->FirmwareVersion,
- Controller->Channels, Controller->MemorySize);
- DAC960_Info(" PCI Bus: %d, Device: %d, Function: %d, I/O Address: ",
- Controller, Controller->Bus,
- Controller->Device, Controller->Function);
- if (Controller->IO_Address == 0)
- DAC960_Info("Unassignedn", Controller);
- else DAC960_Info("0x%Xn", Controller, Controller->IO_Address);
- DAC960_Info(" PCI Address: 0x%X mapped at 0x%lX, IRQ Channel: %dn",
- Controller, Controller->PCI_Address,
- (unsigned long) Controller->BaseAddress,
- Controller->IRQ_Channel);
- DAC960_Info(" Controller Queue Depth: %d, "
- "Maximum Blocks per Command: %dn",
- Controller, Controller->ControllerQueueDepth,
- Controller->MaxBlocksPerCommand);
- DAC960_Info(" Driver Queue Depth: %d, "
- "Scatter/Gather Limit: %d of %d Segmentsn",
- Controller, Controller->DriverQueueDepth,
- Controller->DriverScatterGatherLimit,
- Controller->ControllerScatterGatherLimit);
- if (Controller->FirmwareType == DAC960_V1_Controller)
- {
- DAC960_Info(" Stripe Size: %dKB, Segment Size: %dKB, "
- "BIOS Geometry: %d/%dn", Controller,
- Controller->V1.StripeSize,
- Controller->V1.SegmentSize,
- Controller->V1.GeometryTranslationHeads,
- Controller->V1.GeometryTranslationSectors);
- if (Controller->V1.SAFTE_EnclosureManagementEnabled)
- DAC960_Info(" SAF-TE Enclosure Management Enabledn", Controller);
- }
- return true;
- }
- /*
- 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_V1_ReadDeviceConfiguration(DAC960_Controller_T
- *Controller)
- {
- DAC960_V1_DCDB_T DCDBs[DAC960_V1_MaxChannels], *DCDB;
- Completion_T Completions[DAC960_V1_MaxChannels], *Completion;
- unsigned long ProcessorFlags;
- int Channel, TargetID;
- for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
- {
- for (Channel = 0; Channel < Controller->Channels; Channel++)
- {
- DAC960_Command_T *Command = Controller->Commands[Channel];
- DAC960_SCSI_Inquiry_T *InquiryStandardData =
- &Controller->V1.InquiryStandardData[Channel][TargetID];
- InquiryStandardData->PeripheralDeviceType = 0x1F;
- Completion = &Completions[Channel];
- init_completion(Completion);
- DCDB = &DCDBs[Channel];
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_ImmediateCommand;
- Command->Completion = Completion;
- Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
- Command->V1.CommandMailbox.Type3.BusAddress = Virtual_to_Bus32(DCDB);
- DCDB->Channel = Channel;
- DCDB->TargetID = TargetID;
- DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
- DCDB->EarlyStatus = false;
- DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
- DCDB->NoAutomaticRequestSense = false;
- DCDB->DisconnectPermitted = true;
- DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
- DCDB->BusAddress = Virtual_to_Bus32(InquiryStandardData);
- DCDB->CDBLength = 6;
- DCDB->TransferLengthHigh4 = 0;
- DCDB->SenseLength = sizeof(DCDB->SenseData);
- DCDB->CDB[0] = 0x12; /* INQUIRY */
- DCDB->CDB[1] = 0; /* EVPD = 0 */
- DCDB->CDB[2] = 0; /* Page Code */
- DCDB->CDB[3] = 0; /* Reserved */
- DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
- DCDB->CDB[5] = 0; /* Control */
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- DAC960_QueueCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- }
- for (Channel = 0; Channel < Controller->Channels; Channel++)
- {
- DAC960_Command_T *Command = Controller->Commands[Channel];
- DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
- &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
- InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
- Completion = &Completions[Channel];
- wait_for_completion(Completion);
- if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion)
- continue;
- Command->Completion = Completion;
- DCDB = &DCDBs[Channel];
- DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
- DCDB->BusAddress = Virtual_to_Bus32(InquiryUnitSerialNumber);
- DCDB->SenseLength = sizeof(DCDB->SenseData);
- DCDB->CDB[0] = 0x12; /* INQUIRY */
- DCDB->CDB[1] = 1; /* EVPD = 1 */
- DCDB->CDB[2] = 0x80; /* Page Code */
- DCDB->CDB[3] = 0; /* Reserved */
- DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
- DCDB->CDB[5] = 0; /* Control */
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- DAC960_QueueCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- wait_for_completion(Completion);
- }
- }
- 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_Bus64(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)] = ' ';
- for (i = 0; i < sizeof(InquiryStandardData->ProductIdentification); i++)
- {
- unsigned char ModelCharacter =
- InquiryStandardData->ProductIdentification[i];
- Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
- ? ModelCharacter : ' ');
- }
- Model[sizeof(InquiryStandardData->ProductIdentification)] = ' ';
- for (i = 0; i < sizeof(InquiryStandardData->ProductRevisionLevel); i++)
- {
- unsigned char RevisionCharacter =
- InquiryStandardData->ProductRevisionLevel[i];
- Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
- ? RevisionCharacter : ' ');
- }
- Revision[sizeof(InquiryStandardData->ProductRevisionLevel)] = ' ';
- 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] = ' ';
- }
- /*
- DAC960_V1_ReportDeviceConfiguration reports the Device Configuration
- Information for DAC960 V1 Firmware Controllers.
- */
- 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 < Controller->Targets; TargetID++)
- {
- DAC960_SCSI_Inquiry_T *InquiryStandardData =
- &Controller->V1.InquiryStandardData[Channel][TargetID];
- DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
- &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)];
- if (InquiryStandardData->PeripheralDeviceType == 0x1F) continue;
- DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
- Vendor, Model, Revision, SerialNumber);
- DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %sn",
- Controller, Channel, TargetID, (TargetID < 10 ? " " : ""),
- Vendor, Model, Revision);
- if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
- DAC960_Info(" Serial Number: %sn", Controller, SerialNumber);
- if (DeviceState->Present &&
- DeviceState->DeviceType == DAC960_V1_DiskType)
- {
- if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0)
- DAC960_Info(" Disk Status: %s, %u blocks, %d resetsn",
- Controller,
- (DeviceState->DeviceState == DAC960_V1_Device_Dead
- ? "Dead"
- : DeviceState->DeviceState
- == DAC960_V1_Device_WriteOnly
- ? "Write-Only"
- : DeviceState->DeviceState
- == DAC960_V1_Device_Online
- ? "Online" : "Standby"),
- DeviceState->DiskSize,
- Controller->V1.DeviceResetCount[Channel][TargetID]);
- else
- DAC960_Info(" Disk Status: %s, %u blocksn", Controller,
- (DeviceState->DeviceState == DAC960_V1_Device_Dead
- ? "Dead"
- : DeviceState->DeviceState
- == DAC960_V1_Device_WriteOnly
- ? "Write-Only"
- : DeviceState->DeviceState
- == DAC960_V1_Device_Online
- ? "Online" : "Standby"),
- DeviceState->DiskSize);
- }
- if (ErrorEntry->ParityErrorCount > 0 ||
- ErrorEntry->SoftErrorCount > 0 ||
- ErrorEntry->HardErrorCount > 0 ||
- ErrorEntry->MiscErrorCount > 0)
- DAC960_Info(" Errors - Parity: %d, Soft: %d, "
- "Hard: %d, Misc: %dn", Controller,
- ErrorEntry->ParityErrorCount,
- ErrorEntry->SoftErrorCount,
- ErrorEntry->HardErrorCount,
- ErrorEntry->MiscErrorCount);
- }
- DAC960_Info(" Logical Drives:n", Controller);
- for (LogicalDriveNumber = 0;
- LogicalDriveNumber < Controller->LogicalDriveCount;
- LogicalDriveNumber++)
- {
- DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation =
- &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
- DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %u blocks, %sn",
- Controller, Controller->ControllerNumber, LogicalDriveNumber,
- LogicalDriveInformation->RAIDLevel,
- (LogicalDriveInformation->LogicalDriveState
- == DAC960_V1_LogicalDrive_Online
- ? "Online"
- : LogicalDriveInformation->LogicalDriveState
- == DAC960_V1_LogicalDrive_Critical
- ? "Critical" : "Offline"),
- LogicalDriveInformation->LogicalDriveSize,
- (LogicalDriveInformation->WriteBack
- ? "Write Back" : "Write Thru"));
- }
- return true;
- }
- /*
- DAC960_V2_ReportDeviceConfiguration reports the Device Configuration
- Information for DAC960 V2 Firmware Controllers.
- */
- 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: %sn",
- Controller,
- PhysicalDeviceInfo->Channel,
- PhysicalDeviceInfo->TargetID,
- (PhysicalDeviceInfo->TargetID < 10 ? " " : ""),
- Vendor, Model, Revision);
- if (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers == 0)
- DAC960_Info(" %sAsynchronousn", Controller,
- (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
- ? "Wide " :""));
- else
- DAC960_Info(" %sSynchronous at %d MB/secn", Controller,
- (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
- ? "Wide " :""),
- (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers
- * (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
- ? 2 : 1)));
- if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
- DAC960_Info(" Serial Number: %sn", Controller, SerialNumber);
- if (PhysicalDeviceInfo->PhysicalDeviceState ==
- DAC960_V2_Device_Unconfigured)
- continue;
- DAC960_Info(" Disk Status: %s, %u blocksn", Controller,
- (PhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_Online
- ? "Online"
- : PhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_Rebuild
- ? "Rebuild"
- : PhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_Missing
- ? "Missing"
- : PhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_Critical
- ? "Critical"
- : PhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_Dead
- ? "Dead"
- : PhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_SuspectedDead
- ? "Suspected-Dead"
- : PhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_CommandedOffline
- ? "Commanded-Offline"
- : PhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_Standby
- ? "Standby" : "Unknown"),
- PhysicalDeviceInfo->ConfigurableDeviceSize);
- if (PhysicalDeviceInfo->ParityErrors == 0 &&
- PhysicalDeviceInfo->SoftErrors == 0 &&
- PhysicalDeviceInfo->HardErrors == 0 &&
- 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: %dn", Controller,
- PhysicalDeviceInfo->ParityErrors,
- PhysicalDeviceInfo->SoftErrors,
- PhysicalDeviceInfo->HardErrors,
- PhysicalDeviceInfo->MiscellaneousErrors);
- DAC960_Info(" Timeouts: %d, Retries: %d, "
- "Aborts: %d, Predicted: %dn", 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 %dn",
- Controller, LogicalDeviceInfo->DriveGeometry);
- break;
- }
- DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %u blocksn",
- Controller, Controller->ControllerNumber, LogicalDriveNumber,
- LogicalDeviceInfo->RAIDLevel,
- (LogicalDeviceInfo->LogicalDeviceState
- == DAC960_V2_LogicalDevice_Online
- ? "Online"
- : LogicalDeviceInfo->LogicalDeviceState
- == DAC960_V2_LogicalDevice_Critical
- ? "Critical" : "Offline"),
- LogicalDeviceInfo->ConfigurableDeviceSize);
- DAC960_Info(" Logical Device %s, BIOS Geometry: %sn",
- Controller,
- (LogicalDeviceInfo->LogicalDeviceControl
- .LogicalDeviceInitialized
- ? "Initialized" : "Uninitialized"),
- GeometryTranslation);
- if (LogicalDeviceInfo->StripeSize == 0)
- {
- if (LogicalDeviceInfo->CacheLineSize == 0)
- DAC960_Info(" Stripe Size: N/A, "
- "Segment Size: N/An", Controller);
- else
- DAC960_Info(" Stripe Size: N/A, "
- "Segment Size: %dKBn", Controller,
- 1 << (LogicalDeviceInfo->CacheLineSize - 2));
- }
- else
- {
- if (LogicalDeviceInfo->CacheLineSize == 0)
- DAC960_Info(" Stripe Size: %dKB, "
- "Segment Size: N/An", Controller,
- 1 << (LogicalDeviceInfo->StripeSize - 2));
- else
- DAC960_Info(" Stripe Size: %dKB, "
- "Segment Size: %dKBn", Controller,
- 1 << (LogicalDeviceInfo->StripeSize - 2),
- 1 << (LogicalDeviceInfo->CacheLineSize - 2));
- }
- DAC960_Info(" %s, %sn", 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: %dn", Controller,
- LogicalDeviceInfo->SoftErrors,
- LogicalDeviceInfo->CommandsFailed,
- LogicalDeviceInfo->DeferredWriteErrors);
- }
- return true;
- }
- /*
- 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)
- {
- 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++;
- return true;
- }
- return false;
- }
- /*
- 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)
- {
- 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++;
- return true;
- }
- return false;
- }
- /*
- DAC960_MergeRequestsFunction is the Merge Requests Function for the
- DAC960 driver.
- */
- 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;
- if (Request->bhtail->b_data + Request->bhtail->b_size
- == NextRequest->bh->b_data)
- TotalSegments--;
- if (TotalSegments > MaxSegments ||
- TotalSegments > Controller->DriverScatterGatherLimit)
- return false;
- Request->nr_segments = TotalSegments;
- return true;
- }
- /*
- DAC960_RegisterBlockDevice registers the Block Device structures
- associated with Controller.
- */
- static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
- {
- int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
- RequestQueue_T *RequestQueue;
- int MinorNumber;
- /*
- Register the Block Device Major Number for this DAC960 Controller.
- */
- if (devfs_register_blkdev(MajorNumber, "dac960",
- &DAC960_BlockDeviceOperations) < 0)
- {
- DAC960_Error("UNABLE TO ACQUIRE MAJOR NUMBER %d - DETACHINGn",
- Controller, MajorNumber);
- return false;
- }
- /*
- Initialize the I/O Request Queue.
- */
- 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 Max Sectors per Request array.
- */
- for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++)
- Controller->MaxSectorsPerRequest[MinorNumber] =
- Controller->MaxBlocksPerCommand;
- Controller->GenericDiskInfo.part = Controller->DiskPartitions;
- Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
- blksize_size[MajorNumber] = Controller->BlockSizes;
- max_sectors[MajorNumber] = Controller->MaxSectorsPerRequest;
- /*
- Initialize Read Ahead to 128 sectors.
- */
- read_ahead[MajorNumber] = 128;
- /*
- Complete initialization of the Generic Disk Information structure.
- */
- Controller->GenericDiskInfo.major = MajorNumber;
- Controller->GenericDiskInfo.major_name = "rd";
- Controller->GenericDiskInfo.minor_shift = DAC960_MaxPartitionsBits;
- Controller->GenericDiskInfo.max_p = DAC960_MaxPartitions;
- Controller->GenericDiskInfo.nr_real = DAC960_MaxLogicalDrives;
- Controller->GenericDiskInfo.real_devices = Controller;
- Controller->GenericDiskInfo.next = NULL;
- Controller->GenericDiskInfo.fops = &DAC960_BlockDeviceOperations;
- /*
- Install the Generic Disk Information structure at the end of the list.
- */
- add_gendisk(&Controller->GenericDiskInfo);
- /*
- Indicate the Block Device Registration completed successfully,
- */
- return true;
- }
- /*
- DAC960_UnregisterBlockDevice unregisters the Block Device structures
- associated with Controller.
- */
- static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller)
- {
- int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
- /*
- Unregister the Block Device Major Number for this DAC960 Controller.
- */
- devfs_unregister_blkdev(MajorNumber, "dac960");
- /*
- Remove the I/O Request Queue.
- */
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MajorNumber));
- /*
- Remove the Disk Partitions array, Partition Sizes array, Block Sizes
- array, Max Sectors per Request array, and Max Segments per Request array.
- */
- Controller->GenericDiskInfo.part = NULL;
- Controller->GenericDiskInfo.sizes = NULL;
- blk_size[MajorNumber] = NULL;
- blksize_size[MajorNumber] = NULL;
- max_sectors[MajorNumber] = NULL;
- /*
- Remove the Generic Disk Information structure from the list.
- */
- del_gendisk(&Controller->GenericDiskInfo);
- }
- /*
- DAC960_ComputeGenericDiskInfo computes the values for the Generic Disk
- Information Partition Sector Counts and Block Sizes.
- */
- static void DAC960_ComputeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
- {
- DAC960_Controller_T *Controller =
- (DAC960_Controller_T *) GenericDiskInfo->real_devices;
- int LogicalDriveNumber, i;
- for (LogicalDriveNumber = 0;
- LogicalDriveNumber < DAC960_MaxLogicalDrives;
- LogicalDriveNumber++)
- {
- int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber, 0);
- if (Controller->FirmwareType == DAC960_V1_Controller)
- {
- if (LogicalDriveNumber < Controller->LogicalDriveCount)
- GenericDiskInfo->part[MinorNumber].nr_sects =
- Controller->V1.LogicalDriveInformation
- [LogicalDriveNumber].LogicalDriveSize;
- else GenericDiskInfo->part[MinorNumber].nr_sects = 0;
- }
- else
- {
- DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
- Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
- if (LogicalDeviceInfo != NULL)
- GenericDiskInfo->part[MinorNumber].nr_sects =
- LogicalDeviceInfo->ConfigurableDeviceSize;
- else GenericDiskInfo->part[MinorNumber].nr_sects = 0;
- }
- for (i = 0; i < DAC960_MaxPartitions; i++)
- if (GenericDiskInfo->part[MinorNumber].nr_sects > 0)
- Controller->BlockSizes[MinorNumber + i] = BLOCK_SIZE;
- else Controller->BlockSizes[MinorNumber + i] = 0;
- }
- }
- /*
- DAC960_RegisterDisk registers the DAC960 Logical Disk Device for Logical
- Drive Number if it exists.
- */
- 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->ConfigurableDeviceSize);
- }
- }
- /*
- 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 Respondingn",
- Controller, Parameter1, Parameter0);
- break;
- case 0x08:
- if (Controller->DriveSpinUpMessageDisplayed) break;
- DAC960_Notice("Spinning Up Drivesn", Controller);
- Controller->DriveSpinUpMessageDisplayed = true;
- break;
- case 0x30:
- DAC960_Notice("Configuration Checksum Errorn", Controller);
- break;
- case 0x60:
- DAC960_Notice("Mirror Race Recovery Failedn", Controller);
- break;
- case 0x70:
- DAC960_Notice("Mirror Race Recovery In Progressn", Controller);
- break;
- case 0x90:
- DAC960_Notice("Physical Device %d:%d COD Mismatchn",
- Controller, Parameter1, Parameter0);
- break;
- case 0xA0:
- DAC960_Notice("Logical Drive Installation Abortedn", Controller);
- break;
- case 0xB0:
- DAC960_Notice("Mirror Race On A Critical Logical Driven", Controller);
- break;
- case 0xD0:
- DAC960_Notice("New Controller Configuration Foundn", Controller);
- break;
- case 0xF0:
- DAC960_Error("Fatal Memory Parity Error for Controller atn", Controller);
- return true;
- default:
- DAC960_Error("Unknown Initialization Error %02X for Controller atn",
- 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;
- case DAC960_P_Controller:
- VendorID = PCI_VENDOR_ID_MYLEX;
- DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_P;
- FirmwareType = DAC960_V1_Controller;
- InterruptHandler = DAC960_P_InterruptHandler;
- MemoryWindowSize = DAC960_PD_RegisterWindowSize;
- break;
- }
- while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
- {
- 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;
- case DAC960_P_Controller:
- IO_Address = pci_resource_start(PCI_Device, 0);
- PCI_Address = pci_resource_start(PCI_Device, 1);
- break;
- }
- if (DAC960_ControllerCount == DAC960_MaxControllers)
- {
- DAC960_Error("More than %d DAC960 Controllers detected - "
- "ignoring from Controller atn",
- 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 atn", 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;