]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/block/DAC960.c
drbd: Only downgrade the disk state in case of disk failures
[linux-2.6.git] / drivers / block / DAC960.c
index 70eaa5c7ac088c7db5ed6c8363bf8b5e1f75f881..8066d086578a7124a4873bb8376389dc9a010be9 100644 (file)
@@ -17,8 +17,8 @@
 */
 
 
-#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/slab.h>
+#include <linux/mutex.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/reboot.h>
 #include <linux/spinlock.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"
@@ -48,6 +54,7 @@
 #define DAC960_GAM_MINOR       252
 
 
+static DEFINE_MUTEX(DAC960_mutex);
 static DAC960_Controller_T *DAC960_Controllers[DAC960_MaxControllers];
 static int DAC960_ControllerCount;
 static struct proc_dir_entry *DAC960_ProcDirectoryEntry;
@@ -68,58 +75,57 @@ static long disk_size(DAC960_Controller_T *p, int drive_nr)
        }
 }
 
-static int DAC960_open(struct inode *inode, struct file *file)
+static int DAC960_open(struct block_device *bdev, fmode_t mode)
 {
-       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;
+       int ret = -ENXIO;
 
+       mutex_lock(&DAC960_mutex);
        if (p->FirmwareType == DAC960_V1_Controller) {
                if (p->V1.LogicalDriveInformation[drive_nr].
                    LogicalDriveState == DAC960_V1_LogicalDrive_Offline)
-                       return -ENXIO;
+                       goto out;
        } else {
                DAC960_V2_LogicalDeviceInfo_T *i =
                        p->V2.LogicalDeviceInformation[drive_nr];
                if (!i || i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline)
-                       return -ENXIO;
+                       goto out;
        }
 
-       check_disk_change(inode->i_bdev);
+       check_disk_change(bdev);
 
        if (!get_capacity(p->disks[drive_nr]))
-               return -ENXIO;
-       return 0;
+               goto out;
+       ret = 0;
+out:
+       mutex_unlock(&DAC960_mutex);
+       return ret;
 }
 
-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",
@@ -127,21 +133,21 @@ static int DAC960_ioctl(struct inode *inode, struct file *file,
                        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 unsigned int DAC960_check_events(struct gendisk *disk,
+                                       unsigned int clearing)
 {
        DAC960_Controller_T *p = disk->queue->queuedata;
        int drive_nr = (long)disk->private_data;
 
        if (!p->LogicalDriveInitiallyAccessible[drive_nr])
-               return 1;
+               return DISK_EVENT_MEDIA_CHANGE;
        return 0;
 }
 
@@ -154,11 +160,11 @@ static int DAC960_revalidate_disk(struct gendisk *disk)
        return 0;
 }
 
-static struct block_device_operations DAC960_BlockDeviceOperations = {
+static const struct block_device_operations DAC960_BlockDeviceOperations = {
        .owner                  = THIS_MODULE,
        .open                   = DAC960_open,
-       .ioctl                  = DAC960_ioctl,
-       .media_changed          = DAC960_media_changed,
+       .getgeo                 = DAC960_getgeo,
+       .check_events           = DAC960_check_events,
        .revalidate_disk        = DAC960_revalidate_disk,
 };
 
@@ -182,7 +188,7 @@ static void DAC960_AnnounceDriver(DAC960_Controller_T *Controller)
   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",
@@ -211,7 +217,7 @@ static boolean DAC960_Failure(DAC960_Controller_T *Controller,
   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;
@@ -234,8 +240,7 @@ static void *slice_dma_loaf(struct dma_loaf *loaf, size_t len,
        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;
@@ -256,7 +261,7 @@ static void free_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf_handle)
   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;
@@ -318,11 +323,10 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
                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;
@@ -331,13 +335,13 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
       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,
@@ -351,6 +355,7 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
        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 =
@@ -359,6 +364,7 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
        Command->V2.RequestSense =
                                (DAC960_SCSI_RequestSense_T *)RequestSenseCPU;
        Command->V2.RequestSenseDMA = RequestSenseDMA;
+       sg_init_table(Command->cmd_sglist, DAC960_V2_ScatterGatherLimit);
       }
     }
   return true;
