diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 95f7a76cfafcf8a296f43edec9d22ba7ce342c59..8aed855dd391de862eae8750f132ccbc8c893560 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -541,7 +541,6 @@ config SCSI_ARCMSR
 
 source "drivers/scsi/esas2r/Kconfig"
 source "drivers/scsi/megaraid/Kconfig.megaraid"
-source "drivers/scsi/mpt2sas/Kconfig"
 source "drivers/scsi/mpt3sas/Kconfig"
 source "drivers/scsi/ufs/Kconfig"
 
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 1a8c9b53fafad5900ef775599a7f34abd34978eb..c14bca4a9675c1d1ce29d759354cd8a835bdf98d 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -106,7 +106,6 @@ obj-$(CONFIG_CXLFLASH)		+= cxlflash/
 obj-$(CONFIG_MEGARAID_LEGACY)	+= megaraid.o
 obj-$(CONFIG_MEGARAID_NEWGEN)	+= megaraid/
 obj-$(CONFIG_MEGARAID_SAS)	+= megaraid/
-obj-$(CONFIG_SCSI_MPT2SAS)	+= mpt2sas/
 obj-$(CONFIG_SCSI_MPT3SAS)	+= mpt3sas/
 obj-$(CONFIG_SCSI_UFSHCD)	+= ufs/
 obj-$(CONFIG_SCSI_ACARD)	+= atp870u.o
diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig
deleted file mode 100644
index 1356a0aa5d14e4e562ce4b0e245d5c1e24c3ece4..0000000000000000000000000000000000000000
--- a/drivers/scsi/mpt2sas/Kconfig
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Kernel configuration file for the MPT2SAS
-#
-# This code is based on drivers/scsi/mpt2sas/Kconfig
-# Copyright (C) 2007-2014  LSI Corporation
-#  (mailto:DL-MPTFusionLinux@lsi.com)
-
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# NO WARRANTY
-# THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
-# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
-# LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
-# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
-# solely responsible for determining the appropriateness of using and
-# distributing the Program and assumes all risks associated with its
-# exercise of rights under this Agreement, including but not limited to
-# the risks and costs of program errors, damage to or loss of data,
-# programs or equipment, and unavailability or interruption of operations.
-
-# DISCLAIMER OF LIABILITY
-# NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-# USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
-# HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
-# USA.
-
-config SCSI_MPT2SAS
-	tristate "LSI MPT Fusion SAS 2.0 Device Driver"
-	depends on PCI && SCSI
-	select SCSI_SAS_ATTRS
-	select RAID_ATTRS
-	---help---
-	This driver supports PCI-Express SAS 6Gb/s Host Adapters.
-
-config SCSI_MPT2SAS_MAX_SGE
-	int "LSI MPT Fusion Max number of SG Entries (16 - 128)"
-	depends on PCI && SCSI && SCSI_MPT2SAS
-	default "128"
-	range 16 128
-	---help---
-	This option allows you to specify the maximum number of scatter-
-	gather entries per I/O. The driver default is 128, which matches
-	SAFE_PHYS_SEGMENTS.  However, it may decreased down to 16.
-	Decreasing this parameter will reduce memory requirements
-	on a per controller instance.
diff --git a/drivers/scsi/mpt2sas/Makefile b/drivers/scsi/mpt2sas/Makefile
deleted file mode 100644
index 37716169b91a33b21906322e445e165a94e608ba..0000000000000000000000000000000000000000
--- a/drivers/scsi/mpt2sas/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# mpt2sas makefile
-
-# share the official mpi headers from the mpt3sas driver
-ccflags-y += -I$(src)/../mpt3sas
-ccflags-y += -DSCSI_MPT2SAS
-
-# use the common object files from mpt3sas driver
-obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas.o
-mpt2sas-y +=  ../mpt3sas/mpt3sas_base.o        \
-		../mpt3sas/mpt3sas_config.o    \
-		../mpt3sas/mpt3sas_scsih.o     \
-		../mpt3sas/mpt3sas_transport.o \
-		../mpt3sas/mpt3sas_ctl.o       \
-		../mpt3sas/mpt3sas_trigger_diag.o  \
-		mpt2sas_module.o
diff --git a/drivers/scsi/mpt2sas/mpt2sas_module.c b/drivers/scsi/mpt2sas/mpt2sas_module.c
deleted file mode 100644
index d407ed04315d89ac924b8ef64cea3eb3b8a2a188..0000000000000000000000000000000000000000
--- a/drivers/scsi/mpt2sas/mpt2sas_module.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Scsi Host Layer for MPT (Message Passing Technology) based controllers
- *
- * Copyright (C) 2012-2014  LSI Corporation
- * Copyright (C) 2013-2015 Avago Technologies
- *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
-
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- * You should have received a copy of the GNU General Public License
- * along with this program.
- */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/raid_class.h>
-
-#include "mpt3sas_base.h"
-#include "mpt3sas_ctl.h"
-
-MODULE_AUTHOR(MPT3SAS_AUTHOR);
-MODULE_DESCRIPTION(MPT2SAS_DESCRIPTION);
-MODULE_LICENSE("GPL");
-MODULE_VERSION(MPT2SAS_DRIVER_VERSION);
-
-/* shost template */
-static struct scsi_host_template mpt2sas_driver_template = {
-	.module				= THIS_MODULE,
-	.name				= "Fusion MPT SAS Host",
-	.proc_name			= MPT2SAS_DRIVER_NAME,
-	.queuecommand			= scsih_qcmd,
-	.target_alloc			= scsih_target_alloc,
-	.slave_alloc			= scsih_slave_alloc,
-	.slave_configure		= scsih_slave_configure,
-	.target_destroy			= scsih_target_destroy,
-	.slave_destroy			= scsih_slave_destroy,
-	.scan_finished			= scsih_scan_finished,
-	.scan_start			= scsih_scan_start,
-	.change_queue_depth		= scsih_change_queue_depth,
-	.eh_abort_handler		= scsih_abort,
-	.eh_device_reset_handler	= scsih_dev_reset,
-	.eh_target_reset_handler	= scsih_target_reset,
-	.eh_host_reset_handler		= scsih_host_reset,
-	.bios_param			= scsih_bios_param,
-	.can_queue			= 1,
-	.this_id			= -1,
-	.sg_tablesize			= MPT2SAS_SG_DEPTH,
-	.max_sectors			= 32767,
-	.cmd_per_lun			= 7,
-	.use_clustering			= ENABLE_CLUSTERING,
-	.shost_attrs			= mpt3sas_host_attrs,
-	.sdev_attrs			= mpt3sas_dev_attrs,
-	.track_queue_depth		= 1,
-};
-
-/* raid transport support */
-static struct raid_function_template mpt2sas_raid_functions = {
-	.cookie		= &mpt2sas_driver_template,
-	.is_raid	= scsih_is_raid,
-	.get_resync	= scsih_get_resync,
-	.get_state	= scsih_get_state,
-};
-
-/*
- * The pci device ids are defined in mpi/mpi2_cnfg.h.
- */
-static const struct pci_device_id mpt2sas_pci_table[] = {
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004,
-		PCI_ANY_ID, PCI_ANY_ID },
-	/* Falcon ~ 2008*/
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008,
-		PCI_ANY_ID, PCI_ANY_ID },
-	/* Liberator ~ 2108 */
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
-		PCI_ANY_ID, PCI_ANY_ID },
-	/* Meteor ~ 2116 */
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
-		PCI_ANY_ID, PCI_ANY_ID },
-	/* Thunderbolt ~ 2208 */
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
-		PCI_ANY_ID, PCI_ANY_ID },
-	/* Mustang ~ 2308 */
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_1,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
-		PCI_ANY_ID, PCI_ANY_ID },
-	/* SSS6200 */
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{0}	/* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, mpt2sas_pci_table);
-
-static const struct file_operations mpt2sas_ctl_fops = {
-	.owner = THIS_MODULE,
-	.unlocked_ioctl = ctl_ioctl,
-	.poll = ctl_poll,
-	.fasync = ctl_fasync,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl = ctl_ioctl_compat,
-#endif
-	.llseek = noop_llseek,
-};
-
-static struct miscdevice mpt2sas_ctl_dev = {
-	.minor  = MPT2SAS_MINOR,
-	.name   = MPT2SAS_DEV_NAME,
-	.fops   = &mpt2sas_ctl_fops,
-};
-
-/**
- * mpt2sas_ctl_init - main entry point for ctl.
- *
- */
-void
-mpt2sas_ctl_init(void)
-{
-	ctl_init();
-	if (misc_register(&mpt2sas_ctl_dev) < 0)
-		pr_err("%s can't register misc device [minor=%d]\n",
-		    MPT2SAS_DRIVER_NAME, MPT2SAS_MINOR);
-}
-
-/**
- * mpt2sas_ctl_exit - exit point for ctl
- *
- */
-void
-mpt2sas_ctl_exit(void)
-{
-	ctl_exit();
-	misc_deregister(&mpt2sas_ctl_dev);
-}
-
-/**
- * _mpt2sas_probe - attach and add scsi host
- * @pdev: PCI device struct
- * @id: pci device id
- *
- * Returns 0 success, anything else error.
- */
-static int
-_mpt2sas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-	struct Scsi_Host *shost;
-	int rv;
-
-	shost = scsi_host_alloc(&mpt2sas_driver_template,
-			    sizeof(struct MPT3SAS_ADAPTER));
-	if (!shost)
-		return -ENODEV;
-
-	sprintf(driver_name, "%s", MPT2SAS_DRIVER_NAME);
-	rv = scsih_probe(pdev, shost);
-	return rv;
-}
-
-static struct pci_error_handlers _mpt2sas_err_handler = {
-	.error_detected = scsih_pci_error_detected,
-	.mmio_enabled = scsih_pci_mmio_enabled,
-	.slot_reset =   scsih_pci_slot_reset,
-	.resume =       scsih_pci_resume,
-};
-
-static struct pci_driver mpt2sas_driver = {
-	.name		= MPT2SAS_DRIVER_NAME,
-	.id_table	= mpt2sas_pci_table,
-	.probe		= _mpt2sas_probe,
-	.remove		= scsih_remove,
-	.shutdown	= scsih_shutdown,
-	.err_handler	= &_mpt2sas_err_handler,
-#ifdef CONFIG_PM
-	.suspend	= scsih_suspend,
-	.resume		= scsih_resume,
-#endif
-};
-
-/**
- * _mpt2sas_init - main entry point for this driver.
- *
- * Returns 0 success, anything else error.
- */
-static int __init
-_mpt2sas_init(void)
-{
-	int error;
-
-	pr_info("%s version %s loaded\n", MPT2SAS_DRIVER_NAME,
-					MPT2SAS_DRIVER_VERSION);
-
-	mpt3sas_transport_template =
-	    sas_attach_transport(&mpt3sas_transport_functions);
-	if (!mpt3sas_transport_template)
-		return -ENODEV;
-
-	mpt3sas_raid_template = raid_class_attach(&mpt2sas_raid_functions);
-	if (!mpt3sas_raid_template) {
-		sas_release_transport(mpt3sas_transport_template);
-		return -ENODEV;
-	}
-
-	error = scsih_init();
-	if (error) {
-		scsih_exit();
-		return error;
-	}
-
-	mpt2sas_ctl_init();
-
-	error = pci_register_driver(&mpt2sas_driver);
-	if (error)
-		scsih_exit();
-
-	return error;
-}
-
-/**
- * _mpt2sas_exit - exit point for this driver (when it is a module).
- *
- */
-static void __exit
-_mpt2sas_exit(void)
-{
-	pr_info("mpt2sas version %s unloading\n",
-				MPT2SAS_DRIVER_VERSION);
-
-	pci_unregister_driver(&mpt2sas_driver);
-
-	mpt2sas_ctl_exit();
-
-	scsih_exit();
-}
-
-module_init(_mpt2sas_init);
-module_exit(_mpt2sas_exit);
diff --git a/drivers/scsi/mpt3sas/Kconfig b/drivers/scsi/mpt3sas/Kconfig
index 18b64bce10cb51808c712afacd8d2e5c08c9bf88..29061467cc174e118848dd44244ff28bb198deb3 100644
--- a/drivers/scsi/mpt3sas/Kconfig
+++ b/drivers/scsi/mpt3sas/Kconfig
@@ -41,15 +41,27 @@
 # USA.
 
 config SCSI_MPT3SAS
