Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com>
+ Portions Copyright 2002 by Mylex (An IBM Business Unit)
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
*/
-#define DAC960_DriverVersion "2.5.47"
-#define DAC960_DriverDate "14 November 2002"
+#define DAC960_DriverVersion "2.5.49"
+#define DAC960_DriverDate "21 Aug 2007"
#include <linux/module.h>
#include <linux/genhd.h>
#include <linux/hdreg.h>
#include <linux/blkpg.h>
+#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/timer.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/random.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include "DAC960.h"
return 0;
}
-static int DAC960_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
- struct gendisk *disk = inode->i_bdev->bd_disk;
+ struct gendisk *disk = bdev->bd_disk;
DAC960_Controller_T *p = disk->queue->queuedata;
int drive_nr = (long)disk->private_data;
- struct hd_geometry g;
- struct hd_geometry __user *loc = (struct hd_geometry __user *)arg;
-
- if (cmd != HDIO_GETGEO || !loc)
- return -EINVAL;
if (p->FirmwareType == DAC960_V1_Controller) {
- g.heads = p->V1.GeometryTranslationHeads;
- g.sectors = p->V1.GeometryTranslationSectors;
- g.cylinders = p->V1.LogicalDriveInformation[drive_nr].
- LogicalDriveSize / (g.heads * g.sectors);
+ geo->heads = p->V1.GeometryTranslationHeads;
+ geo->sectors = p->V1.GeometryTranslationSectors;
+ geo->cylinders = p->V1.LogicalDriveInformation[drive_nr].
+ LogicalDriveSize / (geo->heads * geo->sectors);
} else {
DAC960_V2_LogicalDeviceInfo_T *i =
p->V2.LogicalDeviceInformation[drive_nr];
switch (i->DriveGeometry) {
case DAC960_V2_Geometry_128_32:
- g.heads = 128;
- g.sectors = 32;
+ geo->heads = 128;
+ geo->sectors = 32;
break;
case DAC960_V2_Geometry_255_63:
- g.heads = 255;
- g.sectors = 63;
+ geo->heads = 255;
+ geo->sectors = 63;
break;
default:
DAC960_Error("Illegal Logical Device Geometry %d\n",
return -EINVAL;
}
- g.cylinders = i->ConfigurableDeviceSize / (g.heads * g.sectors);
+ geo->cylinders = i->ConfigurableDeviceSize /
+ (geo->heads * geo->sectors);
}
- g.start = get_start_sect(inode->i_bdev);
-
- return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0;
+ return 0;
}
static int DAC960_media_changed(struct gendisk *disk)
static struct block_device_operations DAC960_BlockDeviceOperations = {
.owner = THIS_MODULE,
.open = DAC960_open,
- .ioctl = DAC960_ioctl,
+ .getgeo = DAC960_getgeo,
.media_changed = DAC960_media_changed,
.revalidate_disk = DAC960_revalidate_disk,
};
DAC960_Failure prints a standardized error message, and then returns false.
*/
-static boolean DAC960_Failure(DAC960_Controller_T *Controller,
+static bool DAC960_Failure(DAC960_Controller_T *Controller,
unsigned char *ErrorMessage)
{
DAC960_Error("While configuring DAC960 PCI RAID Controller at\n",
that are passed in.
*/
-static boolean init_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf,
+static bool init_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf,
size_t len)
{
void *cpu_addr;
void *cpu_end = loaf->cpu_free + len;
void *cpu_addr = loaf->cpu_free;
- if (cpu_end > loaf->cpu_base + loaf->length)
- BUG();
+ BUG_ON(cpu_end > loaf->cpu_base + loaf->length);
*dma_handle = loaf->dma_free;
loaf->cpu_free = cpu_end;
loaf->dma_free += len;
failure.
*/
-static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
+static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
{
int CommandAllocationLength, CommandAllocationGroupSize;
int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount;
CommandsRemaining = CommandAllocationGroupSize;
CommandGroupByteCount =
CommandsRemaining * CommandAllocationLength;
- AllocationPointer = kmalloc(CommandGroupByteCount, GFP_ATOMIC);
+ AllocationPointer = kzalloc(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->Next = Controller->FreeCommands;
Controller->FreeCommands = Command;
Controller->Commands[CommandIdentifier-1] = Command;
- ScatterGatherCPU = pci_pool_alloc(ScatterGatherPool, SLAB_ATOMIC,
+ ScatterGatherCPU = pci_pool_alloc(ScatterGatherPool, GFP_ATOMIC,
&ScatterGatherDMA);
if (ScatterGatherCPU == NULL)
return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
if (RequestSensePool != NULL) {
- RequestSenseCPU = pci_pool_alloc(RequestSensePool, SLAB_ATOMIC,
+ RequestSenseCPU = pci_pool_alloc(RequestSensePool, GFP_ATOMIC,
&RequestSenseDMA);
if (RequestSenseCPU == NULL) {
pci_pool_free(ScatterGatherPool, ScatterGatherCPU,
Command->V1.ScatterGatherList =
(DAC960_V1_ScatterGatherSegment_T *)ScatterGatherCPU;
Command->V1.ScatterGatherListDMA = ScatterGatherDMA;
+ sg_init_table(Command->cmd_sglist, DAC960_V1_ScatterGatherLimit);
} else {
Command->cmd_sglist = Command->V2.ScatterList;
Command->V2.ScatterGatherList =
Command->V2.RequestSense =
(DAC960_SCSI_RequestSense_T *)RequestSenseCPU;
Command->V2.RequestSenseDMA = RequestSenseDMA;
+ sg_init_table(Command->cmd_sglist, DAC960_V2_ScatterGatherLimit);
}
}
return true;
* Remember the beginning of the group, but don't free it
* until we've reached the beginning of the next group.
*/
- if (CommandGroup != NULL)
- kfree(CommandGroup);
- CommandGroup = Command;
+ kfree(CommandGroup);
+ CommandGroup = Command;
}
Controller->Commands[i] = NULL;
}
- if (CommandGroup != NULL)
- kfree(CommandGroup);
+ kfree(CommandGroup);
if (Controller->CombinedStatusBuffer != NULL)
{
if (ScatterGatherPool != NULL)
pci_pool_destroy(ScatterGatherPool);
- if (Controller->FirmwareType == DAC960_V1_Controller) return;
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ return;
if (RequestSensePool != NULL)
pci_pool_destroy(RequestSensePool);
- for (i = 0; i < DAC960_MaxLogicalDrives; i++)
- if (Controller->V2.LogicalDeviceInformation[i] != NULL)
- {
+ for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
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;
- }
+ kfree(Controller->V2.PhysicalDeviceInformation[i]);
+ Controller->V2.PhysicalDeviceInformation[i] = NULL;
+ kfree(Controller->V2.InquiryUnitSerialNumber[i]);
+ Controller->V2.InquiryUnitSerialNumber[i] = NULL;
}
}
spin_lock_irq(&Controller->queue_lock);
}
+/*
+ DAC960_GEM_QueueCommand queues Command for DAC960 GEM Series Controllers.
+*/
+
+static void DAC960_GEM_QueueCommand(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ void __iomem *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_GEM_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+
+ if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
+ Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
+ DAC960_GEM_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_BA_QueueCommand queues Command for DAC960 BA Series Controllers.
static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
{
DAC960_Controller_T *Controller = Command->Controller;
- DECLARE_COMPLETION(Completion);
+ DECLARE_COMPLETION_ONSTACK(Completion);
unsigned long flags;
Command->Completion = &Completion;
on failure.
*/
-static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
+static bool DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
DAC960_V1_CommandOpcode_T CommandOpcode,
dma_addr_t DataDMA)
{
on failure.
*/
-static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
+static bool DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
DAC960_V1_CommandOpcode_T CommandOpcode,
unsigned char CommandOpcode2,
dma_addr_t DataDMA)
on failure.
*/
-static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
+static bool DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
DAC960_V1_CommandOpcode_T CommandOpcode,
unsigned char Channel,
unsigned char TargetID,
Return data in The controller's HealthStatusBuffer, which is dma-able memory
*/
-static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller)
+static bool DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
memory buffer.
*/
-static boolean DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller)
+static bool DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
Data is returned in the controller's V2.NewLogicalDeviceInformation
*/
-static boolean DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *Controller,
+static bool DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *Controller,
unsigned short LogicalDeviceNumber)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
*/
-static boolean DAC960_V2_NewPhysicalDeviceInfo(DAC960_Controller_T *Controller,
+static bool DAC960_V2_NewPhysicalDeviceInfo(DAC960_Controller_T *Controller,
unsigned char Channel,
unsigned char TargetID,
unsigned char LogicalUnit)
memory buffer.
*/
-static boolean DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Controller,
+static bool DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Controller,
int Channel, int TargetID, int LogicalUnit)
{
DAC960_Command_T *Command;
success and false on failure.
*/
-static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
+static bool DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
DAC960_V2_OperationDevice_T
OperationDevice)
other dma mapped memory.
*/
-static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
+static bool DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
*Controller)
{
void __iomem *ControllerBaseAddress = Controller->BaseAddress;
int i;
- if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V1_PciDmaMask))
+ if (pci_set_dma_mask(Controller->PCIDevice, DMA_32BIT_MASK))
return DAC960_Failure(Controller, "DMA mask out of range");
- Controller->BounceBufferLimit = DAC690_V1_PciDmaMask;
+ Controller->BounceBufferLimit = DMA_32BIT_MASK;
if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) {
CommandMailboxesSize = 0;
the structures that are contained in that region.
*/
-static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
+static bool DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
*Controller)
{
void __iomem *ControllerBaseAddress = Controller->BaseAddress;
dma_addr_t CommandMailboxDMA;
DAC960_V2_CommandStatus_T CommandStatus;
- if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V2_PciDmaMask))
- return DAC960_Failure(Controller, "DMA mask out of range");
- Controller->BounceBufferLimit = DAC690_V2_PciDmaMask;
+ if (!pci_set_dma_mask(Controller->PCIDevice, DMA_64BIT_MASK))
+ Controller->BounceBufferLimit = DMA_64BIT_MASK;
+ else if (!pci_set_dma_mask(Controller->PCIDevice, DMA_32BIT_MASK))
+ Controller->BounceBufferLimit = DMA_32BIT_MASK;
+ else
+ return DAC960_Failure(Controller, "DMA mask out of range");
/* This is a temporary dma mapping, used only in the scope of this function */
- CommandMailbox =
- (DAC960_V2_CommandMailbox_T *)pci_alloc_consistent( PCI_Device,
+ CommandMailbox = pci_alloc_consistent(PCI_Device,
sizeof(DAC960_V2_CommandMailbox_T), &CommandMailboxDMA);
if (CommandMailbox == NULL)
return false;
Controller->V2.FirstStatusMailboxDMA;
switch (Controller->HardwareType)
{
+ case DAC960_GEM_Controller:
+ while (DAC960_GEM_HardwareMailboxFullP(ControllerBaseAddress))
+ udelay(1);
+ DAC960_GEM_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA);
+ DAC960_GEM_HardwareMailboxNewCommand(ControllerBaseAddress);
+ while (!DAC960_GEM_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
+ udelay(1);
+ CommandStatus = DAC960_GEM_ReadCommandStatus(ControllerBaseAddress);
+ DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+ DAC960_GEM_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
+ break;
case DAC960_BA_Controller:
while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress))
udelay(1);
from DAC960 V1 Firmware Controllers and initializes the Controller structure.
*/
-static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
+static bool DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
*Controller)
{
DAC960_V1_Enquiry2_T *Enquiry2;
from DAC960 V2 Firmware Controllers and initializes the Controller structure.
*/
-static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
+static bool DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
*Controller)
{
DAC960_V2_ControllerInfo_T *ControllerInfo =
if (NewLogicalDeviceInfo->LogicalDeviceState !=
DAC960_V2_LogicalDevice_Offline)
Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true;
- LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
- kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
+ LogicalDeviceInfo = kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T),
+ GFP_ATOMIC);
if (LogicalDeviceInfo == NULL)
return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION");
Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
for Controller.
*/
-static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
+static bool DAC960_ReportControllerConfiguration(DAC960_Controller_T
*Controller)
{
DAC960_Info("Configuring Mylex %s PCI RAID Controller\n",
Controller.
*/
-static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
+static bool DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
*Controller)
{
struct dma_loaf local_dma;
device connected to Controller.
*/
-static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
+static bool DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
*Controller)
{
unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0;
if (!DAC960_V2_NewPhysicalDeviceInfo(Controller, Channel, TargetID, LogicalUnit))
break;
- PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
- kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
+ PhysicalDeviceInfo = kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T),
+ GFP_ATOMIC);
if (PhysicalDeviceInfo == NULL)
return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION");
Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] =
memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
sizeof(DAC960_V2_PhysicalDeviceInfo_T));
- InquiryUnitSerialNumber = (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
- kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
+ InquiryUnitSerialNumber = kmalloc(
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
if (InquiryUnitSerialNumber == NULL) {
kfree(PhysicalDeviceInfo);
return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION");
Information for DAC960 V1 Firmware Controllers.
*/
-static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
+static bool DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
*Controller)
{
int LogicalDriveNumber, Channel, TargetID;
Information for DAC960 V2 Firmware Controllers.
*/
-static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
+static bool DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
*Controller)
{
int PhysicalDeviceIndex, LogicalDriveNumber;
associated with Controller.
*/
-static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
+static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
{
int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
int n;
blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
disk->queue = RequestQueue;
sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n);
- sprintf(disk->devfs_name, "rd/host%d/target%d", Controller->ControllerNumber, n);
disk->major = MajorNumber;
disk->first_minor = n << DAC960_MaxPartitionsBits;
disk->fops = &DAC960_BlockDeviceOperations;
It returns true for fatal errors and false otherwise.
*/
-static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
+static bool DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
unsigned char ErrorStatus,
unsigned char Parameter0,
unsigned char Parameter1)
if (Controller->MemoryMappedAddress) {
switch(Controller->HardwareType)
{
+ case DAC960_GEM_Controller:
+ DAC960_GEM_DisableInterrupts(Controller->BaseAddress);
+ break;
case DAC960_BA_Controller:
DAC960_BA_DisableInterrupts(Controller->BaseAddress);
break;
{
struct DAC960_privdata *privdata =
(struct DAC960_privdata *)entry->driver_data;
- irqreturn_t (*InterruptHandler)(int, void *, struct pt_regs *) =
- privdata->InterruptHandler;
+ irq_handler_t InterruptHandler = privdata->InterruptHandler;
unsigned int MemoryWindowSize = privdata->MemoryWindowSize;
DAC960_Controller_T *Controller = NULL;
unsigned char DeviceFunction = PCI_Device->devfn;
void __iomem *BaseAddress;
int i;
- Controller = (DAC960_Controller_T *)
- kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
+ Controller = kzalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
if (Controller == NULL) {
DAC960_Error("Unable to allocate Controller structure for "
"Controller at\n", NULL);
return NULL;
}
- memset(Controller, 0, sizeof(DAC960_Controller_T));
Controller->ControllerNumber = DAC960_ControllerCount;
DAC960_Controllers[DAC960_ControllerCount++] = Controller;
Controller->Bus = PCI_Device->bus->number;
switch (Controller->HardwareType)
{
+ case DAC960_GEM_Controller:
+ Controller->PCI_Address = pci_resource_start(PCI_Device, 0);
+ break;
case DAC960_BA_Controller:
Controller->PCI_Address = pci_resource_start(PCI_Device, 0);
break;
BaseAddress = Controller->BaseAddress;
switch (Controller->HardwareType)
{
+ case DAC960_GEM_Controller:
+ DAC960_GEM_DisableInterrupts(BaseAddress);
+ DAC960_GEM_AcknowledgeHardwareMailboxStatus(BaseAddress);
+ udelay(1000);
+ while (DAC960_GEM_InitializationInProgressP(BaseAddress))
+ {
+ if (DAC960_GEM_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_GEM_EnableInterrupts(BaseAddress);
+ Controller->QueueCommand = DAC960_GEM_QueueCommand;
+ Controller->ReadControllerConfiguration =
+ DAC960_V2_ReadControllerConfiguration;
+ Controller->ReadDeviceConfiguration =
+ DAC960_V2_ReadDeviceConfiguration;
+ Controller->ReportDeviceConfiguration =
+ DAC960_V2_ReportDeviceConfiguration;
+ Controller->QueueReadWriteCommand =
+ DAC960_V2_QueueReadWriteCommand;
+ break;
case DAC960_BA_Controller:
DAC960_BA_DisableInterrupts(BaseAddress);
DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
Acquire shared access to the IRQ Channel.
*/
IRQ_Channel = PCI_Device->irq;
- if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
+ if (request_irq(IRQ_Channel, InterruptHandler, IRQF_SHARED,
Controller->FullModelName, Controller) < 0)
{
DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
DAC960_InitializeController initializes Controller.
*/
-static boolean
+static bool
DAC960_InitializeController(DAC960_Controller_T *Controller)
{
if (DAC960_ReadControllerConfiguration(Controller) &&
Command->DmaDirection = PCI_DMA_TODEVICE;
Command->CommandType = DAC960_WriteCommand;
}
- Command->Completion = Request->waiting;
+ Command->Completion = Request->end_io_data;
Command->LogicalDriveNumber = (long)Request->rq_disk->private_data;
Command->BlockNumber = Request->sector;
Command->BlockCount = Request->nr_sectors;
individual Buffer.
*/
-static inline boolean DAC960_ProcessCompletedRequest(DAC960_Command_T *Command,
- boolean SuccessfulIO)
+static inline bool DAC960_ProcessCompletedRequest(DAC960_Command_T *Command,
+ bool SuccessfulIO)
{
struct request *Request = Command->Request;
- int UpToDate;
-
- UpToDate = 0;
- if (SuccessfulIO)
- UpToDate = 1;
+ int Error = SuccessfulIO ? 0 : -EIO;
pci_unmap_sg(Command->Controller->PCIDevice, Command->cmd_sglist,
Command->SegmentCount, Command->DmaDirection);
- if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) {
-
- end_that_request_last(Request);
-
+ if (!__blk_end_request(Request, Error, Command->BlockCount << 9)) {
if (Command->Completion) {
complete(Command->Completion);
Command->Completion = NULL;
else if (CommandType == DAC960_ReadRetryCommand ||
CommandType == DAC960_WriteRetryCommand)
{
- boolean normal_completion;
+ bool normal_completion;
#ifdef FORCE_RETRY_FAILURE_DEBUG
static int retry_count = 1;
#endif
(NewEnquiry->EventLogSequenceNumber !=
OldEnquiry->EventLogSequenceNumber) ||
Controller->MonitoringTimerCount == 0 ||
- (jiffies - Controller->SecondaryMonitoringTime
- >= DAC960_SecondaryMonitoringInterval))
+ time_after_eq(jiffies, Controller->SecondaryMonitoringTime
+ + DAC960_SecondaryMonitoringInterval))
{
Controller->V1.NeedLogicalDriveInformation = true;
Controller->V1.NewEventLogSequenceNumber =
if (SenseKey == DAC960_SenseKey_VendorSpecific &&
AdditionalSenseCode == 0x80 &&
AdditionalSenseCodeQualifier <
- sizeof(DAC960_EventMessages) / sizeof(char *))
+ ARRAY_SIZE(DAC960_EventMessages))
DAC960_Critical("Physical Device %d:%d %s\n", Controller,
EventLogEntry->Channel,
EventLogEntry->TargetID,
else if (CommandType == DAC960_ReadRetryCommand ||
CommandType == DAC960_WriteRetryCommand)
{
- boolean normal_completion;
+ bool normal_completion;
#ifdef FORCE_RETRY_FAILURE_DEBUG
static int retry_count = 1;
(NewPhysicalDeviceInfo->LogicalUnit !=
PhysicalDeviceInfo->LogicalUnit))
{
- PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
+ PhysicalDeviceInfo =
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 &&
- PhysicalDeviceInfo != NULL)
+ if (InquiryUnitSerialNumber == NULL ||
+ PhysicalDeviceInfo == NULL)
{
+ kfree(InquiryUnitSerialNumber);
+ InquiryUnitSerialNumber = NULL;
kfree(PhysicalDeviceInfo);
PhysicalDeviceInfo = NULL;
}
PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
PhysicalDevice;
- LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
- kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
+ LogicalDeviceInfo = kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T),
+ GFP_ATOMIC);
Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
LogicalDeviceInfo;
DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
wake_up(&Controller->CommandWaitQueue);
}
+/*
+ DAC960_GEM_InterruptHandler handles hardware interrupts from DAC960 GEM Series
+ Controllers.
+*/
+
+static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel,
+ void *DeviceIdentifier)
+{
+ DAC960_Controller_T *Controller = DeviceIdentifier;
+ void __iomem *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+ unsigned long flags;
+
+ spin_lock_irqsave(&Controller->queue_lock, flags);
+ DAC960_GEM_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.
+ */
+ DAC960_ProcessRequest(Controller);
+ spin_unlock_irqrestore(&Controller->queue_lock, flags);
+ return IRQ_HANDLED;
+}
/*
DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
*/
static irqreturn_t DAC960_BA_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- struct pt_regs *InterruptRegisters)
+ void *DeviceIdentifier)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ DAC960_Controller_T *Controller = DeviceIdentifier;
void __iomem *ControllerBaseAddress = Controller->BaseAddress;
DAC960_V2_StatusMailbox_T *NextStatusMailbox;
unsigned long flags;
*/
static irqreturn_t DAC960_LP_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- struct pt_regs *InterruptRegisters)
+ void *DeviceIdentifier)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ DAC960_Controller_T *Controller = DeviceIdentifier;
void __iomem *ControllerBaseAddress = Controller->BaseAddress;
DAC960_V2_StatusMailbox_T *NextStatusMailbox;
unsigned long flags;
*/
static irqreturn_t DAC960_LA_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- struct pt_regs *InterruptRegisters)
+ void *DeviceIdentifier)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ DAC960_Controller_T *Controller = DeviceIdentifier;
void __iomem *ControllerBaseAddress = Controller->BaseAddress;
DAC960_V1_StatusMailbox_T *NextStatusMailbox;
unsigned long flags;
*/
static irqreturn_t DAC960_PG_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- struct pt_regs *InterruptRegisters)
+ void *DeviceIdentifier)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ DAC960_Controller_T *Controller = DeviceIdentifier;
void __iomem *ControllerBaseAddress = Controller->BaseAddress;
DAC960_V1_StatusMailbox_T *NextStatusMailbox;
unsigned long flags;
*/
static irqreturn_t DAC960_PD_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- struct pt_regs *InterruptRegisters)
+ void *DeviceIdentifier)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ DAC960_Controller_T *Controller = DeviceIdentifier;
void __iomem *ControllerBaseAddress = Controller->BaseAddress;
unsigned long flags;
*/
static irqreturn_t DAC960_P_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- struct pt_regs *InterruptRegisters)
+ void *DeviceIdentifier)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ DAC960_Controller_T *Controller = DeviceIdentifier;
void __iomem *ControllerBaseAddress = Controller->BaseAddress;
unsigned long flags;
&Controller->V2.ControllerInformation;
unsigned int StatusChangeCounter =
Controller->V2.HealthStatusBuffer->StatusChangeCounter;
- boolean ForceMonitoringCommand = false;
- if (jiffies - Controller->SecondaryMonitoringTime
- > DAC960_SecondaryMonitoringInterval)
+ bool ForceMonitoringCommand = false;
+ if (time_after(jiffies, Controller->SecondaryMonitoringTime
+ + DAC960_SecondaryMonitoringInterval))
{
int LogicalDriveNumber;
for (LogicalDriveNumber = 0;
ControllerInfo->ConsistencyChecksActive +
ControllerInfo->RebuildsActive +
ControllerInfo->OnlineExpansionsActive == 0 ||
- jiffies - Controller->PrimaryMonitoringTime
- < DAC960_MonitoringTimerInterval) &&
+ time_before(jiffies, Controller->PrimaryMonitoringTime
+ + DAC960_MonitoringTimerInterval)) &&
!ForceMonitoringCommand)
{
Controller->MonitoringTimer.expires =
necessary. It returns true if there is enough room and false otherwise.
*/
-static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
+static bool DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
unsigned int ByteCount)
{
unsigned char *NewStatusBuffer;
unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize;
while (NewStatusBufferLength < ByteCount)
NewStatusBufferLength *= 2;
- Controller->CombinedStatusBuffer =
- (unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC);
+ Controller->CombinedStatusBuffer = kmalloc(NewStatusBufferLength,
+ GFP_ATOMIC);
if (Controller->CombinedStatusBuffer == NULL) return false;
Controller->CombinedStatusBufferLength = NewStatusBufferLength;
return true;
}
- NewStatusBuffer = (unsigned char *)
- kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC);
+ NewStatusBuffer = kmalloc(2 * Controller->CombinedStatusBufferLength,
+ GFP_ATOMIC);
if (NewStatusBuffer == NULL)
{
DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n",
...)
{
static unsigned char Buffer[DAC960_LineBufferSize];
- static boolean BeginningOfLine = true;
+ static bool BeginningOfLine = true;
va_list Arguments;
int Length = 0;
va_start(Arguments, Controller);
Controller->ProgressBufferLength = Length;
if (Controller->EphemeralProgressMessage)
{
- if (jiffies - Controller->LastProgressReportTime
- >= DAC960_ProgressReportingInterval)
+ if (time_after_eq(jiffies, Controller->LastProgressReportTime
+ + DAC960_ProgressReportingInterval))
{
printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
Controller->ControllerNumber, Buffer);
Channel and TargetID and returns true on success and false on failure.
*/
-static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
+static bool DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
char *UserCommandString,
unsigned char *Channel,
unsigned char *TargetID)
returns true on success and false on failure.
*/
-static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
+static bool DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
char *UserCommandString,
unsigned char *LogicalDriveNumber)
{
Controllers.
*/
-static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
+static bool DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
unsigned char *UserCommand)
{
DAC960_Command_T *Command;
on failure.
*/
-static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
+static bool DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
unsigned char Channel,
unsigned char TargetID,
unsigned short
Controllers.
*/
-static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
+static bool DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
unsigned char *UserCommand)
{
DAC960_Command_T *Command;
return -EINVAL;
}
-static struct file_operations DAC960_gam_fops = {
+static const struct file_operations DAC960_gam_fops = {
.owner = THIS_MODULE,
.ioctl = DAC960_gam_ioctl
};
#endif /* DAC960_GAM_MINOR */
+static struct DAC960_privdata DAC960_GEM_privdata = {
+ .HardwareType = DAC960_GEM_Controller,
+ .FirmwareType = DAC960_V2_Controller,
+ .InterruptHandler = DAC960_GEM_InterruptHandler,
+ .MemoryWindowSize = DAC960_GEM_RegisterWindowSize,
+};
+
+
static struct DAC960_privdata DAC960_BA_privdata = {
.HardwareType = DAC960_BA_Controller,
.FirmwareType = DAC960_V2_Controller,
static struct pci_device_id DAC960_id_table[] = {
{
.vendor = PCI_VENDOR_ID_MYLEX,
+ .device = PCI_DEVICE_ID_MYLEX_DAC960_GEM,
+ .subvendor = PCI_VENDOR_ID_MYLEX,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (unsigned long) &DAC960_GEM_privdata,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_MYLEX,
.device = PCI_DEVICE_ID_MYLEX_DAC960_BA,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
{
int ret;
- ret = pci_module_init(&DAC960_pci_driver);
+ ret = pci_register_driver(&DAC960_pci_driver);
#ifdef DAC960_GAM_MINOR
if (!ret)
DAC960_gam_init();