@@ -777,7 +783,7 @@ static void DAC960_P_QueueCommand(DAC960_Command_T *Command)
 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;
 
@@ -797,7 +803,7 @@ static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
   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)
 {
@@ -821,7 +827,7 @@ static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
   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)
@@ -847,7 +853,7 @@ static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
   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,
@@ -877,7 +883,7 @@ static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
   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;
@@ -915,7 +921,7 @@ static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller)
   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;
@@ -953,7 +959,7 @@ static boolean DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller)
   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);
@@ -1004,7 +1010,7 @@ static boolean DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *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)
@@ -1089,7 +1095,7 @@ static void DAC960_V2_ConstructNewUnitSerialNumber(
   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;
@@ -1117,7 +1123,7 @@ static boolean DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Control
   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)
@@ -1149,7 +1155,7 @@ static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
   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;
@@ -1172,9 +1178,9 @@ static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
   int i;
 
   
-  if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V1_PciDmaMask))
+  if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32)))
        return DAC960_Failure(Controller, "DMA mask out of range");
-  Controller->BounceBufferLimit = DAC690_V1_PciDmaMask;
+  Controller->BounceBufferLimit = DMA_BIT_MASK(32);
 
   if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) {
     CommandMailboxesSize =  0;
@@ -1355,7 +1361,7 @@ skip_mailboxes:
   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;
@@ -1375,13 +1381,15 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
   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_BIT_MASK(64)))
+               Controller->BounceBufferLimit = DMA_BIT_MASK(64);
+       else if (!pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32)))
+               Controller->BounceBufferLimit = DMA_BIT_MASK(32);
+       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;
@@ -1533,7 +1541,7 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
   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;
@@ -1774,7 +1782,7 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
   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 =
@@ -1782,7 +1790,7 @@ static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
   unsigned short LogicalDeviceNumber = 0;
   int ModelNameLength;
 
-  /* Get data into dma-able area, then copy into permanant location */
+  /* Get data into dma-able area, then copy into permanent location */
   if (!DAC960_V2_NewControllerInfo(Controller))
     return DAC960_Failure(Controller, "GET CONTROLLER INFO");
   memcpy(ControllerInfo, Controller->V2.NewControllerInformation,
@@ -1886,8 +1894,8 @@ static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
       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] =
@@ -1905,7 +1913,7 @@ static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
   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",
@@ -1954,7 +1962,7 @@ static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
   Controller.
 */
 
-static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
+static bool DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
                                                 *Controller)
 {
   struct dma_loaf local_dma;
@@ -2102,7 +2110,7 @@ static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
   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;
@@ -2120,8 +2128,8 @@ static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
       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] =
@@ -2129,8 +2137,8 @@ static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
       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");
@@ -2226,7 +2234,7 @@ static void DAC960_SanitizeInquiryData(DAC960_SCSI_Inquiry_T
   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;
@@ -2323,7 +2331,7 @@ static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
   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;
@@ -2508,7 +2516,7 @@ static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
   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;
@@ -2532,15 +2540,14 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
        Controller->RequestQueue[n] = RequestQueue;
        blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit);
        RequestQueue->queuedata = Controller;
-       blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit);
-       blk_queue_max_phys_segments(RequestQueue, Controller->DriverScatterGatherLimit);
-       blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
+       blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit);
+       blk_queue_max_hw_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;
+       disk->events = DISK_EVENT_MEDIA_CHANGE;
    }
   /*
     Indicate the Block Device Registration completed successfully,
@@ -2590,7 +2597,7 @@ static void DAC960_ComputeGenericDiskInfo(DAC960_Controller_T *Controller)
   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)
@@ -2706,8 +2713,7 @@ DAC960_DetectController(struct pci_dev *PCI_Device,
 {
   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;
@@ -2716,14 +2722,12 @@ DAC960_DetectController(struct pci_dev *PCI_Device,
   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;
@@ -3024,7 +3028,7 @@ DAC960_DetectController(struct pci_dev *PCI_Device,
      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",
@@ -3059,7 +3063,7 @@ Failure:
   DAC960_InitializeController initializes Controller.
 */
 
