vserver 1.9.3
[linux-2.6.git] / drivers / message / fusion / mptctl.c
index 434ceb1..bb608fa 100644 (file)
 #include <linux/pci.h>
 #include <linux/miscdevice.h>
 #include <linux/smp_lock.h>
+#include <linux/compat.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-#include <linux/kdev_t.h>      /* needed for access to Scsi_Host struct */
-#include <linux/blkdev.h>
-#include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 
 #define COPYRIGHT      "Copyright (c) 1999-2004 LSI Logic Corporation"
 #define MODULEAUTHOR   "Steven J. Ralston, Noah Romer, Pamela Delaney"
 #define my_VERSION     MPT_LINUX_VERSION_COMMON
 #define MYNAM          "mptctl"
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62)
-EXPORT_NO_SYMBOLS;
-#endif
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
@@ -112,7 +111,6 @@ MODULE_LICENSE("GPL");
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
 static int mptctl_id = -1;
-static struct semaphore mptctl_syscall_sem_ioc[MPT_MAX_ADAPTERS];
 
 static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
 
@@ -141,11 +139,14 @@ static int mptctl_do_reset(unsigned long arg);
 static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
 static int mptctl_hp_targetinfo(unsigned long arg);
 
+static int  mptctl_probe(struct pci_dev *, const struct pci_device_id *);
+static void mptctl_remove(struct pci_dev *);
+
 /*
  * Private function calls.
  */
-static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local);
-static int mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen);
+static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr);
+static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
 static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frags,
                struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
 static void kfree_sgl( MptSge_t *sgl, dma_addr_t sgl_dma,
@@ -209,10 +210,10 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
        }
 
        if (nonblock) {
-               if (down_trylock(&mptctl_syscall_sem_ioc[ioc->id]))
+               if (down_trylock(&ioc->ioctl->sem_ioc))
                        rc = -EAGAIN;
        } else {
-               if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id]))
+               if (down_interruptible(&ioc->ioctl->sem_ioc))
                        rc = -ERESTARTSYS;
        }
        dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc));
@@ -402,7 +403,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
 
        /* Send request
         */
-       if ((mf = mpt_get_msg_frame(mptctl_id, ioctl->ioc->id)) == NULL) {
+       if ((mf = mpt_get_msg_frame(mptctl_id, ioctl->ioc)) == NULL) {
                dctlprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
                                ioctl->ioc->name));
 
@@ -437,7 +438,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
        ioctl->status |= MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
        add_timer(&ioctl->TMtimer);
 
-       retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc->id,
+       retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc,
                        sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, NO_SLEEP);
 
        if (retval != 0) {
@@ -446,7 +447,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
 
                mptctl_free_tm_flags(ioctl->ioc);
                del_timer(&ioctl->TMtimer);
-               mpt_free_msg_frame(mptctl_id, ioctl->ioc->id, mf);
+               mpt_free_msg_frame(ioctl->ioc, mf);
                ioctl->tmPtr = NULL;
        }
 
@@ -483,7 +484,7 @@ mptctl_free_tm_flags(MPT_ADAPTER *ioc)
 
        spin_lock_irqsave(&ioc->FreeQlock, flags);
 
-       hd->tmState = TM_STATE_ERROR;
+       hd->tmState = TM_STATE_NONE;
        hd->tmPending = 0;
        spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 
@@ -521,7 +522,7 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
                if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)){
                        ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
                        del_timer(&ioctl->TMtimer);
-                       mpt_free_msg_frame(mptctl_id, ioc->id, ioctl->tmPtr);
+                       mpt_free_msg_frame(ioc, ioctl->tmPtr);
                }
 
        } else {
@@ -545,38 +546,6 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
        return 1;
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *  struct file_operations functionality.
- *  Members:
- *     llseek, write, read, ioctl, open, release
- */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
-static loff_t
-mptctl_llseek(struct file *file, loff_t offset, int origin)
-{
-       return -ESPIPE;
-}
-#define no_llseek mptctl_llseek
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static ssize_t
-mptctl_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
-       printk(KERN_ERR MYNAM ": ioctl WRITE not yet supported\n");
-       return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static ssize_t
-mptctl_read(struct file *file, char *buf, size_t count, loff_t *ptr)
-{
-       printk(KERN_ERR MYNAM ": ioctl READ not yet supported\n");
-       return 0;
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  MPT ioctl handler
@@ -586,7 +555,7 @@ mptctl_read(struct file *file, char *buf, size_t count, loff_t *ptr)
 static int
 mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
-       mpt_ioctl_header        *uhdr = (mpt_ioctl_header *) arg;
+       mpt_ioctl_header __user *uhdr = (void __user *) arg;
        mpt_ioctl_header         khdr;
        int iocnum;
        unsigned iocnumX;
@@ -599,7 +568,7 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
        if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
                printk(KERN_ERR "%s::mptctl_ioctl() @%d - "
                                "Unable to copy mpt_ioctl_header data @ %p\n",
-                               __FILE__, __LINE__, (void*)uhdr);
+                               __FILE__, __LINE__, uhdr);
                return -EFAULT;
        }
        ret = -ENXIO;                           /* (-6) No such device or address */
