.. | .. |
---|
| 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); |
---|
3004 | 3221 | struct megasas_instance *instance = |
---|
3005 | 3222 | (struct megasas_instance *) shost->hostdata; |
---|
3006 | 3223 | int val = 0; |
---|
3007 | | - unsigned long flags; |
---|
3008 | 3224 | |
---|
3009 | 3225 | if (kstrtoint(buf, 0, &val) != 0) |
---|
3010 | 3226 | return -EINVAL; |
---|
3011 | 3227 | |
---|
3012 | | - spin_lock_irqsave(&instance->crashdump_lock, flags); |
---|
| 3228 | + mutex_lock(&instance->crashdump_lock); |
---|
3013 | 3229 | instance->fw_crash_buffer_offset = val; |
---|
3014 | | - spin_unlock_irqrestore(&instance->crashdump_lock, flags); |
---|
| 3230 | + mutex_unlock(&instance->crashdump_lock); |
---|
3015 | 3231 | return strlen(buf); |
---|
3016 | 3232 | } |
---|
3017 | 3233 | |
---|
3018 | 3234 | static ssize_t |
---|
3019 | | -megasas_fw_crash_buffer_show(struct device *cdev, |
---|
| 3235 | +fw_crash_buffer_show(struct device *cdev, |
---|
3020 | 3236 | struct device_attribute *attr, char *buf) |
---|
3021 | 3237 | { |
---|
3022 | 3238 | struct Scsi_Host *shost = class_to_shost(cdev); |
---|
3023 | 3239 | struct megasas_instance *instance = |
---|
3024 | 3240 | (struct megasas_instance *) shost->hostdata; |
---|
3025 | 3241 | u32 size; |
---|
3026 | | - unsigned long buff_addr; |
---|
3027 | 3242 | unsigned long dmachunk = CRASH_DMA_BUF_SIZE; |
---|
3028 | 3243 | unsigned long chunk_left_bytes; |
---|
3029 | 3244 | unsigned long src_addr; |
---|
3030 | | - unsigned long flags; |
---|
3031 | 3245 | u32 buff_offset; |
---|
3032 | 3246 | |
---|
3033 | | - spin_lock_irqsave(&instance->crashdump_lock, flags); |
---|
| 3247 | + mutex_lock(&instance->crashdump_lock); |
---|
3034 | 3248 | buff_offset = instance->fw_crash_buffer_offset; |
---|
3035 | | - if (!instance->crash_dump_buf && |
---|
| 3249 | + if (!instance->crash_dump_buf || |
---|
3036 | 3250 | !((instance->fw_crash_state == AVAILABLE) || |
---|
3037 | 3251 | (instance->fw_crash_state == COPYING))) { |
---|
3038 | 3252 | dev_err(&instance->pdev->dev, |
---|
3039 | 3253 | "Firmware crash dump is not available\n"); |
---|
3040 | | - spin_unlock_irqrestore(&instance->crashdump_lock, flags); |
---|
| 3254 | + mutex_unlock(&instance->crashdump_lock); |
---|
3041 | 3255 | return -EINVAL; |
---|
3042 | 3256 | } |
---|
3043 | | - |
---|
3044 | | - buff_addr = (unsigned long) buf; |
---|
3045 | 3257 | |
---|
3046 | 3258 | if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) { |
---|
3047 | 3259 | dev_err(&instance->pdev->dev, |
---|
3048 | 3260 | "Firmware crash dump offset is out of range\n"); |
---|
3049 | | - spin_unlock_irqrestore(&instance->crashdump_lock, flags); |
---|
| 3261 | + mutex_unlock(&instance->crashdump_lock); |
---|
3050 | 3262 | return 0; |
---|
3051 | 3263 | } |
---|
3052 | 3264 | |
---|
.. | .. |
---|
3058 | 3270 | src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] + |
---|
3059 | 3271 | (buff_offset % dmachunk); |
---|
3060 | 3272 | memcpy(buf, (void *)src_addr, size); |
---|
3061 | | - spin_unlock_irqrestore(&instance->crashdump_lock, flags); |
---|
| 3273 | + mutex_unlock(&instance->crashdump_lock); |
---|
3062 | 3274 | |
---|
3063 | 3275 | return size; |
---|
3064 | 3276 | } |
---|
3065 | 3277 | |
---|
3066 | 3278 | static ssize_t |
---|
3067 | | -megasas_fw_crash_buffer_size_show(struct device *cdev, |
---|
| 3279 | +fw_crash_buffer_size_show(struct device *cdev, |
---|
3068 | 3280 | struct device_attribute *attr, char *buf) |
---|
3069 | 3281 | { |
---|
3070 | 3282 | struct Scsi_Host *shost = class_to_shost(cdev); |
---|
.. | .. |
---|
3076 | 3288 | } |
---|
3077 | 3289 | |
---|
3078 | 3290 | static ssize_t |
---|
3079 | | -megasas_fw_crash_state_store(struct device *cdev, |
---|
| 3291 | +fw_crash_state_store(struct device *cdev, |
---|
3080 | 3292 | struct device_attribute *attr, const char *buf, size_t count) |
---|
3081 | 3293 | { |
---|
3082 | 3294 | struct Scsi_Host *shost = class_to_shost(cdev); |
---|
3083 | 3295 | struct megasas_instance *instance = |
---|
3084 | 3296 | (struct megasas_instance *) shost->hostdata; |
---|
3085 | 3297 | int val = 0; |
---|
3086 | | - unsigned long flags; |
---|
3087 | 3298 | |
---|
3088 | 3299 | if (kstrtoint(buf, 0, &val) != 0) |
---|
3089 | 3300 | return -EINVAL; |
---|
.. | .. |
---|
3097 | 3308 | instance->fw_crash_state = val; |
---|
3098 | 3309 | |
---|
3099 | 3310 | if ((val == COPIED) || (val == COPY_ERROR)) { |
---|
3100 | | - spin_lock_irqsave(&instance->crashdump_lock, flags); |
---|
| 3311 | + mutex_lock(&instance->crashdump_lock); |
---|
3101 | 3312 | megasas_free_host_crash_buffer(instance); |
---|
3102 | | - spin_unlock_irqrestore(&instance->crashdump_lock, flags); |
---|
| 3313 | + mutex_unlock(&instance->crashdump_lock); |
---|
3103 | 3314 | if (val == COPY_ERROR) |
---|
3104 | 3315 | dev_info(&instance->pdev->dev, "application failed to " |
---|
3105 | 3316 | "copy Firmware crash dump\n"); |
---|
.. | .. |
---|
3111 | 3322 | } |
---|
3112 | 3323 | |
---|
3113 | 3324 | static ssize_t |
---|
3114 | | -megasas_fw_crash_state_show(struct device *cdev, |
---|
| 3325 | +fw_crash_state_show(struct device *cdev, |
---|
3115 | 3326 | struct device_attribute *attr, char *buf) |
---|
3116 | 3327 | { |
---|
3117 | 3328 | struct Scsi_Host *shost = class_to_shost(cdev); |
---|
.. | .. |
---|
3122 | 3333 | } |
---|
3123 | 3334 | |
---|
3124 | 3335 | static ssize_t |
---|
3125 | | -megasas_page_size_show(struct device *cdev, |
---|
| 3336 | +page_size_show(struct device *cdev, |
---|
3126 | 3337 | struct device_attribute *attr, char *buf) |
---|
3127 | 3338 | { |
---|
3128 | 3339 | return snprintf(buf, PAGE_SIZE, "%ld\n", (unsigned long)PAGE_SIZE - 1); |
---|
3129 | 3340 | } |
---|
3130 | 3341 | |
---|
3131 | 3342 | static ssize_t |
---|
3132 | | -megasas_ldio_outstanding_show(struct device *cdev, struct device_attribute *attr, |
---|
| 3343 | +ldio_outstanding_show(struct device *cdev, struct device_attribute *attr, |
---|
3133 | 3344 | char *buf) |
---|
3134 | 3345 | { |
---|
3135 | 3346 | struct Scsi_Host *shost = class_to_shost(cdev); |
---|
.. | .. |
---|
3139 | 3350 | } |
---|
3140 | 3351 | |
---|
3141 | 3352 | static ssize_t |
---|
3142 | | -megasas_fw_cmds_outstanding_show(struct device *cdev, |
---|
| 3353 | +fw_cmds_outstanding_show(struct device *cdev, |
---|
3143 | 3354 | struct device_attribute *attr, char *buf) |
---|
3144 | 3355 | { |
---|
3145 | 3356 | struct Scsi_Host *shost = class_to_shost(cdev); |
---|
.. | .. |
---|
3148 | 3359 | return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&instance->fw_outstanding)); |
---|
3149 | 3360 | } |
---|
3150 | 3361 | |
---|
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); |
---|
| 3362 | +static ssize_t |
---|
| 3363 | +enable_sdev_max_qd_show(struct device *cdev, |
---|
| 3364 | + struct device_attribute *attr, char *buf) |
---|
| 3365 | +{ |
---|
| 3366 | + struct Scsi_Host *shost = class_to_shost(cdev); |
---|
| 3367 | + struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata; |
---|
3163 | 3368 | |
---|
3164 | | -struct device_attribute *megaraid_host_attrs[] = { |
---|
| 3369 | + return snprintf(buf, PAGE_SIZE, "%d\n", instance->enable_sdev_max_qd); |
---|
| 3370 | +} |
---|
| 3371 | + |
---|
| 3372 | +static ssize_t |
---|
| 3373 | +enable_sdev_max_qd_store(struct device *cdev, |
---|
| 3374 | + struct device_attribute *attr, const char *buf, size_t count) |
---|
| 3375 | +{ |
---|
| 3376 | + struct Scsi_Host *shost = class_to_shost(cdev); |
---|
| 3377 | + struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata; |
---|
| 3378 | + u32 val = 0; |
---|
| 3379 | + bool is_target_prop; |
---|
| 3380 | + int ret_target_prop = DCMD_FAILED; |
---|
| 3381 | + struct scsi_device *sdev; |
---|
| 3382 | + |
---|
| 3383 | + if (kstrtou32(buf, 0, &val) != 0) { |
---|
| 3384 | + pr_err("megasas: could not set enable_sdev_max_qd\n"); |
---|
| 3385 | + return -EINVAL; |
---|
| 3386 | + } |
---|
| 3387 | + |
---|
| 3388 | + mutex_lock(&instance->reset_mutex); |
---|
| 3389 | + if (val) |
---|
| 3390 | + instance->enable_sdev_max_qd = true; |
---|
| 3391 | + else |
---|
| 3392 | + instance->enable_sdev_max_qd = false; |
---|
| 3393 | + |
---|
| 3394 | + shost_for_each_device(sdev, shost) { |
---|
| 3395 | + ret_target_prop = megasas_get_target_prop(instance, sdev); |
---|
| 3396 | + is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false; |
---|
| 3397 | + megasas_set_fw_assisted_qd(sdev, is_target_prop); |
---|
| 3398 | + } |
---|
| 3399 | + mutex_unlock(&instance->reset_mutex); |
---|
| 3400 | + |
---|
| 3401 | + return strlen(buf); |
---|
| 3402 | +} |
---|
| 3403 | + |
---|
| 3404 | +static ssize_t |
---|
| 3405 | +dump_system_regs_show(struct device *cdev, |
---|
| 3406 | + struct device_attribute *attr, char *buf) |
---|
| 3407 | +{ |
---|
| 3408 | + struct Scsi_Host *shost = class_to_shost(cdev); |
---|
| 3409 | + struct megasas_instance *instance = |
---|
| 3410 | + (struct megasas_instance *)shost->hostdata; |
---|
| 3411 | + |
---|
| 3412 | + return megasas_dump_sys_regs(instance->reg_set, buf); |
---|
| 3413 | +} |
---|
| 3414 | + |
---|
| 3415 | +static ssize_t |
---|
| 3416 | +raid_map_id_show(struct device *cdev, struct device_attribute *attr, |
---|
| 3417 | + char *buf) |
---|
| 3418 | +{ |
---|
| 3419 | + struct Scsi_Host *shost = class_to_shost(cdev); |
---|
| 3420 | + struct megasas_instance *instance = |
---|
| 3421 | + (struct megasas_instance *)shost->hostdata; |
---|
| 3422 | + |
---|
| 3423 | + return snprintf(buf, PAGE_SIZE, "%ld\n", |
---|
| 3424 | + (unsigned long)instance->map_id); |
---|
| 3425 | +} |
---|
| 3426 | + |
---|
| 3427 | +static DEVICE_ATTR_RW(fw_crash_buffer); |
---|
| 3428 | +static DEVICE_ATTR_RO(fw_crash_buffer_size); |
---|
| 3429 | +static DEVICE_ATTR_RW(fw_crash_state); |
---|
| 3430 | +static DEVICE_ATTR_RO(page_size); |
---|
| 3431 | +static DEVICE_ATTR_RO(ldio_outstanding); |
---|
| 3432 | +static DEVICE_ATTR_RO(fw_cmds_outstanding); |
---|
| 3433 | +static DEVICE_ATTR_RW(enable_sdev_max_qd); |
---|
| 3434 | +static DEVICE_ATTR_RO(dump_system_regs); |
---|
| 3435 | +static DEVICE_ATTR_RO(raid_map_id); |
---|
| 3436 | + |
---|
| 3437 | +static struct device_attribute *megaraid_host_attrs[] = { |
---|
3165 | 3438 | &dev_attr_fw_crash_buffer_size, |
---|
3166 | 3439 | &dev_attr_fw_crash_buffer, |
---|
3167 | 3440 | &dev_attr_fw_crash_state, |
---|
3168 | 3441 | &dev_attr_page_size, |
---|
3169 | 3442 | &dev_attr_ldio_outstanding, |
---|
3170 | 3443 | &dev_attr_fw_cmds_outstanding, |
---|
| 3444 | + &dev_attr_enable_sdev_max_qd, |
---|
| 3445 | + &dev_attr_dump_system_regs, |
---|
| 3446 | + &dev_attr_raid_map_id, |
---|
3171 | 3447 | NULL, |
---|
3172 | 3448 | }; |
---|
3173 | 3449 | |
---|
.. | .. |
---|
3189 | 3465 | .eh_timed_out = megasas_reset_timer, |
---|
3190 | 3466 | .shost_attrs = megaraid_host_attrs, |
---|
3191 | 3467 | .bios_param = megasas_bios_param, |
---|
3192 | | - .use_clustering = ENABLE_CLUSTERING, |
---|
3193 | 3468 | .change_queue_depth = scsi_change_queue_depth, |
---|
3194 | | - .no_write_same = 1, |
---|
| 3469 | + .max_segment_size = 0xffffffff, |
---|
3195 | 3470 | }; |
---|
3196 | 3471 | |
---|
3197 | 3472 | /** |
---|
.. | .. |
---|
3207 | 3482 | megasas_complete_int_cmd(struct megasas_instance *instance, |
---|
3208 | 3483 | struct megasas_cmd *cmd) |
---|
3209 | 3484 | { |
---|
3210 | | - cmd->cmd_status_drv = cmd->frame->io.cmd_status; |
---|
| 3485 | + if (cmd->cmd_status_drv == DCMD_INIT) |
---|
| 3486 | + cmd->cmd_status_drv = |
---|
| 3487 | + (cmd->frame->io.cmd_status == MFI_STAT_OK) ? |
---|
| 3488 | + DCMD_SUCCESS : DCMD_FAILED; |
---|
| 3489 | + |
---|
3211 | 3490 | wake_up(&instance->int_cmd_wait_q); |
---|
3212 | 3491 | } |
---|
3213 | 3492 | |
---|
.. | .. |
---|
3226 | 3505 | { |
---|
3227 | 3506 | if (cmd->sync_cmd) { |
---|
3228 | 3507 | cmd->sync_cmd = 0; |
---|
3229 | | - cmd->cmd_status_drv = 0; |
---|
| 3508 | + cmd->cmd_status_drv = DCMD_SUCCESS; |
---|
3230 | 3509 | wake_up(&instance->abort_cmd_wait_q); |
---|
| 3510 | + } |
---|
| 3511 | +} |
---|
| 3512 | + |
---|
| 3513 | +static void |
---|
| 3514 | +megasas_set_ld_removed_by_fw(struct megasas_instance *instance) |
---|
| 3515 | +{ |
---|
| 3516 | + uint i; |
---|
| 3517 | + |
---|
| 3518 | + for (i = 0; (i < MEGASAS_MAX_LD_IDS); i++) { |
---|
| 3519 | + if (instance->ld_ids_prev[i] != 0xff && |
---|
| 3520 | + instance->ld_ids_from_raidmap[i] == 0xff) { |
---|
| 3521 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
---|
| 3522 | + dev_info(&instance->pdev->dev, |
---|
| 3523 | + "LD target ID %d removed from RAID map\n", i); |
---|
| 3524 | + instance->ld_tgtid_status[i] = LD_TARGET_ID_DELETED; |
---|
| 3525 | + } |
---|
3231 | 3526 | } |
---|
3232 | 3527 | } |
---|
3233 | 3528 | |
---|
.. | .. |
---|
3281 | 3576 | megasas_complete_int_cmd(instance, cmd); |
---|
3282 | 3577 | break; |
---|
3283 | 3578 | } |
---|
| 3579 | + fallthrough; |
---|
3284 | 3580 | |
---|
3285 | 3581 | case MFI_CMD_LD_READ: |
---|
3286 | 3582 | case MFI_CMD_LD_WRITE: |
---|
.. | .. |
---|
3351 | 3647 | case MFI_CMD_SMP: |
---|
3352 | 3648 | case MFI_CMD_STP: |
---|
3353 | 3649 | case MFI_CMD_NVME: |
---|
| 3650 | + case MFI_CMD_TOOLBOX: |
---|
3354 | 3651 | megasas_complete_int_cmd(instance, cmd); |
---|
3355 | 3652 | break; |
---|
3356 | 3653 | |
---|
.. | .. |
---|
3391 | 3688 | fusion->fast_path_io = 0; |
---|
3392 | 3689 | } |
---|
3393 | 3690 | |
---|
| 3691 | + if (instance->adapter_type >= INVADER_SERIES) |
---|
| 3692 | + megasas_set_ld_removed_by_fw(instance); |
---|
| 3693 | + |
---|
3394 | 3694 | megasas_sync_map_info(instance); |
---|
3395 | 3695 | spin_unlock_irqrestore(instance->host->host_lock, |
---|
3396 | 3696 | flags); |
---|
| 3697 | + |
---|
3397 | 3698 | break; |
---|
3398 | 3699 | } |
---|
3399 | 3700 | if (opcode == MR_DCMD_CTRL_EVENT_GET_INFO || |
---|
.. | .. |
---|
3500 | 3801 | dev_notice(&instance->pdev->dev, "%p synchronous cmd" |
---|
3501 | 3802 | "on the internal reset queue," |
---|
3502 | 3803 | "issue it again.\n", cmd); |
---|
3503 | | - cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; |
---|
| 3804 | + cmd->cmd_status_drv = DCMD_INIT; |
---|
3504 | 3805 | instance->instancet->fire_cmd(instance, |
---|
3505 | 3806 | cmd->frame_phys_addr, |
---|
3506 | 3807 | 0, instance->reg_set); |
---|
.. | .. |
---|
3538 | 3839 | megasas_register_aen(instance, seq_num, class_locale.word); |
---|
3539 | 3840 | } |
---|
3540 | 3841 | |
---|
3541 | | -/** |
---|
| 3842 | +/* |
---|
3542 | 3843 | * Move the internal reset pending commands to a deferred queue. |
---|
3543 | 3844 | * |
---|
3544 | 3845 | * We move the commands pending at internal reset time to a |
---|
.. | .. |
---|
3546 | 3847 | * completion of the internal reset sequence. if the internal reset |
---|
3547 | 3848 | * did not complete in time, the kernel reset handler would flush |
---|
3548 | 3849 | * these commands. |
---|
3549 | | - **/ |
---|
| 3850 | + */ |
---|
3550 | 3851 | static void |
---|
3551 | 3852 | megasas_internal_reset_defer_cmds(struct megasas_instance *instance) |
---|
3552 | 3853 | { |
---|
.. | .. |
---|
3668 | 3969 | return IRQ_HANDLED; |
---|
3669 | 3970 | } |
---|
3670 | 3971 | |
---|
3671 | | - if ((mfiStatus = instance->instancet->clear_intr( |
---|
3672 | | - instance->reg_set) |
---|
3673 | | - ) == 0) { |
---|
| 3972 | + mfiStatus = instance->instancet->clear_intr(instance); |
---|
| 3973 | + if (mfiStatus == 0) { |
---|
3674 | 3974 | /* Hardware may not set outbound_intr_status in MSI-X mode */ |
---|
3675 | 3975 | if (!instance->msix_vectors) |
---|
3676 | 3976 | return IRQ_NONE; |
---|
.. | .. |
---|
3680 | 3980 | |
---|
3681 | 3981 | if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) { |
---|
3682 | 3982 | fw_state = instance->instancet->read_fw_status_reg( |
---|
3683 | | - instance->reg_set) & MFI_STATE_MASK; |
---|
| 3983 | + instance) & MFI_STATE_MASK; |
---|
3684 | 3984 | |
---|
3685 | 3985 | if (fw_state != MFI_STATE_FAULT) { |
---|
3686 | 3986 | dev_notice(&instance->pdev->dev, "fw state:%x\n", |
---|
.. | .. |
---|
3725 | 4025 | tasklet_schedule(&instance->isr_tasklet); |
---|
3726 | 4026 | return IRQ_HANDLED; |
---|
3727 | 4027 | } |
---|
| 4028 | + |
---|
3728 | 4029 | /** |
---|
3729 | 4030 | * megasas_isr - isr entry point |
---|
| 4031 | + * @irq: IRQ number |
---|
| 4032 | + * @devp: IRQ context address |
---|
3730 | 4033 | */ |
---|
3731 | 4034 | static irqreturn_t megasas_isr(int irq, void *devp) |
---|
3732 | 4035 | { |
---|
.. | .. |
---|
3748 | 4051 | /** |
---|
3749 | 4052 | * megasas_transition_to_ready - Move the FW to READY state |
---|
3750 | 4053 | * @instance: Adapter soft state |
---|
| 4054 | + * @ocr: Adapter reset state |
---|
3751 | 4055 | * |
---|
3752 | 4056 | * During the initialization, FW passes can potentially be in any one of |
---|
3753 | 4057 | * several possible states. If the FW in operational, waiting-for-handshake |
---|
.. | .. |
---|
3760 | 4064 | int i; |
---|
3761 | 4065 | u8 max_wait; |
---|
3762 | 4066 | u32 fw_state; |
---|
3763 | | - u32 cur_state; |
---|
3764 | 4067 | u32 abs_state, curr_abs_state; |
---|
3765 | 4068 | |
---|
3766 | | - abs_state = instance->instancet->read_fw_status_reg(instance->reg_set); |
---|
| 4069 | + abs_state = instance->instancet->read_fw_status_reg(instance); |
---|
3767 | 4070 | fw_state = abs_state & MFI_STATE_MASK; |
---|
3768 | 4071 | |
---|
3769 | 4072 | if (fw_state != MFI_STATE_READY) |
---|
.. | .. |
---|
3775 | 4078 | switch (fw_state) { |
---|
3776 | 4079 | |
---|
3777 | 4080 | case MFI_STATE_FAULT: |
---|
3778 | | - dev_printk(KERN_DEBUG, &instance->pdev->dev, "FW in FAULT state!!\n"); |
---|
| 4081 | + dev_printk(KERN_ERR, &instance->pdev->dev, |
---|
| 4082 | + "FW in FAULT state, Fault code:0x%x subcode:0x%x func:%s\n", |
---|
| 4083 | + abs_state & MFI_STATE_FAULT_CODE, |
---|
| 4084 | + abs_state & MFI_STATE_FAULT_SUBCODE, __func__); |
---|
3779 | 4085 | if (ocr) { |
---|
3780 | 4086 | max_wait = MEGASAS_RESET_WAIT_TIME; |
---|
3781 | | - cur_state = MFI_STATE_FAULT; |
---|
3782 | 4087 | break; |
---|
3783 | | - } else |
---|
| 4088 | + } else { |
---|
| 4089 | + dev_printk(KERN_DEBUG, &instance->pdev->dev, "System Register set:\n"); |
---|
| 4090 | + megasas_dump_reg_set(instance->reg_set); |
---|
3784 | 4091 | return -ENODEV; |
---|
| 4092 | + } |
---|
3785 | 4093 | |
---|
3786 | 4094 | case MFI_STATE_WAIT_HANDSHAKE: |
---|
3787 | 4095 | /* |
---|
.. | .. |
---|
3801 | 4109 | &instance->reg_set->inbound_doorbell); |
---|
3802 | 4110 | |
---|
3803 | 4111 | max_wait = MEGASAS_RESET_WAIT_TIME; |
---|
3804 | | - cur_state = MFI_STATE_WAIT_HANDSHAKE; |
---|
3805 | 4112 | break; |
---|
3806 | 4113 | |
---|
3807 | 4114 | case MFI_STATE_BOOT_MESSAGE_PENDING: |
---|
.. | .. |
---|
3817 | 4124 | &instance->reg_set->inbound_doorbell); |
---|
3818 | 4125 | |
---|
3819 | 4126 | max_wait = MEGASAS_RESET_WAIT_TIME; |
---|
3820 | | - cur_state = MFI_STATE_BOOT_MESSAGE_PENDING; |
---|
3821 | 4127 | break; |
---|
3822 | 4128 | |
---|
3823 | 4129 | case MFI_STATE_OPERATIONAL: |
---|
.. | .. |
---|
3835 | 4141 | |
---|
3836 | 4142 | if (instance->adapter_type != MFI_SERIES) { |
---|
3837 | 4143 | for (i = 0; i < (10 * 1000); i += 20) { |
---|
3838 | | - if (readl( |
---|
| 4144 | + if (megasas_readl( |
---|
| 4145 | + instance, |
---|
3839 | 4146 | &instance-> |
---|
3840 | 4147 | reg_set-> |
---|
3841 | 4148 | doorbell) & 1) |
---|
.. | .. |
---|
3849 | 4156 | &instance->reg_set->inbound_doorbell); |
---|
3850 | 4157 | |
---|
3851 | 4158 | max_wait = MEGASAS_RESET_WAIT_TIME; |
---|
3852 | | - cur_state = MFI_STATE_OPERATIONAL; |
---|
3853 | 4159 | break; |
---|
3854 | 4160 | |
---|
3855 | 4161 | case MFI_STATE_UNDEFINED: |
---|
.. | .. |
---|
3857 | 4163 | * This state should not last for more than 2 seconds |
---|
3858 | 4164 | */ |
---|
3859 | 4165 | max_wait = MEGASAS_RESET_WAIT_TIME; |
---|
3860 | | - cur_state = MFI_STATE_UNDEFINED; |
---|
3861 | 4166 | break; |
---|
3862 | 4167 | |
---|
3863 | 4168 | case MFI_STATE_BB_INIT: |
---|
3864 | 4169 | max_wait = MEGASAS_RESET_WAIT_TIME; |
---|
3865 | | - cur_state = MFI_STATE_BB_INIT; |
---|
3866 | 4170 | break; |
---|
3867 | 4171 | |
---|
3868 | 4172 | case MFI_STATE_FW_INIT: |
---|
3869 | 4173 | max_wait = MEGASAS_RESET_WAIT_TIME; |
---|
3870 | | - cur_state = MFI_STATE_FW_INIT; |
---|
3871 | 4174 | break; |
---|
3872 | 4175 | |
---|
3873 | 4176 | case MFI_STATE_FW_INIT_2: |
---|
3874 | 4177 | max_wait = MEGASAS_RESET_WAIT_TIME; |
---|
3875 | | - cur_state = MFI_STATE_FW_INIT_2; |
---|
3876 | 4178 | break; |
---|
3877 | 4179 | |
---|
3878 | 4180 | case MFI_STATE_DEVICE_SCAN: |
---|
3879 | 4181 | max_wait = MEGASAS_RESET_WAIT_TIME; |
---|
3880 | | - cur_state = MFI_STATE_DEVICE_SCAN; |
---|
3881 | 4182 | break; |
---|
3882 | 4183 | |
---|
3883 | 4184 | case MFI_STATE_FLUSH_CACHE: |
---|
3884 | 4185 | max_wait = MEGASAS_RESET_WAIT_TIME; |
---|
3885 | | - cur_state = MFI_STATE_FLUSH_CACHE; |
---|
3886 | 4186 | break; |
---|
3887 | 4187 | |
---|
3888 | 4188 | default: |
---|
3889 | 4189 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "Unknown state 0x%x\n", |
---|
3890 | 4190 | fw_state); |
---|
| 4191 | + dev_printk(KERN_DEBUG, &instance->pdev->dev, "System Register set:\n"); |
---|
| 4192 | + megasas_dump_reg_set(instance->reg_set); |
---|
3891 | 4193 | return -ENODEV; |
---|
3892 | 4194 | } |
---|
3893 | 4195 | |
---|
.. | .. |
---|
3896 | 4198 | */ |
---|
3897 | 4199 | for (i = 0; i < max_wait * 50; i++) { |
---|
3898 | 4200 | curr_abs_state = instance->instancet-> |
---|
3899 | | - read_fw_status_reg(instance->reg_set); |
---|
| 4201 | + read_fw_status_reg(instance); |
---|
3900 | 4202 | |
---|
3901 | 4203 | if (abs_state == curr_abs_state) { |
---|
3902 | 4204 | msleep(20); |
---|
.. | .. |
---|
3910 | 4212 | if (curr_abs_state == abs_state) { |
---|
3911 | 4213 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "FW state [%d] hasn't changed " |
---|
3912 | 4214 | "in %d secs\n", fw_state, max_wait); |
---|
| 4215 | + dev_printk(KERN_DEBUG, &instance->pdev->dev, "System Register set:\n"); |
---|
| 4216 | + megasas_dump_reg_set(instance->reg_set); |
---|
3913 | 4217 | return -ENODEV; |
---|
3914 | 4218 | } |
---|
3915 | 4219 | |
---|
.. | .. |
---|
3973 | 4277 | { |
---|
3974 | 4278 | int i; |
---|
3975 | 4279 | u16 max_cmd; |
---|
3976 | | - u32 sge_sz; |
---|
3977 | 4280 | u32 frame_count; |
---|
3978 | 4281 | struct megasas_cmd *cmd; |
---|
3979 | 4282 | |
---|
3980 | 4283 | 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 | 4284 | |
---|
3992 | 4285 | /* |
---|
3993 | 4286 | * For MFI controllers. |
---|
.. | .. |
---|
4239 | 4532 | switch (dcmd_timeout_ocr_possible(instance)) { |
---|
4240 | 4533 | case INITIATE_OCR: |
---|
4241 | 4534 | cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
---|
| 4535 | + mutex_unlock(&instance->reset_mutex); |
---|
4242 | 4536 | megasas_reset_fusion(instance->host, |
---|
4243 | 4537 | MFI_IO_TIMEOUT_OCR); |
---|
| 4538 | + mutex_lock(&instance->reset_mutex); |
---|
4244 | 4539 | break; |
---|
4245 | 4540 | case KILL_ADAPTER: |
---|
4246 | 4541 | megaraid_sas_kill_hba(instance); |
---|
.. | .. |
---|
4276 | 4571 | struct megasas_dcmd_frame *dcmd; |
---|
4277 | 4572 | struct MR_PD_LIST *ci; |
---|
4278 | 4573 | struct MR_PD_ADDRESS *pd_addr; |
---|
4279 | | - dma_addr_t ci_h = 0; |
---|
4280 | 4574 | |
---|
4281 | 4575 | if (instance->pd_list_not_supported) { |
---|
4282 | 4576 | dev_info(&instance->pdev->dev, "MR_DCMD_PD_LIST_QUERY " |
---|
.. | .. |
---|
4285 | 4579 | } |
---|
4286 | 4580 | |
---|
4287 | 4581 | ci = instance->pd_list_buf; |
---|
4288 | | - ci_h = instance->pd_list_buf_h; |
---|
4289 | 4582 | |
---|
4290 | 4583 | cmd = megasas_get_cmd(instance); |
---|
4291 | 4584 | |
---|
.. | .. |
---|
4358 | 4651 | |
---|
4359 | 4652 | case DCMD_SUCCESS: |
---|
4360 | 4653 | pd_addr = ci->addr; |
---|
| 4654 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
---|
| 4655 | + dev_info(&instance->pdev->dev, "%s, sysPD count: 0x%x\n", |
---|
| 4656 | + __func__, le32_to_cpu(ci->count)); |
---|
4361 | 4657 | |
---|
4362 | 4658 | if ((le32_to_cpu(ci->count) > |
---|
4363 | 4659 | (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) |
---|
.. | .. |
---|
4373 | 4669 | pd_addr->scsiDevType; |
---|
4374 | 4670 | instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveState = |
---|
4375 | 4671 | MR_PD_STATE_SYSTEM; |
---|
| 4672 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
---|
| 4673 | + dev_info(&instance->pdev->dev, |
---|
| 4674 | + "PD%d: targetID: 0x%03x deviceType:0x%x\n", |
---|
| 4675 | + pd_index, le16_to_cpu(pd_addr->deviceId), |
---|
| 4676 | + pd_addr->scsiDevType); |
---|
4376 | 4677 | pd_addr++; |
---|
4377 | 4678 | } |
---|
4378 | 4679 | |
---|
.. | .. |
---|
4476 | 4777 | break; |
---|
4477 | 4778 | |
---|
4478 | 4779 | case DCMD_SUCCESS: |
---|
| 4780 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
---|
| 4781 | + dev_info(&instance->pdev->dev, "%s, LD count: 0x%x\n", |
---|
| 4782 | + __func__, ld_count); |
---|
| 4783 | + |
---|
4479 | 4784 | if (ld_count > instance->fw_supported_vd_count) |
---|
4480 | 4785 | break; |
---|
4481 | 4786 | |
---|
.. | .. |
---|
4485 | 4790 | if (ci->ldList[ld_index].state != 0) { |
---|
4486 | 4791 | ids = ci->ldList[ld_index].ref.targetId; |
---|
4487 | 4792 | instance->ld_ids[ids] = ci->ldList[ld_index].ref.targetId; |
---|
| 4793 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
---|
| 4794 | + dev_info(&instance->pdev->dev, |
---|
| 4795 | + "LD%d: targetID: 0x%03x\n", |
---|
| 4796 | + ld_index, ids); |
---|
4488 | 4797 | } |
---|
4489 | 4798 | } |
---|
4490 | 4799 | |
---|
.. | .. |
---|
4500 | 4809 | /** |
---|
4501 | 4810 | * megasas_ld_list_query - Returns FW's ld_list structure |
---|
4502 | 4811 | * @instance: Adapter soft state |
---|
4503 | | - * @ld_list: ld_list structure |
---|
| 4812 | + * @query_type: ld_list structure type |
---|
4504 | 4813 | * |
---|
4505 | 4814 | * Issues an internal command (DCMD) to get the FW's controller PD |
---|
4506 | 4815 | * list structure. This information is mainly used to find out SYSTEM |
---|
.. | .. |
---|
4588 | 4897 | case DCMD_SUCCESS: |
---|
4589 | 4898 | tgtid_count = le32_to_cpu(ci->count); |
---|
4590 | 4899 | |
---|
| 4900 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
---|
| 4901 | + dev_info(&instance->pdev->dev, "%s, LD count: 0x%x\n", |
---|
| 4902 | + __func__, tgtid_count); |
---|
| 4903 | + |
---|
4591 | 4904 | if ((tgtid_count > (instance->fw_supported_vd_count))) |
---|
4592 | 4905 | break; |
---|
4593 | 4906 | |
---|
.. | .. |
---|
4595 | 4908 | for (ld_index = 0; ld_index < tgtid_count; ld_index++) { |
---|
4596 | 4909 | ids = ci->targetId[ld_index]; |
---|
4597 | 4910 | instance->ld_ids[ids] = ci->targetId[ld_index]; |
---|
| 4911 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
---|
| 4912 | + dev_info(&instance->pdev->dev, "LD%d: targetID: 0x%03x\n", |
---|
| 4913 | + ld_index, ci->targetId[ld_index]); |
---|
4598 | 4914 | } |
---|
4599 | 4915 | |
---|
| 4916 | + break; |
---|
| 4917 | + } |
---|
| 4918 | + |
---|
| 4919 | + if (ret != DCMD_TIMEOUT) |
---|
| 4920 | + megasas_return_cmd(instance, cmd); |
---|
| 4921 | + |
---|
| 4922 | + return ret; |
---|
| 4923 | +} |
---|
| 4924 | + |
---|
| 4925 | +/** |
---|
| 4926 | + * dcmd.opcode - MR_DCMD_CTRL_DEVICE_LIST_GET |
---|
| 4927 | + * dcmd.mbox - reserved |
---|
| 4928 | + * dcmd.sge IN - ptr to return MR_HOST_DEVICE_LIST structure |
---|
| 4929 | + * Desc: This DCMD will return the combined device list |
---|
| 4930 | + * Status: MFI_STAT_OK - List returned successfully |
---|
| 4931 | + * MFI_STAT_INVALID_CMD - Firmware support for the feature has been |
---|
| 4932 | + * disabled |
---|
| 4933 | + * @instance: Adapter soft state |
---|
| 4934 | + * @is_probe: Driver probe check |
---|
| 4935 | + * Return: 0 if DCMD succeeded |
---|
| 4936 | + * non-zero if failed |
---|
| 4937 | + */ |
---|
| 4938 | +static int |
---|
| 4939 | +megasas_host_device_list_query(struct megasas_instance *instance, |
---|
| 4940 | + bool is_probe) |
---|
| 4941 | +{ |
---|
| 4942 | + int ret, i, target_id; |
---|
| 4943 | + struct megasas_cmd *cmd; |
---|
| 4944 | + struct megasas_dcmd_frame *dcmd; |
---|
| 4945 | + struct MR_HOST_DEVICE_LIST *ci; |
---|
| 4946 | + u32 count; |
---|
| 4947 | + dma_addr_t ci_h; |
---|
| 4948 | + |
---|
| 4949 | + ci = instance->host_device_list_buf; |
---|
| 4950 | + ci_h = instance->host_device_list_buf_h; |
---|
| 4951 | + |
---|
| 4952 | + cmd = megasas_get_cmd(instance); |
---|
| 4953 | + |
---|
| 4954 | + if (!cmd) { |
---|
| 4955 | + dev_warn(&instance->pdev->dev, |
---|
| 4956 | + "%s: failed to get cmd\n", |
---|
| 4957 | + __func__); |
---|
| 4958 | + return -ENOMEM; |
---|
| 4959 | + } |
---|
| 4960 | + |
---|
| 4961 | + dcmd = &cmd->frame->dcmd; |
---|
| 4962 | + |
---|
| 4963 | + memset(ci, 0, sizeof(*ci)); |
---|
| 4964 | + memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); |
---|
| 4965 | + |
---|
| 4966 | + dcmd->mbox.b[0] = is_probe ? 0 : 1; |
---|
| 4967 | + dcmd->cmd = MFI_CMD_DCMD; |
---|
| 4968 | + dcmd->cmd_status = MFI_STAT_INVALID_STATUS; |
---|
| 4969 | + dcmd->sge_count = 1; |
---|
| 4970 | + dcmd->flags = MFI_FRAME_DIR_READ; |
---|
| 4971 | + dcmd->timeout = 0; |
---|
| 4972 | + dcmd->pad_0 = 0; |
---|
| 4973 | + dcmd->data_xfer_len = cpu_to_le32(HOST_DEVICE_LIST_SZ); |
---|
| 4974 | + dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_DEVICE_LIST_GET); |
---|
| 4975 | + |
---|
| 4976 | + megasas_set_dma_settings(instance, dcmd, ci_h, HOST_DEVICE_LIST_SZ); |
---|
| 4977 | + |
---|
| 4978 | + if (!instance->mask_interrupts) { |
---|
| 4979 | + ret = megasas_issue_blocked_cmd(instance, cmd, |
---|
| 4980 | + MFI_IO_TIMEOUT_SECS); |
---|
| 4981 | + } else { |
---|
| 4982 | + ret = megasas_issue_polled(instance, cmd); |
---|
| 4983 | + cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
---|
| 4984 | + } |
---|
| 4985 | + |
---|
| 4986 | + switch (ret) { |
---|
| 4987 | + case DCMD_SUCCESS: |
---|
| 4988 | + /* Fill the internal pd_list and ld_ids array based on |
---|
| 4989 | + * targetIds returned by FW |
---|
| 4990 | + */ |
---|
| 4991 | + count = le32_to_cpu(ci->count); |
---|
| 4992 | + |
---|
| 4993 | + if (count > (MEGASAS_MAX_PD + MAX_LOGICAL_DRIVES_EXT)) |
---|
| 4994 | + break; |
---|
| 4995 | + |
---|
| 4996 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
---|
| 4997 | + dev_info(&instance->pdev->dev, "%s, Device count: 0x%x\n", |
---|
| 4998 | + __func__, count); |
---|
| 4999 | + |
---|
| 5000 | + memset(instance->local_pd_list, 0, |
---|
| 5001 | + MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)); |
---|
| 5002 | + memset(instance->ld_ids, 0xff, MAX_LOGICAL_DRIVES_EXT); |
---|
| 5003 | + for (i = 0; i < count; i++) { |
---|
| 5004 | + target_id = le16_to_cpu(ci->host_device_list[i].target_id); |
---|
| 5005 | + if (ci->host_device_list[i].flags.u.bits.is_sys_pd) { |
---|
| 5006 | + instance->local_pd_list[target_id].tid = target_id; |
---|
| 5007 | + instance->local_pd_list[target_id].driveType = |
---|
| 5008 | + ci->host_device_list[i].scsi_type; |
---|
| 5009 | + instance->local_pd_list[target_id].driveState = |
---|
| 5010 | + MR_PD_STATE_SYSTEM; |
---|
| 5011 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
---|
| 5012 | + dev_info(&instance->pdev->dev, |
---|
| 5013 | + "Device %d: PD targetID: 0x%03x deviceType:0x%x\n", |
---|
| 5014 | + i, target_id, ci->host_device_list[i].scsi_type); |
---|
| 5015 | + } else { |
---|
| 5016 | + instance->ld_ids[target_id] = target_id; |
---|
| 5017 | + if (megasas_dbg_lvl & LD_PD_DEBUG) |
---|
| 5018 | + dev_info(&instance->pdev->dev, |
---|
| 5019 | + "Device %d: LD targetID: 0x%03x\n", |
---|
| 5020 | + i, target_id); |
---|
| 5021 | + } |
---|
| 5022 | + } |
---|
| 5023 | + |
---|
| 5024 | + memcpy(instance->pd_list, instance->local_pd_list, |
---|
| 5025 | + sizeof(instance->pd_list)); |
---|
| 5026 | + break; |
---|
| 5027 | + |
---|
| 5028 | + case DCMD_TIMEOUT: |
---|
| 5029 | + switch (dcmd_timeout_ocr_possible(instance)) { |
---|
| 5030 | + case INITIATE_OCR: |
---|
| 5031 | + cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
---|
| 5032 | + mutex_unlock(&instance->reset_mutex); |
---|
| 5033 | + megasas_reset_fusion(instance->host, |
---|
| 5034 | + MFI_IO_TIMEOUT_OCR); |
---|
| 5035 | + mutex_lock(&instance->reset_mutex); |
---|
| 5036 | + break; |
---|
| 5037 | + case KILL_ADAPTER: |
---|
| 5038 | + megaraid_sas_kill_hba(instance); |
---|
| 5039 | + break; |
---|
| 5040 | + case IGNORE_TIMEOUT: |
---|
| 5041 | + dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n", |
---|
| 5042 | + __func__, __LINE__); |
---|
| 5043 | + break; |
---|
| 5044 | + } |
---|
| 5045 | + break; |
---|
| 5046 | + case DCMD_FAILED: |
---|
| 5047 | + dev_err(&instance->pdev->dev, |
---|
| 5048 | + "%s: MR_DCMD_CTRL_DEVICE_LIST_GET failed\n", |
---|
| 5049 | + __func__); |
---|
4600 | 5050 | break; |
---|
4601 | 5051 | } |
---|
4602 | 5052 | |
---|
.. | .. |
---|
4639 | 5089 | } |
---|
4640 | 5090 | |
---|
4641 | 5091 | dev_info(&instance->pdev->dev, |
---|
4642 | | - "firmware type\t: %s\n", |
---|
4643 | | - instance->supportmax256vd ? "Extended VD(240 VD)firmware" : |
---|
4644 | | - "Legacy(64 VD) firmware"); |
---|
| 5092 | + "FW provided supportMaxExtLDs: %d\tmax_lds: %d\n", |
---|
| 5093 | + instance->ctrl_info_buf->adapterOperations3.supportMaxExtLDs ? 1 : 0, |
---|
| 5094 | + instance->ctrl_info_buf->max_lds); |
---|
4645 | 5095 | |
---|
4646 | 5096 | if (instance->max_raid_mapsize) { |
---|
4647 | 5097 | ventura_map_sz = instance->max_raid_mapsize * |
---|
.. | .. |
---|
4664 | 5114 | } |
---|
4665 | 5115 | /* irrespective of FW raid maps, driver raid map is constant */ |
---|
4666 | 5116 | fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL); |
---|
| 5117 | +} |
---|
| 5118 | + |
---|
| 5119 | +/* |
---|
| 5120 | + * dcmd.opcode - MR_DCMD_CTRL_SNAPDUMP_GET_PROPERTIES |
---|
| 5121 | + * dcmd.hdr.length - number of bytes to read |
---|
| 5122 | + * dcmd.sge - Ptr to MR_SNAPDUMP_PROPERTIES |
---|
| 5123 | + * Desc: Fill in snapdump properties |
---|
| 5124 | + * Status: MFI_STAT_OK- Command successful |
---|
| 5125 | + */ |
---|
| 5126 | +void megasas_get_snapdump_properties(struct megasas_instance *instance) |
---|
| 5127 | +{ |
---|
| 5128 | + int ret = 0; |
---|
| 5129 | + struct megasas_cmd *cmd; |
---|
| 5130 | + struct megasas_dcmd_frame *dcmd; |
---|
| 5131 | + struct MR_SNAPDUMP_PROPERTIES *ci; |
---|
| 5132 | + dma_addr_t ci_h = 0; |
---|
| 5133 | + |
---|
| 5134 | + ci = instance->snapdump_prop; |
---|
| 5135 | + ci_h = instance->snapdump_prop_h; |
---|
| 5136 | + |
---|
| 5137 | + if (!ci) |
---|
| 5138 | + return; |
---|
| 5139 | + |
---|
| 5140 | + cmd = megasas_get_cmd(instance); |
---|
| 5141 | + |
---|
| 5142 | + if (!cmd) { |
---|
| 5143 | + dev_dbg(&instance->pdev->dev, "Failed to get a free cmd\n"); |
---|
| 5144 | + return; |
---|
| 5145 | + } |
---|
| 5146 | + |
---|
| 5147 | + dcmd = &cmd->frame->dcmd; |
---|
| 5148 | + |
---|
| 5149 | + memset(ci, 0, sizeof(*ci)); |
---|
| 5150 | + memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); |
---|
| 5151 | + |
---|
| 5152 | + dcmd->cmd = MFI_CMD_DCMD; |
---|
| 5153 | + dcmd->cmd_status = MFI_STAT_INVALID_STATUS; |
---|
| 5154 | + dcmd->sge_count = 1; |
---|
| 5155 | + dcmd->flags = MFI_FRAME_DIR_READ; |
---|
| 5156 | + dcmd->timeout = 0; |
---|
| 5157 | + dcmd->pad_0 = 0; |
---|
| 5158 | + dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_SNAPDUMP_PROPERTIES)); |
---|
| 5159 | + dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SNAPDUMP_GET_PROPERTIES); |
---|
| 5160 | + |
---|
| 5161 | + megasas_set_dma_settings(instance, dcmd, ci_h, |
---|
| 5162 | + sizeof(struct MR_SNAPDUMP_PROPERTIES)); |
---|
| 5163 | + |
---|
| 5164 | + if (!instance->mask_interrupts) { |
---|
| 5165 | + ret = megasas_issue_blocked_cmd(instance, cmd, |
---|
| 5166 | + MFI_IO_TIMEOUT_SECS); |
---|
| 5167 | + } else { |
---|
| 5168 | + ret = megasas_issue_polled(instance, cmd); |
---|
| 5169 | + cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
---|
| 5170 | + } |
---|
| 5171 | + |
---|
| 5172 | + switch (ret) { |
---|
| 5173 | + case DCMD_SUCCESS: |
---|
| 5174 | + instance->snapdump_wait_time = |
---|
| 5175 | + min_t(u8, ci->trigger_min_num_sec_before_ocr, |
---|
| 5176 | + MEGASAS_MAX_SNAP_DUMP_WAIT_TIME); |
---|
| 5177 | + break; |
---|
| 5178 | + |
---|
| 5179 | + case DCMD_TIMEOUT: |
---|
| 5180 | + switch (dcmd_timeout_ocr_possible(instance)) { |
---|
| 5181 | + case INITIATE_OCR: |
---|
| 5182 | + cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
---|
| 5183 | + mutex_unlock(&instance->reset_mutex); |
---|
| 5184 | + megasas_reset_fusion(instance->host, |
---|
| 5185 | + MFI_IO_TIMEOUT_OCR); |
---|
| 5186 | + mutex_lock(&instance->reset_mutex); |
---|
| 5187 | + break; |
---|
| 5188 | + case KILL_ADAPTER: |
---|
| 5189 | + megaraid_sas_kill_hba(instance); |
---|
| 5190 | + break; |
---|
| 5191 | + case IGNORE_TIMEOUT: |
---|
| 5192 | + dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n", |
---|
| 5193 | + __func__, __LINE__); |
---|
| 5194 | + break; |
---|
| 5195 | + } |
---|
| 5196 | + } |
---|
| 5197 | + |
---|
| 5198 | + if (ret != DCMD_TIMEOUT) |
---|
| 5199 | + megasas_return_cmd(instance, cmd); |
---|
4667 | 5200 | } |
---|
4668 | 5201 | |
---|
4669 | 5202 | /** |
---|
.. | .. |
---|
4725 | 5258 | * CPU endianness format. |
---|
4726 | 5259 | */ |
---|
4727 | 5260 | le32_to_cpus((u32 *)&ci->properties.OnOffProperties); |
---|
| 5261 | + le16_to_cpus((u16 *)&ci->properties.on_off_properties2); |
---|
4728 | 5262 | le32_to_cpus((u32 *)&ci->adapterOperations2); |
---|
4729 | 5263 | le32_to_cpus((u32 *)&ci->adapterOperations3); |
---|
4730 | 5264 | le16_to_cpus((u16 *)&ci->adapter_operations4); |
---|
| 5265 | + le32_to_cpus((u32 *)&ci->adapter_operations5); |
---|
4731 | 5266 | |
---|
4732 | 5267 | /* Update the latest Ext VD info. |
---|
4733 | 5268 | * From Init path, store current firmware details. |
---|
.. | .. |
---|
4735 | 5270 | * in case of Firmware upgrade without system reboot. |
---|
4736 | 5271 | */ |
---|
4737 | 5272 | megasas_update_ext_vd_details(instance); |
---|
4738 | | - instance->use_seqnum_jbod_fp = |
---|
| 5273 | + instance->support_seqnum_jbod_fp = |
---|
4739 | 5274 | ci->adapterOperations3.useSeqNumJbodFP; |
---|
4740 | 5275 | instance->support_morethan256jbod = |
---|
4741 | 5276 | ci->adapter_operations4.support_pd_map_target_id; |
---|
4742 | 5277 | instance->support_nvme_passthru = |
---|
4743 | 5278 | ci->adapter_operations4.support_nvme_passthru; |
---|
| 5279 | + instance->support_pci_lane_margining = |
---|
| 5280 | + ci->adapter_operations5.support_pci_lane_margining; |
---|
4744 | 5281 | instance->task_abort_tmo = ci->TaskAbortTO; |
---|
4745 | 5282 | instance->max_reset_tmo = ci->MaxResetTO; |
---|
4746 | 5283 | |
---|
4747 | 5284 | /*Check whether controller is iMR or MR */ |
---|
4748 | 5285 | instance->is_imr = (ci->memory_size ? 0 : 1); |
---|
| 5286 | + |
---|
| 5287 | + instance->snapdump_wait_time = |
---|
| 5288 | + (ci->properties.on_off_properties2.enable_snap_dump ? |
---|
| 5289 | + MEGASAS_DEFAULT_SNAP_DUMP_WAIT_TIME : 0); |
---|
| 5290 | + |
---|
| 5291 | + instance->enable_fw_dev_list = |
---|
| 5292 | + ci->properties.on_off_properties2.enable_fw_dev_list; |
---|
| 5293 | + |
---|
4749 | 5294 | dev_info(&instance->pdev->dev, |
---|
4750 | 5295 | "controller type\t: %s(%dMB)\n", |
---|
4751 | 5296 | instance->is_imr ? "iMR" : "MR", |
---|
.. | .. |
---|
4764 | 5309 | dev_info(&instance->pdev->dev, |
---|
4765 | 5310 | "FW provided TM TaskAbort/Reset timeout\t: %d secs/%d secs\n", |
---|
4766 | 5311 | instance->task_abort_tmo, instance->max_reset_tmo); |
---|
| 5312 | + dev_info(&instance->pdev->dev, "JBOD sequence map support\t: %s\n", |
---|
| 5313 | + instance->support_seqnum_jbod_fp ? "Yes" : "No"); |
---|
| 5314 | + dev_info(&instance->pdev->dev, "PCI Lane Margining support\t: %s\n", |
---|
| 5315 | + instance->support_pci_lane_margining ? "Yes" : "No"); |
---|
4767 | 5316 | |
---|
4768 | 5317 | break; |
---|
4769 | 5318 | |
---|
.. | .. |
---|
4771 | 5320 | switch (dcmd_timeout_ocr_possible(instance)) { |
---|
4772 | 5321 | case INITIATE_OCR: |
---|
4773 | 5322 | cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
---|
| 5323 | + mutex_unlock(&instance->reset_mutex); |
---|
4774 | 5324 | megasas_reset_fusion(instance->host, |
---|
4775 | 5325 | MFI_IO_TIMEOUT_OCR); |
---|
| 5326 | + mutex_lock(&instance->reset_mutex); |
---|
4776 | 5327 | break; |
---|
4777 | 5328 | case KILL_ADAPTER: |
---|
4778 | 5329 | megaraid_sas_kill_hba(instance); |
---|
.. | .. |
---|
4947 | 5498 | static u32 |
---|
4948 | 5499 | megasas_init_adapter_mfi(struct megasas_instance *instance) |
---|
4949 | 5500 | { |
---|
4950 | | - struct megasas_register_set __iomem *reg_set; |
---|
4951 | 5501 | u32 context_sz; |
---|
4952 | 5502 | u32 reply_q_sz; |
---|
4953 | | - |
---|
4954 | | - reg_set = instance->reg_set; |
---|
4955 | 5503 | |
---|
4956 | 5504 | /* |
---|
4957 | 5505 | * Get various operational parameters from status register |
---|
4958 | 5506 | */ |
---|
4959 | | - instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF; |
---|
| 5507 | + instance->max_fw_cmds = instance->instancet->read_fw_status_reg(instance) & 0x00FFFF; |
---|
4960 | 5508 | /* |
---|
4961 | 5509 | * Reduce the max supported cmds by 1. This is to ensure that the |
---|
4962 | 5510 | * reply_q_sz (1 more than the max cmd that driver may send) |
---|
.. | .. |
---|
4964 | 5512 | */ |
---|
4965 | 5513 | instance->max_fw_cmds = instance->max_fw_cmds-1; |
---|
4966 | 5514 | instance->max_mfi_cmds = instance->max_fw_cmds; |
---|
4967 | | - instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> |
---|
| 5515 | + instance->max_num_sge = (instance->instancet->read_fw_status_reg(instance) & 0xFF0000) >> |
---|
4968 | 5516 | 0x10; |
---|
4969 | 5517 | /* |
---|
4970 | 5518 | * For MFI skinny adapters, MEGASAS_SKINNY_INT_CMDS commands |
---|
.. | .. |
---|
5000 | 5548 | context_sz = sizeof(u32); |
---|
5001 | 5549 | reply_q_sz = context_sz * (instance->max_fw_cmds + 1); |
---|
5002 | 5550 | |
---|
5003 | | - instance->reply_queue = pci_alloc_consistent(instance->pdev, |
---|
5004 | | - reply_q_sz, |
---|
5005 | | - &instance->reply_queue_h); |
---|
| 5551 | + instance->reply_queue = dma_alloc_coherent(&instance->pdev->dev, |
---|
| 5552 | + reply_q_sz, &instance->reply_queue_h, GFP_KERNEL); |
---|
5006 | 5553 | |
---|
5007 | 5554 | if (!instance->reply_queue) { |
---|
5008 | 5555 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "Out of DMA mem for reply queue\n"); |
---|
.. | .. |
---|
5021 | 5568 | |
---|
5022 | 5569 | instance->fw_support_ieee = 0; |
---|
5023 | 5570 | instance->fw_support_ieee = |
---|
5024 | | - (instance->instancet->read_fw_status_reg(reg_set) & |
---|
| 5571 | + (instance->instancet->read_fw_status_reg(instance) & |
---|
5025 | 5572 | 0x04000000); |
---|
5026 | 5573 | |
---|
5027 | 5574 | dev_notice(&instance->pdev->dev, "megasas_init_mfi: fw_support_ieee=%d", |
---|
.. | .. |
---|
5034 | 5581 | |
---|
5035 | 5582 | fail_fw_init: |
---|
5036 | 5583 | |
---|
5037 | | - pci_free_consistent(instance->pdev, reply_q_sz, |
---|
| 5584 | + dma_free_coherent(&instance->pdev->dev, reply_q_sz, |
---|
5038 | 5585 | instance->reply_queue, instance->reply_queue_h); |
---|
5039 | 5586 | fail_reply_queue: |
---|
5040 | 5587 | megasas_free_cmds(instance); |
---|
5041 | 5588 | |
---|
5042 | 5589 | fail_alloc_cmds: |
---|
5043 | 5590 | return 1; |
---|
| 5591 | +} |
---|
| 5592 | + |
---|
| 5593 | +static |
---|
| 5594 | +void megasas_setup_irq_poll(struct megasas_instance *instance) |
---|
| 5595 | +{ |
---|
| 5596 | + struct megasas_irq_context *irq_ctx; |
---|
| 5597 | + u32 count, i; |
---|
| 5598 | + |
---|
| 5599 | + count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; |
---|
| 5600 | + |
---|
| 5601 | + /* Initialize IRQ poll */ |
---|
| 5602 | + for (i = 0; i < count; i++) { |
---|
| 5603 | + irq_ctx = &instance->irq_context[i]; |
---|
| 5604 | + irq_ctx->os_irq = pci_irq_vector(instance->pdev, i); |
---|
| 5605 | + irq_ctx->irq_poll_scheduled = false; |
---|
| 5606 | + irq_poll_init(&irq_ctx->irqpoll, |
---|
| 5607 | + instance->threshold_reply_count, |
---|
| 5608 | + megasas_irqpoll); |
---|
| 5609 | + } |
---|
5044 | 5610 | } |
---|
5045 | 5611 | |
---|
5046 | 5612 | /* |
---|
.. | .. |
---|
5059 | 5625 | pdev = instance->pdev; |
---|
5060 | 5626 | instance->irq_context[0].instance = instance; |
---|
5061 | 5627 | instance->irq_context[0].MSIxIndex = 0; |
---|
| 5628 | + snprintf(instance->irq_context->name, MEGASAS_MSIX_NAME_LEN, "%s%u", |
---|
| 5629 | + "megasas", instance->host->host_no); |
---|
5062 | 5630 | if (request_irq(pci_irq_vector(pdev, 0), |
---|
5063 | 5631 | instance->instancet->service_isr, IRQF_SHARED, |
---|
5064 | | - "megasas", &instance->irq_context[0])) { |
---|
| 5632 | + instance->irq_context->name, &instance->irq_context[0])) { |
---|
5065 | 5633 | dev_err(&instance->pdev->dev, |
---|
5066 | 5634 | "Failed to register IRQ from %s %d\n", |
---|
5067 | 5635 | __func__, __LINE__); |
---|
5068 | 5636 | return -1; |
---|
5069 | 5637 | } |
---|
| 5638 | + instance->perf_mode = MR_LATENCY_PERF_MODE; |
---|
| 5639 | + instance->low_latency_index_start = 0; |
---|
5070 | 5640 | return 0; |
---|
5071 | 5641 | } |
---|
5072 | 5642 | |
---|
.. | .. |
---|
5091 | 5661 | for (i = 0; i < instance->msix_vectors; i++) { |
---|
5092 | 5662 | instance->irq_context[i].instance = instance; |
---|
5093 | 5663 | instance->irq_context[i].MSIxIndex = i; |
---|
| 5664 | + snprintf(instance->irq_context[i].name, MEGASAS_MSIX_NAME_LEN, "%s%u-msix%u", |
---|
| 5665 | + "megasas", instance->host->host_no, i); |
---|
5094 | 5666 | if (request_irq(pci_irq_vector(pdev, i), |
---|
5095 | | - instance->instancet->service_isr, 0, "megasas", |
---|
| 5667 | + instance->instancet->service_isr, 0, instance->irq_context[i].name, |
---|
5096 | 5668 | &instance->irq_context[i])) { |
---|
5097 | 5669 | dev_err(&instance->pdev->dev, |
---|
5098 | 5670 | "Failed to register IRQ for vector %d.\n", i); |
---|
5099 | | - for (j = 0; j < i; j++) |
---|
| 5671 | + for (j = 0; j < i; j++) { |
---|
| 5672 | + if (j < instance->low_latency_index_start) |
---|
| 5673 | + irq_set_affinity_hint( |
---|
| 5674 | + pci_irq_vector(pdev, j), NULL); |
---|
5100 | 5675 | free_irq(pci_irq_vector(pdev, j), |
---|
5101 | 5676 | &instance->irq_context[j]); |
---|
| 5677 | + } |
---|
5102 | 5678 | /* Retry irq register for IO_APIC*/ |
---|
5103 | 5679 | instance->msix_vectors = 0; |
---|
| 5680 | + instance->msix_load_balance = false; |
---|
5104 | 5681 | if (is_probe) { |
---|
5105 | 5682 | pci_free_irq_vectors(instance->pdev); |
---|
5106 | 5683 | return megasas_setup_irqs_ioapic(instance); |
---|
.. | .. |
---|
5109 | 5686 | } |
---|
5110 | 5687 | } |
---|
5111 | 5688 | } |
---|
| 5689 | + |
---|
5112 | 5690 | return 0; |
---|
5113 | 5691 | } |
---|
5114 | 5692 | |
---|
.. | .. |
---|
5121 | 5699 | megasas_destroy_irqs(struct megasas_instance *instance) { |
---|
5122 | 5700 | |
---|
5123 | 5701 | int i; |
---|
| 5702 | + int count; |
---|
| 5703 | + struct megasas_irq_context *irq_ctx; |
---|
| 5704 | + |
---|
| 5705 | + count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; |
---|
| 5706 | + if (instance->adapter_type != MFI_SERIES) { |
---|
| 5707 | + for (i = 0; i < count; i++) { |
---|
| 5708 | + irq_ctx = &instance->irq_context[i]; |
---|
| 5709 | + irq_poll_disable(&irq_ctx->irqpoll); |
---|
| 5710 | + } |
---|
| 5711 | + } |
---|
5124 | 5712 | |
---|
5125 | 5713 | if (instance->msix_vectors) |
---|
5126 | 5714 | for (i = 0; i < instance->msix_vectors; i++) { |
---|
| 5715 | + if (i < instance->low_latency_index_start) |
---|
| 5716 | + irq_set_affinity_hint( |
---|
| 5717 | + pci_irq_vector(instance->pdev, i), NULL); |
---|
5127 | 5718 | free_irq(pci_irq_vector(instance->pdev, i), |
---|
5128 | 5719 | &instance->irq_context[i]); |
---|
5129 | 5720 | } |
---|
.. | .. |
---|
5135 | 5726 | /** |
---|
5136 | 5727 | * megasas_setup_jbod_map - setup jbod map for FP seq_number. |
---|
5137 | 5728 | * @instance: Adapter soft state |
---|
5138 | | - * @is_probe: Driver probe check |
---|
5139 | 5729 | * |
---|
5140 | 5730 | * Return 0 on success. |
---|
5141 | 5731 | */ |
---|
.. | .. |
---|
5149 | 5739 | pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) + |
---|
5150 | 5740 | (sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1)); |
---|
5151 | 5741 | |
---|
| 5742 | + instance->use_seqnum_jbod_fp = |
---|
| 5743 | + instance->support_seqnum_jbod_fp; |
---|
5152 | 5744 | if (reset_devices || !fusion || |
---|
5153 | | - !instance->ctrl_info_buf->adapterOperations3.useSeqNumJbodFP) { |
---|
| 5745 | + !instance->support_seqnum_jbod_fp) { |
---|
5154 | 5746 | dev_info(&instance->pdev->dev, |
---|
5155 | | - "Jbod map is not supported %s %d\n", |
---|
| 5747 | + "JBOD sequence map is disabled %s %d\n", |
---|
5156 | 5748 | __func__, __LINE__); |
---|
5157 | 5749 | instance->use_seqnum_jbod_fp = false; |
---|
5158 | 5750 | return; |
---|
.. | .. |
---|
5191 | 5783 | static void megasas_setup_reply_map(struct megasas_instance *instance) |
---|
5192 | 5784 | { |
---|
5193 | 5785 | const struct cpumask *mask; |
---|
5194 | | - unsigned int queue, cpu; |
---|
| 5786 | + unsigned int queue, cpu, low_latency_index_start; |
---|
5195 | 5787 | |
---|
5196 | | - for (queue = 0; queue < instance->msix_vectors; queue++) { |
---|
| 5788 | + low_latency_index_start = instance->low_latency_index_start; |
---|
| 5789 | + |
---|
| 5790 | + for (queue = low_latency_index_start; queue < instance->msix_vectors; queue++) { |
---|
5197 | 5791 | mask = pci_irq_get_affinity(instance->pdev, queue); |
---|
5198 | 5792 | if (!mask) |
---|
5199 | 5793 | goto fallback; |
---|
.. | .. |
---|
5204 | 5798 | return; |
---|
5205 | 5799 | |
---|
5206 | 5800 | fallback: |
---|
5207 | | - for_each_possible_cpu(cpu) |
---|
5208 | | - instance->reply_map[cpu] = cpu % instance->msix_vectors; |
---|
| 5801 | + queue = low_latency_index_start; |
---|
| 5802 | + for_each_possible_cpu(cpu) { |
---|
| 5803 | + instance->reply_map[cpu] = queue; |
---|
| 5804 | + if (queue == (instance->msix_vectors - 1)) |
---|
| 5805 | + queue = low_latency_index_start; |
---|
| 5806 | + else |
---|
| 5807 | + queue++; |
---|
| 5808 | + } |
---|
| 5809 | +} |
---|
| 5810 | + |
---|
| 5811 | +/** |
---|
| 5812 | + * megasas_get_device_list - Get the PD and LD device list from FW. |
---|
| 5813 | + * @instance: Adapter soft state |
---|
| 5814 | + * @return: Success or failure |
---|
| 5815 | + * |
---|
| 5816 | + * Issue DCMDs to Firmware to get the PD and LD list. |
---|
| 5817 | + * Based on the FW support, driver sends the HOST_DEVICE_LIST or combination |
---|
| 5818 | + * of PD_LIST/LD_LIST_QUERY DCMDs to get the device list. |
---|
| 5819 | + */ |
---|
| 5820 | +static |
---|
| 5821 | +int megasas_get_device_list(struct megasas_instance *instance) |
---|
| 5822 | +{ |
---|
| 5823 | + memset(instance->pd_list, 0, |
---|
| 5824 | + (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); |
---|
| 5825 | + memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); |
---|
| 5826 | + |
---|
| 5827 | + if (instance->enable_fw_dev_list) { |
---|
| 5828 | + if (megasas_host_device_list_query(instance, true)) |
---|
| 5829 | + return FAILED; |
---|
| 5830 | + } else { |
---|
| 5831 | + if (megasas_get_pd_list(instance) < 0) { |
---|
| 5832 | + dev_err(&instance->pdev->dev, "failed to get PD list\n"); |
---|
| 5833 | + return FAILED; |
---|
| 5834 | + } |
---|
| 5835 | + |
---|
| 5836 | + if (megasas_ld_list_query(instance, |
---|
| 5837 | + MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) { |
---|
| 5838 | + dev_err(&instance->pdev->dev, "failed to get LD list\n"); |
---|
| 5839 | + return FAILED; |
---|
| 5840 | + } |
---|
| 5841 | + } |
---|
| 5842 | + |
---|
| 5843 | + return SUCCESS; |
---|
| 5844 | +} |
---|
| 5845 | + |
---|
| 5846 | +/** |
---|
| 5847 | + * megasas_set_high_iops_queue_affinity_hint - Set affinity hint for high IOPS queues |
---|
| 5848 | + * @instance: Adapter soft state |
---|
| 5849 | + * return: void |
---|
| 5850 | + */ |
---|
| 5851 | +static inline void |
---|
| 5852 | +megasas_set_high_iops_queue_affinity_hint(struct megasas_instance *instance) |
---|
| 5853 | +{ |
---|
| 5854 | + int i; |
---|
| 5855 | + int local_numa_node; |
---|
| 5856 | + |
---|
| 5857 | + if (instance->perf_mode == MR_BALANCED_PERF_MODE) { |
---|
| 5858 | + local_numa_node = dev_to_node(&instance->pdev->dev); |
---|
| 5859 | + |
---|
| 5860 | + for (i = 0; i < instance->low_latency_index_start; i++) |
---|
| 5861 | + irq_set_affinity_hint(pci_irq_vector(instance->pdev, i), |
---|
| 5862 | + cpumask_of_node(local_numa_node)); |
---|
| 5863 | + } |
---|
| 5864 | +} |
---|
| 5865 | + |
---|
| 5866 | +static int |
---|
| 5867 | +__megasas_alloc_irq_vectors(struct megasas_instance *instance) |
---|
| 5868 | +{ |
---|
| 5869 | + int i, irq_flags; |
---|
| 5870 | + struct irq_affinity desc = { .pre_vectors = instance->low_latency_index_start }; |
---|
| 5871 | + struct irq_affinity *descp = &desc; |
---|
| 5872 | + |
---|
| 5873 | + irq_flags = PCI_IRQ_MSIX; |
---|
| 5874 | + |
---|
| 5875 | + if (instance->smp_affinity_enable) |
---|
| 5876 | + irq_flags |= PCI_IRQ_AFFINITY; |
---|
| 5877 | + else |
---|
| 5878 | + descp = NULL; |
---|
| 5879 | + |
---|
| 5880 | + i = pci_alloc_irq_vectors_affinity(instance->pdev, |
---|
| 5881 | + instance->low_latency_index_start, |
---|
| 5882 | + instance->msix_vectors, irq_flags, descp); |
---|
| 5883 | + |
---|
| 5884 | + return i; |
---|
| 5885 | +} |
---|
| 5886 | + |
---|
| 5887 | +/** |
---|
| 5888 | + * megasas_alloc_irq_vectors - Allocate IRQ vectors/enable MSI-x vectors |
---|
| 5889 | + * @instance: Adapter soft state |
---|
| 5890 | + * return: void |
---|
| 5891 | + */ |
---|
| 5892 | +static void |
---|
| 5893 | +megasas_alloc_irq_vectors(struct megasas_instance *instance) |
---|
| 5894 | +{ |
---|
| 5895 | + int i; |
---|
| 5896 | + unsigned int num_msix_req; |
---|
| 5897 | + |
---|
| 5898 | + i = __megasas_alloc_irq_vectors(instance); |
---|
| 5899 | + |
---|
| 5900 | + if ((instance->perf_mode == MR_BALANCED_PERF_MODE) && |
---|
| 5901 | + (i != instance->msix_vectors)) { |
---|
| 5902 | + if (instance->msix_vectors) |
---|
| 5903 | + pci_free_irq_vectors(instance->pdev); |
---|
| 5904 | + /* Disable Balanced IOPS mode and try realloc vectors */ |
---|
| 5905 | + instance->perf_mode = MR_LATENCY_PERF_MODE; |
---|
| 5906 | + instance->low_latency_index_start = 1; |
---|
| 5907 | + num_msix_req = num_online_cpus() + instance->low_latency_index_start; |
---|
| 5908 | + |
---|
| 5909 | + instance->msix_vectors = min(num_msix_req, |
---|
| 5910 | + instance->msix_vectors); |
---|
| 5911 | + |
---|
| 5912 | + i = __megasas_alloc_irq_vectors(instance); |
---|
| 5913 | + |
---|
| 5914 | + } |
---|
| 5915 | + |
---|
| 5916 | + dev_info(&instance->pdev->dev, |
---|
| 5917 | + "requested/available msix %d/%d\n", instance->msix_vectors, i); |
---|
| 5918 | + |
---|
| 5919 | + if (i > 0) |
---|
| 5920 | + instance->msix_vectors = i; |
---|
| 5921 | + else |
---|
| 5922 | + instance->msix_vectors = 0; |
---|
| 5923 | + |
---|
| 5924 | + if (instance->smp_affinity_enable) |
---|
| 5925 | + megasas_set_high_iops_queue_affinity_hint(instance); |
---|
5209 | 5926 | } |
---|
5210 | 5927 | |
---|
5211 | 5928 | /** |
---|
.. | .. |
---|
5219 | 5936 | { |
---|
5220 | 5937 | u32 max_sectors_1; |
---|
5221 | 5938 | u32 max_sectors_2, tmp_sectors, msix_enable; |
---|
5222 | | - u32 scratch_pad_2, scratch_pad_3, scratch_pad_4, status_reg; |
---|
| 5939 | + u32 scratch_pad_1, scratch_pad_2, scratch_pad_3, status_reg; |
---|
5223 | 5940 | resource_size_t base_addr; |
---|
5224 | | - struct megasas_register_set __iomem *reg_set; |
---|
| 5941 | + void *base_addr_phys; |
---|
5225 | 5942 | struct megasas_ctrl_info *ctrl_info = NULL; |
---|
5226 | 5943 | unsigned long bar_list; |
---|
5227 | | - int i, j, loop, fw_msix_count = 0; |
---|
| 5944 | + int i, j, loop; |
---|
5228 | 5945 | struct IOV_111 *iovPtr; |
---|
5229 | 5946 | struct fusion_context *fusion; |
---|
5230 | | - bool do_adp_reset = true; |
---|
| 5947 | + bool intr_coalescing; |
---|
| 5948 | + unsigned int num_msix_req; |
---|
| 5949 | + u16 lnksta, speed; |
---|
5231 | 5950 | |
---|
5232 | 5951 | fusion = instance->ctrl_context; |
---|
5233 | 5952 | |
---|
.. | .. |
---|
5241 | 5960 | } |
---|
5242 | 5961 | |
---|
5243 | 5962 | base_addr = pci_resource_start(instance->pdev, instance->bar); |
---|
5244 | | - instance->reg_set = ioremap_nocache(base_addr, 8192); |
---|
| 5963 | + instance->reg_set = ioremap(base_addr, 8192); |
---|
5245 | 5964 | |
---|
5246 | 5965 | if (!instance->reg_set) { |
---|
5247 | 5966 | dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to map IO mem\n"); |
---|
5248 | 5967 | goto fail_ioremap; |
---|
5249 | 5968 | } |
---|
5250 | 5969 | |
---|
5251 | | - reg_set = instance->reg_set; |
---|
| 5970 | + base_addr_phys = &base_addr; |
---|
| 5971 | + dev_printk(KERN_DEBUG, &instance->pdev->dev, |
---|
| 5972 | + "BAR:0x%lx BAR's base_addr(phys):%pa mapped virt_addr:0x%p\n", |
---|
| 5973 | + instance->bar, base_addr_phys, instance->reg_set); |
---|
5252 | 5974 | |
---|
5253 | 5975 | if (instance->adapter_type != MFI_SERIES) |
---|
5254 | 5976 | instance->instancet = &megasas_instance_template_fusion; |
---|
.. | .. |
---|
5276 | 5998 | } |
---|
5277 | 5999 | |
---|
5278 | 6000 | if (megasas_transition_to_ready(instance, 0)) { |
---|
5279 | | - if (instance->adapter_type >= INVADER_SERIES) { |
---|
| 6001 | + dev_info(&instance->pdev->dev, |
---|
| 6002 | + "Failed to transition controller to ready from %s!\n", |
---|
| 6003 | + __func__); |
---|
| 6004 | + if (instance->adapter_type != MFI_SERIES) { |
---|
5280 | 6005 | 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) { |
---|
| 6006 | + instance); |
---|
| 6007 | + if (status_reg & MFI_RESET_ADAPTER) { |
---|
| 6008 | + if (megasas_adp_reset_wait_for_ready |
---|
| 6009 | + (instance, true, 0) == FAILED) |
---|
| 6010 | + goto fail_ready_state; |
---|
| 6011 | + } else { |
---|
| 6012 | + goto fail_ready_state; |
---|
| 6013 | + } |
---|
| 6014 | + } else { |
---|
5286 | 6015 | atomic_set(&instance->fw_reset_no_pci_access, 1); |
---|
5287 | 6016 | instance->instancet->adp_reset |
---|
5288 | 6017 | (instance, instance->reg_set); |
---|
5289 | 6018 | 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 | 6019 | |
---|
5294 | 6020 | /*waiting for about 30 second before retry*/ |
---|
5295 | 6021 | ssleep(30); |
---|
5296 | 6022 | |
---|
5297 | 6023 | if (megasas_transition_to_ready(instance, 0)) |
---|
5298 | 6024 | goto fail_ready_state; |
---|
5299 | | - } else { |
---|
5300 | | - goto fail_ready_state; |
---|
5301 | 6025 | } |
---|
| 6026 | + |
---|
| 6027 | + dev_info(&instance->pdev->dev, |
---|
| 6028 | + "FW restarted successfully from %s!\n", |
---|
| 6029 | + __func__); |
---|
5302 | 6030 | } |
---|
5303 | 6031 | |
---|
5304 | 6032 | megasas_init_ctrl_params(instance); |
---|
.. | .. |
---|
5314 | 6042 | |
---|
5315 | 6043 | fusion = instance->ctrl_context; |
---|
5316 | 6044 | |
---|
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 >> |
---|
| 6045 | + if (instance->adapter_type >= VENTURA_SERIES) { |
---|
| 6046 | + scratch_pad_2 = |
---|
| 6047 | + megasas_readl(instance, |
---|
| 6048 | + &instance->reg_set->outbound_scratch_pad_2); |
---|
| 6049 | + instance->max_raid_mapsize = ((scratch_pad_2 >> |
---|
5321 | 6050 | MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) & |
---|
5322 | 6051 | MR_MAX_RAID_MAP_SIZE_MASK); |
---|
5323 | 6052 | } |
---|
5324 | 6053 | |
---|
| 6054 | + instance->enable_sdev_max_qd = enable_sdev_max_qd; |
---|
| 6055 | + |
---|
| 6056 | + switch (instance->adapter_type) { |
---|
| 6057 | + case VENTURA_SERIES: |
---|
| 6058 | + fusion->pcie_bw_limitation = true; |
---|
| 6059 | + break; |
---|
| 6060 | + case AERO_SERIES: |
---|
| 6061 | + fusion->r56_div_offload = true; |
---|
| 6062 | + break; |
---|
| 6063 | + default: |
---|
| 6064 | + break; |
---|
| 6065 | + } |
---|
| 6066 | + |
---|
5325 | 6067 | /* Check if MSI-X is supported while in ready state */ |
---|
5326 | | - msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & |
---|
| 6068 | + msix_enable = (instance->instancet->read_fw_status_reg(instance) & |
---|
5327 | 6069 | 0x4000000) >> 0x1a; |
---|
5328 | 6070 | if (msix_enable && !msix_disable) { |
---|
5329 | | - int irq_flags = PCI_IRQ_MSIX; |
---|
5330 | 6071 | |
---|
5331 | | - scratch_pad_2 = readl |
---|
5332 | | - (&instance->reg_set->outbound_scratch_pad_2); |
---|
| 6072 | + scratch_pad_1 = megasas_readl |
---|
| 6073 | + (instance, &instance->reg_set->outbound_scratch_pad_1); |
---|
5333 | 6074 | /* Check max MSI-X vectors */ |
---|
5334 | 6075 | if (fusion) { |
---|
5335 | 6076 | if (instance->adapter_type == THUNDERBOLT_SERIES) { |
---|
5336 | 6077 | /* Thunderbolt Series*/ |
---|
5337 | | - instance->msix_vectors = (scratch_pad_2 |
---|
| 6078 | + instance->msix_vectors = (scratch_pad_1 |
---|
5338 | 6079 | & MR_MAX_REPLY_QUEUES_OFFSET) + 1; |
---|
5339 | | - fw_msix_count = instance->msix_vectors; |
---|
5340 | 6080 | } else { |
---|
5341 | | - instance->msix_vectors = ((scratch_pad_2 |
---|
| 6081 | + instance->msix_vectors = ((scratch_pad_1 |
---|
5342 | 6082 | & MR_MAX_REPLY_QUEUES_EXT_OFFSET) |
---|
5343 | 6083 | >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1; |
---|
5344 | 6084 | |
---|
.. | .. |
---|
5355 | 6095 | if (instance->msix_vectors > 8) |
---|
5356 | 6096 | instance->msix_combined = true; |
---|
5357 | 6097 | break; |
---|
| 6098 | + case AERO_SERIES: |
---|
5358 | 6099 | case VENTURA_SERIES: |
---|
5359 | 6100 | if (instance->msix_vectors > 16) |
---|
5360 | 6101 | instance->msix_combined = true; |
---|
.. | .. |
---|
5362 | 6103 | } |
---|
5363 | 6104 | |
---|
5364 | 6105 | if (rdpq_enable) |
---|
5365 | | - instance->is_rdpq = (scratch_pad_2 & MR_RDPQ_MODE_OFFSET) ? |
---|
| 6106 | + instance->is_rdpq = (scratch_pad_1 & MR_RDPQ_MODE_OFFSET) ? |
---|
5366 | 6107 | 1 : 0; |
---|
5367 | | - fw_msix_count = instance->msix_vectors; |
---|
| 6108 | + |
---|
| 6109 | + if (instance->adapter_type >= INVADER_SERIES && |
---|
| 6110 | + !instance->msix_combined) { |
---|
| 6111 | + instance->msix_load_balance = true; |
---|
| 6112 | + instance->smp_affinity_enable = false; |
---|
| 6113 | + } |
---|
| 6114 | + |
---|
5368 | 6115 | /* Save 1-15 reply post index address to local memory |
---|
5369 | 6116 | * Index 0 is already saved from reg offset |
---|
5370 | 6117 | * MPI2_REPLY_POST_HOST_INDEX_OFFSET |
---|
.. | .. |
---|
5377 | 6124 | + (loop * 0x10)); |
---|
5378 | 6125 | } |
---|
5379 | 6126 | } |
---|
| 6127 | + |
---|
| 6128 | + dev_info(&instance->pdev->dev, |
---|
| 6129 | + "firmware supports msix\t: (%d)", |
---|
| 6130 | + instance->msix_vectors); |
---|
5380 | 6131 | if (msix_vectors) |
---|
5381 | 6132 | instance->msix_vectors = min(msix_vectors, |
---|
5382 | 6133 | instance->msix_vectors); |
---|
5383 | 6134 | } else /* MFI adapters */ |
---|
5384 | 6135 | 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; |
---|
| 6136 | + |
---|
| 6137 | + |
---|
| 6138 | + /* |
---|
| 6139 | + * For Aero (if some conditions are met), driver will configure a |
---|
| 6140 | + * few additional reply queues with interrupt coalescing enabled. |
---|
| 6141 | + * These queues with interrupt coalescing enabled are called |
---|
| 6142 | + * High IOPS queues and rest of reply queues (based on number of |
---|
| 6143 | + * logical CPUs) are termed as Low latency queues. |
---|
| 6144 | + * |
---|
| 6145 | + * Total Number of reply queues = High IOPS queues + low latency queues |
---|
| 6146 | + * |
---|
| 6147 | + * For rest of fusion adapters, 1 additional reply queue will be |
---|
| 6148 | + * reserved for management commands, rest of reply queues |
---|
| 6149 | + * (based on number of logical CPUs) will be used for IOs and |
---|
| 6150 | + * referenced as IO queues. |
---|
| 6151 | + * Total Number of reply queues = 1 + IO queues |
---|
| 6152 | + * |
---|
| 6153 | + * MFI adapters supports single MSI-x so single reply queue |
---|
| 6154 | + * will be used for IO and management commands. |
---|
| 6155 | + */ |
---|
| 6156 | + |
---|
| 6157 | + intr_coalescing = (scratch_pad_1 & MR_INTR_COALESCING_SUPPORT_OFFSET) ? |
---|
| 6158 | + true : false; |
---|
| 6159 | + if (intr_coalescing && |
---|
| 6160 | + (num_online_cpus() >= MR_HIGH_IOPS_QUEUE_COUNT) && |
---|
| 6161 | + (instance->msix_vectors == MEGASAS_MAX_MSIX_QUEUES)) |
---|
| 6162 | + instance->perf_mode = MR_BALANCED_PERF_MODE; |
---|
5394 | 6163 | else |
---|
5395 | | - instance->msix_vectors = 0; |
---|
| 6164 | + instance->perf_mode = MR_LATENCY_PERF_MODE; |
---|
| 6165 | + |
---|
| 6166 | + |
---|
| 6167 | + if (instance->adapter_type == AERO_SERIES) { |
---|
| 6168 | + pcie_capability_read_word(instance->pdev, PCI_EXP_LNKSTA, &lnksta); |
---|
| 6169 | + speed = lnksta & PCI_EXP_LNKSTA_CLS; |
---|
| 6170 | + |
---|
| 6171 | + /* |
---|
| 6172 | + * For Aero, if PCIe link speed is <16 GT/s, then driver should operate |
---|
| 6173 | + * in latency perf mode and enable R1 PCI bandwidth algorithm |
---|
| 6174 | + */ |
---|
| 6175 | + if (speed < 0x4) { |
---|
| 6176 | + instance->perf_mode = MR_LATENCY_PERF_MODE; |
---|
| 6177 | + fusion->pcie_bw_limitation = true; |
---|
| 6178 | + } |
---|
| 6179 | + |
---|
| 6180 | + /* |
---|
| 6181 | + * Performance mode settings provided through module parameter-perf_mode will |
---|
| 6182 | + * take affect only for: |
---|
| 6183 | + * 1. Aero family of adapters. |
---|
| 6184 | + * 2. When user sets module parameter- perf_mode in range of 0-2. |
---|
| 6185 | + */ |
---|
| 6186 | + if ((perf_mode >= MR_BALANCED_PERF_MODE) && |
---|
| 6187 | + (perf_mode <= MR_LATENCY_PERF_MODE)) |
---|
| 6188 | + instance->perf_mode = perf_mode; |
---|
| 6189 | + /* |
---|
| 6190 | + * If intr coalescing is not supported by controller FW, then IOPS |
---|
| 6191 | + * and Balanced modes are not feasible. |
---|
| 6192 | + */ |
---|
| 6193 | + if (!intr_coalescing) |
---|
| 6194 | + instance->perf_mode = MR_LATENCY_PERF_MODE; |
---|
| 6195 | + |
---|
| 6196 | + } |
---|
| 6197 | + |
---|
| 6198 | + if (instance->perf_mode == MR_BALANCED_PERF_MODE) |
---|
| 6199 | + instance->low_latency_index_start = |
---|
| 6200 | + MR_HIGH_IOPS_QUEUE_COUNT; |
---|
| 6201 | + else |
---|
| 6202 | + instance->low_latency_index_start = 1; |
---|
| 6203 | + |
---|
| 6204 | + num_msix_req = num_online_cpus() + instance->low_latency_index_start; |
---|
| 6205 | + |
---|
| 6206 | + instance->msix_vectors = min(num_msix_req, |
---|
| 6207 | + instance->msix_vectors); |
---|
| 6208 | + |
---|
| 6209 | + megasas_alloc_irq_vectors(instance); |
---|
| 6210 | + if (!instance->msix_vectors) |
---|
| 6211 | + instance->msix_load_balance = false; |
---|
5396 | 6212 | } |
---|
5397 | 6213 | /* |
---|
5398 | 6214 | * MSI-X host index 0 is common for all adapter. |
---|
.. | .. |
---|
5417 | 6233 | megasas_setup_reply_map(instance); |
---|
5418 | 6234 | |
---|
5419 | 6235 | dev_info(&instance->pdev->dev, |
---|
5420 | | - "firmware supports msix\t: (%d)", fw_msix_count); |
---|
5421 | | - dev_info(&instance->pdev->dev, |
---|
5422 | 6236 | "current msix/online cpus\t: (%d/%d)\n", |
---|
5423 | 6237 | instance->msix_vectors, (unsigned int)num_online_cpus()); |
---|
5424 | 6238 | dev_info(&instance->pdev->dev, |
---|
.. | .. |
---|
5437 | 6251 | if (instance->instancet->init_adapter(instance)) |
---|
5438 | 6252 | goto fail_init_adapter; |
---|
5439 | 6253 | |
---|
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) >= |
---|
| 6254 | + if (instance->adapter_type >= VENTURA_SERIES) { |
---|
| 6255 | + scratch_pad_3 = |
---|
| 6256 | + megasas_readl(instance, |
---|
| 6257 | + &instance->reg_set->outbound_scratch_pad_3); |
---|
| 6258 | + if ((scratch_pad_3 & MR_NVME_PAGE_SIZE_MASK) >= |
---|
5444 | 6259 | MR_DEFAULT_NVME_PAGE_SHIFT) |
---|
5445 | 6260 | instance->nvme_page_size = |
---|
5446 | | - (1 << (scratch_pad_4 & MR_NVME_PAGE_SIZE_MASK)); |
---|
| 6261 | + (1 << (scratch_pad_3 & MR_NVME_PAGE_SIZE_MASK)); |
---|
5447 | 6262 | |
---|
5448 | 6263 | dev_info(&instance->pdev->dev, |
---|
5449 | 6264 | "NVME page size\t: (%d)\n", instance->nvme_page_size); |
---|
.. | .. |
---|
5454 | 6269 | megasas_setup_irqs_ioapic(instance)) |
---|
5455 | 6270 | goto fail_init_adapter; |
---|
5456 | 6271 | |
---|
| 6272 | + if (instance->adapter_type != MFI_SERIES) |
---|
| 6273 | + megasas_setup_irq_poll(instance); |
---|
| 6274 | + |
---|
5457 | 6275 | instance->instancet->enable_intr(instance); |
---|
5458 | 6276 | |
---|
5459 | 6277 | dev_info(&instance->pdev->dev, "INIT adapter done\n"); |
---|
5460 | 6278 | |
---|
5461 | 6279 | megasas_setup_jbod_map(instance); |
---|
5462 | 6280 | |
---|
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"); |
---|
| 6281 | + if (megasas_get_device_list(instance) != SUCCESS) { |
---|
| 6282 | + dev_err(&instance->pdev->dev, |
---|
| 6283 | + "%s: megasas_get_device_list failed\n", |
---|
| 6284 | + __func__); |
---|
5470 | 6285 | goto fail_get_ld_pd_list; |
---|
5471 | 6286 | } |
---|
5472 | 6287 | |
---|
5473 | | - memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); |
---|
5474 | | - |
---|
5475 | 6288 | /* stream detection initialization */ |
---|
5476 | | - if (instance->adapter_type == VENTURA_SERIES) { |
---|
| 6289 | + if (instance->adapter_type >= VENTURA_SERIES) { |
---|
5477 | 6290 | fusion->stream_detect_by_ld = |
---|
5478 | 6291 | kcalloc(MAX_LOGICAL_DRIVES_EXT, |
---|
5479 | 6292 | sizeof(struct LD_STREAM_DETECT *), |
---|
.. | .. |
---|
5500 | 6313 | = MR_STREAM_BITMAP; |
---|
5501 | 6314 | } |
---|
5502 | 6315 | } |
---|
5503 | | - |
---|
5504 | | - if (megasas_ld_list_query(instance, |
---|
5505 | | - MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) |
---|
5506 | | - goto fail_get_ld_pd_list; |
---|
5507 | 6316 | |
---|
5508 | 6317 | /* |
---|
5509 | 6318 | * Compute the max allowed sectors per IO: The controller info has two |
---|
.. | .. |
---|
5566 | 6375 | |
---|
5567 | 6376 | else { |
---|
5568 | 6377 | if (instance->crash_dump_buf) |
---|
5569 | | - pci_free_consistent(instance->pdev, |
---|
| 6378 | + dma_free_coherent(&instance->pdev->dev, |
---|
5570 | 6379 | CRASH_DMA_BUF_SIZE, |
---|
5571 | 6380 | instance->crash_dump_buf, |
---|
5572 | 6381 | instance->crash_dump_h); |
---|
5573 | 6382 | instance->crash_dump_buf = NULL; |
---|
5574 | 6383 | } |
---|
5575 | 6384 | |
---|
| 6385 | + if (instance->snapdump_wait_time) { |
---|
| 6386 | + megasas_get_snapdump_properties(instance); |
---|
| 6387 | + dev_info(&instance->pdev->dev, "Snap dump wait time\t: %d\n", |
---|
| 6388 | + instance->snapdump_wait_time); |
---|
| 6389 | + } |
---|
5576 | 6390 | |
---|
5577 | 6391 | dev_info(&instance->pdev->dev, |
---|
5578 | 6392 | "pci id\t\t: (0x%04x)/(0x%04x)/(0x%04x)/(0x%04x)\n", |
---|
.. | .. |
---|
5584 | 6398 | instance->UnevenSpanSupport ? "yes" : "no"); |
---|
5585 | 6399 | dev_info(&instance->pdev->dev, "firmware crash dump : %s\n", |
---|
5586 | 6400 | 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 | | - |
---|
| 6401 | + dev_info(&instance->pdev->dev, "JBOD sequence map : %s\n", |
---|
| 6402 | + instance->use_seqnum_jbod_fp ? "enabled" : "disabled"); |
---|
5590 | 6403 | |
---|
5591 | 6404 | instance->max_sectors_per_req = instance->max_num_sge * |
---|
5592 | 6405 | SGE_BUFFER_SIZE / 512; |
---|
.. | .. |
---|
5610 | 6423 | |
---|
5611 | 6424 | /* Launch SR-IOV heartbeat timer */ |
---|
5612 | 6425 | if (instance->requestorId) { |
---|
5613 | | - if (!megasas_sriov_start_heartbeat(instance, 1)) |
---|
| 6426 | + if (!megasas_sriov_start_heartbeat(instance, 1)) { |
---|
5614 | 6427 | megasas_start_timer(instance); |
---|
5615 | | - else |
---|
| 6428 | + } else { |
---|
5616 | 6429 | instance->skip_heartbeat_timer_del = 1; |
---|
| 6430 | + goto fail_get_ld_pd_list; |
---|
| 6431 | + } |
---|
5617 | 6432 | } |
---|
| 6433 | + |
---|
| 6434 | + /* |
---|
| 6435 | + * Create and start watchdog thread which will monitor |
---|
| 6436 | + * controller state every 1 sec and trigger OCR when |
---|
| 6437 | + * it enters fault state |
---|
| 6438 | + */ |
---|
| 6439 | + if (instance->adapter_type != MFI_SERIES) |
---|
| 6440 | + if (megasas_fusion_start_watchdog(instance) != SUCCESS) |
---|
| 6441 | + goto fail_start_watchdog; |
---|
5618 | 6442 | |
---|
5619 | 6443 | return 0; |
---|
5620 | 6444 | |
---|
| 6445 | +fail_start_watchdog: |
---|
| 6446 | + if (instance->requestorId && !instance->skip_heartbeat_timer_del) |
---|
| 6447 | + del_timer_sync(&instance->sriov_heartbeat_timer); |
---|
5621 | 6448 | fail_get_ld_pd_list: |
---|
5622 | 6449 | instance->instancet->disable_intr(instance); |
---|
5623 | 6450 | megasas_destroy_irqs(instance); |
---|
.. | .. |
---|
5648 | 6475 | u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1); |
---|
5649 | 6476 | |
---|
5650 | 6477 | if (instance->reply_queue) |
---|
5651 | | - pci_free_consistent(instance->pdev, reply_q_sz, |
---|
| 6478 | + dma_free_coherent(&instance->pdev->dev, reply_q_sz, |
---|
5652 | 6479 | instance->reply_queue, instance->reply_queue_h); |
---|
5653 | 6480 | |
---|
5654 | 6481 | megasas_free_cmds(instance); |
---|
.. | .. |
---|
5687 | 6514 | } |
---|
5688 | 6515 | |
---|
5689 | 6516 | dcmd = &cmd->frame->dcmd; |
---|
5690 | | - el_info = pci_zalloc_consistent(instance->pdev, |
---|
5691 | | - sizeof(struct megasas_evt_log_info), |
---|
5692 | | - &el_info_h); |
---|
5693 | | - |
---|
| 6517 | + el_info = dma_alloc_coherent(&instance->pdev->dev, |
---|
| 6518 | + sizeof(struct megasas_evt_log_info), |
---|
| 6519 | + &el_info_h, GFP_KERNEL); |
---|
5694 | 6520 | if (!el_info) { |
---|
5695 | 6521 | megasas_return_cmd(instance, cmd); |
---|
5696 | 6522 | return -ENOMEM; |
---|
.. | .. |
---|
5727 | 6553 | eli->boot_seq_num = el_info->boot_seq_num; |
---|
5728 | 6554 | |
---|
5729 | 6555 | dcmd_failed: |
---|
5730 | | - pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info), |
---|
5731 | | - el_info, el_info_h); |
---|
| 6556 | + dma_free_coherent(&instance->pdev->dev, |
---|
| 6557 | + sizeof(struct megasas_evt_log_info), |
---|
| 6558 | + el_info, el_info_h); |
---|
5732 | 6559 | |
---|
5733 | 6560 | megasas_return_cmd(instance, cmd); |
---|
5734 | 6561 | |
---|
.. | .. |
---|
5739 | 6566 | * megasas_register_aen - Registers for asynchronous event notification |
---|
5740 | 6567 | * @instance: Adapter soft state |
---|
5741 | 6568 | * @seq_num: The starting sequence number |
---|
5742 | | - * @class_locale: Class of the event |
---|
| 6569 | + * @class_locale_word: Class of the event |
---|
5743 | 6570 | * |
---|
5744 | 6571 | * This function subscribes for AEN for events beyond the @seq_num. It requests |
---|
5745 | 6572 | * to be notified if and only if the event is of type @class_locale |
---|
.. | .. |
---|
5936 | 6763 | switch (dcmd_timeout_ocr_possible(instance)) { |
---|
5937 | 6764 | case INITIATE_OCR: |
---|
5938 | 6765 | cmd->flags |= DRV_DCMD_SKIP_REFIRE; |
---|
| 6766 | + mutex_unlock(&instance->reset_mutex); |
---|
5939 | 6767 | megasas_reset_fusion(instance->host, |
---|
5940 | 6768 | MFI_IO_TIMEOUT_OCR); |
---|
| 6769 | + mutex_lock(&instance->reset_mutex); |
---|
5941 | 6770 | break; |
---|
5942 | 6771 | case KILL_ADAPTER: |
---|
5943 | 6772 | megaraid_sas_kill_hba(instance); |
---|
.. | .. |
---|
6072 | 6901 | { |
---|
6073 | 6902 | u64 consistent_mask; |
---|
6074 | 6903 | struct pci_dev *pdev; |
---|
6075 | | - u32 scratch_pad_2; |
---|
| 6904 | + u32 scratch_pad_1; |
---|
6076 | 6905 | |
---|
6077 | 6906 | pdev = instance->pdev; |
---|
6078 | 6907 | consistent_mask = (instance->adapter_type >= VENTURA_SERIES) ? |
---|
.. | .. |
---|
6090 | 6919 | * If 32 bit DMA mask fails, then try for 64 bit mask |
---|
6091 | 6920 | * for FW capable of handling 64 bit DMA. |
---|
6092 | 6921 | */ |
---|
6093 | | - scratch_pad_2 = readl |
---|
6094 | | - (&instance->reg_set->outbound_scratch_pad_2); |
---|
| 6922 | + scratch_pad_1 = megasas_readl |
---|
| 6923 | + (instance, &instance->reg_set->outbound_scratch_pad_1); |
---|
6095 | 6924 | |
---|
6096 | | - if (!(scratch_pad_2 & MR_CAN_HANDLE_64_BIT_DMA_OFFSET)) |
---|
| 6925 | + if (!(scratch_pad_1 & MR_CAN_HANDLE_64_BIT_DMA_OFFSET)) |
---|
6097 | 6926 | goto fail_set_dma_mask; |
---|
6098 | 6927 | else if (dma_set_mask_and_coherent(&pdev->dev, |
---|
6099 | 6928 | DMA_BIT_MASK(63))) |
---|
.. | .. |
---|
6108 | 6937 | instance->consistent_mask_64bit = true; |
---|
6109 | 6938 | |
---|
6110 | 6939 | 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"), |
---|
| 6940 | + ((*pdev->dev.dma_mask == DMA_BIT_MASK(63)) ? "63" : "32"), |
---|
6112 | 6941 | (instance->consistent_mask_64bit ? "63" : "32")); |
---|
6113 | 6942 | |
---|
6114 | 6943 | return 0; |
---|
.. | .. |
---|
6122 | 6951 | /* |
---|
6123 | 6952 | * megasas_set_adapter_type - Set adapter type. |
---|
6124 | 6953 | * 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 | | - * }; |
---|
| 6954 | + * different categories- |
---|
| 6955 | + * enum MR_ADAPTER_TYPE { |
---|
| 6956 | + * MFI_SERIES = 1, |
---|
| 6957 | + * THUNDERBOLT_SERIES = 2, |
---|
| 6958 | + * INVADER_SERIES = 3, |
---|
| 6959 | + * VENTURA_SERIES = 4, |
---|
| 6960 | + * AERO_SERIES = 5, |
---|
| 6961 | + * }; |
---|
6131 | 6962 | * @instance: Adapter soft state |
---|
6132 | 6963 | * return: void |
---|
6133 | 6964 | */ |
---|
.. | .. |
---|
6138 | 6969 | instance->adapter_type = MFI_SERIES; |
---|
6139 | 6970 | } else { |
---|
6140 | 6971 | switch (instance->pdev->device) { |
---|
| 6972 | + case PCI_DEVICE_ID_LSI_AERO_10E1: |
---|
| 6973 | + case PCI_DEVICE_ID_LSI_AERO_10E2: |
---|
| 6974 | + case PCI_DEVICE_ID_LSI_AERO_10E5: |
---|
| 6975 | + case PCI_DEVICE_ID_LSI_AERO_10E6: |
---|
| 6976 | + instance->adapter_type = AERO_SERIES; |
---|
| 6977 | + break; |
---|
6141 | 6978 | case PCI_DEVICE_ID_LSI_VENTURA: |
---|
6142 | 6979 | case PCI_DEVICE_ID_LSI_CRUSADER: |
---|
6143 | 6980 | case PCI_DEVICE_ID_LSI_HARPOON: |
---|
.. | .. |
---|
6167 | 7004 | |
---|
6168 | 7005 | static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance) |
---|
6169 | 7006 | { |
---|
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); |
---|
| 7007 | + instance->producer = dma_alloc_coherent(&instance->pdev->dev, |
---|
| 7008 | + sizeof(u32), &instance->producer_h, GFP_KERNEL); |
---|
| 7009 | + instance->consumer = dma_alloc_coherent(&instance->pdev->dev, |
---|
| 7010 | + sizeof(u32), &instance->consumer_h, GFP_KERNEL); |
---|
6174 | 7011 | |
---|
6175 | 7012 | if (!instance->producer || !instance->consumer) { |
---|
6176 | 7013 | dev_err(&instance->pdev->dev, |
---|
.. | .. |
---|
6205 | 7042 | if (megasas_alloc_mfi_ctrl_mem(instance)) |
---|
6206 | 7043 | goto fail; |
---|
6207 | 7044 | break; |
---|
| 7045 | + case AERO_SERIES: |
---|
6208 | 7046 | case VENTURA_SERIES: |
---|
6209 | 7047 | case THUNDERBOLT_SERIES: |
---|
6210 | 7048 | case INVADER_SERIES: |
---|
.. | .. |
---|
6232 | 7070 | kfree(instance->reply_map); |
---|
6233 | 7071 | if (instance->adapter_type == MFI_SERIES) { |
---|
6234 | 7072 | if (instance->producer) |
---|
6235 | | - pci_free_consistent(instance->pdev, sizeof(u32), |
---|
| 7073 | + dma_free_coherent(&instance->pdev->dev, sizeof(u32), |
---|
6236 | 7074 | instance->producer, |
---|
6237 | 7075 | instance->producer_h); |
---|
6238 | 7076 | if (instance->consumer) |
---|
6239 | | - pci_free_consistent(instance->pdev, sizeof(u32), |
---|
| 7077 | + dma_free_coherent(&instance->pdev->dev, sizeof(u32), |
---|
6240 | 7078 | instance->consumer, |
---|
6241 | 7079 | instance->consumer_h); |
---|
6242 | 7080 | } else { |
---|
.. | .. |
---|
6248 | 7086 | * megasas_alloc_ctrl_dma_buffers - Allocate consistent DMA buffers during |
---|
6249 | 7087 | * driver load time |
---|
6250 | 7088 | * |
---|
6251 | | - * @instance- Adapter soft instance |
---|
6252 | | - * @return- O for SUCCESS |
---|
| 7089 | + * @instance: Adapter soft instance |
---|
| 7090 | + * |
---|
| 7091 | + * @return: O for SUCCESS |
---|
6253 | 7092 | */ |
---|
6254 | 7093 | static inline |
---|
6255 | 7094 | int megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance) |
---|
.. | .. |
---|
6257 | 7096 | struct pci_dev *pdev = instance->pdev; |
---|
6258 | 7097 | struct fusion_context *fusion = instance->ctrl_context; |
---|
6259 | 7098 | |
---|
6260 | | - instance->evt_detail = |
---|
6261 | | - pci_alloc_consistent(pdev, |
---|
6262 | | - sizeof(struct megasas_evt_detail), |
---|
6263 | | - &instance->evt_detail_h); |
---|
| 7099 | + instance->evt_detail = dma_alloc_coherent(&pdev->dev, |
---|
| 7100 | + sizeof(struct megasas_evt_detail), |
---|
| 7101 | + &instance->evt_detail_h, GFP_KERNEL); |
---|
6264 | 7102 | |
---|
6265 | 7103 | if (!instance->evt_detail) { |
---|
6266 | 7104 | dev_err(&instance->pdev->dev, |
---|
.. | .. |
---|
6280 | 7118 | "Failed to allocate PD list buffer\n"); |
---|
6281 | 7119 | return -ENOMEM; |
---|
6282 | 7120 | } |
---|
| 7121 | + |
---|
| 7122 | + instance->snapdump_prop = dma_alloc_coherent(&pdev->dev, |
---|
| 7123 | + sizeof(struct MR_SNAPDUMP_PROPERTIES), |
---|
| 7124 | + &instance->snapdump_prop_h, GFP_KERNEL); |
---|
| 7125 | + |
---|
| 7126 | + if (!instance->snapdump_prop) |
---|
| 7127 | + dev_err(&pdev->dev, |
---|
| 7128 | + "Failed to allocate snapdump properties buffer\n"); |
---|
| 7129 | + |
---|
| 7130 | + instance->host_device_list_buf = dma_alloc_coherent(&pdev->dev, |
---|
| 7131 | + HOST_DEVICE_LIST_SZ, |
---|
| 7132 | + &instance->host_device_list_buf_h, |
---|
| 7133 | + GFP_KERNEL); |
---|
| 7134 | + |
---|
| 7135 | + if (!instance->host_device_list_buf) { |
---|
| 7136 | + dev_err(&pdev->dev, |
---|
| 7137 | + "Failed to allocate targetid list buffer\n"); |
---|
| 7138 | + return -ENOMEM; |
---|
| 7139 | + } |
---|
| 7140 | + |
---|
6283 | 7141 | } |
---|
6284 | 7142 | |
---|
6285 | 7143 | instance->pd_list_buf = |
---|
6286 | | - pci_alloc_consistent(pdev, |
---|
| 7144 | + dma_alloc_coherent(&pdev->dev, |
---|
6287 | 7145 | MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), |
---|
6288 | | - &instance->pd_list_buf_h); |
---|
| 7146 | + &instance->pd_list_buf_h, GFP_KERNEL); |
---|
6289 | 7147 | |
---|
6290 | 7148 | if (!instance->pd_list_buf) { |
---|
6291 | 7149 | dev_err(&pdev->dev, "Failed to allocate PD list buffer\n"); |
---|
.. | .. |
---|
6293 | 7151 | } |
---|
6294 | 7152 | |
---|
6295 | 7153 | instance->ctrl_info_buf = |
---|
6296 | | - pci_alloc_consistent(pdev, |
---|
| 7154 | + dma_alloc_coherent(&pdev->dev, |
---|
6297 | 7155 | sizeof(struct megasas_ctrl_info), |
---|
6298 | | - &instance->ctrl_info_buf_h); |
---|
| 7156 | + &instance->ctrl_info_buf_h, GFP_KERNEL); |
---|
6299 | 7157 | |
---|
6300 | 7158 | if (!instance->ctrl_info_buf) { |
---|
6301 | 7159 | dev_err(&pdev->dev, |
---|
.. | .. |
---|
6304 | 7162 | } |
---|
6305 | 7163 | |
---|
6306 | 7164 | instance->ld_list_buf = |
---|
6307 | | - pci_alloc_consistent(pdev, |
---|
| 7165 | + dma_alloc_coherent(&pdev->dev, |
---|
6308 | 7166 | sizeof(struct MR_LD_LIST), |
---|
6309 | | - &instance->ld_list_buf_h); |
---|
| 7167 | + &instance->ld_list_buf_h, GFP_KERNEL); |
---|
6310 | 7168 | |
---|
6311 | 7169 | if (!instance->ld_list_buf) { |
---|
6312 | 7170 | dev_err(&pdev->dev, "Failed to allocate LD list buffer\n"); |
---|
.. | .. |
---|
6314 | 7172 | } |
---|
6315 | 7173 | |
---|
6316 | 7174 | instance->ld_targetid_list_buf = |
---|
6317 | | - pci_alloc_consistent(pdev, |
---|
6318 | | - sizeof(struct MR_LD_TARGETID_LIST), |
---|
6319 | | - &instance->ld_targetid_list_buf_h); |
---|
| 7175 | + dma_alloc_coherent(&pdev->dev, |
---|
| 7176 | + sizeof(struct MR_LD_TARGETID_LIST), |
---|
| 7177 | + &instance->ld_targetid_list_buf_h, GFP_KERNEL); |
---|
6320 | 7178 | |
---|
6321 | 7179 | if (!instance->ld_targetid_list_buf) { |
---|
6322 | 7180 | dev_err(&pdev->dev, |
---|
.. | .. |
---|
6326 | 7184 | |
---|
6327 | 7185 | if (!reset_devices) { |
---|
6328 | 7186 | instance->system_info_buf = |
---|
6329 | | - pci_alloc_consistent(pdev, |
---|
6330 | | - sizeof(struct MR_DRV_SYSTEM_INFO), |
---|
6331 | | - &instance->system_info_h); |
---|
| 7187 | + dma_alloc_coherent(&pdev->dev, |
---|
| 7188 | + sizeof(struct MR_DRV_SYSTEM_INFO), |
---|
| 7189 | + &instance->system_info_h, GFP_KERNEL); |
---|
6332 | 7190 | instance->pd_info = |
---|
6333 | | - pci_alloc_consistent(pdev, |
---|
6334 | | - sizeof(struct MR_PD_INFO), |
---|
6335 | | - &instance->pd_info_h); |
---|
| 7191 | + dma_alloc_coherent(&pdev->dev, |
---|
| 7192 | + sizeof(struct MR_PD_INFO), |
---|
| 7193 | + &instance->pd_info_h, GFP_KERNEL); |
---|
6336 | 7194 | instance->tgt_prop = |
---|
6337 | | - pci_alloc_consistent(pdev, |
---|
6338 | | - sizeof(struct MR_TARGET_PROPERTIES), |
---|
6339 | | - &instance->tgt_prop_h); |
---|
| 7195 | + dma_alloc_coherent(&pdev->dev, |
---|
| 7196 | + sizeof(struct MR_TARGET_PROPERTIES), |
---|
| 7197 | + &instance->tgt_prop_h, GFP_KERNEL); |
---|
6340 | 7198 | instance->crash_dump_buf = |
---|
6341 | | - pci_alloc_consistent(pdev, |
---|
6342 | | - CRASH_DMA_BUF_SIZE, |
---|
6343 | | - &instance->crash_dump_h); |
---|
| 7199 | + dma_alloc_coherent(&pdev->dev, CRASH_DMA_BUF_SIZE, |
---|
| 7200 | + &instance->crash_dump_h, GFP_KERNEL); |
---|
6344 | 7201 | |
---|
6345 | 7202 | if (!instance->system_info_buf) |
---|
6346 | 7203 | dev_err(&instance->pdev->dev, |
---|
.. | .. |
---|
6376 | 7233 | struct fusion_context *fusion = instance->ctrl_context; |
---|
6377 | 7234 | |
---|
6378 | 7235 | if (instance->evt_detail) |
---|
6379 | | - pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), |
---|
| 7236 | + dma_free_coherent(&pdev->dev, sizeof(struct megasas_evt_detail), |
---|
6380 | 7237 | instance->evt_detail, |
---|
6381 | 7238 | instance->evt_detail_h); |
---|
6382 | 7239 | |
---|
.. | .. |
---|
6387 | 7244 | fusion->ioc_init_request_phys); |
---|
6388 | 7245 | |
---|
6389 | 7246 | if (instance->pd_list_buf) |
---|
6390 | | - pci_free_consistent(pdev, |
---|
| 7247 | + dma_free_coherent(&pdev->dev, |
---|
6391 | 7248 | MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), |
---|
6392 | 7249 | instance->pd_list_buf, |
---|
6393 | 7250 | instance->pd_list_buf_h); |
---|
6394 | 7251 | |
---|
6395 | 7252 | if (instance->ld_list_buf) |
---|
6396 | | - pci_free_consistent(pdev, sizeof(struct MR_LD_LIST), |
---|
| 7253 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_LD_LIST), |
---|
6397 | 7254 | instance->ld_list_buf, |
---|
6398 | 7255 | instance->ld_list_buf_h); |
---|
6399 | 7256 | |
---|
6400 | 7257 | if (instance->ld_targetid_list_buf) |
---|
6401 | | - pci_free_consistent(pdev, sizeof(struct MR_LD_TARGETID_LIST), |
---|
| 7258 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_LD_TARGETID_LIST), |
---|
6402 | 7259 | instance->ld_targetid_list_buf, |
---|
6403 | 7260 | instance->ld_targetid_list_buf_h); |
---|
6404 | 7261 | |
---|
6405 | 7262 | if (instance->ctrl_info_buf) |
---|
6406 | | - pci_free_consistent(pdev, sizeof(struct megasas_ctrl_info), |
---|
| 7263 | + dma_free_coherent(&pdev->dev, sizeof(struct megasas_ctrl_info), |
---|
6407 | 7264 | instance->ctrl_info_buf, |
---|
6408 | 7265 | instance->ctrl_info_buf_h); |
---|
6409 | 7266 | |
---|
6410 | 7267 | if (instance->system_info_buf) |
---|
6411 | | - pci_free_consistent(pdev, sizeof(struct MR_DRV_SYSTEM_INFO), |
---|
| 7268 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_DRV_SYSTEM_INFO), |
---|
6412 | 7269 | instance->system_info_buf, |
---|
6413 | 7270 | instance->system_info_h); |
---|
6414 | 7271 | |
---|
6415 | 7272 | if (instance->pd_info) |
---|
6416 | | - pci_free_consistent(pdev, sizeof(struct MR_PD_INFO), |
---|
| 7273 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_PD_INFO), |
---|
6417 | 7274 | instance->pd_info, instance->pd_info_h); |
---|
6418 | 7275 | |
---|
6419 | 7276 | if (instance->tgt_prop) |
---|
6420 | | - pci_free_consistent(pdev, sizeof(struct MR_TARGET_PROPERTIES), |
---|
| 7277 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_TARGET_PROPERTIES), |
---|
6421 | 7278 | instance->tgt_prop, instance->tgt_prop_h); |
---|
6422 | 7279 | |
---|
6423 | 7280 | if (instance->crash_dump_buf) |
---|
6424 | | - pci_free_consistent(pdev, CRASH_DMA_BUF_SIZE, |
---|
| 7281 | + dma_free_coherent(&pdev->dev, CRASH_DMA_BUF_SIZE, |
---|
6425 | 7282 | instance->crash_dump_buf, |
---|
6426 | 7283 | instance->crash_dump_h); |
---|
| 7284 | + |
---|
| 7285 | + if (instance->snapdump_prop) |
---|
| 7286 | + dma_free_coherent(&pdev->dev, |
---|
| 7287 | + sizeof(struct MR_SNAPDUMP_PROPERTIES), |
---|
| 7288 | + instance->snapdump_prop, |
---|
| 7289 | + instance->snapdump_prop_h); |
---|
| 7290 | + |
---|
| 7291 | + if (instance->host_device_list_buf) |
---|
| 7292 | + dma_free_coherent(&pdev->dev, |
---|
| 7293 | + HOST_DEVICE_LIST_SZ, |
---|
| 7294 | + instance->host_device_list_buf, |
---|
| 7295 | + instance->host_device_list_buf_h); |
---|
| 7296 | + |
---|
6427 | 7297 | } |
---|
6428 | 7298 | |
---|
6429 | 7299 | /* |
---|
.. | .. |
---|
6447 | 7317 | INIT_LIST_HEAD(&instance->internal_reset_pending_q); |
---|
6448 | 7318 | |
---|
6449 | 7319 | atomic_set(&instance->fw_outstanding, 0); |
---|
| 7320 | + atomic64_set(&instance->total_io_count, 0); |
---|
6450 | 7321 | |
---|
6451 | 7322 | init_waitqueue_head(&instance->int_cmd_wait_q); |
---|
6452 | 7323 | init_waitqueue_head(&instance->abort_cmd_wait_q); |
---|
6453 | 7324 | |
---|
6454 | | - spin_lock_init(&instance->crashdump_lock); |
---|
| 7325 | + mutex_init(&instance->crashdump_lock); |
---|
6455 | 7326 | spin_lock_init(&instance->mfi_pool_lock); |
---|
6456 | 7327 | spin_lock_init(&instance->hba_lock); |
---|
6457 | 7328 | spin_lock_init(&instance->stream_lock); |
---|
.. | .. |
---|
6469 | 7340 | instance->last_time = 0; |
---|
6470 | 7341 | instance->disableOnlineCtrlReset = 1; |
---|
6471 | 7342 | instance->UnevenSpanSupport = 0; |
---|
| 7343 | + instance->smp_affinity_enable = smp_affinity_enable ? true : false; |
---|
| 7344 | + instance->msix_load_balance = false; |
---|
6472 | 7345 | |
---|
6473 | | - if (instance->adapter_type != MFI_SERIES) { |
---|
| 7346 | + if (instance->adapter_type != MFI_SERIES) |
---|
6474 | 7347 | INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq); |
---|
6475 | | - INIT_WORK(&instance->crash_init, megasas_fusion_crash_dump_wq); |
---|
6476 | | - } else { |
---|
| 7348 | + else |
---|
6477 | 7349 | INIT_WORK(&instance->work_init, process_fw_state_change_wq); |
---|
6478 | | - } |
---|
6479 | 7350 | } |
---|
6480 | 7351 | |
---|
6481 | 7352 | /** |
---|
.. | .. |
---|
6490 | 7361 | struct Scsi_Host *host; |
---|
6491 | 7362 | struct megasas_instance *instance; |
---|
6492 | 7363 | u16 control = 0; |
---|
| 7364 | + |
---|
| 7365 | + switch (pdev->device) { |
---|
| 7366 | + case PCI_DEVICE_ID_LSI_AERO_10E0: |
---|
| 7367 | + case PCI_DEVICE_ID_LSI_AERO_10E3: |
---|
| 7368 | + case PCI_DEVICE_ID_LSI_AERO_10E4: |
---|
| 7369 | + case PCI_DEVICE_ID_LSI_AERO_10E7: |
---|
| 7370 | + dev_err(&pdev->dev, "Adapter is in non secure mode\n"); |
---|
| 7371 | + return 1; |
---|
| 7372 | + case PCI_DEVICE_ID_LSI_AERO_10E1: |
---|
| 7373 | + case PCI_DEVICE_ID_LSI_AERO_10E5: |
---|
| 7374 | + dev_info(&pdev->dev, "Adapter is in configurable secure mode\n"); |
---|
| 7375 | + break; |
---|
| 7376 | + } |
---|
6493 | 7377 | |
---|
6494 | 7378 | /* Reset MSI-X in the kdump kernel */ |
---|
6495 | 7379 | if (reset_devices) { |
---|
.. | .. |
---|
6549 | 7433 | if (instance->requestorId) { |
---|
6550 | 7434 | if (instance->PlasmaFW111) { |
---|
6551 | 7435 | instance->vf_affiliation_111 = |
---|
6552 | | - pci_alloc_consistent(pdev, sizeof(struct MR_LD_VF_AFFILIATION_111), |
---|
6553 | | - &instance->vf_affiliation_111_h); |
---|
| 7436 | + dma_alloc_coherent(&pdev->dev, |
---|
| 7437 | + sizeof(struct MR_LD_VF_AFFILIATION_111), |
---|
| 7438 | + &instance->vf_affiliation_111_h, |
---|
| 7439 | + GFP_KERNEL); |
---|
6554 | 7440 | if (!instance->vf_affiliation_111) |
---|
6555 | 7441 | dev_warn(&pdev->dev, "Can't allocate " |
---|
6556 | 7442 | "memory for VF affiliation buffer\n"); |
---|
6557 | 7443 | } else { |
---|
6558 | 7444 | 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); |
---|
| 7445 | + dma_alloc_coherent(&pdev->dev, |
---|
| 7446 | + (MAX_LOGICAL_DRIVES + 1) * |
---|
| 7447 | + sizeof(struct MR_LD_VF_AFFILIATION), |
---|
| 7448 | + &instance->vf_affiliation_h, |
---|
| 7449 | + GFP_KERNEL); |
---|
6563 | 7450 | if (!instance->vf_affiliation) |
---|
6564 | 7451 | dev_warn(&pdev->dev, "Can't allocate " |
---|
6565 | 7452 | "memory for VF affiliation buffer\n"); |
---|
.. | .. |
---|
6589 | 7476 | /* |
---|
6590 | 7477 | * Trigger SCSI to scan our drives |
---|
6591 | 7478 | */ |
---|
6592 | | - scsi_scan_host(host); |
---|
| 7479 | + if (!instance->enable_fw_dev_list || |
---|
| 7480 | + (instance->host_device_list_buf->count > 0)) |
---|
| 7481 | + scsi_scan_host(host); |
---|
6593 | 7482 | |
---|
6594 | 7483 | /* |
---|
6595 | 7484 | * Initiate AEN (Asynchronous Event Notification) |
---|
.. | .. |
---|
6599 | 7488 | goto fail_start_aen; |
---|
6600 | 7489 | } |
---|
6601 | 7490 | |
---|
| 7491 | + megasas_setup_debugfs(instance); |
---|
| 7492 | + |
---|
6602 | 7493 | /* Get current SR-IOV LD/VF affiliation */ |
---|
6603 | 7494 | if (instance->requestorId) |
---|
6604 | 7495 | megasas_get_ld_vf_affiliation(instance, 1); |
---|
.. | .. |
---|
6606 | 7497 | return 0; |
---|
6607 | 7498 | |
---|
6608 | 7499 | fail_start_aen: |
---|
| 7500 | + instance->unload = 1; |
---|
| 7501 | + scsi_remove_host(instance->host); |
---|
6609 | 7502 | fail_io_attach: |
---|
6610 | 7503 | megasas_mgmt_info.count--; |
---|
6611 | 7504 | megasas_mgmt_info.max_index--; |
---|
6612 | 7505 | megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL; |
---|
| 7506 | + |
---|
| 7507 | + if (instance->requestorId && !instance->skip_heartbeat_timer_del) |
---|
| 7508 | + del_timer_sync(&instance->sriov_heartbeat_timer); |
---|
6613 | 7509 | |
---|
6614 | 7510 | instance->instancet->disable_intr(instance); |
---|
6615 | 7511 | megasas_destroy_irqs(instance); |
---|
.. | .. |
---|
6618 | 7514 | megasas_release_fusion(instance); |
---|
6619 | 7515 | else |
---|
6620 | 7516 | megasas_release_mfi(instance); |
---|
| 7517 | + |
---|
6621 | 7518 | if (instance->msix_vectors) |
---|
6622 | 7519 | pci_free_irq_vectors(instance->pdev); |
---|
| 7520 | + instance->msix_vectors = 0; |
---|
| 7521 | + |
---|
| 7522 | + if (instance->fw_crash_state != UNAVAILABLE) |
---|
| 7523 | + megasas_free_host_crash_buffer(instance); |
---|
| 7524 | + |
---|
| 7525 | + if (instance->adapter_type != MFI_SERIES) |
---|
| 7526 | + megasas_fusion_stop_watchdog(instance); |
---|
6623 | 7527 | fail_init_mfi: |
---|
6624 | 7528 | scsi_host_put(host); |
---|
6625 | 7529 | fail_alloc_instance: |
---|
.. | .. |
---|
6730 | 7634 | static int |
---|
6731 | 7635 | megasas_suspend(struct pci_dev *pdev, pm_message_t state) |
---|
6732 | 7636 | { |
---|
6733 | | - struct Scsi_Host *host; |
---|
6734 | 7637 | struct megasas_instance *instance; |
---|
6735 | 7638 | |
---|
6736 | 7639 | instance = pci_get_drvdata(pdev); |
---|
6737 | | - host = instance->host; |
---|
| 7640 | + |
---|
| 7641 | + if (!instance) |
---|
| 7642 | + return 0; |
---|
| 7643 | + |
---|
6738 | 7644 | instance->unload = 1; |
---|
| 7645 | + |
---|
| 7646 | + dev_info(&pdev->dev, "%s is called\n", __func__); |
---|
6739 | 7647 | |
---|
6740 | 7648 | /* Shutdown SR-IOV heartbeat timer */ |
---|
6741 | 7649 | if (instance->requestorId && !instance->skip_heartbeat_timer_del) |
---|
6742 | 7650 | del_timer_sync(&instance->sriov_heartbeat_timer); |
---|
| 7651 | + |
---|
| 7652 | + /* Stop the FW fault detection watchdog */ |
---|
| 7653 | + if (instance->adapter_type != MFI_SERIES) |
---|
| 7654 | + megasas_fusion_stop_watchdog(instance); |
---|
6743 | 7655 | |
---|
6744 | 7656 | megasas_flush_cache(instance); |
---|
6745 | 7657 | megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN); |
---|
.. | .. |
---|
6779 | 7691 | int rval; |
---|
6780 | 7692 | struct Scsi_Host *host; |
---|
6781 | 7693 | struct megasas_instance *instance; |
---|
6782 | | - int irq_flags = PCI_IRQ_LEGACY; |
---|
| 7694 | + u32 status_reg; |
---|
6783 | 7695 | |
---|
6784 | 7696 | instance = pci_get_drvdata(pdev); |
---|
| 7697 | + |
---|
| 7698 | + if (!instance) |
---|
| 7699 | + return 0; |
---|
| 7700 | + |
---|
6785 | 7701 | host = instance->host; |
---|
6786 | 7702 | pci_set_power_state(pdev, PCI_D0); |
---|
6787 | 7703 | pci_enable_wake(pdev, PCI_D0, 0); |
---|
6788 | 7704 | pci_restore_state(pdev); |
---|
6789 | 7705 | |
---|
| 7706 | + dev_info(&pdev->dev, "%s is called\n", __func__); |
---|
6790 | 7707 | /* |
---|
6791 | 7708 | * PCI prepping: enable device set bus mastering and dma mask |
---|
6792 | 7709 | */ |
---|
.. | .. |
---|
6802 | 7719 | /* |
---|
6803 | 7720 | * We expect the FW state to be READY |
---|
6804 | 7721 | */ |
---|
6805 | | - if (megasas_transition_to_ready(instance, 0)) |
---|
6806 | | - goto fail_ready_state; |
---|
6807 | 7722 | |
---|
| 7723 | + if (megasas_transition_to_ready(instance, 0)) { |
---|
| 7724 | + dev_info(&instance->pdev->dev, |
---|
| 7725 | + "Failed to transition controller to ready from %s!\n", |
---|
| 7726 | + __func__); |
---|
| 7727 | + if (instance->adapter_type != MFI_SERIES) { |
---|
| 7728 | + status_reg = |
---|
| 7729 | + instance->instancet->read_fw_status_reg(instance); |
---|
| 7730 | + if (!(status_reg & MFI_RESET_ADAPTER) || |
---|
| 7731 | + ((megasas_adp_reset_wait_for_ready |
---|
| 7732 | + (instance, true, 0)) == FAILED)) |
---|
| 7733 | + goto fail_ready_state; |
---|
| 7734 | + } else { |
---|
| 7735 | + atomic_set(&instance->fw_reset_no_pci_access, 1); |
---|
| 7736 | + instance->instancet->adp_reset |
---|
| 7737 | + (instance, instance->reg_set); |
---|
| 7738 | + atomic_set(&instance->fw_reset_no_pci_access, 0); |
---|
| 7739 | + |
---|
| 7740 | + /* waiting for about 30 seconds before retry */ |
---|
| 7741 | + ssleep(30); |
---|
| 7742 | + |
---|
| 7743 | + if (megasas_transition_to_ready(instance, 0)) |
---|
| 7744 | + goto fail_ready_state; |
---|
| 7745 | + } |
---|
| 7746 | + |
---|
| 7747 | + dev_info(&instance->pdev->dev, |
---|
| 7748 | + "FW restarted successfully from %s!\n", |
---|
| 7749 | + __func__); |
---|
| 7750 | + } |
---|
6808 | 7751 | if (megasas_set_dma_mask(instance)) |
---|
6809 | 7752 | goto fail_set_dma_mask; |
---|
6810 | 7753 | |
---|
.. | .. |
---|
6816 | 7759 | atomic_set(&instance->ldio_outstanding, 0); |
---|
6817 | 7760 | |
---|
6818 | 7761 | /* 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; |
---|
| 7762 | + if (instance->msix_vectors) |
---|
| 7763 | + megasas_alloc_irq_vectors(instance); |
---|
| 7764 | + |
---|
| 7765 | + if (!instance->msix_vectors) { |
---|
| 7766 | + rval = pci_alloc_irq_vectors(instance->pdev, 1, 1, |
---|
| 7767 | + PCI_IRQ_LEGACY); |
---|
| 7768 | + if (rval < 0) |
---|
| 7769 | + goto fail_reenable_msix; |
---|
6823 | 7770 | } |
---|
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 | 7771 | |
---|
6830 | 7772 | megasas_setup_reply_map(instance); |
---|
6831 | 7773 | |
---|
.. | .. |
---|
6856 | 7798 | megasas_setup_irqs_ioapic(instance)) |
---|
6857 | 7799 | goto fail_init_mfi; |
---|
6858 | 7800 | |
---|
| 7801 | + if (instance->adapter_type != MFI_SERIES) |
---|
| 7802 | + megasas_setup_irq_poll(instance); |
---|
| 7803 | + |
---|
6859 | 7804 | /* Re-launch SR-IOV heartbeat timer */ |
---|
6860 | 7805 | if (instance->requestorId) { |
---|
6861 | 7806 | if (!megasas_sriov_start_heartbeat(instance, 0)) |
---|
.. | .. |
---|
6876 | 7821 | if (megasas_start_aen(instance)) |
---|
6877 | 7822 | dev_err(&instance->pdev->dev, "Start AEN failed\n"); |
---|
6878 | 7823 | |
---|
| 7824 | + /* Re-launch FW fault watchdog */ |
---|
| 7825 | + if (instance->adapter_type != MFI_SERIES) |
---|
| 7826 | + if (megasas_fusion_start_watchdog(instance) != SUCCESS) |
---|
| 7827 | + goto fail_start_watchdog; |
---|
| 7828 | + |
---|
6879 | 7829 | return 0; |
---|
6880 | 7830 | |
---|
| 7831 | +fail_start_watchdog: |
---|
| 7832 | + if (instance->requestorId && !instance->skip_heartbeat_timer_del) |
---|
| 7833 | + del_timer_sync(&instance->sriov_heartbeat_timer); |
---|
6881 | 7834 | fail_init_mfi: |
---|
6882 | 7835 | megasas_free_ctrl_dma_buffers(instance); |
---|
6883 | 7836 | megasas_free_ctrl_mem(instance); |
---|
.. | .. |
---|
6938 | 7891 | u32 pd_seq_map_sz; |
---|
6939 | 7892 | |
---|
6940 | 7893 | instance = pci_get_drvdata(pdev); |
---|
| 7894 | + |
---|
| 7895 | + if (!instance) |
---|
| 7896 | + return; |
---|
| 7897 | + |
---|
6941 | 7898 | host = instance->host; |
---|
6942 | 7899 | fusion = instance->ctrl_context; |
---|
6943 | 7900 | |
---|
6944 | 7901 | /* Shutdown SR-IOV heartbeat timer */ |
---|
6945 | 7902 | if (instance->requestorId && !instance->skip_heartbeat_timer_del) |
---|
6946 | 7903 | del_timer_sync(&instance->sriov_heartbeat_timer); |
---|
| 7904 | + |
---|
| 7905 | + /* Stop the FW fault detection watchdog */ |
---|
| 7906 | + if (instance->adapter_type != MFI_SERIES) |
---|
| 7907 | + megasas_fusion_stop_watchdog(instance); |
---|
6947 | 7908 | |
---|
6948 | 7909 | if (instance->fw_crash_state != UNAVAILABLE) |
---|
6949 | 7910 | megasas_free_host_crash_buffer(instance); |
---|
.. | .. |
---|
6989 | 7950 | if (instance->msix_vectors) |
---|
6990 | 7951 | pci_free_irq_vectors(instance->pdev); |
---|
6991 | 7952 | |
---|
6992 | | - if (instance->adapter_type == VENTURA_SERIES) { |
---|
| 7953 | + if (instance->adapter_type >= VENTURA_SERIES) { |
---|
6993 | 7954 | for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) |
---|
6994 | 7955 | kfree(fusion->stream_detect_by_ld[i]); |
---|
6995 | 7956 | kfree(fusion->stream_detect_by_ld); |
---|
.. | .. |
---|
7027 | 7988 | } |
---|
7028 | 7989 | |
---|
7029 | 7990 | if (instance->vf_affiliation) |
---|
7030 | | - pci_free_consistent(pdev, (MAX_LOGICAL_DRIVES + 1) * |
---|
| 7991 | + dma_free_coherent(&pdev->dev, (MAX_LOGICAL_DRIVES + 1) * |
---|
7031 | 7992 | sizeof(struct MR_LD_VF_AFFILIATION), |
---|
7032 | 7993 | instance->vf_affiliation, |
---|
7033 | 7994 | instance->vf_affiliation_h); |
---|
7034 | 7995 | |
---|
7035 | 7996 | if (instance->vf_affiliation_111) |
---|
7036 | | - pci_free_consistent(pdev, |
---|
| 7997 | + dma_free_coherent(&pdev->dev, |
---|
7037 | 7998 | sizeof(struct MR_LD_VF_AFFILIATION_111), |
---|
7038 | 7999 | instance->vf_affiliation_111, |
---|
7039 | 8000 | instance->vf_affiliation_111_h); |
---|
7040 | 8001 | |
---|
7041 | 8002 | if (instance->hb_host_mem) |
---|
7042 | | - pci_free_consistent(pdev, sizeof(struct MR_CTRL_HB_HOST_MEM), |
---|
| 8003 | + dma_free_coherent(&pdev->dev, sizeof(struct MR_CTRL_HB_HOST_MEM), |
---|
7043 | 8004 | instance->hb_host_mem, |
---|
7044 | 8005 | instance->hb_host_mem_h); |
---|
7045 | 8006 | |
---|
7046 | 8007 | megasas_free_ctrl_dma_buffers(instance); |
---|
7047 | 8008 | |
---|
7048 | 8009 | megasas_free_ctrl_mem(instance); |
---|
| 8010 | + |
---|
| 8011 | + megasas_destroy_debugfs(instance); |
---|
7049 | 8012 | |
---|
7050 | 8013 | scsi_host_put(host); |
---|
7051 | 8014 | |
---|
.. | .. |
---|
7054 | 8017 | |
---|
7055 | 8018 | /** |
---|
7056 | 8019 | * megasas_shutdown - Shutdown entry point |
---|
7057 | | - * @device: Generic device structure |
---|
| 8020 | + * @pdev: Generic device structure |
---|
7058 | 8021 | */ |
---|
7059 | 8022 | static void megasas_shutdown(struct pci_dev *pdev) |
---|
7060 | 8023 | { |
---|
7061 | 8024 | struct megasas_instance *instance = pci_get_drvdata(pdev); |
---|
| 8025 | + |
---|
| 8026 | + if (!instance) |
---|
| 8027 | + return; |
---|
7062 | 8028 | |
---|
7063 | 8029 | instance->unload = 1; |
---|
7064 | 8030 | |
---|
.. | .. |
---|
7076 | 8042 | pci_free_irq_vectors(instance->pdev); |
---|
7077 | 8043 | } |
---|
7078 | 8044 | |
---|
7079 | | -/** |
---|
| 8045 | +/* |
---|
7080 | 8046 | * megasas_mgmt_open - char node "open" entry point |
---|
| 8047 | + * @inode: char node inode |
---|
| 8048 | + * @filep: char node file |
---|
7081 | 8049 | */ |
---|
7082 | 8050 | static int megasas_mgmt_open(struct inode *inode, struct file *filep) |
---|
7083 | 8051 | { |
---|
.. | .. |
---|
7090 | 8058 | return 0; |
---|
7091 | 8059 | } |
---|
7092 | 8060 | |
---|
7093 | | -/** |
---|
| 8061 | +/* |
---|
7094 | 8062 | * megasas_mgmt_fasync - Async notifier registration from applications |
---|
| 8063 | + * @fd: char node file descriptor number |
---|
| 8064 | + * @filep: char node file |
---|
| 8065 | + * @mode: notifier on/off |
---|
7095 | 8066 | * |
---|
7096 | 8067 | * This function adds the calling process to a driver global queue. When an |
---|
7097 | 8068 | * event occurs, SIGIO will be sent to all processes in this queue. |
---|
.. | .. |
---|
7117 | 8088 | return rc; |
---|
7118 | 8089 | } |
---|
7119 | 8090 | |
---|
7120 | | -/** |
---|
| 8091 | +/* |
---|
7121 | 8092 | * megasas_mgmt_poll - char node "poll" entry point |
---|
7122 | | - * */ |
---|
| 8093 | + * @filep: char node file |
---|
| 8094 | + * @wait: Events to poll for |
---|
| 8095 | + */ |
---|
7123 | 8096 | static __poll_t megasas_mgmt_poll(struct file *file, poll_table *wait) |
---|
7124 | 8097 | { |
---|
7125 | 8098 | __poll_t mask; |
---|
.. | .. |
---|
7177 | 8150 | /** |
---|
7178 | 8151 | * megasas_mgmt_fw_ioctl - Issues management ioctls to FW |
---|
7179 | 8152 | * @instance: Adapter soft state |
---|
7180 | | - * @argp: User's ioctl packet |
---|
| 8153 | + * @user_ioc: User's ioctl packet |
---|
| 8154 | + * @ioc: ioctl packet |
---|
7181 | 8155 | */ |
---|
7182 | 8156 | static int |
---|
7183 | 8157 | megasas_mgmt_fw_ioctl(struct megasas_instance *instance, |
---|
.. | .. |
---|
7194 | 8168 | dma_addr_t sense_handle; |
---|
7195 | 8169 | void *sense_ptr; |
---|
7196 | 8170 | u32 opcode = 0; |
---|
| 8171 | + int ret = DCMD_SUCCESS; |
---|
7197 | 8172 | |
---|
7198 | 8173 | memset(kbuff_arr, 0, sizeof(kbuff_arr)); |
---|
7199 | 8174 | |
---|
.. | .. |
---|
7205 | 8180 | |
---|
7206 | 8181 | if ((ioc->frame.hdr.cmd >= MFI_CMD_OP_COUNT) || |
---|
7207 | 8182 | ((ioc->frame.hdr.cmd == MFI_CMD_NVME) && |
---|
7208 | | - !instance->support_nvme_passthru)) { |
---|
| 8183 | + !instance->support_nvme_passthru) || |
---|
| 8184 | + ((ioc->frame.hdr.cmd == MFI_CMD_TOOLBOX) && |
---|
| 8185 | + !instance->support_pci_lane_margining)) { |
---|
7209 | 8186 | dev_err(&instance->pdev->dev, |
---|
7210 | 8187 | "Received invalid ioctl command 0x%x\n", |
---|
7211 | 8188 | ioc->frame.hdr.cmd); |
---|
.. | .. |
---|
7241 | 8218 | opcode = le32_to_cpu(cmd->frame->dcmd.opcode); |
---|
7242 | 8219 | |
---|
7243 | 8220 | if (opcode == MR_DCMD_CTRL_SHUTDOWN) { |
---|
| 8221 | + mutex_lock(&instance->reset_mutex); |
---|
7244 | 8222 | if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) { |
---|
7245 | 8223 | megasas_return_cmd(instance, cmd); |
---|
| 8224 | + mutex_unlock(&instance->reset_mutex); |
---|
7246 | 8225 | return -1; |
---|
7247 | 8226 | } |
---|
| 8227 | + mutex_unlock(&instance->reset_mutex); |
---|
7248 | 8228 | } |
---|
7249 | 8229 | |
---|
7250 | 8230 | if (opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) { |
---|
.. | .. |
---|
7287 | 8267 | |
---|
7288 | 8268 | /* |
---|
7289 | 8269 | * We don't change the dma_coherent_mask, so |
---|
7290 | | - * pci_alloc_consistent only returns 32bit addresses |
---|
| 8270 | + * dma_alloc_coherent only returns 32bit addresses |
---|
7291 | 8271 | */ |
---|
7292 | 8272 | if (instance->consistent_mask_64bit) { |
---|
7293 | 8273 | kern_sge64[i].phys_addr = cpu_to_le64(buf_handle); |
---|
.. | .. |
---|
7333 | 8313 | * cmd to the SCSI mid-layer |
---|
7334 | 8314 | */ |
---|
7335 | 8315 | cmd->sync_cmd = 1; |
---|
7336 | | - if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) { |
---|
| 8316 | + |
---|
| 8317 | + ret = megasas_issue_blocked_cmd(instance, cmd, 0); |
---|
| 8318 | + switch (ret) { |
---|
| 8319 | + case DCMD_INIT: |
---|
| 8320 | + case DCMD_BUSY: |
---|
7337 | 8321 | cmd->sync_cmd = 0; |
---|
7338 | 8322 | dev_err(&instance->pdev->dev, |
---|
7339 | 8323 | "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; |
---|
| 8324 | + __func__, __LINE__, cmd->frame->hdr.cmd, opcode, |
---|
| 8325 | + cmd->cmd_status_drv); |
---|
| 8326 | + error = -EBUSY; |
---|
| 8327 | + goto out; |
---|
7343 | 8328 | } |
---|
7344 | 8329 | |
---|
7345 | 8330 | cmd->sync_cmd = 0; |
---|
.. | .. |
---|
7510 | 8495 | |
---|
7511 | 8496 | /** |
---|
7512 | 8497 | * megasas_mgmt_ioctl - char node ioctl entry point |
---|
| 8498 | + * @file: char device file pointer |
---|
| 8499 | + * @cmd: ioctl command |
---|
| 8500 | + * @arg: ioctl command arguments address |
---|
7513 | 8501 | */ |
---|
7514 | 8502 | static long |
---|
7515 | 8503 | megasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
---|
.. | .. |
---|
7690 | 8678 | |
---|
7691 | 8679 | static DRIVER_ATTR_RO(support_nvme_encapsulation); |
---|
7692 | 8680 | |
---|
| 8681 | +static ssize_t |
---|
| 8682 | +support_pci_lane_margining_show(struct device_driver *dd, char *buf) |
---|
| 8683 | +{ |
---|
| 8684 | + return sprintf(buf, "%u\n", support_pci_lane_margining); |
---|
| 8685 | +} |
---|
| 8686 | + |
---|
| 8687 | +static DRIVER_ATTR_RO(support_pci_lane_margining); |
---|
| 8688 | + |
---|
7693 | 8689 | static inline void megasas_remove_scsi_device(struct scsi_device *sdev) |
---|
7694 | 8690 | { |
---|
7695 | 8691 | sdev_printk(KERN_INFO, sdev, "SCSI device is removed\n"); |
---|
.. | .. |
---|
7697 | 8693 | scsi_device_put(sdev); |
---|
7698 | 8694 | } |
---|
7699 | 8695 | |
---|
7700 | | -static void |
---|
7701 | | -megasas_aen_polling(struct work_struct *work) |
---|
| 8696 | +/** |
---|
| 8697 | + * megasas_update_device_list - Update the PD and LD device list from FW |
---|
| 8698 | + * after an AEN event notification |
---|
| 8699 | + * @instance: Adapter soft state |
---|
| 8700 | + * @event_type: Indicates type of event (PD or LD event) |
---|
| 8701 | + * |
---|
| 8702 | + * @return: Success or failure |
---|
| 8703 | + * |
---|
| 8704 | + * Issue DCMDs to Firmware to update the internal device list in driver. |
---|
| 8705 | + * Based on the FW support, driver sends the HOST_DEVICE_LIST or combination |
---|
| 8706 | + * of PD_LIST/LD_LIST_QUERY DCMDs to get the device list. |
---|
| 8707 | + */ |
---|
| 8708 | +static |
---|
| 8709 | +int megasas_update_device_list(struct megasas_instance *instance, |
---|
| 8710 | + int event_type) |
---|
7702 | 8711 | { |
---|
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; |
---|
| 8712 | + int dcmd_ret = DCMD_SUCCESS; |
---|
7715 | 8713 | |
---|
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 | | - } |
---|
| 8714 | + if (instance->enable_fw_dev_list) { |
---|
| 8715 | + dcmd_ret = megasas_host_device_list_query(instance, false); |
---|
| 8716 | + if (dcmd_ret != DCMD_SUCCESS) |
---|
| 8717 | + goto out; |
---|
7783 | 8718 | } else { |
---|
7784 | | - dev_err(&instance->pdev->dev, "invalid evt_detail!\n"); |
---|
7785 | | - mutex_unlock(&instance->reset_mutex); |
---|
7786 | | - kfree(ev); |
---|
7787 | | - return; |
---|
| 8719 | + if (event_type & SCAN_PD_CHANNEL) { |
---|
| 8720 | + dcmd_ret = megasas_get_pd_list(instance); |
---|
| 8721 | + |
---|
| 8722 | + if (dcmd_ret != DCMD_SUCCESS) |
---|
| 8723 | + goto out; |
---|
| 8724 | + } |
---|
| 8725 | + |
---|
| 8726 | + if (event_type & SCAN_VD_CHANNEL) { |
---|
| 8727 | + if (!instance->requestorId || |
---|
| 8728 | + (instance->requestorId && |
---|
| 8729 | + megasas_get_ld_vf_affiliation(instance, 0))) { |
---|
| 8730 | + dcmd_ret = megasas_ld_list_query(instance, |
---|
| 8731 | + MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); |
---|
| 8732 | + if (dcmd_ret != DCMD_SUCCESS) |
---|
| 8733 | + goto out; |
---|
| 8734 | + } |
---|
| 8735 | + } |
---|
7788 | 8736 | } |
---|
7789 | 8737 | |
---|
7790 | | - mutex_unlock(&instance->reset_mutex); |
---|
| 8738 | +out: |
---|
| 8739 | + return dcmd_ret; |
---|
| 8740 | +} |
---|
7791 | 8741 | |
---|
7792 | | - if (doscan & SCAN_PD_CHANNEL) { |
---|
| 8742 | +/** |
---|
| 8743 | + * megasas_add_remove_devices - Add/remove devices to SCSI mid-layer |
---|
| 8744 | + * after an AEN event notification |
---|
| 8745 | + * @instance: Adapter soft state |
---|
| 8746 | + * @scan_type: Indicates type of devices (PD/LD) to add |
---|
| 8747 | + * @return void |
---|
| 8748 | + */ |
---|
| 8749 | +static |
---|
| 8750 | +void megasas_add_remove_devices(struct megasas_instance *instance, |
---|
| 8751 | + int scan_type) |
---|
| 8752 | +{ |
---|
| 8753 | + int i, j; |
---|
| 8754 | + u16 pd_index = 0; |
---|
| 8755 | + u16 ld_index = 0; |
---|
| 8756 | + u16 channel = 0, id = 0; |
---|
| 8757 | + struct Scsi_Host *host; |
---|
| 8758 | + struct scsi_device *sdev1; |
---|
| 8759 | + struct MR_HOST_DEVICE_LIST *targetid_list = NULL; |
---|
| 8760 | + struct MR_HOST_DEVICE_LIST_ENTRY *targetid_entry = NULL; |
---|
| 8761 | + |
---|
| 8762 | + host = instance->host; |
---|
| 8763 | + |
---|
| 8764 | + if (instance->enable_fw_dev_list) { |
---|
| 8765 | + targetid_list = instance->host_device_list_buf; |
---|
| 8766 | + for (i = 0; i < targetid_list->count; i++) { |
---|
| 8767 | + targetid_entry = &targetid_list->host_device_list[i]; |
---|
| 8768 | + if (targetid_entry->flags.u.bits.is_sys_pd) { |
---|
| 8769 | + channel = le16_to_cpu(targetid_entry->target_id) / |
---|
| 8770 | + MEGASAS_MAX_DEV_PER_CHANNEL; |
---|
| 8771 | + id = le16_to_cpu(targetid_entry->target_id) % |
---|
| 8772 | + MEGASAS_MAX_DEV_PER_CHANNEL; |
---|
| 8773 | + } else { |
---|
| 8774 | + channel = MEGASAS_MAX_PD_CHANNELS + |
---|
| 8775 | + (le16_to_cpu(targetid_entry->target_id) / |
---|
| 8776 | + MEGASAS_MAX_DEV_PER_CHANNEL); |
---|
| 8777 | + id = le16_to_cpu(targetid_entry->target_id) % |
---|
| 8778 | + MEGASAS_MAX_DEV_PER_CHANNEL; |
---|
| 8779 | + } |
---|
| 8780 | + sdev1 = scsi_device_lookup(host, channel, id, 0); |
---|
| 8781 | + if (!sdev1) { |
---|
| 8782 | + scsi_add_device(host, channel, id, 0); |
---|
| 8783 | + } else { |
---|
| 8784 | + scsi_device_put(sdev1); |
---|
| 8785 | + } |
---|
| 8786 | + } |
---|
| 8787 | + } |
---|
| 8788 | + |
---|
| 8789 | + if (scan_type & SCAN_PD_CHANNEL) { |
---|
7793 | 8790 | for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { |
---|
7794 | 8791 | for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) { |
---|
7795 | | - pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j; |
---|
| 8792 | + pd_index = i * MEGASAS_MAX_DEV_PER_CHANNEL + j; |
---|
7796 | 8793 | sdev1 = scsi_device_lookup(host, i, j, 0); |
---|
7797 | 8794 | if (instance->pd_list[pd_index].driveState == |
---|
7798 | 8795 | MR_PD_STATE_SYSTEM) { |
---|
.. | .. |
---|
7808 | 8805 | } |
---|
7809 | 8806 | } |
---|
7810 | 8807 | |
---|
7811 | | - if (doscan & SCAN_VD_CHANNEL) { |
---|
| 8808 | + if (scan_type & SCAN_VD_CHANNEL) { |
---|
7812 | 8809 | for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { |
---|
7813 | 8810 | for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) { |
---|
7814 | 8811 | ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; |
---|
7815 | | - sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0); |
---|
| 8812 | + sdev1 = scsi_device_lookup(host, |
---|
| 8813 | + MEGASAS_MAX_PD_CHANNELS + i, j, 0); |
---|
7816 | 8814 | if (instance->ld_ids[ld_index] != 0xff) { |
---|
7817 | 8815 | if (!sdev1) |
---|
7818 | 8816 | scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0); |
---|
.. | .. |
---|
7825 | 8823 | } |
---|
7826 | 8824 | } |
---|
7827 | 8825 | } |
---|
| 8826 | + |
---|
| 8827 | +} |
---|
| 8828 | + |
---|
| 8829 | +static void |
---|
| 8830 | +megasas_aen_polling(struct work_struct *work) |
---|
| 8831 | +{ |
---|
| 8832 | + struct megasas_aen_event *ev = |
---|
| 8833 | + container_of(work, struct megasas_aen_event, hotplug_work.work); |
---|
| 8834 | + struct megasas_instance *instance = ev->instance; |
---|
| 8835 | + union megasas_evt_class_locale class_locale; |
---|
| 8836 | + int event_type = 0; |
---|
| 8837 | + u32 seq_num; |
---|
| 8838 | + u16 ld_target_id; |
---|
| 8839 | + int error; |
---|
| 8840 | + u8 dcmd_ret = DCMD_SUCCESS; |
---|
| 8841 | + struct scsi_device *sdev1; |
---|
| 8842 | + |
---|
| 8843 | + if (!instance) { |
---|
| 8844 | + printk(KERN_ERR "invalid instance!\n"); |
---|
| 8845 | + kfree(ev); |
---|
| 8846 | + return; |
---|
| 8847 | + } |
---|
| 8848 | + |
---|
| 8849 | + /* Don't run the event workqueue thread if OCR is running */ |
---|
| 8850 | + mutex_lock(&instance->reset_mutex); |
---|
| 8851 | + |
---|
| 8852 | + instance->ev = NULL; |
---|
| 8853 | + if (instance->evt_detail) { |
---|
| 8854 | + megasas_decode_evt(instance); |
---|
| 8855 | + |
---|
| 8856 | + switch (le32_to_cpu(instance->evt_detail->code)) { |
---|
| 8857 | + |
---|
| 8858 | + case MR_EVT_PD_INSERTED: |
---|
| 8859 | + case MR_EVT_PD_REMOVED: |
---|
| 8860 | + event_type = SCAN_PD_CHANNEL; |
---|
| 8861 | + break; |
---|
| 8862 | + |
---|
| 8863 | + case MR_EVT_LD_OFFLINE: |
---|
| 8864 | + case MR_EVT_LD_DELETED: |
---|
| 8865 | + ld_target_id = instance->evt_detail->args.ld.target_id; |
---|
| 8866 | + sdev1 = scsi_device_lookup(instance->host, |
---|
| 8867 | + MEGASAS_MAX_PD_CHANNELS + |
---|
| 8868 | + (ld_target_id / MEGASAS_MAX_DEV_PER_CHANNEL), |
---|
| 8869 | + (ld_target_id - MEGASAS_MAX_DEV_PER_CHANNEL), |
---|
| 8870 | + 0); |
---|
| 8871 | + if (sdev1) |
---|
| 8872 | + megasas_remove_scsi_device(sdev1); |
---|
| 8873 | + |
---|
| 8874 | + event_type = SCAN_VD_CHANNEL; |
---|
| 8875 | + break; |
---|
| 8876 | + case MR_EVT_LD_CREATED: |
---|
| 8877 | + event_type = SCAN_VD_CHANNEL; |
---|
| 8878 | + break; |
---|
| 8879 | + |
---|
| 8880 | + case MR_EVT_CFG_CLEARED: |
---|
| 8881 | + case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED: |
---|
| 8882 | + case MR_EVT_FOREIGN_CFG_IMPORTED: |
---|
| 8883 | + case MR_EVT_LD_STATE_CHANGE: |
---|
| 8884 | + event_type = SCAN_PD_CHANNEL | SCAN_VD_CHANNEL; |
---|
| 8885 | + dev_info(&instance->pdev->dev, "scanning for scsi%d...\n", |
---|
| 8886 | + instance->host->host_no); |
---|
| 8887 | + break; |
---|
| 8888 | + |
---|
| 8889 | + case MR_EVT_CTRL_PROP_CHANGED: |
---|
| 8890 | + dcmd_ret = megasas_get_ctrl_info(instance); |
---|
| 8891 | + if (dcmd_ret == DCMD_SUCCESS && |
---|
| 8892 | + instance->snapdump_wait_time) { |
---|
| 8893 | + megasas_get_snapdump_properties(instance); |
---|
| 8894 | + dev_info(&instance->pdev->dev, |
---|
| 8895 | + "Snap dump wait time\t: %d\n", |
---|
| 8896 | + instance->snapdump_wait_time); |
---|
| 8897 | + } |
---|
| 8898 | + break; |
---|
| 8899 | + default: |
---|
| 8900 | + event_type = 0; |
---|
| 8901 | + break; |
---|
| 8902 | + } |
---|
| 8903 | + } else { |
---|
| 8904 | + dev_err(&instance->pdev->dev, "invalid evt_detail!\n"); |
---|
| 8905 | + mutex_unlock(&instance->reset_mutex); |
---|
| 8906 | + kfree(ev); |
---|
| 8907 | + return; |
---|
| 8908 | + } |
---|
| 8909 | + |
---|
| 8910 | + if (event_type) |
---|
| 8911 | + dcmd_ret = megasas_update_device_list(instance, event_type); |
---|
| 8912 | + |
---|
| 8913 | + mutex_unlock(&instance->reset_mutex); |
---|
| 8914 | + |
---|
| 8915 | + if (event_type && dcmd_ret == DCMD_SUCCESS) |
---|
| 8916 | + megasas_add_remove_devices(instance, event_type); |
---|
7828 | 8917 | |
---|
7829 | 8918 | if (dcmd_ret == DCMD_SUCCESS) |
---|
7830 | 8919 | seq_num = le32_to_cpu(instance->evt_detail->seq_num) + 1; |
---|
.. | .. |
---|
7879 | 8968 | support_poll_for_event = 2; |
---|
7880 | 8969 | support_device_change = 1; |
---|
7881 | 8970 | support_nvme_encapsulation = true; |
---|
| 8971 | + support_pci_lane_margining = true; |
---|
7882 | 8972 | |
---|
7883 | 8973 | memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info)); |
---|
7884 | 8974 | |
---|
.. | .. |
---|
7894 | 8984 | |
---|
7895 | 8985 | megasas_mgmt_majorno = rval; |
---|
7896 | 8986 | |
---|
| 8987 | + megasas_init_debugfs(); |
---|
| 8988 | + |
---|
7897 | 8989 | /* |
---|
7898 | 8990 | * Register ourselves as PCI hotplug module |
---|
7899 | 8991 | */ |
---|
.. | .. |
---|
7902 | 8994 | if (rval) { |
---|
7903 | 8995 | printk(KERN_DEBUG "megasas: PCI hotplug registration failed \n"); |
---|
7904 | 8996 | goto err_pcidrv; |
---|
| 8997 | + } |
---|
| 8998 | + |
---|
| 8999 | + if ((event_log_level < MFI_EVT_CLASS_DEBUG) || |
---|
| 9000 | + (event_log_level > MFI_EVT_CLASS_DEAD)) { |
---|
| 9001 | + 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"); |
---|
| 9002 | + event_log_level = MFI_EVT_CLASS_CRITICAL; |
---|
7905 | 9003 | } |
---|
7906 | 9004 | |
---|
7907 | 9005 | rval = driver_create_file(&megasas_pci_driver.driver, |
---|
.. | .. |
---|
7933 | 9031 | if (rval) |
---|
7934 | 9032 | goto err_dcf_support_nvme_encapsulation; |
---|
7935 | 9033 | |
---|
| 9034 | + rval = driver_create_file(&megasas_pci_driver.driver, |
---|
| 9035 | + &driver_attr_support_pci_lane_margining); |
---|
| 9036 | + if (rval) |
---|
| 9037 | + goto err_dcf_support_pci_lane_margining; |
---|
| 9038 | + |
---|
7936 | 9039 | return rval; |
---|
| 9040 | + |
---|
| 9041 | +err_dcf_support_pci_lane_margining: |
---|
| 9042 | + driver_remove_file(&megasas_pci_driver.driver, |
---|
| 9043 | + &driver_attr_support_nvme_encapsulation); |
---|
7937 | 9044 | |
---|
7938 | 9045 | err_dcf_support_nvme_encapsulation: |
---|
7939 | 9046 | driver_remove_file(&megasas_pci_driver.driver, |
---|
.. | .. |
---|
7953 | 9060 | err_dcf_attr_ver: |
---|
7954 | 9061 | pci_unregister_driver(&megasas_pci_driver); |
---|
7955 | 9062 | err_pcidrv: |
---|
| 9063 | + megasas_exit_debugfs(); |
---|
7956 | 9064 | unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); |
---|
7957 | 9065 | return rval; |
---|
7958 | 9066 | } |
---|
.. | .. |
---|
7973 | 9081 | driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); |
---|
7974 | 9082 | driver_remove_file(&megasas_pci_driver.driver, |
---|
7975 | 9083 | &driver_attr_support_nvme_encapsulation); |
---|
| 9084 | + driver_remove_file(&megasas_pci_driver.driver, |
---|
| 9085 | + &driver_attr_support_pci_lane_margining); |
---|
7976 | 9086 | |
---|
7977 | 9087 | pci_unregister_driver(&megasas_pci_driver); |
---|
| 9088 | + megasas_exit_debugfs(); |
---|
7978 | 9089 | unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); |
---|
7979 | 9090 | } |
---|
7980 | 9091 | |
---|