-static boolean 
+static bool 
 DAC960_InitializeController(DAC960_Controller_T *Controller)
 {
   if (DAC960_ReadControllerConfiguration(Controller) &&
@@ -3326,7 +3330,7 @@ static int DAC960_process_queue(DAC960_Controller_T *Controller, struct request_
        DAC960_Command_T *Command;
 
    while(1) {
-       Request = elv_next_request(req_q);
+       Request = blk_peek_request(req_q);
        if (!Request)
                return 1;
 
@@ -3341,12 +3345,12 @@ static int DAC960_process_queue(DAC960_Controller_T *Controller, struct request_
                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;
+       Command->BlockNumber = blk_rq_pos(Request);
+       Command->BlockCount = blk_rq_sectors(Request);
        Command->Request = Request;
-       blkdev_dequeue_request(Request);
+       blk_start_request(Request);
        Command->SegmentCount = blk_rq_map_sg(req_q,
                  Command->Request, Command->cmd_sglist);
        /* pci_map_sg MAY change the value of SegCount */
@@ -3436,7 +3440,7 @@ static void DAC960_queue_partial_rw(DAC960_Command_T *Command)
    * successfully as possible.
    */
   Command->SegmentCount = 1;
-  Command->BlockNumber = Request->sector;
+  Command->BlockNumber = blk_rq_pos(Request);
   Command->BlockCount = 1;
   DAC960_QueueReadWriteCommand(Command);
   return;
@@ -3456,23 +3460,16 @@ static void DAC960_RequestFunction(struct request_queue *RequestQueue)
   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;
@@ -3583,7 +3580,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
   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
@@ -3664,8 +3661,8 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
              (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 =
@@ -3767,7 +3764,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
              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,
@@ -4670,7 +4667,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
   else if (CommandType == DAC960_ReadRetryCommand ||
           CommandType == DAC960_WriteRetryCommand)
     {
-      boolean normal_completion;
+      bool normal_completion;
 
 #ifdef FORCE_RETRY_FAILURE_DEBUG
       static int retry_count = 1;
@@ -4789,15 +4786,16 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
              (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;
                }
@@ -4959,8 +4957,8 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
              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) "
@@ -5262,10 +5260,9 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
 */
 
 static irqreturn_t DAC960_GEM_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;
@@ -5304,10 +5301,9 @@ static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel,
 */
 
 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;
@@ -5347,10 +5343,9 @@ static irqreturn_t DAC960_BA_InterruptHandler(int IRQ_Channel,
 */
 
 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;
@@ -5390,10 +5385,9 @@ static irqreturn_t DAC960_LP_InterruptHandler(int IRQ_Channel,
 */
 
 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;
@@ -5429,10 +5423,9 @@ static irqreturn_t DAC960_LA_InterruptHandler(int IRQ_Channel,
 */
 
 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;
@@ -5468,10 +5461,9 @@ static irqreturn_t DAC960_PG_InterruptHandler(int IRQ_Channel,
 */
 
 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;
 
@@ -5507,10 +5499,9 @@ static irqreturn_t DAC960_PD_InterruptHandler(int IRQ_Channel,
 */
 
 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;
 
@@ -5649,9 +5640,9 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
        &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;
@@ -5679,8 +5670,8 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
           ControllerInfo->ConsistencyChecksActive +
           ControllerInfo->RebuildsActive +
           ControllerInfo->OnlineExpansionsActive == 0 ||
-          jiffies - Controller->PrimaryMonitoringTime
-          < DAC960_MonitoringTimerInterval) &&
+          time_before(jiffies, Controller->PrimaryMonitoringTime
+          + DAC960_MonitoringTimerInterval)) &&
          !ForceMonitoringCommand)
        {
          Controller->MonitoringTimer.expires =
@@ -5713,7 +5704,7 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
   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;
@@ -5726,14 +5717,14 @@ static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
       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",
@@ -5761,7 +5752,7 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
                           ...)
 {
   static unsigned char Buffer[DAC960_LineBufferSize];
-  static boolean BeginningOfLine = true;
+  static bool BeginningOfLine = true;
   va_list Arguments;
   int Length = 0;
   va_start(Arguments, Controller);
@@ -5817,8 +5808,8 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
       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);
@@ -5854,7 +5845,7 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
   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)
@@ -5887,7 +5878,7 @@ static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
   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)
 {
@@ -5968,7 +5959,7 @@ static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller,
   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;
@@ -6183,7 +6174,7 @@ failure:
   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
@@ -6230,7 +6221,7 @@ static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
   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;
@@ -6439,16 +6430,10 @@ static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
   return true;
 }
 
-
-/*
-  DAC960_ProcReadStatus implements reading /proc/rd/status.
-*/
-
-static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
-                                int Count, int *EOF, void *Data)
+static int dac960_proc_show(struct seq_file *m, void *v)
 {
   unsigned char *StatusMessage = "OK\n";
-  int ControllerNumber, BytesAvailable;
+  int ControllerNumber;
   for (ControllerNumber = 0;
        ControllerNumber < DAC960_ControllerCount;
        ControllerNumber++)
@@ -6461,52 +6446,49 @@ static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
          break;
        }
     }
-  BytesAvailable = strlen(StatusMessage) - Offset;
-  if (Count >= BytesAvailable)
-    {
-      Count = BytesAvailable;
-      *EOF = true;
-    }
-  if (Count <= 0) return 0;
-  *Start = Page;
-  memcpy(Page, &StatusMessage[Offset], Count);
-  return Count;
+  seq_puts(m, StatusMessage);
+  return 0;
 }
 
+static int dac960_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dac960_proc_show, NULL);
+}
 
-/*
-  DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status.
-*/
+static const struct file_operations dac960_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = dac960_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 
-static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset,
-                                       int Count, int *EOF, void *Data)
+static int dac960_initial_status_proc_show(struct seq_file *m, void *v)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
-  int BytesAvailable = Controller->InitialStatusLength - Offset;
-  if (Count >= BytesAvailable)
-    {
-      Count = BytesAvailable;
-      *EOF = true;
-    }
-  if (Count <= 0) return 0;
-  *Start = Page;
-  memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
-  return Count;
+       DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private;
+       seq_printf(m, "%.*s", Controller->InitialStatusLength, Controller->CombinedStatusBuffer);
+       return 0;
 }
 