@@ -663,15 +632,14 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
        else
                ret = -EINVAL;
 
-
-       up(&mptctl_syscall_sem_ioc[iocp->id]);
+       up(&iocp->ioctl->sem_ioc);
 
        return ret;
 }
 
 static int mptctl_do_reset(unsigned long arg)
 {
-       struct mpt_ioctl_diag_reset *urinfo = (struct mpt_ioctl_diag_reset *) arg;
+       struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
        struct mpt_ioctl_diag_reset krinfo;
        MPT_ADAPTER             *iocp;
 
@@ -680,7 +648,7 @@ static int mptctl_do_reset(unsigned long arg)
        if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
                printk(KERN_ERR "%s@%d::mptctl_do_reset - "
                                "Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
-                               __FILE__, __LINE__, (void*)urinfo);
+                               __FILE__, __LINE__, urinfo);
                return -EFAULT;
        }
 
@@ -699,21 +667,6 @@ static int mptctl_do_reset(unsigned long arg)
        return 0;
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int mptctl_open(struct inode *inode, struct file *file)
-{
-       /*
-        * Should support multiple management users
-        */
-       return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int mptctl_release(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * MPT FW download function.  Cast the arg into the mpt_fw_xfer structure.
@@ -734,14 +687,14 @@ static int mptctl_release(struct inode *inode, struct file *file)
 static int
 mptctl_fw_download(unsigned long arg)
 {
-       struct mpt_fw_xfer      *ufwdl = (struct mpt_fw_xfer *) arg;
+       struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
        struct mpt_fw_xfer       kfwdl;
 
        dctlprintk((KERN_INFO "mptctl_fwdl called. mptctl_id = %xh\n", mptctl_id)); //tc
        if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
                printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
                                "Unable to copy mpt_fw_xfer struct @ %p\n",
-                               __FILE__, __LINE__, (void*)ufwdl);
+                               __FILE__, __LINE__, ufwdl);
                return -EFAULT;
        }
 
@@ -763,7 +716,7 @@ mptctl_fw_download(unsigned long arg)
  *             -ENOMSG if FW upload returned bad status
  */
 static int
-mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
+mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
 {
        FWDownload_t            *dlmsg;
        MPT_FRAME_HDR           *mf;
@@ -800,7 +753,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
 
        /*  Valid device. Get a message frame and construct the FW download message.
         */
-       if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
+       if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
                return -EAGAIN;
        dlmsg = (FWDownload_t*) mf;
        ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
@@ -892,7 +845,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
                        if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
                                printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
                                                "Unable to copy f/w buffer hunk#%d @ %p\n",
-                                               __FILE__, __LINE__, n, (void*)ufwbuf);
+                                               __FILE__, __LINE__, n, ufwbuf);
                                goto fwdl_out;
                        }
                        fw_bytes_copied += bl->len;
@@ -916,7 +869,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
         * Finally, perform firmware download.
         */
        ReplyMsg = NULL;
