| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Linux MegaRAID driver for SAS based RAID controllers |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2003-2013 LSI Corporation |
|---|
| 5 | | - * Copyright (c) 2013-2014 Avago Technologies |
|---|
| 6 | + * Copyright (c) 2013-2016 Avago Technologies |
|---|
| 7 | + * Copyright (c) 2016-2018 Broadcom Inc. |
|---|
| 6 | 8 | * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or |
|---|
| 8 | | - * modify it under the terms of the GNU General Public License |
|---|
| 9 | | - * as published by the Free Software Foundation; either version 2 |
|---|
| 10 | | - * of the License, or (at your option) any later version. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | | - * GNU General Public License for more details. |
|---|
| 16 | | - * |
|---|
| 17 | | - * You should have received a copy of the GNU General Public License |
|---|
| 18 | | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 19 | | - * |
|---|
| 20 | | - * Authors: Avago Technologies |
|---|
| 9 | + * Authors: Broadcom Inc. |
|---|
| 21 | 10 | * Sreenivas Bagalkote |
|---|
| 22 | 11 | * Sumant Patro |
|---|
| 23 | 12 | * Bo Yang |
|---|
| 24 | 13 | * Adam Radford |
|---|
| 25 | | - * Kashyap Desai <kashyap.desai@avagotech.com> |
|---|
| 26 | | - * Sumit Saxena <sumit.saxena@avagotech.com> |
|---|
| 14 | + * Kashyap Desai <kashyap.desai@broadcom.com> |
|---|
| 15 | + * Sumit Saxena <sumit.saxena@broadcom.com> |
|---|
| 27 | 16 | * |
|---|
| 28 | | - * Send feedback to: megaraidlinux.pdl@avagotech.com |
|---|
| 29 | | - * |
|---|
| 30 | | - * Mail to: Avago Technologies, 350 West Trimble Road, Building 90, |
|---|
| 31 | | - * San Jose, California 95131 |
|---|
| 17 | + * Send feedback to: megaraidlinux.pdl@broadcom.com |
|---|
| 32 | 18 | */ |
|---|
| 33 | 19 | |
|---|
| 34 | 20 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 50 | 36 | #include <linux/mutex.h> |
|---|
| 51 | 37 | #include <linux/poll.h> |
|---|
| 52 | 38 | #include <linux/vmalloc.h> |
|---|
| 39 | +#include <linux/irq_poll.h> |
|---|
| 53 | 40 | |
|---|
| 54 | 41 | #include <scsi/scsi.h> |
|---|
| 55 | 42 | #include <scsi/scsi_cmnd.h> |
|---|
| 56 | 43 | #include <scsi/scsi_device.h> |
|---|
| 57 | 44 | #include <scsi/scsi_host.h> |
|---|
| 58 | 45 | #include <scsi/scsi_tcq.h> |
|---|
| 46 | +#include <scsi/scsi_dbg.h> |
|---|
| 59 | 47 | #include "megaraid_sas_fusion.h" |
|---|
| 60 | 48 | #include "megaraid_sas.h" |
|---|
| 61 | 49 | |
|---|
| .. | .. |
|---|
| 64 | 52 | * Will be set in megasas_init_mfi if user does not provide |
|---|
| 65 | 53 | */ |
|---|
| 66 | 54 | static unsigned int max_sectors; |
|---|
| 67 | | -module_param_named(max_sectors, max_sectors, int, 0); |
|---|
| 55 | +module_param_named(max_sectors, max_sectors, int, 0444); |
|---|
| 68 | 56 | MODULE_PARM_DESC(max_sectors, |
|---|
| 69 | 57 | "Maximum number of sectors per IO command"); |
|---|
| 70 | 58 | |
|---|
| 71 | 59 | static int msix_disable; |
|---|
| 72 | | -module_param(msix_disable, int, S_IRUGO); |
|---|
| 60 | +module_param(msix_disable, int, 0444); |
|---|
| 73 | 61 | MODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0"); |
|---|
| 74 | 62 | |
|---|
| 75 | 63 | static unsigned int msix_vectors; |
|---|
| 76 | | -module_param(msix_vectors, int, S_IRUGO); |
|---|
| 64 | +module_param(msix_vectors, int, 0444); |
|---|
| 77 | 65 | MODULE_PARM_DESC(msix_vectors, "MSI-X max vector count. Default: Set by FW"); |
|---|
| 78 | 66 | |
|---|
| 79 | 67 | static int allow_vf_ioctls; |
|---|
| 80 | | -module_param(allow_vf_ioctls, int, S_IRUGO); |
|---|
| 68 | +module_param(allow_vf_ioctls, int, 0444); |
|---|
| 81 | 69 | MODULE_PARM_DESC(allow_vf_ioctls, "Allow ioctls in SR-IOV VF mode. Default: 0"); |
|---|
| 82 | 70 | |
|---|
| 83 | 71 | static unsigned int throttlequeuedepth = MEGASAS_THROTTLE_QUEUE_DEPTH; |
|---|
| 84 | | -module_param(throttlequeuedepth, int, S_IRUGO); |
|---|
| 72 | +module_param(throttlequeuedepth, int, 0444); |
|---|
| 85 | 73 | MODULE_PARM_DESC(throttlequeuedepth, |
|---|
| 86 | 74 | "Adapter queue depth when throttled due to I/O timeout. Default: 16"); |
|---|
| 87 | 75 | |
|---|
| 88 | 76 | unsigned int resetwaittime = MEGASAS_RESET_WAIT_TIME; |
|---|
| 89 | | -module_param(resetwaittime, int, S_IRUGO); |
|---|
| 90 | | -MODULE_PARM_DESC(resetwaittime, "Wait time in seconds after I/O timeout " |
|---|
| 91 | | - "before resetting adapter. Default: 180"); |
|---|
| 77 | +module_param(resetwaittime, int, 0444); |
|---|
| 78 | +MODULE_PARM_DESC(resetwaittime, "Wait time in (1-180s) after I/O timeout before resetting adapter. Default: 180s"); |
|---|
| 92 | 79 | |
|---|
| 93 | | -int smp_affinity_enable = 1; |
|---|
| 94 | | -module_param(smp_affinity_enable, int, S_IRUGO); |
|---|
| 80 | +static int smp_affinity_enable = 1; |
|---|
| 81 | +module_param(smp_affinity_enable, int, 0444); |
|---|
| 95 | 82 | MODULE_PARM_DESC(smp_affinity_enable, "SMP affinity feature enable/disable Default: enable(1)"); |
|---|
| 96 | 83 | |
|---|
| 97 | | -int rdpq_enable = 1; |
|---|
| 98 | | -module_param(rdpq_enable, int, S_IRUGO); |
|---|
| 99 | | -MODULE_PARM_DESC(rdpq_enable, " Allocate reply queue in chunks for large queue depth enable/disable Default: disable(0)"); |
|---|
| 84 | +static int rdpq_enable = 1; |
|---|
| 85 | +module_param(rdpq_enable, int, 0444); |
|---|
| 86 | +MODULE_PARM_DESC(rdpq_enable, "Allocate reply queue in chunks for large queue depth enable/disable Default: enable(1)"); |
|---|
| 100 | 87 | |
|---|
| 101 | 88 | unsigned int dual_qdepth_disable; |
|---|
| 102 | | -module_param(dual_qdepth_disable, int, S_IRUGO); |
|---|
| 89 | +module_param(dual_qdepth_disable, int, 0444); |
|---|
| 103 | 90 | MODULE_PARM_DESC(dual_qdepth_disable, "Disable dual queue depth feature. Default: 0"); |
|---|
| 104 | 91 | |
|---|
| 105 | | -unsigned int scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT; |
|---|
| 106 | | -module_param(scmd_timeout, int, S_IRUGO); |
|---|
| 92 | +static unsigned int scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT; |
|---|
| 93 | +module_param(scmd_timeout, int, 0444); |
|---|
| 107 | 94 | MODULE_PARM_DESC(scmd_timeout, "scsi command timeout (10-90s), default 90s. See megasas_reset_timer."); |
|---|
| 95 | + |
|---|
| 96 | +int perf_mode = -1; |
|---|
| 97 | +module_param(perf_mode, int, 0444); |
|---|
| 98 | +MODULE_PARM_DESC(perf_mode, "Performance mode (only for Aero adapters), options:\n\t\t" |
|---|
| 99 | + "0 - balanced: High iops and low latency queues are allocated &\n\t\t" |
|---|
| 100 | + "interrupt coalescing is enabled only on high iops queues\n\t\t" |
|---|
| 101 | + "1 - iops: High iops queues are not allocated &\n\t\t" |
|---|
| 102 | + "interrupt coalescing is enabled on all queues\n\t\t" |
|---|
| 103 | + "2 - latency: High iops queues are not allocated &\n\t\t" |
|---|
| 104 | + "interrupt coalescing is disabled on all queues\n\t\t" |
|---|
| 105 | + "default mode is 'balanced'" |
|---|
| 106 | + ); |
|---|
| 107 | + |
|---|
| 108 | +int event_log_level = MFI_EVT_CLASS_CRITICAL; |
|---|
| 109 | +module_param(event_log_level, int, 0644); |
|---|
| 110 | +MODULE_PARM_DESC(event_log_level, "Asynchronous event logging level- range is: -2(CLASS_DEBUG) to 4(CLASS_DEAD), Default: 2(CLASS_CRITICAL)"); |
|---|
| 111 | + |
|---|
| 112 | +unsigned int enable_sdev_max_qd; |
|---|
| 113 | +module_param(enable_sdev_max_qd, int, 0444); |
|---|
| 114 | +MODULE_PARM_DESC(enable_sdev_max_qd, "Enable sdev max qd as can_queue. Default: 0"); |
|---|
| 108 | 115 | |
|---|
| 109 | 116 | MODULE_LICENSE("GPL"); |
|---|
| 110 | 117 | MODULE_VERSION(MEGASAS_VERSION); |
|---|
| 111 | | -MODULE_AUTHOR("megaraidlinux.pdl@avagotech.com"); |
|---|
| 112 | | -MODULE_DESCRIPTION("Avago MegaRAID SAS Driver"); |
|---|
| 118 | +MODULE_AUTHOR("megaraidlinux.pdl@broadcom.com"); |
|---|
| 119 | +MODULE_DESCRIPTION("Broadcom MegaRAID SAS Driver"); |
|---|
| 113 | 120 | |
|---|
| 114 | 121 | int megasas_transition_to_ready(struct megasas_instance *instance, int ocr); |
|---|
| 115 | 122 | static int megasas_get_pd_list(struct megasas_instance *instance); |
|---|
| .. | .. |
|---|
| 120 | 127 | u32 seq_num, u32 class_locale_word); |
|---|
| 121 | 128 | static void megasas_get_pd_info(struct megasas_instance *instance, |
|---|
| 122 | 129 | struct scsi_device *sdev); |
|---|
| 130 | +static void |
|---|
| 131 | +megasas_set_ld_removed_by_fw(struct megasas_instance *instance); |
|---|
| 123 | 132 | |
|---|
| 124 | 133 | /* |
|---|
| 125 | 134 | * PCI ID table for all supported controllers |
|---|
| .. | .. |
|---|
| 165 | 174 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_TOMCAT)}, |
|---|
| 166 | 175 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA_4PORT)}, |
|---|
| 167 | 176 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CRUSADER_4PORT)}, |
|---|
| 177 | + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E1)}, |
|---|
| 178 | + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E2)}, |
|---|
| 179 | + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E5)}, |
|---|
| 180 | + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E6)}, |
|---|
| 181 | + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E0)}, |
|---|
| 182 | + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E3)}, |
|---|
| 183 | + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E4)}, |
|---|
| 184 | + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E7)}, |
|---|
| 168 | 185 | {} |
|---|
| 169 | 186 | }; |
|---|
| 170 | 187 | |
|---|
| .. | .. |
|---|
| 181 | 198 | u32 megasas_dbg_lvl; |
|---|
| 182 | 199 | static u32 support_device_change; |
|---|
| 183 | 200 | static bool support_nvme_encapsulation; |
|---|
| 201 | +static bool support_pci_lane_margining; |
|---|
| 184 | 202 | |
|---|
| 185 | 203 | /* define lock for aen poll */ |
|---|
| 186 | | -spinlock_t poll_aen_lock; |
|---|
| 204 | +static spinlock_t poll_aen_lock; |
|---|
| 205 | + |
|---|
| 206 | +extern struct dentry *megasas_debugfs_root; |
|---|
| 187 | 207 | |
|---|
| 188 | 208 | void |
|---|
| 189 | 209 | megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, |
|---|
| 190 | 210 | u8 alt_status); |
|---|
| 191 | 211 | static u32 |
|---|
| 192 | | -megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs); |
|---|
| 212 | +megasas_read_fw_status_reg_gen2(struct megasas_instance *instance); |
|---|
| 193 | 213 | static int |
|---|
| 194 | 214 | megasas_adp_reset_gen2(struct megasas_instance *instance, |
|---|
| 195 | 215 | struct megasas_register_set __iomem *reg_set); |
|---|
| .. | .. |
|---|
| 219 | 239 | static inline void |
|---|
| 220 | 240 | megasas_init_ctrl_params(struct megasas_instance *instance); |
|---|
| 221 | 241 | |
|---|
| 242 | +u32 megasas_readl(struct megasas_instance *instance, |
|---|
| 243 | + const volatile void __iomem *addr) |
|---|
| 244 | +{ |
|---|
| 245 | + u32 i = 0, ret_val; |
|---|
| 246 | + /* |
|---|
| 247 | + * Due to a HW errata in Aero controllers, reads to certain |
|---|
| 248 | + * Fusion registers could intermittently return all zeroes. |
|---|
| 249 | + * This behavior is transient in nature and subsequent reads will |
|---|
| 250 | + * return valid value. As a workaround in driver, retry readl for |
|---|
| 251 | + * upto three times until a non-zero value is read. |
|---|
| 252 | + */ |
|---|
| 253 | + if (instance->adapter_type == AERO_SERIES) { |
|---|
| 254 | + do { |
|---|
| 255 | + ret_val = readl(addr); |
|---|
| 256 | + i++; |
|---|
| 257 | + } while (ret_val == 0 && i < 3); |
|---|
| 258 | + return ret_val; |
|---|
| 259 | + } else { |
|---|
| 260 | + return readl(addr); |
|---|
| 261 | + } |
|---|
| 262 | +} |
|---|
| 263 | + |
|---|
| 222 | 264 | /** |
|---|
| 223 | 265 | * megasas_set_dma_settings - Populate DMA address, length and flags for DCMDs |
|---|
| 224 | 266 | * @instance: Adapter soft state |
|---|
| .. | .. |
|---|
| 244 | 286 | } |
|---|
| 245 | 287 | } |
|---|
| 246 | 288 | |
|---|
| 247 | | -void |
|---|
| 289 | +static void |
|---|
| 248 | 290 | megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd) |
|---|
| 249 | 291 | { |
|---|
| 250 | 292 | instance->instancet->fire_cmd(instance, |
|---|
| .. | .. |
|---|
| 368 | 410 | union megasas_evt_class_locale class_locale; |
|---|
| 369 | 411 | class_locale.word = le32_to_cpu(evt_detail->cl.word); |
|---|
| 370 | 412 | |
|---|
| 371 | | - if (class_locale.members.class >= MFI_EVT_CLASS_CRITICAL) |
|---|
| 413 | + if ((event_log_level < MFI_EVT_CLASS_DEBUG) || |
|---|
| 414 | + (event_log_level > MFI_EVT_CLASS_DEAD)) { |
|---|
| 415 | + printk(KERN_WARNING "megaraid_sas: provided event log level is out of range, setting it to default 2(CLASS_CRITICAL), permissible range is: -2 to 4\n"); |
|---|
| 416 | + event_log_level = MFI_EVT_CLASS_CRITICAL; |
|---|
| 417 | + } |
|---|
| 418 | + |
|---|
| 419 | + if (class_locale.members.class >= event_log_level) |
|---|
| 372 | 420 | dev_info(&instance->pdev->dev, "%d (%s/0x%04x/%s) - %s\n", |
|---|
| 373 | 421 | le32_to_cpu(evt_detail->seq_num), |
|---|
| 374 | 422 | format_timestamp(le32_to_cpu(evt_detail->time_stamp)), |
|---|
| 375 | 423 | (class_locale.members.locale), |
|---|
| 376 | 424 | format_class(class_locale.members.class), |
|---|
| 377 | 425 | evt_detail->description); |
|---|
| 426 | + |
|---|
| 427 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 428 | + dev_info(&instance->pdev->dev, |
|---|
| 429 | + "evt_detail.args.ld.target_id/index %d/%d\n", |
|---|
| 430 | + evt_detail->args.ld.target_id, evt_detail->args.ld.ld_index); |
|---|
| 431 | + |
|---|
| 378 | 432 | } |
|---|
| 379 | 433 | |
|---|
| 380 | | -/** |
|---|
| 381 | | -* The following functions are defined for xscale |
|---|
| 382 | | -* (deviceid : 1064R, PERC5) controllers |
|---|
| 383 | | -*/ |
|---|
| 434 | +/* |
|---|
| 435 | + * The following functions are defined for xscale |
|---|
| 436 | + * (deviceid : 1064R, PERC5) controllers |
|---|
| 437 | + */ |
|---|
| 384 | 438 | |
|---|
| 385 | 439 | /** |
|---|
| 386 | 440 | * megasas_enable_intr_xscale - Enables interrupts |
|---|
| 387 | | - * @regs: MFI register set |
|---|
| 441 | + * @instance: Adapter soft state |
|---|
| 388 | 442 | */ |
|---|
| 389 | 443 | static inline void |
|---|
| 390 | 444 | megasas_enable_intr_xscale(struct megasas_instance *instance) |
|---|
| .. | .. |
|---|
| 400 | 454 | |
|---|
| 401 | 455 | /** |
|---|
| 402 | 456 | * megasas_disable_intr_xscale -Disables interrupt |
|---|
| 403 | | - * @regs: MFI register set |
|---|
| 457 | + * @instance: Adapter soft state |
|---|
| 404 | 458 | */ |
|---|
| 405 | 459 | static inline void |
|---|
| 406 | 460 | megasas_disable_intr_xscale(struct megasas_instance *instance) |
|---|
| .. | .. |
|---|
| 416 | 470 | |
|---|
| 417 | 471 | /** |
|---|
| 418 | 472 | * megasas_read_fw_status_reg_xscale - returns the current FW status value |
|---|
| 419 | | - * @regs: MFI register set |
|---|
| 473 | + * @instance: Adapter soft state |
|---|
| 420 | 474 | */ |
|---|
| 421 | 475 | static u32 |
|---|
| 422 | | -megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs) |
|---|
| 476 | +megasas_read_fw_status_reg_xscale(struct megasas_instance *instance) |
|---|
| 423 | 477 | { |
|---|
| 424 | | - return readl(&(regs)->outbound_msg_0); |
|---|
| 478 | + return readl(&instance->reg_set->outbound_msg_0); |
|---|
| 425 | 479 | } |
|---|
| 426 | 480 | /** |
|---|
| 427 | 481 | * megasas_clear_interrupt_xscale - Check & clear interrupt |
|---|
| 428 | | - * @regs: MFI register set |
|---|
| 482 | + * @instance: Adapter soft state |
|---|
| 429 | 483 | */ |
|---|
| 430 | 484 | static int |
|---|
| 431 | | -megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs) |
|---|
| 485 | +megasas_clear_intr_xscale(struct megasas_instance *instance) |
|---|
| 432 | 486 | { |
|---|
| 433 | 487 | u32 status; |
|---|
| 434 | 488 | u32 mfiStatus = 0; |
|---|
| 489 | + struct megasas_register_set __iomem *regs; |
|---|
| 490 | + regs = instance->reg_set; |
|---|
| 435 | 491 | |
|---|
| 436 | 492 | /* |
|---|
| 437 | 493 | * Check if it is our interrupt |
|---|
| .. | .. |
|---|
| 457 | 513 | |
|---|
| 458 | 514 | /** |
|---|
| 459 | 515 | * megasas_fire_cmd_xscale - Sends command to the FW |
|---|
| 460 | | - * @frame_phys_addr : Physical address of cmd |
|---|
| 461 | | - * @frame_count : Number of frames for the command |
|---|
| 462 | | - * @regs : MFI register set |
|---|
| 516 | + * @instance: Adapter soft state |
|---|
| 517 | + * @frame_phys_addr : Physical address of cmd |
|---|
| 518 | + * @frame_count : Number of frames for the command |
|---|
| 519 | + * @regs : MFI register set |
|---|
| 463 | 520 | */ |
|---|
| 464 | 521 | static inline void |
|---|
| 465 | 522 | megasas_fire_cmd_xscale(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 477 | 534 | |
|---|
| 478 | 535 | /** |
|---|
| 479 | 536 | * megasas_adp_reset_xscale - For controller reset |
|---|
| 480 | | - * @regs: MFI register set |
|---|
| 537 | + * @instance: Adapter soft state |
|---|
| 538 | + * @regs: MFI register set |
|---|
| 481 | 539 | */ |
|---|
| 482 | 540 | static int |
|---|
| 483 | 541 | megasas_adp_reset_xscale(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 518 | 576 | |
|---|
| 519 | 577 | /** |
|---|
| 520 | 578 | * megasas_check_reset_xscale - For controller reset check |
|---|
| 521 | | - * @regs: MFI register set |
|---|
| 579 | + * @instance: Adapter soft state |
|---|
| 580 | + * @regs: MFI register set |
|---|
| 522 | 581 | */ |
|---|
| 523 | 582 | static int |
|---|
| 524 | 583 | megasas_check_reset_xscale(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 547 | 606 | .issue_dcmd = megasas_issue_dcmd, |
|---|
| 548 | 607 | }; |
|---|
| 549 | 608 | |
|---|
| 550 | | -/** |
|---|
| 551 | | -* This is the end of set of functions & definitions specific |
|---|
| 552 | | -* to xscale (deviceid : 1064R, PERC5) controllers |
|---|
| 553 | | -*/ |
|---|
| 609 | +/* |
|---|
| 610 | + * This is the end of set of functions & definitions specific |
|---|
| 611 | + * to xscale (deviceid : 1064R, PERC5) controllers |
|---|
| 612 | + */ |
|---|
| 554 | 613 | |
|---|
| 555 | | -/** |
|---|
| 556 | | -* The following functions are defined for ppc (deviceid : 0x60) |
|---|
| 557 | | -* controllers |
|---|
| 558 | | -*/ |
|---|
| 614 | +/* |
|---|
| 615 | + * The following functions are defined for ppc (deviceid : 0x60) |
|---|
| 616 | + * controllers |
|---|
| 617 | + */ |
|---|
| 559 | 618 | |
|---|
| 560 | 619 | /** |
|---|
| 561 | 620 | * megasas_enable_intr_ppc - Enables interrupts |
|---|
| 562 | | - * @regs: MFI register set |
|---|
| 621 | + * @instance: Adapter soft state |
|---|
| 563 | 622 | */ |
|---|
| 564 | 623 | static inline void |
|---|
| 565 | 624 | megasas_enable_intr_ppc(struct megasas_instance *instance) |
|---|
| .. | .. |
|---|
| 577 | 636 | |
|---|
| 578 | 637 | /** |
|---|
| 579 | 638 | * megasas_disable_intr_ppc - Disable interrupt |
|---|
| 580 | | - * @regs: MFI register set |
|---|
| 639 | + * @instance: Adapter soft state |
|---|
| 581 | 640 | */ |
|---|
| 582 | 641 | static inline void |
|---|
| 583 | 642 | megasas_disable_intr_ppc(struct megasas_instance *instance) |
|---|
| .. | .. |
|---|
| 593 | 652 | |
|---|
| 594 | 653 | /** |
|---|
| 595 | 654 | * megasas_read_fw_status_reg_ppc - returns the current FW status value |
|---|
| 596 | | - * @regs: MFI register set |
|---|
| 655 | + * @instance: Adapter soft state |
|---|
| 597 | 656 | */ |
|---|
| 598 | 657 | static u32 |
|---|
| 599 | | -megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs) |
|---|
| 658 | +megasas_read_fw_status_reg_ppc(struct megasas_instance *instance) |
|---|
| 600 | 659 | { |
|---|
| 601 | | - return readl(&(regs)->outbound_scratch_pad); |
|---|
| 660 | + return readl(&instance->reg_set->outbound_scratch_pad_0); |
|---|
| 602 | 661 | } |
|---|
| 603 | 662 | |
|---|
| 604 | 663 | /** |
|---|
| 605 | 664 | * megasas_clear_interrupt_ppc - Check & clear interrupt |
|---|
| 606 | | - * @regs: MFI register set |
|---|
| 665 | + * @instance: Adapter soft state |
|---|
| 607 | 666 | */ |
|---|
| 608 | 667 | static int |
|---|
| 609 | | -megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs) |
|---|
| 668 | +megasas_clear_intr_ppc(struct megasas_instance *instance) |
|---|
| 610 | 669 | { |
|---|
| 611 | 670 | u32 status, mfiStatus = 0; |
|---|
| 671 | + struct megasas_register_set __iomem *regs; |
|---|
| 672 | + regs = instance->reg_set; |
|---|
| 612 | 673 | |
|---|
| 613 | 674 | /* |
|---|
| 614 | 675 | * Check if it is our interrupt |
|---|
| .. | .. |
|---|
| 634 | 695 | |
|---|
| 635 | 696 | /** |
|---|
| 636 | 697 | * megasas_fire_cmd_ppc - Sends command to the FW |
|---|
| 637 | | - * @frame_phys_addr : Physical address of cmd |
|---|
| 638 | | - * @frame_count : Number of frames for the command |
|---|
| 639 | | - * @regs : MFI register set |
|---|
| 698 | + * @instance: Adapter soft state |
|---|
| 699 | + * @frame_phys_addr: Physical address of cmd |
|---|
| 700 | + * @frame_count: Number of frames for the command |
|---|
| 701 | + * @regs: MFI register set |
|---|
| 640 | 702 | */ |
|---|
| 641 | 703 | static inline void |
|---|
| 642 | 704 | megasas_fire_cmd_ppc(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 654 | 716 | |
|---|
| 655 | 717 | /** |
|---|
| 656 | 718 | * megasas_check_reset_ppc - For controller reset check |
|---|
| 657 | | - * @regs: MFI register set |
|---|
| 719 | + * @instance: Adapter soft state |
|---|
| 720 | + * @regs: MFI register set |
|---|
| 658 | 721 | */ |
|---|
| 659 | 722 | static int |
|---|
| 660 | 723 | megasas_check_reset_ppc(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 684 | 747 | |
|---|
| 685 | 748 | /** |
|---|
| 686 | 749 | * megasas_enable_intr_skinny - Enables interrupts |
|---|
| 687 | | - * @regs: MFI register set |
|---|
| 750 | + * @instance: Adapter soft state |
|---|
| 688 | 751 | */ |
|---|
| 689 | 752 | static inline void |
|---|
| 690 | 753 | megasas_enable_intr_skinny(struct megasas_instance *instance) |
|---|
| .. | .. |
|---|
| 702 | 765 | |
|---|
| 703 | 766 | /** |
|---|
| 704 | 767 | * megasas_disable_intr_skinny - Disables interrupt |
|---|
| 705 | | - * @regs: MFI register set |
|---|
| 768 | + * @instance: Adapter soft state |
|---|
| 706 | 769 | */ |
|---|
| 707 | 770 | static inline void |
|---|
| 708 | 771 | megasas_disable_intr_skinny(struct megasas_instance *instance) |
|---|
| .. | .. |
|---|
| 718 | 781 | |
|---|
| 719 | 782 | /** |
|---|
| 720 | 783 | * megasas_read_fw_status_reg_skinny - returns the current FW status value |
|---|
| 721 | | - * @regs: MFI register set |
|---|
| 784 | + * @instance: Adapter soft state |
|---|
| 722 | 785 | */ |
|---|
| 723 | 786 | static u32 |
|---|
| 724 | | -megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs) |
|---|
| 787 | +megasas_read_fw_status_reg_skinny(struct megasas_instance *instance) |
|---|
| 725 | 788 | { |
|---|
| 726 | | - return readl(&(regs)->outbound_scratch_pad); |
|---|
| 789 | + return readl(&instance->reg_set->outbound_scratch_pad_0); |
|---|
| 727 | 790 | } |
|---|
| 728 | 791 | |
|---|
| 729 | 792 | /** |
|---|
| 730 | 793 | * megasas_clear_interrupt_skinny - Check & clear interrupt |
|---|
| 731 | | - * @regs: MFI register set |
|---|
| 794 | + * @instance: Adapter soft state |
|---|
| 732 | 795 | */ |
|---|
| 733 | 796 | static int |
|---|
| 734 | | -megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) |
|---|
| 797 | +megasas_clear_intr_skinny(struct megasas_instance *instance) |
|---|
| 735 | 798 | { |
|---|
| 736 | 799 | u32 status; |
|---|
| 737 | 800 | u32 mfiStatus = 0; |
|---|
| 801 | + struct megasas_register_set __iomem *regs; |
|---|
| 802 | + regs = instance->reg_set; |
|---|
| 738 | 803 | |
|---|
| 739 | 804 | /* |
|---|
| 740 | 805 | * Check if it is our interrupt |
|---|
| .. | .. |
|---|
| 748 | 813 | /* |
|---|
| 749 | 814 | * Check if it is our interrupt |
|---|
| 750 | 815 | */ |
|---|
| 751 | | - if ((megasas_read_fw_status_reg_skinny(regs) & MFI_STATE_MASK) == |
|---|
| 816 | + if ((megasas_read_fw_status_reg_skinny(instance) & MFI_STATE_MASK) == |
|---|
| 752 | 817 | MFI_STATE_FAULT) { |
|---|
| 753 | 818 | mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; |
|---|
| 754 | 819 | } else |
|---|
| .. | .. |
|---|
| 769 | 834 | |
|---|
| 770 | 835 | /** |
|---|
| 771 | 836 | * megasas_fire_cmd_skinny - Sends command to the FW |
|---|
| 772 | | - * @frame_phys_addr : Physical address of cmd |
|---|
| 773 | | - * @frame_count : Number of frames for the command |
|---|
| 774 | | - * @regs : MFI register set |
|---|
| 837 | + * @instance: Adapter soft state |
|---|
| 838 | + * @frame_phys_addr: Physical address of cmd |
|---|
| 839 | + * @frame_count: Number of frames for the command |
|---|
| 840 | + * @regs: MFI register set |
|---|
| 775 | 841 | */ |
|---|
| 776 | 842 | static inline void |
|---|
| 777 | 843 | megasas_fire_cmd_skinny(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 786 | 852 | &(regs)->inbound_high_queue_port); |
|---|
| 787 | 853 | writel((lower_32_bits(frame_phys_addr) | (frame_count<<1))|1, |
|---|
| 788 | 854 | &(regs)->inbound_low_queue_port); |
|---|
| 789 | | - mmiowb(); |
|---|
| 790 | 855 | spin_unlock_irqrestore(&instance->hba_lock, flags); |
|---|
| 791 | 856 | } |
|---|
| 792 | 857 | |
|---|
| 793 | 858 | /** |
|---|
| 794 | 859 | * megasas_check_reset_skinny - For controller reset check |
|---|
| 795 | | - * @regs: MFI register set |
|---|
| 860 | + * @instance: Adapter soft state |
|---|
| 861 | + * @regs: MFI register set |
|---|
| 796 | 862 | */ |
|---|
| 797 | 863 | static int |
|---|
| 798 | 864 | megasas_check_reset_skinny(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 821 | 887 | }; |
|---|
| 822 | 888 | |
|---|
| 823 | 889 | |
|---|
| 824 | | -/** |
|---|
| 825 | | -* The following functions are defined for gen2 (deviceid : 0x78 0x79) |
|---|
| 826 | | -* controllers |
|---|
| 827 | | -*/ |
|---|
| 890 | +/* |
|---|
| 891 | + * The following functions are defined for gen2 (deviceid : 0x78 0x79) |
|---|
| 892 | + * controllers |
|---|
| 893 | + */ |
|---|
| 828 | 894 | |
|---|
| 829 | 895 | /** |
|---|
| 830 | 896 | * megasas_enable_intr_gen2 - Enables interrupts |
|---|
| 831 | | - * @regs: MFI register set |
|---|
| 897 | + * @instance: Adapter soft state |
|---|
| 832 | 898 | */ |
|---|
| 833 | 899 | static inline void |
|---|
| 834 | 900 | megasas_enable_intr_gen2(struct megasas_instance *instance) |
|---|
| .. | .. |
|---|
| 847 | 913 | |
|---|
| 848 | 914 | /** |
|---|
| 849 | 915 | * megasas_disable_intr_gen2 - Disables interrupt |
|---|
| 850 | | - * @regs: MFI register set |
|---|
| 916 | + * @instance: Adapter soft state |
|---|
| 851 | 917 | */ |
|---|
| 852 | 918 | static inline void |
|---|
| 853 | 919 | megasas_disable_intr_gen2(struct megasas_instance *instance) |
|---|
| .. | .. |
|---|
| 863 | 929 | |
|---|
| 864 | 930 | /** |
|---|
| 865 | 931 | * megasas_read_fw_status_reg_gen2 - returns the current FW status value |
|---|
| 866 | | - * @regs: MFI register set |
|---|
| 932 | + * @instance: Adapter soft state |
|---|
| 867 | 933 | */ |
|---|
| 868 | 934 | static u32 |
|---|
| 869 | | -megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs) |
|---|
| 935 | +megasas_read_fw_status_reg_gen2(struct megasas_instance *instance) |
|---|
| 870 | 936 | { |
|---|
| 871 | | - return readl(&(regs)->outbound_scratch_pad); |
|---|
| 937 | + return readl(&instance->reg_set->outbound_scratch_pad_0); |
|---|
| 872 | 938 | } |
|---|
| 873 | 939 | |
|---|
| 874 | 940 | /** |
|---|
| 875 | 941 | * megasas_clear_interrupt_gen2 - Check & clear interrupt |
|---|
| 876 | | - * @regs: MFI register set |
|---|
| 942 | + * @instance: Adapter soft state |
|---|
| 877 | 943 | */ |
|---|
| 878 | 944 | static int |
|---|
| 879 | | -megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs) |
|---|
| 945 | +megasas_clear_intr_gen2(struct megasas_instance *instance) |
|---|
| 880 | 946 | { |
|---|
| 881 | 947 | u32 status; |
|---|
| 882 | 948 | u32 mfiStatus = 0; |
|---|
| 949 | + struct megasas_register_set __iomem *regs; |
|---|
| 950 | + regs = instance->reg_set; |
|---|
| 883 | 951 | |
|---|
| 884 | 952 | /* |
|---|
| 885 | 953 | * Check if it is our interrupt |
|---|
| .. | .. |
|---|
| 904 | 972 | |
|---|
| 905 | 973 | return mfiStatus; |
|---|
| 906 | 974 | } |
|---|
| 975 | + |
|---|
| 907 | 976 | /** |
|---|
| 908 | 977 | * megasas_fire_cmd_gen2 - Sends command to the FW |
|---|
| 909 | | - * @frame_phys_addr : Physical address of cmd |
|---|
| 910 | | - * @frame_count : Number of frames for the command |
|---|
| 911 | | - * @regs : MFI register set |
|---|
| 978 | + * @instance: Adapter soft state |
|---|
| 979 | + * @frame_phys_addr: Physical address of cmd |
|---|
| 980 | + * @frame_count: Number of frames for the command |
|---|
| 981 | + * @regs: MFI register set |
|---|
| 912 | 982 | */ |
|---|
| 913 | 983 | static inline void |
|---|
| 914 | 984 | megasas_fire_cmd_gen2(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 926 | 996 | |
|---|
| 927 | 997 | /** |
|---|
| 928 | 998 | * megasas_adp_reset_gen2 - For controller reset |
|---|
| 929 | | - * @regs: MFI register set |
|---|
| 999 | + * @instance: Adapter soft state |
|---|
| 1000 | + * @reg_set: MFI register set |
|---|
| 930 | 1001 | */ |
|---|
| 931 | 1002 | static int |
|---|
| 932 | 1003 | megasas_adp_reset_gen2(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 986 | 1057 | |
|---|
| 987 | 1058 | /** |
|---|
| 988 | 1059 | * megasas_check_reset_gen2 - For controller reset check |
|---|
| 989 | | - * @regs: MFI register set |
|---|
| 1060 | + * @instance: Adapter soft state |
|---|
| 1061 | + * @regs: MFI register set |
|---|
| 990 | 1062 | */ |
|---|
| 991 | 1063 | static int |
|---|
| 992 | 1064 | megasas_check_reset_gen2(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 1014 | 1086 | .issue_dcmd = megasas_issue_dcmd, |
|---|
| 1015 | 1087 | }; |
|---|
| 1016 | 1088 | |
|---|
| 1017 | | -/** |
|---|
| 1018 | | -* This is the end of set of functions & definitions |
|---|
| 1019 | | -* specific to gen2 (deviceid : 0x78, 0x79) controllers |
|---|
| 1020 | | -*/ |
|---|
| 1089 | +/* |
|---|
| 1090 | + * This is the end of set of functions & definitions |
|---|
| 1091 | + * specific to gen2 (deviceid : 0x78, 0x79) controllers |
|---|
| 1092 | + */ |
|---|
| 1021 | 1093 | |
|---|
| 1022 | 1094 | /* |
|---|
| 1023 | 1095 | * Template added for TB (Fusion) |
|---|
| .. | .. |
|---|
| 1042 | 1114 | if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { |
|---|
| 1043 | 1115 | dev_err(&instance->pdev->dev, "Failed from %s %d\n", |
|---|
| 1044 | 1116 | __func__, __LINE__); |
|---|
| 1045 | | - return DCMD_NOT_FIRED; |
|---|
| 1117 | + return DCMD_INIT; |
|---|
| 1046 | 1118 | } |
|---|
| 1047 | 1119 | |
|---|
| 1048 | 1120 | instance->instancet->issue_dcmd(instance, cmd); |
|---|
| .. | .. |
|---|
| 1066 | 1138 | struct megasas_cmd *cmd, int timeout) |
|---|
| 1067 | 1139 | { |
|---|
| 1068 | 1140 | int ret = 0; |
|---|
| 1069 | | - cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; |
|---|
| 1141 | + cmd->cmd_status_drv = DCMD_INIT; |
|---|
| 1070 | 1142 | |
|---|
| 1071 | 1143 | if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { |
|---|
| 1072 | 1144 | dev_err(&instance->pdev->dev, "Failed from %s %d\n", |
|---|
| 1073 | 1145 | __func__, __LINE__); |
|---|
| 1074 | | - return DCMD_NOT_FIRED; |
|---|
| 1146 | + return DCMD_INIT; |
|---|
| 1075 | 1147 | } |
|---|
| 1076 | 1148 | |
|---|
| 1077 | 1149 | instance->instancet->issue_dcmd(instance, cmd); |
|---|
| 1078 | 1150 | |
|---|
| 1079 | 1151 | if (timeout) { |
|---|
| 1080 | 1152 | ret = wait_event_timeout(instance->int_cmd_wait_q, |
|---|
| 1081 | | - cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ); |
|---|
| 1153 | + cmd->cmd_status_drv != DCMD_INIT, timeout * HZ); |
|---|
| 1082 | 1154 | if (!ret) { |
|---|
| 1083 | | - dev_err(&instance->pdev->dev, "Failed from %s %d DCMD Timed out\n", |
|---|
| 1084 | | - __func__, __LINE__); |
|---|
| 1155 | + dev_err(&instance->pdev->dev, |
|---|
| 1156 | + "DCMD(opcode: 0x%x) is timed out, func:%s\n", |
|---|
| 1157 | + cmd->frame->dcmd.opcode, __func__); |
|---|
| 1085 | 1158 | return DCMD_TIMEOUT; |
|---|
| 1086 | 1159 | } |
|---|
| 1087 | 1160 | } else |
|---|
| 1088 | 1161 | wait_event(instance->int_cmd_wait_q, |
|---|
| 1089 | | - cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS); |
|---|
| 1162 | + cmd->cmd_status_drv != DCMD_INIT); |
|---|
| 1090 | 1163 | |
|---|
| 1091 | | - return (cmd->cmd_status_drv == MFI_STAT_OK) ? |
|---|
| 1092 | | - DCMD_SUCCESS : DCMD_FAILED; |
|---|
| 1164 | + return cmd->cmd_status_drv; |
|---|
| 1093 | 1165 | } |
|---|
| 1094 | 1166 | |
|---|
| 1095 | 1167 | /** |
|---|
| .. | .. |
|---|
| 1110 | 1182 | struct megasas_cmd *cmd; |
|---|
| 1111 | 1183 | struct megasas_abort_frame *abort_fr; |
|---|
| 1112 | 1184 | int ret = 0; |
|---|
| 1185 | + u32 opcode; |
|---|
| 1113 | 1186 | |
|---|
| 1114 | 1187 | cmd = megasas_get_cmd(instance); |
|---|
| 1115 | 1188 | |
|---|
| .. | .. |
|---|
| 1131 | 1204 | cpu_to_le32(upper_32_bits(cmd_to_abort->frame_phys_addr)); |
|---|
| 1132 | 1205 | |
|---|
| 1133 | 1206 | cmd->sync_cmd = 1; |
|---|
| 1134 | | - cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; |
|---|
| 1207 | + cmd->cmd_status_drv = DCMD_INIT; |
|---|
| 1135 | 1208 | |
|---|
| 1136 | 1209 | if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { |
|---|
| 1137 | 1210 | dev_err(&instance->pdev->dev, "Failed from %s %d\n", |
|---|
| 1138 | 1211 | __func__, __LINE__); |
|---|
| 1139 | | - return DCMD_NOT_FIRED; |
|---|
| 1212 | + return DCMD_INIT; |
|---|
| 1140 | 1213 | } |
|---|
| 1141 | 1214 | |
|---|
| 1142 | 1215 | instance->instancet->issue_dcmd(instance, cmd); |
|---|
| 1143 | 1216 | |
|---|
| 1144 | 1217 | if (timeout) { |
|---|
| 1145 | 1218 | ret = wait_event_timeout(instance->abort_cmd_wait_q, |
|---|
| 1146 | | - cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ); |
|---|
| 1219 | + cmd->cmd_status_drv != DCMD_INIT, timeout * HZ); |
|---|
| 1147 | 1220 | if (!ret) { |
|---|
| 1148 | | - dev_err(&instance->pdev->dev, "Failed from %s %d Abort Timed out\n", |
|---|
| 1149 | | - __func__, __LINE__); |
|---|
| 1221 | + opcode = cmd_to_abort->frame->dcmd.opcode; |
|---|
| 1222 | + dev_err(&instance->pdev->dev, |
|---|
| 1223 | + "Abort(to be aborted DCMD opcode: 0x%x) is timed out func:%s\n", |
|---|
| 1224 | + opcode, __func__); |
|---|
| 1150 | 1225 | return DCMD_TIMEOUT; |
|---|
| 1151 | 1226 | } |
|---|
| 1152 | 1227 | } else |
|---|
| 1153 | 1228 | wait_event(instance->abort_cmd_wait_q, |
|---|
| 1154 | | - cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS); |
|---|
| 1229 | + cmd->cmd_status_drv != DCMD_INIT); |
|---|
| 1155 | 1230 | |
|---|
| 1156 | 1231 | cmd->sync_cmd = 0; |
|---|
| 1157 | 1232 | |
|---|
| 1158 | 1233 | megasas_return_cmd(instance, cmd); |
|---|
| 1159 | | - return (cmd->cmd_status_drv == MFI_STAT_OK) ? |
|---|
| 1160 | | - DCMD_SUCCESS : DCMD_FAILED; |
|---|
| 1234 | + return cmd->cmd_status_drv; |
|---|
| 1161 | 1235 | } |
|---|
| 1162 | 1236 | |
|---|
| 1163 | 1237 | /** |
|---|
| .. | .. |
|---|
| 1330 | 1404 | device_id = MEGASAS_DEV_INDEX(scp); |
|---|
| 1331 | 1405 | pthru = (struct megasas_pthru_frame *)cmd->frame; |
|---|
| 1332 | 1406 | |
|---|
| 1333 | | - if (scp->sc_data_direction == PCI_DMA_TODEVICE) |
|---|
| 1407 | + if (scp->sc_data_direction == DMA_TO_DEVICE) |
|---|
| 1334 | 1408 | flags = MFI_FRAME_DIR_WRITE; |
|---|
| 1335 | | - else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) |
|---|
| 1409 | + else if (scp->sc_data_direction == DMA_FROM_DEVICE) |
|---|
| 1336 | 1410 | flags = MFI_FRAME_DIR_READ; |
|---|
| 1337 | | - else if (scp->sc_data_direction == PCI_DMA_NONE) |
|---|
| 1411 | + else if (scp->sc_data_direction == DMA_NONE) |
|---|
| 1338 | 1412 | flags = MFI_FRAME_DIR_NONE; |
|---|
| 1339 | 1413 | |
|---|
| 1340 | 1414 | if (instance->flag_ieee == 1) { |
|---|
| .. | .. |
|---|
| 1428 | 1502 | device_id = MEGASAS_DEV_INDEX(scp); |
|---|
| 1429 | 1503 | ldio = (struct megasas_io_frame *)cmd->frame; |
|---|
| 1430 | 1504 | |
|---|
| 1431 | | - if (scp->sc_data_direction == PCI_DMA_TODEVICE) |
|---|
| 1505 | + if (scp->sc_data_direction == DMA_TO_DEVICE) |
|---|
| 1432 | 1506 | flags = MFI_FRAME_DIR_WRITE; |
|---|
| 1433 | | - else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) |
|---|
| 1507 | + else if (scp->sc_data_direction == DMA_FROM_DEVICE) |
|---|
| 1434 | 1508 | flags = MFI_FRAME_DIR_READ; |
|---|
| 1435 | 1509 | |
|---|
| 1436 | 1510 | if (instance->flag_ieee == 1) { |
|---|
| .. | .. |
|---|
| 1550 | 1624 | /** |
|---|
| 1551 | 1625 | * megasas_cmd_type - Checks if the cmd is for logical drive/sysPD |
|---|
| 1552 | 1626 | * and whether it's RW or non RW |
|---|
| 1553 | | - * @scmd: SCSI command |
|---|
| 1627 | + * @cmd: SCSI command |
|---|
| 1554 | 1628 | * |
|---|
| 1555 | 1629 | */ |
|---|
| 1556 | 1630 | inline int megasas_cmd_type(struct scsi_cmnd *cmd) |
|---|
| .. | .. |
|---|
| 1690 | 1764 | |
|---|
| 1691 | 1765 | /** |
|---|
| 1692 | 1766 | * megasas_queue_command - Queue entry point |
|---|
| 1767 | + * @shost: adapter SCSI host |
|---|
| 1693 | 1768 | * @scmd: SCSI command to be queued |
|---|
| 1694 | | - * @done: Callback entry point |
|---|
| 1695 | 1769 | */ |
|---|
| 1696 | 1770 | static int |
|---|
| 1697 | 1771 | megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) |
|---|
| 1698 | 1772 | { |
|---|
| 1699 | 1773 | struct megasas_instance *instance; |
|---|
| 1700 | 1774 | struct MR_PRIV_DEVICE *mr_device_priv_data; |
|---|
| 1775 | + u32 ld_tgt_id; |
|---|
| 1701 | 1776 | |
|---|
| 1702 | 1777 | instance = (struct megasas_instance *) |
|---|
| 1703 | 1778 | scmd->device->host->hostdata; |
|---|
| .. | .. |
|---|
| 1724 | 1799 | } |
|---|
| 1725 | 1800 | } |
|---|
| 1726 | 1801 | |
|---|
| 1727 | | - if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { |
|---|
| 1802 | + mr_device_priv_data = scmd->device->hostdata; |
|---|
| 1803 | + if (!mr_device_priv_data || |
|---|
| 1804 | + (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)) { |
|---|
| 1728 | 1805 | scmd->result = DID_NO_CONNECT << 16; |
|---|
| 1729 | 1806 | scmd->scsi_done(scmd); |
|---|
| 1730 | 1807 | return 0; |
|---|
| 1731 | 1808 | } |
|---|
| 1732 | 1809 | |
|---|
| 1733 | | - mr_device_priv_data = scmd->device->hostdata; |
|---|
| 1734 | | - if (!mr_device_priv_data) { |
|---|
| 1735 | | - scmd->result = DID_NO_CONNECT << 16; |
|---|
| 1736 | | - scmd->scsi_done(scmd); |
|---|
| 1737 | | - return 0; |
|---|
| 1810 | + if (MEGASAS_IS_LOGICAL(scmd->device)) { |
|---|
| 1811 | + ld_tgt_id = MEGASAS_TARGET_ID(scmd->device); |
|---|
| 1812 | + if (instance->ld_tgtid_status[ld_tgt_id] == LD_TARGET_ID_DELETED) { |
|---|
| 1813 | + scmd->result = DID_NO_CONNECT << 16; |
|---|
| 1814 | + scmd->scsi_done(scmd); |
|---|
| 1815 | + return 0; |
|---|
| 1816 | + } |
|---|
| 1738 | 1817 | } |
|---|
| 1739 | 1818 | |
|---|
| 1740 | 1819 | if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) |
|---|
| .. | .. |
|---|
| 1826 | 1905 | |
|---|
| 1827 | 1906 | mr_device_priv_data->is_tm_capable = |
|---|
| 1828 | 1907 | raid->capability.tmCapable; |
|---|
| 1908 | + |
|---|
| 1909 | + if (!raid->flags.isEPD) |
|---|
| 1910 | + sdev->no_write_same = 1; |
|---|
| 1911 | + |
|---|
| 1829 | 1912 | } else if (instance->use_seqnum_jbod_fp) { |
|---|
| 1830 | 1913 | pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + |
|---|
| 1831 | 1914 | sdev->id; |
|---|
| .. | .. |
|---|
| 1884 | 1967 | blk_queue_virt_boundary(sdev->request_queue, mr_nvme_pg_size - 1); |
|---|
| 1885 | 1968 | } |
|---|
| 1886 | 1969 | |
|---|
| 1970 | +/* |
|---|
| 1971 | + * megasas_set_fw_assisted_qd - |
|---|
| 1972 | + * set device queue depth to can_queue |
|---|
| 1973 | + * set device queue depth to fw assisted qd |
|---|
| 1974 | + * |
|---|
| 1975 | + * @sdev: scsi device |
|---|
| 1976 | + * @is_target_prop true, if fw provided target properties. |
|---|
| 1977 | + */ |
|---|
| 1978 | +static void megasas_set_fw_assisted_qd(struct scsi_device *sdev, |
|---|
| 1979 | + bool is_target_prop) |
|---|
| 1980 | +{ |
|---|
| 1981 | + u8 interface_type; |
|---|
| 1982 | + u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN; |
|---|
| 1983 | + u32 tgt_device_qd; |
|---|
| 1984 | + struct megasas_instance *instance; |
|---|
| 1985 | + struct MR_PRIV_DEVICE *mr_device_priv_data; |
|---|
| 1986 | + |
|---|
| 1987 | + instance = megasas_lookup_instance(sdev->host->host_no); |
|---|
| 1988 | + mr_device_priv_data = sdev->hostdata; |
|---|
| 1989 | + interface_type = mr_device_priv_data->interface_type; |
|---|
| 1990 | + |
|---|
| 1991 | + switch (interface_type) { |
|---|
| 1992 | + case SAS_PD: |
|---|
| 1993 | + device_qd = MEGASAS_SAS_QD; |
|---|
| 1994 | + break; |
|---|
| 1995 | + case SATA_PD: |
|---|
| 1996 | + device_qd = MEGASAS_SATA_QD; |
|---|
| 1997 | + break; |
|---|
| 1998 | + case NVME_PD: |
|---|
| 1999 | + device_qd = MEGASAS_NVME_QD; |
|---|
| 2000 | + break; |
|---|
| 2001 | + } |
|---|
| 2002 | + |
|---|
| 2003 | + if (is_target_prop) { |
|---|
| 2004 | + tgt_device_qd = le32_to_cpu(instance->tgt_prop->device_qdepth); |
|---|
| 2005 | + if (tgt_device_qd) |
|---|
| 2006 | + device_qd = min(instance->host->can_queue, |
|---|
| 2007 | + (int)tgt_device_qd); |
|---|
| 2008 | + } |
|---|
| 2009 | + |
|---|
| 2010 | + if (instance->enable_sdev_max_qd && interface_type != UNKNOWN_DRIVE) |
|---|
| 2011 | + device_qd = instance->host->can_queue; |
|---|
| 2012 | + |
|---|
| 2013 | + scsi_change_queue_depth(sdev, device_qd); |
|---|
| 2014 | +} |
|---|
| 1887 | 2015 | |
|---|
| 1888 | 2016 | /* |
|---|
| 1889 | 2017 | * megasas_set_static_target_properties - |
|---|
| .. | .. |
|---|
| 1900 | 2028 | static void megasas_set_static_target_properties(struct scsi_device *sdev, |
|---|
| 1901 | 2029 | bool is_target_prop) |
|---|
| 1902 | 2030 | { |
|---|
| 1903 | | - u16 target_index = 0; |
|---|
| 1904 | | - u8 interface_type; |
|---|
| 1905 | | - u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN; |
|---|
| 1906 | 2031 | u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB; |
|---|
| 1907 | | - u32 tgt_device_qd; |
|---|
| 1908 | 2032 | struct megasas_instance *instance; |
|---|
| 1909 | | - struct MR_PRIV_DEVICE *mr_device_priv_data; |
|---|
| 1910 | 2033 | |
|---|
| 1911 | 2034 | instance = megasas_lookup_instance(sdev->host->host_no); |
|---|
| 1912 | | - mr_device_priv_data = sdev->hostdata; |
|---|
| 1913 | | - interface_type = mr_device_priv_data->interface_type; |
|---|
| 1914 | 2035 | |
|---|
| 1915 | 2036 | /* |
|---|
| 1916 | 2037 | * The RAID firmware may require extended timeouts. |
|---|
| 1917 | 2038 | */ |
|---|
| 1918 | 2039 | blk_queue_rq_timeout(sdev->request_queue, scmd_timeout * HZ); |
|---|
| 1919 | 2040 | |
|---|
| 1920 | | - target_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; |
|---|
| 1921 | | - |
|---|
| 1922 | | - switch (interface_type) { |
|---|
| 1923 | | - case SAS_PD: |
|---|
| 1924 | | - device_qd = MEGASAS_SAS_QD; |
|---|
| 1925 | | - break; |
|---|
| 1926 | | - case SATA_PD: |
|---|
| 1927 | | - device_qd = MEGASAS_SATA_QD; |
|---|
| 1928 | | - break; |
|---|
| 1929 | | - case NVME_PD: |
|---|
| 1930 | | - device_qd = MEGASAS_NVME_QD; |
|---|
| 1931 | | - break; |
|---|
| 1932 | | - } |
|---|
| 1933 | | - |
|---|
| 1934 | | - if (is_target_prop) { |
|---|
| 1935 | | - tgt_device_qd = le32_to_cpu(instance->tgt_prop->device_qdepth); |
|---|
| 1936 | | - if (tgt_device_qd && |
|---|
| 1937 | | - (tgt_device_qd <= instance->host->can_queue)) |
|---|
| 1938 | | - device_qd = tgt_device_qd; |
|---|
| 1939 | | - |
|---|
| 1940 | | - /* max_io_size_kb will be set to non zero for |
|---|
| 1941 | | - * nvme based vd and syspd. |
|---|
| 1942 | | - */ |
|---|
| 2041 | + /* max_io_size_kb will be set to non zero for |
|---|
| 2042 | + * nvme based vd and syspd. |
|---|
| 2043 | + */ |
|---|
| 2044 | + if (is_target_prop) |
|---|
| 1943 | 2045 | max_io_size_kb = le32_to_cpu(instance->tgt_prop->max_io_size_kb); |
|---|
| 1944 | | - } |
|---|
| 1945 | 2046 | |
|---|
| 1946 | 2047 | if (instance->nvme_page_size && max_io_size_kb) |
|---|
| 1947 | 2048 | megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 10)); |
|---|
| 1948 | 2049 | |
|---|
| 1949 | | - scsi_change_queue_depth(sdev, device_qd); |
|---|
| 1950 | | - |
|---|
| 2050 | + megasas_set_fw_assisted_qd(sdev, is_target_prop); |
|---|
| 1951 | 2051 | } |
|---|
| 1952 | 2052 | |
|---|
| 1953 | 2053 | |
|---|
| .. | .. |
|---|
| 1993 | 2093 | |
|---|
| 1994 | 2094 | static int megasas_slave_alloc(struct scsi_device *sdev) |
|---|
| 1995 | 2095 | { |
|---|
| 1996 | | - u16 pd_index = 0; |
|---|
| 2096 | + u16 pd_index = 0, ld_tgt_id; |
|---|
| 1997 | 2097 | struct megasas_instance *instance ; |
|---|
| 1998 | 2098 | struct MR_PRIV_DEVICE *mr_device_priv_data; |
|---|
| 1999 | 2099 | |
|---|
| .. | .. |
|---|
| 2011 | 2111 | goto scan_target; |
|---|
| 2012 | 2112 | } |
|---|
| 2013 | 2113 | return -ENXIO; |
|---|
| 2114 | + } else if (!MEGASAS_IS_LUN_VALID(sdev)) { |
|---|
| 2115 | + sdev_printk(KERN_INFO, sdev, "%s: invalid LUN\n", __func__); |
|---|
| 2116 | + return -ENXIO; |
|---|
| 2014 | 2117 | } |
|---|
| 2015 | 2118 | |
|---|
| 2016 | 2119 | scan_target: |
|---|
| .. | .. |
|---|
| 2018 | 2121 | GFP_KERNEL); |
|---|
| 2019 | 2122 | if (!mr_device_priv_data) |
|---|
| 2020 | 2123 | return -ENOMEM; |
|---|
| 2124 | + |
|---|
| 2125 | + if (MEGASAS_IS_LOGICAL(sdev)) { |
|---|
| 2126 | + ld_tgt_id = MEGASAS_TARGET_ID(sdev); |
|---|
| 2127 | + instance->ld_tgtid_status[ld_tgt_id] = LD_TARGET_ID_ACTIVE; |
|---|
| 2128 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 2129 | + sdev_printk(KERN_INFO, sdev, "LD target ID %d created.\n", ld_tgt_id); |
|---|
| 2130 | + } |
|---|
| 2131 | + |
|---|
| 2021 | 2132 | sdev->hostdata = mr_device_priv_data; |
|---|
| 2022 | 2133 | |
|---|
| 2023 | 2134 | atomic_set(&mr_device_priv_data->r1_ldio_hint, |
|---|
| .. | .. |
|---|
| 2027 | 2138 | |
|---|
| 2028 | 2139 | static void megasas_slave_destroy(struct scsi_device *sdev) |
|---|
| 2029 | 2140 | { |
|---|
| 2141 | + u16 ld_tgt_id; |
|---|
| 2142 | + struct megasas_instance *instance; |
|---|
| 2143 | + |
|---|
| 2144 | + instance = megasas_lookup_instance(sdev->host->host_no); |
|---|
| 2145 | + |
|---|
| 2146 | + if (MEGASAS_IS_LOGICAL(sdev)) { |
|---|
| 2147 | + if (!MEGASAS_IS_LUN_VALID(sdev)) { |
|---|
| 2148 | + sdev_printk(KERN_INFO, sdev, "%s: invalid LUN\n", __func__); |
|---|
| 2149 | + return; |
|---|
| 2150 | + } |
|---|
| 2151 | + ld_tgt_id = MEGASAS_TARGET_ID(sdev); |
|---|
| 2152 | + instance->ld_tgtid_status[ld_tgt_id] = LD_TARGET_ID_DELETED; |
|---|
| 2153 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 2154 | + sdev_printk(KERN_INFO, sdev, |
|---|
| 2155 | + "LD target ID %d removed from OS stack\n", ld_tgt_id); |
|---|
| 2156 | + } |
|---|
| 2157 | + |
|---|
| 2030 | 2158 | kfree(sdev->hostdata); |
|---|
| 2031 | 2159 | sdev->hostdata = NULL; |
|---|
| 2032 | 2160 | } |
|---|
| .. | .. |
|---|
| 2072 | 2200 | |
|---|
| 2073 | 2201 | void megaraid_sas_kill_hba(struct megasas_instance *instance) |
|---|
| 2074 | 2202 | { |
|---|
| 2203 | + if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { |
|---|
| 2204 | + dev_warn(&instance->pdev->dev, |
|---|
| 2205 | + "Adapter already dead, skipping kill HBA\n"); |
|---|
| 2206 | + return; |
|---|
| 2207 | + } |
|---|
| 2208 | + |
|---|
| 2075 | 2209 | /* Set critical error to block I/O & ioctls in case caller didn't */ |
|---|
| 2076 | 2210 | atomic_set(&instance->adprecovery, MEGASAS_HW_CRITICAL_ERROR); |
|---|
| 2077 | 2211 | /* Wait 1 second to ensure IO or ioctls in build have posted */ |
|---|
| .. | .. |
|---|
| 2079 | 2213 | if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || |
|---|
| 2080 | 2214 | (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || |
|---|
| 2081 | 2215 | (instance->adapter_type != MFI_SERIES)) { |
|---|
| 2082 | | - writel(MFI_STOP_ADP, &instance->reg_set->doorbell); |
|---|
| 2083 | | - /* Flush */ |
|---|
| 2084 | | - readl(&instance->reg_set->doorbell); |
|---|
| 2216 | + if (!instance->requestorId) { |
|---|
| 2217 | + writel(MFI_STOP_ADP, &instance->reg_set->doorbell); |
|---|
| 2218 | + /* Flush */ |
|---|
| 2219 | + readl(&instance->reg_set->doorbell); |
|---|
| 2220 | + } |
|---|
| 2085 | 2221 | if (instance->requestorId && instance->peerIsPresent) |
|---|
| 2086 | 2222 | memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); |
|---|
| 2087 | 2223 | } else { |
|---|
| .. | .. |
|---|
| 2191 | 2327 | static void |
|---|
| 2192 | 2328 | process_fw_state_change_wq(struct work_struct *work); |
|---|
| 2193 | 2329 | |
|---|
| 2194 | | -void megasas_do_ocr(struct megasas_instance *instance) |
|---|
| 2330 | +static void megasas_do_ocr(struct megasas_instance *instance) |
|---|
| 2195 | 2331 | { |
|---|
| 2196 | 2332 | if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) || |
|---|
| 2197 | 2333 | (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) || |
|---|
| .. | .. |
|---|
| 2240 | 2376 | sizeof(struct MR_LD_VF_AFFILIATION_111)); |
|---|
| 2241 | 2377 | else { |
|---|
| 2242 | 2378 | new_affiliation_111 = |
|---|
| 2243 | | - pci_zalloc_consistent(instance->pdev, |
|---|
| 2244 | | - sizeof(struct MR_LD_VF_AFFILIATION_111), |
|---|
| 2245 | | - &new_affiliation_111_h); |
|---|
| 2379 | + dma_alloc_coherent(&instance->pdev->dev, |
|---|
| 2380 | + sizeof(struct MR_LD_VF_AFFILIATION_111), |
|---|
| 2381 | + &new_affiliation_111_h, GFP_KERNEL); |
|---|
| 2246 | 2382 | if (!new_affiliation_111) { |
|---|
| 2247 | 2383 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate " |
|---|
| 2248 | 2384 | "memory for new affiliation for scsi%d\n", |
|---|
| .. | .. |
|---|
| 2302 | 2438 | } |
|---|
| 2303 | 2439 | out: |
|---|
| 2304 | 2440 | if (new_affiliation_111) { |
|---|
| 2305 | | - pci_free_consistent(instance->pdev, |
|---|
| 2441 | + dma_free_coherent(&instance->pdev->dev, |
|---|
| 2306 | 2442 | sizeof(struct MR_LD_VF_AFFILIATION_111), |
|---|
| 2307 | 2443 | new_affiliation_111, |
|---|
| 2308 | 2444 | new_affiliation_111_h); |
|---|
| .. | .. |
|---|
| 2347 | 2483 | sizeof(struct MR_LD_VF_AFFILIATION)); |
|---|
| 2348 | 2484 | else { |
|---|
| 2349 | 2485 | new_affiliation = |
|---|
| 2350 | | - pci_zalloc_consistent(instance->pdev, |
|---|
| 2351 | | - (MAX_LOGICAL_DRIVES + 1) * |
|---|
| 2352 | | - sizeof(struct MR_LD_VF_AFFILIATION), |
|---|
| 2353 | | - &new_affiliation_h); |
|---|
| 2486 | + dma_alloc_coherent(&instance->pdev->dev, |
|---|
| 2487 | + (MAX_LOGICAL_DRIVES + 1) * sizeof(struct MR_LD_VF_AFFILIATION), |
|---|
| 2488 | + &new_affiliation_h, GFP_KERNEL); |
|---|
| 2354 | 2489 | if (!new_affiliation) { |
|---|
| 2355 | 2490 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate " |
|---|
| 2356 | 2491 | "memory for new affiliation for scsi%d\n", |
|---|
| .. | .. |
|---|
| 2470 | 2605 | } |
|---|
| 2471 | 2606 | |
|---|
| 2472 | 2607 | if (new_affiliation) |
|---|
| 2473 | | - pci_free_consistent(instance->pdev, |
|---|
| 2608 | + dma_free_coherent(&instance->pdev->dev, |
|---|
| 2474 | 2609 | (MAX_LOGICAL_DRIVES + 1) * |
|---|
| 2475 | 2610 | sizeof(struct MR_LD_VF_AFFILIATION), |
|---|
| 2476 | 2611 | new_affiliation, new_affiliation_h); |
|---|
| .. | .. |
|---|
| 2513 | 2648 | |
|---|
| 2514 | 2649 | if (initial) { |
|---|
| 2515 | 2650 | instance->hb_host_mem = |
|---|
| 2516 | | - pci_zalloc_consistent(instance->pdev, |
|---|
| 2517 | | - sizeof(struct MR_CTRL_HB_HOST_MEM), |
|---|
| 2518 | | - &instance->hb_host_mem_h); |
|---|
| 2651 | + dma_alloc_coherent(&instance->pdev->dev, |
|---|
| 2652 | + sizeof(struct MR_CTRL_HB_HOST_MEM), |
|---|
| 2653 | + &instance->hb_host_mem_h, |
|---|
| 2654 | + GFP_KERNEL); |
|---|
| 2519 | 2655 | if (!instance->hb_host_mem) { |
|---|
| 2520 | 2656 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate" |
|---|
| 2521 | 2657 | " memory for heartbeat host memory for scsi%d\n", |
|---|
| .. | .. |
|---|
| 2646 | 2782 | "reset queue\n", |
|---|
| 2647 | 2783 | reset_cmd); |
|---|
| 2648 | 2784 | |
|---|
| 2649 | | - reset_cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; |
|---|
| 2785 | + reset_cmd->cmd_status_drv = DCMD_INIT; |
|---|
| 2650 | 2786 | instance->instancet->fire_cmd(instance, |
|---|
| 2651 | 2787 | reset_cmd->frame_phys_addr, |
|---|
| 2652 | 2788 | 0, instance->reg_set); |
|---|
| .. | .. |
|---|
| 2682 | 2818 | |
|---|
| 2683 | 2819 | i = 0; |
|---|
| 2684 | 2820 | outstanding = atomic_read(&instance->fw_outstanding); |
|---|
| 2685 | | - fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK; |
|---|
| 2821 | + fw_state = instance->instancet->read_fw_status_reg(instance) & MFI_STATE_MASK; |
|---|
| 2686 | 2822 | |
|---|
| 2687 | 2823 | if ((!outstanding && (fw_state == MFI_STATE_OPERATIONAL))) |
|---|
| 2688 | 2824 | goto no_outstanding; |
|---|
| .. | .. |
|---|
| 2692 | 2828 | do { |
|---|
| 2693 | 2829 | if ((fw_state == MFI_STATE_FAULT) || atomic_read(&instance->fw_outstanding)) { |
|---|
| 2694 | 2830 | dev_info(&instance->pdev->dev, |
|---|
| 2695 | | - "%s:%d waiting_for_outstanding: before issue OCR. FW state = 0x%x, oustanding 0x%x\n", |
|---|
| 2831 | + "%s:%d waiting_for_outstanding: before issue OCR. FW state = 0x%x, outstanding 0x%x\n", |
|---|
| 2696 | 2832 | __func__, __LINE__, fw_state, atomic_read(&instance->fw_outstanding)); |
|---|
| 2697 | 2833 | if (i == 3) |
|---|
| 2698 | 2834 | goto kill_hba_and_failed; |
|---|
| .. | .. |
|---|
| 2711 | 2847 | |
|---|
| 2712 | 2848 | outstanding = atomic_read(&instance->fw_outstanding); |
|---|
| 2713 | 2849 | |
|---|
| 2714 | | - fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK; |
|---|
| 2850 | + fw_state = instance->instancet->read_fw_status_reg(instance) & MFI_STATE_MASK; |
|---|
| 2715 | 2851 | if ((!outstanding && (fw_state == MFI_STATE_OPERATIONAL))) |
|---|
| 2716 | 2852 | goto no_outstanding; |
|---|
| 2717 | 2853 | } |
|---|
| .. | .. |
|---|
| 2802 | 2938 | } |
|---|
| 2803 | 2939 | |
|---|
| 2804 | 2940 | /** |
|---|
| 2805 | | - * megasas_dump_frame - This function will dump MPT/MFI frame |
|---|
| 2941 | + * megasas_dump - This function will print hexdump of provided buffer. |
|---|
| 2942 | + * @buf: Buffer to be dumped |
|---|
| 2943 | + * @sz: Size in bytes |
|---|
| 2944 | + * @format: Different formats of dumping e.g. format=n will |
|---|
| 2945 | + * cause only 'n' 32 bit words to be dumped in a single |
|---|
| 2946 | + * line. |
|---|
| 2806 | 2947 | */ |
|---|
| 2807 | | -static inline void |
|---|
| 2808 | | -megasas_dump_frame(void *mpi_request, int sz) |
|---|
| 2948 | +inline void |
|---|
| 2949 | +megasas_dump(void *buf, int sz, int format) |
|---|
| 2809 | 2950 | { |
|---|
| 2810 | 2951 | int i; |
|---|
| 2811 | | - __le32 *mfp = (__le32 *)mpi_request; |
|---|
| 2952 | + __le32 *buf_loc = (__le32 *)buf; |
|---|
| 2812 | 2953 | |
|---|
| 2813 | | - printk(KERN_INFO "IO request frame:\n\t"); |
|---|
| 2814 | | - for (i = 0; i < sz / sizeof(__le32); i++) { |
|---|
| 2815 | | - if (i && ((i % 8) == 0)) |
|---|
| 2816 | | - printk("\n\t"); |
|---|
| 2817 | | - printk("%08x ", le32_to_cpu(mfp[i])); |
|---|
| 2954 | + for (i = 0; i < (sz / sizeof(__le32)); i++) { |
|---|
| 2955 | + if ((i % format) == 0) { |
|---|
| 2956 | + if (i != 0) |
|---|
| 2957 | + printk(KERN_CONT "\n"); |
|---|
| 2958 | + printk(KERN_CONT "%08x: ", (i * 4)); |
|---|
| 2959 | + } |
|---|
| 2960 | + printk(KERN_CONT "%08x ", le32_to_cpu(buf_loc[i])); |
|---|
| 2818 | 2961 | } |
|---|
| 2819 | | - printk("\n"); |
|---|
| 2962 | + printk(KERN_CONT "\n"); |
|---|
| 2963 | +} |
|---|
| 2964 | + |
|---|
| 2965 | +/** |
|---|
| 2966 | + * megasas_dump_reg_set - This function will print hexdump of register set |
|---|
| 2967 | + * @reg_set: Register set to be dumped |
|---|
| 2968 | + */ |
|---|
| 2969 | +inline void |
|---|
| 2970 | +megasas_dump_reg_set(void __iomem *reg_set) |
|---|
| 2971 | +{ |
|---|
| 2972 | + unsigned int i, sz = 256; |
|---|
| 2973 | + u32 __iomem *reg = (u32 __iomem *)reg_set; |
|---|
| 2974 | + |
|---|
| 2975 | + for (i = 0; i < (sz / sizeof(u32)); i++) |
|---|
| 2976 | + printk("%08x: %08x\n", (i * 4), readl(®[i])); |
|---|
| 2977 | +} |
|---|
| 2978 | + |
|---|
| 2979 | +/** |
|---|
| 2980 | + * megasas_dump_fusion_io - This function will print key details |
|---|
| 2981 | + * of SCSI IO |
|---|
| 2982 | + * @scmd: SCSI command pointer of SCSI IO |
|---|
| 2983 | + */ |
|---|
| 2984 | +void |
|---|
| 2985 | +megasas_dump_fusion_io(struct scsi_cmnd *scmd) |
|---|
| 2986 | +{ |
|---|
| 2987 | + struct megasas_cmd_fusion *cmd; |
|---|
| 2988 | + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; |
|---|
| 2989 | + struct megasas_instance *instance; |
|---|
| 2990 | + |
|---|
| 2991 | + cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr; |
|---|
| 2992 | + instance = (struct megasas_instance *)scmd->device->host->hostdata; |
|---|
| 2993 | + |
|---|
| 2994 | + scmd_printk(KERN_INFO, scmd, |
|---|
| 2995 | + "scmd: (0x%p) retries: 0x%x allowed: 0x%x\n", |
|---|
| 2996 | + scmd, scmd->retries, scmd->allowed); |
|---|
| 2997 | + scsi_print_command(scmd); |
|---|
| 2998 | + |
|---|
| 2999 | + if (cmd) { |
|---|
| 3000 | + req_desc = (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)cmd->request_desc; |
|---|
| 3001 | + scmd_printk(KERN_INFO, scmd, "Request descriptor details:\n"); |
|---|
| 3002 | + scmd_printk(KERN_INFO, scmd, |
|---|
| 3003 | + "RequestFlags:0x%x MSIxIndex:0x%x SMID:0x%x LMID:0x%x DevHandle:0x%x\n", |
|---|
| 3004 | + req_desc->SCSIIO.RequestFlags, |
|---|
| 3005 | + req_desc->SCSIIO.MSIxIndex, req_desc->SCSIIO.SMID, |
|---|
| 3006 | + req_desc->SCSIIO.LMID, req_desc->SCSIIO.DevHandle); |
|---|
| 3007 | + |
|---|
| 3008 | + printk(KERN_INFO "IO request frame:\n"); |
|---|
| 3009 | + megasas_dump(cmd->io_request, |
|---|
| 3010 | + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE, 8); |
|---|
| 3011 | + printk(KERN_INFO "Chain frame:\n"); |
|---|
| 3012 | + megasas_dump(cmd->sg_frame, |
|---|
| 3013 | + instance->max_chain_frame_sz, 8); |
|---|
| 3014 | + } |
|---|
| 3015 | + |
|---|
| 3016 | +} |
|---|
| 3017 | + |
|---|
| 3018 | +/* |
|---|
| 3019 | + * megasas_dump_sys_regs - This function will dump system registers through |
|---|
| 3020 | + * sysfs. |
|---|
| 3021 | + * @reg_set: Pointer to System register set. |
|---|
| 3022 | + * @buf: Buffer to which output is to be written. |
|---|
| 3023 | + * @return: Number of bytes written to buffer. |
|---|
| 3024 | + */ |
|---|
| 3025 | +static inline ssize_t |
|---|
| 3026 | +megasas_dump_sys_regs(void __iomem *reg_set, char *buf) |
|---|
| 3027 | +{ |
|---|
| 3028 | + unsigned int i, sz = 256; |
|---|
| 3029 | + int bytes_wrote = 0; |
|---|
| 3030 | + char *loc = (char *)buf; |
|---|
| 3031 | + u32 __iomem *reg = (u32 __iomem *)reg_set; |
|---|
| 3032 | + |
|---|
| 3033 | + for (i = 0; i < sz / sizeof(u32); i++) { |
|---|
| 3034 | + bytes_wrote += scnprintf(loc + bytes_wrote, |
|---|
| 3035 | + PAGE_SIZE - bytes_wrote, |
|---|
| 3036 | + "%08x: %08x\n", (i * 4), |
|---|
| 3037 | + readl(®[i])); |
|---|
| 3038 | + } |
|---|
| 3039 | + return bytes_wrote; |
|---|
| 2820 | 3040 | } |
|---|
| 2821 | 3041 | |
|---|
| 2822 | 3042 | /** |
|---|
| 2823 | 3043 | * megasas_reset_bus_host - Bus & host reset handler entry point |
|---|
| 3044 | + * @scmd: Mid-layer SCSI command |
|---|
| 2824 | 3045 | */ |
|---|
| 2825 | 3046 | static int megasas_reset_bus_host(struct scsi_cmnd *scmd) |
|---|
| 2826 | 3047 | { |
|---|
| .. | .. |
|---|
| 2830 | 3051 | instance = (struct megasas_instance *)scmd->device->host->hostdata; |
|---|
| 2831 | 3052 | |
|---|
| 2832 | 3053 | scmd_printk(KERN_INFO, scmd, |
|---|
| 2833 | | - "Controller reset is requested due to IO timeout\n" |
|---|
| 2834 | | - "SCSI command pointer: (%p)\t SCSI host state: %d\t" |
|---|
| 2835 | | - " SCSI host busy: %d\t FW outstanding: %d\n", |
|---|
| 2836 | | - scmd, scmd->device->host->shost_state, |
|---|
| 3054 | + "OCR is requested due to IO timeout!!\n"); |
|---|
| 3055 | + |
|---|
| 3056 | + scmd_printk(KERN_INFO, scmd, |
|---|
| 3057 | + "SCSI host state: %d SCSI host busy: %d FW outstanding: %d\n", |
|---|
| 3058 | + scmd->device->host->shost_state, |
|---|
| 2837 | 3059 | scsi_host_busy(scmd->device->host), |
|---|
| 2838 | 3060 | atomic_read(&instance->fw_outstanding)); |
|---|
| 2839 | | - |
|---|
| 2840 | 3061 | /* |
|---|
| 2841 | 3062 | * First wait for all commands to complete |
|---|
| 2842 | 3063 | */ |
|---|
| 2843 | 3064 | if (instance->adapter_type == MFI_SERIES) { |
|---|
| 2844 | 3065 | ret = megasas_generic_reset(scmd); |
|---|
| 2845 | 3066 | } else { |
|---|
| 2846 | | - struct megasas_cmd_fusion *cmd; |
|---|
| 2847 | | - cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr; |
|---|
| 2848 | | - if (cmd) |
|---|
| 2849 | | - megasas_dump_frame(cmd->io_request, |
|---|
| 2850 | | - MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE); |
|---|
| 3067 | + megasas_dump_fusion_io(scmd); |
|---|
| 2851 | 3068 | ret = megasas_reset_fusion(scmd->device->host, |
|---|
| 2852 | 3069 | SCSIIO_TIMEOUT_OCR); |
|---|
| 2853 | 3070 | } |
|---|
| .. | .. |
|---|
| 2997 | 3214 | } |
|---|
| 2998 | 3215 | |
|---|
| 2999 | 3216 | static ssize_t |
|---|
| 3000 | | -megasas_fw_crash_buffer_store(struct device *cdev, |
|---|
| 3217 | +fw_crash_buffer_store(struct device *cdev, |
|---|
| 3001 | 3218 | struct device_attribute *attr, const char *buf, size_t count) |
|---|
| 3002 | 3219 | { |
|---|
| 3003 | 3220 | struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| .. | .. |
|---|
| 3016 | 3233 | } |
|---|
| 3017 | 3234 | |
|---|
| 3018 | 3235 | static ssize_t |
|---|
| 3019 | | -megasas_fw_crash_buffer_show(struct device *cdev, |
|---|
| 3236 | +fw_crash_buffer_show(struct device *cdev, |
|---|
| 3020 | 3237 | struct device_attribute *attr, char *buf) |
|---|
| 3021 | 3238 | { |
|---|
| 3022 | 3239 | struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| 3023 | 3240 | struct megasas_instance *instance = |
|---|
| 3024 | 3241 | (struct megasas_instance *) shost->hostdata; |
|---|
| 3025 | 3242 | u32 size; |
|---|
| 3026 | | - unsigned long buff_addr; |
|---|
| 3027 | 3243 | unsigned long dmachunk = CRASH_DMA_BUF_SIZE; |
|---|
| 3028 | 3244 | unsigned long chunk_left_bytes; |
|---|
| 3029 | 3245 | unsigned long src_addr; |
|---|
| .. | .. |
|---|
| 3040 | 3256 | spin_unlock_irqrestore(&instance->crashdump_lock, flags); |
|---|
| 3041 | 3257 | return -EINVAL; |
|---|
| 3042 | 3258 | } |
|---|
| 3043 | | - |
|---|
| 3044 | | - buff_addr = (unsigned long) buf; |
|---|
| 3045 | 3259 | |
|---|
| 3046 | 3260 | if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) { |
|---|
| 3047 | 3261 | dev_err(&instance->pdev->dev, |
|---|
| .. | .. |
|---|
| 3064 | 3278 | } |
|---|
| 3065 | 3279 | |
|---|
| 3066 | 3280 | static ssize_t |
|---|
| 3067 | | -megasas_fw_crash_buffer_size_show(struct device *cdev, |
|---|
| 3281 | +fw_crash_buffer_size_show(struct device *cdev, |
|---|
| 3068 | 3282 | struct device_attribute *attr, char *buf) |
|---|
| 3069 | 3283 | { |
|---|
| 3070 | 3284 | struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| .. | .. |
|---|
| 3076 | 3290 | } |
|---|
| 3077 | 3291 | |
|---|
| 3078 | 3292 | static ssize_t |
|---|
| 3079 | | -megasas_fw_crash_state_store(struct device *cdev, |
|---|
| 3293 | +fw_crash_state_store(struct device *cdev, |
|---|
| 3080 | 3294 | struct device_attribute *attr, const char *buf, size_t count) |
|---|
| 3081 | 3295 | { |
|---|
| 3082 | 3296 | struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| .. | .. |
|---|
| 3111 | 3325 | } |
|---|
| 3112 | 3326 | |
|---|
| 3113 | 3327 | static ssize_t |
|---|
| 3114 | | -megasas_fw_crash_state_show(struct device *cdev, |
|---|
| 3328 | +fw_crash_state_show(struct device *cdev, |
|---|
| 3115 | 3329 | struct device_attribute *attr, char *buf) |
|---|
| 3116 | 3330 | { |
|---|
| 3117 | 3331 | struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| .. | .. |
|---|
| 3122 | 3336 | } |
|---|
| 3123 | 3337 | |
|---|
| 3124 | 3338 | static ssize_t |
|---|
| 3125 | | -megasas_page_size_show(struct device *cdev, |
|---|
| 3339 | +page_size_show(struct device *cdev, |
|---|
| 3126 | 3340 | struct device_attribute *attr, char *buf) |
|---|
| 3127 | 3341 | { |
|---|
| 3128 | 3342 | return snprintf(buf, PAGE_SIZE, "%ld\n", (unsigned long)PAGE_SIZE - 1); |
|---|
| 3129 | 3343 | } |
|---|
| 3130 | 3344 | |
|---|
| 3131 | 3345 | static ssize_t |
|---|
| 3132 | | -megasas_ldio_outstanding_show(struct device *cdev, struct device_attribute *attr, |
|---|
| 3346 | +ldio_outstanding_show(struct device *cdev, struct device_attribute *attr, |
|---|
| 3133 | 3347 | char *buf) |
|---|
| 3134 | 3348 | { |
|---|
| 3135 | 3349 | struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| .. | .. |
|---|
| 3139 | 3353 | } |
|---|
| 3140 | 3354 | |
|---|
| 3141 | 3355 | static ssize_t |
|---|
| 3142 | | -megasas_fw_cmds_outstanding_show(struct device *cdev, |
|---|
| 3356 | +fw_cmds_outstanding_show(struct device *cdev, |
|---|
| 3143 | 3357 | struct device_attribute *attr, char *buf) |
|---|
| 3144 | 3358 | { |
|---|
| 3145 | 3359 | struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| .. | .. |
|---|
| 3148 | 3362 | return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&instance->fw_outstanding)); |
|---|
| 3149 | 3363 | } |
|---|
| 3150 | 3364 | |
|---|
| 3151 | | -static DEVICE_ATTR(fw_crash_buffer, S_IRUGO | S_IWUSR, |
|---|
| 3152 | | - megasas_fw_crash_buffer_show, megasas_fw_crash_buffer_store); |
|---|
| 3153 | | -static DEVICE_ATTR(fw_crash_buffer_size, S_IRUGO, |
|---|
| 3154 | | - megasas_fw_crash_buffer_size_show, NULL); |
|---|
| 3155 | | -static DEVICE_ATTR(fw_crash_state, S_IRUGO | S_IWUSR, |
|---|
| 3156 | | - megasas_fw_crash_state_show, megasas_fw_crash_state_store); |
|---|
| 3157 | | -static DEVICE_ATTR(page_size, S_IRUGO, |
|---|
| 3158 | | - megasas_page_size_show, NULL); |
|---|
| 3159 | | -static DEVICE_ATTR(ldio_outstanding, S_IRUGO, |
|---|
| 3160 | | - megasas_ldio_outstanding_show, NULL); |
|---|
| 3161 | | -static DEVICE_ATTR(fw_cmds_outstanding, S_IRUGO, |
|---|
| 3162 | | - megasas_fw_cmds_outstanding_show, NULL); |
|---|
| 3365 | +static ssize_t |
|---|
| 3366 | +enable_sdev_max_qd_show(struct device *cdev, |
|---|
| 3367 | + struct device_attribute *attr, char *buf) |
|---|
| 3368 | +{ |
|---|
| 3369 | + struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| 3370 | + struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata; |
|---|
| 3163 | 3371 | |
|---|
| 3164 | | -struct device_attribute *megaraid_host_attrs[] = { |
|---|
| 3372 | + return snprintf(buf, PAGE_SIZE, "%d\n", instance->enable_sdev_max_qd); |
|---|
| 3373 | +} |
|---|
| 3374 | + |
|---|
| 3375 | +static ssize_t |
|---|
| 3376 | +enable_sdev_max_qd_store(struct device *cdev, |
|---|
| 3377 | + struct device_attribute *attr, const char *buf, size_t count) |
|---|
| 3378 | +{ |
|---|
| 3379 | + struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| 3380 | + struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata; |
|---|
| 3381 | + u32 val = 0; |
|---|
| 3382 | + bool is_target_prop; |
|---|
| 3383 | + int ret_target_prop = DCMD_FAILED; |
|---|
| 3384 | + struct scsi_device *sdev; |
|---|
| 3385 | + |
|---|
| 3386 | + if (kstrtou32(buf, 0, &val) != 0) { |
|---|
| 3387 | + pr_err("megasas: could not set enable_sdev_max_qd\n"); |
|---|
| 3388 | + return -EINVAL; |
|---|
| 3389 | + } |
|---|
| 3390 | + |
|---|
| 3391 | + mutex_lock(&instance->reset_mutex); |
|---|
| 3392 | + if (val) |
|---|
| 3393 | + instance->enable_sdev_max_qd = true; |
|---|
| 3394 | + else |
|---|
| 3395 | + instance->enable_sdev_max_qd = false; |
|---|
| 3396 | + |
|---|
| 3397 | + shost_for_each_device(sdev, shost) { |
|---|
| 3398 | + ret_target_prop = megasas_get_target_prop(instance, sdev); |
|---|
| 3399 | + is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false; |
|---|
| 3400 | + megasas_set_fw_assisted_qd(sdev, is_target_prop); |
|---|
| 3401 | + } |
|---|
| 3402 | + mutex_unlock(&instance->reset_mutex); |
|---|
| 3403 | + |
|---|
| 3404 | + return strlen(buf); |
|---|
| 3405 | +} |
|---|
| 3406 | + |
|---|
| 3407 | +static ssize_t |
|---|
| 3408 | +dump_system_regs_show(struct device *cdev, |
|---|
| 3409 | + struct device_attribute *attr, char *buf) |
|---|
| 3410 | +{ |
|---|
| 3411 | + struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| 3412 | + struct megasas_instance *instance = |
|---|
| 3413 | + (struct megasas_instance *)shost->hostdata; |
|---|
| 3414 | + |
|---|
| 3415 | + return megasas_dump_sys_regs(instance->reg_set, buf); |
|---|
| 3416 | +} |
|---|
| 3417 | + |
|---|
| 3418 | +static ssize_t |
|---|
| 3419 | +raid_map_id_show(struct device *cdev, struct device_attribute *attr, |
|---|
| 3420 | + char *buf) |
|---|
| 3421 | +{ |
|---|
| 3422 | + struct Scsi_Host *shost = class_to_shost(cdev); |
|---|
| 3423 | + struct megasas_instance *instance = |
|---|
| 3424 | + (struct megasas_instance *)shost->hostdata; |
|---|
| 3425 | + |
|---|
| 3426 | + return snprintf(buf, PAGE_SIZE, "%ld\n", |
|---|
| 3427 | + (unsigned long)instance->map_id); |
|---|
| 3428 | +} |
|---|
| 3429 | + |
|---|
| 3430 | +static DEVICE_ATTR_RW(fw_crash_buffer); |
|---|
| 3431 | +static DEVICE_ATTR_RO(fw_crash_buffer_size); |
|---|
| 3432 | +static DEVICE_ATTR_RW(fw_crash_state); |
|---|
| 3433 | +static DEVICE_ATTR_RO(page_size); |
|---|
| 3434 | +static DEVICE_ATTR_RO(ldio_outstanding); |
|---|
| 3435 | +static DEVICE_ATTR_RO(fw_cmds_outstanding); |
|---|
| 3436 | +static DEVICE_ATTR_RW(enable_sdev_max_qd); |
|---|
| 3437 | +static DEVICE_ATTR_RO(dump_system_regs); |
|---|
| 3438 | +static DEVICE_ATTR_RO(raid_map_id); |
|---|
| 3439 | + |
|---|
| 3440 | +static struct device_attribute *megaraid_host_attrs[] = { |
|---|
| 3165 | 3441 | &dev_attr_fw_crash_buffer_size, |
|---|
| 3166 | 3442 | &dev_attr_fw_crash_buffer, |
|---|
| 3167 | 3443 | &dev_attr_fw_crash_state, |
|---|
| 3168 | 3444 | &dev_attr_page_size, |
|---|
| 3169 | 3445 | &dev_attr_ldio_outstanding, |
|---|
| 3170 | 3446 | &dev_attr_fw_cmds_outstanding, |
|---|
| 3447 | + &dev_attr_enable_sdev_max_qd, |
|---|
| 3448 | + &dev_attr_dump_system_regs, |
|---|
| 3449 | + &dev_attr_raid_map_id, |
|---|
| 3171 | 3450 | NULL, |
|---|
| 3172 | 3451 | }; |
|---|
| 3173 | 3452 | |
|---|
| .. | .. |
|---|
| 3189 | 3468 | .eh_timed_out = megasas_reset_timer, |
|---|
| 3190 | 3469 | .shost_attrs = megaraid_host_attrs, |
|---|
| 3191 | 3470 | .bios_param = megasas_bios_param, |
|---|
| 3192 | | - .use_clustering = ENABLE_CLUSTERING, |
|---|
| 3193 | 3471 | .change_queue_depth = scsi_change_queue_depth, |
|---|
| 3194 | | - .no_write_same = 1, |
|---|
| 3472 | + .max_segment_size = 0xffffffff, |
|---|
| 3195 | 3473 | }; |
|---|
| 3196 | 3474 | |
|---|
| 3197 | 3475 | /** |
|---|
| .. | .. |
|---|
| 3207 | 3485 | megasas_complete_int_cmd(struct megasas_instance *instance, |
|---|
| 3208 | 3486 | struct megasas_cmd *cmd) |
|---|
| 3209 | 3487 | { |
|---|
| 3210 | | - cmd->cmd_status_drv = cmd->frame->io.cmd_status; |
|---|
| 3488 | + if (cmd->cmd_status_drv == DCMD_INIT) |
|---|
| 3489 | + cmd->cmd_status_drv = |
|---|
| 3490 | + (cmd->frame->io.cmd_status == MFI_STAT_OK) ? |
|---|
| 3491 | + DCMD_SUCCESS : DCMD_FAILED; |
|---|
| 3492 | + |
|---|
| 3211 | 3493 | wake_up(&instance->int_cmd_wait_q); |
|---|
| 3212 | 3494 | } |
|---|
| 3213 | 3495 | |
|---|
| .. | .. |
|---|
| 3226 | 3508 | { |
|---|
| 3227 | 3509 | if (cmd->sync_cmd) { |
|---|
| 3228 | 3510 | cmd->sync_cmd = 0; |
|---|
| 3229 | | - cmd->cmd_status_drv = 0; |
|---|
| 3511 | + cmd->cmd_status_drv = DCMD_SUCCESS; |
|---|
| 3230 | 3512 | wake_up(&instance->abort_cmd_wait_q); |
|---|
| 3513 | + } |
|---|
| 3514 | +} |
|---|
| 3515 | + |
|---|
| 3516 | +static void |
|---|
| 3517 | +megasas_set_ld_removed_by_fw(struct megasas_instance *instance) |
|---|
| 3518 | +{ |
|---|
| 3519 | + uint i; |
|---|
| 3520 | + |
|---|
| 3521 | + for (i = 0; (i < MEGASAS_MAX_LD_IDS); i++) { |
|---|
| 3522 | + if (instance->ld_ids_prev[i] != 0xff && |
|---|
| 3523 | + instance->ld_ids_from_raidmap[i] == 0xff) { |
|---|
| 3524 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 3525 | + dev_info(&instance->pdev->dev, |
|---|
| 3526 | + "LD target ID %d removed from RAID map\n", i); |
|---|
| 3527 | + instance->ld_tgtid_status[i] = LD_TARGET_ID_DELETED; |
|---|
| 3528 | + } |
|---|
| 3231 | 3529 | } |
|---|
| 3232 | 3530 | } |
|---|
| 3233 | 3531 | |
|---|
| .. | .. |
|---|
| 3281 | 3579 | megasas_complete_int_cmd(instance, cmd); |
|---|
| 3282 | 3580 | break; |
|---|
| 3283 | 3581 | } |
|---|
| 3582 | + fallthrough; |
|---|
| 3284 | 3583 | |
|---|
| 3285 | 3584 | case MFI_CMD_LD_READ: |
|---|
| 3286 | 3585 | case MFI_CMD_LD_WRITE: |
|---|
| .. | .. |
|---|
| 3351 | 3650 | case MFI_CMD_SMP: |
|---|
| 3352 | 3651 | case MFI_CMD_STP: |
|---|
| 3353 | 3652 | case MFI_CMD_NVME: |
|---|
| 3653 | + case MFI_CMD_TOOLBOX: |
|---|
| 3354 | 3654 | megasas_complete_int_cmd(instance, cmd); |
|---|
| 3355 | 3655 | break; |
|---|
| 3356 | 3656 | |
|---|
| .. | .. |
|---|
| 3391 | 3691 | fusion->fast_path_io = 0; |
|---|
| 3392 | 3692 | } |
|---|
| 3393 | 3693 | |
|---|
| 3694 | + if (instance->adapter_type >= INVADER_SERIES) |
|---|
| 3695 | + megasas_set_ld_removed_by_fw(instance); |
|---|
| 3696 | + |
|---|
| 3394 | 3697 | megasas_sync_map_info(instance); |
|---|
| 3395 | 3698 | spin_unlock_irqrestore(instance->host->host_lock, |
|---|
| 3396 | 3699 | flags); |
|---|
| 3700 | + |
|---|
| 3397 | 3701 | break; |
|---|
| 3398 | 3702 | } |
|---|
| 3399 | 3703 | if (opcode == MR_DCMD_CTRL_EVENT_GET_INFO || |
|---|
| .. | .. |
|---|
| 3500 | 3804 | dev_notice(&instance->pdev->dev, "%p synchronous cmd" |
|---|
| 3501 | 3805 | "on the internal reset queue," |
|---|
| 3502 | 3806 | "issue it again.\n", cmd); |
|---|
| 3503 | | - cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; |
|---|
| 3807 | + cmd->cmd_status_drv = DCMD_INIT; |
|---|
| 3504 | 3808 | instance->instancet->fire_cmd(instance, |
|---|
| 3505 | 3809 | cmd->frame_phys_addr, |
|---|
| 3506 | 3810 | 0, instance->reg_set); |
|---|
| .. | .. |
|---|
| 3538 | 3842 | megasas_register_aen(instance, seq_num, class_locale.word); |
|---|
| 3539 | 3843 | } |
|---|
| 3540 | 3844 | |
|---|
| 3541 | | -/** |
|---|
| 3845 | +/* |
|---|
| 3542 | 3846 | * Move the internal reset pending commands to a deferred queue. |
|---|
| 3543 | 3847 | * |
|---|
| 3544 | 3848 | * We move the commands pending at internal reset time to a |
|---|
| .. | .. |
|---|
| 3546 | 3850 | * completion of the internal reset sequence. if the internal reset |
|---|
| 3547 | 3851 | * did not complete in time, the kernel reset handler would flush |
|---|
| 3548 | 3852 | * these commands. |
|---|
| 3549 | | - **/ |
|---|
| 3853 | + */ |
|---|
| 3550 | 3854 | static void |
|---|
| 3551 | 3855 | megasas_internal_reset_defer_cmds(struct megasas_instance *instance) |
|---|
| 3552 | 3856 | { |
|---|
| .. | .. |
|---|
| 3668 | 3972 | return IRQ_HANDLED; |
|---|
| 3669 | 3973 | } |
|---|
| 3670 | 3974 | |
|---|
| 3671 | | - if ((mfiStatus = instance->instancet->clear_intr( |
|---|
| 3672 | | - instance->reg_set) |
|---|
| 3673 | | - ) == 0) { |
|---|
| 3975 | + mfiStatus = instance->instancet->clear_intr(instance); |
|---|
| 3976 | + if (mfiStatus == 0) { |
|---|
| 3674 | 3977 | /* Hardware may not set outbound_intr_status in MSI-X mode */ |
|---|
| 3675 | 3978 | if (!instance->msix_vectors) |
|---|
| 3676 | 3979 | return IRQ_NONE; |
|---|
| .. | .. |
|---|
| 3680 | 3983 | |
|---|
| 3681 | 3984 | if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) { |
|---|
| 3682 | 3985 | fw_state = instance->instancet->read_fw_status_reg( |
|---|
| 3683 | | - instance->reg_set) & MFI_STATE_MASK; |
|---|
| 3986 | + instance) & MFI_STATE_MASK; |
|---|
| 3684 | 3987 | |
|---|
| 3685 | 3988 | if (fw_state != MFI_STATE_FAULT) { |
|---|
| 3686 | 3989 | dev_notice(&instance->pdev->dev, "fw state:%x\n", |
|---|
| .. | .. |
|---|
| 3725 | 4028 | tasklet_schedule(&instance->isr_tasklet); |
|---|
| 3726 | 4029 | return IRQ_HANDLED; |
|---|
| 3727 | 4030 | } |
|---|
| 4031 | + |
|---|
| 3728 | 4032 | /** |
|---|
| 3729 | 4033 | * megasas_isr - isr entry point |
|---|
| 4034 | + * @irq: IRQ number |
|---|
| 4035 | + * @devp: IRQ context address |
|---|
| 3730 | 4036 | */ |
|---|
| 3731 | 4037 | static irqreturn_t megasas_isr(int irq, void *devp) |
|---|
| 3732 | 4038 | { |
|---|
| .. | .. |
|---|
| 3748 | 4054 | /** |
|---|
| 3749 | 4055 | * megasas_transition_to_ready - Move the FW to READY state |
|---|
| 3750 | 4056 | * @instance: Adapter soft state |
|---|
| 4057 | + * @ocr: Adapter reset state |
|---|
| 3751 | 4058 | * |
|---|
| 3752 | 4059 | * During the initialization, FW passes can potentially be in any one of |
|---|
| 3753 | 4060 | * several possible states. If the FW in operational, waiting-for-handshake |
|---|
| .. | .. |
|---|
| 3760 | 4067 | int i; |
|---|
| 3761 | 4068 | u8 max_wait; |
|---|
| 3762 | 4069 | u32 fw_state; |
|---|
| 3763 | | - u32 cur_state; |
|---|
| 3764 | 4070 | u32 abs_state, curr_abs_state; |
|---|
| 3765 | 4071 | |
|---|
| 3766 | | - abs_state = instance->instancet->read_fw_status_reg(instance->reg_set); |
|---|
| 4072 | + abs_state = instance->instancet->read_fw_status_reg(instance); |
|---|
| 3767 | 4073 | fw_state = abs_state & MFI_STATE_MASK; |
|---|
| 3768 | 4074 | |
|---|
| 3769 | 4075 | if (fw_state != MFI_STATE_READY) |
|---|
| .. | .. |
|---|
| 3775 | 4081 | switch (fw_state) { |
|---|
| 3776 | 4082 | |
|---|
| 3777 | 4083 | case MFI_STATE_FAULT: |
|---|
| 3778 | | - dev_printk(KERN_DEBUG, &instance->pdev->dev, "FW in FAULT state!!\n"); |
|---|
| 4084 | + dev_printk(KERN_ERR, &instance->pdev->dev, |
|---|
| 4085 | + "FW in FAULT state, Fault code:0x%x subcode:0x%x func:%s\n", |
|---|
| 4086 | + abs_state & MFI_STATE_FAULT_CODE, |
|---|
| 4087 | + abs_state & MFI_STATE_FAULT_SUBCODE, __func__); |
|---|
| 3779 | 4088 | if (ocr) { |
|---|
| 3780 | 4089 | max_wait = MEGASAS_RESET_WAIT_TIME; |
|---|
| 3781 | | - cur_state = MFI_STATE_FAULT; |
|---|
| 3782 | 4090 | break; |
|---|
| 3783 | | - } else |
|---|
| 4091 | + } else { |
|---|
| 4092 | + dev_printk(KERN_DEBUG, &instance->pdev->dev, "System Register set:\n"); |
|---|
| 4093 | + megasas_dump_reg_set(instance->reg_set); |
|---|
| 3784 | 4094 | return -ENODEV; |
|---|
| 4095 | + } |
|---|
| 3785 | 4096 | |
|---|
| 3786 | 4097 | case MFI_STATE_WAIT_HANDSHAKE: |
|---|
| 3787 | 4098 | /* |
|---|
| .. | .. |
|---|
| 3801 | 4112 | &instance->reg_set->inbound_doorbell); |
|---|
| 3802 | 4113 | |
|---|
| 3803 | 4114 | max_wait = MEGASAS_RESET_WAIT_TIME; |
|---|
| 3804 | | - cur_state = MFI_STATE_WAIT_HANDSHAKE; |
|---|
| 3805 | 4115 | break; |
|---|
| 3806 | 4116 | |
|---|
| 3807 | 4117 | case MFI_STATE_BOOT_MESSAGE_PENDING: |
|---|
| .. | .. |
|---|
| 3817 | 4127 | &instance->reg_set->inbound_doorbell); |
|---|
| 3818 | 4128 | |
|---|
| 3819 | 4129 | max_wait = MEGASAS_RESET_WAIT_TIME; |
|---|
| 3820 | | - cur_state = MFI_STATE_BOOT_MESSAGE_PENDING; |
|---|
| 3821 | 4130 | break; |
|---|
| 3822 | 4131 | |
|---|
| 3823 | 4132 | case MFI_STATE_OPERATIONAL: |
|---|
| .. | .. |
|---|
| 3835 | 4144 | |
|---|
| 3836 | 4145 | if (instance->adapter_type != MFI_SERIES) { |
|---|
| 3837 | 4146 | for (i = 0; i < (10 * 1000); i += 20) { |
|---|
| 3838 | | - if (readl( |
|---|
| 4147 | + if (megasas_readl( |
|---|
| 4148 | + instance, |
|---|
| 3839 | 4149 | &instance-> |
|---|
| 3840 | 4150 | reg_set-> |
|---|
| 3841 | 4151 | doorbell) & 1) |
|---|
| .. | .. |
|---|
| 3849 | 4159 | &instance->reg_set->inbound_doorbell); |
|---|
| 3850 | 4160 | |
|---|
| 3851 | 4161 | max_wait = MEGASAS_RESET_WAIT_TIME; |
|---|
| 3852 | | - cur_state = MFI_STATE_OPERATIONAL; |
|---|
| 3853 | 4162 | break; |
|---|
| 3854 | 4163 | |
|---|
| 3855 | 4164 | case MFI_STATE_UNDEFINED: |
|---|
| .. | .. |
|---|
| 3857 | 4166 | * This state should not last for more than 2 seconds |
|---|
| 3858 | 4167 | */ |
|---|
| 3859 | 4168 | max_wait = MEGASAS_RESET_WAIT_TIME; |
|---|
| 3860 | | - cur_state = MFI_STATE_UNDEFINED; |
|---|
| 3861 | 4169 | break; |
|---|
| 3862 | 4170 | |
|---|
| 3863 | 4171 | case MFI_STATE_BB_INIT: |
|---|
| 3864 | 4172 | max_wait = MEGASAS_RESET_WAIT_TIME; |
|---|
| 3865 | | - cur_state = MFI_STATE_BB_INIT; |
|---|
| 3866 | 4173 | break; |
|---|
| 3867 | 4174 | |
|---|
| 3868 | 4175 | case MFI_STATE_FW_INIT: |
|---|
| 3869 | 4176 | max_wait = MEGASAS_RESET_WAIT_TIME; |
|---|
| 3870 | | - cur_state = MFI_STATE_FW_INIT; |
|---|
| 3871 | 4177 | break; |
|---|
| 3872 | 4178 | |
|---|
| 3873 | 4179 | case MFI_STATE_FW_INIT_2: |
|---|
| 3874 | 4180 | max_wait = MEGASAS_RESET_WAIT_TIME; |
|---|
| 3875 | | - cur_state = MFI_STATE_FW_INIT_2; |
|---|
| 3876 | 4181 | break; |
|---|
| 3877 | 4182 | |
|---|
| 3878 | 4183 | case MFI_STATE_DEVICE_SCAN: |
|---|
| 3879 | 4184 | max_wait = MEGASAS_RESET_WAIT_TIME; |
|---|
| 3880 | | - cur_state = MFI_STATE_DEVICE_SCAN; |
|---|
| 3881 | 4185 | break; |
|---|
| 3882 | 4186 | |
|---|
| 3883 | 4187 | case MFI_STATE_FLUSH_CACHE: |
|---|
| 3884 | 4188 | max_wait = MEGASAS_RESET_WAIT_TIME; |
|---|
| 3885 | | - cur_state = MFI_STATE_FLUSH_CACHE; |
|---|
| 3886 | 4189 | break; |
|---|
| 3887 | 4190 | |
|---|
| 3888 | 4191 | default: |
|---|
| 3889 | 4192 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "Unknown state 0x%x\n", |
|---|
| 3890 | 4193 | fw_state); |
|---|
| 4194 | + dev_printk(KERN_DEBUG, &instance->pdev->dev, "System Register set:\n"); |
|---|
| 4195 | + megasas_dump_reg_set(instance->reg_set); |
|---|
| 3891 | 4196 | return -ENODEV; |
|---|
| 3892 | 4197 | } |
|---|
| 3893 | 4198 | |
|---|
| .. | .. |
|---|
| 3896 | 4201 | */ |
|---|
| 3897 | 4202 | for (i = 0; i < max_wait * 50; i++) { |
|---|
| 3898 | 4203 | curr_abs_state = instance->instancet-> |
|---|
| 3899 | | - read_fw_status_reg(instance->reg_set); |
|---|
| 4204 | + read_fw_status_reg(instance); |
|---|
| 3900 | 4205 | |
|---|
| 3901 | 4206 | if (abs_state == curr_abs_state) { |
|---|
| 3902 | 4207 | msleep(20); |
|---|
| .. | .. |
|---|
| 3910 | 4215 | if (curr_abs_state == abs_state) { |
|---|
| 3911 | 4216 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "FW state [%d] hasn't changed " |
|---|
| 3912 | 4217 | "in %d secs\n", fw_state, max_wait); |
|---|
| 4218 | + dev_printk(KERN_DEBUG, &instance->pdev->dev, "System Register set:\n"); |
|---|
| 4219 | + megasas_dump_reg_set(instance->reg_set); |
|---|
| 3913 | 4220 | return -ENODEV; |
|---|
| 3914 | 4221 | } |
|---|
| 3915 | 4222 | |
|---|
| .. | .. |
|---|
| 3973 | 4280 | { |
|---|
| 3974 | 4281 | int i; |
|---|
| 3975 | 4282 | u16 max_cmd; |
|---|
| 3976 | | - u32 sge_sz; |
|---|
| 3977 | 4283 | u32 frame_count; |
|---|
| 3978 | 4284 | struct megasas_cmd *cmd; |
|---|
| 3979 | 4285 | |
|---|
| 3980 | 4286 | max_cmd = instance->max_mfi_cmds; |
|---|
| 3981 | | - |
|---|
| 3982 | | - /* |
|---|
| 3983 | | - * Size of our frame is 64 bytes for MFI frame, followed by max SG |
|---|
| 3984 | | - * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer |
|---|
| 3985 | | - */ |
|---|
| 3986 | | - sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : |
|---|
| 3987 | | - sizeof(struct megasas_sge32); |
|---|
| 3988 | | - |
|---|
| 3989 | | - if (instance->flag_ieee) |
|---|
| 3990 | | - sge_sz = sizeof(struct megasas_sge_skinny); |
|---|
| 3991 | 4287 | |
|---|
| 3992 | 4288 | /* |
|---|
| 3993 | 4289 | * For MFI controllers. |
|---|
| .. | .. |
|---|
| 4239 | 4535 | switch (dcmd_timeout_ocr_possible(instance)) { |
|---|
| 4240 | 4536 | case INITIATE_OCR: |
|---|
| 4241 | 4537 | cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
|---|
| 4538 | + mutex_unlock(&instance->reset_mutex); |
|---|
| 4242 | 4539 | megasas_reset_fusion(instance->host, |
|---|
| 4243 | 4540 | MFI_IO_TIMEOUT_OCR); |
|---|
| 4541 | + mutex_lock(&instance->reset_mutex); |
|---|
| 4244 | 4542 | break; |
|---|
| 4245 | 4543 | case KILL_ADAPTER: |
|---|
| 4246 | 4544 | megaraid_sas_kill_hba(instance); |
|---|
| .. | .. |
|---|
| 4276 | 4574 | struct megasas_dcmd_frame *dcmd; |
|---|
| 4277 | 4575 | struct MR_PD_LIST *ci; |
|---|
| 4278 | 4576 | struct MR_PD_ADDRESS *pd_addr; |
|---|
| 4279 | | - dma_addr_t ci_h = 0; |
|---|
| 4280 | 4577 | |
|---|
| 4281 | 4578 | if (instance->pd_list_not_supported) { |
|---|
| 4282 | 4579 | dev_info(&instance->pdev->dev, "MR_DCMD_PD_LIST_QUERY " |
|---|
| .. | .. |
|---|
| 4285 | 4582 | } |
|---|
| 4286 | 4583 | |
|---|
| 4287 | 4584 | ci = instance->pd_list_buf; |
|---|
| 4288 | | - ci_h = instance->pd_list_buf_h; |
|---|
| 4289 | 4585 | |
|---|
| 4290 | 4586 | cmd = megasas_get_cmd(instance); |
|---|
| 4291 | 4587 | |
|---|
| .. | .. |
|---|
| 4358 | 4654 | |
|---|
| 4359 | 4655 | case DCMD_SUCCESS: |
|---|
| 4360 | 4656 | pd_addr = ci->addr; |
|---|
| 4657 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 4658 | + dev_info(&instance->pdev->dev, "%s, sysPD count: 0x%x\n", |
|---|
| 4659 | + __func__, le32_to_cpu(ci->count)); |
|---|
| 4361 | 4660 | |
|---|
| 4362 | 4661 | if ((le32_to_cpu(ci->count) > |
|---|
| 4363 | 4662 | (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) |
|---|
| .. | .. |
|---|
| 4373 | 4672 | pd_addr->scsiDevType; |
|---|
| 4374 | 4673 | instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveState = |
|---|
| 4375 | 4674 | MR_PD_STATE_SYSTEM; |
|---|
| 4675 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 4676 | + dev_info(&instance->pdev->dev, |
|---|
| 4677 | + "PD%d: targetID: 0x%03x deviceType:0x%x\n", |
|---|
| 4678 | + pd_index, le16_to_cpu(pd_addr->deviceId), |
|---|
| 4679 | + pd_addr->scsiDevType); |
|---|
| 4376 | 4680 | pd_addr++; |
|---|
| 4377 | 4681 | } |
|---|
| 4378 | 4682 | |
|---|
| .. | .. |
|---|
| 4476 | 4780 | break; |
|---|
| 4477 | 4781 | |
|---|
| 4478 | 4782 | case DCMD_SUCCESS: |
|---|
| 4783 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 4784 | + dev_info(&instance->pdev->dev, "%s, LD count: 0x%x\n", |
|---|
| 4785 | + __func__, ld_count); |
|---|
| 4786 | + |
|---|
| 4479 | 4787 | if (ld_count > instance->fw_supported_vd_count) |
|---|
| 4480 | 4788 | break; |
|---|
| 4481 | 4789 | |
|---|
| .. | .. |
|---|
| 4485 | 4793 | if (ci->ldList[ld_index].state != 0) { |
|---|
| 4486 | 4794 | ids = ci->ldList[ld_index].ref.targetId; |
|---|
| 4487 | 4795 | instance->ld_ids[ids] = ci->ldList[ld_index].ref.targetId; |
|---|
| 4796 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 4797 | + dev_info(&instance->pdev->dev, |
|---|
| 4798 | + "LD%d: targetID: 0x%03x\n", |
|---|
| 4799 | + ld_index, ids); |
|---|
| 4488 | 4800 | } |
|---|
| 4489 | 4801 | } |
|---|
| 4490 | 4802 | |
|---|
| .. | .. |
|---|
| 4500 | 4812 | /** |
|---|
| 4501 | 4813 | * megasas_ld_list_query - Returns FW's ld_list structure |
|---|
| 4502 | 4814 | * @instance: Adapter soft state |
|---|
| 4503 | | - * @ld_list: ld_list structure |
|---|
| 4815 | + * @query_type: ld_list structure type |
|---|
| 4504 | 4816 | * |
|---|
| 4505 | 4817 | * Issues an internal command (DCMD) to get the FW's controller PD |
|---|
| 4506 | 4818 | * list structure. This information is mainly used to find out SYSTEM |
|---|
| .. | .. |
|---|
| 4588 | 4900 | case DCMD_SUCCESS: |
|---|
| 4589 | 4901 | tgtid_count = le32_to_cpu(ci->count); |
|---|
| 4590 | 4902 | |
|---|
| 4903 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 4904 | + dev_info(&instance->pdev->dev, "%s, LD count: 0x%x\n", |
|---|
| 4905 | + __func__, tgtid_count); |
|---|
| 4906 | + |
|---|
| 4591 | 4907 | if ((tgtid_count > (instance->fw_supported_vd_count))) |
|---|
| 4592 | 4908 | break; |
|---|
| 4593 | 4909 | |
|---|
| .. | .. |
|---|
| 4595 | 4911 | for (ld_index = 0; ld_index < tgtid_count; ld_index++) { |
|---|
| 4596 | 4912 | ids = ci->targetId[ld_index]; |
|---|
| 4597 | 4913 | instance->ld_ids[ids] = ci->targetId[ld_index]; |
|---|
| 4914 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 4915 | + dev_info(&instance->pdev->dev, "LD%d: targetID: 0x%03x\n", |
|---|
| 4916 | + ld_index, ci->targetId[ld_index]); |
|---|
| 4598 | 4917 | } |
|---|
| 4599 | 4918 | |
|---|
| 4919 | + break; |
|---|
| 4920 | + } |
|---|
| 4921 | + |
|---|
| 4922 | + if (ret != DCMD_TIMEOUT) |
|---|
| 4923 | + megasas_return_cmd(instance, cmd); |
|---|
| 4924 | + |
|---|
| 4925 | + return ret; |
|---|
| 4926 | +} |
|---|
| 4927 | + |
|---|
| 4928 | +/** |
|---|
| 4929 | + * dcmd.opcode - MR_DCMD_CTRL_DEVICE_LIST_GET |
|---|
| 4930 | + * dcmd.mbox - reserved |
|---|
| 4931 | + * dcmd.sge IN - ptr to return MR_HOST_DEVICE_LIST structure |
|---|
| 4932 | + * Desc: This DCMD will return the combined device list |
|---|
| 4933 | + * Status: MFI_STAT_OK - List returned successfully |
|---|
| 4934 | + * MFI_STAT_INVALID_CMD - Firmware support for the feature has been |
|---|
| 4935 | + * disabled |
|---|
| 4936 | + * @instance: Adapter soft state |
|---|
| 4937 | + * @is_probe: Driver probe check |
|---|
| 4938 | + * Return: 0 if DCMD succeeded |
|---|
| 4939 | + * non-zero if failed |
|---|
| 4940 | + */ |
|---|
| 4941 | +static int |
|---|
| 4942 | +megasas_host_device_list_query(struct megasas_instance *instance, |
|---|
| 4943 | + bool is_probe) |
|---|
| 4944 | +{ |
|---|
| 4945 | + int ret, i, target_id; |
|---|
| 4946 | + struct megasas_cmd *cmd; |
|---|
| 4947 | + struct megasas_dcmd_frame *dcmd; |
|---|
| 4948 | + struct MR_HOST_DEVICE_LIST *ci; |
|---|
| 4949 | + u32 count; |
|---|
| 4950 | + dma_addr_t ci_h; |
|---|
| 4951 | + |
|---|
| 4952 | + ci = instance->host_device_list_buf; |
|---|
| 4953 | + ci_h = instance->host_device_list_buf_h; |
|---|
| 4954 | + |
|---|
| 4955 | + cmd = megasas_get_cmd(instance); |
|---|
| 4956 | + |
|---|
| 4957 | + if (!cmd) { |
|---|
| 4958 | + dev_warn(&instance->pdev->dev, |
|---|
| 4959 | + "%s: failed to get cmd\n", |
|---|
| 4960 | + __func__); |
|---|
| 4961 | + return -ENOMEM; |
|---|
| 4962 | + } |
|---|
| 4963 | + |
|---|
| 4964 | + dcmd = &cmd->frame->dcmd; |
|---|
| 4965 | + |
|---|
| 4966 | + memset(ci, 0, sizeof(*ci)); |
|---|
| 4967 | + memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); |
|---|
| 4968 | + |
|---|
| 4969 | + dcmd->mbox.b[0] = is_probe ? 0 : 1; |
|---|
| 4970 | + dcmd->cmd = MFI_CMD_DCMD; |
|---|
| 4971 | + dcmd->cmd_status = MFI_STAT_INVALID_STATUS; |
|---|
| 4972 | + dcmd->sge_count = 1; |
|---|
| 4973 | + dcmd->flags = MFI_FRAME_DIR_READ; |
|---|
| 4974 | + dcmd->timeout = 0; |
|---|
| 4975 | + dcmd->pad_0 = 0; |
|---|
| 4976 | + dcmd->data_xfer_len = cpu_to_le32(HOST_DEVICE_LIST_SZ); |
|---|
| 4977 | + dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_DEVICE_LIST_GET); |
|---|
| 4978 | + |
|---|
| 4979 | + megasas_set_dma_settings(instance, dcmd, ci_h, HOST_DEVICE_LIST_SZ); |
|---|
| 4980 | + |
|---|
| 4981 | + if (!instance->mask_interrupts) { |
|---|
| 4982 | + ret = megasas_issue_blocked_cmd(instance, cmd, |
|---|
| 4983 | + MFI_IO_TIMEOUT_SECS); |
|---|
| 4984 | + } else { |
|---|
| 4985 | + ret = megasas_issue_polled(instance, cmd); |
|---|
| 4986 | + cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
|---|
| 4987 | + } |
|---|
| 4988 | + |
|---|
| 4989 | + switch (ret) { |
|---|
| 4990 | + case DCMD_SUCCESS: |
|---|
| 4991 | + /* Fill the internal pd_list and ld_ids array based on |
|---|
| 4992 | + * targetIds returned by FW |
|---|
| 4993 | + */ |
|---|
| 4994 | + count = le32_to_cpu(ci->count); |
|---|
| 4995 | + |
|---|
| 4996 | + if (count > (MEGASAS_MAX_PD + MAX_LOGICAL_DRIVES_EXT)) |
|---|
| 4997 | + break; |
|---|
| 4998 | + |
|---|
| 4999 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 5000 | + dev_info(&instance->pdev->dev, "%s, Device count: 0x%x\n", |
|---|
| 5001 | + __func__, count); |
|---|
| 5002 | + |
|---|
| 5003 | + memset(instance->local_pd_list, 0, |
|---|
| 5004 | + MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)); |
|---|
| 5005 | + memset(instance->ld_ids, 0xff, MAX_LOGICAL_DRIVES_EXT); |
|---|
| 5006 | + for (i = 0; i < count; i++) { |
|---|
| 5007 | + target_id = le16_to_cpu(ci->host_device_list[i].target_id); |
|---|
| 5008 | + if (ci->host_device_list[i].flags.u.bits.is_sys_pd) { |
|---|
| 5009 | + instance->local_pd_list[target_id].tid = target_id; |
|---|
| 5010 | + instance->local_pd_list[target_id].driveType = |
|---|
| 5011 | + ci->host_device_list[i].scsi_type; |
|---|
| 5012 | + instance->local_pd_list[target_id].driveState = |
|---|
| 5013 | + MR_PD_STATE_SYSTEM; |
|---|
| 5014 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 5015 | + dev_info(&instance->pdev->dev, |
|---|
| 5016 | + "Device %d: PD targetID: 0x%03x deviceType:0x%x\n", |
|---|
| 5017 | + i, target_id, ci->host_device_list[i].scsi_type); |
|---|
| 5018 | + } else { |
|---|
| 5019 | + instance->ld_ids[target_id] = target_id; |
|---|
| 5020 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
|---|
| 5021 | + dev_info(&instance->pdev->dev, |
|---|
| 5022 | + "Device %d: LD targetID: 0x%03x\n", |
|---|
| 5023 | + i, target_id); |
|---|
| 5024 | + } |
|---|
| 5025 | + } |
|---|
| 5026 | + |
|---|
| 5027 | + memcpy(instance->pd_list, instance->local_pd_list, |
|---|
| 5028 | + sizeof(instance->pd_list)); |
|---|
| 5029 | + break; |
|---|
| 5030 | + |
|---|
| 5031 | + case DCMD_TIMEOUT: |
|---|
| 5032 | + switch (dcmd_timeout_ocr_possible(instance)) { |
|---|
| 5033 | + case INITIATE_OCR: |
|---|
| 5034 | + cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
|---|
| 5035 | + mutex_unlock(&instance->reset_mutex); |
|---|
| 5036 | + megasas_reset_fusion(instance->host, |
|---|
| 5037 | + MFI_IO_TIMEOUT_OCR); |
|---|
| 5038 | + mutex_lock(&instance->reset_mutex); |
|---|
| 5039 | + break; |
|---|
| 5040 | + case KILL_ADAPTER: |
|---|
| 5041 | + megaraid_sas_kill_hba(instance); |
|---|
| 5042 | + break; |
|---|
| 5043 | + case IGNORE_TIMEOUT: |
|---|
| 5044 | + dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n", |
|---|
| 5045 | + __func__, __LINE__); |
|---|
| 5046 | + break; |
|---|
| 5047 | + } |
|---|
| 5048 | + break; |
|---|
| 5049 | + case DCMD_FAILED: |
|---|
| 5050 | + dev_err(&instance->pdev->dev, |
|---|
| 5051 | + "%s: MR_DCMD_CTRL_DEVICE_LIST_GET failed\n", |
|---|
| 5052 | + __func__); |
|---|
| 4600 | 5053 | break; |
|---|
| 4601 | 5054 | } |
|---|
| 4602 | 5055 | |
|---|
| .. | .. |
|---|
| 4639 | 5092 | } |
|---|
| 4640 | 5093 | |
|---|
| 4641 | 5094 | dev_info(&instance->pdev->dev, |
|---|
| 4642 | | - "firmware type\t: %s\n", |
|---|
| 4643 | | - instance->supportmax256vd ? "Extended VD(240 VD)firmware" : |
|---|
| 4644 | | - "Legacy(64 VD) firmware"); |
|---|
| 5095 | + "FW provided supportMaxExtLDs: %d\tmax_lds: %d\n", |
|---|
| 5096 | + instance->ctrl_info_buf->adapterOperations3.supportMaxExtLDs ? 1 : 0, |
|---|
| 5097 | + instance->ctrl_info_buf->max_lds); |
|---|
| 4645 | 5098 | |
|---|
| 4646 | 5099 | if (instance->max_raid_mapsize) { |
|---|
| 4647 | 5100 | ventura_map_sz = instance->max_raid_mapsize * |
|---|
| .. | .. |
|---|
| 4664 | 5117 | } |
|---|
| 4665 | 5118 | /* irrespective of FW raid maps, driver raid map is constant */ |
|---|
| 4666 | 5119 | fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL); |
|---|
| 5120 | +} |
|---|
| 5121 | + |
|---|
| 5122 | +/* |
|---|
| 5123 | + * dcmd.opcode - MR_DCMD_CTRL_SNAPDUMP_GET_PROPERTIES |
|---|
| 5124 | + * dcmd.hdr.length - number of bytes to read |
|---|
| 5125 | + * dcmd.sge - Ptr to MR_SNAPDUMP_PROPERTIES |
|---|
| 5126 | + * Desc: Fill in snapdump properties |
|---|
| 5127 | + * Status: MFI_STAT_OK- Command successful |
|---|
| 5128 | + */ |
|---|
| 5129 | +void megasas_get_snapdump_properties(struct megasas_instance *instance) |
|---|
| 5130 | +{ |
|---|
| 5131 | + int ret = 0; |
|---|
| 5132 | + struct megasas_cmd *cmd; |
|---|
| 5133 | + struct megasas_dcmd_frame *dcmd; |
|---|
| 5134 | + struct MR_SNAPDUMP_PROPERTIES *ci; |
|---|
| 5135 | + dma_addr_t ci_h = 0; |
|---|
| 5136 | + |
|---|
| 5137 | + ci = instance->snapdump_prop; |
|---|
| 5138 | + ci_h = instance->snapdump_prop_h; |
|---|
| 5139 | + |
|---|
| 5140 | + if (!ci) |
|---|
| 5141 | + return; |
|---|
| 5142 | + |
|---|
| 5143 | + cmd = megasas_get_cmd(instance); |
|---|
| 5144 | + |
|---|
| 5145 | + if (!cmd) { |
|---|
| 5146 | + dev_dbg(&instance->pdev->dev, "Failed to get a free cmd\n"); |
|---|
| 5147 | + return; |
|---|
| 5148 | + } |
|---|
| 5149 | + |
|---|
| 5150 | + dcmd = &cmd->frame->dcmd; |
|---|
| 5151 | + |
|---|
| 5152 | + memset(ci, 0, sizeof(*ci)); |
|---|
| 5153 | + memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); |
|---|
| 5154 | + |
|---|
| 5155 | + dcmd->cmd = MFI_CMD_DCMD; |
|---|
| 5156 | + dcmd->cmd_status = MFI_STAT_INVALID_STATUS; |
|---|
| 5157 | + dcmd->sge_count = 1; |
|---|
| 5158 | + dcmd->flags = MFI_FRAME_DIR_READ; |
|---|
| 5159 | + dcmd->timeout = 0; |
|---|
| 5160 | + dcmd->pad_0 = 0; |
|---|
| 5161 | + dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_SNAPDUMP_PROPERTIES)); |
|---|
| 5162 | + dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SNAPDUMP_GET_PROPERTIES); |
|---|
| 5163 | + |
|---|
| 5164 | + megasas_set_dma_settings(instance, dcmd, ci_h, |
|---|
| 5165 | + sizeof(struct MR_SNAPDUMP_PROPERTIES)); |
|---|
| 5166 | + |
|---|
| 5167 | + if (!instance->mask_interrupts) { |
|---|
| 5168 | + ret = megasas_issue_blocked_cmd(instance, cmd, |
|---|
| 5169 | + MFI_IO_TIMEOUT_SECS); |
|---|
| 5170 | + } else { |
|---|
| 5171 | + ret = megasas_issue_polled(instance, cmd); |
|---|
| 5172 | + cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
|---|
| 5173 | + } |
|---|
| 5174 | + |
|---|
| 5175 | + switch (ret) { |
|---|
| 5176 | + case DCMD_SUCCESS: |
|---|
| 5177 | + instance->snapdump_wait_time = |
|---|
| 5178 | + min_t(u8, ci->trigger_min_num_sec_before_ocr, |
|---|
| 5179 | + MEGASAS_MAX_SNAP_DUMP_WAIT_TIME); |
|---|
| 5180 | + break; |
|---|
| 5181 | + |
|---|
| 5182 | + case DCMD_TIMEOUT: |
|---|
| 5183 | + switch (dcmd_timeout_ocr_possible(instance)) { |
|---|
| 5184 | + case INITIATE_OCR: |
|---|
| 5185 | + cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
|---|
| 5186 | + mutex_unlock(&instance->reset_mutex); |
|---|
| 5187 | + megasas_reset_fusion(instance->host, |
|---|
| 5188 | + MFI_IO_TIMEOUT_OCR); |
|---|
| 5189 | + mutex_lock(&instance->reset_mutex); |
|---|
| 5190 | + break; |
|---|
| 5191 | + case KILL_ADAPTER: |
|---|
| 5192 | + megaraid_sas_kill_hba(instance); |
|---|
| 5193 | + break; |
|---|
| 5194 | + case IGNORE_TIMEOUT: |
|---|
| 5195 | + dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n", |
|---|
| 5196 | + __func__, __LINE__); |
|---|
| 5197 | + break; |
|---|
| 5198 | + } |
|---|
| 5199 | + } |
|---|
| 5200 | + |
|---|
| 5201 | + if (ret != DCMD_TIMEOUT) |
|---|
| 5202 | + megasas_return_cmd(instance, cmd); |
|---|
| 4667 | 5203 | } |
|---|
| 4668 | 5204 | |
|---|
| 4669 | 5205 | /** |
|---|
| .. | .. |
|---|
| 4725 | 5261 | * CPU endianness format. |
|---|
| 4726 | 5262 | */ |
|---|
| 4727 | 5263 | le32_to_cpus((u32 *)&ci->properties.OnOffProperties); |
|---|
| 5264 | + le16_to_cpus((u16 *)&ci->properties.on_off_properties2); |
|---|
| 4728 | 5265 | le32_to_cpus((u32 *)&ci->adapterOperations2); |
|---|
| 4729 | 5266 | le32_to_cpus((u32 *)&ci->adapterOperations3); |
|---|
| 4730 | 5267 | le16_to_cpus((u16 *)&ci->adapter_operations4); |
|---|
| 5268 | + le32_to_cpus((u32 *)&ci->adapter_operations5); |
|---|
| 4731 | 5269 | |
|---|
| 4732 | 5270 | /* Update the latest Ext VD info. |
|---|
| 4733 | 5271 | * From Init path, store current firmware details. |
|---|
| .. | .. |
|---|
| 4735 | 5273 | * in case of Firmware upgrade without system reboot. |
|---|
| 4736 | 5274 | */ |
|---|
| 4737 | 5275 | megasas_update_ext_vd_details(instance); |
|---|
| 4738 | | - instance->use_seqnum_jbod_fp = |
|---|
| 5276 | + instance->support_seqnum_jbod_fp = |
|---|
| 4739 | 5277 | ci->adapterOperations3.useSeqNumJbodFP; |
|---|
| 4740 | 5278 | instance->support_morethan256jbod = |
|---|
| 4741 | 5279 | ci->adapter_operations4.support_pd_map_target_id; |
|---|
| 4742 | 5280 | instance->support_nvme_passthru = |
|---|
| 4743 | 5281 | ci->adapter_operations4.support_nvme_passthru; |
|---|
| 5282 | + instance->support_pci_lane_margining = |
|---|
| 5283 | + ci->adapter_operations5.support_pci_lane_margining; |
|---|
| 4744 | 5284 | instance->task_abort_tmo = ci->TaskAbortTO; |
|---|
| 4745 | 5285 | instance->max_reset_tmo = ci->MaxResetTO; |
|---|
| 4746 | 5286 | |
|---|
| 4747 | 5287 | /*Check whether controller is iMR or MR */ |
|---|
| 4748 | 5288 | instance->is_imr = (ci->memory_size ? 0 : 1); |
|---|
| 5289 | + |
|---|
| 5290 | + instance->snapdump_wait_time = |
|---|
| 5291 | + (ci->properties.on_off_properties2.enable_snap_dump ? |
|---|
| 5292 | + MEGASAS_DEFAULT_SNAP_DUMP_WAIT_TIME : 0); |
|---|
| 5293 | + |
|---|
| 5294 | + instance->enable_fw_dev_list = |
|---|
| 5295 | + ci->properties.on_off_properties2.enable_fw_dev_list; |
|---|
| 5296 | + |
|---|
| 4749 | 5297 | dev_info(&instance->pdev->dev, |
|---|
| 4750 | 5298 | "controller type\t: %s(%dMB)\n", |
|---|
| 4751 | 5299 | instance->is_imr ? "iMR" : "MR", |
|---|
| .. | .. |
|---|
| 4764 | 5312 | dev_info(&instance->pdev->dev, |
|---|
| 4765 | 5313 | "FW provided TM TaskAbort/Reset timeout\t: %d secs/%d secs\n", |
|---|
| 4766 | 5314 | instance->task_abort_tmo, instance->max_reset_tmo); |
|---|
| 5315 | + dev_info(&instance->pdev->dev, "JBOD sequence map support\t: %s\n", |
|---|
| 5316 | + instance->support_seqnum_jbod_fp ? "Yes" : "No"); |
|---|
| 5317 | + dev_info(&instance->pdev->dev, "PCI Lane Margining support\t: %s\n", |
|---|
| 5318 | + instance->support_pci_lane_margining ? "Yes" : "No"); |
|---|
| 4767 | 5319 | |
|---|
| 4768 | 5320 | break; |
|---|
| 4769 | 5321 | |
|---|
| .. | .. |
|---|
| 4771 | 5323 | switch (dcmd_timeout_ocr_possible(instance)) { |
|---|
| 4772 | 5324 | case INITIATE_OCR: |
|---|
| 4773 | 5325 | cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
|---|
| 5326 | + mutex_unlock(&instance->reset_mutex); |
|---|
| 4774 | 5327 | megasas_reset_fusion(instance->host, |
|---|
| 4775 | 5328 | MFI_IO_TIMEOUT_OCR); |
|---|
| 5329 | + mutex_lock(&instance->reset_mutex); |
|---|
| 4776 | 5330 | break; |
|---|
| 4777 | 5331 | case KILL_ADAPTER: |
|---|
| 4778 | 5332 | megaraid_sas_kill_hba(instance); |
|---|
| .. | .. |
|---|
| 4947 | 5501 | static u32 |
|---|
| 4948 | 5502 | megasas_init_adapter_mfi(struct megasas_instance *instance) |
|---|
| 4949 | 5503 | { |
|---|
| 4950 | | - struct megasas_register_set __iomem *reg_set; |
|---|
| 4951 | 5504 | u32 context_sz; |
|---|
| 4952 | 5505 | u32 reply_q_sz; |
|---|
| 4953 | | - |
|---|
| 4954 | | - reg_set = instance->reg_set; |
|---|
| 4955 | 5506 | |
|---|
| 4956 | 5507 | /* |
|---|
| 4957 | 5508 | * Get various operational parameters from status register |
|---|
| 4958 | 5509 | */ |
|---|
| 4959 | | - instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF; |
|---|
| 5510 | + instance->max_fw_cmds = instance->instancet->read_fw_status_reg(instance) & 0x00FFFF; |
|---|
| 4960 | 5511 | /* |
|---|
| 4961 | 5512 | * Reduce the max supported cmds by 1. This is to ensure that the |
|---|
| 4962 | 5513 | * reply_q_sz (1 more than the max cmd that driver may send) |
|---|
| .. | .. |
|---|
| 4964 | 5515 | */ |
|---|
| 4965 | 5516 | instance->max_fw_cmds = instance->max_fw_cmds-1; |
|---|
| 4966 | 5517 | instance->max_mfi_cmds = instance->max_fw_cmds; |
|---|
| 4967 | | - instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> |
|---|
| 5518 | + instance->max_num_sge = (instance->instancet->read_fw_status_reg(instance) & 0xFF0000) >> |
|---|
| 4968 | 5519 | 0x10; |
|---|
| 4969 | 5520 | /* |
|---|
| 4970 | 5521 | * For MFI skinny adapters, MEGASAS_SKINNY_INT_CMDS commands |
|---|
| .. | .. |
|---|
| 5000 | 5551 | context_sz = sizeof(u32); |
|---|
| 5001 | 5552 | reply_q_sz = context_sz * (instance->max_fw_cmds + 1); |
|---|
| 5002 | 5553 | |
|---|
| 5003 | | - instance->reply_queue = pci_alloc_consistent(instance->pdev, |
|---|
| 5004 | | - reply_q_sz, |
|---|
| 5005 | | - &instance->reply_queue_h); |
|---|
| 5554 | + instance->reply_queue = dma_alloc_coherent(&instance->pdev->dev, |
|---|
| 5555 | + reply_q_sz, &instance->reply_queue_h, GFP_KERNEL); |
|---|
| 5006 | 5556 | |
|---|
| 5007 | 5557 | if (!instance->reply_queue) { |
|---|
| 5008 | 5558 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "Out of DMA mem for reply queue\n"); |
|---|
| .. | .. |
|---|
| 5021 | 5571 | |
|---|
| 5022 | 5572 | instance->fw_support_ieee = 0; |
|---|
| 5023 | 5573 | instance->fw_support_ieee = |
|---|
| 5024 | | - (instance->instancet->read_fw_status_reg(reg_set) & |
|---|
| 5574 | + (instance->instancet->read_fw_status_reg(instance) & |
|---|
| 5025 | 5575 | 0x04000000); |
|---|
| 5026 | 5576 | |
|---|
| 5027 | 5577 | dev_notice(&instance->pdev->dev, "megasas_init_mfi: fw_support_ieee=%d", |
|---|
| .. | .. |
|---|
| 5034 | 5584 | |
|---|
| 5035 | 5585 | fail_fw_init: |
|---|
| 5036 | 5586 | |
|---|
| 5037 | | - pci_free_consistent(instance->pdev, reply_q_sz, |
|---|
| 5587 | + dma_free_coherent(&instance->pdev->dev, reply_q_sz, |
|---|
| 5038 | 5588 | instance->reply_queue, instance->reply_queue_h); |
|---|
| 5039 | 5589 | fail_reply_queue: |
|---|
| 5040 | 5590 | megasas_free_cmds(instance); |
|---|
| 5041 | 5591 | |
|---|
| 5042 | 5592 | fail_alloc_cmds: |
|---|
| 5043 | 5593 | return 1; |
|---|
| 5594 | +} |
|---|
| 5595 | + |
|---|
| 5596 | +static |
|---|
| 5597 | +void megasas_setup_irq_poll(struct megasas_instance *instance) |
|---|
| 5598 | +{ |
|---|
| 5599 | + struct megasas_irq_context *irq_ctx; |
|---|
| 5600 | + u32 count, i; |
|---|
| 5601 | + |
|---|
| 5602 | + count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; |
|---|
| 5603 | + |
|---|
| 5604 | + /* Initialize IRQ poll */ |
|---|
| 5605 | + for (i = 0; i < count; i++) { |
|---|
| 5606 | + irq_ctx = &instance->irq_context[i]; |
|---|
| 5607 | + irq_ctx->os_irq = pci_irq_vector(instance->pdev, i); |
|---|
| 5608 | + irq_ctx->irq_poll_scheduled = false; |
|---|
| 5609 | + irq_poll_init(&irq_ctx->irqpoll, |
|---|
| 5610 | + instance->threshold_reply_count, |
|---|
| 5611 | + megasas_irqpoll); |
|---|
| 5612 | + } |
|---|
| 5044 | 5613 | } |
|---|
| 5045 | 5614 | |
|---|
| 5046 | 5615 | /* |
|---|
| .. | .. |
|---|
| 5059 | 5628 | pdev = instance->pdev; |
|---|
| 5060 | 5629 | instance->irq_context[0].instance = instance; |
|---|
| 5061 | 5630 | instance->irq_context[0].MSIxIndex = 0; |
|---|
| 5631 | + snprintf(instance->irq_context->name, MEGASAS_MSIX_NAME_LEN, "%s%u", |
|---|
| 5632 | + "megasas", instance->host->host_no); |
|---|
| 5062 | 5633 | if (request_irq(pci_irq_vector(pdev, 0), |
|---|
| 5063 | 5634 | instance->instancet->service_isr, IRQF_SHARED, |
|---|
| 5064 | | - "megasas", &instance->irq_context[0])) { |
|---|
| 5635 | + instance->irq_context->name, &instance->irq_context[0])) { |
|---|
| 5065 | 5636 | dev_err(&instance->pdev->dev, |
|---|
| 5066 | 5637 | "Failed to register IRQ from %s %d\n", |
|---|
| 5067 | 5638 | __func__, __LINE__); |
|---|
| 5068 | 5639 | return -1; |
|---|
| 5069 | 5640 | } |
|---|
| 5641 | + instance->perf_mode = MR_LATENCY_PERF_MODE; |
|---|
| 5642 | + instance->low_latency_index_start = 0; |
|---|
| 5070 | 5643 | return 0; |
|---|
| 5071 | 5644 | } |
|---|
| 5072 | 5645 | |
|---|
| .. | .. |
|---|
| 5091 | 5664 | for (i = 0; i < instance->msix_vectors; i++) { |
|---|
| 5092 | 5665 | instance->irq_context[i].instance = instance; |
|---|
| 5093 | 5666 | instance->irq_context[i].MSIxIndex = i; |
|---|
| 5667 | + snprintf(instance->irq_context[i].name, MEGASAS_MSIX_NAME_LEN, "%s%u-msix%u", |
|---|
| 5668 | + "megasas", instance->host->host_no, i); |
|---|
| 5094 | 5669 | if (request_irq(pci_irq_vector(pdev, i), |
|---|
| 5095 | | - instance->instancet->service_isr, 0, "megasas", |
|---|
| 5670 | + instance->instancet->service_isr, 0, instance->irq_context[i].name, |
|---|
| 5096 | 5671 | &instance->irq_context[i])) { |
|---|
| 5097 | 5672 | dev_err(&instance->pdev->dev, |
|---|
| 5098 | 5673 | "Failed to register IRQ for vector %d.\n", i); |
|---|
| 5099 | | - for (j = 0; j < i; j++) |
|---|
| 5674 | + for (j = 0; j < i; j++) { |
|---|
| 5675 | + if (j < instance->low_latency_index_start) |
|---|
| 5676 | + irq_set_affinity_hint( |
|---|
| 5677 | + pci_irq_vector(pdev, j), NULL); |
|---|
| 5100 | 5678 | free_irq(pci_irq_vector(pdev, j), |
|---|
| 5101 | 5679 | &instance->irq_context[j]); |
|---|
| 5680 | + } |
|---|
| 5102 | 5681 | /* Retry irq register for IO_APIC*/ |
|---|
| 5103 | 5682 | instance->msix_vectors = 0; |
|---|
| 5683 | + instance->msix_load_balance = false; |
|---|
| 5104 | 5684 | if (is_probe) { |
|---|
| 5105 | 5685 | pci_free_irq_vectors(instance->pdev); |
|---|
| 5106 | 5686 | return megasas_setup_irqs_ioapic(instance); |
|---|
| .. | .. |
|---|
| 5109 | 5689 | } |
|---|
| 5110 | 5690 | } |
|---|
| 5111 | 5691 | } |
|---|
| 5692 | + |
|---|
| 5112 | 5693 | return 0; |
|---|
| 5113 | 5694 | } |
|---|
| 5114 | 5695 | |
|---|
| .. | .. |
|---|
| 5121 | 5702 | megasas_destroy_irqs(struct megasas_instance *instance) { |
|---|
| 5122 | 5703 | |
|---|
| 5123 | 5704 | int i; |
|---|
| 5705 | + int count; |
|---|
| 5706 | + struct megasas_irq_context *irq_ctx; |
|---|
| 5707 | + |
|---|
| 5708 | + count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; |
|---|
| 5709 | + if (instance->adapter_type != MFI_SERIES) { |
|---|
| 5710 | + for (i = 0; i < count; i++) { |
|---|
| 5711 | + irq_ctx = &instance->irq_context[i]; |
|---|
| 5712 | + irq_poll_disable(&irq_ctx->irqpoll); |
|---|
| 5713 | + } |
|---|
| 5714 | + } |
|---|
| 5124 | 5715 | |
|---|
| 5125 | 5716 | if (instance->msix_vectors) |
|---|
| 5126 | 5717 | for (i = 0; i < instance->msix_vectors; i++) { |
|---|
| 5718 | + if (i < instance->low_latency_index_start) |
|---|
| 5719 | + irq_set_affinity_hint( |
|---|
| 5720 | + pci_irq_vector(instance->pdev, i), NULL); |
|---|
| 5127 | 5721 | free_irq(pci_irq_vector(instance->pdev, i), |
|---|
| 5128 | 5722 | &instance->irq_context[i]); |
|---|
| 5129 | 5723 | } |
|---|
| .. | .. |
|---|
| 5135 | 5729 | /** |
|---|
| 5136 | 5730 | * megasas_setup_jbod_map - setup jbod map for FP seq_number. |
|---|
| 5137 | 5731 | * @instance: Adapter soft state |
|---|
| 5138 | | - * @is_probe: Driver probe check |
|---|
| 5139 | 5732 | * |
|---|
| 5140 | 5733 | * Return 0 on success. |
|---|
| 5141 | 5734 | */ |
|---|
| .. | .. |
|---|
| 5149 | 5742 | pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) + |
|---|
| 5150 | 5743 | (sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1)); |
|---|
| 5151 | 5744 | |
|---|
| 5745 | + instance->use_seqnum_jbod_fp = |
|---|
| 5746 | + instance->support_seqnum_jbod_fp; |
|---|
| 5152 | 5747 | if (reset_devices || !fusion || |
|---|
| 5153 | | - !instance->ctrl_info_buf->adapterOperations3.useSeqNumJbodFP) { |
|---|
| 5748 | + !instance->support_seqnum_jbod_fp) { |
|---|
| 5154 | 5749 | dev_info(&instance->pdev->dev, |
|---|
| 5155 | | - "Jbod map is not supported %s %d\n", |
|---|
| 5750 | + "JBOD sequence map is disabled %s %d\n", |
|---|
| 5156 | 5751 | __func__, __LINE__); |
|---|
| 5157 | 5752 | instance->use_seqnum_jbod_fp = false; |
|---|
| 5158 | 5753 | return; |
|---|
| .. | .. |
|---|
| 5191 | 5786 | static void megasas_setup_reply_map(struct megasas_instance *instance) |
|---|
| 5192 | 5787 | { |
|---|
| 5193 | 5788 | const struct cpumask *mask; |
|---|
| 5194 | | - unsigned int queue, cpu; |
|---|
| 5789 | + unsigned int queue, cpu, low_latency_index_start; |
|---|
| 5195 | 5790 | |
|---|
| 5196 | | - for (queue = 0; queue < instance->msix_vectors; queue++) { |
|---|
| 5791 | + low_latency_index_start = instance->low_latency_index_start; |
|---|
| 5792 | + |
|---|
| 5793 | + for (queue = low_latency_index_start; queue < instance->msix_vectors; queue++) { |
|---|
| 5197 | 5794 | mask = pci_irq_get_affinity(instance->pdev, queue); |
|---|
| 5198 | 5795 | if (!mask) |
|---|
| 5199 | 5796 | goto fallback; |
|---|
| .. | .. |
|---|
| 5204 | 5801 | return; |
|---|
| 5205 | 5802 | |
|---|
| 5206 | 5803 | fallback: |
|---|
| 5207 | | - for_each_possible_cpu(cpu) |
|---|
| 5208 | | - instance->reply_map[cpu] = cpu % instance->msix_vectors; |
|---|
| 5804 | + queue = low_latency_index_start; |
|---|
| 5805 | + for_each_possible_cpu(cpu) { |
|---|
| 5806 | + instance->reply_map[cpu] = queue; |
|---|
| 5807 | + if (queue == (instance->msix_vectors - 1)) |
|---|
| 5808 | + queue = low_latency_index_start; |
|---|
| 5809 | + else |
|---|
| 5810 | + queue++; |
|---|
| 5811 | + } |
|---|
| 5812 | +} |
|---|
| 5813 | + |
|---|
| 5814 | +/** |
|---|
| 5815 | + * megasas_get_device_list - Get the PD and LD device list from FW. |
|---|
| 5816 | + * @instance: Adapter soft state |
|---|
| 5817 | + * @return: Success or failure |
|---|
| 5818 | + * |
|---|
| 5819 | + * Issue DCMDs to Firmware to get the PD and LD list. |
|---|
| 5820 | + * Based on the FW support, driver sends the HOST_DEVICE_LIST or combination |
|---|
| 5821 | + * of PD_LIST/LD_LIST_QUERY DCMDs to get the device list. |
|---|
| 5822 | + */ |
|---|
| 5823 | +static |
|---|
| 5824 | +int megasas_get_device_list(struct megasas_instance *instance) |
|---|
| 5825 | +{ |
|---|
| 5826 | + memset(instance->pd_list, 0, |
|---|
| 5827 | + (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); |
|---|
| 5828 | + memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); |
|---|
| 5829 | + |
|---|
| 5830 | + if (instance->enable_fw_dev_list) { |
|---|
| 5831 | + if (megasas_host_device_list_query(instance, true)) |
|---|
| 5832 | + return FAILED; |
|---|
| 5833 | + } else { |
|---|
| 5834 | + if (megasas_get_pd_list(instance) < 0) { |
|---|
| 5835 | + dev_err(&instance->pdev->dev, "failed to get PD list\n"); |
|---|
| 5836 | + return FAILED; |
|---|
| 5837 | + } |
|---|
| 5838 | + |
|---|
| 5839 | + if (megasas_ld_list_query(instance, |
|---|
| 5840 | + MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) { |
|---|
| 5841 | + dev_err(&instance->pdev->dev, "failed to get LD list\n"); |
|---|
| 5842 | + return FAILED; |
|---|
| 5843 | + } |
|---|
| 5844 | + } |
|---|
| 5845 | + |
|---|
| 5846 | + return SUCCESS; |
|---|
| 5847 | +} |
|---|
| 5848 | + |
|---|
| 5849 | +/** |
|---|
| 5850 | + * megasas_set_high_iops_queue_affinity_hint - Set affinity hint for high IOPS queues |
|---|
| 5851 | + * @instance: Adapter soft state |
|---|
| 5852 | + * return: void |
|---|
| 5853 | + */ |
|---|
| 5854 | +static inline void |
|---|
| 5855 | +megasas_set_high_iops_queue_affinity_hint(struct megasas_instance *instance) |
|---|
| 5856 | +{ |
|---|
| 5857 | + int i; |
|---|
| 5858 | + int local_numa_node; |
|---|
| 5859 | + |
|---|
| 5860 | + if (instance->perf_mode == MR_BALANCED_PERF_MODE) { |
|---|
| 5861 | + local_numa_node = dev_to_node(&instance->pdev->dev); |
|---|
| 5862 | + |
|---|
| 5863 | + for (i = 0; i < instance->low_latency_index_start; i++) |
|---|
| 5864 | + irq_set_affinity_hint(pci_irq_vector(instance->pdev, i), |
|---|
| 5865 | + cpumask_of_node(local_numa_node)); |
|---|
| 5866 | + } |
|---|
| 5867 | +} |
|---|
| 5868 | + |
|---|
| 5869 | +static int |
|---|
| 5870 | +__megasas_alloc_irq_vectors(struct megasas_instance *instance) |
|---|
| 5871 | +{ |
|---|
| 5872 | + int i, irq_flags; |
|---|
| 5873 | + struct irq_affinity desc = { .pre_vectors = instance->low_latency_index_start }; |
|---|
| 5874 | + struct irq_affinity *descp = &desc; |
|---|
| 5875 | + |
|---|
| 5876 | + irq_flags = PCI_IRQ_MSIX; |
|---|
| 5877 | + |
|---|
| 5878 | + if (instance->smp_affinity_enable) |
|---|
| 5879 | + irq_flags |= PCI_IRQ_AFFINITY; |
|---|
| 5880 | + else |
|---|
| 5881 | + descp = NULL; |
|---|
| 5882 | + |
|---|
| 5883 | + i = pci_alloc_irq_vectors_affinity(instance->pdev, |
|---|
| 5884 | + instance->low_latency_index_start, |
|---|
| 5885 | + instance->msix_vectors, irq_flags, descp); |
|---|
| 5886 | + |
|---|
| 5887 | + return i; |
|---|
| 5888 | +} |
|---|
| 5889 | + |
|---|
| 5890 | +/** |
|---|
| 5891 | + * megasas_alloc_irq_vectors - Allocate IRQ vectors/enable MSI-x vectors |
|---|
| 5892 | + * @instance: Adapter soft state |
|---|
| 5893 | + * return: void |
|---|
| 5894 | + */ |
|---|
| 5895 | +static void |
|---|
| 5896 | +megasas_alloc_irq_vectors(struct megasas_instance *instance) |
|---|
| 5897 | +{ |
|---|
| 5898 | + int i; |
|---|
| 5899 | + unsigned int num_msix_req; |
|---|
| 5900 | + |
|---|
| 5901 | + i = __megasas_alloc_irq_vectors(instance); |
|---|
| 5902 | + |
|---|
| 5903 | + if ((instance->perf_mode == MR_BALANCED_PERF_MODE) && |
|---|
| 5904 | + (i != instance->msix_vectors)) { |
|---|
| 5905 | + if (instance->msix_vectors) |
|---|
| 5906 | + pci_free_irq_vectors(instance->pdev); |
|---|
| 5907 | + /* Disable Balanced IOPS mode and try realloc vectors */ |
|---|
| 5908 | + instance->perf_mode = MR_LATENCY_PERF_MODE; |
|---|
| 5909 | + instance->low_latency_index_start = 1; |
|---|
| 5910 | + num_msix_req = num_online_cpus() + instance->low_latency_index_start; |
|---|
| 5911 | + |
|---|
| 5912 | + instance->msix_vectors = min(num_msix_req, |
|---|
| 5913 | + instance->msix_vectors); |
|---|
| 5914 | + |
|---|
| 5915 | + i = __megasas_alloc_irq_vectors(instance); |
|---|
| 5916 | + |
|---|
| 5917 | + } |
|---|
| 5918 | + |
|---|
| 5919 | + dev_info(&instance->pdev->dev, |
|---|
| 5920 | + "requested/available msix %d/%d\n", instance->msix_vectors, i); |
|---|
| 5921 | + |
|---|
| 5922 | + if (i > 0) |
|---|
| 5923 | + instance->msix_vectors = i; |
|---|
| 5924 | + else |
|---|
| 5925 | + instance->msix_vectors = 0; |
|---|
| 5926 | + |
|---|
| 5927 | + if (instance->smp_affinity_enable) |
|---|
| 5928 | + megasas_set_high_iops_queue_affinity_hint(instance); |
|---|
| 5209 | 5929 | } |
|---|
| 5210 | 5930 | |
|---|
| 5211 | 5931 | /** |
|---|
| .. | .. |
|---|
| 5219 | 5939 | { |
|---|
| 5220 | 5940 | u32 max_sectors_1; |
|---|
| 5221 | 5941 | u32 max_sectors_2, tmp_sectors, msix_enable; |
|---|
| 5222 | | - u32 scratch_pad_2, scratch_pad_3, scratch_pad_4, status_reg; |
|---|
| 5942 | + u32 scratch_pad_1, scratch_pad_2, scratch_pad_3, status_reg; |
|---|
| 5223 | 5943 | resource_size_t base_addr; |
|---|
| 5224 | | - struct megasas_register_set __iomem *reg_set; |
|---|
| 5944 | + void *base_addr_phys; |
|---|
| 5225 | 5945 | struct megasas_ctrl_info *ctrl_info = NULL; |
|---|
| 5226 | 5946 | unsigned long bar_list; |
|---|
| 5227 | | - int i, j, loop, fw_msix_count = 0; |
|---|
| 5947 | + int i, j, loop; |
|---|
| 5228 | 5948 | struct IOV_111 *iovPtr; |
|---|
| 5229 | 5949 | struct fusion_context *fusion; |
|---|
| 5230 | | - bool do_adp_reset = true; |
|---|
| 5950 | + bool intr_coalescing; |
|---|
| 5951 | + unsigned int num_msix_req; |
|---|
| 5952 | + u16 lnksta, speed; |
|---|
| 5231 | 5953 | |
|---|
| 5232 | 5954 | fusion = instance->ctrl_context; |
|---|
| 5233 | 5955 | |
|---|
| .. | .. |
|---|
| 5241 | 5963 | } |
|---|
| 5242 | 5964 | |
|---|
| 5243 | 5965 | base_addr = pci_resource_start(instance->pdev, instance->bar); |
|---|
| 5244 | | - instance->reg_set = ioremap_nocache(base_addr, 8192); |
|---|
| 5966 | + instance->reg_set = ioremap(base_addr, 8192); |
|---|
| 5245 | 5967 | |
|---|
| 5246 | 5968 | if (!instance->reg_set) { |
|---|
| 5247 | 5969 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to map IO mem\n"); |
|---|
| 5248 | 5970 | goto fail_ioremap; |
|---|
| 5249 | 5971 | } |
|---|
| 5250 | 5972 | |
|---|
| 5251 | | - reg_set = instance->reg_set; |
|---|
| 5973 | + base_addr_phys = &base_addr; |
|---|
| 5974 | + dev_printk(KERN_DEBUG, &instance->pdev->dev, |
|---|
| 5975 | + "BAR:0x%lx BAR's base_addr(phys):%pa mapped virt_addr:0x%p\n", |
|---|
| 5976 | + instance->bar, base_addr_phys, instance->reg_set); |
|---|
| 5252 | 5977 | |
|---|
| 5253 | 5978 | if (instance->adapter_type != MFI_SERIES) |
|---|
| 5254 | 5979 | instance->instancet = &megasas_instance_template_fusion; |
|---|
| .. | .. |
|---|
| 5276 | 6001 | } |
|---|
| 5277 | 6002 | |
|---|
| 5278 | 6003 | if (megasas_transition_to_ready(instance, 0)) { |
|---|
| 5279 | | - if (instance->adapter_type >= INVADER_SERIES) { |
|---|
| 6004 | + dev_info(&instance->pdev->dev, |
|---|
| 6005 | + "Failed to transition controller to ready from %s!\n", |
|---|
| 6006 | + __func__); |
|---|
| 6007 | + if (instance->adapter_type != MFI_SERIES) { |
|---|
| 5280 | 6008 | status_reg = instance->instancet->read_fw_status_reg( |
|---|
| 5281 | | - instance->reg_set); |
|---|
| 5282 | | - do_adp_reset = status_reg & MFI_RESET_ADAPTER; |
|---|
| 5283 | | - } |
|---|
| 5284 | | - |
|---|
| 5285 | | - if (do_adp_reset) { |
|---|
| 6009 | + instance); |
|---|
| 6010 | + if (status_reg & MFI_RESET_ADAPTER) { |
|---|
| 6011 | + if (megasas_adp_reset_wait_for_ready |
|---|
| 6012 | + (instance, true, 0) == FAILED) |
|---|
| 6013 | + goto fail_ready_state; |
|---|
| 6014 | + } else { |
|---|
| 6015 | + goto fail_ready_state; |
|---|
| 6016 | + } |
|---|
| 6017 | + } else { |
|---|
| 5286 | 6018 | atomic_set(&instance->fw_reset_no_pci_access, 1); |
|---|
| 5287 | 6019 | instance->instancet->adp_reset |
|---|
| 5288 | 6020 | (instance, instance->reg_set); |
|---|
| 5289 | 6021 | atomic_set(&instance->fw_reset_no_pci_access, 0); |
|---|
| 5290 | | - dev_info(&instance->pdev->dev, |
|---|
| 5291 | | - "FW restarted successfully from %s!\n", |
|---|
| 5292 | | - __func__); |
|---|
| 5293 | 6022 | |
|---|
| 5294 | 6023 | /*waiting for about 30 second before retry*/ |
|---|
| 5295 | 6024 | ssleep(30); |
|---|
| 5296 | 6025 | |
|---|
| 5297 | 6026 | if (megasas_transition_to_ready(instance, 0)) |
|---|
| 5298 | 6027 | goto fail_ready_state; |
|---|
| 5299 | | - } else { |
|---|
| 5300 | | - goto fail_ready_state; |
|---|
| 5301 | 6028 | } |
|---|
| 6029 | + |
|---|
| 6030 | + dev_info(&instance->pdev->dev, |
|---|
| 6031 | + "FW restarted successfully from %s!\n", |
|---|
| 6032 | + __func__); |
|---|
| 5302 | 6033 | } |
|---|
| 5303 | 6034 | |
|---|
| 5304 | 6035 | megasas_init_ctrl_params(instance); |
|---|
| .. | .. |
|---|
| 5314 | 6045 | |
|---|
| 5315 | 6046 | fusion = instance->ctrl_context; |
|---|
| 5316 | 6047 | |
|---|
| 5317 | | - if (instance->adapter_type == VENTURA_SERIES) { |
|---|
| 5318 | | - scratch_pad_3 = |
|---|
| 5319 | | - readl(&instance->reg_set->outbound_scratch_pad_3); |
|---|
| 5320 | | - instance->max_raid_mapsize = ((scratch_pad_3 >> |
|---|
| 6048 | + if (instance->adapter_type >= VENTURA_SERIES) { |
|---|
| 6049 | + scratch_pad_2 = |
|---|
| 6050 | + megasas_readl(instance, |
|---|
| 6051 | + &instance->reg_set->outbound_scratch_pad_2); |
|---|
| 6052 | + instance->max_raid_mapsize = ((scratch_pad_2 >> |
|---|
| 5321 | 6053 | MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) & |
|---|
| 5322 | 6054 | MR_MAX_RAID_MAP_SIZE_MASK); |
|---|
| 5323 | 6055 | } |
|---|
| 5324 | 6056 | |
|---|
| 6057 | + instance->enable_sdev_max_qd = enable_sdev_max_qd; |
|---|
| 6058 | + |
|---|
| 6059 | + switch (instance->adapter_type) { |
|---|
| 6060 | + case VENTURA_SERIES: |
|---|
| 6061 | + fusion->pcie_bw_limitation = true; |
|---|
| 6062 | + break; |
|---|
| 6063 | + case AERO_SERIES: |
|---|
| 6064 | + fusion->r56_div_offload = true; |
|---|
| 6065 | + break; |
|---|
| 6066 | + default: |
|---|
| 6067 | + break; |
|---|
| 6068 | + } |
|---|
| 6069 | + |
|---|
| 5325 | 6070 | /* Check if MSI-X is supported while in ready state */ |
|---|
| 5326 | | - msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & |
|---|
| 6071 | + msix_enable = (instance->instancet->read_fw_status_reg(instance) & |
|---|
| 5327 | 6072 | 0x4000000) >> 0x1a; |
|---|
| 5328 | 6073 | if (msix_enable && !msix_disable) { |
|---|
| 5329 | | - int irq_flags = PCI_IRQ_MSIX; |
|---|
| 5330 | 6074 | |
|---|
| 5331 | | - scratch_pad_2 = readl |
|---|
| 5332 | | - (&instance->reg_set->outbound_scratch_pad_2); |
|---|
| 6075 | + scratch_pad_1 = megasas_readl |
|---|
| 6076 | + (instance, &instance->reg_set->outbound_scratch_pad_1); |
|---|
| 5333 | 6077 | /* Check max MSI-X vectors */ |
|---|
| 5334 | 6078 | if (fusion) { |
|---|
| 5335 | 6079 | if (instance->adapter_type == THUNDERBOLT_SERIES) { |
|---|
| 5336 | 6080 | /* Thunderbolt Series*/ |
|---|
| 5337 | | - instance->msix_vectors = (scratch_pad_2 |
|---|
| 6081 | + instance->msix_vectors = (scratch_pad_1 |
|---|
| 5338 | 6082 | & MR_MAX_REPLY_QUEUES_OFFSET) + 1; |
|---|
| 5339 | | - fw_msix_count = instance->msix_vectors; |
|---|
| 5340 | 6083 | } else { |
|---|
| 5341 | | - instance->msix_vectors = ((scratch_pad_2 |
|---|
| 6084 | + instance->msix_vectors = ((scratch_pad_1 |
|---|
| 5342 | 6085 | & MR_MAX_REPLY_QUEUES_EXT_OFFSET) |
|---|
| 5343 | 6086 | >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1; |
|---|
| 5344 | 6087 | |
|---|
| .. | .. |
|---|
| 5355 | 6098 | if (instance->msix_vectors > 8) |
|---|
| 5356 | 6099 | instance->msix_combined = true; |
|---|
| 5357 | 6100 | break; |
|---|
| 6101 | + case AERO_SERIES: |
|---|
| 5358 | 6102 | case VENTURA_SERIES: |
|---|
| 5359 | 6103 | if (instance->msix_vectors > 16) |
|---|
| 5360 | 6104 | instance->msix_combined = true; |
|---|
| .. | .. |
|---|
| 5362 | 6106 | } |
|---|
| 5363 | 6107 | |
|---|
| 5364 | 6108 | if (rdpq_enable) |
|---|
| 5365 | | - instance->is_rdpq = (scratch_pad_2 & MR_RDPQ_MODE_OFFSET) ? |
|---|
| 6109 | + instance->is_rdpq = (scratch_pad_1 & MR_RDPQ_MODE_OFFSET) ? |
|---|
| 5366 | 6110 | 1 : 0; |
|---|
| 5367 | | - fw_msix_count = instance->msix_vectors; |
|---|
| 6111 | + |
|---|
| 6112 | + if (instance->adapter_type >= INVADER_SERIES && |
|---|
| 6113 | + !instance->msix_combined) { |
|---|
| 6114 | + instance->msix_load_balance = true; |
|---|
| 6115 | + instance->smp_affinity_enable = false; |
|---|
| 6116 | + } |
|---|
| 6117 | + |
|---|
| 5368 | 6118 | /* Save 1-15 reply post index address to local memory |
|---|
| 5369 | 6119 | * Index 0 is already saved from reg offset |
|---|
| 5370 | 6120 | * MPI2_REPLY_POST_HOST_INDEX_OFFSET |
|---|
| .. | .. |
|---|
| 5377 | 6127 | + (loop * 0x10)); |
|---|
| 5378 | 6128 | } |
|---|
| 5379 | 6129 | } |
|---|
| 6130 | + |
|---|
| 6131 | + dev_info(&instance->pdev->dev, |
|---|
| 6132 | + "firmware supports msix\t: (%d)", |
|---|
| 6133 | + instance->msix_vectors); |
|---|
| 5380 | 6134 | if (msix_vectors) |
|---|
| 5381 | 6135 | instance->msix_vectors = min(msix_vectors, |
|---|
| 5382 | 6136 | instance->msix_vectors); |
|---|
| 5383 | 6137 | } else /* MFI adapters */ |
|---|
| 5384 | 6138 | instance->msix_vectors = 1; |
|---|
| 5385 | | - /* Don't bother allocating more MSI-X vectors than cpus */ |
|---|
| 5386 | | - instance->msix_vectors = min(instance->msix_vectors, |
|---|
| 5387 | | - (unsigned int)num_online_cpus()); |
|---|
| 5388 | | - if (smp_affinity_enable) |
|---|
| 5389 | | - irq_flags |= PCI_IRQ_AFFINITY; |
|---|
| 5390 | | - i = pci_alloc_irq_vectors(instance->pdev, 1, |
|---|
| 5391 | | - instance->msix_vectors, irq_flags); |
|---|
| 5392 | | - if (i > 0) |
|---|
| 5393 | | - instance->msix_vectors = i; |
|---|
| 6139 | + |
|---|
| 6140 | + |
|---|
| 6141 | + /* |
|---|
| 6142 | + * For Aero (if some conditions are met), driver will configure a |
|---|
| 6143 | + * few additional reply queues with interrupt coalescing enabled. |
|---|
| 6144 | + * These queues with interrupt coalescing enabled are called |
|---|
| 6145 | + * High IOPS queues and rest of reply queues (based on number of |
|---|
| 6146 | + * logical CPUs) are termed as Low latency queues. |
|---|
| 6147 | + * |
|---|
| 6148 | + * Total Number of reply queues = High IOPS queues + low latency queues |
|---|
| 6149 | + * |
|---|
| 6150 | + * For rest of fusion adapters, 1 additional reply queue will be |
|---|
| 6151 | + * reserved for management commands, rest of reply queues |
|---|
| 6152 | + * (based on number of logical CPUs) will be used for IOs and |
|---|
| 6153 | + * referenced as IO queues. |
|---|
| 6154 | + * Total Number of reply queues = 1 + IO queues |
|---|
| 6155 | + * |
|---|
| 6156 | + * MFI adapters supports single MSI-x so single reply queue |
|---|
| 6157 | + * will be used for IO and management commands. |
|---|
| 6158 | + */ |
|---|
| 6159 | + |
|---|
| 6160 | + intr_coalescing = (scratch_pad_1 & MR_INTR_COALESCING_SUPPORT_OFFSET) ? |
|---|
| 6161 | + true : false; |
|---|
| 6162 | + if (intr_coalescing && |
|---|
| 6163 | + (num_online_cpus() >= MR_HIGH_IOPS_QUEUE_COUNT) && |
|---|
| 6164 | + (instance->msix_vectors == MEGASAS_MAX_MSIX_QUEUES)) |
|---|
| 6165 | + instance->perf_mode = MR_BALANCED_PERF_MODE; |
|---|
| 5394 | 6166 | else |
|---|
| 5395 | | - instance->msix_vectors = 0; |
|---|
| 6167 | + instance->perf_mode = MR_LATENCY_PERF_MODE; |
|---|
| 6168 | + |
|---|
| 6169 | + |
|---|
| 6170 | + if (instance->adapter_type == AERO_SERIES) { |
|---|
| 6171 | + pcie_capability_read_word(instance->pdev, PCI_EXP_LNKSTA, &lnksta); |
|---|
| 6172 | + speed = lnksta & PCI_EXP_LNKSTA_CLS; |
|---|
| 6173 | + |
|---|
| 6174 | + /* |
|---|
| 6175 | + * For Aero, if PCIe link speed is <16 GT/s, then driver should operate |
|---|
| 6176 | + * in latency perf mode and enable R1 PCI bandwidth algorithm |
|---|
| 6177 | + */ |
|---|
| 6178 | + if (speed < 0x4) { |
|---|
| 6179 | + instance->perf_mode = MR_LATENCY_PERF_MODE; |
|---|
| 6180 | + fusion->pcie_bw_limitation = true; |
|---|
| 6181 | + } |
|---|
| 6182 | + |
|---|
| 6183 | + /* |
|---|
| 6184 | + * Performance mode settings provided through module parameter-perf_mode will |
|---|
| 6185 | + * take affect only for: |
|---|
| 6186 | + * 1. Aero family of adapters. |
|---|
| 6187 | + * 2. When user sets module parameter- perf_mode in range of 0-2. |
|---|
| 6188 | + */ |
|---|
| 6189 | + if ((perf_mode >= MR_BALANCED_PERF_MODE) && |
|---|
| 6190 | + (perf_mode <= MR_LATENCY_PERF_MODE)) |
|---|
| 6191 | + instance->perf_mode = perf_mode; |
|---|
| 6192 | + /* |
|---|
| 6193 | + * If intr coalescing is not supported by controller FW, then IOPS |
|---|
| 6194 | + * and Balanced modes are not feasible. |
|---|
| 6195 | + */ |
|---|
| 6196 | + if (!intr_coalescing) |
|---|
| 6197 | + instance->perf_mode = MR_LATENCY_PERF_MODE; |
|---|
| 6198 | + |
|---|
| 6199 | + } |
|---|
| 6200 | + |
|---|
| 6201 | + if (instance->perf_mode == MR_BALANCED_PERF_MODE) |
|---|
| 6202 | + instance->low_latency_index_start = |
|---|
| 6203 | + MR_HIGH_IOPS_QUEUE_COUNT; |
|---|
| 6204 | + else |
|---|
| 6205 | + instance->low_latency_index_start = 1; |
|---|
| 6206 | + |
|---|
| 6207 | + num_msix_req = num_online_cpus() + instance->low_latency_index_start; |
|---|
| 6208 | + |
|---|
| 6209 | + instance->msix_vectors = min(num_msix_req, |
|---|
| 6210 | + instance->msix_vectors); |
|---|
| 6211 | + |
|---|
| 6212 | + megasas_alloc_irq_vectors(instance); |
|---|
| 6213 | + if (!instance->msix_vectors) |
|---|
| 6214 | + instance->msix_load_balance = false; |
|---|
| 5396 | 6215 | } |
|---|
| 5397 | 6216 | /* |
|---|
| 5398 | 6217 | * MSI-X host index 0 is common for all adapter. |
|---|
| .. | .. |
|---|
| 5417 | 6236 | megasas_setup_reply_map(instance); |
|---|
| 5418 | 6237 | |
|---|
| 5419 | 6238 | dev_info(&instance->pdev->dev, |
|---|
| 5420 | | - "firmware supports msix\t: (%d)", fw_msix_count); |
|---|
| 5421 | | - dev_info(&instance->pdev->dev, |
|---|
| 5422 | 6239 | "current msix/online cpus\t: (%d/%d)\n", |
|---|
| 5423 | 6240 | instance->msix_vectors, (unsigned int)num_online_cpus()); |
|---|
| 5424 | 6241 | dev_info(&instance->pdev->dev, |
|---|
| .. | .. |
|---|
| 5437 | 6254 | if (instance->instancet->init_adapter(instance)) |
|---|
| 5438 | 6255 | goto fail_init_adapter; |
|---|
| 5439 | 6256 | |
|---|
| 5440 | | - if (instance->adapter_type == VENTURA_SERIES) { |
|---|
| 5441 | | - scratch_pad_4 = |
|---|
| 5442 | | - readl(&instance->reg_set->outbound_scratch_pad_4); |
|---|
| 5443 | | - if ((scratch_pad_4 & MR_NVME_PAGE_SIZE_MASK) >= |
|---|
| 6257 | + if (instance->adapter_type >= VENTURA_SERIES) { |
|---|
| 6258 | + scratch_pad_3 = |
|---|
| 6259 | + megasas_readl(instance, |
|---|
| 6260 | + &instance->reg_set->outbound_scratch_pad_3); |
|---|
| 6261 | + if ((scratch_pad_3 & MR_NVME_PAGE_SIZE_MASK) >= |
|---|
| 5444 | 6262 | MR_DEFAULT_NVME_PAGE_SHIFT) |
|---|
| 5445 | 6263 | instance->nvme_page_size = |
|---|
| 5446 | | - (1 << (scratch_pad_4 & MR_NVME_PAGE_SIZE_MASK)); |
|---|
| 6264 | + (1 << (scratch_pad_3 & MR_NVME_PAGE_SIZE_MASK)); |
|---|
| 5447 | 6265 | |
|---|
| 5448 | 6266 | dev_info(&instance->pdev->dev, |
|---|
| 5449 | 6267 | "NVME page size\t: (%d)\n", instance->nvme_page_size); |
|---|
| .. | .. |
|---|
| 5454 | 6272 | megasas_setup_irqs_ioapic(instance)) |
|---|
| 5455 | 6273 | goto fail_init_adapter; |
|---|
| 5456 | 6274 | |
|---|
| 6275 | + if (instance->adapter_type != MFI_SERIES) |
|---|
| 6276 | + megasas_setup_irq_poll(instance); |
|---|
| 6277 | + |
|---|
| 5457 | 6278 | instance->instancet->enable_intr(instance); |
|---|
| 5458 | 6279 | |
|---|
| 5459 | 6280 | dev_info(&instance->pdev->dev, "INIT adapter done\n"); |
|---|
| 5460 | 6281 | |
|---|
| 5461 | 6282 | megasas_setup_jbod_map(instance); |
|---|
| 5462 | 6283 | |
|---|
| 5463 | | - /** for passthrough |
|---|
| 5464 | | - * the following function will get the PD LIST. |
|---|
| 5465 | | - */ |
|---|
| 5466 | | - memset(instance->pd_list, 0, |
|---|
| 5467 | | - (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); |
|---|
| 5468 | | - if (megasas_get_pd_list(instance) < 0) { |
|---|
| 5469 | | - dev_err(&instance->pdev->dev, "failed to get PD list\n"); |
|---|
| 6284 | + if (megasas_get_device_list(instance) != SUCCESS) { |
|---|
| 6285 | + dev_err(&instance->pdev->dev, |
|---|
| 6286 | + "%s: megasas_get_device_list failed\n", |
|---|
| 6287 | + __func__); |
|---|
| 5470 | 6288 | goto fail_get_ld_pd_list; |
|---|
| 5471 | 6289 | } |
|---|
| 5472 | 6290 | |
|---|
| 5473 | | - memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); |
|---|
| 5474 | | - |
|---|
| 5475 | 6291 | /* stream detection initialization */ |
|---|
| 5476 | | - if (instance->adapter_type == VENTURA_SERIES) { |
|---|
| 6292 | + if (instance->adapter_type >= VENTURA_SERIES) { |
|---|
| 5477 | 6293 | fusion->stream_detect_by_ld = |
|---|
| 5478 | 6294 | kcalloc(MAX_LOGICAL_DRIVES_EXT, |
|---|
| 5479 | 6295 | sizeof(struct LD_STREAM_DETECT *), |
|---|
| .. | .. |
|---|
| 5500 | 6316 | = MR_STREAM_BITMAP; |
|---|
| 5501 | 6317 | } |
|---|
| 5502 | 6318 | } |
|---|
| 5503 | | - |
|---|
| 5504 | | - if (megasas_ld_list_query(instance, |
|---|
| 5505 | | - MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) |
|---|
| 5506 | | - goto fail_get_ld_pd_list; |
|---|
| 5507 | 6319 | |
|---|
| 5508 | 6320 | /* |
|---|
| 5509 | 6321 | * Compute the max allowed sectors per IO: The controller info has two |
|---|
| .. | .. |
|---|
| 5566 | 6378 | |
|---|
| 5567 | 6379 | else { |
|---|
| 5568 | 6380 | if (instance->crash_dump_buf) |
|---|
| 5569 | | - pci_free_consistent(instance->pdev, |
|---|
| 6381 | + dma_free_coherent(&instance->pdev->dev, |
|---|
| 5570 | 6382 | CRASH_DMA_BUF_SIZE, |
|---|
| 5571 | 6383 | instance->crash_dump_buf, |
|---|
| 5572 | 6384 | instance->crash_dump_h); |
|---|
| 5573 | 6385 | instance->crash_dump_buf = NULL; |
|---|
| 5574 | 6386 | } |
|---|
| 5575 | 6387 | |
|---|
| 6388 | + if (instance->snapdump_wait_time) { |
|---|
| 6389 | + megasas_get_snapdump_properties(instance); |
|---|
| 6390 | + dev_info(&instance->pdev->dev, "Snap dump wait time\t: %d\n", |
|---|
| 6391 | + instance->snapdump_wait_time); |
|---|
| 6392 | + } |
|---|
| 5576 | 6393 | |
|---|
| 5577 | 6394 | dev_info(&instance->pdev->dev, |
|---|
| 5578 | 6395 | "pci id\t\t: (0x%04x)/(0x%04x)/(0x%04x)/(0x%04x)\n", |
|---|
| .. | .. |
|---|
| 5584 | 6401 | instance->UnevenSpanSupport ? "yes" : "no"); |
|---|
| 5585 | 6402 | dev_info(&instance->pdev->dev, "firmware crash dump : %s\n", |
|---|
| 5586 | 6403 | instance->crash_dump_drv_support ? "yes" : "no"); |
|---|
| 5587 | | - dev_info(&instance->pdev->dev, "jbod sync map : %s\n", |
|---|
| 5588 | | - instance->use_seqnum_jbod_fp ? "yes" : "no"); |
|---|
| 5589 | | - |
|---|
| 6404 | + dev_info(&instance->pdev->dev, "JBOD sequence map : %s\n", |
|---|
| 6405 | + instance->use_seqnum_jbod_fp ? "enabled" : "disabled"); |
|---|
| 5590 | 6406 | |
|---|
| 5591 | 6407 | instance->max_sectors_per_req = instance->max_num_sge * |
|---|
| 5592 | 6408 | SGE_BUFFER_SIZE / 512; |
|---|
| .. | .. |
|---|
| 5610 | 6426 | |
|---|
| 5611 | 6427 | /* Launch SR-IOV heartbeat timer */ |
|---|
| 5612 | 6428 | if (instance->requestorId) { |
|---|
| 5613 | | - if (!megasas_sriov_start_heartbeat(instance, 1)) |
|---|
| 6429 | + if (!megasas_sriov_start_heartbeat(instance, 1)) { |
|---|
| 5614 | 6430 | megasas_start_timer(instance); |
|---|
| 5615 | | - else |
|---|
| 6431 | + } else { |
|---|
| 5616 | 6432 | instance->skip_heartbeat_timer_del = 1; |
|---|
| 6433 | + goto fail_get_ld_pd_list; |
|---|
| 6434 | + } |
|---|
| 5617 | 6435 | } |
|---|
| 6436 | + |
|---|
| 6437 | + /* |
|---|
| 6438 | + * Create and start watchdog thread which will monitor |
|---|
| 6439 | + * controller state every 1 sec and trigger OCR when |
|---|
| 6440 | + * it enters fault state |
|---|
| 6441 | + */ |
|---|
| 6442 | + if (instance->adapter_type != MFI_SERIES) |
|---|
| 6443 | + if (megasas_fusion_start_watchdog(instance) != SUCCESS) |
|---|
| 6444 | + goto fail_start_watchdog; |
|---|
| 5618 | 6445 | |
|---|
| 5619 | 6446 | return 0; |
|---|
| 5620 | 6447 | |
|---|
| 6448 | +fail_start_watchdog: |
|---|
| 6449 | + if (instance->requestorId && !instance->skip_heartbeat_timer_del) |
|---|
| 6450 | + del_timer_sync(&instance->sriov_heartbeat_timer); |
|---|
| 5621 | 6451 | fail_get_ld_pd_list: |
|---|
| 5622 | 6452 | instance->instancet->disable_intr(instance); |
|---|
| 5623 | 6453 | megasas_destroy_irqs(instance); |
|---|
| .. | .. |
|---|
| 5648 | 6478 | u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1); |
|---|
| 5649 | 6479 | |
|---|
| 5650 | 6480 | if (instance->reply_queue) |
|---|
| 5651 | | - pci_free_consistent(instance->pdev, reply_q_sz, |
|---|
| 6481 | + dma_free_coherent(&instance->pdev->dev, reply_q_sz, |
|---|
| 5652 | 6482 | instance->reply_queue, instance->reply_queue_h); |
|---|
| 5653 | 6483 | |
|---|
| 5654 | 6484 | megasas_free_cmds(instance); |
|---|
| .. | .. |
|---|
| 5687 | 6517 | } |
|---|
| 5688 | 6518 | |
|---|
| 5689 | 6519 | dcmd = &cmd->frame->dcmd; |
|---|
| 5690 | | - el_info = pci_zalloc_consistent(instance->pdev, |
|---|
| 5691 | | - sizeof(struct megasas_evt_log_info), |
|---|
| 5692 | | - &el_info_h); |
|---|
| 5693 | | - |
|---|
| 6520 | + el_info = dma_alloc_coherent(&instance->pdev->dev, |
|---|
| 6521 | + sizeof(struct megasas_evt_log_info), |
|---|
| 6522 | + &el_info_h, GFP_KERNEL); |
|---|
| 5694 | 6523 | if (!el_info) { |
|---|
| 5695 | 6524 | megasas_return_cmd(instance, cmd); |
|---|
| 5696 | 6525 | return -ENOMEM; |
|---|
| .. | .. |
|---|
| 5727 | 6556 | eli->boot_seq_num = el_info->boot_seq_num; |
|---|
| 5728 | 6557 | |
|---|
| 5729 | 6558 | dcmd_failed: |
|---|
| 5730 | | - pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info), |
|---|
| 5731 | | - el_info, el_info_h); |
|---|
| 6559 | + dma_free_coherent(&instance->pdev->dev, |
|---|
| 6560 | + sizeof(struct megasas_evt_log_info), |
|---|
| 6561 | + el_info, el_info_h); |
|---|
| 5732 | 6562 | |
|---|
| 5733 | 6563 | megasas_return_cmd(instance, cmd); |
|---|
| 5734 | 6564 | |
|---|
| .. | .. |
|---|
| 5739 | 6569 | * megasas_register_aen - Registers for asynchronous event notification |
|---|
| 5740 | 6570 | * @instance: Adapter soft state |
|---|
| 5741 | 6571 | * @seq_num: The starting sequence number |
|---|
| 5742 | | - * @class_locale: Class of the event |
|---|
| 6572 | + * @class_locale_word: Class of the event |
|---|
| 5743 | 6573 | * |
|---|
| 5744 | 6574 | * This function subscribes for AEN for events beyond the @seq_num. It requests |
|---|
| 5745 | 6575 | * to be notified if and only if the event is of type @class_locale |
|---|
| .. | .. |
|---|
| 5936 | 6766 | switch (dcmd_timeout_ocr_possible(instance)) { |
|---|
| 5937 | 6767 | case INITIATE_OCR: |
|---|
| 5938 | 6768 | cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
|---|
| 6769 | + mutex_unlock(&instance->reset_mutex); |
|---|
| 5939 | 6770 | megasas_reset_fusion(instance->host, |
|---|
| 5940 | 6771 | MFI_IO_TIMEOUT_OCR); |
|---|
| 6772 | + mutex_lock(&instance->reset_mutex); |
|---|
| 5941 | 6773 | break; |
|---|
| 5942 | 6774 | case KILL_ADAPTER: |
|---|
| 5943 | 6775 | megaraid_sas_kill_hba(instance); |
|---|
| .. | .. |
|---|
| 6072 | 6904 | { |
|---|
| 6073 | 6905 | u64 consistent_mask; |
|---|
| 6074 | 6906 | struct pci_dev *pdev; |
|---|
| 6075 | | - u32 scratch_pad_2; |
|---|
| 6907 | + u32 scratch_pad_1; |
|---|
| 6076 | 6908 | |
|---|
| 6077 | 6909 | pdev = instance->pdev; |
|---|
| 6078 | 6910 | consistent_mask = (instance->adapter_type >= VENTURA_SERIES) ? |
|---|
| .. | .. |
|---|
| 6090 | 6922 | * If 32 bit DMA mask fails, then try for 64 bit mask |
|---|
| 6091 | 6923 | * for FW capable of handling 64 bit DMA. |
|---|
| 6092 | 6924 | */ |
|---|
| 6093 | | - scratch_pad_2 = readl |
|---|
| 6094 | | - (&instance->reg_set->outbound_scratch_pad_2); |
|---|
| 6925 | + scratch_pad_1 = megasas_readl |
|---|
| 6926 | + (instance, &instance->reg_set->outbound_scratch_pad_1); |
|---|
| 6095 | 6927 | |
|---|
| 6096 | | - if (!(scratch_pad_2 & MR_CAN_HANDLE_64_BIT_DMA_OFFSET)) |
|---|
| 6928 | + if (!(scratch_pad_1 & MR_CAN_HANDLE_64_BIT_DMA_OFFSET)) |
|---|
| 6097 | 6929 | goto fail_set_dma_mask; |
|---|
| 6098 | 6930 | else if (dma_set_mask_and_coherent(&pdev->dev, |
|---|
| 6099 | 6931 | DMA_BIT_MASK(63))) |
|---|
| .. | .. |
|---|
| 6108 | 6940 | instance->consistent_mask_64bit = true; |
|---|
| 6109 | 6941 | |
|---|
| 6110 | 6942 | dev_info(&pdev->dev, "%s bit DMA mask and %s bit consistent mask\n", |
|---|
| 6111 | | - ((*pdev->dev.dma_mask == DMA_BIT_MASK(64)) ? "63" : "32"), |
|---|
| 6943 | + ((*pdev->dev.dma_mask == DMA_BIT_MASK(63)) ? "63" : "32"), |
|---|
| 6112 | 6944 | (instance->consistent_mask_64bit ? "63" : "32")); |
|---|
| 6113 | 6945 | |
|---|
| 6114 | 6946 | return 0; |
|---|
| .. | .. |
|---|
| 6122 | 6954 | /* |
|---|
| 6123 | 6955 | * megasas_set_adapter_type - Set adapter type. |
|---|
| 6124 | 6956 | * Supported controllers can be divided in |
|---|
| 6125 | | - * 4 categories- enum MR_ADAPTER_TYPE { |
|---|
| 6126 | | - * MFI_SERIES = 1, |
|---|
| 6127 | | - * THUNDERBOLT_SERIES = 2, |
|---|
| 6128 | | - * INVADER_SERIES = 3, |
|---|
| 6129 | | - * VENTURA_SERIES = 4, |
|---|
| 6130 | | - * }; |
|---|
| 6957 | + * different categories- |
|---|
| 6958 | + * enum MR_ADAPTER_TYPE { |
|---|
| 6959 | + * MFI_SERIES = 1, |
|---|
| 6960 | + * THUNDERBOLT_SERIES = 2, |
|---|
| 6961 | + * INVADER_SERIES = 3, |
|---|
| 6962 | + * VENTURA_SERIES = 4, |
|---|
| 6963 | + * AERO_SERIES = 5, |
|---|
| 6964 | + * }; |
|---|
| 6131 | 6965 | * @instance: Adapter soft state |
|---|
| 6132 | 6966 | * return: void |
|---|
| 6133 | 6967 | */ |
|---|
| .. | .. |
|---|
| 6138 | 6972 | instance->adapter_type = MFI_SERIES; |
|---|
| 6139 | 6973 | } else { |
|---|
| 6140 | 6974 | switch (instance->pdev->device) { |
|---|
| 6975 | + case PCI_DEVICE_ID_LSI_AERO_10E1: |
|---|
| 6976 | + case PCI_DEVICE_ID_LSI_AERO_10E2: |
|---|
| 6977 | + case PCI_DEVICE_ID_LSI_AERO_10E5: |
|---|
| 6978 | + case PCI_DEVICE_ID_LSI_AERO_10E6: |
|---|
| 6979 | + instance->adapter_type = AERO_SERIES; |
|---|
| 6980 | + break; |
|---|
| 6141 | 6981 | case PCI_DEVICE_ID_LSI_VENTURA: |
|---|
| 6142 | 6982 | case PCI_DEVICE_ID_LSI_CRUSADER: |
|---|
| 6143 | 6983 | case PCI_DEVICE_ID_LSI_HARPOON: |
|---|
| .. | .. |
|---|
| 6167 | 7007 | |
|---|
| 6168 | 7008 | static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance) |
|---|
| 6169 | 7009 | { |
|---|
| 6170 | | - instance->producer = pci_alloc_consistent(instance->pdev, sizeof(u32), |
|---|
| 6171 | | - &instance->producer_h); |
|---|
| 6172 | | - instance->consumer = pci_alloc_consistent(instance->pdev, sizeof(u32), |
|---|
| 6173 | | - &instance->consumer_h); |
|---|
| 7010 | + instance->producer = dma_alloc_coherent(&instance->pdev->dev, |
|---|
| 7011 | + sizeof(u32), &instance->producer_h, GFP_KERNEL); |
|---|
| 7012 | + instance->consumer = dma_alloc_coherent(&instance->pdev->dev, |
|---|
| 7013 | + sizeof(u32), &instance->consumer_h, GFP_KERNEL); |
|---|
| 6174 | 7014 | |
|---|
| 6175 | 7015 | if (!instance->producer || !instance->consumer) { |
|---|
| 6176 | 7016 | dev_err(&instance->pdev->dev, |
|---|
| .. | .. |
|---|
| 6205 | 7045 | if (megasas_alloc_mfi_ctrl_mem(instance)) |
|---|
| 6206 | 7046 | goto fail; |
|---|
| 6207 | 7047 | break; |
|---|
| 7048 | + case AERO_SERIES: |
|---|
| 6208 | 7049 | case VENTURA_SERIES: |
|---|
| 6209 | 7050 | case THUNDERBOLT_SERIES: |
|---|
| 6210 | 7051 | case INVADER_SERIES: |
|---|
| .. | .. |
|---|
| 6232 | 7073 | kfree(instance->reply_map); |
|---|
| 6233 | 7074 | if (instance->adapter_type == MFI_SERIES) { |
|---|
| 6234 | 7075 | if (instance->producer) |
|---|
| 6235 | | - pci_free_consistent(instance->pdev, sizeof(u32), |
|---|
| 7076 | + dma_free_coherent(&instance->pdev->dev, sizeof(u32), |
|---|
| 6236 | 7077 | instance->producer, |
|---|
| 6237 | 7078 | instance->producer_h); |
|---|
| 6238 | 7079 | if (instance->consumer) |
|---|
| 6239 | | - pci_free_consistent(instance->pdev, sizeof(u32), |
|---|
| 7080 | + dma_free_coherent(&instance->pdev->dev, sizeof(u32), |
|---|
| 6240 | 7081 | instance->consumer, |
|---|
| 6241 | 7082 | instance->consumer_h); |
|---|
| 6242 | 7083 | } else { |
|---|
| .. | .. |
|---|
| 6248 | 7089 | * megasas_alloc_ctrl_dma_buffers - Allocate consistent DMA buffers during |
|---|
| 6249 | 7090 | * driver load time |
|---|
| 6250 | 7091 | * |
|---|
| 6251 | | - * @instance- Adapter soft instance |
|---|
| 6252 | | - * @return- O for SUCCESS |
|---|
| 7092 | + * @instance: Adapter soft instance |
|---|
| 7093 | + * |
|---|
| 7094 | + * @return: O for SUCCESS |
|---|
| 6253 | 7095 | */ |
|---|
| 6254 | 7096 | static inline |
|---|
| 6255 | 7097 | int megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance) |
|---|
| .. | .. |
|---|
| 6257 | 7099 | struct pci_dev *pdev = instance->pdev; |
|---|
| 6258 | 7100 | struct fusion_context *fusion = instance->ctrl_context; |
|---|
| 6259 | 7101 | |
|---|
| 6260 | | - instance->evt_detail = |
|---|
| 6261 | | - pci_alloc_consistent(pdev, |
|---|
| 6262 | | - sizeof(struct megasas_evt_detail), |
|---|
| 6263 | | - &instance->evt_detail_h); |
|---|
| 7102 | + instance->evt_detail = dma_alloc_coherent(&pdev->dev, |
|---|
| 7103 | + sizeof(struct megasas_evt_detail), |
|---|
| 7104 | + &instance->evt_detail_h, GFP_KERNEL); |
|---|
| 6264 | 7105 | |
|---|
| 6265 | 7106 | if (!instance->evt_detail) { |
|---|
| 6266 | 7107 | dev_err(&instance->pdev->dev, |
|---|
| .. | .. |
|---|
| 6280 | 7121 | "Failed to allocate PD list buffer\n"); |
|---|
| 6281 | 7122 | return -ENOMEM; |
|---|
| 6282 | 7123 | } |
|---|
| 7124 | + |
|---|
| 7125 | + instance->snapdump_prop = dma_alloc_coherent(&pdev->dev, |
|---|
| 7126 | + sizeof(struct MR_SNAPDUMP_PROPERTIES), |
|---|
| 7127 | + &instance->snapdump_prop_h, GFP_KERNEL); |
|---|
| 7128 | + |
|---|
| 7129 | + if (!instance->snapdump_prop) |
|---|
| 7130 | + dev_err(&pdev->dev, |
|---|
| 7131 | + "Failed to allocate snapdump properties buffer\n"); |
|---|
| 7132 | + |
|---|
| 7133 | + instance->host_device_list_buf = dma_alloc_coherent(&pdev->dev, |
|---|
| 7134 | + HOST_DEVICE_LIST_SZ, |
|---|
| 7135 | + &instance->host_device_list_buf_h, |
|---|
| 7136 | + GFP_KERNEL); |
|---|
| 7137 | + |
|---|
| 7138 | + if (!instance->host_device_list_buf) { |
|---|
| 7139 | + dev_err(&pdev->dev, |
|---|
| 7140 | + "Failed to allocate targetid list buffer\n"); |
|---|
| 7141 | + return -ENOMEM; |
|---|
| 7142 | + } |
|---|
| 7143 | + |
|---|
| 6283 | 7144 | } |
|---|
| 6284 | 7145 | |
|---|
| 6285 | 7146 | instance->pd_list_buf = |
|---|
| 6286 | | - pci_alloc_consistent(pdev, |
|---|
| 7147 | + dma_alloc_coherent(&pdev->dev, |
|---|
| 6287 | 7148 | MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), |
|---|
| 6288 | | - &instance->pd_list_buf_h); |
|---|
| 7149 | + &instance->pd_list_buf_h, GFP_KERNEL); |
|---|
| 6289 | 7150 | |
|---|
| 6290 | 7151 | if (!instance->pd_list_buf) { |
|---|
| 6291 | 7152 | dev_err(&pdev->dev, "Failed to allocate PD list buffer\n"); |
|---|
| .. | .. |
|---|
| 6293 | 7154 | } |
|---|
| 6294 | 7155 | |
|---|
| 6295 | 7156 | instance->ctrl_info_buf = |
|---|
| 6296 | | - pci_alloc_consistent(pdev, |
|---|
| 7157 | + dma_alloc_coherent(&pdev->dev, |
|---|
| 6297 | 7158 | sizeof(struct megasas_ctrl_info), |
|---|
| 6298 | | - &instance->ctrl_info_buf_h); |
|---|
| 7159 | + &instance->ctrl_info_buf_h, GFP_KERNEL); |
|---|
| 6299 | 7160 | |
|---|
| 6300 | 7161 | if (!instance->ctrl_info_buf) { |
|---|
| 6301 | 7162 | dev_err(&pdev->dev, |
|---|
| .. | .. |
|---|
| 6304 | 7165 | } |
|---|
| 6305 | 7166 | |
|---|
| 6306 | 7167 | instance->ld_list_buf = |
|---|
| 6307 | | - pci_alloc_consistent(pdev, |
|---|
| 7168 | + dma_alloc_coherent(&pdev->dev, |
|---|
| 6308 | 7169 | sizeof(struct MR_LD_LIST), |
|---|
| 6309 | | - &instance->ld_list_buf_h); |
|---|
| 7170 | + &instance->ld_list_buf_h, GFP_KERNEL); |
|---|
| 6310 | 7171 | |
|---|
| 6311 | 7172 | if (!instance->ld_list_buf) { |
|---|
| 6312 | 7173 | dev_err(&pdev->dev, "Failed to allocate LD list buffer\n"); |
|---|
| .. | .. |
|---|
| 6314 | 7175 | } |
|---|
| 6315 | 7176 | |
|---|
| 6316 | 7177 | instance->ld_targetid_list_buf = |
|---|
| 6317 | | - pci_alloc_consistent(pdev, |
|---|
| 6318 | | - sizeof(struct MR_LD_TARGETID_LIST), |
|---|
| 6319 | | - &instance->ld_targetid_list_buf_h); |
|---|
| 7178 | + dma_alloc_coherent(&pdev->dev, |
|---|
| 7179 | + sizeof(struct MR_LD_TARGETID_LIST), |
|---|
| 7180 | + &instance->ld_targetid_list_buf_h, GFP_KERNEL); |
|---|
| 6320 | 7181 | |
|---|
| 6321 | 7182 | if (!instance->ld_targetid_list_buf) { |
|---|
| 6322 | 7183 | dev_err(&pdev->dev, |
|---|
| .. | .. |
|---|
| 6326 | 7187 | |
|---|
| 6327 | 7188 | if (!reset_devices) { |
|---|
| 6328 | 7189 | instance->system_info_buf = |
|---|
| 6329 | | - pci_alloc_consistent(pdev, |
|---|
| 6330 | | - sizeof(struct MR_DRV_SYSTEM_INFO), |
|---|
| 6331 | | - &instance->system_info_h); |
|---|
| 7190 | + dma_alloc_coherent(&pdev->dev, |
|---|
| 7191 | + sizeof(struct MR_DRV_SYSTEM_INFO), |
|---|
| 7192 | + &instance->system_info_h, GFP_KERNEL); |
|---|
| 6332 | 7193 | instance->pd_info = |
|---|
| 6333 | | - pci_alloc_consistent(pdev, |
|---|
| 6334 | | - sizeof(struct MR_PD_INFO), |
|---|
| 6335 | | - &instance->pd_info_h); |
|---|
| 7194 | + dma_alloc_coherent(&pdev->dev, |
|---|
| 7195 | + sizeof(struct MR_PD_INFO), |
|---|
| 7196 | + &instance->pd_info_h, GFP_KERNEL); |
|---|
| 6336 | 7197 | instance->tgt_prop = |
|---|
| 6337 | | - pci_alloc_consistent(pdev, |
|---|
| 6338 | | - sizeof(struct MR_TARGET_PROPERTIES), |
|---|
| 6339 | | - &instance->tgt_prop_h); |
|---|
| 7198 | + dma_alloc_coherent(&pdev->dev, |
|---|
| 7199 | + sizeof(struct MR_TARGET_PROPERTIES), |
|---|
| 7200 | + &instance->tgt_prop_h, GFP_KERNEL); |
|---|
| 6340 | 7201 | instance->crash_dump_buf = |
|---|
| 6341 | | - pci_alloc_consistent(pdev, |
|---|
| 6342 | | - CRASH_DMA_BUF_SIZE, |
|---|
| 6343 | | - &instance->crash_dump_h); |
|---|
| 7202 | + dma_alloc_coherent(&pdev->dev, CRASH_DMA_BUF_SIZE, |
|---|
| 7203 | + &instance->crash_dump_h, GFP_KERNEL); |
|---|
| 6344 | 7204 | |
|---|
| 6345 | 7205 | if (!instance->system_info_buf) |
|---|
| 6346 | 7206 | dev_err(&instance->pdev->dev, |
|---|
| .. | .. |
|---|
| 6376 | 7236 | struct fusion_context *fusion = instance->ctrl_context; |
|---|
| 6377 | 7237 | |
|---|
| 6378 | 7238 | if (instance->evt_detail) |
|---|
| 6379 | | - pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), |
|---|
| 7239 | + dma_free_coherent(&pdev->dev, sizeof(struct megasas_evt_detail), |
|---|
| 6380 | 7240 | instance->evt_detail, |
|---|
| 6381 | 7241 | instance->evt_detail_h); |
|---|
| 6382 | 7242 | |
|---|
| .. | .. |
|---|
| 6387 | 7247 | fusion->ioc_init_request_phys); |
|---|
| 6388 | 7248 | |
|---|
| 6389 | 7249 | if (instance->pd_list_buf) |
|---|
| 6390 | | - pci_free_consistent(pdev, |
|---|
| 7250 | + dma_free_coherent(&pdev->dev, |
|---|
| 6391 | 7251 | MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), |
|---|
| 6392 | 7252 | instance->pd_list_buf, |
|---|
| 6393 | 7253 | instance->pd_list_buf_h); |
|---|
| 6394 | 7254 | |
|---|
| 6395 | 7255 | if (instance->ld_list_buf) |
|---|
| 6396 | | - pci_free_consistent(pdev, sizeof(struct MR_LD_LIST), |
|---|
| 7256 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_LD_LIST), |
|---|
| 6397 | 7257 | instance->ld_list_buf, |
|---|
| 6398 | 7258 | instance->ld_list_buf_h); |
|---|
| 6399 | 7259 | |
|---|
| 6400 | 7260 | if (instance->ld_targetid_list_buf) |
|---|
| 6401 | | - pci_free_consistent(pdev, sizeof(struct MR_LD_TARGETID_LIST), |
|---|
| 7261 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_LD_TARGETID_LIST), |
|---|
| 6402 | 7262 | instance->ld_targetid_list_buf, |
|---|
| 6403 | 7263 | instance->ld_targetid_list_buf_h); |
|---|
| 6404 | 7264 | |
|---|
| 6405 | 7265 | if (instance->ctrl_info_buf) |
|---|
| 6406 | | - pci_free_consistent(pdev, sizeof(struct megasas_ctrl_info), |
|---|
| 7266 | + dma_free_coherent(&pdev->dev, sizeof(struct megasas_ctrl_info), |
|---|
| 6407 | 7267 | instance->ctrl_info_buf, |
|---|
| 6408 | 7268 | instance->ctrl_info_buf_h); |
|---|
| 6409 | 7269 | |
|---|
| 6410 | 7270 | if (instance->system_info_buf) |
|---|
| 6411 | | - pci_free_consistent(pdev, sizeof(struct MR_DRV_SYSTEM_INFO), |
|---|
| 7271 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_DRV_SYSTEM_INFO), |
|---|
| 6412 | 7272 | instance->system_info_buf, |
|---|
| 6413 | 7273 | instance->system_info_h); |
|---|
| 6414 | 7274 | |
|---|
| 6415 | 7275 | if (instance->pd_info) |
|---|
| 6416 | | - pci_free_consistent(pdev, sizeof(struct MR_PD_INFO), |
|---|
| 7276 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_PD_INFO), |
|---|
| 6417 | 7277 | instance->pd_info, instance->pd_info_h); |
|---|
| 6418 | 7278 | |
|---|
| 6419 | 7279 | if (instance->tgt_prop) |
|---|
| 6420 | | - pci_free_consistent(pdev, sizeof(struct MR_TARGET_PROPERTIES), |
|---|
| 7280 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_TARGET_PROPERTIES), |
|---|
| 6421 | 7281 | instance->tgt_prop, instance->tgt_prop_h); |
|---|
| 6422 | 7282 | |
|---|
| 6423 | 7283 | if (instance->crash_dump_buf) |
|---|
| 6424 | | - pci_free_consistent(pdev, CRASH_DMA_BUF_SIZE, |
|---|
| 7284 | + dma_free_coherent(&pdev->dev, CRASH_DMA_BUF_SIZE, |
|---|
| 6425 | 7285 | instance->crash_dump_buf, |
|---|
| 6426 | 7286 | instance->crash_dump_h); |
|---|
| 7287 | + |
|---|
| 7288 | + if (instance->snapdump_prop) |
|---|
| 7289 | + dma_free_coherent(&pdev->dev, |
|---|
| 7290 | + sizeof(struct MR_SNAPDUMP_PROPERTIES), |
|---|
| 7291 | + instance->snapdump_prop, |
|---|
| 7292 | + instance->snapdump_prop_h); |
|---|
| 7293 | + |
|---|
| 7294 | + if (instance->host_device_list_buf) |
|---|
| 7295 | + dma_free_coherent(&pdev->dev, |
|---|
| 7296 | + HOST_DEVICE_LIST_SZ, |
|---|
| 7297 | + instance->host_device_list_buf, |
|---|
| 7298 | + instance->host_device_list_buf_h); |
|---|
| 7299 | + |
|---|
| 6427 | 7300 | } |
|---|
| 6428 | 7301 | |
|---|
| 6429 | 7302 | /* |
|---|
| .. | .. |
|---|
| 6447 | 7320 | INIT_LIST_HEAD(&instance->internal_reset_pending_q); |
|---|
| 6448 | 7321 | |
|---|
| 6449 | 7322 | atomic_set(&instance->fw_outstanding, 0); |
|---|
| 7323 | + atomic64_set(&instance->total_io_count, 0); |
|---|
| 6450 | 7324 | |
|---|
| 6451 | 7325 | init_waitqueue_head(&instance->int_cmd_wait_q); |
|---|
| 6452 | 7326 | init_waitqueue_head(&instance->abort_cmd_wait_q); |
|---|
| .. | .. |
|---|
| 6469 | 7343 | instance->last_time = 0; |
|---|
| 6470 | 7344 | instance->disableOnlineCtrlReset = 1; |
|---|
| 6471 | 7345 | instance->UnevenSpanSupport = 0; |
|---|
| 7346 | + instance->smp_affinity_enable = smp_affinity_enable ? true : false; |
|---|
| 7347 | + instance->msix_load_balance = false; |
|---|
| 6472 | 7348 | |
|---|
| 6473 | | - if (instance->adapter_type != MFI_SERIES) { |
|---|
| 7349 | + if (instance->adapter_type != MFI_SERIES) |
|---|
| 6474 | 7350 | INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq); |
|---|
| 6475 | | - INIT_WORK(&instance->crash_init, megasas_fusion_crash_dump_wq); |
|---|
| 6476 | | - } else { |
|---|
| 7351 | + else |
|---|
| 6477 | 7352 | INIT_WORK(&instance->work_init, process_fw_state_change_wq); |
|---|
| 6478 | | - } |
|---|
| 6479 | 7353 | } |
|---|
| 6480 | 7354 | |
|---|
| 6481 | 7355 | /** |
|---|
| .. | .. |
|---|
| 6490 | 7364 | struct Scsi_Host *host; |
|---|
| 6491 | 7365 | struct megasas_instance *instance; |
|---|
| 6492 | 7366 | u16 control = 0; |
|---|
| 7367 | + |
|---|
| 7368 | + switch (pdev->device) { |
|---|
| 7369 | + case PCI_DEVICE_ID_LSI_AERO_10E0: |
|---|
| 7370 | + case PCI_DEVICE_ID_LSI_AERO_10E3: |
|---|
| 7371 | + case PCI_DEVICE_ID_LSI_AERO_10E4: |
|---|
| 7372 | + case PCI_DEVICE_ID_LSI_AERO_10E7: |
|---|
| 7373 | + dev_err(&pdev->dev, "Adapter is in non secure mode\n"); |
|---|
| 7374 | + return 1; |
|---|
| 7375 | + case PCI_DEVICE_ID_LSI_AERO_10E1: |
|---|
| 7376 | + case PCI_DEVICE_ID_LSI_AERO_10E5: |
|---|
| 7377 | + dev_info(&pdev->dev, "Adapter is in configurable secure mode\n"); |
|---|
| 7378 | + break; |
|---|
| 7379 | + } |
|---|
| 6493 | 7380 | |
|---|
| 6494 | 7381 | /* Reset MSI-X in the kdump kernel */ |
|---|
| 6495 | 7382 | if (reset_devices) { |
|---|
| .. | .. |
|---|
| 6549 | 7436 | if (instance->requestorId) { |
|---|
| 6550 | 7437 | if (instance->PlasmaFW111) { |
|---|
| 6551 | 7438 | instance->vf_affiliation_111 = |
|---|
| 6552 | | - pci_alloc_consistent(pdev, sizeof(struct MR_LD_VF_AFFILIATION_111), |
|---|
| 6553 | | - &instance->vf_affiliation_111_h); |
|---|
| 7439 | + dma_alloc_coherent(&pdev->dev, |
|---|
| 7440 | + sizeof(struct MR_LD_VF_AFFILIATION_111), |
|---|
| 7441 | + &instance->vf_affiliation_111_h, |
|---|
| 7442 | + GFP_KERNEL); |
|---|
| 6554 | 7443 | if (!instance->vf_affiliation_111) |
|---|
| 6555 | 7444 | dev_warn(&pdev->dev, "Can't allocate " |
|---|
| 6556 | 7445 | "memory for VF affiliation buffer\n"); |
|---|
| 6557 | 7446 | } else { |
|---|
| 6558 | 7447 | instance->vf_affiliation = |
|---|
| 6559 | | - pci_alloc_consistent(pdev, |
|---|
| 6560 | | - (MAX_LOGICAL_DRIVES + 1) * |
|---|
| 6561 | | - sizeof(struct MR_LD_VF_AFFILIATION), |
|---|
| 6562 | | - &instance->vf_affiliation_h); |
|---|
| 7448 | + dma_alloc_coherent(&pdev->dev, |
|---|
| 7449 | + (MAX_LOGICAL_DRIVES + 1) * |
|---|
| 7450 | + sizeof(struct MR_LD_VF_AFFILIATION), |
|---|
| 7451 | + &instance->vf_affiliation_h, |
|---|
| 7452 | + GFP_KERNEL); |
|---|
| 6563 | 7453 | if (!instance->vf_affiliation) |
|---|
| 6564 | 7454 | dev_warn(&pdev->dev, "Can't allocate " |
|---|
| 6565 | 7455 | "memory for VF affiliation buffer\n"); |
|---|
| .. | .. |
|---|
| 6589 | 7479 | /* |
|---|
| 6590 | 7480 | * Trigger SCSI to scan our drives |
|---|
| 6591 | 7481 | */ |
|---|
| 6592 | | - scsi_scan_host(host); |
|---|
| 7482 | + if (!instance->enable_fw_dev_list || |
|---|
| 7483 | + (instance->host_device_list_buf->count > 0)) |
|---|
| 7484 | + scsi_scan_host(host); |
|---|
| 6593 | 7485 | |
|---|
| 6594 | 7486 | /* |
|---|
| 6595 | 7487 | * Initiate AEN (Asynchronous Event Notification) |
|---|
| .. | .. |
|---|
| 6599 | 7491 | goto fail_start_aen; |
|---|
| 6600 | 7492 | } |
|---|
| 6601 | 7493 | |
|---|
| 7494 | + megasas_setup_debugfs(instance); |
|---|
| 7495 | + |
|---|
| 6602 | 7496 | /* Get current SR-IOV LD/VF affiliation */ |
|---|
| 6603 | 7497 | if (instance->requestorId) |
|---|
| 6604 | 7498 | megasas_get_ld_vf_affiliation(instance, 1); |
|---|
| .. | .. |
|---|
| 6606 | 7500 | return 0; |
|---|
| 6607 | 7501 | |
|---|
| 6608 | 7502 | fail_start_aen: |
|---|
| 7503 | + instance->unload = 1; |
|---|
| 7504 | + scsi_remove_host(instance->host); |
|---|
| 6609 | 7505 | fail_io_attach: |
|---|
| 6610 | 7506 | megasas_mgmt_info.count--; |
|---|
| 6611 | 7507 | megasas_mgmt_info.max_index--; |
|---|
| 6612 | 7508 | megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL; |
|---|
| 7509 | + |
|---|
| 7510 | + if (instance->requestorId && !instance->skip_heartbeat_timer_del) |
|---|
| 7511 | + del_timer_sync(&instance->sriov_heartbeat_timer); |
|---|
| 6613 | 7512 | |
|---|
| 6614 | 7513 | instance->instancet->disable_intr(instance); |
|---|
| 6615 | 7514 | megasas_destroy_irqs(instance); |
|---|
| .. | .. |
|---|
| 6618 | 7517 | megasas_release_fusion(instance); |
|---|
| 6619 | 7518 | else |
|---|
| 6620 | 7519 | megasas_release_mfi(instance); |
|---|
| 7520 | + |
|---|
| 6621 | 7521 | if (instance->msix_vectors) |
|---|
| 6622 | 7522 | pci_free_irq_vectors(instance->pdev); |
|---|
| 7523 | + instance->msix_vectors = 0; |
|---|
| 7524 | + |
|---|
| 7525 | + if (instance->fw_crash_state != UNAVAILABLE) |
|---|
| 7526 | + megasas_free_host_crash_buffer(instance); |
|---|
| 7527 | + |
|---|
| 7528 | + if (instance->adapter_type != MFI_SERIES) |
|---|
| 7529 | + megasas_fusion_stop_watchdog(instance); |
|---|
| 6623 | 7530 | fail_init_mfi: |
|---|
| 6624 | 7531 | scsi_host_put(host); |
|---|
| 6625 | 7532 | fail_alloc_instance: |
|---|
| .. | .. |
|---|
| 6730 | 7637 | static int |
|---|
| 6731 | 7638 | megasas_suspend(struct pci_dev *pdev, pm_message_t state) |
|---|
| 6732 | 7639 | { |
|---|
| 6733 | | - struct Scsi_Host *host; |
|---|
| 6734 | 7640 | struct megasas_instance *instance; |
|---|
| 6735 | 7641 | |
|---|
| 6736 | 7642 | instance = pci_get_drvdata(pdev); |
|---|
| 6737 | | - host = instance->host; |
|---|
| 7643 | + |
|---|
| 7644 | + if (!instance) |
|---|
| 7645 | + return 0; |
|---|
| 7646 | + |
|---|
| 6738 | 7647 | instance->unload = 1; |
|---|
| 7648 | + |
|---|
| 7649 | + dev_info(&pdev->dev, "%s is called\n", __func__); |
|---|
| 6739 | 7650 | |
|---|
| 6740 | 7651 | /* Shutdown SR-IOV heartbeat timer */ |
|---|
| 6741 | 7652 | if (instance->requestorId && !instance->skip_heartbeat_timer_del) |
|---|
| 6742 | 7653 | del_timer_sync(&instance->sriov_heartbeat_timer); |
|---|
| 7654 | + |
|---|
| 7655 | + /* Stop the FW fault detection watchdog */ |
|---|
| 7656 | + if (instance->adapter_type != MFI_SERIES) |
|---|
| 7657 | + megasas_fusion_stop_watchdog(instance); |
|---|
| 6743 | 7658 | |
|---|
| 6744 | 7659 | megasas_flush_cache(instance); |
|---|
| 6745 | 7660 | megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN); |
|---|
| .. | .. |
|---|
| 6779 | 7694 | int rval; |
|---|
| 6780 | 7695 | struct Scsi_Host *host; |
|---|
| 6781 | 7696 | struct megasas_instance *instance; |
|---|
| 6782 | | - int irq_flags = PCI_IRQ_LEGACY; |
|---|
| 7697 | + u32 status_reg; |
|---|
| 6783 | 7698 | |
|---|
| 6784 | 7699 | instance = pci_get_drvdata(pdev); |
|---|
| 7700 | + |
|---|
| 7701 | + if (!instance) |
|---|
| 7702 | + return 0; |
|---|
| 7703 | + |
|---|
| 6785 | 7704 | host = instance->host; |
|---|
| 6786 | 7705 | pci_set_power_state(pdev, PCI_D0); |
|---|
| 6787 | 7706 | pci_enable_wake(pdev, PCI_D0, 0); |
|---|
| 6788 | 7707 | pci_restore_state(pdev); |
|---|
| 6789 | 7708 | |
|---|
| 7709 | + dev_info(&pdev->dev, "%s is called\n", __func__); |
|---|
| 6790 | 7710 | /* |
|---|
| 6791 | 7711 | * PCI prepping: enable device set bus mastering and dma mask |
|---|
| 6792 | 7712 | */ |
|---|
| .. | .. |
|---|
| 6802 | 7722 | /* |
|---|
| 6803 | 7723 | * We expect the FW state to be READY |
|---|
| 6804 | 7724 | */ |
|---|
| 6805 | | - if (megasas_transition_to_ready(instance, 0)) |
|---|
| 6806 | | - goto fail_ready_state; |
|---|
| 6807 | 7725 | |
|---|
| 7726 | + if (megasas_transition_to_ready(instance, 0)) { |
|---|
| 7727 | + dev_info(&instance->pdev->dev, |
|---|
| 7728 | + "Failed to transition controller to ready from %s!\n", |
|---|
| 7729 | + __func__); |
|---|
| 7730 | + if (instance->adapter_type != MFI_SERIES) { |
|---|
| 7731 | + status_reg = |
|---|
| 7732 | + instance->instancet->read_fw_status_reg(instance); |
|---|
| 7733 | + if (!(status_reg & MFI_RESET_ADAPTER) || |
|---|
| 7734 | + ((megasas_adp_reset_wait_for_ready |
|---|
| 7735 | + (instance, true, 0)) == FAILED)) |
|---|
| 7736 | + goto fail_ready_state; |
|---|
| 7737 | + } else { |
|---|
| 7738 | + atomic_set(&instance->fw_reset_no_pci_access, 1); |
|---|
| 7739 | + instance->instancet->adp_reset |
|---|
| 7740 | + (instance, instance->reg_set); |
|---|
| 7741 | + atomic_set(&instance->fw_reset_no_pci_access, 0); |
|---|
| 7742 | + |
|---|
| 7743 | + /* waiting for about 30 seconds before retry */ |
|---|
| 7744 | + ssleep(30); |
|---|
| 7745 | + |
|---|
| 7746 | + if (megasas_transition_to_ready(instance, 0)) |
|---|
| 7747 | + goto fail_ready_state; |
|---|
| 7748 | + } |
|---|
| 7749 | + |
|---|
| 7750 | + dev_info(&instance->pdev->dev, |
|---|
| 7751 | + "FW restarted successfully from %s!\n", |
|---|
| 7752 | + __func__); |
|---|
| 7753 | + } |
|---|
| 6808 | 7754 | if (megasas_set_dma_mask(instance)) |
|---|
| 6809 | 7755 | goto fail_set_dma_mask; |
|---|
| 6810 | 7756 | |
|---|
| .. | .. |
|---|
| 6816 | 7762 | atomic_set(&instance->ldio_outstanding, 0); |
|---|
| 6817 | 7763 | |
|---|
| 6818 | 7764 | /* Now re-enable MSI-X */ |
|---|
| 6819 | | - if (instance->msix_vectors) { |
|---|
| 6820 | | - irq_flags = PCI_IRQ_MSIX; |
|---|
| 6821 | | - if (smp_affinity_enable) |
|---|
| 6822 | | - irq_flags |= PCI_IRQ_AFFINITY; |
|---|
| 7765 | + if (instance->msix_vectors) |
|---|
| 7766 | + megasas_alloc_irq_vectors(instance); |
|---|
| 7767 | + |
|---|
| 7768 | + if (!instance->msix_vectors) { |
|---|
| 7769 | + rval = pci_alloc_irq_vectors(instance->pdev, 1, 1, |
|---|
| 7770 | + PCI_IRQ_LEGACY); |
|---|
| 7771 | + if (rval < 0) |
|---|
| 7772 | + goto fail_reenable_msix; |
|---|
| 6823 | 7773 | } |
|---|
| 6824 | | - rval = pci_alloc_irq_vectors(instance->pdev, 1, |
|---|
| 6825 | | - instance->msix_vectors ? |
|---|
| 6826 | | - instance->msix_vectors : 1, irq_flags); |
|---|
| 6827 | | - if (rval < 0) |
|---|
| 6828 | | - goto fail_reenable_msix; |
|---|
| 6829 | 7774 | |
|---|
| 6830 | 7775 | megasas_setup_reply_map(instance); |
|---|
| 6831 | 7776 | |
|---|
| .. | .. |
|---|
| 6856 | 7801 | megasas_setup_irqs_ioapic(instance)) |
|---|
| 6857 | 7802 | goto fail_init_mfi; |
|---|
| 6858 | 7803 | |
|---|
| 7804 | + if (instance->adapter_type != MFI_SERIES) |
|---|
| 7805 | + megasas_setup_irq_poll(instance); |
|---|
| 7806 | + |
|---|
| 6859 | 7807 | /* Re-launch SR-IOV heartbeat timer */ |
|---|
| 6860 | 7808 | if (instance->requestorId) { |
|---|
| 6861 | 7809 | if (!megasas_sriov_start_heartbeat(instance, 0)) |
|---|
| .. | .. |
|---|
| 6876 | 7824 | if (megasas_start_aen(instance)) |
|---|
| 6877 | 7825 | dev_err(&instance->pdev->dev, "Start AEN failed\n"); |
|---|
| 6878 | 7826 | |
|---|
| 7827 | + /* Re-launch FW fault watchdog */ |
|---|
| 7828 | + if (instance->adapter_type != MFI_SERIES) |
|---|
| 7829 | + if (megasas_fusion_start_watchdog(instance) != SUCCESS) |
|---|
| 7830 | + goto fail_start_watchdog; |
|---|
| 7831 | + |
|---|
| 6879 | 7832 | return 0; |
|---|
| 6880 | 7833 | |
|---|
| 7834 | +fail_start_watchdog: |
|---|
| 7835 | + if (instance->requestorId && !instance->skip_heartbeat_timer_del) |
|---|
| 7836 | + del_timer_sync(&instance->sriov_heartbeat_timer); |
|---|
| 6881 | 7837 | fail_init_mfi: |
|---|
| 6882 | 7838 | megasas_free_ctrl_dma_buffers(instance); |
|---|
| 6883 | 7839 | megasas_free_ctrl_mem(instance); |
|---|
| .. | .. |
|---|
| 6938 | 7894 | u32 pd_seq_map_sz; |
|---|
| 6939 | 7895 | |
|---|
| 6940 | 7896 | instance = pci_get_drvdata(pdev); |
|---|
| 7897 | + |
|---|
| 7898 | + if (!instance) |
|---|
| 7899 | + return; |
|---|
| 7900 | + |
|---|
| 6941 | 7901 | host = instance->host; |
|---|
| 6942 | 7902 | fusion = instance->ctrl_context; |
|---|
| 6943 | 7903 | |
|---|
| 6944 | 7904 | /* Shutdown SR-IOV heartbeat timer */ |
|---|
| 6945 | 7905 | if (instance->requestorId && !instance->skip_heartbeat_timer_del) |
|---|
| 6946 | 7906 | del_timer_sync(&instance->sriov_heartbeat_timer); |
|---|
| 7907 | + |
|---|
| 7908 | + /* Stop the FW fault detection watchdog */ |
|---|
| 7909 | + if (instance->adapter_type != MFI_SERIES) |
|---|
| 7910 | + megasas_fusion_stop_watchdog(instance); |
|---|
| 6947 | 7911 | |
|---|
| 6948 | 7912 | if (instance->fw_crash_state != UNAVAILABLE) |
|---|
| 6949 | 7913 | megasas_free_host_crash_buffer(instance); |
|---|
| .. | .. |
|---|
| 6989 | 7953 | if (instance->msix_vectors) |
|---|
| 6990 | 7954 | pci_free_irq_vectors(instance->pdev); |
|---|
| 6991 | 7955 | |
|---|
| 6992 | | - if (instance->adapter_type == VENTURA_SERIES) { |
|---|
| 7956 | + if (instance->adapter_type >= VENTURA_SERIES) { |
|---|
| 6993 | 7957 | for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) |
|---|
| 6994 | 7958 | kfree(fusion->stream_detect_by_ld[i]); |
|---|
| 6995 | 7959 | kfree(fusion->stream_detect_by_ld); |
|---|
| .. | .. |
|---|
| 7027 | 7991 | } |
|---|
| 7028 | 7992 | |
|---|
| 7029 | 7993 | if (instance->vf_affiliation) |
|---|
| 7030 | | - pci_free_consistent(pdev, (MAX_LOGICAL_DRIVES + 1) * |
|---|
| 7994 | + dma_free_coherent(&pdev->dev, (MAX_LOGICAL_DRIVES + 1) * |
|---|
| 7031 | 7995 | sizeof(struct MR_LD_VF_AFFILIATION), |
|---|
| 7032 | 7996 | instance->vf_affiliation, |
|---|
| 7033 | 7997 | instance->vf_affiliation_h); |
|---|
| 7034 | 7998 | |
|---|
| 7035 | 7999 | if (instance->vf_affiliation_111) |
|---|
| 7036 | | - pci_free_consistent(pdev, |
|---|
| 8000 | + dma_free_coherent(&pdev->dev, |
|---|
| 7037 | 8001 | sizeof(struct MR_LD_VF_AFFILIATION_111), |
|---|
| 7038 | 8002 | instance->vf_affiliation_111, |
|---|
| 7039 | 8003 | instance->vf_affiliation_111_h); |
|---|
| 7040 | 8004 | |
|---|
| 7041 | 8005 | if (instance->hb_host_mem) |
|---|
| 7042 | | - pci_free_consistent(pdev, sizeof(struct MR_CTRL_HB_HOST_MEM), |
|---|
| 8006 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_CTRL_HB_HOST_MEM), |
|---|
| 7043 | 8007 | instance->hb_host_mem, |
|---|
| 7044 | 8008 | instance->hb_host_mem_h); |
|---|
| 7045 | 8009 | |
|---|
| 7046 | 8010 | megasas_free_ctrl_dma_buffers(instance); |
|---|
| 7047 | 8011 | |
|---|
| 7048 | 8012 | megasas_free_ctrl_mem(instance); |
|---|
| 8013 | + |
|---|
| 8014 | + megasas_destroy_debugfs(instance); |
|---|
| 7049 | 8015 | |
|---|
| 7050 | 8016 | scsi_host_put(host); |
|---|
| 7051 | 8017 | |
|---|
| .. | .. |
|---|
| 7054 | 8020 | |
|---|
| 7055 | 8021 | /** |
|---|
| 7056 | 8022 | * megasas_shutdown - Shutdown entry point |
|---|
| 7057 | | - * @device: Generic device structure |
|---|
| 8023 | + * @pdev: Generic device structure |
|---|
| 7058 | 8024 | */ |
|---|
| 7059 | 8025 | static void megasas_shutdown(struct pci_dev *pdev) |
|---|
| 7060 | 8026 | { |
|---|
| 7061 | 8027 | struct megasas_instance *instance = pci_get_drvdata(pdev); |
|---|
| 8028 | + |
|---|
| 8029 | + if (!instance) |
|---|
| 8030 | + return; |
|---|
| 7062 | 8031 | |
|---|
| 7063 | 8032 | instance->unload = 1; |
|---|
| 7064 | 8033 | |
|---|
| .. | .. |
|---|
| 7076 | 8045 | pci_free_irq_vectors(instance->pdev); |
|---|
| 7077 | 8046 | } |
|---|
| 7078 | 8047 | |
|---|
| 7079 | | -/** |
|---|
| 8048 | +/* |
|---|
| 7080 | 8049 | * megasas_mgmt_open - char node "open" entry point |
|---|
| 8050 | + * @inode: char node inode |
|---|
| 8051 | + * @filep: char node file |
|---|
| 7081 | 8052 | */ |
|---|
| 7082 | 8053 | static int megasas_mgmt_open(struct inode *inode, struct file *filep) |
|---|
| 7083 | 8054 | { |
|---|
| .. | .. |
|---|
| 7090 | 8061 | return 0; |
|---|
| 7091 | 8062 | } |
|---|
| 7092 | 8063 | |
|---|
| 7093 | | -/** |
|---|
| 8064 | +/* |
|---|
| 7094 | 8065 | * megasas_mgmt_fasync - Async notifier registration from applications |
|---|
| 8066 | + * @fd: char node file descriptor number |
|---|
| 8067 | + * @filep: char node file |
|---|
| 8068 | + * @mode: notifier on/off |
|---|
| 7095 | 8069 | * |
|---|
| 7096 | 8070 | * This function adds the calling process to a driver global queue. When an |
|---|
| 7097 | 8071 | * event occurs, SIGIO will be sent to all processes in this queue. |
|---|
| .. | .. |
|---|
| 7117 | 8091 | return rc; |
|---|
| 7118 | 8092 | } |
|---|
| 7119 | 8093 | |
|---|
| 7120 | | -/** |
|---|
| 8094 | +/* |
|---|
| 7121 | 8095 | * megasas_mgmt_poll - char node "poll" entry point |
|---|
| 7122 | | - * */ |
|---|
| 8096 | + * @filep: char node file |
|---|
| 8097 | + * @wait: Events to poll for |
|---|
| 8098 | + */ |
|---|
| 7123 | 8099 | static __poll_t megasas_mgmt_poll(struct file *file, poll_table *wait) |
|---|
| 7124 | 8100 | { |
|---|
| 7125 | 8101 | __poll_t mask; |
|---|
| .. | .. |
|---|
| 7177 | 8153 | /** |
|---|
| 7178 | 8154 | * megasas_mgmt_fw_ioctl - Issues management ioctls to FW |
|---|
| 7179 | 8155 | * @instance: Adapter soft state |
|---|
| 7180 | | - * @argp: User's ioctl packet |
|---|
| 8156 | + * @user_ioc: User's ioctl packet |
|---|
| 8157 | + * @ioc: ioctl packet |
|---|
| 7181 | 8158 | */ |
|---|
| 7182 | 8159 | static int |
|---|
| 7183 | 8160 | megasas_mgmt_fw_ioctl(struct megasas_instance *instance, |
|---|
| .. | .. |
|---|
| 7194 | 8171 | dma_addr_t sense_handle; |
|---|
| 7195 | 8172 | void *sense_ptr; |
|---|
| 7196 | 8173 | u32 opcode = 0; |
|---|
| 8174 | + int ret = DCMD_SUCCESS; |
|---|
| 7197 | 8175 | |
|---|
| 7198 | 8176 | memset(kbuff_arr, 0, sizeof(kbuff_arr)); |
|---|
| 7199 | 8177 | |
|---|
| .. | .. |
|---|
| 7205 | 8183 | |
|---|
| 7206 | 8184 | if ((ioc->frame.hdr.cmd >= MFI_CMD_OP_COUNT) || |
|---|
| 7207 | 8185 | ((ioc->frame.hdr.cmd == MFI_CMD_NVME) && |
|---|
| 7208 | | - !instance->support_nvme_passthru)) { |
|---|
| 8186 | + !instance->support_nvme_passthru) || |
|---|
| 8187 | + ((ioc->frame.hdr.cmd == MFI_CMD_TOOLBOX) && |
|---|
| 8188 | + !instance->support_pci_lane_margining)) { |
|---|
| 7209 | 8189 | dev_err(&instance->pdev->dev, |
|---|
| 7210 | 8190 | "Received invalid ioctl command 0x%x\n", |
|---|
| 7211 | 8191 | ioc->frame.hdr.cmd); |
|---|
| .. | .. |
|---|
| 7241 | 8221 | opcode = le32_to_cpu(cmd->frame->dcmd.opcode); |
|---|
| 7242 | 8222 | |
|---|
| 7243 | 8223 | if (opcode == MR_DCMD_CTRL_SHUTDOWN) { |
|---|
| 8224 | + mutex_lock(&instance->reset_mutex); |
|---|
| 7244 | 8225 | if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) { |
|---|
| 7245 | 8226 | megasas_return_cmd(instance, cmd); |
|---|
| 8227 | + mutex_unlock(&instance->reset_mutex); |
|---|
| 7246 | 8228 | return -1; |
|---|
| 7247 | 8229 | } |
|---|
| 8230 | + mutex_unlock(&instance->reset_mutex); |
|---|
| 7248 | 8231 | } |
|---|
| 7249 | 8232 | |
|---|
| 7250 | 8233 | if (opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) { |
|---|
| .. | .. |
|---|
| 7287 | 8270 | |
|---|
| 7288 | 8271 | /* |
|---|
| 7289 | 8272 | * We don't change the dma_coherent_mask, so |
|---|
| 7290 | | - * pci_alloc_consistent only returns 32bit addresses |
|---|
| 8273 | + * dma_alloc_coherent only returns 32bit addresses |
|---|
| 7291 | 8274 | */ |
|---|
| 7292 | 8275 | if (instance->consistent_mask_64bit) { |
|---|
| 7293 | 8276 | kern_sge64[i].phys_addr = cpu_to_le64(buf_handle); |
|---|
| .. | .. |
|---|
| 7333 | 8316 | * cmd to the SCSI mid-layer |
|---|
| 7334 | 8317 | */ |
|---|
| 7335 | 8318 | cmd->sync_cmd = 1; |
|---|
| 7336 | | - if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) { |
|---|
| 8319 | + |
|---|
| 8320 | + ret = megasas_issue_blocked_cmd(instance, cmd, 0); |
|---|
| 8321 | + switch (ret) { |
|---|
| 8322 | + case DCMD_INIT: |
|---|
| 8323 | + case DCMD_BUSY: |
|---|
| 7337 | 8324 | cmd->sync_cmd = 0; |
|---|
| 7338 | 8325 | dev_err(&instance->pdev->dev, |
|---|
| 7339 | 8326 | "return -EBUSY from %s %d cmd 0x%x opcode 0x%x cmd->cmd_status_drv 0x%x\n", |
|---|
| 7340 | | - __func__, __LINE__, cmd->frame->hdr.cmd, opcode, |
|---|
| 7341 | | - cmd->cmd_status_drv); |
|---|
| 7342 | | - return -EBUSY; |
|---|
| 8327 | + __func__, __LINE__, cmd->frame->hdr.cmd, opcode, |
|---|
| 8328 | + cmd->cmd_status_drv); |
|---|
| 8329 | + error = -EBUSY; |
|---|
| 8330 | + goto out; |
|---|
| 7343 | 8331 | } |
|---|
| 7344 | 8332 | |
|---|
| 7345 | 8333 | cmd->sync_cmd = 0; |
|---|
| .. | .. |
|---|
| 7510 | 8498 | |
|---|
| 7511 | 8499 | /** |
|---|
| 7512 | 8500 | * megasas_mgmt_ioctl - char node ioctl entry point |
|---|
| 8501 | + * @file: char device file pointer |
|---|
| 8502 | + * @cmd: ioctl command |
|---|
| 8503 | + * @arg: ioctl command arguments address |
|---|
| 7513 | 8504 | */ |
|---|
| 7514 | 8505 | static long |
|---|
| 7515 | 8506 | megasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
|---|
| .. | .. |
|---|
| 7690 | 8681 | |
|---|
| 7691 | 8682 | static DRIVER_ATTR_RO(support_nvme_encapsulation); |
|---|
| 7692 | 8683 | |
|---|
| 8684 | +static ssize_t |
|---|
| 8685 | +support_pci_lane_margining_show(struct device_driver *dd, char *buf) |
|---|
| 8686 | +{ |
|---|
| 8687 | + return sprintf(buf, "%u\n", support_pci_lane_margining); |
|---|
| 8688 | +} |
|---|
| 8689 | + |
|---|
| 8690 | +static DRIVER_ATTR_RO(support_pci_lane_margining); |
|---|
| 8691 | + |
|---|
| 7693 | 8692 | static inline void megasas_remove_scsi_device(struct scsi_device *sdev) |
|---|
| 7694 | 8693 | { |
|---|
| 7695 | 8694 | sdev_printk(KERN_INFO, sdev, "SCSI device is removed\n"); |
|---|
| .. | .. |
|---|
| 7697 | 8696 | scsi_device_put(sdev); |
|---|
| 7698 | 8697 | } |
|---|
| 7699 | 8698 | |
|---|
| 7700 | | -static void |
|---|
| 7701 | | -megasas_aen_polling(struct work_struct *work) |
|---|
| 8699 | +/** |
|---|
| 8700 | + * megasas_update_device_list - Update the PD and LD device list from FW |
|---|
| 8701 | + * after an AEN event notification |
|---|
| 8702 | + * @instance: Adapter soft state |
|---|
| 8703 | + * @event_type: Indicates type of event (PD or LD event) |
|---|
| 8704 | + * |
|---|
| 8705 | + * @return: Success or failure |
|---|
| 8706 | + * |
|---|
| 8707 | + * Issue DCMDs to Firmware to update the internal device list in driver. |
|---|
| 8708 | + * Based on the FW support, driver sends the HOST_DEVICE_LIST or combination |
|---|
| 8709 | + * of PD_LIST/LD_LIST_QUERY DCMDs to get the device list. |
|---|
| 8710 | + */ |
|---|
| 8711 | +static |
|---|
| 8712 | +int megasas_update_device_list(struct megasas_instance *instance, |
|---|
| 8713 | + int event_type) |
|---|
| 7702 | 8714 | { |
|---|
| 7703 | | - struct megasas_aen_event *ev = |
|---|
| 7704 | | - container_of(work, struct megasas_aen_event, hotplug_work.work); |
|---|
| 7705 | | - struct megasas_instance *instance = ev->instance; |
|---|
| 7706 | | - union megasas_evt_class_locale class_locale; |
|---|
| 7707 | | - struct Scsi_Host *host; |
|---|
| 7708 | | - struct scsi_device *sdev1; |
|---|
| 7709 | | - u16 pd_index = 0; |
|---|
| 7710 | | - u16 ld_index = 0; |
|---|
| 7711 | | - int i, j, doscan = 0; |
|---|
| 7712 | | - u32 seq_num, wait_time = MEGASAS_RESET_WAIT_TIME; |
|---|
| 7713 | | - int error; |
|---|
| 7714 | | - u8 dcmd_ret = DCMD_SUCCESS; |
|---|
| 8715 | + int dcmd_ret = DCMD_SUCCESS; |
|---|
| 7715 | 8716 | |
|---|
| 7716 | | - if (!instance) { |
|---|
| 7717 | | - printk(KERN_ERR "invalid instance!\n"); |
|---|
| 7718 | | - kfree(ev); |
|---|
| 7719 | | - return; |
|---|
| 7720 | | - } |
|---|
| 7721 | | - |
|---|
| 7722 | | - /* Adjust event workqueue thread wait time for VF mode */ |
|---|
| 7723 | | - if (instance->requestorId) |
|---|
| 7724 | | - wait_time = MEGASAS_ROUTINE_WAIT_TIME_VF; |
|---|
| 7725 | | - |
|---|
| 7726 | | - /* Don't run the event workqueue thread if OCR is running */ |
|---|
| 7727 | | - mutex_lock(&instance->reset_mutex); |
|---|
| 7728 | | - |
|---|
| 7729 | | - instance->ev = NULL; |
|---|
| 7730 | | - host = instance->host; |
|---|
| 7731 | | - if (instance->evt_detail) { |
|---|
| 7732 | | - megasas_decode_evt(instance); |
|---|
| 7733 | | - |
|---|
| 7734 | | - switch (le32_to_cpu(instance->evt_detail->code)) { |
|---|
| 7735 | | - |
|---|
| 7736 | | - case MR_EVT_PD_INSERTED: |
|---|
| 7737 | | - case MR_EVT_PD_REMOVED: |
|---|
| 7738 | | - dcmd_ret = megasas_get_pd_list(instance); |
|---|
| 7739 | | - if (dcmd_ret == DCMD_SUCCESS) |
|---|
| 7740 | | - doscan = SCAN_PD_CHANNEL; |
|---|
| 7741 | | - break; |
|---|
| 7742 | | - |
|---|
| 7743 | | - case MR_EVT_LD_OFFLINE: |
|---|
| 7744 | | - case MR_EVT_CFG_CLEARED: |
|---|
| 7745 | | - case MR_EVT_LD_DELETED: |
|---|
| 7746 | | - case MR_EVT_LD_CREATED: |
|---|
| 7747 | | - if (!instance->requestorId || |
|---|
| 7748 | | - (instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0))) |
|---|
| 7749 | | - dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); |
|---|
| 7750 | | - |
|---|
| 7751 | | - if (dcmd_ret == DCMD_SUCCESS) |
|---|
| 7752 | | - doscan = SCAN_VD_CHANNEL; |
|---|
| 7753 | | - |
|---|
| 7754 | | - break; |
|---|
| 7755 | | - |
|---|
| 7756 | | - case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED: |
|---|
| 7757 | | - case MR_EVT_FOREIGN_CFG_IMPORTED: |
|---|
| 7758 | | - case MR_EVT_LD_STATE_CHANGE: |
|---|
| 7759 | | - dcmd_ret = megasas_get_pd_list(instance); |
|---|
| 7760 | | - |
|---|
| 7761 | | - if (dcmd_ret != DCMD_SUCCESS) |
|---|
| 7762 | | - break; |
|---|
| 7763 | | - |
|---|
| 7764 | | - if (!instance->requestorId || |
|---|
| 7765 | | - (instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0))) |
|---|
| 7766 | | - dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); |
|---|
| 7767 | | - |
|---|
| 7768 | | - if (dcmd_ret != DCMD_SUCCESS) |
|---|
| 7769 | | - break; |
|---|
| 7770 | | - |
|---|
| 7771 | | - doscan = SCAN_VD_CHANNEL | SCAN_PD_CHANNEL; |
|---|
| 7772 | | - dev_info(&instance->pdev->dev, "scanning for scsi%d...\n", |
|---|
| 7773 | | - instance->host->host_no); |
|---|
| 7774 | | - break; |
|---|
| 7775 | | - |
|---|
| 7776 | | - case MR_EVT_CTRL_PROP_CHANGED: |
|---|
| 7777 | | - dcmd_ret = megasas_get_ctrl_info(instance); |
|---|
| 7778 | | - break; |
|---|
| 7779 | | - default: |
|---|
| 7780 | | - doscan = 0; |
|---|
| 7781 | | - break; |
|---|
| 7782 | | - } |
|---|
| 8717 | + if (instance->enable_fw_dev_list) { |
|---|
| 8718 | + dcmd_ret = megasas_host_device_list_query(instance, false); |
|---|
| 8719 | + if (dcmd_ret != DCMD_SUCCESS) |
|---|
| 8720 | + goto out; |
|---|
| 7783 | 8721 | } else { |
|---|
| 7784 | | - dev_err(&instance->pdev->dev, "invalid evt_detail!\n"); |
|---|
| 7785 | | - mutex_unlock(&instance->reset_mutex); |
|---|
| 7786 | | - kfree(ev); |
|---|
| 7787 | | - return; |
|---|
| 8722 | + if (event_type & SCAN_PD_CHANNEL) { |
|---|
| 8723 | + dcmd_ret = megasas_get_pd_list(instance); |
|---|
| 8724 | + |
|---|
| 8725 | + if (dcmd_ret != DCMD_SUCCESS) |
|---|
| 8726 | + goto out; |
|---|
| 8727 | + } |
|---|
| 8728 | + |
|---|
| 8729 | + if (event_type & SCAN_VD_CHANNEL) { |
|---|
| 8730 | + if (!instance->requestorId || |
|---|
| 8731 | + (instance->requestorId && |
|---|
| 8732 | + megasas_get_ld_vf_affiliation(instance, 0))) { |
|---|
| 8733 | + dcmd_ret = megasas_ld_list_query(instance, |
|---|
| 8734 | + MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); |
|---|
| 8735 | + if (dcmd_ret != DCMD_SUCCESS) |
|---|
| 8736 | + goto out; |
|---|
| 8737 | + } |
|---|
| 8738 | + } |
|---|
| 7788 | 8739 | } |
|---|
| 7789 | 8740 | |
|---|
| 7790 | | - mutex_unlock(&instance->reset_mutex); |
|---|
| 8741 | +out: |
|---|
| 8742 | + return dcmd_ret; |
|---|
| 8743 | +} |
|---|
| 7791 | 8744 | |
|---|
| 7792 | | - if (doscan & SCAN_PD_CHANNEL) { |
|---|
| 8745 | +/** |
|---|
| 8746 | + * megasas_add_remove_devices - Add/remove devices to SCSI mid-layer |
|---|
| 8747 | + * after an AEN event notification |
|---|
| 8748 | + * @instance: Adapter soft state |
|---|
| 8749 | + * @scan_type: Indicates type of devices (PD/LD) to add |
|---|
| 8750 | + * @return void |
|---|
| 8751 | + */ |
|---|
| 8752 | +static |
|---|
| 8753 | +void megasas_add_remove_devices(struct megasas_instance *instance, |
|---|
| 8754 | + int scan_type) |
|---|
| 8755 | +{ |
|---|
| 8756 | + int i, j; |
|---|
| 8757 | + u16 pd_index = 0; |
|---|
| 8758 | + u16 ld_index = 0; |
|---|
| 8759 | + u16 channel = 0, id = 0; |
|---|
| 8760 | + struct Scsi_Host *host; |
|---|
| 8761 | + struct scsi_device *sdev1; |
|---|
| 8762 | + struct MR_HOST_DEVICE_LIST *targetid_list = NULL; |
|---|
| 8763 | + struct MR_HOST_DEVICE_LIST_ENTRY *targetid_entry = NULL; |
|---|
| 8764 | + |
|---|
| 8765 | + host = instance->host; |
|---|
| 8766 | + |
|---|
| 8767 | + if (instance->enable_fw_dev_list) { |
|---|
| 8768 | + targetid_list = instance->host_device_list_buf; |
|---|
| 8769 | + for (i = 0; i < targetid_list->count; i++) { |
|---|
| 8770 | + targetid_entry = &targetid_list->host_device_list[i]; |
|---|
| 8771 | + if (targetid_entry->flags.u.bits.is_sys_pd) { |
|---|
| 8772 | + channel = le16_to_cpu(targetid_entry->target_id) / |
|---|
| 8773 | + MEGASAS_MAX_DEV_PER_CHANNEL; |
|---|
| 8774 | + id = le16_to_cpu(targetid_entry->target_id) % |
|---|
| 8775 | + MEGASAS_MAX_DEV_PER_CHANNEL; |
|---|
| 8776 | + } else { |
|---|
| 8777 | + channel = MEGASAS_MAX_PD_CHANNELS + |
|---|
| 8778 | + (le16_to_cpu(targetid_entry->target_id) / |
|---|
| 8779 | + MEGASAS_MAX_DEV_PER_CHANNEL); |
|---|
| 8780 | + id = le16_to_cpu(targetid_entry->target_id) % |
|---|
| 8781 | + MEGASAS_MAX_DEV_PER_CHANNEL; |
|---|
| 8782 | + } |
|---|
| 8783 | + sdev1 = scsi_device_lookup(host, channel, id, 0); |
|---|
| 8784 | + if (!sdev1) { |
|---|
| 8785 | + scsi_add_device(host, channel, id, 0); |
|---|
| 8786 | + } else { |
|---|
| 8787 | + scsi_device_put(sdev1); |
|---|
| 8788 | + } |
|---|
| 8789 | + } |
|---|
| 8790 | + } |
|---|
| 8791 | + |
|---|
| 8792 | + if (scan_type & SCAN_PD_CHANNEL) { |
|---|
| 7793 | 8793 | for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { |
|---|
| 7794 | 8794 | for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) { |
|---|
| 7795 | | - pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j; |
|---|
| 8795 | + pd_index = i * MEGASAS_MAX_DEV_PER_CHANNEL + j; |
|---|
| 7796 | 8796 | sdev1 = scsi_device_lookup(host, i, j, 0); |
|---|
| 7797 | 8797 | if (instance->pd_list[pd_index].driveState == |
|---|
| 7798 | 8798 | MR_PD_STATE_SYSTEM) { |
|---|
| .. | .. |
|---|
| 7808 | 8808 | } |
|---|
| 7809 | 8809 | } |
|---|
| 7810 | 8810 | |
|---|
| 7811 | | - if (doscan & SCAN_VD_CHANNEL) { |
|---|
| 8811 | + if (scan_type & SCAN_VD_CHANNEL) { |
|---|
| 7812 | 8812 | for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { |
|---|
| 7813 | 8813 | for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) { |
|---|
| 7814 | 8814 | ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; |
|---|
| 7815 | | - sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0); |
|---|
| 8815 | + sdev1 = scsi_device_lookup(host, |
|---|
| 8816 | + MEGASAS_MAX_PD_CHANNELS + i, j, 0); |
|---|
| 7816 | 8817 | if (instance->ld_ids[ld_index] != 0xff) { |
|---|
| 7817 | 8818 | if (!sdev1) |
|---|
| 7818 | 8819 | scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0); |
|---|
| .. | .. |
|---|
| 7825 | 8826 | } |
|---|
| 7826 | 8827 | } |
|---|
| 7827 | 8828 | } |
|---|
| 8829 | + |
|---|
| 8830 | +} |
|---|
| 8831 | + |
|---|
| 8832 | +static void |
|---|
| 8833 | +megasas_aen_polling(struct work_struct *work) |
|---|
| 8834 | +{ |
|---|
| 8835 | + struct megasas_aen_event *ev = |
|---|
| 8836 | + container_of(work, struct megasas_aen_event, hotplug_work.work); |
|---|
| 8837 | + struct megasas_instance *instance = ev->instance; |
|---|
| 8838 | + union megasas_evt_class_locale class_locale; |
|---|
| 8839 | + int event_type = 0; |
|---|
| 8840 | + u32 seq_num; |
|---|
| 8841 | + u16 ld_target_id; |
|---|
| 8842 | + int error; |
|---|
| 8843 | + u8 dcmd_ret = DCMD_SUCCESS; |
|---|
| 8844 | + struct scsi_device *sdev1; |
|---|
| 8845 | + |
|---|
| 8846 | + if (!instance) { |
|---|
| 8847 | + printk(KERN_ERR "invalid instance!\n"); |
|---|
| 8848 | + kfree(ev); |
|---|
| 8849 | + return; |
|---|
| 8850 | + } |
|---|
| 8851 | + |
|---|
| 8852 | + /* Don't run the event workqueue thread if OCR is running */ |
|---|
| 8853 | + mutex_lock(&instance->reset_mutex); |
|---|
| 8854 | + |
|---|
| 8855 | + instance->ev = NULL; |
|---|
| 8856 | + if (instance->evt_detail) { |
|---|
| 8857 | + megasas_decode_evt(instance); |
|---|
| 8858 | + |
|---|
| 8859 | + switch (le32_to_cpu(instance->evt_detail->code)) { |
|---|
| 8860 | + |
|---|
| 8861 | + case MR_EVT_PD_INSERTED: |
|---|
| 8862 | + case MR_EVT_PD_REMOVED: |
|---|
| 8863 | + event_type = SCAN_PD_CHANNEL; |
|---|
| 8864 | + break; |
|---|
| 8865 | + |
|---|
| 8866 | + case MR_EVT_LD_OFFLINE: |
|---|
| 8867 | + case MR_EVT_LD_DELETED: |
|---|
| 8868 | + ld_target_id = instance->evt_detail->args.ld.target_id; |
|---|
| 8869 | + sdev1 = scsi_device_lookup(instance->host, |
|---|
| 8870 | + MEGASAS_MAX_PD_CHANNELS + |
|---|
| 8871 | + (ld_target_id / MEGASAS_MAX_DEV_PER_CHANNEL), |
|---|
| 8872 | + (ld_target_id - MEGASAS_MAX_DEV_PER_CHANNEL), |
|---|
| 8873 | + 0); |
|---|
| 8874 | + if (sdev1) |
|---|
| 8875 | + megasas_remove_scsi_device(sdev1); |
|---|
| 8876 | + |
|---|
| 8877 | + event_type = SCAN_VD_CHANNEL; |
|---|
| 8878 | + break; |
|---|
| 8879 | + case MR_EVT_LD_CREATED: |
|---|
| 8880 | + event_type = SCAN_VD_CHANNEL; |
|---|
| 8881 | + break; |
|---|
| 8882 | + |
|---|
| 8883 | + case MR_EVT_CFG_CLEARED: |
|---|
| 8884 | + case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED: |
|---|
| 8885 | + case MR_EVT_FOREIGN_CFG_IMPORTED: |
|---|
| 8886 | + case MR_EVT_LD_STATE_CHANGE: |
|---|
| 8887 | + event_type = SCAN_PD_CHANNEL | SCAN_VD_CHANNEL; |
|---|
| 8888 | + dev_info(&instance->pdev->dev, "scanning for scsi%d...\n", |
|---|
| 8889 | + instance->host->host_no); |
|---|
| 8890 | + break; |
|---|
| 8891 | + |
|---|
| 8892 | + case MR_EVT_CTRL_PROP_CHANGED: |
|---|
| 8893 | + dcmd_ret = megasas_get_ctrl_info(instance); |
|---|
| 8894 | + if (dcmd_ret == DCMD_SUCCESS && |
|---|
| 8895 | + instance->snapdump_wait_time) { |
|---|
| 8896 | + megasas_get_snapdump_properties(instance); |
|---|
| 8897 | + dev_info(&instance->pdev->dev, |
|---|
| 8898 | + "Snap dump wait time\t: %d\n", |
|---|
| 8899 | + instance->snapdump_wait_time); |
|---|
| 8900 | + } |
|---|
| 8901 | + break; |
|---|
| 8902 | + default: |
|---|
| 8903 | + event_type = 0; |
|---|
| 8904 | + break; |
|---|
| 8905 | + } |
|---|
| 8906 | + } else { |
|---|
| 8907 | + dev_err(&instance->pdev->dev, "invalid evt_detail!\n"); |
|---|
| 8908 | + mutex_unlock(&instance->reset_mutex); |
|---|
| 8909 | + kfree(ev); |
|---|
| 8910 | + return; |
|---|
| 8911 | + } |
|---|
| 8912 | + |
|---|
| 8913 | + if (event_type) |
|---|
| 8914 | + dcmd_ret = megasas_update_device_list(instance, event_type); |
|---|
| 8915 | + |
|---|
| 8916 | + mutex_unlock(&instance->reset_mutex); |
|---|
| 8917 | + |
|---|
| 8918 | + if (event_type && dcmd_ret == DCMD_SUCCESS) |
|---|
| 8919 | + megasas_add_remove_devices(instance, event_type); |
|---|
| 7828 | 8920 | |
|---|
| 7829 | 8921 | if (dcmd_ret == DCMD_SUCCESS) |
|---|
| 7830 | 8922 | seq_num = le32_to_cpu(instance->evt_detail->seq_num) + 1; |
|---|
| .. | .. |
|---|
| 7879 | 8971 | support_poll_for_event = 2; |
|---|
| 7880 | 8972 | support_device_change = 1; |
|---|
| 7881 | 8973 | support_nvme_encapsulation = true; |
|---|
| 8974 | + support_pci_lane_margining = true; |
|---|
| 7882 | 8975 | |
|---|
| 7883 | 8976 | memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info)); |
|---|
| 7884 | 8977 | |
|---|
| .. | .. |
|---|
| 7894 | 8987 | |
|---|
| 7895 | 8988 | megasas_mgmt_majorno = rval; |
|---|
| 7896 | 8989 | |
|---|
| 8990 | + megasas_init_debugfs(); |
|---|
| 8991 | + |
|---|
| 7897 | 8992 | /* |
|---|
| 7898 | 8993 | * Register ourselves as PCI hotplug module |
|---|
| 7899 | 8994 | */ |
|---|
| .. | .. |
|---|
| 7902 | 8997 | if (rval) { |
|---|
| 7903 | 8998 | printk(KERN_DEBUG "megasas: PCI hotplug registration failed \n"); |
|---|
| 7904 | 8999 | goto err_pcidrv; |
|---|
| 9000 | + } |
|---|
| 9001 | + |
|---|
| 9002 | + if ((event_log_level < MFI_EVT_CLASS_DEBUG) || |
|---|
| 9003 | + (event_log_level > MFI_EVT_CLASS_DEAD)) { |
|---|
| 9004 | + pr_warn("megaraid_sas: provided event log level is out of range, setting it to default 2(CLASS_CRITICAL), permissible range is: -2 to 4\n"); |
|---|
| 9005 | + event_log_level = MFI_EVT_CLASS_CRITICAL; |
|---|
| 7905 | 9006 | } |
|---|
| 7906 | 9007 | |
|---|
| 7907 | 9008 | rval = driver_create_file(&megasas_pci_driver.driver, |
|---|
| .. | .. |
|---|
| 7933 | 9034 | if (rval) |
|---|
| 7934 | 9035 | goto err_dcf_support_nvme_encapsulation; |
|---|
| 7935 | 9036 | |
|---|
| 9037 | + rval = driver_create_file(&megasas_pci_driver.driver, |
|---|
| 9038 | + &driver_attr_support_pci_lane_margining); |
|---|
| 9039 | + if (rval) |
|---|
| 9040 | + goto err_dcf_support_pci_lane_margining; |
|---|
| 9041 | + |
|---|
| 7936 | 9042 | return rval; |
|---|
| 9043 | + |
|---|
| 9044 | +err_dcf_support_pci_lane_margining: |
|---|
| 9045 | + driver_remove_file(&megasas_pci_driver.driver, |
|---|
| 9046 | + &driver_attr_support_nvme_encapsulation); |
|---|
| 7937 | 9047 | |
|---|
| 7938 | 9048 | err_dcf_support_nvme_encapsulation: |
|---|
| 7939 | 9049 | driver_remove_file(&megasas_pci_driver.driver, |
|---|
| .. | .. |
|---|
| 7953 | 9063 | err_dcf_attr_ver: |
|---|
| 7954 | 9064 | pci_unregister_driver(&megasas_pci_driver); |
|---|
| 7955 | 9065 | err_pcidrv: |
|---|
| 9066 | + megasas_exit_debugfs(); |
|---|
| 7956 | 9067 | unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); |
|---|
| 7957 | 9068 | return rval; |
|---|
| 7958 | 9069 | } |
|---|
| .. | .. |
|---|
| 7973 | 9084 | driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); |
|---|
| 7974 | 9085 | driver_remove_file(&megasas_pci_driver.driver, |
|---|
| 7975 | 9086 | &driver_attr_support_nvme_encapsulation); |
|---|
| 9087 | + driver_remove_file(&megasas_pci_driver.driver, |
|---|
| 9088 | + &driver_attr_support_pci_lane_margining); |
|---|
| 7976 | 9089 | |
|---|
| 7977 | 9090 | pci_unregister_driver(&megasas_pci_driver); |
|---|
| 9091 | + megasas_exit_debugfs(); |
|---|
| 7978 | 9092 | unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); |
|---|
| 7979 | 9093 | } |
|---|
| 7980 | 9094 | |
|---|