+static int dac960_initial_status_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dac960_initial_status_proc_show, PDE(inode)->data);
+}
 
-/*
-  DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status.
-*/
+static const struct file_operations dac960_initial_status_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = dac960_initial_status_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 
-static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
-                                       int Count, int *EOF, void *Data)
+static int dac960_current_status_proc_show(struct seq_file *m, void *v)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) m->private;
   unsigned char *StatusMessage =
     "No Rebuild or Consistency Check in Progress\n";
   int ProgressMessageLength = strlen(StatusMessage);
-  int BytesAvailable;
   if (jiffies != Controller->LastCurrentStatusTime)
     {
       Controller->CurrentStatusLength = 0;
@@ -6530,56 +6512,48 @@ static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
        }
       Controller->LastCurrentStatusTime = jiffies;
     }
-  BytesAvailable = Controller->CurrentStatusLength - Offset;
-  if (Count >= BytesAvailable)
-    {
-      Count = BytesAvailable;
-      *EOF = true;
-    }
-  if (Count <= 0) return 0;
-  *Start = Page;
-  memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count);
-  return Count;
+       seq_printf(m, "%.*s", Controller->CurrentStatusLength, Controller->CurrentStatusBuffer);
+       return 0;
 }
 
+static int dac960_current_status_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dac960_current_status_proc_show, PDE(inode)->data);
+}
 