-       mpt_put_msg_frame(mptctl_id, ioc, mf);
+       mpt_put_msg_frame(mptctl_id, iocp, mf);
 
        /*
         *  Wait until the reply has been received
@@ -1198,7 +1151,7 @@ kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTE
 static int
 mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
 {
-       struct mpt_ioctl_iocinfo *uarg = (struct mpt_ioctl_iocinfo *) arg;
+       struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
        struct mpt_ioctl_iocinfo *karg;
        MPT_ADAPTER             *ioc;
        struct pci_dev          *pdev;
@@ -1238,7 +1191,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
        if (copy_from_user(karg, uarg, data_size)) {
                printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
                        "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                kfree(karg);
                return -EFAULT;
        }
@@ -1278,10 +1231,8 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
        karg->pciId = pdev->device;
        pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
        karg->hwRev = revision;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
        karg->subSystemDevice = pdev->subsystem_device;
        karg->subSystemVendor = pdev->subsystem_vendor;
-#endif
 
        if (cim_rev == 1) {
                /* Get the PCI bus, device, and function numbers for the IOC
@@ -1335,10 +1286,10 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
 
        /* Copy the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, karg, data_size)) {
+       if (copy_to_user((char __user *)arg, karg, data_size)) {
                printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
                        "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                kfree(karg);
                return -EFAULT;
        }
@@ -1360,7 +1311,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
 static int
 mptctl_gettargetinfo (unsigned long arg)
 {
-       struct mpt_ioctl_targetinfo *uarg = (struct mpt_ioctl_targetinfo *) arg;
+       struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
        struct mpt_ioctl_targetinfo karg;
        MPT_ADAPTER             *ioc;
        struct Scsi_Host        *sh;
@@ -1369,6 +1320,7 @@ mptctl_gettargetinfo (unsigned long arg)
        char                    *pmem;
        int                     *pdata;
        IOCPage2_t              *pIoc2;
+       IOCPage3_t              *pIoc3;
        int                     iocnum;
        int                     numDevices = 0;
        unsigned int            max_id;
@@ -1382,7 +1334,7 @@ mptctl_gettargetinfo (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
                printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
                        "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1445,53 +1397,57 @@ mptctl_gettargetinfo (unsigned long arg)
                if (hd && hd->Targets) {
                        mpt_findImVolumes(ioc);
                        pIoc2 = ioc->spi_data.pIocPg2;
-                       for ( id = 0; id <= max_id; id++ ) {
-                               if ( pIoc2 && pIoc2->NumActiveVolumes &&
-                                       ( id == pIoc2->RaidVolume[0].VolumeID ) ) {
-                                       if (maxWordsLeft <= 0) {
-                                               printk(KERN_ERR "mptctl_gettargetinfo - "
+                       for ( id = 0; id <= max_id; ) {
+                               if ( pIoc2 && pIoc2->NumActiveVolumes ) {
+                                       if ( id == pIoc2->RaidVolume[0].VolumeID ) {
+                                               if (maxWordsLeft <= 0) {
+                                                       printk(KERN_ERR "mptctl_gettargetinfo - "
                        "buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);
-                                               goto data_space_full;
-                                       }
-                                       if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )
-                                               devType = 0x80;
-                                       else
-                                               devType = 0xC0;
-                                       bus_id = pIoc2->RaidVolume[0].VolumeBus;
-                                       numDevices++;
-                                       *pdata = ( (devType << 24) | (bus_id << 8) | id );
-                                       dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
+                                                       goto data_space_full;
+                                               }
+                                               if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )
+                                                       devType = 0x80;
+                                               else
+                                                       devType = 0xC0;
+                                               bus_id = pIoc2->RaidVolume[0].VolumeBus;
+                                               numDevices++;
+                                               *pdata = ( (devType << 24) | (bus_id << 8) | id );
+                                               dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
                "volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
-                                       pdata++;
-                                       --maxWordsLeft;
-                               } else {
-                                       vdev = hd->Targets[id];
-                                       if (vdev) {
-                                               for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
-                                                       lun_index = (jj >> 5);
-                                                       indexed_lun = (jj % 32);
-                                                       lun = (1 << indexed_lun);
-                                                       if (vdev->luns[lun_index] & lun) {
-                                                               if (maxWordsLeft <= 0) {
-                                                                       printk(KERN_ERR
-                                                                       "mptctl_gettargetinfo - "
-                                                                       "buffer is full but more targets are available on ioc %d numDevices=%d\n",
-                                                                       iocnum, numDevices);
-                                                                       goto data_space_full;
-                                                               }
-                                                               bus_id = vdev->bus_id;
-                                                               numDevices++;
-                                                               *pdata = ( (jj << 16) | (bus_id << 8) | id );
-                                                               dctlprintk((KERN_ERR
-                                                                "mptctl_gettargetinfo - "
-                                                                "target ioc=%d target=%x numDevices=%d pdata=%p\n",
-                                                                iocnum, *pdata, numDevices, pdata));
-                                                               pdata++;
-                                                               --maxWordsLeft;
+                                               pdata++;
+                                               --maxWordsLeft;
+                                               goto next_id;
+                                       } else {
+                                               pIoc3 = ioc->spi_data.pIocPg3;
+                                               for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
+                                                       if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
+                                                               goto next_id;
+                                               }
+                                       }
+                               }
+                               if ( (vdev = hd->Targets[id]) ) {
+                                       for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
+                                               lun_index = (jj >> 5);
+                                               indexed_lun = (jj % 32);
+                                               lun = (1 << indexed_lun);
+                                               if (vdev->luns[lun_index] & lun) {
+                                                       if (maxWordsLeft <= 0) {
+                                                               printk(KERN_ERR "mptctl_gettargetinfo - "
+                       "buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices);
+                                                               goto data_space_full;
                                                        }
+                                                       bus_id = vdev->bus_id;
+                                                       numDevices++;
+                                                       *pdata = ( (jj << 16) | (bus_id << 8) | id );
+                                                       dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
+               "target ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
+                                                       pdata++;
+                                                       --maxWordsLeft;
                                                }
                                        }
                                }
+next_id:
+                               id++;
                        }
                }
        }
@@ -1500,21 +1456,21 @@ data_space_full:
 
        /* Copy part of the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, &karg,
+       if (copy_to_user((char __user *)arg, &karg,
                                sizeof(struct mpt_ioctl_targetinfo))) {
                printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                kfree(pmem);
                return -EFAULT;
        }
 
        /* Copy the remaining data from kernel memory to user memory
         */
-       if (copy_to_user((char *) uarg->targetInfo, pmem, numBytes)) {
+       if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
                printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)pdata);
+                               __FILE__, __LINE__, pdata);
                kfree(pmem);
                return -EFAULT;
        }