-	tristate "LSI MPT Fusion SAS 3.0 Device Driver"
+	tristate "LSI MPT Fusion SAS 3.0 & SAS 2.0 Device Driver"
 	depends on PCI && SCSI
 	select SCSI_SAS_ATTRS
 	select RAID_ATTRS
 	---help---
 	This driver supports PCI-Express SAS 12Gb/s Host Adapters.
 
+config SCSI_MPT2SAS_MAX_SGE
+	int "LSI MPT Fusion SAS 2.0 Max number of SG Entries (16 - 256)"
+	depends on PCI && SCSI && SCSI_MPT3SAS
+	default "128"
+	range 16 256
+	---help---
+	This option allows you to specify the maximum number of scatter-
+	gather entries per I/O. The driver default is 128, which matches
+	MAX_PHYS_SEGMENTS in most kernels.  However in SuSE kernels this
+	can be 256. However, it may decreased down to 16.  Decreasing this
+	parameter will reduce memory requirements on a per controller instance.
+
 config SCSI_MPT3SAS_MAX_SGE
-	int "LSI MPT Fusion Max number of SG Entries (16 - 256)"
+	int "LSI MPT Fusion SAS 3.0 Max number of SG Entries (16 - 256)"
 	depends on PCI && SCSI && SCSI_MPT3SAS
 	default "128"
 	range 16 256
diff --git a/drivers/scsi/mpt3sas/Makefile b/drivers/scsi/mpt3sas/Makefile
index 188057f69a9222c31975e70451adf09168d4872d..b7643f596c1e67ab67e0a954ab2250577de637d8 100644
--- a/drivers/scsi/mpt3sas/Makefile
+++ b/drivers/scsi/mpt3sas/Makefile
@@ -6,4 +6,4 @@ mpt3sas-y +=  mpt3sas_base.o     \
 		mpt3sas_transport.o     \
 		mpt3sas_ctl.o	\
 		mpt3sas_trigger_diag.o \
-		mpt3sas_module.o
+		mpt3sas_warpdrive.o
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index f5d589e839b324ebd57f6f771a6f836643994c0b..11393ebf1a68ef8f14a38d58f1321d7783a84d72 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -198,7 +198,7 @@ _base_fault_reset_work(struct work_struct *work)
 		ioc->remove_host = 1;
 		/*Remove the Dead Host */
 		p = kthread_run(mpt3sas_remove_dead_ioc_func, ioc,
-		    "mpt3sas_dead_ioc_%d", ioc->id);
+		    "%s_dead_ioc_%d", ioc->driver_name, ioc->id);
 		if (IS_ERR(p))
 			pr_err(MPT3SAS_FMT
 			"%s: Running mpt3sas_dead_ioc thread failed !!!!\n",
@@ -254,7 +254,8 @@ mpt3sas_base_start_watchdog(struct MPT3SAS_ADAPTER *ioc)
 
 	INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
 	snprintf(ioc->fault_reset_work_q_name,
-	    sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
+	    sizeof(ioc->fault_reset_work_q_name), "poll_%s%d_status",
+	    ioc->driver_name, ioc->id);
 	ioc->fault_reset_work_q =
 		create_singlethread_workqueue(ioc->fault_reset_work_q_name);
 	if (!ioc->fault_reset_work_q) {
@@ -1835,10 +1836,10 @@ _base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index, u32 vector)
 	atomic_set(&reply_q->busy, 0);
 	if (ioc->msix_enable)
 		snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d",
-		    driver_name, ioc->id, index);
+		    ioc->driver_name, ioc->id, index);
 	else
 		snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d",
-		    driver_name, ioc->id);
+		    ioc->driver_name, ioc->id);
 	r = request_irq(vector, _base_interrupt, IRQF_SHARED, reply_q->name,
 	    reply_q);
 	if (r) {
@@ -2064,7 +2065,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
 
 
 	if (pci_request_selected_regions(pdev, ioc->bars,
-	    driver_name)) {
+	    ioc->driver_name)) {
 		pr_warn(MPT3SAS_FMT "pci_request_selected_regions: failed\n",
 			ioc->name);
 		ioc->bars = 0;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 213d7f8fe3dc9a574721fecc891afe8021bef72e..25c141c9ec9d8773b2a7c3cb639f88259bf99609 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -935,6 +935,7 @@ struct MPT3SAS_ADAPTER {
 	u8		id;
 	int		cpu_count;
 	char		name[MPT_NAME_LENGTH];
+	char		driver_name[MPT_NAME_LENGTH];
 	char		tmp_string[MPT_STRING_LENGTH];
 	struct pci_dev	*pdev;
 	Mpi2SystemInterfaceRegs_t __iomem *chip;
@@ -1246,7 +1247,6 @@ int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc);
 
 
 /* scsih shared API */
-extern struct raid_template *mpt3sas_raid_template;
 u8 mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
 	u32 reply);
 void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);
@@ -1270,39 +1270,8 @@ struct _sas_device *__mpt3sas_get_sdev_by_addr(
 	 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
 
 void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
-
-void scsih_exit(void);
-int scsih_init(void);
-int scsih_probe(struct pci_dev *pdev, struct Scsi_Host *shost);
-void scsih_remove(struct pci_dev *pdev);
-void scsih_shutdown(struct pci_dev *pdev);
-pci_ers_result_t scsih_pci_error_detected(struct pci_dev *pdev,
-	pci_channel_state_t state);
-pci_ers_result_t scsih_pci_mmio_enabled(struct pci_dev *pdev);
-pci_ers_result_t scsih_pci_slot_reset(struct pci_dev *pdev);
-void scsih_pci_resume(struct pci_dev *pdev);
-int scsih_suspend(struct pci_dev *pdev, pm_message_t state);
-int scsih_resume(struct pci_dev *pdev);
-
-int scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd);
-int scsih_target_alloc(struct scsi_target *starget);
-int scsih_slave_alloc(struct scsi_device *sdev);
-int scsih_slave_configure(struct scsi_device *sdev);
-void scsih_target_destroy(struct scsi_target *starget);
-void scsih_slave_destroy(struct scsi_device *sdev);
-int scsih_scan_finished(struct Scsi_Host *shost, unsigned long time);
-void scsih_scan_start(struct Scsi_Host *shost);
-int scsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
-int scsih_abort(struct scsi_cmnd *scmd);
-int scsih_dev_reset(struct scsi_cmnd *scmd);
-int scsih_target_reset(struct scsi_cmnd *scmd);
-int scsih_host_reset(struct scsi_cmnd *scmd);
-int scsih_bios_param(struct scsi_device *sdev, struct block_device *bdev,
-	sector_t capacity, int params[]);
-
-int scsih_is_raid(struct device *dev);
-void scsih_get_resync(struct device *dev);
-void scsih_get_state(struct device *dev);
+struct _raid_device *
+mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 
 /* config shared API */
 u8 mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
