fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / scsi / megaraid.c
index 7df9fc6..77d9d38 100644 (file)
@@ -2,7 +2,7 @@
  *
  *                     Linux MegaRAID device driver
  *
- * Copyright © 2002  LSI Logic Corporation.
+ * Copyright (c) 2002  LSI Logic Corporation.
  *
  *        This program is free software; you can redistribute it and/or
  *        modify it under the terms of the GNU General Public License
@@ -17,7 +17,8 @@
  * Copyright (c) 2003  Christoph Hellwig  <hch@lst.de>
  *       - new-style, hotplug-aware pci probing and scsi registration
  *
- * Version : v2.00.3 (Feb 19, 2003) - Atul Mukker <Atul.Mukker@lsil.com>
+ * Version : v2.00.4 Mon Nov 14 14:02:43 EST 2005 - Seokmann Ju
+ *                                             <Seokmann.Ju@lsil.com>
  *
  * Description: Linux device driver for LSI Logic MegaRAID controller
  *
  *                                     518, 520, 531, 532
  *
  * This driver is supported by LSI Logic, with assistance from Red Hat, Dell,
- * and others. Please send updates to the public mailing list
- * linux-megaraid-devel@dell.com, and subscribe to and read archives of this
- * list at http://lists.us.dell.com/.
- *
- * For history of changes, see ChangeLog.megaraid.
+ * and others. Please send updates to the mailing list
+ * linux-scsi@vger.kernel.org .
  *
  */
 
@@ -38,6 +36,7 @@
 #include <linux/blkdev.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
+#include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/reboot.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/dma-mapping.h>
 #include <scsi/scsicam.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "megaraid.h"
 
-MODULE_AUTHOR ("LSI Logic Corporation");
-MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");
+#define MEGARAID_MODULE_VERSION "2.00.4"
+
+MODULE_AUTHOR ("sju@lsil.com");
+MODULE_DESCRIPTION ("LSI Logic MegaRAID legacy driver");
 MODULE_LICENSE ("GPL");
+MODULE_VERSION(MEGARAID_MODULE_VERSION);
 
 static unsigned int max_cmd_per_lun = DEF_CMD_PER_LUN;
-MODULE_PARM(max_cmd_per_lun, "i");
+module_param(max_cmd_per_lun, uint, 0);
 MODULE_PARM_DESC(max_cmd_per_lun, "Maximum number of commands which can be issued to a single LUN (default=DEF_CMD_PER_LUN=63)");
 
 static unsigned short int max_sectors_per_io = MAX_SECTORS_PER_IO;
-MODULE_PARM(max_sectors_per_io, "h");
+module_param(max_sectors_per_io, ushort, 0);
 MODULE_PARM_DESC(max_sectors_per_io, "Maximum number of sectors per I/O request (default=MAX_SECTORS_PER_IO=128)");
 
 
 static unsigned short int max_mbox_busy_wait = MBOX_BUSY_WAIT;
-MODULE_PARM(max_mbox_busy_wait, "h");
+module_param(max_mbox_busy_wait, ushort, 0);
 MODULE_PARM_DESC(max_mbox_busy_wait, "Maximum wait for mailbox in microseconds if busy (default=MBOX_BUSY_WAIT=10)");
 
-#define RDINDOOR(adapter)              readl((adapter)->base + 0x20)
-#define RDOUTDOOR(adapter)             readl((adapter)->base + 0x2C)
-#define WRINDOOR(adapter,value)                writel(value, (adapter)->base + 0x20)
-#define WROUTDOOR(adapter,value)       writel(value, (adapter)->base + 0x2C)
+#define RDINDOOR(adapter)      readl((adapter)->mmio_base + 0x20)
+#define RDOUTDOOR(adapter)     readl((adapter)->mmio_base + 0x2C)
+#define WRINDOOR(adapter,value)         writel(value, (adapter)->mmio_base + 0x20)
+#define WROUTDOOR(adapter,value) writel(value, (adapter)->mmio_base + 0x2C)
 
 /*
  * Global variables
@@ -335,6 +338,18 @@ mega_query_adapter(adapter_t *adapter)
        return 0;
 }
 
+/**
+ * mega_runpendq()
+ * @adapter - pointer to our soft state
+ *
+ * Runs through the list of pending requests.
+ */
+static inline void
+mega_runpendq(adapter_t *adapter)
+{
+       if(!list_empty(&adapter->pending_list))
+               __mega_runpendq(adapter);
+}
 
 /*
  * megaraid_queue()
@@ -349,6 +364,7 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
        adapter_t       *adapter;
        scb_t   *scb;
        int     busy=0;
+       unsigned long flags;
 
        adapter = (adapter_t *)scmd->device->host->hostdata;
 
@@ -364,26 +380,117 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
         * return 0 in that case.
         */
 
+       spin_lock_irqsave(&adapter->lock, flags);
        scb = mega_build_cmd(adapter, scmd, &busy);
+       if (!scb)
+               goto out;
 
-       if(scb) {
-               scb->state |= SCB_PENDQ;
-               list_add_tail(&scb->list, &adapter->pending_list);
+       scb->state |= SCB_PENDQ;
+       list_add_tail(&scb->list, &adapter->pending_list);
 
-               /*
-                * Check if the HBA is in quiescent state, e.g., during a
-                * delete logical drive opertion. If it is, don't run
-                * the pending_list.
-                */
-               if(atomic_read(&adapter->quiescent) == 0) {
-                       mega_runpendq(adapter);
-               }
-               return 0;
-       }
+       /*
+        * Check if the HBA is in quiescent state, e.g., during a
+        * delete logical drive opertion. If it is, don't run
+        * the pending_list.
+        */
+       if (atomic_read(&adapter->quiescent) == 0)
+               mega_runpendq(adapter);
 
+       busy = 0;
+ out:
+       spin_unlock_irqrestore(&adapter->lock, flags);
        return busy;
 }
 