@@ -1535,7 +1491,7 @@ data_space_full:
 static int
 mptctl_readtest (unsigned long arg)
 {
-       struct mpt_ioctl_test   *uarg = (struct mpt_ioctl_test *) arg;
+       struct mpt_ioctl_test __user *uarg = (void __user *) arg;
        struct mpt_ioctl_test    karg;
        MPT_ADAPTER *ioc;
        int iocnum;
@@ -1544,7 +1500,7 @@ mptctl_readtest (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
                printk(KERN_ERR "%s@%d::mptctl_readtest - "
                        "Unable to read in mpt_ioctl_test struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1571,10 +1527,10 @@ mptctl_readtest (unsigned long arg)
 
        /* Copy the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
+       if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
                printk(KERN_ERR "%s@%d::mptctl_readtest - "
                        "Unable to write out mpt_ioctl_test struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1595,7 +1551,7 @@ mptctl_readtest (unsigned long arg)
 static int
 mptctl_eventquery (unsigned long arg)
 {
-       struct mpt_ioctl_eventquery     *uarg = (struct mpt_ioctl_eventquery *) arg;
+       struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
        struct mpt_ioctl_eventquery      karg;
        MPT_ADAPTER *ioc;
        int iocnum;
@@ -1604,7 +1560,7 @@ mptctl_eventquery (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
                printk(KERN_ERR "%s@%d::mptctl_eventquery - "
                        "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1620,10 +1576,10 @@ mptctl_eventquery (unsigned long arg)
 
        /* Copy the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
+       if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
                printk(KERN_ERR "%s@%d::mptctl_eventquery - "
                        "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
        return 0;
@@ -1633,7 +1589,7 @@ mptctl_eventquery (unsigned long arg)
 static int
 mptctl_eventenable (unsigned long arg)
 {
-       struct mpt_ioctl_eventenable    *uarg = (struct mpt_ioctl_eventenable *) arg;
+       struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
        struct mpt_ioctl_eventenable     karg;
        MPT_ADAPTER *ioc;
        int iocnum;
@@ -1642,7 +1598,7 @@ mptctl_eventenable (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
                printk(KERN_ERR "%s@%d::mptctl_eventenable - "
                        "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1680,7 +1636,7 @@ mptctl_eventenable (unsigned long arg)
 static int
 mptctl_eventreport (unsigned long arg)
 {
-       struct mpt_ioctl_eventreport    *uarg = (struct mpt_ioctl_eventreport *) arg;
+       struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
        struct mpt_ioctl_eventreport     karg;
        MPT_ADAPTER              *ioc;
        int                      iocnum;
@@ -1690,7 +1646,7 @@ mptctl_eventreport (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
                printk(KERN_ERR "%s@%d::mptctl_eventreport - "
                        "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1716,10 +1672,10 @@ mptctl_eventreport (unsigned long arg)
        /* Copy the data from kernel memory to user memory
         */
        numBytes = max * sizeof(MPT_IOCTL_EVENTS);
-       if (copy_to_user((char *) uarg->eventData, ioc->events, numBytes)) {
+       if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
                printk(KERN_ERR "%s@%d::mptctl_eventreport - "
                        "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
-                               __FILE__, __LINE__, (void*)ioc->events);
+                               __FILE__, __LINE__, ioc->events);
                return -EFAULT;
        }
 
@@ -1730,21 +1686,17 @@ mptctl_eventreport (unsigned long arg)
 static int
 mptctl_replace_fw (unsigned long arg)
 {
-       struct mpt_ioctl_replace_fw     *uarg = (struct mpt_ioctl_replace_fw *) arg;
+       struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
        struct mpt_ioctl_replace_fw      karg;
        MPT_ADAPTER              *ioc;
-       fw_image_t               **fwmem = NULL;
        int                      iocnum;
        int                      newFwSize;
-       int                      num_frags, alloc_sz;
-       int                      ii;
-       u32                      offset;
 
        dctlprintk(("mptctl_replace_fw called.\n"));
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
                printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
                        "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1755,52 +1707,39 @@ mptctl_replace_fw (unsigned long arg)
                return -ENODEV;
        }
 
-       /* If not caching FW, return 0
+       /* If caching FW, Free the old FW image
         */
-       if ((ioc->cached_fw == NULL) && (ioc->alt_ioc) && (ioc->alt_ioc->cached_fw == NULL))
+       if (ioc->cached_fw == NULL)
                return 0;
 
+       mpt_free_fw_memory(ioc);
+
        /* Allocate memory for the new FW image
         */
        newFwSize = karg.newImageSize;
-       fwmem = mpt_alloc_fw_memory(ioc, newFwSize, &num_frags, &alloc_sz);
-       if (fwmem == NULL)
-               return -ENOMEM;
 
-       offset = 0;
-       for (ii = 0; ii < num_frags; ii++) {
-               /* Copy the data from user memory to kernel space
-                */
-               if (copy_from_user(fwmem[ii]->fw, uarg->newImage + offset, fwmem[ii]->size)) {
-                       printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
-                               "Unable to read in mpt_ioctl_replace_fw image @ %p\n",
-                                       __FILE__, __LINE__, (void*)uarg);
-
-                       mpt_free_fw_memory(ioc, fwmem);
-                       return -EFAULT;
-               }
-               offset += fwmem[ii]->size;
-       }
+       if (newFwSize & 0x01)
+               newFwSize += 1;
+       if (newFwSize & 0x02)
+               newFwSize += 2;
 
+       mpt_alloc_fw_memory(ioc, newFwSize);
+       if (ioc->cached_fw == NULL)
+               return -ENOMEM;
 
-       /* Free the old FW image
+       /* Copy the data from user memory to kernel space
         */
-       if (ioc->cached_fw) {
-               mpt_free_fw_memory(ioc, 0);
-               ioc->cached_fw = fwmem;
-               ioc->alloc_total += alloc_sz;
-       } else if ((ioc->alt_ioc) && (ioc->alt_ioc->cached_fw)) {
-               mpt_free_fw_memory(ioc->alt_ioc, 0);
-               ioc->alt_ioc->cached_fw = fwmem;
-               ioc->alt_ioc->alloc_total += alloc_sz;
+       if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
+               printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
+                               "Unable to read in mpt_ioctl_replace_fw image "
+                               "@ %p\n", __FILE__, __LINE__, uarg);
+               mpt_free_fw_memory(ioc);
+               return -EFAULT;
        }
 
        /* Update IOCFactsReply
         */
        ioc->facts.FWImageSize = newFwSize;
