linux/drivers/scsi/mpt2sas/mpt2sas_module.c
Sreekanth Reddy d357e84d65 mpt3sas: Define 'hba_mpi_version_belonged' IOC variable
1. Use 'hba_mpi_version_belonged' IOC varable to uniquely identify each
individual generation driver functionality at runtime.

2. Declare global variable 'driver_name' and use this variable while
reserving PCI regions and while allocating the IRQs.

Signed-off-by: Sreekanth Reddy <Sreekanth.Reddy@avagotech.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2015-11-11 18:29:34 -05:00

282 lines
8.0 KiB
C

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