@@ -1342,10 +1311,8 @@ int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
 	u16 sz);
 int mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	*mpi_reply, Mpi2IOUnitPage1_t *config_page);
-#ifdef SCSI_MPT2SAS
 int mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
 	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz);
-#endif
 int mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	*mpi_reply, Mpi2IOUnitPage1_t *config_page);
 int mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
@@ -1390,12 +1357,8 @@ int mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc,
 /* ctl shared API */
 extern struct device_attribute *mpt3sas_host_attrs[];
 extern struct device_attribute *mpt3sas_dev_attrs[];
-long ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-unsigned int ctl_poll(struct file *filep, poll_table *wait);
-int ctl_fasync(int fd, struct file *filep, int mode);
-long ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg);
-void ctl_init(void);
-void ctl_exit(void);
+void mpt3sas_ctl_init(ushort hbas_to_enumerate);
+void mpt3sas_ctl_exit(ushort hbas_to_enumerate);
 u8 mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
 	u32 reply);
 void mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);
@@ -1442,4 +1405,18 @@ void mpt3sas_trigger_scsi(struct MPT3SAS_ADAPTER *ioc, u8 sense_key,
 	u8 asc, u8 ascq);
 void mpt3sas_trigger_mpi(struct MPT3SAS_ADAPTER *ioc, u16 ioc_status,
 	u32 loginfo);
+
+/* warpdrive APIs */
+u8 mpt3sas_get_num_volumes(struct MPT3SAS_ADAPTER *ioc);
+void mpt3sas_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc,
+	struct _raid_device *raid_device);
+inline u8
+mpt3sas_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid);
+inline void
+mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io);
+void
+mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
+	struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
+	u16 smid);
+
 #endif /* MPT3SAS_BASE_H_INCLUDED */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c
index 2bbb0346b46296745b9717d195656fa8861bdd2c..a6914ec99cc047ecb492e107988a1f5bb9551c1e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -865,7 +865,6 @@ mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
 	return r;
 }
 
-#ifdef SCSI_MPT2SAS
 /**
  * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
  * @ioc: per adapter object
@@ -901,7 +900,6 @@ mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
  out:
 	return r;
 }
-#endif
 
 /**
  * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index f257c962c8993b6f98857d3ea6a4d4210a786dd3..d8366b056b70f48c046b1fcb06637f70174914ee 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -409,11 +409,14 @@ mpt3sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
  * _ctl_verify_adapter - validates ioc_number passed from application
  * @ioc: per adapter object
  * @iocpp: The ioc pointer is returned in this.
+ * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &
+ *		MPI25_VERSION for mpt3ctl ioctl device.
  *
  * Return (-1) means error, else ioc_number.
  */
 static int
-_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp)
+_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp,
+							int mpi_version)
 {
 	struct MPT3SAS_ADAPTER *ioc;
 	/* global ioc lock to protect controller on list operations */
@@ -421,6 +424,11 @@ _ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp)
 	list_for_each_entry(ioc, &mpt3sas_ioc_list, list) {
 		if (ioc->id != ioc_number)
 			continue;
+		/* Check whether this ioctl command is from right
+		 * ioctl device or not, if not continue the search.
+		 */
+		if (ioc->hba_mpi_version_belonged != mpi_version)
+			continue;
 		spin_unlock(&gioc_lock);
 		*iocpp = ioc;
 		return ioc_number;
@@ -488,7 +496,7 @@ mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
 }
 
 /**
- * ctl_fasync -
+ * _ctl_fasync -
  * @fd -
  * @filep -
  * @mode -
@@ -496,19 +504,19 @@ mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
  * Called when application request fasyn callback handler.
  */
 int
-ctl_fasync(int fd, struct file *filep, int mode)
+_ctl_fasync(int fd, struct file *filep, int mode)
 {
 	return fasync_helper(fd, filep, mode, &async_queue);
 }
 
 /**
- * ctl_poll -
+ * _ctl_poll -
  * @file -
  * @wait -
  *
  */
 unsigned int
-ctl_poll(struct file *filep, poll_table *wait)
+_ctl_poll(struct file *filep, poll_table *wait)
 {
 	struct MPT3SAS_ADAPTER *ioc;
 
@@ -1034,7 +1042,7 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
 	karg.pci_information.u.bits.function = PCI_FUNC(ioc->pdev->devfn);
 	karg.pci_information.segment_id = pci_domain_nr(ioc->pdev->bus);
 	karg.firmware_version = ioc->facts.FWVersion.Word;
-	strcpy(karg.driver_version, driver_name);
+	strcpy(karg.driver_version, ioc->driver_name);
 	strcat(karg.driver_version, "-");
 	switch  (ioc->hba_mpi_version_belonged) {
 	case MPI2_VERSION:
@@ -1049,10 +1057,6 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
 		strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
 		break;
 	}
-	if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
-		strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION);
-	else
-		strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
 	karg.bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion);
 
 	if (copy_to_user(arg, &karg, sizeof(karg))) {
@@ -2196,12 +2200,14 @@ _ctl_compat_mpt_command(struct MPT3SAS_ADAPTER *ioc, unsigned cmd,
  * _ctl_ioctl_main - main ioctl entry point
  * @file - (struct file)
  * @cmd - ioctl opcode
- * @arg -
- * compat - handles 32 bit applications in 64bit os
+ * @arg - user space data buffer
+ * @compat - handles 32 bit applications in 64bit os
+ * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &
+ *		MPI25_VERSION for mpt3ctl ioctl device.
  */
 static long
 _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
-	u8 compat)
+	u8 compat, u16 mpi_version)
 {
 	struct MPT3SAS_ADAPTER *ioc;
 	struct mpt3_ioctl_header ioctl_header;
@@ -2216,7 +2222,8 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
 		return -EFAULT;
 	}
 
-	if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc)
+	if (_ctl_verify_adapter(ioctl_header.ioc_number,
+				&ioc, mpi_version) == -1 || !ioc)
 		return -ENODEV;
 
 	/* pci_access_mutex lock acquired by ioctl path */
@@ -2324,23 +2331,43 @@ out_unlock_pciaccess:
 }
 
 /**
- * ctl_ioctl - main ioctl entry point (unlocked)
+ * _ctl_ioctl - mpt3ctl main ioctl entry point (unlocked)
  * @file - (struct file)
  * @cmd - ioctl opcode
  * @arg -
  */
 long
-ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	long ret;
 
-	ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0);
+	/* pass MPI25_VERSION value, to indicate that this ioctl cmd
+	 * came from mpt3ctl ioctl device.
+	 */
+	ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI25_VERSION);
 	return ret;
 }
 
+/**
+ * _ctl_mpt2_ioctl - mpt2ctl main ioctl entry point (unlocked)
+ * @file - (struct file)
+ * @cmd - ioctl opcode
+ * @arg -
+ */
+long
+_ctl_mpt2_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long ret;
+
+	/* pass MPI2_VERSION value, to indicate that this ioctl cmd
+	 * came from mpt2ctl ioctl device.
+	 */
+	ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI2_VERSION);
+	return ret;
+}
 #ifdef CONFIG_COMPAT
 /**
- * ctl_ioctl_compat - main ioctl entry point (compat)
+ *_ ctl_ioctl_compat - main ioctl entry point (compat)
  * @file -
  * @cmd -
  * @arg -
@@ -2348,11 +2375,28 @@ ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  * This routine handles 32 bit applications in 64bit os.
  */
 long
-ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
+_ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
 {
 	long ret;
 
-	ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1);
+	ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI25_VERSION);
+	return ret;
+}
+
+/**
+ *_ ctl_mpt2_ioctl_compat - main ioctl entry point (compat)
+ * @file -
+ * @cmd -
+ * @arg -
+ *
+ * This routine handles 32 bit applications in 64bit os.
+ */
+long
+_ctl_mpt2_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
+{
+	long ret;
+
+	ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI2_VERSION);
 	return ret;
 }
 #endif
@@ -2739,7 +2783,6 @@ _ctl_ioc_reply_queue_count_show(struct device *cdev,
 static DEVICE_ATTR(reply_queue_count, S_IRUGO, _ctl_ioc_reply_queue_count_show,
 	NULL);
 
-#ifdef SCSI_MPT2SAS
 /**
  * _ctl_BRM_status_show - Backup Rail Monitor Status
  * @cdev - pointer to embedded class device
@@ -2815,7 +2858,6 @@ _ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
 	return rc;
 }
 static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL);
-#endif
 
 struct DIAG_BUFFER_START {
 	__le32	Size;
@@ -3269,9 +3311,7 @@ struct device_attribute *mpt3sas_host_attrs[] = {
 	&dev_attr_diag_trigger_event,
 	&dev_attr_diag_trigger_scsi,
 	&dev_attr_diag_trigger_mpi,
-#ifdef SCSI_MPT2SAS
 	&dev_attr_BRM_status,
-#endif
 	NULL,
 };
 
@@ -3325,23 +3365,74 @@ struct device_attribute *mpt3sas_dev_attrs[] = {
 	NULL,
 };
 
+/* file operations table for mpt3ctl device */
+static const struct file_operations ctl_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = _ctl_ioctl,
+	.poll = _ctl_poll,
+	.fasync = _ctl_fasync,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = _ctl_ioctl_compat,
+#endif
+};
+
+/* file operations table for mpt2ctl device */
+static const struct file_operations ctl_gen2_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = _ctl_mpt2_ioctl,
+	.poll = _ctl_poll,
+	.fasync = _ctl_fasync,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = _ctl_mpt2_ioctl_compat,
+#endif
+};
+
+static struct miscdevice ctl_dev = {
+	.minor  = MPT3SAS_MINOR,
+	.name   = MPT3SAS_DEV_NAME,
+	.fops   = &ctl_fops,
+};
+
+static struct miscdevice gen2_ctl_dev = {
+	.minor  = MPT2SAS_MINOR,
+	.name   = MPT2SAS_DEV_NAME,
+	.fops   = &ctl_gen2_fops,
+};
+
 /**
- * ctl_init - main entry point for ctl.
+ * mpt3sas_ctl_init - main entry point for ctl.
  *
  */
 void