+/**
+ * mega_allocate_scb()
+ * @adapter - pointer to our soft state
+ * @cmd - scsi command from the mid-layer
+ *
+ * Allocate a SCB structure. This is the central structure for controller
+ * commands.
+ */
+static inline scb_t *
+mega_allocate_scb(adapter_t *adapter, Scsi_Cmnd *cmd)
+{
+       struct list_head *head = &adapter->free_list;
+       scb_t   *scb;
+
+       /* Unlink command from Free List */
+       if( !list_empty(head) ) {
+
+               scb = list_entry(head->next, scb_t, list);
+
+               list_del_init(head->next);
+
+               scb->state = SCB_ACTIVE;
+               scb->cmd = cmd;
+               scb->dma_type = MEGA_DMA_TYPE_NONE;
+
+               return scb;
+       }
+
+       return NULL;
+}
+
+/**
+ * mega_get_ldrv_num()
+ * @adapter - pointer to our soft state
+ * @cmd - scsi mid layer command
+ * @channel - channel on the controller
+ *
+ * Calculate the logical drive number based on the information in scsi command
+ * and the channel number.
+ */
+static inline int
+mega_get_ldrv_num(adapter_t *adapter, Scsi_Cmnd *cmd, int channel)
+{
+       int             tgt;
+       int             ldrv_num;
+
+       tgt = cmd->device->id;
+       
+       if ( tgt > adapter->this_id )
+               tgt--;  /* we do not get inquires for initiator id */
+
+       ldrv_num = (channel * 15) + tgt;
+
+
+       /*
+        * If we have a logical drive with boot enabled, project it first
+        */
+       if( adapter->boot_ldrv_enabled ) {
+               if( ldrv_num == 0 ) {
+                       ldrv_num = adapter->boot_ldrv;
+               }
+               else {
+                       if( ldrv_num <= adapter->boot_ldrv ) {
+                               ldrv_num--;
+                       }
+               }
+       }
+
+       /*
+        * If "delete logical drive" feature is enabled on this controller.
+        * Do only if at least one delete logical drive operation was done.
+        *
+        * Also, after logical drive deletion, instead of logical drive number,
+        * the value returned should be 0x80+logical drive id.
+        *
+        * These is valid only for IO commands.
+        */
+
+       if (adapter->support_random_del && adapter->read_ldidmap )
+               switch (cmd->cmnd[0]) {
+               case READ_6:    /* fall through */
+               case WRITE_6:   /* fall through */
+               case READ_10:   /* fall through */
+               case WRITE_10:
+                       ldrv_num += 0x80;
+               }
+
+       return ldrv_num;
+}
 
 /**
  * mega_build_cmd()
@@ -417,7 +524,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
         * filter the internal and ioctl commands
         */
        if((cmd->cmnd[0] == MEGA_INTERNAL_CMD)) {
-               return cmd->buffer;
+               return cmd->request_buffer;
        }
 
 