-       if (ioc->alt_ioc)
-               ioc->alt_ioc->facts.FWImageSize = newFwSize;
-
        return 0;
 }
 
@@ -1819,7 +1758,7 @@ mptctl_replace_fw (unsigned long arg)
 static int
 mptctl_mpt_command (unsigned long arg)
 {
-       struct mpt_ioctl_command *uarg = (struct mpt_ioctl_command *) arg;
+       struct mpt_ioctl_command __user *uarg = (void __user *) arg;
        struct mpt_ioctl_command  karg;
        MPT_ADAPTER     *ioc;
        int             iocnum;
@@ -1830,7 +1769,7 @@ mptctl_mpt_command (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
                printk(KERN_ERR "%s@%d::mptctl_mpt_command - "
                        "Unable to read in mpt_ioctl_command struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1841,7 +1780,7 @@ mptctl_mpt_command (unsigned long arg)
                return -ENODEV;
        }
 
-       rc = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0);
+       rc = mptctl_do_mpt_command (karg, &uarg->MF);
 
        return rc;
 }
@@ -1859,7 +1798,7 @@ mptctl_mpt_command (unsigned long arg)
  *             -EPERM if SCSI I/O and target is untagged
  */
 static int
-mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
+mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
 {
        MPT_ADAPTER     *ioc;
        MPT_FRAME_HDR   *mf = NULL;
@@ -1869,7 +1808,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
        struct buflist  bufOut; /* data Out buffer */
        dma_addr_t      dma_addr_in;
        dma_addr_t      dma_addr_out;
-       int             dir;    /* PCI data direction */
        int             sgSize = 0;     /* Num SG elements */
        int             iocnum, flagsLength;
        int             sz, rc = 0;
@@ -1914,7 +1852,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
 
        /* Get a free request frame and save the message context.
         */
-        if ((mf = mpt_get_msg_frame(mptctl_id, ioc->id)) == NULL)
+        if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
                 return -EAGAIN;
 
        hdr = (MPIHeader_t *) mf;
@@ -1923,23 +1861,15 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
 
        /* Copy the request frame
         * Reset the saved message context.
+        * Request frame in user space
         */
-        if (local) {
-               /* Request frame in kernel space
-                */
-               memcpy((char *)mf, (char *) mfPtr, karg.dataSgeOffset * 4);
-        } else {
-               /* Request frame in user space
-                */
-               if (copy_from_user((char *)mf, (char *) mfPtr,
-                                       karg.dataSgeOffset * 4)){
-                       printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
-                               "Unable to read MF from mpt_ioctl_command struct @ %p\n",
-                               __FILE__, __LINE__, (void*)mfPtr);
-                       rc = -EFAULT;
-                       goto done_free_mem;
-               }
-        }
+       if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
+               printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+                       "Unable to read MF from mpt_ioctl_command struct @ %p\n",
+                       __FILE__, __LINE__, mfPtr);
+               rc = -EFAULT;
+               goto done_free_mem;
+       }
        hdr->MsgContext = cpu_to_le32(msgContext);
 
 