-ctl_init(void)
+mpt3sas_ctl_init(ushort hbas_to_enumerate)
 {
 	async_queue = NULL;
+
+	/* Don't register mpt3ctl ioctl device if
+	 * hbas_to_enumarate is one.
+	 */
+	if (hbas_to_enumerate != 1)
+		if (misc_register(&ctl_dev) < 0)
+			pr_err("%s can't register misc device [minor=%d]\n",
+			    MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR);
+
+	/* Don't register mpt3ctl ioctl device if
+	 * hbas_to_enumarate is two.
+	 */
+	if (hbas_to_enumerate != 2)
+		if (misc_register(&gen2_ctl_dev) < 0)
+			pr_err("%s can't register misc device [minor=%d]\n",
+			    MPT2SAS_DRIVER_NAME, MPT2SAS_MINOR);
+
 	init_waitqueue_head(&ctl_poll_wait);
 }
 
 /**
- * ctl_exit - exit point for ctl
+ * mpt3sas_ctl_exit - exit point for ctl
  *
  */
 void
-ctl_exit(void)
+mpt3sas_ctl_exit(ushort hbas_to_enumerate)
 {
 	struct MPT3SAS_ADAPTER *ioc;
 	int i;
@@ -3366,4 +3457,8 @@ ctl_exit(void)
 
 		kfree(ioc->event_log);
 	}
+	if (hbas_to_enumerate != 1)
+		misc_deregister(&ctl_dev);
+	if (hbas_to_enumerate != 2)
+		misc_deregister(&gen2_ctl_dev);
 }
diff --git a/drivers/scsi/mpt3sas/mpt3sas_module.c b/drivers/scsi/mpt3sas/mpt3sas_module.c
deleted file mode 100644
index 322dc8da3d7d274264e80654ff3178d5c644e242..0000000000000000000000000000000000000000
--- a/drivers/scsi/mpt3sas/mpt3sas_module.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Scsi Host Layer for MPT (Message Passing Technology) based controllers
- *
- * Copyright (C) 2012-2014  LSI Corporation
- * Copyright (C) 2013-2015 Avago Technologies
- *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
-
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- * You should have received a copy of the GNU General Public License
- * along with this program.
- */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/raid_class.h>
-
-#include "mpt3sas_base.h"
-#include "mpt3sas_ctl.h"
-
-MODULE_AUTHOR(MPT3SAS_AUTHOR);
-MODULE_DESCRIPTION(MPT3SAS_DESCRIPTION);
-MODULE_LICENSE("GPL");
-MODULE_VERSION(MPT3SAS_DRIVER_VERSION);
-
-/* shost template */
-static struct scsi_host_template mpt3sas_driver_template = {
-	.module				= THIS_MODULE,
-	.name				= "Fusion MPT SAS Host",
-	.proc_name			= MPT3SAS_DRIVER_NAME,
-	.queuecommand			= scsih_qcmd,
-	.target_alloc			= scsih_target_alloc,
-	.slave_alloc			= scsih_slave_alloc,
-	.slave_configure		= scsih_slave_configure,
-	.target_destroy			= scsih_target_destroy,
-	.slave_destroy			= scsih_slave_destroy,
-	.scan_finished			= scsih_scan_finished,
-	.scan_start			= scsih_scan_start,
-	.change_queue_depth		= scsih_change_queue_depth,
-	.eh_abort_handler		= scsih_abort,
-	.eh_device_reset_handler	= scsih_dev_reset,
-	.eh_target_reset_handler	= scsih_target_reset,
-	.eh_host_reset_handler		= scsih_host_reset,
-	.bios_param			= scsih_bios_param,
-	.can_queue			= 1,
-	.this_id			= -1,
-	.sg_tablesize			= MPT3SAS_SG_DEPTH,
-	.max_sectors			= 32767,
-	.cmd_per_lun			= 7,
-	.use_clustering			= ENABLE_CLUSTERING,
-	.shost_attrs			= mpt3sas_host_attrs,
-	.sdev_attrs			= mpt3sas_dev_attrs,
-	.track_queue_depth		= 1,
-};
-
-/* raid transport support */
-static struct raid_function_template mpt3sas_raid_functions = {
-	.cookie		= &mpt3sas_driver_template,
-	.is_raid	= scsih_is_raid,
-	.get_resync	= scsih_get_resync,
-	.get_state	= scsih_get_state,
-};
-
-/*
- * The pci device ids are defined in mpi/mpi2_cnfg.h.
- */
-static const struct pci_device_id mpt3sas_pci_table[] = {
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008,
-		PCI_ANY_ID, PCI_ANY_ID },
-	/* Invader ~ 3108 */
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{0}     /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, mpt3sas_pci_table);
-
-static const struct file_operations mpt3sas_ctl_fops = {
-	.owner = THIS_MODULE,
-	.unlocked_ioctl = ctl_ioctl,
-	.poll = ctl_poll,
-	.fasync = ctl_fasync,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl = ctl_ioctl_compat,
-#endif
-};
-
-static struct miscdevice mpt3sas_ctl_dev = {
-	.minor  = MPT3SAS_MINOR,
-	.name   = MPT3SAS_DEV_NAME,
-	.fops   = &mpt3sas_ctl_fops,
-};
-
-/**
- * mpt3sas_ctl_init - main entry point for ctl.
- *
- */
-void
-mpt3sas_ctl_init(void)
-{
-	ctl_init();
-	if (misc_register(&mpt3sas_ctl_dev) < 0)
-		pr_err("%s can't register misc device [minor=%d]\n",
-		    MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR);
-}
-
-/**
- * mpt3sas_ctl_exit - exit point for ctl
- *
- */
-void
-mpt3sas_ctl_exit(void)
-{
-	ctl_exit();
-	misc_deregister(&mpt3sas_ctl_dev);
-}
-
-/**
- * _mpt3sas_probe - attach and add scsi host
- * @pdev: PCI device struct
- * @id: pci device id
- *
- * Returns 0 success, anything else error.
- */
-static int
-_mpt3sas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-	struct Scsi_Host *shost;
-	int rv;
-
-	shost = scsi_host_alloc(&mpt3sas_driver_template,
-				sizeof(struct MPT3SAS_ADAPTER));
-	if (!shost)
-		return -ENODEV;
-
-	sprintf(driver_name, "%s", MPT3SAS_DRIVER_NAME);
-	rv = scsih_probe(pdev, shost);
-	return rv;
-}
-
-static struct pci_error_handlers _mpt3sas_err_handler = {
-	.error_detected	= scsih_pci_error_detected,
-	.mmio_enabled	= scsih_pci_mmio_enabled,
-	.slot_reset	= scsih_pci_slot_reset,
-	.resume		= scsih_pci_resume,
-};
-
-static struct pci_driver mpt3sas_driver = {
-	.name		= MPT3SAS_DRIVER_NAME,
-	.id_table	= mpt3sas_pci_table,
-	.probe		= _mpt3sas_probe,
-	.remove		= scsih_remove,
-	.shutdown	= scsih_shutdown,
-	.err_handler	= &_mpt3sas_err_handler,
-#ifdef CONFIG_PM
-	.suspend	= scsih_suspend,
-	.resume		= scsih_resume,
-#endif
-};
-
-/**
- * _mpt3sas_init - main entry point for this driver.
- *
- * Returns 0 success, anything else error.
- */
-static int __init
-_mpt3sas_init(void)
-{
-	int error;
-
-	pr_info("%s version %s loaded\n", MPT3SAS_DRIVER_NAME,
-					MPT3SAS_DRIVER_VERSION);
-
-	mpt3sas_transport_template =
-	    sas_attach_transport(&mpt3sas_transport_functions);
-	if (!mpt3sas_transport_template)
-		return -ENODEV;
-
-	mpt3sas_raid_template = raid_class_attach(&mpt3sas_raid_functions);
-	if (!mpt3sas_raid_template) {
-		sas_release_transport(mpt3sas_transport_template);
-		return -ENODEV;
-	}
-
-	error = scsih_init();
-	if (error) {
-		scsih_exit();
-		return error;
-	}
-
-	mpt3sas_ctl_init();
-
-	error = pci_register_driver(&mpt3sas_driver);
-	if (error)
-		scsih_exit();
-
-	return error;
-}
-
-/**
- * _mpt3sas_exit - exit point for this driver (when it is a module).
- *
- */
-static void __exit
-_mpt3sas_exit(void)
-{
-	pr_info("mpt3sas version %s unloading\n",
-				MPT3SAS_DRIVER_VERSION);
-
-	pci_unregister_driver(&mpt3sas_driver);
-
-	mpt3sas_ctl_exit();
-
-	scsih_exit();
-}
-
-module_init(_mpt3sas_init);
-module_exit(_mpt3sas_exit);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index d0ab0028c2eb2a4947a52f59c43d238650931e46..d95206b7e1167861531d2cd29c9ef27e7da82c25 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -71,28 +71,17 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
-#ifdef SCSI_MPT2SAS
-static void _scsih_disable_ddio(struct MPT3SAS_ADAPTER *ioc);
-static u8 _scsih_get_num_volumes(struct MPT3SAS_ADAPTER *ioc);
-static void
-_scsih_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc,
-	struct _raid_device *raid_device);
-static inline u8
-_scsih_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid);
-static inline void
-_scsih_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io);
-static void
-_scsih_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
-	struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
-	u16 smid);
-#endif
-
 /* global parameters */
 LIST_HEAD(mpt3sas_ioc_list);