-/*
-  DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command.
-*/
+static const struct file_operations dac960_current_status_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = dac960_current_status_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 
-static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset,
-                                     int Count, int *EOF, void *Data)
+static int dac960_user_command_proc_show(struct seq_file *m, void *v)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
-  int BytesAvailable = Controller->UserStatusLength - Offset;
-  if (Count >= BytesAvailable)
-    {
-      Count = BytesAvailable;
-      *EOF = true;
-    }
-  if (Count <= 0) return 0;
-  *Start = Page;
-  memcpy(Page, &Controller->UserStatusBuffer[Offset], Count);
-  return Count;
-}
+       DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private;
 
+       seq_printf(m, "%.*s", Controller->UserStatusLength, Controller->UserStatusBuffer);
+       return 0;
+}
 
-/*
-  DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
-*/
+static int dac960_user_command_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dac960_user_command_proc_show, PDE(inode)->data);
+}
 
-static int DAC960_ProcWriteUserCommand(struct file *file,
+static ssize_t dac960_user_command_proc_write(struct file *file,
                                       const char __user *Buffer,
-                                      unsigned long Count, void *Data)
+                                      size_t Count, loff_t *pos)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) PDE(file->f_path.dentry->d_inode)->data;
   unsigned char CommandBuffer[80];
   int Length;
   if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
   if (copy_from_user(CommandBuffer, Buffer, Count)) return -EFAULT;
   CommandBuffer[Count] = '\0';
   Length = strlen(CommandBuffer);
-  if (CommandBuffer[Length-1] == '\n')
+  if (Length > 0 && CommandBuffer[Length-1] == '\n')
     CommandBuffer[--Length] = '\0';
   if (Controller->FirmwareType == DAC960_V1_Controller)
     return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer)
@@ -6589,6 +6563,14 @@ static int DAC960_ProcWriteUserCommand(struct file *file,
            ? Count : -EBUSY);
 }
 
+static const struct file_operations dac960_user_command_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = dac960_user_command_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .write          = dac960_user_command_proc_write,
+};
 
 /*
   DAC960_CreateProcEntries creates the /proc/rd/... entries for the
@@ -6603,23 +6585,17 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller)
 
        if (DAC960_ProcDirectoryEntry == NULL) {
                DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
-               StatusProcEntry = create_proc_read_entry("status", 0,
+               StatusProcEntry = proc_create("status", 0,
                                           DAC960_ProcDirectoryEntry,
-                                          DAC960_ProcReadStatus, NULL);
+                                          &dac960_proc_fops);
        }
 
       sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
       ControllerProcEntry = proc_mkdir(Controller->ControllerName,
                                       DAC960_ProcDirectoryEntry);
-      create_proc_read_entry("initial_status", 0, ControllerProcEntry,
-                            DAC960_ProcReadInitialStatus, Controller);
-      create_proc_read_entry("current_status", 0, ControllerProcEntry,
-                            DAC960_ProcReadCurrentStatus, Controller);
-      UserCommandProcEntry =
-       create_proc_read_entry("user_command", S_IWUSR | S_IRUSR,
-                              ControllerProcEntry, DAC960_ProcReadUserCommand,
-                              Controller);
-      UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
+      proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller);
+      proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller);
+      UserCommandProcEntry = proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller);
       Controller->ControllerProcEntry = ControllerProcEntry;
 }
 
@@ -6646,15 +6622,18 @@ static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller)
  * DAC960_gam_ioctl is the ioctl function for performing RAID operations.
 */
 