@@ -2187,9 +2117,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
 
                /* Set up the dataOut memory allocation */
                if (karg.dataOutSize > 0) {
-                       dir = PCI_DMA_TODEVICE;
                        if (karg.dataInSize > 0) {
                                flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+                                               MPI_SGE_FLAGS_END_OF_BUFFER |
                                                MPI_SGE_FLAGS_DIRECTION |
                                                mpt_addr_size() )
                                                << MPI_SGE_FLAGS_SHIFT;
@@ -2220,7 +2150,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
                                                "%s@%d::mptctl_do_mpt_command - Unable "
                                                "to read user data "
                                                "struct @ %p\n",
-                                               __FILE__, __LINE__,(void*)karg.dataOutBufPtr);
+                                               __FILE__, __LINE__,karg.dataOutBufPtr);
                                        rc =  -EFAULT;
                                        goto done_free_mem;
                                }
@@ -2228,7 +2158,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
                }
 
                if (karg.dataInSize > 0) {
-                       dir = PCI_DMA_FROMDEVICE;
                        flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
                        flagsLength |= karg.dataInSize;
 
@@ -2266,7 +2195,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
        add_timer(&ioc->ioctl->timer);
 
        if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
-               rc = mpt_send_handshake_request(mptctl_id, ioc->id,
+               DBG_DUMP_TM_REQUEST_FRAME((u32 *)mf);
+               rc = mpt_send_handshake_request(mptctl_id, ioc,
                                sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
                if (rc == 0) {
                        wait_event(mptctl_wait, ioc->ioctl->wait_done);
@@ -2276,10 +2206,10 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
                        del_timer(&ioc->ioctl->timer);
                        ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
                        ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED;
-                       mpt_free_msg_frame(mptctl_id, ioc->id, mf);
+                       mpt_free_msg_frame(ioc, mf);
                }
        } else {
-               mpt_put_msg_frame(mptctl_id, ioc->id, mf);
+               mpt_put_msg_frame(mptctl_id, ioc, mf);
                wait_event(mptctl_wait, ioc->ioctl->wait_done);
        }
 
@@ -2321,12 +2251,12 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
                        }
 
                        if (sz > 0) {
-                               if (copy_to_user((char *)karg.replyFrameBufPtr,
+                               if (copy_to_user(karg.replyFrameBufPtr,
                                         &ioc->ioctl->ReplyFrame, sz)){
 
                                         printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
                                         "Unable to write out reply frame %p\n",
-                                        __FILE__, __LINE__, (void*)karg.replyFrameBufPtr);
+                                        __FILE__, __LINE__, karg.replyFrameBufPtr);
                                         rc =  -ENODATA;
                                         goto done_free_mem;
                                }
@@ -2338,11 +2268,11 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
                if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) {
                        sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
                        if (sz > 0) {
-                               if (copy_to_user((char *)karg.senseDataPtr, ioc->ioctl->sense, sz)) {
+                               if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) {
                                        printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
                                        "Unable to write sense data to user %p\n",
                                        __FILE__, __LINE__,
-                                       (void*)karg.senseDataPtr);
+                                       karg.senseDataPtr);
                                        rc =  -ENODATA;
                                        goto done_free_mem;
                                }
@@ -2355,12 +2285,12 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
                if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) &&
                                        (karg.dataInSize > 0) && (bufIn.kptr)) {
 
-                       if (copy_to_user((char *)karg.dataInBufPtr,
+                       if (copy_to_user(karg.dataInBufPtr,
                                         bufIn.kptr, karg.dataInSize)) {
                                printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
                                        "Unable to write data to user %p\n",
                                        __FILE__, __LINE__,
-                                       (void*)karg.dataInBufPtr);
+                                       karg.dataInBufPtr);
                                rc =  -ENODATA;
                        }
                }
@@ -2394,7 +2324,7 @@ done_free_mem:
         * otherwise, failure occured after mf acquired.
         */
        if (mf)
-               mpt_free_msg_frame(mptctl_id, ioc->id, mf);
+               mpt_free_msg_frame(ioc, mf);
 
        return rc;
 }