-char    driver_name[MPT_NAME_LENGTH];
 /* global ioc lock for list operations */
 DEFINE_SPINLOCK(gioc_lock);
 
+MODULE_AUTHOR(MPT3SAS_AUTHOR);
+MODULE_DESCRIPTION(MPT3SAS_DESCRIPTION);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(MPT3SAS_DRIVER_VERSION);
+MODULE_ALIAS("mpt2sas");
+
 /* local parameters */
 static u8 scsi_io_cb_idx = -1;
 static u8 tm_cb_idx = -1;
@@ -102,7 +91,8 @@ static u8 port_enable_cb_idx = -1;
 static u8 transport_cb_idx = -1;
 static u8 scsih_cb_idx = -1;
 static u8 config_cb_idx = -1;
-static int mpt_ids;
+static int mpt2_ids;
+static int mpt3_ids;
 
 static u8 tm_tr_cb_idx = -1 ;
 static u8 tm_tr_volume_cb_idx = -1 ;
@@ -129,8 +119,12 @@ static u64 max_lun = MPT3SAS_MAX_LUN;
 module_param(max_lun, ullong, 0);
 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
 
-
-
+static ushort hbas_to_enumerate;
+module_param(hbas_to_enumerate, ushort, 0);
+MODULE_PARM_DESC(hbas_to_enumerate,
+		" 0 - enumerates both SAS 2.0 & SAS 3.0 generation HBAs\n \
+		  1 - enumerates only SAS 2.0 generation HBAs\n \
+		  2 - enumerates only SAS 3.0 generation HBAs (default=0)");
 
 /* diag_buffer_enable is bitwise
  * bit 0 set = TRACE
@@ -156,6 +150,7 @@ MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=7 ");
 
 /* raid transport support */
 struct raid_template *mpt3sas_raid_template;
+struct raid_template *mpt2sas_raid_template;
 
 
 /**
@@ -879,7 +874,7 @@ _scsih_raid_device_find_by_id(struct MPT3SAS_ADAPTER *ioc, int id, int channel)
 }
 
 /**
- * _scsih_raid_device_find_by_handle - raid device search
+ * mpt3sas_raid_device_find_by_handle - raid device search
  * @ioc: per adapter object
  * @handle: sas device handle (assigned by firmware)
  * Context: Calling function should acquire ioc->raid_device_lock
@@ -887,8 +882,8 @@ _scsih_raid_device_find_by_id(struct MPT3SAS_ADAPTER *ioc, int id, int channel)
  * This searches for raid_device based on handle, then return raid_device
  * object.
  */
-static struct _raid_device *
-_scsih_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+struct _raid_device *
+mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 {
 	struct _raid_device *raid_device, *r;
 
@@ -1304,10 +1299,8 @@ scsih_target_alloc(struct scsi_target *starget)
 		if (test_bit(sas_device->handle, ioc->pd_handles))
 			sas_target_priv_data->flags |=
 			    MPT_TARGET_FLAGS_RAID_COMPONENT;
-#ifndef SCSI_MPT2SAS
 		if (sas_device->fast_path)
 			sas_target_priv_data->flags |= MPT_TARGET_FASTPATH_IO;
-#endif
 	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
@@ -1596,7 +1589,10 @@ scsih_get_resync(struct device *dev)
 		percent_complete = 0;
 
  out:
-	raid_set_resync(mpt3sas_raid_template, dev, percent_complete);
+	if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+		raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
+	if (ioc->hba_mpi_version_belonged == MPI25_VERSION)
+		raid_set_resync(mpt3sas_raid_template, dev, percent_complete);
 }
 
 /**
@@ -1654,7 +1650,10 @@ scsih_get_state(struct device *dev)
 		break;
 	}
  out:
-	raid_set_state(mpt3sas_raid_template, dev, state);
+	if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+		raid_set_state(mpt2sas_raid_template, dev, state);
+	if (ioc->hba_mpi_version_belonged == MPI25_VERSION)
+		raid_set_state(mpt3sas_raid_template, dev, state);
 }
 
 /**
@@ -1663,7 +1662,8 @@ scsih_get_state(struct device *dev)
  * @volume_type: volume type
  */
 static void
-_scsih_set_level(struct scsi_device *sdev, u8 volume_type)
+_scsih_set_level(struct MPT3SAS_ADAPTER *ioc,
+	struct scsi_device *sdev, u8 volume_type)
 {
 	enum raid_level level = RAID_LEVEL_UNKNOWN;
 
@@ -1682,7 +1682,12 @@ _scsih_set_level(struct scsi_device *sdev, u8 volume_type)
 		break;
 	}
 
-	raid_set_level(mpt3sas_raid_template, &sdev->sdev_gendev, level);
+	if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+		raid_set_level(mpt2sas_raid_template,
+			       &sdev->sdev_gendev, level);
+	if (ioc->hba_mpi_version_belonged == MPI25_VERSION)
+		raid_set_level(mpt3sas_raid_template,
+			       &sdev->sdev_gendev, level);
 }
 
 
@@ -1814,7 +1819,7 @@ scsih_slave_configure(struct scsi_device *sdev)
 	if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) {
 
 		spin_lock_irqsave(&ioc->raid_device_lock, flags);
-		raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+		raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
 		spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
 		if (!raid_device) {
 			dfailprintk(ioc, pr_warn(MPT3SAS_FMT
@@ -1830,12 +1835,10 @@ scsih_slave_configure(struct scsi_device *sdev)
 			return 1;
 		}
 
-#ifdef SCSI_MPT2SAS
 		/*
 		 * WARPDRIVE: Initialize the required data for Direct IO
 		 */
-		_scsih_init_warpdrive_properties(ioc, raid_device);
-#endif
+		mpt3sas_init_warpdrive_properties(ioc, raid_device);
 
 		/* RAID Queue Depth Support
 		 * IS volume = underlying qdepth of drive type, either
@@ -1896,7 +1899,7 @@ scsih_slave_configure(struct scsi_device *sdev)
 
 		/* raid transport support */
 		if (!ioc->is_warpdrive)
-			_scsih_set_level(sdev, raid_device->volume_type);
+			_scsih_set_level(ioc, sdev, raid_device->volume_type);
 		return 0;
 	}
 
@@ -3523,7 +3526,7 @@ _scsih_set_volume_delete_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	unsigned long flags;
 
 	spin_lock_irqsave(&ioc->raid_device_lock, flags);
-	raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+	raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
 	if (raid_device && raid_device->starget &&
 	    raid_device->starget->hostdata) {
 		sas_target_priv_data =
@@ -3841,9 +3844,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 	struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
 	struct MPT3SAS_DEVICE *sas_device_priv_data;
 	struct MPT3SAS_TARGET *sas_target_priv_data;
-#ifdef SCSI_MPT2SAS
 	struct _raid_device *raid_device;
-#endif
 	Mpi2SCSIIORequest_t *mpi_request;
 	u32 mpi_control;
 	u16 smid;
@@ -3947,21 +3948,17 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 	} else
 		ioc->build_zero_len_sge(ioc, &mpi_request->SGL);
 
-#ifdef SCSI_MPT2SAS
 	raid_device = sas_target_priv_data->raid_device;
 	if (raid_device && raid_device->direct_io_enabled)
-		_scsih_setup_direct_io(ioc, scmd, raid_device, mpi_request,
+		mpt3sas_setup_direct_io(ioc, scmd, raid_device, mpi_request,
 		    smid);
-#endif
 
 	if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) {
-#ifndef SCSI_MPT2SAS
 		if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) {
 			mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len |
 			    MPI25_SCSIIO_IOFLAGS_FAST_PATH);
 			mpt3sas_base_put_smid_fast_path(ioc, smid, handle);
 		} else
-#endif
 			mpt3sas_base_put_smid_scsi_io(ioc, smid,
 			    le16_to_cpu(mpi_request->DevHandle));
 	} else
@@ -4422,9 +4419,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
 	u32 log_info;
 	struct MPT3SAS_DEVICE *sas_device_priv_data;
 	u32 response_code = 0;
-#ifdef SCSI_MPT2SAS
 	unsigned long flags;
-#endif
 
 	mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
 	scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
@@ -4446,18 +4441,17 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
 	}
 	ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
 
-#ifdef SCSI_MPT2SAS
 	/*
 	 * WARPDRIVE: If direct_io is set then it is directIO,
 	 * the failed direct I/O should be redirected to volume
 	 */
