--- /dev/null
+/*
+ * 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;
+
+       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);