@@ -2413,7 +2343,7 @@ done_free_mem:
 static int
 mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 {
-       hp_host_info_t  *uarg = (hp_host_info_t *) arg;
+       hp_host_info_t  __user *uarg = (void __user *) arg;
        MPT_ADAPTER             *ioc;
        struct pci_dev          *pdev;
        char                    *pbuf;
@@ -2437,7 +2367,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
        if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
                printk(KERN_ERR "%s@%d::mptctl_hp_host_info - "
                        "Unable to read in hp_host_info struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -2455,10 +2385,8 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 
        karg.vendor = pdev->vendor;
        karg.device = pdev->device;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
        karg.subsystem_id = pdev->subsystem_device;
        karg.subsystem_vendor = pdev->subsystem_vendor;
-#endif
        karg.devfn = pdev->devfn;
        karg.bus = pdev->bus->number;
 
@@ -2540,7 +2468,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
                break;
        }
 
-       karg.base_io_addr = pdev->PCI_BASEADDR_START(0);
+       karg.base_io_addr = pci_resource_start(pdev, 0);
 
        if ((int)ioc->chip_type <= (int) FC929)
                karg.bus_phys_width = HP_BUS_WIDTH_UNK;
@@ -2576,11 +2504,10 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 
        /* Copy the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, &karg,
-                               sizeof(hp_host_info_t))) {
+       if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
                printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - "
                        "Unable to write out hp_host_info @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -2602,7 +2529,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 static int
 mptctl_hp_targetinfo(unsigned long arg)
 {
-       hp_target_info_t        *uarg = (hp_target_info_t *) arg;
+       hp_target_info_t __user *uarg = (void __user *) arg;
        SCSIDevicePage0_t       *pg0_alloc;
        SCSIDevicePage3_t       *pg3_alloc;
        MPT_ADAPTER             *ioc;
@@ -2619,7 +2546,7 @@ mptctl_hp_targetinfo(unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
                printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - "
                        "Unable to read in hp_host_targetinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
        
@@ -2727,10 +2654,10 @@ mptctl_hp_targetinfo(unsigned long arg)
 
        /* Copy the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, &karg, sizeof(hp_target_info_t))) {
+       if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
                printk(KERN_ERR "%s@%d::mptctl_hp_target_info - "
                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -2739,20 +2666,10 @@ mptctl_hp_targetinfo(unsigned long arg)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
-#define        owner_THIS_MODULE  .owner = THIS_MODULE,
-#else
-#define        owner_THIS_MODULE
-#endif
-
 static struct file_operations mptctl_fops = {
-       owner_THIS_MODULE
+       .owner =        THIS_MODULE,
        .llseek =       no_llseek,
-       .read =         mptctl_read,
-       .write =        mptctl_write,
        .ioctl =        mptctl_ioctl,
-       .open =         mptctl_open,
-       .release =      mptctl_release,
 };
 
 static struct miscdevice mptctl_miscdev = {
@@ -2800,7 +2717,7 @@ compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
 
        dctlprintk((KERN_INFO MYNAM "::compat_mptfwxfer_ioctl() called\n"));
 
-       if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32)))
+       if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
                return -EFAULT;
 
        /* Verify intended MPT adapter */
@@ -2817,11 +2734,11 @@ compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
 
        kfw.iocnum = iocnum;
        kfw.fwlen = kfw32.fwlen;
-       kfw.bufp = (void *)(unsigned long)kfw32.bufp;
+       kfw.bufp = compat_ptr(kfw32.bufp);
 
        ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
 
-       up(&mptctl_syscall_sem_ioc[iocp->id]);
+       up(&iocp->ioctl->sem_ioc);
 
        return ret;
 }