-	if (_scsih_scsi_direct_io_get(ioc, smid) &&
+	if (mpt3sas_scsi_direct_io_get(ioc, smid) &&
 	     ((ioc_status & MPI2_IOCSTATUS_MASK)
 	      != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) {
 		spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
 		ioc->scsi_lookup[smid - 1].scmd = scmd;
 		spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-		_scsih_scsi_direct_io_set(ioc, smid, 0);
+		mpt3sas_scsi_direct_io_set(ioc, smid, 0);
 		memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
 		mpi_request->DevHandle =
 		    cpu_to_le16(sas_device_priv_data->sas_target->handle);
@@ -4465,7 +4459,6 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
 		    sas_device_priv_data->sas_target->handle);
 		return 0;
 	}
-#endif
 	/* turning off TLR */
 	scsi_state = mpi_reply->SCSIState;
 	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
@@ -4475,10 +4468,11 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
 		sas_device_priv_data->tlr_snoop_check++;
 		if (!ioc->is_warpdrive &&
 		    !scsih_is_raid(&scmd->device->sdev_gendev) &&
-		    (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) &&
-		    response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
-			sas_device_priv_data->flags &=
-			    ~MPT_DEVICE_TLR_ON;
+		    sas_is_tlr_enabled(scmd->device) &&
+		    response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
+			sas_disable_tlr(scmd->device);
+			sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
+		}
 	}
 
 	xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
@@ -5309,10 +5303,8 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
 	sas_device->device_info = device_info;
 	sas_device->sas_address = sas_address;
 	sas_device->phy = sas_device_pg0.PhyNum;
-#ifndef SCSI_MPT2SAS
 	sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) &
 	    MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0;
-#endif
 
 	if (sas_device_pg0.Flags & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
 		sas_device->enclosure_level =
@@ -6014,7 +6006,6 @@ _scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc,
 	}
 }
 
-#ifndef SCSI_MPT2SAS
 /**
  * _scsih_ir_fastpath - turn on fastpath for IR physdisk
  * @ioc: per adapter object
@@ -6034,6 +6025,9 @@ _scsih_ir_fastpath(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phys_disk_num)
 	u16 ioc_status;
 	u32 log_info;
 
+	if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+		return rc;
+
 	mutex_lock(&ioc->scsih_cmds.mutex);
 
 	if (ioc->scsih_cmds.status != MPT3_CMD_NOT_USED) {
@@ -6108,8 +6102,6 @@ _scsih_ir_fastpath(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phys_disk_num)
 		    FORCE_BIG_HAMMER);
 	return rc;
 }
-/* End of not defined SCSI_MPT2SAS */
-#endif
 
 /**
  * _scsih_reprobe_lun - reprobing lun
@@ -6202,7 +6194,7 @@ _scsih_sas_volume_delete(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	struct scsi_target *starget = NULL;
 
 	spin_lock_irqsave(&ioc->raid_device_lock, flags);
-	raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+	raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
 	if (raid_device) {
 		if (raid_device->starget) {
 			starget = raid_device->starget;
@@ -6304,10 +6296,9 @@ _scsih_sas_pd_hide(struct MPT3SAS_ADAPTER *ioc,
 	if (!sas_device)
 		return;
 
-#ifndef SCSI_MPT2SAS
 	/* hiding raid component */
 	_scsih_ir_fastpath(ioc, handle, element->PhysDiskNum);
-#endif
+
 	if (starget)
 		starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun);
 
@@ -6355,9 +6346,7 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc,
 
 	sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
 	if (sas_device) {
-#ifndef SCSI_MPT2SAS
 		_scsih_ir_fastpath(ioc, handle, element->PhysDiskNum);
-#endif
 		sas_device_put(sas_device);
 		return;
 	}
@@ -6382,9 +6371,7 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc,
 		mpt3sas_transport_update_links(ioc, sas_address, handle,
 		    sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
 
-#ifndef SCSI_MPT2SAS
 	_scsih_ir_fastpath(ioc, handle, element->PhysDiskNum);
-#endif
 	_scsih_add_device(ioc, handle, 0, 1);
 }
 
@@ -6495,15 +6482,14 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc,
 	    MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
 
 	element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
-	if (ioc->shost_recovery) {
-#ifndef SCSI_MPT2SAS
+	if (ioc->shost_recovery &&
+	    ioc->hba_mpi_version_belonged != MPI2_VERSION) {
 		for (i = 0; i < event_data->NumElements; i++, element++) {
 			if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_HIDE)
 				_scsih_ir_fastpath(ioc,
 					le16_to_cpu(element->PhysDiskDevHandle),
 					element->PhysDiskNum);
 		}
-#endif
 		return;
 	}
 
@@ -6586,7 +6572,7 @@ _scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc,
 	case MPI2_RAID_VOL_STATE_OPTIMAL:
 
 		spin_lock_irqsave(&ioc->raid_device_lock, flags);
-		raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+		raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
 		spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
 
 		if (raid_device)
@@ -6782,7 +6768,7 @@ _scsih_sas_ir_operation_status_event(struct MPT3SAS_ADAPTER *ioc,
 
 		spin_lock_irqsave(&ioc->raid_device_lock, flags);
 		handle = le16_to_cpu(event_data->VolDevHandle);
-		raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+		raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
 		if (raid_device)
 			raid_device->percent_complete =
 			    event_data->PercentComplete;
@@ -6964,14 +6950,12 @@ _scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid,
 			    "handle(0x%04x), wwid(0x%016llx)\n", handle,
 			    (unsigned long long)raid_device->wwid);
 
-#ifdef SCSI_MPT2SAS
 			/*
 			 * WARPDRIVE: The handles of the PDs might have changed
 			 * across the host reset so re-initialize the
 			 * required data for Direct IO
 			 */