-static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
-                           unsigned int Request, unsigned long Argument)
+static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
+                                               unsigned long Argument)
 {
-  int ErrorCode = 0;
+  long ErrorCode = 0;
   if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+
+  mutex_lock(&DAC960_mutex);
   switch (Request)
     {
     case DAC960_IOCTL_GET_CONTROLLER_COUNT:
-      return DAC960_ControllerCount;
+      ErrorCode = DAC960_ControllerCount;
+      break;
     case DAC960_IOCTL_GET_CONTROLLER_INFO:
       {
        DAC960_ControllerInfo_T __user *UserSpaceControllerInfo =
@@ -6662,15 +6641,20 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
        DAC960_ControllerInfo_T ControllerInfo;
        DAC960_Controller_T *Controller;
        int ControllerNumber;
-       if (UserSpaceControllerInfo == NULL) return -EINVAL;
-       ErrorCode = get_user(ControllerNumber,
+       if (UserSpaceControllerInfo == NULL)
+               ErrorCode = -EINVAL;
+       else ErrorCode = get_user(ControllerNumber,
                             &UserSpaceControllerInfo->ControllerNumber);
-       if (ErrorCode != 0) return ErrorCode;
+       if (ErrorCode != 0)
+               break;
+       ErrorCode = -ENXIO;
        if (ControllerNumber < 0 ||
-           ControllerNumber > DAC960_ControllerCount - 1)
-         return -ENXIO;
+           ControllerNumber > DAC960_ControllerCount - 1) {
+         break;
+       }
        Controller = DAC960_Controllers[ControllerNumber];
-       if (Controller == NULL) return -ENXIO;
+       if (Controller == NULL)
+               break;
        memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
        ControllerInfo.ControllerNumber = ControllerNumber;
        ControllerInfo.FirmwareType = Controller->FirmwareType;
@@ -6683,8 +6667,9 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
        ControllerInfo.PCI_Address = Controller->PCI_Address;
        strcpy(ControllerInfo.ModelName, Controller->ModelName);
        strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
-       return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
+       ErrorCode = (copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
                             sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0);
+       break;
       }
     case DAC960_IOCTL_V1_EXECUTE_COMMAND:
       {
@@ -6702,30 +6687,39 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
        int ControllerNumber, DataTransferLength;
        unsigned char *DataTransferBuffer = NULL;
        dma_addr_t DataTransferBufferDMA;
-       if (UserSpaceUserCommand == NULL) return -EINVAL;
+       if (UserSpaceUserCommand == NULL) {
+               ErrorCode = -EINVAL;
+               break;
+       }
        if (copy_from_user(&UserCommand, UserSpaceUserCommand,
                                   sizeof(DAC960_V1_UserCommand_T))) {
                ErrorCode = -EFAULT;
-               goto Failure1a;
+               break;
        }
        ControllerNumber = UserCommand.ControllerNumber;
+       ErrorCode = -ENXIO;
        if (ControllerNumber < 0 ||
            ControllerNumber > DAC960_ControllerCount - 1)
-         return -ENXIO;
+               break;
        Controller = DAC960_Controllers[ControllerNumber];
-       if (Controller == NULL) return -ENXIO;
-       if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
+       if (Controller == NULL)
+               break;
+       ErrorCode = -EINVAL;
+       if (Controller->FirmwareType != DAC960_V1_Controller)
+               break;
        CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
        DataTransferLength = UserCommand.DataTransferLength;
-       if (CommandOpcode & 0x80) return -EINVAL;
+       if (CommandOpcode & 0x80)
+               break;
        if (CommandOpcode == DAC960_V1_DCDB)
          {
            if (copy_from_user(&DCDB, UserCommand.DCDB,
                               sizeof(DAC960_V1_DCDB_T))) {
                ErrorCode = -EFAULT;
-               goto Failure1a;
+               break;
            }
-           if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL;
+           if (DCDB.Channel >= DAC960_V1_MaxChannels)
+                       break;
            if (!((DataTransferLength == 0 &&
                   DCDB.Direction
                   == DAC960_V1_DCDB_NoDataTransfer) ||
@@ -6735,38 +6729,37 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
                  (DataTransferLength < 0 &&
                   DCDB.Direction
                   == DAC960_V1_DCDB_DataTransferSystemToDevice)))
-             return -EINVAL;
+                       break;
            if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
                != abs(DataTransferLength))
-             return -EINVAL;
+                       break;
            DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice,
                        sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA);
-           if (DCDB_IOBUF == NULL)
-                       return -ENOMEM;
+           if (DCDB_IOBUF == NULL) {
+                       ErrorCode = -ENOMEM;
+                       break;
+               }
          }
+       ErrorCode = -ENOMEM;
        if (DataTransferLength > 0)
          {
            DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
                                DataTransferLength, &DataTransferBufferDMA);
-           if (DataTransferBuffer == NULL) {
-               ErrorCode = -ENOMEM;
-               goto Failure1;
-           }
+           if (DataTransferBuffer == NULL)
+               break;
            memset(DataTransferBuffer, 0, DataTransferLength);
          }
        else if (DataTransferLength < 0)
          {
            DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
                                -DataTransferLength, &DataTransferBufferDMA);