@@ -2831,7 +2748,7 @@ compat_mpt_command(unsigned int fd, unsigned int cmd,
                        unsigned long arg, struct file *filp)
 {
        struct mpt_ioctl_command32 karg32;
-       struct mpt_ioctl_command32 *uarg = (struct mpt_ioctl_command32 *) arg;
+       struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
        struct mpt_ioctl_command karg;
        MPT_ADAPTER *iocp = NULL;
        int iocnum, iocnumX;
@@ -2840,7 +2757,7 @@ compat_mpt_command(unsigned int fd, unsigned int cmd,
 
        dctlprintk((KERN_INFO MYNAM "::compat_mpt_command() called\n"));
 
-       if (copy_from_user(&karg32, (char *)arg, sizeof(karg32)))
+       if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
                return -EFAULT;
 
        /* Verify intended MPT adapter */
@@ -2866,64 +2783,100 @@ compat_mpt_command(unsigned int fd, unsigned int cmd,
        karg.maxSenseBytes = karg32.maxSenseBytes;
        karg.dataSgeOffset = karg32.dataSgeOffset;
 
-       karg.replyFrameBufPtr = (char *)(unsigned long)karg32.replyFrameBufPtr;
-       karg.dataInBufPtr = (char *)(unsigned long)karg32.dataInBufPtr;
-       karg.dataOutBufPtr = (char *)(unsigned long)karg32.dataOutBufPtr;
-       karg.senseDataPtr = (char *)(unsigned long)karg32.senseDataPtr;
+       karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
+       karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
+       karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
+       karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
 
        /* Pass new structure to do_mpt_command
         */
-       ret = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0);
+       ret = mptctl_do_mpt_command (karg, &uarg->MF);
 
-       up(&mptctl_syscall_sem_ioc[iocp->id]);
+       up(&iocp->ioctl->sem_ioc);
 
        return ret;
 }
 
 #endif
 
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-int __init mptctl_init(void)
+/*
+ *     mptctl_probe - Installs ioctl devices per bus.
+ *     @pdev: Pointer to pci_dev structure
+ *
+ *     Returns 0 for success, non-zero for failure.
+ *
+ */
+
+static int
+mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        int err;
-       int i;
-       int where = 1;
        int sz;
        u8 *mem;
-       MPT_ADAPTER *ioc = NULL;
-       int iocnum;
+       MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
 
-       show_mptmod_ver(my_NAME, my_VERSION);
+       /*
+        * Allocate and inite a MPT_IOCTL structure
+       */
+       sz = sizeof (MPT_IOCTL);
+       mem = kmalloc(sz, GFP_KERNEL);
+       if (mem == NULL) {
+               err = -ENOMEM;
+               goto out_fail;
+       }
 
-       for (i=0; i<MPT_MAX_ADAPTERS; i++) {
-               sema_init(&mptctl_syscall_sem_ioc[i], 1);
+       memset(mem, 0, sz);
+       ioc->ioctl = (MPT_IOCTL *) mem;
+       ioc->ioctl->ioc = ioc;
+       init_timer (&ioc->ioctl->timer);
+       ioc->ioctl->timer.data = (unsigned long) ioc->ioctl;
+       ioc->ioctl->timer.function = mptctl_timer_expired;
+       init_timer (&ioc->ioctl->TMtimer);
+       ioc->ioctl->TMtimer.data = (unsigned long) ioc->ioctl;
+       ioc->ioctl->TMtimer.function = mptctl_timer_expired;
+       sema_init(&ioc->ioctl->sem_ioc, 1);
+       return 0;
 
-               ioc = NULL;
-               if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
-                   (ioc == NULL)) {
-                       continue;
-               }
-               else {
-                       /* This adapter instance is found.
-                        * Allocate and inite a MPT_IOCTL structure
-                        */
-                       sz = sizeof (MPT_IOCTL);
-                       mem = kmalloc(sz, GFP_KERNEL);
-                       if (mem == NULL) {
-                               err = -ENOMEM;
-                               goto out_fail;
-                       }
+out_fail:
 
-                       memset(mem, 0, sz);
-                       ioc->ioctl = (MPT_IOCTL *) mem;
-                       ioc->ioctl->ioc = ioc;
-                       init_timer (&ioc->ioctl->timer);
-                       ioc->ioctl->timer.data = (unsigned long) ioc->ioctl;
-                       ioc->ioctl->timer.function = mptctl_timer_expired;
-                       init_timer (&ioc->ioctl->TMtimer);
-                       ioc->ioctl->TMtimer.data = (unsigned long) ioc->ioctl;
-                       ioc->ioctl->TMtimer.function = mptctl_timer_expired;
-               }
+       mptctl_remove(pdev);
+       return err;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *     mptctl_remove - Removed ioctl devices
+ *     @pdev: Pointer to pci_dev structure
+ *
+ *
+ */
+static void
+mptctl_remove(struct pci_dev *pdev)
+{
+       MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+
+       kfree ( ioc->ioctl );
+}
+
+static struct mpt_pci_driver mptctl_driver = {
+  .probe               = mptctl_probe,
+  .remove              = mptctl_remove,
+};
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int __init mptctl_init(void)
+{
+       int err;
+       int where = 1;
+
+       show_mptmod_ver(my_NAME, my_VERSION);
+
+       if(mpt_device_driver_register(&mptctl_driver,
+         MPTCTL_DRIVER) != 0 ) {
+               dprintk((KERN_INFO MYNAM
+               ": failed to register dd callbacks\n"));
        }
 
 #ifdef CONFIG_COMPAT
@@ -3005,29 +2958,14 @@ out_fail:
        unregister_ioctl32_conversion(HP_GETTARGETINFO);
 #endif
 
-       for (i=0; i<MPT_MAX_ADAPTERS; i++) {
-               ioc = NULL;
-               if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
-                   (ioc == NULL)) {
-                       continue;
-               }
-               else {
-                       if (ioc->ioctl) {
-                               kfree ( ioc->ioctl );
-                               ioc->ioctl = NULL;
-                       }
-               }
-       }
+       mpt_device_driver_deregister(MPTCTL_DRIVER);
+
        return err;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-void mptctl_exit(void)
+static void mptctl_exit(void)
 {
-       int i;
-       MPT_ADAPTER *ioc;
-       int iocnum;
-
        misc_deregister(&mptctl_miscdev);
        printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
                         mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
@@ -3040,6 +2978,8 @@ void mptctl_exit(void)
        mpt_deregister(mptctl_id);
        printk(KERN_INFO MYNAM ": Deregistered from Fusion MPT base driver\n");
 
+        mpt_device_driver_deregister(MPTCTL_DRIVER);
+
 #ifdef CONFIG_COMPAT
        unregister_ioctl32_conversion(MPTIOCINFO);
        unregister_ioctl32_conversion(MPTIOCINFO1);
@@ -3056,20 +2996,6 @@ void mptctl_exit(void)
        unregister_ioctl32_conversion(HP_GETTARGETINFO);
 #endif
 
-       /* Free allocated memory */
-       for (i=0; i<MPT_MAX_ADAPTERS; i++) {
-               ioc = NULL;
-               if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
-                   (ioc == NULL)) {
-                       continue;
-               }
-               else {
-                       if (ioc->ioctl) {
-                               kfree ( ioc->ioctl );
-                               ioc->ioctl = NULL;
-                       }
-               }
-       }
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/