-			_scsih_init_warpdrive_properties(ioc, raid_device);
-#endif
+			mpt3sas_init_warpdrive_properties(ioc, raid_device);
 			spin_lock_irqsave(&ioc->raid_device_lock, flags);
 			if (raid_device->handle == handle) {
 				spin_unlock_irqrestore(&ioc->raid_device_lock,
@@ -8326,13 +8310,96 @@ scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
 	return 1;
 }
 
-void
-_scsih_determine_hba_mpi_version(struct MPT3SAS_ADAPTER *ioc) {
+/* shost template for SAS 2.0 HBA devices */
+static struct scsi_host_template mpt2sas_driver_template = {
+	.module				= THIS_MODULE,
+	.name				= "Fusion MPT SAS Host",
+	.proc_name			= MPT2SAS_DRIVER_NAME,
+	.queuecommand			= scsih_qcmd,
+	.target_alloc			= scsih_target_alloc,
+	.slave_alloc			= scsih_slave_alloc,
+	.slave_configure		= scsih_slave_configure,
+	.target_destroy			= scsih_target_destroy,
+	.slave_destroy			= scsih_slave_destroy,
+	.scan_finished			= scsih_scan_finished,
+	.scan_start			= scsih_scan_start,
+	.change_queue_depth		= scsih_change_queue_depth,
+	.eh_abort_handler		= scsih_abort,
+	.eh_device_reset_handler	= scsih_dev_reset,
+	.eh_target_reset_handler	= scsih_target_reset,
+	.eh_host_reset_handler		= scsih_host_reset,
+	.bios_param			= scsih_bios_param,
+	.can_queue			= 1,
+	.this_id			= -1,
+	.sg_tablesize			= MPT2SAS_SG_DEPTH,
+	.max_sectors			= 32767,
+	.cmd_per_lun			= 7,
+	.use_clustering			= ENABLE_CLUSTERING,
+	.shost_attrs			= mpt3sas_host_attrs,
+	.sdev_attrs			= mpt3sas_dev_attrs,
+	.track_queue_depth		= 1,
+};
+
+/* raid transport support for SAS 2.0 HBA devices */
+static struct raid_function_template mpt2sas_raid_functions = {
+	.cookie		= &mpt2sas_driver_template,
+	.is_raid	= scsih_is_raid,
+	.get_resync	= scsih_get_resync,
+	.get_state	= scsih_get_state,
+};
 
-	switch (ioc->pdev->device) {
+/* shost template for SAS 3.0 HBA devices */
+static struct scsi_host_template mpt3sas_driver_template = {
+	.module				= THIS_MODULE,
+	.name				= "Fusion MPT SAS Host",
+	.proc_name			= MPT3SAS_DRIVER_NAME,
+	.queuecommand			= scsih_qcmd,
+	.target_alloc			= scsih_target_alloc,
+	.slave_alloc			= scsih_slave_alloc,
+	.slave_configure		= scsih_slave_configure,
+	.target_destroy			= scsih_target_destroy,
+	.slave_destroy			= scsih_slave_destroy,
+	.scan_finished			= scsih_scan_finished,
+	.scan_start			= scsih_scan_start,
+	.change_queue_depth		= scsih_change_queue_depth,
+	.eh_abort_handler		= scsih_abort,
+	.eh_device_reset_handler	= scsih_dev_reset,
+	.eh_target_reset_handler	= scsih_target_reset,
+	.eh_host_reset_handler		= scsih_host_reset,
+	.bios_param			= scsih_bios_param,
+	.can_queue			= 1,
+	.this_id			= -1,
+	.sg_tablesize			= MPT3SAS_SG_DEPTH,
+	.max_sectors			= 32767,
+	.cmd_per_lun			= 7,
+	.use_clustering			= ENABLE_CLUSTERING,
+	.shost_attrs			= mpt3sas_host_attrs,
+	.sdev_attrs			= mpt3sas_dev_attrs,
+	.track_queue_depth		= 1,
+};
+
+/* raid transport support for SAS 3.0 HBA devices */
+static struct raid_function_template mpt3sas_raid_functions = {
+	.cookie		= &mpt3sas_driver_template,
+	.is_raid	= scsih_is_raid,
+	.get_resync	= scsih_get_resync,
+	.get_state	= scsih_get_state,
+};
+
+/**
+ * _scsih_determine_hba_mpi_version - determine in which MPI version class
+ *					this device belongs to.
+ * @pdev: PCI device struct
+ *
+ * return MPI2_VERSION for SAS 2.0 HBA devices,
+ *	MPI25_VERSION for SAS 3.0 HBA devices.
+ */
+u16
+_scsih_determine_hba_mpi_version(struct pci_dev *pdev)
+{
+
+	switch (pdev->device) {
 	case MPI2_MFGPAGE_DEVID_SSS6200:
-		ioc->is_warpdrive = 1;
-		ioc->hide_ir_msg = 1;
 	case MPI2_MFGPAGE_DEVID_SAS2004:
 	case MPI2_MFGPAGE_DEVID_SAS2008:
 	case MPI2_MFGPAGE_DEVID_SAS2108_1:
@@ -8349,52 +8416,91 @@ _scsih_determine_hba_mpi_version(struct MPT3SAS_ADAPTER *ioc) {
 	case MPI2_MFGPAGE_DEVID_SAS2308_1:
 	case MPI2_MFGPAGE_DEVID_SAS2308_2:
 	case MPI2_MFGPAGE_DEVID_SAS2308_3:
-		ioc->hba_mpi_version_belonged = MPI2_VERSION;
-		break;
+		return MPI2_VERSION;
 	case MPI25_MFGPAGE_DEVID_SAS3004:
 	case MPI25_MFGPAGE_DEVID_SAS3008:
 	case MPI25_MFGPAGE_DEVID_SAS3108_1:
 	case MPI25_MFGPAGE_DEVID_SAS3108_2:
 	case MPI25_MFGPAGE_DEVID_SAS3108_5:
 	case MPI25_MFGPAGE_DEVID_SAS3108_6:
-		ioc->hba_mpi_version_belonged = MPI25_VERSION;
-
-		/* Check whether the controller revision is C0 or above.
-		 * only C0 and above revision controllers support 96 MSI-X
-		 * vectors.
-		 */
-		if (ioc->pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION)
-			ioc->msix96_vector = 1;
-		break;
+		return MPI25_VERSION;
 	}
-
-	if ((ioc->pdev->device != MPI2_MFGPAGE_DEVID_SSS6200) &&
-	    (ioc->hba_mpi_version_belonged == MPI2_VERSION))
-		ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
+	return 0;
 }
 
 /**
- * scsih_probe - attach and add scsi host
+ * _scsih_probe - attach and add scsi host
  * @pdev: PCI device struct
  * @id: pci device id
  *
  * Returns 0 success, anything else error.
  */
 int
-scsih_probe(struct pci_dev *pdev, struct Scsi_Host *shost)
+_scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct MPT3SAS_ADAPTER *ioc;
+	struct Scsi_Host *shost = NULL;
 	int rv;
+	u16 hba_mpi_version;
+
+	/* Determine in which MPI version class this pci device belongs */
+	hba_mpi_version = _scsih_determine_hba_mpi_version(pdev);
+	if (hba_mpi_version == 0)
+		return -ENODEV;
+
+	/* Enumerate only SAS 2.0 HBA's if hbas_to_enumerate is one,
+	 * for other generation HBA's return with -ENODEV
+	 */
+	if ((hbas_to_enumerate == 1) && (hba_mpi_version !=  MPI2_VERSION))
+		return -ENODEV;
+
+	/* Enumerate only SAS 3.0 HBA's if hbas_to_enumerate is two,
+	 * for other generation HBA's return with -ENODEV
+	 */
+	if ((hbas_to_enumerate == 2) && (hba_mpi_version !=  MPI25_VERSION))
+		return -ENODEV;
+
+	switch (hba_mpi_version) {
+	case MPI2_VERSION:
+		/* Use mpt2sas driver host template for SAS 2.0 HBA's */
+		shost = scsi_host_alloc(&mpt2sas_driver_template,
+		  sizeof(struct MPT3SAS_ADAPTER));
+		if (!shost)
+			return -ENODEV;
+		ioc = shost_priv(shost);
+		memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER));
+		ioc->hba_mpi_version_belonged = hba_mpi_version;
+		ioc->id = mpt2_ids++;
+		sprintf(ioc->driver_name, "%s", MPT2SAS_DRIVER_NAME);
+		if (pdev->device == MPI2_MFGPAGE_DEVID_SSS6200) {
+			ioc->is_warpdrive = 1;
+			ioc->hide_ir_msg = 1;
+		} else
+			ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
+		break;
+	case MPI25_VERSION:
+		/* Use mpt3sas driver host template for SAS 3.0 HBA's */
+		shost = scsi_host_alloc(&mpt3sas_driver_template,
+		  sizeof(struct MPT3SAS_ADAPTER));
+		if (!shost)
+			return -ENODEV;
+		ioc = shost_priv(shost);
+		memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER));
+		ioc->hba_mpi_version_belonged = hba_mpi_version;
+		ioc->id = mpt3_ids++;
+		sprintf(ioc->driver_name, "%s", MPT3SAS_DRIVER_NAME);
+		if (pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION)
+			ioc->msix96_vector = 1;
+		break;
+	default:
+		return -ENODEV;
+	}
 
-	/* init local params */
-	ioc = shost_priv(shost);
-	memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER));
 	INIT_LIST_HEAD(&ioc->list);
 	spin_lock(&gioc_lock);
 	list_add_tail(&ioc->list, &mpt3sas_ioc_list);
 	spin_unlock(&gioc_lock);
 	ioc->shost = shost;
-	ioc->id = mpt_ids++;
 	ioc->pdev = pdev;
 	ioc->scsi_io_cb_idx = scsi_io_cb_idx;
 	ioc->tm_cb_idx = tm_cb_idx;
@@ -8431,8 +8537,7 @@ scsih_probe(struct pci_dev *pdev, struct Scsi_Host *shost)
 	INIT_LIST_HEAD(&ioc->delayed_tr_volume_list);
 	INIT_LIST_HEAD(&ioc->reply_queue_list);
 
-	_scsih_determine_hba_mpi_version(ioc);
-	sprintf(ioc->name, "%s_cm%d", driver_name, ioc->id);
+	sprintf(ioc->name, "%s_cm%d", ioc->driver_name, ioc->id);
 
 	/* init shost parameters */
 	shost->max_cmd_len = 32;
@@ -8472,7 +8577,7 @@ scsih_probe(struct pci_dev *pdev, struct Scsi_Host *shost)
 
 	/* event thread */
 	snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
-	    "fw_event%d", ioc->id);
+	    "fw_event_%s%d", ioc->driver_name, ioc->id);
 	ioc->firmware_event_thread = alloc_ordered_workqueue(
 	    ioc->firmware_event_name, WQ_MEM_RECLAIM);
 	if (!ioc->firmware_event_thread) {
@@ -8490,21 +8595,19 @@ scsih_probe(struct pci_dev *pdev, struct Scsi_Host *shost)
 		goto out_attach_fail;
 	}
 
-#ifdef SCSI_MPT2SAS
 	if (ioc->is_warpdrive) {
 		if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_EXPOSE_ALL_DISKS)
 			ioc->hide_drives = 0;
 		else if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_HIDE_ALL_DISKS)
 			ioc->hide_drives = 1;
 		else {
-			if (_scsih_get_num_volumes(ioc))
+			if (mpt3sas_get_num_volumes(ioc))
 				ioc->hide_drives = 1;
 			else
 				ioc->hide_drives = 0;
 		}
 	} else
 		ioc->hide_drives = 0;
-#endif
 
 	rv = scsi_add_host(shost, &pdev->dev);
 	if (rv) {
@@ -8705,6 +8808,89 @@ scsih_pci_mmio_enabled(struct pci_dev *pdev)
 	return PCI_ERS_RESULT_NEED_RESET;
 }
 