@@ -519,8 +626,6 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
        if(islogical) {
                switch (cmd->cmnd[0]) {
                case TEST_UNIT_READY:
-                       memset(cmd->request_buffer, 0, cmd->request_bufflen);
-
 #if MEGA_HAVE_CLUSTERING
                        /*
                         * Do we support clustering and is the support enabled
@@ -533,11 +638,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
                        }
 
                        if(!(scb = mega_allocate_scb(adapter, cmd))) {
-
-                               cmd->result = (DID_ERROR << 16);
-                               cmd->scsi_done(cmd);
                                *busy = 1;
-
                                return NULL;
                        }
 
@@ -554,11 +655,28 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
                        return NULL;
 #endif
 
-               case MODE_SENSE:
-                       memset(cmd->request_buffer, 0, cmd->cmnd[4]);
+               case MODE_SENSE: {
+                       char *buf;
+
+                       if (cmd->use_sg) {
+                               struct scatterlist *sg;
+
+                               sg = (struct scatterlist *)cmd->request_buffer;
+                               buf = kmap_atomic(sg->page, KM_IRQ0) +
+                                       sg->offset;
+                       } else
+                               buf = cmd->request_buffer;
+                       memset(buf, 0, cmd->cmnd[4]);
+                       if (cmd->use_sg) {
+                               struct scatterlist *sg;
+
+                               sg = (struct scatterlist *)cmd->request_buffer;
+                               kunmap_atomic(buf - sg->offset, KM_IRQ0);
+                       }
                        cmd->result = (DID_OK << 16);
                        cmd->scsi_done(cmd);
                        return NULL;
+               }
 
                case READ_CAPACITY:
                case INQUIRY:
@@ -576,11 +694,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
 
                        /* Allocate a SCB and initialize passthru */
                        if(!(scb = mega_allocate_scb(adapter, cmd))) {
-
-                               cmd->result = (DID_ERROR << 16);
-                               cmd->scsi_done(cmd);
                                *busy = 1;
-
                                return NULL;
                        }
                        pthru = scb->pthru;
@@ -622,11 +736,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
 
                        /* Allocate a SCB and initialize mailbox */
                        if(!(scb = mega_allocate_scb(adapter, cmd))) {
-
-                               cmd->result = (DID_ERROR << 16);
-                               cmd->scsi_done(cmd);
                                *busy = 1;
-
                                return NULL;
                        }
                        mbox = (mbox_t *)scb->raw_mbox;
@@ -766,11 +876,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
 
                        /* Allocate a SCB and initialize mailbox */
                        if(!(scb = mega_allocate_scb(adapter, cmd))) {
-
-                               cmd->result = (DID_ERROR << 16);
-                               cmd->scsi_done(cmd);
                                *busy = 1;
-
                                return NULL;
                        }
 
@@ -798,11 +904,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
        else {
                /* Allocate a SCB and initialize passthru */
                if(!(scb = mega_allocate_scb(adapter, cmd))) {
-
-                       cmd->result = (DID_ERROR << 16);
-                       cmd->scsi_done(cmd);
                        *busy = 1;
-
                        return NULL;
                }
 
@@ -966,52 +1068,6 @@ mega_prepare_extpassthru(adapter_t *adapter, scb_t *scb, Scsi_Cmnd *cmd,
        return epthru;
 }
 
-
-/**
- * mega_allocate_scb()
- * @adapter - pointer to our soft state
- * @cmd - scsi command from the mid-layer
- *
- * Allocate a SCB structure. This is the central structure for controller
- * commands.
- */
-static inline scb_t *
-mega_allocate_scb(adapter_t *adapter, Scsi_Cmnd *cmd)
-{
-       struct list_head *head = &adapter->free_list;
-       scb_t   *scb;
-
-       /* Unlink command from Free List */
-       if( !list_empty(head) ) {
-
-               scb = list_entry(head->next, scb_t, list);
-
-               list_del_init(head->next);
-
-               scb->state = SCB_ACTIVE;
-               scb->cmd = cmd;
-               scb->dma_type = MEGA_DMA_TYPE_NONE;
-
-               return scb;
-       }
-
-       return NULL;
-}
-
-
-/**
- * mega_runpendq()
- * @adapter - pointer to our soft state
- *
- * Runs through the list of pending requests.
- */
-static inline void
-mega_runpendq(adapter_t *adapter)
-{
-       if(!list_empty(&adapter->pending_list))
-               __mega_runpendq(adapter);
-}
-
 static void
 __mega_runpendq(adapter_t *adapter)
 {
@@ -1043,7 +1099,7 @@ __mega_runpendq(adapter_t *adapter)
  * busy. We also take the scb from the pending list if the mailbox is
  * available.
  */
-static inline int
+static int
 issue_scb(adapter_t *adapter, scb_t *scb)
 {
        volatile mbox64_t       *mbox64 = adapter->mbox64;
@@ -1104,6 +1160,16 @@ issue_scb(adapter_t *adapter, scb_t *scb)
        return 0;
 }
 
+/*
+ * Wait until the controller's mailbox is available
+ */
+static inline int
+mega_busywait_mbox (adapter_t *adapter)
+{
+       if (adapter->mbox->m_in.busy)
+               return __mega_busywait_mbox(adapter);
+       return 0;
+}
 
 /**
  * issue_scb_block()
@@ -1190,14 +1256,13 @@ bug_blocked_mailbox:
  * megaraid_isr_iomapped()
  * @irq - irq
  * @devp - pointer to our soft state
- * @regs - unused
  *
  * Interrupt service routine for io-mapped controllers.
  * Find out if our device is interrupting. If yes, acknowledge the interrupt
  * and service the completed commands.
  */
 static irqreturn_t
-megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
+megaraid_isr_iomapped(int irq, void *devp)
 {
        adapter_t       *adapter = devp;
        unsigned long   flags;
@@ -1267,14 +1332,13 @@ megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
  * megaraid_isr_memmapped()
  * @irq - irq
  * @devp - pointer to our soft state
- * @regs - unused
  *
  * Interrupt service routine for memory-mapped controllers.
  * Find out if our device is interrupting. If yes, acknowledge the interrupt
  * and service the completed commands.
  */
 static irqreturn_t
-megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs)
+megaraid_isr_memmapped(int irq, void *devp)
 {
        adapter_t       *adapter = devp;
        unsigned long   flags;
@@ -1322,7 +1386,8 @@ megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs)
 
                handled = 1;
 
-               while( RDINDOOR(adapter) & 0x02 ) cpu_relax();
+               while( RDINDOOR(adapter) & 0x02 )
+                       cpu_relax();
 
                mega_cmd_done(adapter, completed, nstatus, status);
 
@@ -1350,7 +1415,7 @@ megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs)
  *
  * Complete the comamnds and call the scsi mid-layer callback hooks.
  */
-static inline void
+static void
 mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
 {
        mega_ext_passthru       *epthru = NULL;
@@ -1622,7 +1687,7 @@ mega_rundoneq (adapter_t *adapter)
 
        list_for_each(pos, &adapter->completed_list) {
 
-               Scsi_Pointer* spos = (Scsi_Pointer *)pos;
+               struct scsi_pointer* spos = (struct scsi_pointer *)pos;
 
                cmd = list_entry(spos, Scsi_Cmnd, SCp);
                cmd->scsi_done(cmd);
@@ -1639,14 +1704,23 @@ mega_rundoneq (adapter_t *adapter)
 static void
 mega_free_scb(adapter_t *adapter, scb_t *scb)
 {
+       unsigned long length;
+
        switch( scb->dma_type ) {
 
        case MEGA_DMA_TYPE_NONE:
                break;
 
        case MEGA_BULK_DATA:
+               if (scb->cmd->use_sg == 0)
+                       length = scb->cmd->request_bufflen;
+               else {
+                       struct scatterlist *sgl =
+                               (struct scatterlist *)scb->cmd->request_buffer;
+                       length = sgl->length;
+               }
                pci_unmap_page(adapter->dev, scb->dma_h_bulkdata,
-                       scb->cmd->request_bufflen, scb->dma_direction);
+                              length, scb->dma_direction);
                break;
 
        case MEGA_SGLIST:
@@ -1671,17 +1745,6 @@ mega_free_scb(adapter_t *adapter, scb_t *scb)
 }
 
 
-/*
- * Wait until the controller's mailbox is available
- */
-static inline int
-mega_busywait_mbox (adapter_t *adapter)
-{
-       if (adapter->mbox->m_in.busy)
-               return __mega_busywait_mbox(adapter);
-       return 0;
-}
-
 static int
 __mega_busywait_mbox (adapter_t *adapter)
 {
@@ -1706,6 +1769,7 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
        struct scatterlist      *sgl;
        struct page     *page;
        unsigned long   offset;
+       unsigned int    length;
        Scsi_Cmnd       *cmd;
        int     sgcnt;
        int     idx;
@@ -1713,14 +1777,23 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
        cmd = scb->cmd;
 
        /* Scatter-gather not used */
-       if( !cmd->use_sg ) {
-
-               page = virt_to_page(cmd->request_buffer);
-               offset = offset_in_page(cmd->request_buffer);
+       if( cmd->use_sg == 0 || (cmd->use_sg == 1 && 
+                                !adapter->has_64bit_addr)) {
+
+               if (cmd->use_sg == 0) {
+                       page = virt_to_page(cmd->request_buffer);
+                       offset = offset_in_page(cmd->request_buffer);
+                       length = cmd->request_bufflen;
+               } else {
+                       sgl = (struct scatterlist *)cmd->request_buffer;
+                       page = sgl->page;
+                       offset = sgl->offset;
+                       length = sgl->length;
+               }
 
                scb->dma_h_bulkdata = pci_map_page(adapter->dev,
                                                  page, offset,
-                                                 cmd->request_bufflen,
+                                                 length,
                                                  scb->dma_direction);
                scb->dma_type = MEGA_BULK_DATA;
 
@@ -1730,14 +1803,14 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
                 */
                if( adapter->has_64bit_addr ) {
                        scb->sgl64[0].address = scb->dma_h_bulkdata;
-                       scb->sgl64[0].length = cmd->request_bufflen;
+                       scb->sgl64[0].length = length;
                        *buf = (u32)scb->sgl_dma_addr;
-                       *len = (u32)cmd->request_bufflen;
+                       *len = (u32)length;
                        return 1;
                }
                else {
                        *buf = (u32)scb->dma_h_bulkdata;
-                       *len = (u32)cmd->request_bufflen;
+                       *len = (u32)length;
                }
                return 0;
        }
@@ -1754,29 +1827,25 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
 
        scb->dma_type = MEGA_SGLIST;
 
-       if( sgcnt > adapter->sglen ) BUG();
+       BUG_ON(sgcnt > adapter->sglen);
+
+       *len = 0;
 
        for( idx = 0; idx < sgcnt; idx++, sgl++ ) {
 
                if( adapter->has_64bit_addr ) {
                        scb->sgl64[idx].address = sg_dma_address(sgl);
-                       scb->sgl64[idx].length = sg_dma_len(sgl);
+                       *len += scb->sgl64[idx].length = sg_dma_len(sgl);
                }
                else {
                        scb->sgl[idx].address = sg_dma_address(sgl);
-                       scb->sgl[idx].length = sg_dma_len(sgl);
+                       *len += scb->sgl[idx].length = sg_dma_len(sgl);
                }
        }
 
        /* Reset pointer and length fields */
        *buf = scb->sgl_dma_addr;
 
-       /*
-        * For passthru command, dataxferlen must be set, even for commands
-        * with a sg list
-        */
-       *len = (u32)cmd->request_bufflen;
-
        /* Return count of SG requests */
        return sgcnt;
 }
@@ -1904,7 +1973,7 @@ megaraid_abort(Scsi_Cmnd *cmd)
 
 
 static int
-megaraid_reset(Scsi_Cmnd *cmd)
+megaraid_reset(struct scsi_cmnd *cmd)
 {
        adapter_t       *adapter;
        megacmd_t       mc;
@@ -1916,17 +1985,17 @@ megaraid_reset(Scsi_Cmnd *cmd)
        mc.cmd = MEGA_CLUSTER_CMD;
        mc.opcode = MEGA_RESET_RESERVATIONS;
 
-       spin_unlock_irq(&adapter->lock);
-       if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) {
+       if( mega_internal_command(adapter, &mc, NULL) != 0 ) {
                printk(KERN_WARNING
                                "megaraid: reservation reset failed.\n");
        }
        else {
                printk(KERN_INFO "megaraid: reservation reset.\n");
        }
-       spin_lock_irq(&adapter->lock);
 #endif
 
+       spin_lock_irq(&adapter->lock);
+
        rval =  megaraid_abort_and_reset(adapter, cmd, SCB_RESET);
 
        /*
@@ -1934,12 +2003,11 @@ megaraid_reset(Scsi_Cmnd *cmd)
         * to be communicated over to the mid layer.
         */
        mega_rundoneq(adapter);
+       spin_unlock_irq(&adapter->lock);
 
        return rval;
 }
 
-
-
 /**
  * megaraid_abort_and_reset()
  * @adapter - megaraid soft state
@@ -2017,6 +2085,49 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
        return FALSE;
 }
 
+static inline int
+make_local_pdev(adapter_t *adapter, struct pci_dev **pdev)
+{
+       *pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+
+       if( *pdev == NULL ) return -1;
+
+       memcpy(*pdev, adapter->dev, sizeof(struct pci_dev));
+
+       if( pci_set_dma_mask(*pdev, DMA_32BIT_MASK) != 0 ) {
+               kfree(*pdev);
+               return -1;
+       }
+
+       return 0;
+}
+
+static inline void
+free_local_pdev(struct pci_dev *pdev)
+{
+       kfree(pdev);
+}
+
+/**
+ * mega_allocate_inquiry()
+ * @dma_handle - handle returned for dma address
+ * @pdev - handle to pci device
+ *
+ * allocates memory for inquiry structure
+ */
+static inline void *
+mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev)
+{
+       return pci_alloc_consistent(pdev, sizeof(mega_inquiry3), dma_handle);
+}
+
+
+static inline void
+mega_free_inquiry(void *inquiry, dma_addr_t dma_handle, struct pci_dev *pdev)
+{
+       pci_free_consistent(pdev, sizeof(mega_inquiry3), inquiry, dma_handle);
+}
+
 
 #ifdef CONFIG_PROC_FS
 /* Following code handles /proc fs  */
@@ -2710,9 +2821,7 @@ mega_print_inquiry(char *page, char *scsi_inq)
 
        i = scsi_inq[0] & 0x1f;
 
-       len += sprintf(page+len, "  Type:   %s ",
-               i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] :
-                  "Unknown          ");
+       len += sprintf(page+len, "  Type:   %s ", scsi_device_type(i));
 
        len += sprintf(page+len,
        "                 ANSI SCSI revision: %02x", scsi_inq[2] & 0x07);
@@ -2904,7 +3013,7 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end )
                mc.cmd = FC_NEW_CONFIG;
                mc.opcode = OP_DCMD_READ_CONFIG;
 
-               if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) {
+               if( mega_internal_command(adapter, &mc, NULL) ) {
 
                        len = sprintf(page, "40LD read config failed.\n");
 
@@ -2922,11 +3031,11 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end )
        else {
                mc.cmd = NEW_READ_CONFIG_8LD;
 
-               if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) {
+               if( mega_internal_command(adapter, &mc, NULL) ) {
 
                        mc.cmd = READ_CONFIG_8LD;
 
-                       if( mega_internal_command(adapter, LOCK_INT, &mc,
+                       if( mega_internal_command(adapter, &mc,
                                                NULL) ){
 
                                len = sprintf(page,
@@ -3269,13 +3378,13 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
        nitioctl_t      uioc;
        int             adapno;
        int             rval;
-       mega_passthru   *upthru;        /* user address for passthru */
+       mega_passthru   __user *upthru; /* user address for passthru */
        mega_passthru   *pthru;         /* copy user passthru here */
        dma_addr_t      pthru_dma_hndl;
        void            *data = NULL;   /* data to be transferred */
        dma_addr_t      data_dma_hndl;  /* dma handle for data xfer area */
        megacmd_t       mc;
-       megastat_t      *ustats;
+       megastat_t      __user *ustats;
        int             num_ldrv;
        u32             uxferaddr = 0;
        struct pci_dev  *pdev;
@@ -3300,20 +3409,20 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
         * addresses.
         */
        memset(&uioc, 0, sizeof(nitioctl_t));
-       if( (rval = mega_m_to_n( (void *)arg, &uioc)) != 0 )
+       if( (rval = mega_m_to_n( (void __user *)arg, &uioc)) != 0 )
                return rval;
 
 
        switch( uioc.opcode ) {
 
        case GET_DRIVER_VER:
-               if( put_user(driver_ver, (u32 *)uioc.uioc_uaddr) )
+               if( put_user(driver_ver, (u32 __user *)uioc.uioc_uaddr) )
                        return (-EFAULT);
 
                break;
 
        case GET_N_ADAP:
-               if( put_user(hba_count, (u32 *)uioc.uioc_uaddr) )
+               if( put_user(hba_count, (u32 __user *)uioc.uioc_uaddr) )
                        return (-EFAULT);
 
                /*
@@ -3347,7 +3456,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
 
                adapter = hba_soft_state[adapno];
 
-               ustats = (megastat_t *)uioc.uioc_uaddr;
+               ustats = uioc.uioc_uaddr;
 
                if( copy_from_user(&num_ldrv, &ustats->num_ldrv, sizeof(int)) )
                        return (-EFAULT);
@@ -3418,7 +3527,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
 
                                mc.status = rval;
 
-                               rval = mega_n_to_m((void *)arg, &mc);
+                               rval = mega_n_to_m((void __user *)arg, &mc);
                        }
 
                        return rval;
@@ -3458,12 +3567,12 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
                        /*
                         * The user passthru structure
                         */
-                       upthru = (mega_passthru *)MBOX(uioc)->xferaddr;
+                       upthru = (mega_passthru __user *)MBOX(uioc)->xferaddr;
 
                        /*
                         * Copy in the user passthru here.
                         */
-                       if( copy_from_user(pthru, (char *)upthru,
+                       if( copy_from_user(pthru, upthru,
                                                sizeof(mega_passthru)) ) {
 
                                pci_free_consistent(pdev,
@@ -3510,7 +3619,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
                                /*
                                 * Get the user data
                                 */
-                               if( copy_from_user(data, (char *)uxferaddr,
+                               if( copy_from_user(data, (char __user *)uxferaddr,
                                                        pthru->dataxferlen) ) {
                                        rval = (-EFAULT);
                                        goto freemem_and_return;
@@ -3525,9 +3634,9 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
                        /*
                         * Issue the command
                         */
-                       mega_internal_command(adapter, LOCK_INT, &mc, pthru);
+                       mega_internal_command(adapter, &mc, pthru);
 
-                       rval = mega_n_to_m((void *)arg, &mc);
+                       rval = mega_n_to_m((void __user *)arg, &mc);
 
                        if( rval ) goto freemem_and_return;
 
@@ -3536,7 +3645,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
                         * Is data going up-stream
                         */
                        if( pthru->dataxferlen && (uioc.flags & UIOC_RD) ) {
-                               if( copy_to_user((char *)uxferaddr, data,
+                               if( copy_to_user((char __user *)uxferaddr, data,
                                                        pthru->dataxferlen) ) {
                                        rval = (-EFAULT);
                                }
@@ -3546,8 +3655,9 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
                         * Send the request sense data also, irrespective of
                         * whether the user has asked for it or not.
                         */
-                       copy_to_user(upthru->reqsensearea,
-                                       pthru->reqsensearea, 14);
+                       if (copy_to_user(upthru->reqsensearea,
+                                       pthru->reqsensearea, 14))
+                               rval = -EFAULT;
 
 freemem_and_return:
                        if( pthru->dataxferlen ) {
@@ -3588,7 +3698,7 @@ freemem_and_return:
                                /*
                                 * Get the user data
                                 */
-                               if( copy_from_user(data, (char *)uxferaddr,
+                               if( copy_from_user(data, (char __user *)uxferaddr,
                                                        uioc.xferlen) ) {
 
                                        pci_free_consistent(pdev,
@@ -3608,9 +3718,9 @@ freemem_and_return:
                        /*
                         * Issue the command
                         */
-                       mega_internal_command(adapter, LOCK_INT, &mc, NULL);
+                       mega_internal_command(adapter, &mc, NULL);
 
-                       rval = mega_n_to_m((void *)arg, &mc);
+                       rval = mega_n_to_m((void __user *)arg, &mc);
 
                        if( rval ) {
                                if( uioc.xferlen ) {
@@ -3628,7 +3738,7 @@ freemem_and_return:
                         * Is data going up-stream
                         */
                        if( uioc.xferlen && (uioc.flags & UIOC_RD) ) {
-                               if( copy_to_user((char *)uxferaddr, data,
+                               if( copy_to_user((char __user *)uxferaddr, data,
                                                        uioc.xferlen) ) {
 
                                        rval = (-EFAULT);
@@ -3664,7 +3774,7 @@ freemem_and_return:
  * Converts the older mimd ioctl structure to newer NIT structure
  */
 static int
-mega_m_to_n(void *arg, nitioctl_t *uioc)
+mega_m_to_n(void __user *arg, nitioctl_t *uioc)
 {
        struct uioctl_t uioc_mimd;
        char    signature[8] = {0};
@@ -3679,7 +3789,7 @@ mega_m_to_n(void *arg, nitioctl_t *uioc)
         * begining of the structure.
         */
 
-       if( copy_from_user(signature, (char *)arg, 7) )
+       if( copy_from_user(signature, arg, 7) )
                return (-EFAULT);
 
        if( memcmp(signature, "MEGANIT", 7) == 0 ) {
@@ -3692,7 +3802,7 @@ mega_m_to_n(void *arg, nitioctl_t *uioc)
                 */
                return -EINVAL;
 #if 0
-               if( copy_from_user(uioc, (char *)arg, sizeof(nitioctl_t)) )
+               if( copy_from_user(uioc, arg, sizeof(nitioctl_t)) )
                        return (-EFAULT);
                return 0;
 #endif
@@ -3703,7 +3813,7 @@ mega_m_to_n(void *arg, nitioctl_t *uioc)
         *
         * Get the user ioctl structure
         */
-       if( copy_from_user(&uioc_mimd, (char *)arg, sizeof(struct uioctl_t)) )
+       if( copy_from_user(&uioc_mimd, arg, sizeof(struct uioctl_t)) )
                return (-EFAULT);
 
 
@@ -3790,50 +3900,52 @@ mega_m_to_n(void *arg, nitioctl_t *uioc)
  * conforms to older mimd ioctl interface or newer NIT ioctl interface
  */
 static int
-mega_n_to_m(void *arg, megacmd_t *mc)
+mega_n_to_m(void __user *arg, megacmd_t *mc)
 {
-       nitioctl_t      *uiocp;
-       megacmd_t       *umc;
-       mega_passthru   *upthru;
-       struct uioctl_t *uioc_mimd;
+       nitioctl_t      __user *uiocp;
+       megacmd_t       __user *umc;
+       mega_passthru   __user *upthru;
+       struct uioctl_t __user *uioc_mimd;
        char    signature[8] = {0};
 
        /*
         * check is the application conforms to NIT.
         */
-       if( copy_from_user(signature, (char *)arg, 7) )
+       if( copy_from_user(signature, arg, 7) )
                return -EFAULT;
 
        if( memcmp(signature, "MEGANIT", 7) == 0 ) {
 
-               uiocp = (nitioctl_t *)arg;
+               uiocp = arg;
 
-               if( put_user(mc->status, (u8 *)&MBOX_P(uiocp)->status) )
+               if( put_user(mc->status, (u8 __user *)&MBOX_P(uiocp)->status) )
                        return (-EFAULT);
 
                if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
 
                        umc = MBOX_P(uiocp);
 
-                       upthru = (mega_passthru *)umc->xferaddr;
+                       if (get_user(upthru, (mega_passthru __user * __user *)&umc->xferaddr))
+                               return -EFAULT;
 
-                       if( put_user(mc->status, (u8 *)&upthru->scsistatus) )
+                       if( put_user(mc->status, (u8 __user *)&upthru->scsistatus))
                                return (-EFAULT);
                }
        }
        else {
-               uioc_mimd = (struct uioctl_t *)arg;
+               uioc_mimd = arg;
 
-               if( put_user(mc->status, (u8 *)&uioc_mimd->mbox[17]) )
+               if( put_user(mc->status, (u8 __user *)&uioc_mimd->mbox[17]) )
                        return (-EFAULT);
 
                if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
 
-                       umc = (megacmd_t *)uioc_mimd->mbox;
+                       umc = (megacmd_t __user *)uioc_mimd->mbox;
 
-                       upthru = (mega_passthru *)umc->xferaddr;
+                       if (get_user(upthru, (mega_passthru __user * __user *)&umc->xferaddr))
+                               return (-EFAULT);
 
-                       if( put_user(mc->status, (u8 *)&upthru->scsistatus) )
+                       if( put_user(mc->status, (u8 __user *)&upthru->scsistatus) )
                                return (-EFAULT);
                }
        }
@@ -3907,7 +4019,7 @@ mega_enum_raid_scsi(adapter_t *adapter)
        mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
        /*
-        * Non-ROMB firware fail this command, so all channels
+        * Non-ROMB firmware fail this command, so all channels
         * must be shown RAID
         */
        adapter->mega_ch_class = 0xFF;
@@ -4068,7 +4180,6 @@ mega_support_ext_cdb(adapter_t *adapter)
 static int
 mega_del_logdrv(adapter_t *adapter, int logdrv)
 {
-       DECLARE_WAIT_QUEUE_HEAD(wq);
        unsigned long flags;
        scb_t *scb;
        int rval;
@@ -4083,11 +4194,9 @@ mega_del_logdrv(adapter_t *adapter, int logdrv)
         * Wait till all the issued commands are complete and there are no
         * commands in the pending queue
         */
-       while( atomic_read(&adapter->pend_cmds) > 0 ||
-                       !list_empty(&adapter->pending_list) ) {
-
-               sleep_on_timeout( &wq, 1*HZ );  /* sleep for 1s */
-       }
+       while (atomic_read(&adapter->pend_cmds) > 0 ||
+              !list_empty(&adapter->pending_list))
+               msleep(1000);   /* sleep for 1s */
 
        rval = mega_do_del_logdrv(adapter, logdrv);
 
@@ -4128,7 +4237,7 @@ mega_do_del_logdrv(adapter_t *adapter, int logdrv)
        mc.opcode = OP_DEL_LOGDRV;
        mc.subopcode = logdrv;
 
-       rval = mega_internal_command(adapter, LOCK_INT, &mc, NULL);
+       rval = mega_internal_command(adapter, &mc, NULL);
 
        /* log this event */
        if(rval) {
@@ -4234,67 +4343,6 @@ mega_support_cluster(adapter_t *adapter)
 }
 
 
-
-/**
- * mega_get_ldrv_num()
- * @adapter - pointer to our soft state
- * @cmd - scsi mid layer command
- * @channel - channel on the controller
- *
- * Calculate the logical drive number based on the information in scsi command
- * and the channel number.
- */
-static inline int
-mega_get_ldrv_num(adapter_t *adapter, Scsi_Cmnd *cmd, int channel)
-{
-       int             tgt;
-       int             ldrv_num;
-
-       tgt = cmd->device->id;
-       
-       if ( tgt > adapter->this_id )
-               tgt--;  /* we do not get inquires for initiator id */
-
-       ldrv_num = (channel * 15) + tgt;
-
-
-       /*
-        * If we have a logical drive with boot enabled, project it first
-        */
-       if( adapter->boot_ldrv_enabled ) {
-               if( ldrv_num == 0 ) {
-                       ldrv_num = adapter->boot_ldrv;
-               }
-               else {
-                       if( ldrv_num <= adapter->boot_ldrv ) {
-                               ldrv_num--;
-                       }
-               }
-       }
-
-       /*
-        * If "delete logical drive" feature is enabled on this controller.
-        * Do only if at least one delete logical drive operation was done.
-        *
-        * Also, after logical drive deletion, instead of logical drive number,
-        * the value returned should be 0x80+logical drive id.
-        *
-        * These is valid only for IO commands.
-        */
-
-       if (adapter->support_random_del && adapter->read_ldidmap )
-               switch (cmd->cmnd[0]) {
-               case READ_6:    /* fall through */
-               case WRITE_6:   /* fall through */
-               case READ_10:   /* fall through */
-               case WRITE_10:
-                       ldrv_num += 0x80;
-               }
-
-       return ldrv_num;
-}
-
-
 /**
  * mega_adapinq()
  * @adapter - pointer to our soft state
@@ -4322,7 +4370,7 @@ mega_adapinq(adapter_t *adapter, dma_addr_t dma_handle)
 
        mc.xferaddr = (u32)dma_handle;
 
-       if ( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) {
+       if ( mega_internal_command(adapter, &mc, NULL) != 0 ) {
                return -1;
        }
 
@@ -4330,27 +4378,6 @@ mega_adapinq(adapter_t *adapter, dma_addr_t dma_handle)
 }
 
 
-/**
- * mega_allocate_inquiry()
- * @dma_handle - handle returned for dma address
- * @pdev - handle to pci device
- *
- * allocates memory for inquiry structure
- */
-static inline caddr_t
-mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev)
-{
-       return pci_alloc_consistent(pdev, sizeof(mega_inquiry3), dma_handle);
-}
-
-
-static inline void
-mega_free_inquiry(caddr_t inquiry, dma_addr_t dma_handle, struct pci_dev *pdev)
-{
-       pci_free_consistent(pdev, sizeof(mega_inquiry3), inquiry, dma_handle);
-}
-
-
 /** mega_internal_dev_inquiry()
  * @adapter - pointer to our soft state
  * @ch - channel for this device
@@ -4411,7 +4438,7 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt,
        mc.cmd = MEGA_MBOXCMD_PASSTHRU;
        mc.xferaddr = (u32)pthru_dma_handle;
 
-       rval = mega_internal_command(adapter, LOCK_INT, &mc, pthru);
+       rval = mega_internal_command(adapter, &mc, pthru);
 
        pci_free_consistent(pdev, sizeof(mega_passthru), pthru,
                        pthru_dma_handle);
@@ -4425,7 +4452,6 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt,
 /**
  * mega_internal_command()
  * @adapter - pointer to our soft state
- * @ls - the scope of the exclusion lock.
  * @mc - the mailbox command
  * @pthru - Passthru structure for DCDB commands
  *
@@ -4439,12 +4465,10 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt,
  * Note: parameter 'pthru' is null for non-passthru commands.
  */
 static int
-mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc,
-               mega_passthru *pthru )
+mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
 {
        Scsi_Cmnd       *scmd;
        struct  scsi_device *sdev;
-       unsigned long   flags = 0;
        scb_t   *scb;
        int     rval;
 
@@ -4453,7 +4477,7 @@ mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc,
         * serialized. This is so because we want to reserve maximum number of
         * available command ids for the I/O commands.
         */
-       down(&adapter->int_mtx);
+       mutex_lock(&adapter->int_mtx);
 
        scb = &adapter->int_scb;
        memset(scb, 0, sizeof(scb_t));
@@ -4466,7 +4490,7 @@ mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc,
        scmd->device = sdev;
 
        scmd->device->host = adapter->host;
-       scmd->buffer = (void *)scb;
+       scmd->request_buffer = (void *)scb;
        scmd->cmnd[0] = MEGA_INTERNAL_CMD;
 
        scb->state |= SCB_ACTIVE;
@@ -4484,26 +4508,9 @@ mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc,
 
        scb->idx = CMDID_INT_CMDS;
 
-       scmd->state = 0;
-
-       /*
-        * Get the lock only if the caller has not acquired it already
-        */
-       if( ls == LOCK_INT ) spin_lock_irqsave(&adapter->lock, flags);
-
        megaraid_queue(scmd, mega_internal_done);
 
-       if( ls == LOCK_INT ) spin_unlock_irqrestore(&adapter->lock, flags);
-
-       /*
-        * Wait till this command finishes. Do not use
-        * wait_event_interruptible(). It causes panic if CTRL-C is hit when
-        * dumping e.g., physical disk information through /proc interface.
-        */
-#if 0
-       wait_event_interruptible(adapter->int_waitq, scmd->state);
-#endif
-       wait_event(adapter->int_waitq, scmd->state);
+       wait_for_completion(&adapter->int_waitq);
 
        rval = scmd->result;
        mc->status = scmd->result;
@@ -4518,7 +4525,7 @@ mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc,
                        mc->cmd, mc->opcode, mc->subopcode, scmd->result);
        }
 
-       up(&adapter->int_mtx);
+       mutex_unlock(&adapter->int_mtx);
 
        return rval;
 }
@@ -4537,47 +4544,15 @@ mega_internal_done(Scsi_Cmnd *scmd)
 
        adapter = (adapter_t *)scmd->device->host->hostdata;
 
-       scmd->state = 1; /* thread waiting for its command to complete */
-
-       /*
-        * See comment in mega_internal_command() routine for
-        * wait_event_interruptible()
-        */
-#if 0
-       wake_up_interruptible(&adapter->int_waitq);
-#endif
-       wake_up(&adapter->int_waitq);
-
-}
-
-
-static inline int
-make_local_pdev(adapter_t *adapter, struct pci_dev **pdev)
-{
-       *pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
-
-       if( *pdev == NULL ) return -1;
-
-       memcpy(*pdev, adapter->dev, sizeof(struct pci_dev));
-
-       if( pci_set_dma_mask(*pdev, 0xffffffff) != 0 ) {
-               kfree(*pdev);
-               return -1;
-       }
+       complete(&adapter->int_waitq);
 
-       return 0;
 }
 
-static inline void
-free_local_pdev(struct pci_dev *pdev)
-{
-       kfree(pdev);
-}
 
 static struct scsi_host_template megaraid_template = {
        .module                         = THIS_MODULE,
        .name                           = "MegaRAID",
-       .proc_name                      = "megaraid",
+       .proc_name                      = "megaraid_legacy",
        .info                           = megaraid_info,
        .queuecommand                   = megaraid_queue,       
        .bios_param                     = megaraid_biosparam,
@@ -4611,6 +4586,26 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        pci_bus = pdev->bus->number;
        pci_dev_func = pdev->devfn;
 
+       /*
+        * The megaraid3 stuff reports the ID of the Intel part which is not
+        * remotely specific to the megaraid
+        */
+       if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
+               u16 magic;
+               /*
+                * Don't fall over the Compaq management cards using the same
+                * PCI identifier
+                */
+               if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ &&
+                   pdev->subsystem_device == 0xC000)
+                       return -ENODEV;
+               /* Now check the magic signature byte */
+               pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
+               if (magic != HBA_SIGNATURE_471 && magic != HBA_SIGNATURE)
+                       return -ENODEV;
+               /* Ok it is probably a megaraid */
+       }
+
        /*
         * For these vendor and device ids, signature offsets are not
         * valid and 64 bit is implicit
@@ -4674,6 +4669,8 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                host->host_no, mega_baseport, irq);
 
        adapter->base = mega_baseport;
+       if (flag & BOARD_MEMMAP)
+               adapter->mmio_base = (void __iomem *) mega_baseport;
 
        INIT_LIST_HEAD(&adapter->free_list);
        INIT_LIST_HEAD(&adapter->pending_list);
@@ -4681,7 +4678,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        adapter->flag = flag;
        spin_lock_init(&adapter->lock);
-       scsi_assign_lock(host, &adapter->lock);
 
        host->cmd_per_lun = max_cmd_per_lun;
        host->max_sectors = max_sectors_per_io;
@@ -4718,7 +4714,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        if (request_irq(irq, (adapter->flag & BOARD_MEMMAP) ?
                                megaraid_isr_memmapped : megaraid_isr_iomapped,
-                                       SA_SHIRQ, "megaraid", adapter)) {
+                                       IRQF_SHARED, "megaraid", adapter)) {
                printk(KERN_WARNING
                        "megaraid: Couldn't register IRQ %d!\n", irq);
                goto out_free_scb_list;
@@ -4863,15 +4859,15 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        /* Set the Mode of addressing to 64 bit if we can */
        if ((adapter->flag & BOARD_64BIT) && (sizeof(dma_addr_t) == 8)) {
-               pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
+               pci_set_dma_mask(pdev, DMA_64BIT_MASK);
                adapter->has_64bit_addr = 1;
        } else  {
-               pci_set_dma_mask(pdev, 0xffffffff);
+               pci_set_dma_mask(pdev, DMA_32BIT_MASK);
                adapter->has_64bit_addr = 0;
        }
                
-       init_MUTEX(&adapter->int_mtx);
-       init_waitqueue_head(&adapter->int_waitq);
+       mutex_init(&adapter->int_mtx);
+       init_completion(&adapter->int_waitq);
 
        adapter->this_id = DEFAULT_INITIATOR_ID;
        adapter->host->this_id = DEFAULT_INITIATOR_ID;
@@ -5033,43 +5029,31 @@ megaraid_remove_one(struct pci_dev *pdev)
 }
 
 static void
-megaraid_shutdown(struct device *dev)
+megaraid_shutdown(struct pci_dev *pdev)
 {
-       struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
+       struct Scsi_Host *host = pci_get_drvdata(pdev);
        adapter_t *adapter = (adapter_t *)host->hostdata;
 
        __megaraid_shutdown(adapter);
 }
 
 static struct pci_device_id megaraid_pci_tbl[] = {
-       {PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DISCOVERY,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
-       {PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_QC_VERDE,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
        {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_AMI_MEGARAID3,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_AMI_MEGARAID3,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {0,}
 };
 MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);
 
 static struct pci_driver megaraid_pci_driver = {
-       .name           = "megaraid",
+       .name           = "megaraid_legacy",
        .id_table       = megaraid_pci_tbl,
        .probe          = megaraid_probe_one,
        .remove         = __devexit_p(megaraid_remove_one),
-       .driver         = {
-               .shutdown = megaraid_shutdown,
-       },
+       .shutdown       = megaraid_shutdown,
 };
 
 static int __init megaraid_init(void)
@@ -5102,7 +5086,7 @@ static int __init megaraid_init(void)
         * First argument (major) to register_chrdev implies a dynamic
         * major number allocation.
         */
-       major = register_chrdev(0, "megadev", &megadev_fops);
+       major = register_chrdev(0, "megadev_legacy", &megadev_fops);
        if (!major) {
                printk(KERN_WARNING
                                "megaraid: failed to register char device\n");
@@ -5116,13 +5100,13 @@ static void __exit megaraid_exit(void)
        /*
         * Unregister the character device interface to the driver.
         */
-       unregister_chrdev(major, "megadev");
+       unregister_chrdev(major, "megadev_legacy");
+
+       pci_unregister_driver(&megaraid_pci_driver);
 
 #ifdef CONFIG_PROC_FS
        remove_proc_entry("megaraid", &proc_root);
 #endif
-
-       pci_unregister_driver(&megaraid_pci_driver);
 }
 
 module_init(megaraid_init);