-           if (DataTransferBuffer == NULL) {
-               ErrorCode = -ENOMEM;
-               goto Failure1;
-           }
+           if (DataTransferBuffer == NULL)
+               break;
            if (copy_from_user(DataTransferBuffer,
                               UserCommand.DataTransferBuffer,
                               -DataTransferLength)) {
                ErrorCode = -EFAULT;
-               goto Failure1;
+               break;
            }
          }
        if (CommandOpcode == DAC960_V1_DCDB)
@@ -6843,8 +6836,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
        if (DCDB_IOBUF != NULL)
          pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T),
                        DCDB_IOBUF, DCDB_IOBUFDMA);
-      Failure1a:
-       return ErrorCode;
+       break;
       }
     case DAC960_IOCTL_V2_EXECUTE_COMMAND:
       {
@@ -6862,32 +6854,43 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
        dma_addr_t DataTransferBufferDMA;
        unsigned char *RequestSenseBuffer = NULL;
        dma_addr_t RequestSenseBufferDMA;
-       if (UserSpaceUserCommand == NULL) return -EINVAL;
+
+       ErrorCode = -EINVAL;
+       if (UserSpaceUserCommand == NULL)
+               break;
        if (copy_from_user(&UserCommand, UserSpaceUserCommand,
                           sizeof(DAC960_V2_UserCommand_T))) {
                ErrorCode = -EFAULT;
-               goto Failure2a;
+               break;
        }
+       ErrorCode = -ENXIO;
        ControllerNumber = UserCommand.ControllerNumber;
        if (ControllerNumber < 0 ||
            ControllerNumber > DAC960_ControllerCount - 1)
-         return -ENXIO;
+               break;
        Controller = DAC960_Controllers[ControllerNumber];
-       if (Controller == NULL) return -ENXIO;
-       if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+       if (Controller == NULL)
+               break;
+       if (Controller->FirmwareType != DAC960_V2_Controller){
+               ErrorCode = -EINVAL;
+               break;
+       }
        DataTransferLength = UserCommand.DataTransferLength;
+       ErrorCode = -ENOMEM;
        if (DataTransferLength > 0)
          {
            DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
                                DataTransferLength, &DataTransferBufferDMA);
-           if (DataTransferBuffer == NULL) return -ENOMEM;
+           if (DataTransferBuffer == NULL)
+               break;
            memset(DataTransferBuffer, 0, DataTransferLength);
          }
        else if (DataTransferLength < 0)
          {
            DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
                                -DataTransferLength, &DataTransferBufferDMA);
-           if (DataTransferBuffer == NULL) return -ENOMEM;
+           if (DataTransferBuffer == NULL)
+               break;
            if (copy_from_user(DataTransferBuffer,
                               UserCommand.DataTransferBuffer,
                               -DataTransferLength)) {
@@ -6997,8 +7000,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
        if (RequestSenseBuffer != NULL)
          pci_free_consistent(Controller->PCIDevice, RequestSenseLength,
                RequestSenseBuffer, RequestSenseBufferDMA);
-      Failure2a:
-       return ErrorCode;
+        break;
       }
     case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
       {
@@ -7008,21 +7010,33 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
        DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
        DAC960_Controller_T *Controller;
        int ControllerNumber;
-       if (UserSpaceGetHealthStatus == NULL) return -EINVAL;
+       if (UserSpaceGetHealthStatus == NULL) {
+               ErrorCode = -EINVAL;
+               break;
+       }
        if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
-                          sizeof(DAC960_V2_GetHealthStatus_T)))
-               return -EFAULT;
+                          sizeof(DAC960_V2_GetHealthStatus_T))) {
+               ErrorCode = -EFAULT;
+               break;
+       }
+       ErrorCode = -ENXIO;
        ControllerNumber = GetHealthStatus.ControllerNumber;
        if (ControllerNumber < 0 ||
            ControllerNumber > DAC960_ControllerCount - 1)
