diff options
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_sas_base.c')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_base.c | 164 |
1 files changed, 98 insertions, 66 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5640ad1c8214..f05580e693d0 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Linux MegaRAID driver for SAS based RAID controllers | 2 | * Linux MegaRAID driver for SAS based RAID controllers |
3 | * | 3 | * |
4 | * Copyright (c) 2003-2012 LSI Corporation. | 4 | * Copyright (c) 2003-2013 LSI Corporation |
5 | * Copyright (c) 2013-2014 Avago Technologies | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
@@ -14,22 +15,20 @@ | |||
14 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
15 | * | 16 | * |
16 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | 19 | * |
20 | * FILE: megaraid_sas_base.c | 20 | * Authors: Avago Technologies |
21 | * Version : 06.805.06.00-rc1 | ||
22 | * | ||
23 | * Authors: LSI Corporation | ||
24 | * Sreenivas Bagalkote | 21 | * Sreenivas Bagalkote |
25 | * Sumant Patro | 22 | * Sumant Patro |
26 | * Bo Yang | 23 | * Bo Yang |
27 | * Adam Radford <linuxraid@lsi.com> | 24 | * Adam Radford |
25 | * Kashyap Desai <kashyap.desai@avagotech.com> | ||
26 | * Sumit Saxena <sumit.saxena@avagotech.com> | ||
28 | * | 27 | * |
29 | * Send feedback to: <megaraidlinux@lsi.com> | 28 | * Send feedback to: megaraidlinux.pdl@avagotech.com |
30 | * | 29 | * |
31 | * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035 | 30 | * Mail to: Avago Technologies, 350 West Trimble Road, Building 90, |
32 | * ATTN: Linuxraid | 31 | * San Jose, California 95131 |
33 | */ | 32 | */ |
34 | 33 | ||
35 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
@@ -1008,7 +1007,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance, | |||
1008 | cpu_to_le32(upper_32_bits(cmd_to_abort->frame_phys_addr)); | 1007 | cpu_to_le32(upper_32_bits(cmd_to_abort->frame_phys_addr)); |
1009 | 1008 | ||
1010 | cmd->sync_cmd = 1; | 1009 | cmd->sync_cmd = 1; |
1011 | cmd->cmd_status = 0xFF; | 1010 | cmd->cmd_status = ENODATA; |
1012 | 1011 | ||
1013 | instance->instancet->issue_dcmd(instance, cmd); | 1012 | instance->instancet->issue_dcmd(instance, cmd); |
1014 | 1013 | ||
@@ -1572,6 +1571,12 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | |||
1572 | instance = (struct megasas_instance *) | 1571 | instance = (struct megasas_instance *) |
1573 | scmd->device->host->hostdata; | 1572 | scmd->device->host->hostdata; |
1574 | 1573 | ||
1574 | if (instance->unload == 1) { | ||
1575 | scmd->result = DID_NO_CONNECT << 16; | ||
1576 | scmd->scsi_done(scmd); | ||
1577 | return 0; | ||
1578 | } | ||
1579 | |||
1575 | if (instance->issuepend_done == 0) | 1580 | if (instance->issuepend_done == 0) |
1576 | return SCSI_MLQUEUE_HOST_BUSY; | 1581 | return SCSI_MLQUEUE_HOST_BUSY; |
1577 | 1582 | ||
@@ -2586,20 +2591,6 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) | |||
2586 | } | 2591 | } |
2587 | } | 2592 | } |
2588 | 2593 | ||
2589 | static int megasas_change_queue_depth(struct scsi_device *sdev, | ||
2590 | int queue_depth, int reason) | ||
2591 | { | ||
2592 | if (reason != SCSI_QDEPTH_DEFAULT) | ||
2593 | return -EOPNOTSUPP; | ||
2594 | |||
2595 | if (queue_depth > sdev->host->can_queue) | ||
2596 | queue_depth = sdev->host->can_queue; | ||
2597 | scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), | ||
2598 | queue_depth); | ||
2599 | |||
2600 | return queue_depth; | ||
2601 | } | ||
2602 | |||
2603 | static ssize_t | 2594 | static ssize_t |
2604 | megasas_fw_crash_buffer_store(struct device *cdev, | 2595 | megasas_fw_crash_buffer_store(struct device *cdev, |
2605 | struct device_attribute *attr, const char *buf, size_t count) | 2596 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -2764,7 +2755,7 @@ static struct scsi_host_template megasas_template = { | |||
2764 | .shost_attrs = megaraid_host_attrs, | 2755 | .shost_attrs = megaraid_host_attrs, |
2765 | .bios_param = megasas_bios_param, | 2756 | .bios_param = megasas_bios_param, |
2766 | .use_clustering = ENABLE_CLUSTERING, | 2757 | .use_clustering = ENABLE_CLUSTERING, |
2767 | .change_queue_depth = megasas_change_queue_depth, | 2758 | .change_queue_depth = scsi_change_queue_depth, |
2768 | .no_write_same = 1, | 2759 | .no_write_same = 1, |
2769 | }; | 2760 | }; |
2770 | 2761 | ||
@@ -4028,25 +4019,83 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) | |||
4028 | return ret; | 4019 | return ret; |
4029 | } | 4020 | } |
4030 | 4021 | ||
4022 | /* | ||
4023 | * megasas_update_ext_vd_details : Update details w.r.t Extended VD | ||
4024 | * instance : Controller's instance | ||
4025 | */ | ||
4026 | static void megasas_update_ext_vd_details(struct megasas_instance *instance) | ||
4027 | { | ||
4028 | struct fusion_context *fusion; | ||
4029 | u32 old_map_sz; | ||
4030 | u32 new_map_sz; | ||
4031 | |||
4032 | fusion = instance->ctrl_context; | ||
4033 | /* For MFI based controllers return dummy success */ | ||
4034 | if (!fusion) | ||
4035 | return; | ||
4036 | |||
4037 | instance->supportmax256vd = | ||
4038 | instance->ctrl_info->adapterOperations3.supportMaxExtLDs; | ||
4039 | /* Below is additional check to address future FW enhancement */ | ||
4040 | if (instance->ctrl_info->max_lds > 64) | ||
4041 | instance->supportmax256vd = 1; | ||
4042 | |||
4043 | instance->drv_supported_vd_count = MEGASAS_MAX_LD_CHANNELS | ||
4044 | * MEGASAS_MAX_DEV_PER_CHANNEL; | ||
4045 | instance->drv_supported_pd_count = MEGASAS_MAX_PD_CHANNELS | ||
4046 | * MEGASAS_MAX_DEV_PER_CHANNEL; | ||
4047 | if (instance->supportmax256vd) { | ||
4048 | instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT; | ||
4049 | instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES; | ||
4050 | } else { | ||
4051 | instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES; | ||
4052 | instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES; | ||
4053 | } | ||
4054 | dev_info(&instance->pdev->dev, "Firmware supports %d VD %d PD\n", | ||
4055 | instance->fw_supported_vd_count, | ||
4056 | instance->fw_supported_pd_count); | ||
4057 | dev_info(&instance->pdev->dev, "Driver supports %d VD %d PD\n", | ||
4058 | instance->drv_supported_vd_count, | ||
4059 | instance->drv_supported_pd_count); | ||
4060 | |||
4061 | old_map_sz = sizeof(struct MR_FW_RAID_MAP) + | ||
4062 | (sizeof(struct MR_LD_SPAN_MAP) * | ||
4063 | (instance->fw_supported_vd_count - 1)); | ||
4064 | new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT); | ||
4065 | fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP) + | ||
4066 | (sizeof(struct MR_LD_SPAN_MAP) * | ||
4067 | (instance->drv_supported_vd_count - 1)); | ||
4068 | |||
4069 | fusion->max_map_sz = max(old_map_sz, new_map_sz); | ||
4070 | |||
4071 | |||
4072 | if (instance->supportmax256vd) | ||
4073 | fusion->current_map_sz = new_map_sz; | ||
4074 | else | ||
4075 | fusion->current_map_sz = old_map_sz; | ||
4076 | |||
4077 | } | ||
4078 | |||
4031 | /** | 4079 | /** |
4032 | * megasas_get_controller_info - Returns FW's controller structure | 4080 | * megasas_get_controller_info - Returns FW's controller structure |
4033 | * @instance: Adapter soft state | 4081 | * @instance: Adapter soft state |
4034 | * @ctrl_info: Controller information structure | ||
4035 | * | 4082 | * |
4036 | * Issues an internal command (DCMD) to get the FW's controller structure. | 4083 | * Issues an internal command (DCMD) to get the FW's controller structure. |
4037 | * This information is mainly used to find out the maximum IO transfer per | 4084 | * This information is mainly used to find out the maximum IO transfer per |
4038 | * command supported by the FW. | 4085 | * command supported by the FW. |
4039 | */ | 4086 | */ |
4040 | int | 4087 | int |
4041 | megasas_get_ctrl_info(struct megasas_instance *instance, | 4088 | megasas_get_ctrl_info(struct megasas_instance *instance) |
4042 | struct megasas_ctrl_info *ctrl_info) | ||
4043 | { | 4089 | { |
4044 | int ret = 0; | 4090 | int ret = 0; |
4045 | struct megasas_cmd *cmd; | 4091 | struct megasas_cmd *cmd; |
4046 | struct megasas_dcmd_frame *dcmd; | 4092 | struct megasas_dcmd_frame *dcmd; |
4047 | struct megasas_ctrl_info *ci; | 4093 | struct megasas_ctrl_info *ci; |
4094 | struct megasas_ctrl_info *ctrl_info; | ||
4048 | dma_addr_t ci_h = 0; | 4095 | dma_addr_t ci_h = 0; |
4049 | 4096 | ||
4097 | ctrl_info = instance->ctrl_info; | ||
4098 | |||
4050 | cmd = megasas_get_cmd(instance); | 4099 | cmd = megasas_get_cmd(instance); |
4051 | 4100 | ||
4052 | if (!cmd) { | 4101 | if (!cmd) { |
@@ -4086,8 +4135,13 @@ megasas_get_ctrl_info(struct megasas_instance *instance, | |||
4086 | else | 4135 | else |
4087 | ret = megasas_issue_polled(instance, cmd); | 4136 | ret = megasas_issue_polled(instance, cmd); |
4088 | 4137 | ||
4089 | if (!ret) | 4138 | if (!ret) { |
4090 | memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info)); | 4139 | memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info)); |
4140 | le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties); | ||
4141 | le32_to_cpus((u32 *)&ctrl_info->adapterOperations2); | ||
4142 | le32_to_cpus((u32 *)&ctrl_info->adapterOperations3); | ||
4143 | megasas_update_ext_vd_details(instance); | ||
4144 | } | ||
4091 | 4145 | ||
4092 | pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info), | 4146 | pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info), |
4093 | ci, ci_h); | 4147 | ci, ci_h); |
@@ -4289,7 +4343,7 @@ megasas_init_adapter_mfi(struct megasas_instance *instance) | |||
4289 | if (megasas_issue_init_mfi(instance)) | 4343 | if (megasas_issue_init_mfi(instance)) |
4290 | goto fail_fw_init; | 4344 | goto fail_fw_init; |
4291 | 4345 | ||
4292 | if (megasas_get_ctrl_info(instance, instance->ctrl_info)) { | 4346 | if (megasas_get_ctrl_info(instance)) { |
4293 | dev_err(&instance->pdev->dev, "(%d): Could get controller info " | 4347 | dev_err(&instance->pdev->dev, "(%d): Could get controller info " |
4294 | "Fail from %s %d\n", instance->unique_id, | 4348 | "Fail from %s %d\n", instance->unique_id, |
4295 | __func__, __LINE__); | 4349 | __func__, __LINE__); |
@@ -4527,12 +4581,8 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
4527 | dev_info(&instance->pdev->dev, | 4581 | dev_info(&instance->pdev->dev, |
4528 | "Controller type: iMR\n"); | 4582 | "Controller type: iMR\n"); |
4529 | } | 4583 | } |
4530 | /* OnOffProperties are converted into CPU arch*/ | ||
4531 | le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties); | ||
4532 | instance->disableOnlineCtrlReset = | 4584 | instance->disableOnlineCtrlReset = |
4533 | ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; | 4585 | ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; |
4534 | /* adapterOperations2 are converted into CPU arch*/ | ||
4535 | le32_to_cpus((u32 *)&ctrl_info->adapterOperations2); | ||
4536 | instance->mpio = ctrl_info->adapterOperations2.mpio; | 4586 | instance->mpio = ctrl_info->adapterOperations2.mpio; |
4537 | instance->UnevenSpanSupport = | 4587 | instance->UnevenSpanSupport = |
4538 | ctrl_info->adapterOperations2.supportUnevenSpans; | 4588 | ctrl_info->adapterOperations2.supportUnevenSpans; |
@@ -4562,7 +4612,6 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
4562 | "requestorId %d\n", instance->requestorId); | 4612 | "requestorId %d\n", instance->requestorId); |
4563 | } | 4613 | } |
4564 | 4614 | ||
4565 | le32_to_cpus((u32 *)&ctrl_info->adapterOperations3); | ||
4566 | instance->crash_dump_fw_support = | 4615 | instance->crash_dump_fw_support = |
4567 | ctrl_info->adapterOperations3.supportCrashDump; | 4616 | ctrl_info->adapterOperations3.supportCrashDump; |
4568 | instance->crash_dump_drv_support = | 4617 | instance->crash_dump_drv_support = |
@@ -4587,8 +4636,6 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
4587 | if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors)) | 4636 | if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors)) |
4588 | instance->max_sectors_per_req = tmp_sectors; | 4637 | instance->max_sectors_per_req = tmp_sectors; |
4589 | 4638 | ||
4590 | kfree(ctrl_info); | ||
4591 | |||
4592 | /* Check for valid throttlequeuedepth module parameter */ | 4639 | /* Check for valid throttlequeuedepth module parameter */ |
4593 | if (instance->is_imr) { | 4640 | if (instance->is_imr) { |
4594 | if (throttlequeuedepth > (instance->max_fw_cmds - | 4641 | if (throttlequeuedepth > (instance->max_fw_cmds - |
@@ -4957,10 +5004,6 @@ static int megasas_io_attach(struct megasas_instance *instance) | |||
4957 | return -ENODEV; | 5004 | return -ENODEV; |
4958 | } | 5005 | } |
4959 | 5006 | ||
4960 | /* | ||
4961 | * Trigger SCSI to scan our drives | ||
4962 | */ | ||
4963 | scsi_scan_host(host); | ||
4964 | return 0; | 5007 | return 0; |
4965 | } | 5008 | } |
4966 | 5009 | ||
@@ -5083,6 +5126,8 @@ static int megasas_probe_one(struct pci_dev *pdev, | |||
5083 | goto fail_alloc_dma_buf; | 5126 | goto fail_alloc_dma_buf; |
5084 | } | 5127 | } |
5085 | fusion = instance->ctrl_context; | 5128 | fusion = instance->ctrl_context; |
5129 | memset(fusion, 0, | ||
5130 | ((1 << PAGE_SHIFT) << instance->ctrl_context_pages)); | ||
5086 | INIT_LIST_HEAD(&fusion->cmd_pool); | 5131 | INIT_LIST_HEAD(&fusion->cmd_pool); |
5087 | spin_lock_init(&fusion->mpt_pool_lock); | 5132 | spin_lock_init(&fusion->mpt_pool_lock); |
5088 | memset(fusion->load_balance_info, 0, | 5133 | memset(fusion->load_balance_info, 0, |
@@ -5288,6 +5333,10 @@ retry_irq_register: | |||
5288 | goto fail_io_attach; | 5333 | goto fail_io_attach; |
5289 | 5334 | ||
5290 | instance->unload = 0; | 5335 | instance->unload = 0; |
5336 | /* | ||
5337 | * Trigger SCSI to scan our drives | ||
5338 | */ | ||
5339 | scsi_scan_host(host); | ||
5291 | 5340 | ||
5292 | /* | 5341 | /* |
5293 | * Initiate AEN (Asynchronous Event Notification) | 5342 | * Initiate AEN (Asynchronous Event Notification) |
@@ -6051,6 +6100,11 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, | |||
6051 | megasas_issue_blocked_cmd(instance, cmd, 0); | 6100 | megasas_issue_blocked_cmd(instance, cmd, 0); |
6052 | cmd->sync_cmd = 0; | 6101 | cmd->sync_cmd = 0; |
6053 | 6102 | ||
6103 | if (instance->unload == 1) { | ||
6104 | dev_info(&instance->pdev->dev, "Driver unload is in progress " | ||
6105 | "don't submit data to application\n"); | ||
6106 | goto out; | ||
6107 | } | ||
6054 | /* | 6108 | /* |
6055 | * copy out the kernel buffers to user buffers | 6109 | * copy out the kernel buffers to user buffers |
6056 | */ | 6110 | */ |
@@ -6400,16 +6454,6 @@ static ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf) | |||
6400 | static DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL); | 6454 | static DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL); |
6401 | 6455 | ||
6402 | static ssize_t | 6456 | static ssize_t |
6403 | megasas_sysfs_show_release_date(struct device_driver *dd, char *buf) | ||
6404 | { | ||
6405 | return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n", | ||
6406 | MEGASAS_RELDATE); | ||
6407 | } | ||
6408 | |||
6409 | static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date, | ||
6410 | NULL); | ||
6411 | |||
6412 | static ssize_t | ||
6413 | megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf) | 6457 | megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf) |
6414 | { | 6458 | { |
6415 | return sprintf(buf, "%u\n", support_poll_for_event); | 6459 | return sprintf(buf, "%u\n", support_poll_for_event); |
@@ -6712,8 +6756,7 @@ static int __init megasas_init(void) | |||
6712 | /* | 6756 | /* |
6713 | * Announce driver version and other information | 6757 | * Announce driver version and other information |
6714 | */ | 6758 | */ |
6715 | printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, | 6759 | pr_info("megasas: %s\n", MEGASAS_VERSION); |
6716 | MEGASAS_EXT_VERSION); | ||
6717 | 6760 | ||
6718 | spin_lock_init(&poll_aen_lock); | 6761 | spin_lock_init(&poll_aen_lock); |
6719 | 6762 | ||
@@ -6748,10 +6791,6 @@ static int __init megasas_init(void) | |||
6748 | &driver_attr_version); | 6791 | &driver_attr_version); |
6749 | if (rval) | 6792 | if (rval) |
6750 | goto err_dcf_attr_ver; | 6793 | goto err_dcf_attr_ver; |
6751 | rval = driver_create_file(&megasas_pci_driver.driver, | ||
6752 | &driver_attr_release_date); | ||
6753 | if (rval) | ||
6754 | goto err_dcf_rel_date; | ||
6755 | 6794 | ||
6756 | rval = driver_create_file(&megasas_pci_driver.driver, | 6795 | rval = driver_create_file(&megasas_pci_driver.driver, |
6757 | &driver_attr_support_poll_for_event); | 6796 | &driver_attr_support_poll_for_event); |
@@ -6775,12 +6814,7 @@ err_dcf_support_device_change: | |||
6775 | err_dcf_dbg_lvl: | 6814 | err_dcf_dbg_lvl: |
6776 | driver_remove_file(&megasas_pci_driver.driver, | 6815 | driver_remove_file(&megasas_pci_driver.driver, |
6777 | &driver_attr_support_poll_for_event); | 6816 | &driver_attr_support_poll_for_event); |
6778 | |||
6779 | err_dcf_support_poll_for_event: | 6817 | err_dcf_support_poll_for_event: |
6780 | driver_remove_file(&megasas_pci_driver.driver, | ||
6781 | &driver_attr_release_date); | ||
6782 | |||
6783 | err_dcf_rel_date: | ||
6784 | driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); | 6818 | driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); |
6785 | err_dcf_attr_ver: | 6819 | err_dcf_attr_ver: |
6786 | pci_unregister_driver(&megasas_pci_driver); | 6820 | pci_unregister_driver(&megasas_pci_driver); |
@@ -6800,8 +6834,6 @@ static void __exit megasas_exit(void) | |||
6800 | &driver_attr_support_poll_for_event); | 6834 | &driver_attr_support_poll_for_event); |
6801 | driver_remove_file(&megasas_pci_driver.driver, | 6835 | driver_remove_file(&megasas_pci_driver.driver, |
6802 | &driver_attr_support_device_change); | 6836 | &driver_attr_support_device_change); |
6803 | driver_remove_file(&megasas_pci_driver.driver, | ||
6804 | &driver_attr_release_date); | ||
6805 | driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); | 6837 | driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); |
6806 | 6838 | ||
6807 | pci_unregister_driver(&megasas_pci_driver); | 6839 | pci_unregister_driver(&megasas_pci_driver); |