+/*
+ * The pci device ids are defined in mpi/mpi2_cnfg.h.
+ */
+static const struct pci_device_id mpt3sas_pci_table[] = {
+	/* Spitfire ~ 2004 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004,
+		PCI_ANY_ID, PCI_ANY_ID },
+	/* Falcon ~ 2008 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008,
+		PCI_ANY_ID, PCI_ANY_ID },
+	/* Liberator ~ 2108 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
+		PCI_ANY_ID, PCI_ANY_ID },
+	/* Meteor ~ 2116 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
+		PCI_ANY_ID, PCI_ANY_ID },
+	/* Thunderbolt ~ 2208 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
+		PCI_ANY_ID, PCI_ANY_ID },
+	/* Mustang ~ 2308 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_1,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
+		PCI_ANY_ID, PCI_ANY_ID },
+	/* SSS6200 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
+		PCI_ANY_ID, PCI_ANY_ID },
+	/* Fury ~ 3004 and 3008 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008,
+		PCI_ANY_ID, PCI_ANY_ID },
+	/* Invader ~ 3108 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{0}     /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(pci, mpt3sas_pci_table);
+
+static struct pci_error_handlers _mpt3sas_err_handler = {
+	.error_detected	= scsih_pci_error_detected,
+	.mmio_enabled	= scsih_pci_mmio_enabled,
+	.slot_reset	= scsih_pci_slot_reset,
+	.resume		= scsih_pci_resume,
+};
+
+static struct pci_driver mpt3sas_driver = {
+	.name		= MPT3SAS_DRIVER_NAME,
+	.id_table	= mpt3sas_pci_table,
+	.probe		= _scsih_probe,
+	.remove		= scsih_remove,
+	.shutdown	= scsih_shutdown,
+	.err_handler	= &_mpt3sas_err_handler,
+#ifdef CONFIG_PM
+	.suspend	= scsih_suspend,
+	.resume		= scsih_resume,
+#endif
+};
+
 /**
  * scsih_init - main entry point for this driver.
  *
@@ -8713,7 +8899,8 @@ scsih_pci_mmio_enabled(struct pci_dev *pdev)
 int
 scsih_init(void)
 {
-	mpt_ids = 0;
+	mpt2_ids = 0;
+	mpt3_ids = 0;
 
 	mpt3sas_base_initialize_callback_handler();
 
@@ -8777,10 +8964,86 @@ scsih_exit(void)
 	mpt3sas_base_release_callback_handler(tm_sas_control_cb_idx);
 
 /* raid transport support */
-	raid_class_release(mpt3sas_raid_template);
+	if (hbas_to_enumerate != 1)
+		raid_class_release(mpt3sas_raid_template);
+	if (hbas_to_enumerate != 2)
+		raid_class_release(mpt2sas_raid_template);
 	sas_release_transport(mpt3sas_transport_template);
 }
 
-#ifdef SCSI_MPT2SAS
-#include "../mpt2sas/mpt2sas_warpdrive.c"
-#endif
+/**
+ * _mpt3sas_init - main entry point for this driver.
+ *
+ * Returns 0 success, anything else error.
+ */
+static int __init
+_mpt3sas_init(void)
+{
+	int error;
+
+	pr_info("%s version %s loaded\n", MPT3SAS_DRIVER_NAME,
+					MPT3SAS_DRIVER_VERSION);
+
+	mpt3sas_transport_template =
+	    sas_attach_transport(&mpt3sas_transport_functions);
+	if (!mpt3sas_transport_template)
+		return -ENODEV;
+
+	/* No need attach mpt3sas raid functions template
+	 * if hbas_to_enumarate value is one.
+	 */
+	if (hbas_to_enumerate != 1) {
+		mpt3sas_raid_template =
+				raid_class_attach(&mpt3sas_raid_functions);
+		if (!mpt3sas_raid_template) {
+			sas_release_transport(mpt3sas_transport_template);
+			return -ENODEV;
+		}
+	}
+
+	/* No need to attach mpt2sas raid functions template
+	 * if hbas_to_enumarate value is two
+	 */
+	if (hbas_to_enumerate != 2) {
+		mpt2sas_raid_template =
+				raid_class_attach(&mpt2sas_raid_functions);
+		if (!mpt2sas_raid_template) {
+			sas_release_transport(mpt3sas_transport_template);
+			return -ENODEV;
+		}
+	}
+
+	error = scsih_init();
+	if (error) {
+		scsih_exit();
+		return error;
+	}
+
+	mpt3sas_ctl_init(hbas_to_enumerate);
+
+	error = pci_register_driver(&mpt3sas_driver);
+	if (error)
+		scsih_exit();
+
+	return error;
+}
+
+/**
+ * _mpt3sas_exit - exit point for this driver (when it is a module).
+ *
+ */
+static void __exit
+_mpt3sas_exit(void)
+{
+	pr_info("mpt3sas version %s unloading\n",
+				MPT3SAS_DRIVER_VERSION);
+
+	pci_unregister_driver(&mpt3sas_driver);
+
+	mpt3sas_ctl_exit(hbas_to_enumerate);
+
+	scsih_exit();
+}
+
+module_init(_mpt3sas_init);
+module_exit(_mpt3sas_exit);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_warpdrive.c b/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c
similarity index 88%
rename from drivers/scsi/mpt2sas/mpt2sas_warpdrive.c
rename to drivers/scsi/mpt3sas/mpt3sas_warpdrive.c
index c4fcbc2273469e83797938834f201fef705893d6..540bd5005149b769b5045e9256ed8f3a22a2b562 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_warpdrive.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c
@@ -38,13 +38,20 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.
  */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <asm/unaligned.h>
+
+#include "mpt3sas_base.h"
 
 /**
- * _scsih_disable_ddio - Disable direct I/O for all the volumes
+ * _warpdrive_disable_ddio - Disable direct I/O for all the volumes
  * @ioc: per adapter object
  */
 static void
-_scsih_disable_ddio(struct MPT3SAS_ADAPTER *ioc)
+_warpdrive_disable_ddio(struct MPT3SAS_ADAPTER *ioc)
 {
 	Mpi2RaidVolPage1_t vol_pg1;
 	Mpi2ConfigReply_t mpi_reply;
@@ -62,7 +69,7 @@ _scsih_disable_ddio(struct MPT3SAS_ADAPTER *ioc)
 			break;
 		handle = le16_to_cpu(vol_pg1.DevHandle);
 		spin_lock_irqsave(&ioc->raid_device_lock, flags);
-		raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+		raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
 		if (raid_device)
 			raid_device->direct_io_enabled = 0;
 		spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
@@ -72,11 +79,11 @@ _scsih_disable_ddio(struct MPT3SAS_ADAPTER *ioc)
 
 
 /**
- * _scsih_get_num_volumes - Get number of volumes in the ioc
+ * mpt3sas_get_num_volumes - Get number of volumes in the ioc
  * @ioc: per adapter object
  */
-static u8
-_scsih_get_num_volumes(struct MPT3SAS_ADAPTER *ioc)
+u8
+mpt3sas_get_num_volumes(struct MPT3SAS_ADAPTER *ioc)
 {
 	Mpi2RaidVolPage1_t vol_pg1;
 	Mpi2ConfigReply_t mpi_reply;
@@ -99,12 +106,12 @@ _scsih_get_num_volumes(struct MPT3SAS_ADAPTER *ioc)
 
 
 /**
- * _scsih_init_warpdrive_properties - Set properties for warpdrive direct I/O.
+ * mpt3sas_init_warpdrive_properties - Set properties for warpdrive direct I/O.
  * @ioc: per adapter object
  * @raid_device: the raid_device object
  */
-static void
-_scsih_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc,
+void
+mpt3sas_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc,
 	struct _raid_device *raid_device)
 {
 	Mpi2RaidVolPage0_t *vol_pg0;
@@ -124,8 +131,8 @@ _scsih_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc,
 		    "globally as drives are exposed\n", ioc->name);
 		return;
 	}
-	if (_scsih_get_num_volumes(ioc) > 1) {
-		_scsih_disable_ddio(ioc);
+	if (mpt3sas_get_num_volumes(ioc) > 1) {
+		_warpdrive_disable_ddio(ioc);
 		pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
 		    "globally as number of drives > 1\n", ioc->name);
 		return;
@@ -254,34 +261,34 @@ out_error:
 }
 
 /**
- * _scsih_scsi_direct_io_get - returns direct io flag
+ * mpt3sas_scsi_direct_io_get - returns direct io flag
  * @ioc: per adapter object
  * @smid: system request message index
  *
  * Returns the smid stored scmd pointer.
  */
-static inline u8
-_scsih_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+inline u8
+mpt3sas_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 {
 	return ioc->scsi_lookup[smid - 1].direct_io;
 }
 
 /**
- * _scsih_scsi_direct_io_set - sets direct io flag
+ * mpt3sas_scsi_direct_io_set - sets direct io flag
  * @ioc: per adapter object
  * @smid: system request message index
  * @direct_io: Zero or non-zero value to set in the direct_io flag
  *
  * Returns Nothing.
  */
-static inline void
-_scsih_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
+inline void
+mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
 {
 	ioc->scsi_lookup[smid - 1].direct_io = direct_io;
 }
 
 /**
- * _scsih_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O
+ * mpt3sas_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O
  * @ioc: per adapter object
  * @scmd: pointer to scsi command object
  * @raid_device: pointer to raid device data structure
@@ -290,12 +297,12 @@ _scsih_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
  *
  * Returns nothing
  */
-static void
-_scsih_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
+void
+mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 	struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
 	u16 smid)
 {
-	sector_t v_lba, p_lba, stripe_off, stripe_unit, column, io_size;
+	sector_t v_lba, p_lba, stripe_off, column, io_size;
 	u32 stripe_sz, stripe_exp;
 	u8 num_pds, cmd = scmd->cmnd[0];
 
@@ -323,9 +330,8 @@ _scsih_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 
 	num_pds = raid_device->num_pds;
 	p_lba = v_lba >> stripe_exp;
-	stripe_unit = p_lba / num_pds;
-	column = p_lba % num_pds;
-	p_lba = (stripe_unit << stripe_exp) + stripe_off;
+	column = sector_div(p_lba, num_pds);
+	p_lba = (p_lba << stripe_exp) + stripe_off;
 	mpi_request->DevHandle = cpu_to_le16(raid_device->pd_handle[column]);
 
 	if (cmd == READ_10 || cmd == WRITE_10)
@@ -334,5 +340,5 @@ _scsih_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 	else
 		put_unaligned_be64(p_lba, &mpi_request->CDB.CDB32[2]);
 
-	_scsih_scsi_direct_io_set(ioc, smid, 1);
+	mpt3sas_scsi_direct_io_set(ioc, smid, 1);
 }