-         return -ENXIO;
+                   break;
        Controller = DAC960_Controllers[ControllerNumber];
-       if (Controller == NULL) return -ENXIO;
-       if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+       if (Controller == NULL)
+               break;
+       if (Controller->FirmwareType != DAC960_V2_Controller) {
+               ErrorCode = -EINVAL;
+               break;
+       }
        if (copy_from_user(&HealthStatusBuffer,
                           GetHealthStatus.HealthStatusBuffer,
-                          sizeof(DAC960_V2_HealthStatusBuffer_T)))
-               return -EFAULT;
+                          sizeof(DAC960_V2_HealthStatusBuffer_T))) {
+               ErrorCode = -EFAULT;
+               break;
+       }
        while (Controller->V2.HealthStatusBuffer->StatusChangeCounter
               == HealthStatusBuffer.StatusChangeCounter &&
               Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
@@ -7030,21 +7044,29 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
          {
            interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue,
                                           DAC960_MonitoringTimerInterval);
-           if (signal_pending(current)) return -EINTR;
+           if (signal_pending(current)) {
+               ErrorCode = -EINTR;
+               break;
+           }
          }
        if (copy_to_user(GetHealthStatus.HealthStatusBuffer,
                         Controller->V2.HealthStatusBuffer,
                         sizeof(DAC960_V2_HealthStatusBuffer_T)))
-               return -EFAULT;
-       return 0;
+               ErrorCode = -EFAULT;
+       else
+               ErrorCode =  0;
       }
+      default:
+       ErrorCode = -ENOTTY;
     }
-  return -EINVAL;
+  mutex_unlock(&DAC960_mutex);
+  return ErrorCode;
 }
 
-static struct file_operations DAC960_gam_fops = {
+static const struct file_operations DAC960_gam_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = DAC960_gam_ioctl
+       .unlocked_ioctl = DAC960_gam_ioctl,
+       .llseek         = noop_llseek,
 };
 
 static struct miscdevice DAC960_gam_dev = {
@@ -7087,7 +7109,7 @@ static struct DAC960_privdata DAC960_BA_privdata = {
 
 static struct DAC960_privdata DAC960_LP_privdata = {
        .HardwareType =         DAC960_LP_Controller,
-       .FirmwareType   =       DAC960_LP_Controller,
+       .FirmwareType   =       DAC960_V2_Controller,
        .InterruptHandler =     DAC960_LP_InterruptHandler,
        .MemoryWindowSize =     DAC960_LP_RegisterWindowSize,
 };
@@ -7120,11 +7142,11 @@ static struct DAC960_privdata DAC960_P_privdata = {
        .MemoryWindowSize =     DAC960_PD_RegisterWindowSize,
 };
 
-static struct pci_device_id DAC960_id_table[] = {
+static const struct pci_device_id DAC960_id_table[] = {
        {
                .vendor         = PCI_VENDOR_ID_MYLEX,
                .device         = PCI_DEVICE_ID_MYLEX_DAC960_GEM,
-               .subvendor      = PCI_ANY_ID,
+               .subvendor      = PCI_VENDOR_ID_MYLEX,
                .subdevice      = PCI_ANY_ID,
                .driver_data    = (unsigned long) &DAC960_GEM_privdata,
        },
@@ -7182,11 +7204,11 @@ static struct pci_driver DAC960_pci_driver = {
        .remove         = DAC960_Remove,
 };
 
-static int DAC960_init_module(void)
+static int __init DAC960_init_module(void)
 {
        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();
@@ -7194,7 +7216,7 @@ static int DAC960_init_module(void)
        return ret;
 }
 
-static void DAC960_cleanup_module(void)
+static void __exit DAC960_cleanup_module(void)
 {
        int i;