diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_module.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_module.c | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_module.c b/drivers/scsi/mpt2sas/mpt2sas_module.c new file mode 100644 index 000000000000..2b7069329612 --- /dev/null +++ b/drivers/scsi/mpt2sas/mpt2sas_module.c @@ -0,0 +1,280 @@ +/* + * 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); |