blob: bb1bea6ab99c8732104550791f663cdf5122a309 [file] [log] [blame]
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001/*
adam radford3f1530c2010-12-14 18:51:48 -08002 * Linux MegaRAID driver for SAS based RAID controllers
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003 *
Sumit.Saxena@avagotech.come3990652014-11-17 15:24:03 +05304 * Copyright (c) 2003-2013 LSI Corporation
Shivasharan S365597c2018-10-16 23:37:43 -07005 * Copyright (c) 2013-2016 Avago Technologies
6 * Copyright (c) 2016-2018 Broadcom Inc.
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007 *
adam radford3f1530c2010-12-14 18:51:48 -08008 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040012 *
adam radford3f1530c2010-12-14 18:51:48 -080013 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040017 *
adam radford3f1530c2010-12-14 18:51:48 -080018 * You should have received a copy of the GNU General Public License
Sumit.Saxena@avagotech.come3990652014-11-17 15:24:03 +053019 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040020 *
Shivasharan S365597c2018-10-16 23:37:43 -070021 * Authors: Broadcom Inc.
adam radford3f1530c2010-12-14 18:51:48 -080022 * Sreenivas Bagalkote
23 * Sumant Patro
24 * Bo Yang
Sumit.Saxena@avagotech.come3990652014-11-17 15:24:03 +053025 * Adam Radford
Shivasharan S365597c2018-10-16 23:37:43 -070026 * Kashyap Desai <kashyap.desai@broadcom.com>
27 * Sumit Saxena <sumit.saxena@broadcom.com>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040028 *
Shivasharan S365597c2018-10-16 23:37:43 -070029 * Send feedback to: megaraidlinux.pdl@broadcom.com
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040030 */
31
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/pci.h>
35#include <linux/list.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040036#include <linux/moduleparam.h>
37#include <linux/module.h>
38#include <linux/spinlock.h>
39#include <linux/interrupt.h>
40#include <linux/delay.h>
41#include <linux/uio.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090042#include <linux/slab.h>
Linus Torvalds7c0f6ba2016-12-24 11:46:01 -080043#include <linux/uaccess.h>
Shivasharan S318aaef2017-02-10 00:59:22 -080044#include <asm/unaligned.h>
Al Viro43399232005-10-04 17:36:04 +010045#include <linux/fs.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040046#include <linux/compat.h>
Sumant Patrocf62a0a2007-02-14 12:41:55 -080047#include <linux/blkdev.h>
Arjan van de Ven0b950672006-01-11 13:16:10 +010048#include <linux/mutex.h>
Yang, Boc3518832009-10-06 14:18:02 -060049#include <linux/poll.h>
Shivasharan Sdef3e8d2017-08-23 04:47:03 -070050#include <linux/vmalloc.h>
Shivasharan S62a04f82019-05-07 10:05:35 -070051#include <linux/irq_poll.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040052
53#include <scsi/scsi.h>
54#include <scsi/scsi_cmnd.h>
55#include <scsi/scsi_device.h>
56#include <scsi/scsi_host.h>
adam radford4bcde502011-07-26 15:42:52 -070057#include <scsi/scsi_tcq.h>
Shivasharan S96c96032019-05-07 10:05:37 -070058#include <scsi/scsi_dbg.h>
adam radford9c915a82010-12-21 13:34:31 -080059#include "megaraid_sas_fusion.h"
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040060#include "megaraid_sas.h"
61
bo yangad84db22007-11-09 04:40:16 -050062/*
Yang, Bo1fd10682010-10-12 07:18:50 -060063 * Number of sectors per IO command
64 * Will be set in megasas_init_mfi if user does not provide
65 */
66static unsigned int max_sectors;
Tomas Henzlea14e462019-05-29 18:00:40 +020067module_param_named(max_sectors, max_sectors, int, 0444);
Yang, Bo1fd10682010-10-12 07:18:50 -060068MODULE_PARM_DESC(max_sectors,
69 "Maximum number of sectors per IO command");
70
adam radford80d9da92010-12-21 10:17:40 -080071static int msix_disable;
Tomas Henzlea14e462019-05-29 18:00:40 +020072module_param(msix_disable, int, 0444);
adam radford80d9da92010-12-21 10:17:40 -080073MODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0");
74
adam radford079eadd2012-10-01 19:26:59 -070075static unsigned int msix_vectors;
Tomas Henzlea14e462019-05-29 18:00:40 +020076module_param(msix_vectors, int, 0444);
adam radford079eadd2012-10-01 19:26:59 -070077MODULE_PARM_DESC(msix_vectors, "MSI-X max vector count. Default: Set by FW");
78
adam radford229fe472014-03-10 02:51:56 -070079static int allow_vf_ioctls;
Tomas Henzlea14e462019-05-29 18:00:40 +020080module_param(allow_vf_ioctls, int, 0444);
adam radford229fe472014-03-10 02:51:56 -070081MODULE_PARM_DESC(allow_vf_ioctls, "Allow ioctls in SR-IOV VF mode. Default: 0");
82
Sumit.Saxena@avagotech.comae09a6c2015-01-05 20:06:23 +053083static unsigned int throttlequeuedepth = MEGASAS_THROTTLE_QUEUE_DEPTH;
Tomas Henzlea14e462019-05-29 18:00:40 +020084module_param(throttlequeuedepth, int, 0444);
adam radfordc5daa6a2012-07-17 18:20:03 -070085MODULE_PARM_DESC(throttlequeuedepth,
86 "Adapter queue depth when throttled due to I/O timeout. Default: 16");
87
Sumit Saxenae3d178c2016-01-28 21:04:34 +053088unsigned int resetwaittime = MEGASAS_RESET_WAIT_TIME;
Tomas Henzlea14e462019-05-29 18:00:40 +020089module_param(resetwaittime, int, 0444);
Shivasharan S14013712018-10-16 23:37:45 -070090MODULE_PARM_DESC(resetwaittime, "Wait time in (1-180s) after I/O timeout before resetting adapter. Default: 180s");
adam radfordc007b8b2012-07-17 18:20:24 -070091
Sumit.Saxena@avagotech.comac951362014-09-12 18:57:48 +053092int smp_affinity_enable = 1;
Tomas Henzlea14e462019-05-29 18:00:40 +020093module_param(smp_affinity_enable, int, 0444);
Colin Ian King55d9a1d2018-04-29 13:25:32 +010094MODULE_PARM_DESC(smp_affinity_enable, "SMP affinity feature enable/disable Default: enable(1)");
Sumit.Saxena@avagotech.comac951362014-09-12 18:57:48 +053095
Sumit Saxena179ac142016-01-28 21:04:28 +053096int rdpq_enable = 1;
Tomas Henzlea14e462019-05-29 18:00:40 +020097module_param(rdpq_enable, int, 0444);
Shivasharan S14013712018-10-16 23:37:45 -070098MODULE_PARM_DESC(rdpq_enable, "Allocate reply queue in chunks for large queue depth enable/disable Default: enable(1)");
Sumit Saxena179ac142016-01-28 21:04:28 +053099
Sumit Saxena308ec452016-01-28 21:04:30 +0530100unsigned int dual_qdepth_disable;
Tomas Henzlea14e462019-05-29 18:00:40 +0200101module_param(dual_qdepth_disable, int, 0444);
Sumit Saxena308ec452016-01-28 21:04:30 +0530102MODULE_PARM_DESC(dual_qdepth_disable, "Disable dual queue depth feature. Default: 0");
103
Sumit Saxenae3d178c2016-01-28 21:04:34 +0530104unsigned int scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT;
Tomas Henzlea14e462019-05-29 18:00:40 +0200105module_param(scmd_timeout, int, 0444);
Sumit Saxenae3d178c2016-01-28 21:04:34 +0530106MODULE_PARM_DESC(scmd_timeout, "scsi command timeout (10-90s), default 90s. See megasas_reset_timer.");
107
Chandrakanth Patil299ee422019-06-25 16:34:35 +0530108int perf_mode = -1;
109module_param(perf_mode, int, 0444);
110MODULE_PARM_DESC(perf_mode, "Performance mode (only for Aero adapters), options:\n\t\t"
111 "0 - balanced: High iops and low latency queues are allocated &\n\t\t"
112 "interrupt coalescing is enabled only on high iops queues\n\t\t"
113 "1 - iops: High iops queues are not allocated &\n\t\t"
114 "interrupt coalescing is enabled on all queues\n\t\t"
115 "2 - latency: High iops queues are not allocated &\n\t\t"
116 "interrupt coalescing is disabled on all queues\n\t\t"
117 "default mode is 'balanced'"
118 );
119
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400120MODULE_LICENSE("GPL");
121MODULE_VERSION(MEGASAS_VERSION);
Shivasharan S365597c2018-10-16 23:37:43 -0700122MODULE_AUTHOR("megaraidlinux.pdl@broadcom.com");
123MODULE_DESCRIPTION("Broadcom MegaRAID SAS Driver");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400124
adam radford058a8fa2011-10-08 18:14:27 -0700125int megasas_transition_to_ready(struct megasas_instance *instance, int ocr);
bo yang39a98552010-09-22 22:36:29 -0400126static int megasas_get_pd_list(struct megasas_instance *instance);
adam radford21c9e162013-09-06 15:27:14 -0700127static int megasas_ld_list_query(struct megasas_instance *instance,
128 u8 query_type);
bo yang39a98552010-09-22 22:36:29 -0400129static int megasas_issue_init_mfi(struct megasas_instance *instance);
130static int megasas_register_aen(struct megasas_instance *instance,
131 u32 seq_num, u32 class_locale_word);
Shivasharan S15dd0382017-02-10 00:59:10 -0800132static void megasas_get_pd_info(struct megasas_instance *instance,
133 struct scsi_device *sdev);
Shivasharan Se9495e22018-06-04 03:45:12 -0700134
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400135/*
136 * PCI ID table for all supported controllers
137 */
138static struct pci_device_id megasas_pci_table[] = {
139
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200140 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064R)},
141 /* xscale IOP */
142 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
143 /* ppc IOP */
bo yangaf7a5642008-03-17 04:13:07 -0400144 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)},
145 /* ppc IOP */
Yang, Bo6610a6b2008-08-10 12:42:38 -0700146 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)},
147 /* gen2*/
148 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
149 /* gen2*/
Yang, Bo87911122009-10-06 14:31:54 -0600150 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
151 /* skinny*/
152 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
153 /* skinny*/
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200154 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
155 /* xscale IOP, vega */
156 {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
157 /* xscale IOP */
adam radford9c915a82010-12-21 13:34:31 -0800158 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FUSION)},
159 /* Fusion */
adam radford229fe472014-03-10 02:51:56 -0700160 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_PLASMA)},
161 /* Plasma */
adam radford36807e62011-10-08 18:15:06 -0700162 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INVADER)},
163 /* Invader */
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +0530164 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FURY)},
165 /* Fury */
sumit.saxena@avagotech.com90c204b2015-10-15 13:39:44 +0530166 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INTRUDER)},
167 /* Intruder */
168 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INTRUDER_24)},
169 /* Intruder 24 port*/
sumit.saxena@avagotech.com7364d342015-10-15 13:39:54 +0530170 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_52)},
171 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_53)},
Sasikumar Chandrasekaran45f4f2e2017-01-10 18:20:43 -0500172 /* VENTURA */
173 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA)},
Shivasharan S754f1ba2017-10-19 02:48:49 -0700174 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CRUSADER)},
Sasikumar Chandrasekaran45f4f2e2017-01-10 18:20:43 -0500175 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_HARPOON)},
176 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_TOMCAT)},
177 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA_4PORT)},
178 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CRUSADER_4PORT)},
Shivasharan S469f72d2018-11-09 09:47:20 -0800179 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E1)},
180 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E2)},
181 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E5)},
182 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E6)},
Chandrakanth Patildd807692019-06-25 16:34:20 +0530183 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E0)},
184 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E3)},
185 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E4)},
186 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E7)},
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200187 {}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400188};
189
190MODULE_DEVICE_TABLE(pci, megasas_pci_table);
191
192static int megasas_mgmt_majorno;
adam radford229fe472014-03-10 02:51:56 -0700193struct megasas_mgmt_info megasas_mgmt_info;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400194static struct fasync_struct *megasas_async_queue;
Arjan van de Ven0b950672006-01-11 13:16:10 +0100195static DEFINE_MUTEX(megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400196
Yang, Boc3518832009-10-06 14:18:02 -0600197static int megasas_poll_wait_aen;
198static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
Yang, Bo72c4fd32009-10-06 14:20:59 -0600199static u32 support_poll_for_event;
adam radford9c915a82010-12-21 13:34:31 -0800200u32 megasas_dbg_lvl;
Yang, Bo837f5fe2010-10-11 06:59:20 -0600201static u32 support_device_change;
Shivasharan Sf870bcb2018-01-05 05:33:04 -0800202static bool support_nvme_encapsulation;
Chandrakanth Patil58136852019-06-25 16:34:30 +0530203static bool support_pci_lane_margining;
Sumant Patro658dced2006-10-03 13:09:14 -0700204
Yang, Boc3518832009-10-06 14:18:02 -0600205/* define lock for aen poll */
206spinlock_t poll_aen_lock;
207
Shivasharan Sba535722019-05-07 10:05:49 -0700208extern struct dentry *megasas_debugfs_root;
209extern void megasas_init_debugfs(void);
210extern void megasas_exit_debugfs(void);
211extern void megasas_setup_debugfs(struct megasas_instance *instance);
212extern void megasas_destroy_debugfs(struct megasas_instance *instance);
213
adam radford9c915a82010-12-21 13:34:31 -0800214void
bo yang7343eb62007-11-09 04:35:44 -0500215megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
216 u8 alt_status);
adam radfordebf054b2011-02-24 20:57:15 -0800217static u32
Shivasharan Sde516372018-12-17 00:47:39 -0800218megasas_read_fw_status_reg_gen2(struct megasas_instance *instance);
adam radfordebf054b2011-02-24 20:57:15 -0800219static int
220megasas_adp_reset_gen2(struct megasas_instance *instance,
221 struct megasas_register_set __iomem *reg_set);
adam radfordcd50ba82010-12-21 10:23:23 -0800222static irqreturn_t megasas_isr(int irq, void *devp);
223static u32
224megasas_init_adapter_mfi(struct megasas_instance *instance);
225u32
226megasas_build_and_issue_cmd(struct megasas_instance *instance,
227 struct scsi_cmnd *scmd);
228static void megasas_complete_cmd_dpc(unsigned long instance_addr);
adam radford9c915a82010-12-21 13:34:31 -0800229int
adam radford229fe472014-03-10 02:51:56 -0700230wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
231 int seconds);
adam radford9c915a82010-12-21 13:34:31 -0800232void megasas_fusion_ocr_wq(struct work_struct *work);
adam radford229fe472014-03-10 02:51:56 -0700233static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
234 int initial);
Shivasharan Se5d65b42017-10-19 02:48:59 -0700235static int
Shivasharan S107a60d2017-10-19 02:49:05 -0700236megasas_set_dma_mask(struct megasas_instance *instance);
Shivasharan Se5d65b42017-10-19 02:48:59 -0700237static int
238megasas_alloc_ctrl_mem(struct megasas_instance *instance);
239static inline void
240megasas_free_ctrl_mem(struct megasas_instance *instance);
241static inline int
242megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance);
243static inline void
244megasas_free_ctrl_dma_buffers(struct megasas_instance *instance);
245static inline void
246megasas_init_ctrl_params(struct megasas_instance *instance);
adam radfordcd50ba82010-12-21 10:23:23 -0800247
Shivasharan S272652f2018-12-17 00:47:40 -0800248u32 megasas_readl(struct megasas_instance *instance,
249 const volatile void __iomem *addr)
250{
251 u32 i = 0, ret_val;
252 /*
253 * Due to a HW errata in Aero controllers, reads to certain
254 * Fusion registers could intermittently return all zeroes.
255 * This behavior is transient in nature and subsequent reads will
256 * return valid value. As a workaround in driver, retry readl for
257 * upto three times until a non-zero value is read.
258 */
259 if (instance->adapter_type == AERO_SERIES) {
260 do {
261 ret_val = readl(addr);
262 i++;
263 } while (ret_val == 0 && i < 3);
264 return ret_val;
265 } else {
266 return readl(addr);
267 }
268}
269
Shivasharan S107a60d2017-10-19 02:49:05 -0700270/**
271 * megasas_set_dma_settings - Populate DMA address, length and flags for DCMDs
272 * @instance: Adapter soft state
273 * @dcmd: DCMD frame inside MFI command
274 * @dma_addr: DMA address of buffer to be passed to FW
275 * @dma_len: Length of DMA buffer to be passed to FW
276 * @return: void
277 */
278void megasas_set_dma_settings(struct megasas_instance *instance,
279 struct megasas_dcmd_frame *dcmd,
280 dma_addr_t dma_addr, u32 dma_len)
281{
282 if (instance->consistent_mask_64bit) {
283 dcmd->sgl.sge64[0].phys_addr = cpu_to_le64(dma_addr);
284 dcmd->sgl.sge64[0].length = cpu_to_le32(dma_len);
285 dcmd->flags = cpu_to_le16(dcmd->flags | MFI_FRAME_SGL64);
286
287 } else {
288 dcmd->sgl.sge32[0].phys_addr =
289 cpu_to_le32(lower_32_bits(dma_addr));
290 dcmd->sgl.sge32[0].length = cpu_to_le32(dma_len);
291 dcmd->flags = cpu_to_le16(dcmd->flags);
292 }
293}
adam radfordcd50ba82010-12-21 10:23:23 -0800294
YueHaibing6764f512019-07-02 21:01:14 +0800295static void
adam radfordcd50ba82010-12-21 10:23:23 -0800296megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
297{
298 instance->instancet->fire_cmd(instance,
299 cmd->frame_phys_addr, 0, instance->reg_set);
Shivasharan Sf4fc2092017-02-10 00:59:09 -0800300 return;
adam radfordcd50ba82010-12-21 10:23:23 -0800301}
bo yang7343eb62007-11-09 04:35:44 -0500302
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400303/**
304 * megasas_get_cmd - Get a command from the free pool
305 * @instance: Adapter soft state
306 *
307 * Returns a free command from the pool
308 */
adam radford9c915a82010-12-21 13:34:31 -0800309struct megasas_cmd *megasas_get_cmd(struct megasas_instance
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400310 *instance)
311{
312 unsigned long flags;
313 struct megasas_cmd *cmd = NULL;
314
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +0530315 spin_lock_irqsave(&instance->mfi_pool_lock, flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400316
317 if (!list_empty(&instance->cmd_pool)) {
318 cmd = list_entry((&instance->cmd_pool)->next,
319 struct megasas_cmd, list);
320 list_del_init(&cmd->list);
321 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500322 dev_err(&instance->pdev->dev, "Command pool empty!\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400323 }
324
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +0530325 spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400326 return cmd;
327}
328
329/**
330 * megasas_return_cmd - Return a cmd to free command pool
331 * @instance: Adapter soft state
332 * @cmd: Command packet to be returned to free command pool
333 */
Andi Kleen68b43742017-05-08 15:58:53 -0700334void
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400335megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
336{
337 unsigned long flags;
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +0530338 u32 blk_tags;
339 struct megasas_cmd_fusion *cmd_fusion;
340 struct fusion_context *fusion = instance->ctrl_context;
341
342 /* This flag is used only for fusion adapter.
343 * Wait for Interrupt for Polled mode DCMD
344 */
345 if (cmd->flags & DRV_DCMD_POLLED_MODE)
346 return;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400347
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +0530348 spin_lock_irqsave(&instance->mfi_pool_lock, flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400349
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +0530350 if (fusion) {
351 blk_tags = instance->max_scsi_cmds + cmd->index;
352 cmd_fusion = fusion->cmd_list[blk_tags];
353 megasas_return_cmd_fusion(instance, cmd_fusion);
354 }
355 cmd->scmd = NULL;
356 cmd->frame_count = 0;
357 cmd->flags = 0;
Shivasharan S21c34002017-02-10 00:59:28 -0800358 memset(cmd->frame, 0, instance->mfi_frame_size);
359 cmd->frame->io.context = cpu_to_le32(cmd->index);
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +0530360 if (!fusion && reset_devices)
361 cmd->frame->hdr.cmd = MFI_CMD_INVALID;
362 list_add(&cmd->list, (&instance->cmd_pool)->next);
363
364 spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
365
366}
Sumant Patro1341c932006-01-25 12:02:40 -0800367
sumit.saxena@avagotech.com714f5172015-08-31 17:23:51 +0530368static const char *
369format_timestamp(uint32_t timestamp)
370{
371 static char buffer[32];
372
373 if ((timestamp & 0xff000000) == 0xff000000)
374 snprintf(buffer, sizeof(buffer), "boot + %us", timestamp &
375 0x00ffffff);
376 else
377 snprintf(buffer, sizeof(buffer), "%us", timestamp);
378 return buffer;
379}
380
381static const char *
382format_class(int8_t class)
383{
384 static char buffer[6];
385
386 switch (class) {
387 case MFI_EVT_CLASS_DEBUG:
388 return "debug";
389 case MFI_EVT_CLASS_PROGRESS:
390 return "progress";
391 case MFI_EVT_CLASS_INFO:
392 return "info";
393 case MFI_EVT_CLASS_WARNING:
394 return "WARN";
395 case MFI_EVT_CLASS_CRITICAL:
396 return "CRIT";
397 case MFI_EVT_CLASS_FATAL:
398 return "FATAL";
399 case MFI_EVT_CLASS_DEAD:
400 return "DEAD";
401 default:
402 snprintf(buffer, sizeof(buffer), "%d", class);
403 return buffer;
404 }
405}
406
407/**
408 * megasas_decode_evt: Decode FW AEN event and print critical event
409 * for information.
410 * @instance: Adapter soft state
411 */
412static void
413megasas_decode_evt(struct megasas_instance *instance)
414{
415 struct megasas_evt_detail *evt_detail = instance->evt_detail;
416 union megasas_evt_class_locale class_locale;
417 class_locale.word = le32_to_cpu(evt_detail->cl.word);
418
419 if (class_locale.members.class >= MFI_EVT_CLASS_CRITICAL)
420 dev_info(&instance->pdev->dev, "%d (%s/0x%04x/%s) - %s\n",
421 le32_to_cpu(evt_detail->seq_num),
422 format_timestamp(le32_to_cpu(evt_detail->time_stamp)),
423 (class_locale.members.locale),
424 format_class(class_locale.members.class),
425 evt_detail->description);
426}
427
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400428/**
adam radford0d490162010-12-14 19:17:17 -0800429* The following functions are defined for xscale
Sumant Patro1341c932006-01-25 12:02:40 -0800430* (deviceid : 1064R, PERC5) controllers
431*/
432
433/**
434 * megasas_enable_intr_xscale - Enables interrupts
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400435 * @regs: MFI register set
436 */
437static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530438megasas_enable_intr_xscale(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400439{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530440 struct megasas_register_set __iomem *regs;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500441
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530442 regs = instance->reg_set;
bo yang39a98552010-09-22 22:36:29 -0400443 writel(0, &(regs)->outbound_intr_mask);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400444
445 /* Dummy readl to force pci flush */
446 readl(&regs->outbound_intr_mask);
447}
448
449/**
Sumant Patrob274cab2006-10-03 12:52:12 -0700450 * megasas_disable_intr_xscale -Disables interrupt
451 * @regs: MFI register set
452 */
453static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530454megasas_disable_intr_xscale(struct megasas_instance *instance)
Sumant Patrob274cab2006-10-03 12:52:12 -0700455{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530456 struct megasas_register_set __iomem *regs;
Sumant Patrob274cab2006-10-03 12:52:12 -0700457 u32 mask = 0x1f;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500458
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530459 regs = instance->reg_set;
Sumant Patrob274cab2006-10-03 12:52:12 -0700460 writel(mask, &regs->outbound_intr_mask);
461 /* Dummy readl to force pci flush */
462 readl(&regs->outbound_intr_mask);
463}
464
465/**
Sumant Patro1341c932006-01-25 12:02:40 -0800466 * megasas_read_fw_status_reg_xscale - returns the current FW status value
467 * @regs: MFI register set
468 */
469static u32
Shivasharan Sde516372018-12-17 00:47:39 -0800470megasas_read_fw_status_reg_xscale(struct megasas_instance *instance)
Sumant Patro1341c932006-01-25 12:02:40 -0800471{
Shivasharan Sde516372018-12-17 00:47:39 -0800472 return readl(&instance->reg_set->outbound_msg_0);
Sumant Patro1341c932006-01-25 12:02:40 -0800473}
474/**
475 * megasas_clear_interrupt_xscale - Check & clear interrupt
476 * @regs: MFI register set
477 */
adam radford0d490162010-12-14 19:17:17 -0800478static int
Shivasharan Sde516372018-12-17 00:47:39 -0800479megasas_clear_intr_xscale(struct megasas_instance *instance)
Sumant Patro1341c932006-01-25 12:02:40 -0800480{
481 u32 status;
bo yang39a98552010-09-22 22:36:29 -0400482 u32 mfiStatus = 0;
Shivasharan Sde516372018-12-17 00:47:39 -0800483 struct megasas_register_set __iomem *regs;
484 regs = instance->reg_set;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500485
Sumant Patro1341c932006-01-25 12:02:40 -0800486 /*
487 * Check if it is our interrupt
488 */
489 status = readl(&regs->outbound_intr_status);
490
bo yang39a98552010-09-22 22:36:29 -0400491 if (status & MFI_OB_INTR_STATUS_MASK)
492 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
493 if (status & MFI_XSCALE_OMR0_CHANGE_INTERRUPT)
494 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
Sumant Patro1341c932006-01-25 12:02:40 -0800495
496 /*
497 * Clear the interrupt by writing back the same value
498 */
bo yang39a98552010-09-22 22:36:29 -0400499 if (mfiStatus)
500 writel(status, &regs->outbound_intr_status);
Sumant Patro1341c932006-01-25 12:02:40 -0800501
Yang, Bo06f579d2008-08-10 12:42:37 -0700502 /* Dummy readl to force pci flush */
503 readl(&regs->outbound_intr_status);
504
bo yang39a98552010-09-22 22:36:29 -0400505 return mfiStatus;
Sumant Patro1341c932006-01-25 12:02:40 -0800506}
507
508/**
509 * megasas_fire_cmd_xscale - Sends command to the FW
510 * @frame_phys_addr : Physical address of cmd
511 * @frame_count : Number of frames for the command
512 * @regs : MFI register set
513 */
adam radford0d490162010-12-14 19:17:17 -0800514static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600515megasas_fire_cmd_xscale(struct megasas_instance *instance,
516 dma_addr_t frame_phys_addr,
517 u32 frame_count,
518 struct megasas_register_set __iomem *regs)
Sumant Patro1341c932006-01-25 12:02:40 -0800519{
bo yang39a98552010-09-22 22:36:29 -0400520 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500521
bo yang39a98552010-09-22 22:36:29 -0400522 spin_lock_irqsave(&instance->hba_lock, flags);
Sumant Patro1341c932006-01-25 12:02:40 -0800523 writel((frame_phys_addr >> 3)|(frame_count),
524 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400525 spin_unlock_irqrestore(&instance->hba_lock, flags);
526}
527
528/**
529 * megasas_adp_reset_xscale - For controller reset
530 * @regs: MFI register set
531 */
532static int
533megasas_adp_reset_xscale(struct megasas_instance *instance,
534 struct megasas_register_set __iomem *regs)
535{
536 u32 i;
537 u32 pcidata;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500538
bo yang39a98552010-09-22 22:36:29 -0400539 writel(MFI_ADP_RESET, &regs->inbound_doorbell);
540
541 for (i = 0; i < 3; i++)
542 msleep(1000); /* sleep for 3 secs */
543 pcidata = 0;
544 pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata);
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500545 dev_notice(&instance->pdev->dev, "pcidata = %x\n", pcidata);
bo yang39a98552010-09-22 22:36:29 -0400546 if (pcidata & 0x2) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500547 dev_notice(&instance->pdev->dev, "mfi 1068 offset read=%x\n", pcidata);
bo yang39a98552010-09-22 22:36:29 -0400548 pcidata &= ~0x2;
549 pci_write_config_dword(instance->pdev,
550 MFI_1068_PCSR_OFFSET, pcidata);
551
552 for (i = 0; i < 2; i++)
553 msleep(1000); /* need to wait 2 secs again */
554
555 pcidata = 0;
556 pci_read_config_dword(instance->pdev,
557 MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata);
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500558 dev_notice(&instance->pdev->dev, "1068 offset handshake read=%x\n", pcidata);
bo yang39a98552010-09-22 22:36:29 -0400559 if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500560 dev_notice(&instance->pdev->dev, "1068 offset pcidt=%x\n", pcidata);
bo yang39a98552010-09-22 22:36:29 -0400561 pcidata = 0;
562 pci_write_config_dword(instance->pdev,
563 MFI_1068_FW_HANDSHAKE_OFFSET, pcidata);
564 }
565 }
566 return 0;
567}
568
569/**
570 * megasas_check_reset_xscale - For controller reset check
571 * @regs: MFI register set
572 */
573static int
574megasas_check_reset_xscale(struct megasas_instance *instance,
575 struct megasas_register_set __iomem *regs)
576{
Sumit Saxena8a01a412016-01-28 21:04:32 +0530577 if ((atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) &&
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +0530578 (le32_to_cpu(*instance->consumer) ==
579 MEGASAS_ADPRESET_INPROG_SIGN))
bo yang39a98552010-09-22 22:36:29 -0400580 return 1;
bo yang39a98552010-09-22 22:36:29 -0400581 return 0;
Sumant Patro1341c932006-01-25 12:02:40 -0800582}
583
584static struct megasas_instance_template megasas_instance_template_xscale = {
585
586 .fire_cmd = megasas_fire_cmd_xscale,
587 .enable_intr = megasas_enable_intr_xscale,
Sumant Patrob274cab2006-10-03 12:52:12 -0700588 .disable_intr = megasas_disable_intr_xscale,
Sumant Patro1341c932006-01-25 12:02:40 -0800589 .clear_intr = megasas_clear_intr_xscale,
590 .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
bo yang39a98552010-09-22 22:36:29 -0400591 .adp_reset = megasas_adp_reset_xscale,
592 .check_reset = megasas_check_reset_xscale,
adam radfordcd50ba82010-12-21 10:23:23 -0800593 .service_isr = megasas_isr,
594 .tasklet = megasas_complete_cmd_dpc,
595 .init_adapter = megasas_init_adapter_mfi,
596 .build_and_issue_cmd = megasas_build_and_issue_cmd,
597 .issue_dcmd = megasas_issue_dcmd,
Sumant Patro1341c932006-01-25 12:02:40 -0800598};
599
600/**
adam radford0d490162010-12-14 19:17:17 -0800601* This is the end of set of functions & definitions specific
Sumant Patro1341c932006-01-25 12:02:40 -0800602* to xscale (deviceid : 1064R, PERC5) controllers
603*/
604
605/**
adam radford0d490162010-12-14 19:17:17 -0800606* The following functions are defined for ppc (deviceid : 0x60)
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500607* controllers
Sumant Patrof9876f02006-02-03 15:34:35 -0800608*/
609
610/**
611 * megasas_enable_intr_ppc - Enables interrupts
612 * @regs: MFI register set
613 */
614static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530615megasas_enable_intr_ppc(struct megasas_instance *instance)
Sumant Patrof9876f02006-02-03 15:34:35 -0800616{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530617 struct megasas_register_set __iomem *regs;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500618
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530619 regs = instance->reg_set;
Sumant Patrof9876f02006-02-03 15:34:35 -0800620 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
adam radford0d490162010-12-14 19:17:17 -0800621
bo yang39a98552010-09-22 22:36:29 -0400622 writel(~0x80000000, &(regs)->outbound_intr_mask);
Sumant Patrof9876f02006-02-03 15:34:35 -0800623
624 /* Dummy readl to force pci flush */
625 readl(&regs->outbound_intr_mask);
626}
627
628/**
Sumant Patrob274cab2006-10-03 12:52:12 -0700629 * megasas_disable_intr_ppc - Disable interrupt
630 * @regs: MFI register set
631 */
632static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530633megasas_disable_intr_ppc(struct megasas_instance *instance)
Sumant Patrob274cab2006-10-03 12:52:12 -0700634{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530635 struct megasas_register_set __iomem *regs;
Sumant Patrob274cab2006-10-03 12:52:12 -0700636 u32 mask = 0xFFFFFFFF;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500637
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530638 regs = instance->reg_set;
Sumant Patrob274cab2006-10-03 12:52:12 -0700639 writel(mask, &regs->outbound_intr_mask);
640 /* Dummy readl to force pci flush */
641 readl(&regs->outbound_intr_mask);
642}
643
644/**
Sumant Patrof9876f02006-02-03 15:34:35 -0800645 * megasas_read_fw_status_reg_ppc - returns the current FW status value
646 * @regs: MFI register set
647 */
648static u32
Shivasharan Sde516372018-12-17 00:47:39 -0800649megasas_read_fw_status_reg_ppc(struct megasas_instance *instance)
Sumant Patrof9876f02006-02-03 15:34:35 -0800650{
Shivasharan Sde516372018-12-17 00:47:39 -0800651 return readl(&instance->reg_set->outbound_scratch_pad_0);
Sumant Patrof9876f02006-02-03 15:34:35 -0800652}
653
654/**
655 * megasas_clear_interrupt_ppc - Check & clear interrupt
656 * @regs: MFI register set
657 */
adam radford0d490162010-12-14 19:17:17 -0800658static int
Shivasharan Sde516372018-12-17 00:47:39 -0800659megasas_clear_intr_ppc(struct megasas_instance *instance)
Sumant Patrof9876f02006-02-03 15:34:35 -0800660{
adam radford3cc6851f92011-05-11 18:34:52 -0700661 u32 status, mfiStatus = 0;
Shivasharan Sde516372018-12-17 00:47:39 -0800662 struct megasas_register_set __iomem *regs;
663 regs = instance->reg_set;
adam radford3cc6851f92011-05-11 18:34:52 -0700664
Sumant Patrof9876f02006-02-03 15:34:35 -0800665 /*
666 * Check if it is our interrupt
667 */
668 status = readl(&regs->outbound_intr_status);
669
adam radford3cc6851f92011-05-11 18:34:52 -0700670 if (status & MFI_REPLY_1078_MESSAGE_INTERRUPT)
671 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
672
673 if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT)
674 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
Sumant Patrof9876f02006-02-03 15:34:35 -0800675
676 /*
677 * Clear the interrupt by writing back the same value
678 */
679 writel(status, &regs->outbound_doorbell_clear);
680
Yang, Bo06f579d2008-08-10 12:42:37 -0700681 /* Dummy readl to force pci flush */
682 readl(&regs->outbound_doorbell_clear);
683
adam radford3cc6851f92011-05-11 18:34:52 -0700684 return mfiStatus;
Sumant Patrof9876f02006-02-03 15:34:35 -0800685}
adam radford3cc6851f92011-05-11 18:34:52 -0700686
Sumant Patrof9876f02006-02-03 15:34:35 -0800687/**
688 * megasas_fire_cmd_ppc - Sends command to the FW
689 * @frame_phys_addr : Physical address of cmd
690 * @frame_count : Number of frames for the command
691 * @regs : MFI register set
692 */
adam radford0d490162010-12-14 19:17:17 -0800693static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600694megasas_fire_cmd_ppc(struct megasas_instance *instance,
695 dma_addr_t frame_phys_addr,
696 u32 frame_count,
697 struct megasas_register_set __iomem *regs)
Sumant Patrof9876f02006-02-03 15:34:35 -0800698{
bo yang39a98552010-09-22 22:36:29 -0400699 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500700
bo yang39a98552010-09-22 22:36:29 -0400701 spin_lock_irqsave(&instance->hba_lock, flags);
adam radford0d490162010-12-14 19:17:17 -0800702 writel((frame_phys_addr | (frame_count<<1))|1,
Sumant Patrof9876f02006-02-03 15:34:35 -0800703 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400704 spin_unlock_irqrestore(&instance->hba_lock, flags);
Sumant Patrof9876f02006-02-03 15:34:35 -0800705}
706
bo yang39a98552010-09-22 22:36:29 -0400707/**
bo yang39a98552010-09-22 22:36:29 -0400708 * megasas_check_reset_ppc - For controller reset check
709 * @regs: MFI register set
710 */
711static int
712megasas_check_reset_ppc(struct megasas_instance *instance,
713 struct megasas_register_set __iomem *regs)
714{
Sumit Saxena8a01a412016-01-28 21:04:32 +0530715 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
adam radford3cc6851f92011-05-11 18:34:52 -0700716 return 1;
717
bo yang39a98552010-09-22 22:36:29 -0400718 return 0;
719}
adam radford3cc6851f92011-05-11 18:34:52 -0700720
Sumant Patrof9876f02006-02-03 15:34:35 -0800721static struct megasas_instance_template megasas_instance_template_ppc = {
adam radford0d490162010-12-14 19:17:17 -0800722
Sumant Patrof9876f02006-02-03 15:34:35 -0800723 .fire_cmd = megasas_fire_cmd_ppc,
724 .enable_intr = megasas_enable_intr_ppc,
Sumant Patrob274cab2006-10-03 12:52:12 -0700725 .disable_intr = megasas_disable_intr_ppc,
Sumant Patrof9876f02006-02-03 15:34:35 -0800726 .clear_intr = megasas_clear_intr_ppc,
727 .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
adam radford3cc6851f92011-05-11 18:34:52 -0700728 .adp_reset = megasas_adp_reset_xscale,
bo yang39a98552010-09-22 22:36:29 -0400729 .check_reset = megasas_check_reset_ppc,
adam radfordcd50ba82010-12-21 10:23:23 -0800730 .service_isr = megasas_isr,
731 .tasklet = megasas_complete_cmd_dpc,
732 .init_adapter = megasas_init_adapter_mfi,
733 .build_and_issue_cmd = megasas_build_and_issue_cmd,
734 .issue_dcmd = megasas_issue_dcmd,
Sumant Patrof9876f02006-02-03 15:34:35 -0800735};
736
737/**
Yang, Bo87911122009-10-06 14:31:54 -0600738 * megasas_enable_intr_skinny - Enables interrupts
739 * @regs: MFI register set
740 */
741static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530742megasas_enable_intr_skinny(struct megasas_instance *instance)
Yang, Bo87911122009-10-06 14:31:54 -0600743{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530744 struct megasas_register_set __iomem *regs;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500745
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530746 regs = instance->reg_set;
Yang, Bo87911122009-10-06 14:31:54 -0600747 writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
748
749 writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
750
751 /* Dummy readl to force pci flush */
752 readl(&regs->outbound_intr_mask);
753}
754
755/**
756 * megasas_disable_intr_skinny - Disables interrupt
757 * @regs: MFI register set
758 */
759static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530760megasas_disable_intr_skinny(struct megasas_instance *instance)
Yang, Bo87911122009-10-06 14:31:54 -0600761{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530762 struct megasas_register_set __iomem *regs;
Yang, Bo87911122009-10-06 14:31:54 -0600763 u32 mask = 0xFFFFFFFF;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500764
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530765 regs = instance->reg_set;
Yang, Bo87911122009-10-06 14:31:54 -0600766 writel(mask, &regs->outbound_intr_mask);
767 /* Dummy readl to force pci flush */
768 readl(&regs->outbound_intr_mask);
769}
770
771/**
772 * megasas_read_fw_status_reg_skinny - returns the current FW status value
773 * @regs: MFI register set
774 */
775static u32
Shivasharan Sde516372018-12-17 00:47:39 -0800776megasas_read_fw_status_reg_skinny(struct megasas_instance *instance)
Yang, Bo87911122009-10-06 14:31:54 -0600777{
Shivasharan Sde516372018-12-17 00:47:39 -0800778 return readl(&instance->reg_set->outbound_scratch_pad_0);
Yang, Bo87911122009-10-06 14:31:54 -0600779}
780
781/**
782 * megasas_clear_interrupt_skinny - Check & clear interrupt
783 * @regs: MFI register set
784 */
785static int
Shivasharan Sde516372018-12-17 00:47:39 -0800786megasas_clear_intr_skinny(struct megasas_instance *instance)
Yang, Bo87911122009-10-06 14:31:54 -0600787{
788 u32 status;
adam radfordebf054b2011-02-24 20:57:15 -0800789 u32 mfiStatus = 0;
Shivasharan Sde516372018-12-17 00:47:39 -0800790 struct megasas_register_set __iomem *regs;
791 regs = instance->reg_set;
adam radfordebf054b2011-02-24 20:57:15 -0800792
Yang, Bo87911122009-10-06 14:31:54 -0600793 /*
794 * Check if it is our interrupt
795 */
796 status = readl(&regs->outbound_intr_status);
797
798 if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
bo yang39a98552010-09-22 22:36:29 -0400799 return 0;
Yang, Bo87911122009-10-06 14:31:54 -0600800 }
801
802 /*
adam radfordebf054b2011-02-24 20:57:15 -0800803 * Check if it is our interrupt
804 */
Shivasharan Sde516372018-12-17 00:47:39 -0800805 if ((megasas_read_fw_status_reg_skinny(instance) & MFI_STATE_MASK) ==
adam radfordebf054b2011-02-24 20:57:15 -0800806 MFI_STATE_FAULT) {
807 mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
808 } else
809 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
810
811 /*
Yang, Bo87911122009-10-06 14:31:54 -0600812 * Clear the interrupt by writing back the same value
813 */
814 writel(status, &regs->outbound_intr_status);
815
816 /*
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500817 * dummy read to flush PCI
818 */
Yang, Bo87911122009-10-06 14:31:54 -0600819 readl(&regs->outbound_intr_status);
820
adam radfordebf054b2011-02-24 20:57:15 -0800821 return mfiStatus;
Yang, Bo87911122009-10-06 14:31:54 -0600822}
823
824/**
825 * megasas_fire_cmd_skinny - Sends command to the FW
826 * @frame_phys_addr : Physical address of cmd
827 * @frame_count : Number of frames for the command
828 * @regs : MFI register set
829 */
830static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600831megasas_fire_cmd_skinny(struct megasas_instance *instance,
832 dma_addr_t frame_phys_addr,
833 u32 frame_count,
Yang, Bo87911122009-10-06 14:31:54 -0600834 struct megasas_register_set __iomem *regs)
835{
Yang, Bo0c79e682009-10-06 14:47:35 -0600836 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500837
bo yang39a98552010-09-22 22:36:29 -0400838 spin_lock_irqsave(&instance->hba_lock, flags);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +0530839 writel(upper_32_bits(frame_phys_addr),
840 &(regs)->inbound_high_queue_port);
841 writel((lower_32_bits(frame_phys_addr) | (frame_count<<1))|1,
842 &(regs)->inbound_low_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400843 spin_unlock_irqrestore(&instance->hba_lock, flags);
844}
845
846/**
bo yang39a98552010-09-22 22:36:29 -0400847 * megasas_check_reset_skinny - For controller reset check
848 * @regs: MFI register set
849 */
850static int
851megasas_check_reset_skinny(struct megasas_instance *instance,
852 struct megasas_register_set __iomem *regs)
853{
Sumit Saxena8a01a412016-01-28 21:04:32 +0530854 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
adam radford3cc6851f92011-05-11 18:34:52 -0700855 return 1;
856
bo yang39a98552010-09-22 22:36:29 -0400857 return 0;
Yang, Bo87911122009-10-06 14:31:54 -0600858}
859
860static struct megasas_instance_template megasas_instance_template_skinny = {
861
862 .fire_cmd = megasas_fire_cmd_skinny,
863 .enable_intr = megasas_enable_intr_skinny,
864 .disable_intr = megasas_disable_intr_skinny,
865 .clear_intr = megasas_clear_intr_skinny,
866 .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
adam radfordebf054b2011-02-24 20:57:15 -0800867 .adp_reset = megasas_adp_reset_gen2,
bo yang39a98552010-09-22 22:36:29 -0400868 .check_reset = megasas_check_reset_skinny,
adam radfordcd50ba82010-12-21 10:23:23 -0800869 .service_isr = megasas_isr,
870 .tasklet = megasas_complete_cmd_dpc,
871 .init_adapter = megasas_init_adapter_mfi,
872 .build_and_issue_cmd = megasas_build_and_issue_cmd,
873 .issue_dcmd = megasas_issue_dcmd,
Yang, Bo87911122009-10-06 14:31:54 -0600874};
875
876
877/**
Yang, Bo6610a6b2008-08-10 12:42:38 -0700878* The following functions are defined for gen2 (deviceid : 0x78 0x79)
879* controllers
880*/
881
882/**
883 * megasas_enable_intr_gen2 - Enables interrupts
884 * @regs: MFI register set
885 */
886static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530887megasas_enable_intr_gen2(struct megasas_instance *instance)
Yang, Bo6610a6b2008-08-10 12:42:38 -0700888{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530889 struct megasas_register_set __iomem *regs;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500890
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530891 regs = instance->reg_set;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700892 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
893
894 /* write ~0x00000005 (4 & 1) to the intr mask*/
895 writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
896
897 /* Dummy readl to force pci flush */
898 readl(&regs->outbound_intr_mask);
899}
900
901/**
902 * megasas_disable_intr_gen2 - Disables interrupt
903 * @regs: MFI register set
904 */
905static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530906megasas_disable_intr_gen2(struct megasas_instance *instance)
Yang, Bo6610a6b2008-08-10 12:42:38 -0700907{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530908 struct megasas_register_set __iomem *regs;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700909 u32 mask = 0xFFFFFFFF;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500910
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530911 regs = instance->reg_set;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700912 writel(mask, &regs->outbound_intr_mask);
913 /* Dummy readl to force pci flush */
914 readl(&regs->outbound_intr_mask);
915}
916
917/**
918 * megasas_read_fw_status_reg_gen2 - returns the current FW status value
919 * @regs: MFI register set
920 */
921static u32
Shivasharan Sde516372018-12-17 00:47:39 -0800922megasas_read_fw_status_reg_gen2(struct megasas_instance *instance)
Yang, Bo6610a6b2008-08-10 12:42:38 -0700923{
Shivasharan Sde516372018-12-17 00:47:39 -0800924 return readl(&instance->reg_set->outbound_scratch_pad_0);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700925}
926
927/**
928 * megasas_clear_interrupt_gen2 - Check & clear interrupt
929 * @regs: MFI register set
930 */
931static int
Shivasharan Sde516372018-12-17 00:47:39 -0800932megasas_clear_intr_gen2(struct megasas_instance *instance)
Yang, Bo6610a6b2008-08-10 12:42:38 -0700933{
934 u32 status;
bo yang39a98552010-09-22 22:36:29 -0400935 u32 mfiStatus = 0;
Shivasharan Sde516372018-12-17 00:47:39 -0800936 struct megasas_register_set __iomem *regs;
937 regs = instance->reg_set;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500938
Yang, Bo6610a6b2008-08-10 12:42:38 -0700939 /*
940 * Check if it is our interrupt
941 */
942 status = readl(&regs->outbound_intr_status);
943
Sumit.Saxena@lsi.comb5bccad2013-05-22 12:29:54 +0530944 if (status & MFI_INTR_FLAG_REPLY_MESSAGE) {
bo yang39a98552010-09-22 22:36:29 -0400945 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
946 }
947 if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) {
948 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
949 }
Yang, Bo6610a6b2008-08-10 12:42:38 -0700950
951 /*
952 * Clear the interrupt by writing back the same value
953 */
bo yang39a98552010-09-22 22:36:29 -0400954 if (mfiStatus)
955 writel(status, &regs->outbound_doorbell_clear);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700956
957 /* Dummy readl to force pci flush */
958 readl(&regs->outbound_intr_status);
959
bo yang39a98552010-09-22 22:36:29 -0400960 return mfiStatus;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700961}
962/**
963 * megasas_fire_cmd_gen2 - Sends command to the FW
964 * @frame_phys_addr : Physical address of cmd
965 * @frame_count : Number of frames for the command
966 * @regs : MFI register set
967 */
968static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600969megasas_fire_cmd_gen2(struct megasas_instance *instance,
970 dma_addr_t frame_phys_addr,
971 u32 frame_count,
Yang, Bo6610a6b2008-08-10 12:42:38 -0700972 struct megasas_register_set __iomem *regs)
973{
bo yang39a98552010-09-22 22:36:29 -0400974 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500975
bo yang39a98552010-09-22 22:36:29 -0400976 spin_lock_irqsave(&instance->hba_lock, flags);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700977 writel((frame_phys_addr | (frame_count<<1))|1,
978 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400979 spin_unlock_irqrestore(&instance->hba_lock, flags);
980}
981
982/**
983 * megasas_adp_reset_gen2 - For controller reset
984 * @regs: MFI register set
985 */
986static int
987megasas_adp_reset_gen2(struct megasas_instance *instance,
988 struct megasas_register_set __iomem *reg_set)
989{
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500990 u32 retry = 0 ;
991 u32 HostDiag;
992 u32 __iomem *seq_offset = &reg_set->seq_offset;
993 u32 __iomem *hostdiag_offset = &reg_set->host_diag;
bo yang39a98552010-09-22 22:36:29 -0400994
adam radfordebf054b2011-02-24 20:57:15 -0800995 if (instance->instancet == &megasas_instance_template_skinny) {
996 seq_offset = &reg_set->fusion_seq_offset;
997 hostdiag_offset = &reg_set->fusion_host_diag;
998 }
999
1000 writel(0, seq_offset);
1001 writel(4, seq_offset);
1002 writel(0xb, seq_offset);
1003 writel(2, seq_offset);
1004 writel(7, seq_offset);
1005 writel(0xd, seq_offset);
1006
bo yang39a98552010-09-22 22:36:29 -04001007 msleep(1000);
1008
adam radfordebf054b2011-02-24 20:57:15 -08001009 HostDiag = (u32)readl(hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -04001010
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001011 while (!(HostDiag & DIAG_WRITE_ENABLE)) {
bo yang39a98552010-09-22 22:36:29 -04001012 msleep(100);
adam radfordebf054b2011-02-24 20:57:15 -08001013 HostDiag = (u32)readl(hostdiag_offset);
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001014 dev_notice(&instance->pdev->dev, "RESETGEN2: retry=%x, hostdiag=%x\n",
bo yang39a98552010-09-22 22:36:29 -04001015 retry, HostDiag);
1016
1017 if (retry++ >= 100)
1018 return 1;
1019
1020 }
1021
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001022 dev_notice(&instance->pdev->dev, "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag);
bo yang39a98552010-09-22 22:36:29 -04001023
adam radfordebf054b2011-02-24 20:57:15 -08001024 writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -04001025
1026 ssleep(10);
1027
adam radfordebf054b2011-02-24 20:57:15 -08001028 HostDiag = (u32)readl(hostdiag_offset);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001029 while (HostDiag & DIAG_RESET_ADAPTER) {
bo yang39a98552010-09-22 22:36:29 -04001030 msleep(100);
adam radfordebf054b2011-02-24 20:57:15 -08001031 HostDiag = (u32)readl(hostdiag_offset);
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001032 dev_notice(&instance->pdev->dev, "RESET_GEN2: retry=%x, hostdiag=%x\n",
bo yang39a98552010-09-22 22:36:29 -04001033 retry, HostDiag);
1034
1035 if (retry++ >= 1000)
1036 return 1;
1037
1038 }
1039 return 0;
1040}
1041
1042/**
1043 * megasas_check_reset_gen2 - For controller reset check
1044 * @regs: MFI register set
1045 */
1046static int
1047megasas_check_reset_gen2(struct megasas_instance *instance,
1048 struct megasas_register_set __iomem *regs)
1049{
Sumit Saxena8a01a412016-01-28 21:04:32 +05301050 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
Yang, Bo707e09b2010-10-12 07:20:27 -06001051 return 1;
Yang, Bo707e09b2010-10-12 07:20:27 -06001052
bo yang39a98552010-09-22 22:36:29 -04001053 return 0;
Yang, Bo6610a6b2008-08-10 12:42:38 -07001054}
1055
1056static struct megasas_instance_template megasas_instance_template_gen2 = {
1057
1058 .fire_cmd = megasas_fire_cmd_gen2,
1059 .enable_intr = megasas_enable_intr_gen2,
1060 .disable_intr = megasas_disable_intr_gen2,
1061 .clear_intr = megasas_clear_intr_gen2,
1062 .read_fw_status_reg = megasas_read_fw_status_reg_gen2,
bo yang39a98552010-09-22 22:36:29 -04001063 .adp_reset = megasas_adp_reset_gen2,
1064 .check_reset = megasas_check_reset_gen2,
adam radfordcd50ba82010-12-21 10:23:23 -08001065 .service_isr = megasas_isr,
1066 .tasklet = megasas_complete_cmd_dpc,
1067 .init_adapter = megasas_init_adapter_mfi,
1068 .build_and_issue_cmd = megasas_build_and_issue_cmd,
1069 .issue_dcmd = megasas_issue_dcmd,
Yang, Bo6610a6b2008-08-10 12:42:38 -07001070};
1071
1072/**
Sumant Patrof9876f02006-02-03 15:34:35 -08001073* This is the end of set of functions & definitions
bo yang39a98552010-09-22 22:36:29 -04001074* specific to gen2 (deviceid : 0x78, 0x79) controllers
Sumant Patrof9876f02006-02-03 15:34:35 -08001075*/
1076
adam radford9c915a82010-12-21 13:34:31 -08001077/*
1078 * Template added for TB (Fusion)
1079 */
1080extern struct megasas_instance_template megasas_instance_template_fusion;
1081
Sumant Patrof9876f02006-02-03 15:34:35 -08001082/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001083 * megasas_issue_polled - Issues a polling command
1084 * @instance: Adapter soft state
adam radford0d490162010-12-14 19:17:17 -08001085 * @cmd: Command packet to be issued
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001086 *
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301087 * For polling, MFI requires the cmd_status to be set to MFI_STAT_INVALID_STATUS before posting.
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001088 */
adam radford9c915a82010-12-21 13:34:31 -08001089int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001090megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
1091{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001092 struct megasas_header *frame_hdr = &cmd->frame->hdr;
1093
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301094 frame_hdr->cmd_status = MFI_STAT_INVALID_STATUS;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301095 frame_hdr->flags |= cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001096
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001097 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301098 dev_err(&instance->pdev->dev, "Failed from %s %d\n",
1099 __func__, __LINE__);
1100 return DCMD_NOT_FIRED;
1101 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001102
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001103 instance->instancet->issue_dcmd(instance, cmd);
1104
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301105 return wait_and_poll(instance, cmd, instance->requestorId ?
1106 MEGASAS_ROUTINE_WAIT_TIME_VF : MFI_IO_TIMEOUT_SECS);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001107}
1108
1109/**
1110 * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds
1111 * @instance: Adapter soft state
1112 * @cmd: Command to be issued
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301113 * @timeout: Timeout in seconds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001114 *
1115 * This function waits on an event for the command to be returned from ISR.
Sumant Patro2a3681e2006-10-03 13:19:21 -07001116 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001117 * Used to issue ioctl commands.
1118 */
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05301119int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001120megasas_issue_blocked_cmd(struct megasas_instance *instance,
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301121 struct megasas_cmd *cmd, int timeout)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001122{
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301123 int ret = 0;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301124 cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001125
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001126 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301127 dev_err(&instance->pdev->dev, "Failed from %s %d\n",
1128 __func__, __LINE__);
1129 return DCMD_NOT_FIRED;
1130 }
1131
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001132 instance->instancet->issue_dcmd(instance, cmd);
1133
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301134 if (timeout) {
1135 ret = wait_event_timeout(instance->int_cmd_wait_q,
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301136 cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301137 if (!ret) {
Shivasharan S2ce43502019-05-07 10:05:38 -07001138 dev_err(&instance->pdev->dev,
1139 "DCMD(opcode: 0x%x) is timed out, func:%s\n",
1140 cmd->frame->dcmd.opcode, __func__);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301141 return DCMD_TIMEOUT;
1142 }
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301143 } else
1144 wait_event(instance->int_cmd_wait_q,
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301145 cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001146
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301147 return (cmd->cmd_status_drv == MFI_STAT_OK) ?
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301148 DCMD_SUCCESS : DCMD_FAILED;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001149}
1150
1151/**
1152 * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd
1153 * @instance: Adapter soft state
1154 * @cmd_to_abort: Previously issued cmd to be aborted
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301155 * @timeout: Timeout in seconds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001156 *
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301157 * MFI firmware can abort previously issued AEN comamnd (automatic event
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001158 * notification). The megasas_issue_blocked_abort_cmd() issues such abort
Sumant Patro2a3681e2006-10-03 13:19:21 -07001159 * cmd and waits for return status.
1160 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001161 */
1162static int
1163megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301164 struct megasas_cmd *cmd_to_abort, int timeout)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001165{
1166 struct megasas_cmd *cmd;
1167 struct megasas_abort_frame *abort_fr;
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301168 int ret = 0;
Shivasharan S2ce43502019-05-07 10:05:38 -07001169 u32 opcode;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001170
1171 cmd = megasas_get_cmd(instance);
1172
1173 if (!cmd)
1174 return -1;
1175
1176 abort_fr = &cmd->frame->abort;
1177
1178 /*
1179 * Prepare and issue the abort frame
1180 */
1181 abort_fr->cmd = MFI_CMD_ABORT;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301182 abort_fr->cmd_status = MFI_STAT_INVALID_STATUS;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301183 abort_fr->flags = cpu_to_le16(0);
1184 abort_fr->abort_context = cpu_to_le32(cmd_to_abort->index);
1185 abort_fr->abort_mfi_phys_addr_lo =
1186 cpu_to_le32(lower_32_bits(cmd_to_abort->frame_phys_addr));
1187 abort_fr->abort_mfi_phys_addr_hi =
1188 cpu_to_le32(upper_32_bits(cmd_to_abort->frame_phys_addr));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001189
1190 cmd->sync_cmd = 1;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301191 cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001192
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001193 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301194 dev_err(&instance->pdev->dev, "Failed from %s %d\n",
1195 __func__, __LINE__);
1196 return DCMD_NOT_FIRED;
1197 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001198
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001199 instance->instancet->issue_dcmd(instance, cmd);
1200
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301201 if (timeout) {
1202 ret = wait_event_timeout(instance->abort_cmd_wait_q,
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301203 cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ);
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301204 if (!ret) {
Shivasharan S2ce43502019-05-07 10:05:38 -07001205 opcode = cmd_to_abort->frame->dcmd.opcode;
1206 dev_err(&instance->pdev->dev,
1207 "Abort(to be aborted DCMD opcode: 0x%x) is timed out func:%s\n",
1208 opcode, __func__);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301209 return DCMD_TIMEOUT;
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301210 }
1211 } else
1212 wait_event(instance->abort_cmd_wait_q,
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301213 cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS);
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301214
bo yang39a98552010-09-22 22:36:29 -04001215 cmd->sync_cmd = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001216
1217 megasas_return_cmd(instance, cmd);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301218 return (cmd->cmd_status_drv == MFI_STAT_OK) ?
1219 DCMD_SUCCESS : DCMD_FAILED;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001220}
1221
1222/**
1223 * megasas_make_sgl32 - Prepares 32-bit SGL
1224 * @instance: Adapter soft state
1225 * @scp: SCSI command from the mid-layer
1226 * @mfi_sgl: SGL to be filled in
1227 *
1228 * If successful, this function returns the number of SG elements. Otherwise,
1229 * it returnes -1.
1230 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001231static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001232megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp,
1233 union megasas_sgl *mfi_sgl)
1234{
1235 int i;
1236 int sge_count;
1237 struct scatterlist *os_sgl;
1238
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001239 sge_count = scsi_dma_map(scp);
1240 BUG_ON(sge_count < 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001241
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001242 if (sge_count) {
1243 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301244 mfi_sgl->sge32[i].length = cpu_to_le32(sg_dma_len(os_sgl));
1245 mfi_sgl->sge32[i].phys_addr = cpu_to_le32(sg_dma_address(os_sgl));
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001246 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001247 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001248 return sge_count;
1249}
1250
1251/**
1252 * megasas_make_sgl64 - Prepares 64-bit SGL
1253 * @instance: Adapter soft state
1254 * @scp: SCSI command from the mid-layer
1255 * @mfi_sgl: SGL to be filled in
1256 *
1257 * If successful, this function returns the number of SG elements. Otherwise,
1258 * it returnes -1.
1259 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001260static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001261megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
1262 union megasas_sgl *mfi_sgl)
1263{
1264 int i;
1265 int sge_count;
1266 struct scatterlist *os_sgl;
1267
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001268 sge_count = scsi_dma_map(scp);
1269 BUG_ON(sge_count < 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001270
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001271 if (sge_count) {
1272 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301273 mfi_sgl->sge64[i].length = cpu_to_le32(sg_dma_len(os_sgl));
1274 mfi_sgl->sge64[i].phys_addr = cpu_to_le64(sg_dma_address(os_sgl));
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001275 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001276 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001277 return sge_count;
1278}
1279
Yang, Bof4c9a132009-10-06 14:43:28 -06001280/**
1281 * megasas_make_sgl_skinny - Prepares IEEE SGL
1282 * @instance: Adapter soft state
1283 * @scp: SCSI command from the mid-layer
1284 * @mfi_sgl: SGL to be filled in
1285 *
1286 * If successful, this function returns the number of SG elements. Otherwise,
1287 * it returnes -1.
1288 */
1289static int
1290megasas_make_sgl_skinny(struct megasas_instance *instance,
1291 struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
1292{
1293 int i;
1294 int sge_count;
1295 struct scatterlist *os_sgl;
1296
1297 sge_count = scsi_dma_map(scp);
1298
1299 if (sge_count) {
1300 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301301 mfi_sgl->sge_skinny[i].length =
1302 cpu_to_le32(sg_dma_len(os_sgl));
Yang, Bof4c9a132009-10-06 14:43:28 -06001303 mfi_sgl->sge_skinny[i].phys_addr =
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301304 cpu_to_le64(sg_dma_address(os_sgl));
1305 mfi_sgl->sge_skinny[i].flag = cpu_to_le32(0);
Yang, Bof4c9a132009-10-06 14:43:28 -06001306 }
1307 }
1308 return sge_count;
1309}
1310
Sumant Patrob1df99d2006-10-03 12:40:47 -07001311 /**
1312 * megasas_get_frame_count - Computes the number of frames
bo yangd532dbe2008-03-17 03:36:43 -04001313 * @frame_type : type of frame- io or pthru frame
Sumant Patrob1df99d2006-10-03 12:40:47 -07001314 * @sge_count : number of sg elements
1315 *
1316 * Returns the number of frames required for numnber of sge's (sge_count)
1317 */
1318
Yang, Bof4c9a132009-10-06 14:43:28 -06001319static u32 megasas_get_frame_count(struct megasas_instance *instance,
1320 u8 sge_count, u8 frame_type)
Sumant Patrob1df99d2006-10-03 12:40:47 -07001321{
1322 int num_cnt;
1323 int sge_bytes;
1324 u32 sge_sz;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001325 u32 frame_count = 0;
Sumant Patrob1df99d2006-10-03 12:40:47 -07001326
1327 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
1328 sizeof(struct megasas_sge32);
1329
Yang, Bof4c9a132009-10-06 14:43:28 -06001330 if (instance->flag_ieee) {
1331 sge_sz = sizeof(struct megasas_sge_skinny);
1332 }
1333
Sumant Patrob1df99d2006-10-03 12:40:47 -07001334 /*
bo yangd532dbe2008-03-17 03:36:43 -04001335 * Main frame can contain 2 SGEs for 64-bit SGLs and
1336 * 3 SGEs for 32-bit SGLs for ldio &
1337 * 1 SGEs for 64-bit SGLs and
1338 * 2 SGEs for 32-bit SGLs for pthru frame
1339 */
1340 if (unlikely(frame_type == PTHRU_FRAME)) {
Yang, Bof4c9a132009-10-06 14:43:28 -06001341 if (instance->flag_ieee == 1) {
1342 num_cnt = sge_count - 1;
1343 } else if (IS_DMA64)
bo yangd532dbe2008-03-17 03:36:43 -04001344 num_cnt = sge_count - 1;
1345 else
1346 num_cnt = sge_count - 2;
1347 } else {
Yang, Bof4c9a132009-10-06 14:43:28 -06001348 if (instance->flag_ieee == 1) {
1349 num_cnt = sge_count - 1;
1350 } else if (IS_DMA64)
bo yangd532dbe2008-03-17 03:36:43 -04001351 num_cnt = sge_count - 2;
1352 else
1353 num_cnt = sge_count - 3;
1354 }
Sumant Patrob1df99d2006-10-03 12:40:47 -07001355
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001356 if (num_cnt > 0) {
Sumant Patrob1df99d2006-10-03 12:40:47 -07001357 sge_bytes = sge_sz * num_cnt;
1358
1359 frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
1360 ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ;
1361 }
1362 /* Main frame */
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001363 frame_count += 1;
Sumant Patrob1df99d2006-10-03 12:40:47 -07001364
1365 if (frame_count > 7)
1366 frame_count = 8;
1367 return frame_count;
1368}
1369
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001370/**
1371 * megasas_build_dcdb - Prepares a direct cdb (DCDB) command
1372 * @instance: Adapter soft state
1373 * @scp: SCSI command
1374 * @cmd: Command to be prepared in
1375 *
1376 * This function prepares CDB commands. These are typcially pass-through
1377 * commands to the devices.
1378 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001379static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001380megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
1381 struct megasas_cmd *cmd)
1382{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001383 u32 is_logical;
1384 u32 device_id;
1385 u16 flags = 0;
1386 struct megasas_pthru_frame *pthru;
1387
Shivasharan S3cabd162017-02-10 00:59:05 -08001388 is_logical = MEGASAS_IS_LOGICAL(scp->device);
Sumit.Saxena@avagotech.com4a5c8142015-04-23 16:30:39 +05301389 device_id = MEGASAS_DEV_INDEX(scp);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001390 pthru = (struct megasas_pthru_frame *)cmd->frame;
1391
Christoph Hellwig60ee6522018-10-10 19:31:25 +02001392 if (scp->sc_data_direction == DMA_TO_DEVICE)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001393 flags = MFI_FRAME_DIR_WRITE;
Christoph Hellwig60ee6522018-10-10 19:31:25 +02001394 else if (scp->sc_data_direction == DMA_FROM_DEVICE)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001395 flags = MFI_FRAME_DIR_READ;
Christoph Hellwig60ee6522018-10-10 19:31:25 +02001396 else if (scp->sc_data_direction == DMA_NONE)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001397 flags = MFI_FRAME_DIR_NONE;
1398
Yang, Bof4c9a132009-10-06 14:43:28 -06001399 if (instance->flag_ieee == 1) {
1400 flags |= MFI_FRAME_IEEE;
1401 }
1402
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001403 /*
1404 * Prepare the DCDB frame
1405 */
1406 pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO;
1407 pthru->cmd_status = 0x0;
1408 pthru->scsi_status = 0x0;
1409 pthru->target_id = device_id;
1410 pthru->lun = scp->device->lun;
1411 pthru->cdb_len = scp->cmd_len;
1412 pthru->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07001413 pthru->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301414 pthru->flags = cpu_to_le16(flags);
1415 pthru->data_xfer_len = cpu_to_le32(scsi_bufflen(scp));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001416
1417 memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
1418
1419 /*
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001420 * If the command is for the tape device, set the
1421 * pthru timeout to the os layer timeout value.
1422 */
Yang, Bo8d568252009-10-06 14:12:21 -06001423 if (scp->device->type == TYPE_TAPE) {
1424 if ((scp->request->timeout / HZ) > 0xFFFF)
Christoph Hellwigc6f5bf82015-04-23 16:33:09 +05301425 pthru->timeout = cpu_to_le16(0xFFFF);
Yang, Bo8d568252009-10-06 14:12:21 -06001426 else
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301427 pthru->timeout = cpu_to_le16(scp->request->timeout / HZ);
Yang, Bo8d568252009-10-06 14:12:21 -06001428 }
1429
1430 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001431 * Construct SGL
1432 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001433 if (instance->flag_ieee == 1) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301434 pthru->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Yang, Bof4c9a132009-10-06 14:43:28 -06001435 pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
1436 &pthru->sgl);
1437 } else if (IS_DMA64) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301438 pthru->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001439 pthru->sge_count = megasas_make_sgl64(instance, scp,
1440 &pthru->sgl);
1441 } else
1442 pthru->sge_count = megasas_make_sgl32(instance, scp,
1443 &pthru->sgl);
1444
Yang, Bobdc6fb82009-12-06 08:30:19 -07001445 if (pthru->sge_count > instance->max_num_sge) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001446 dev_err(&instance->pdev->dev, "DCDB too many SGE NUM=%x\n",
Yang, Bobdc6fb82009-12-06 08:30:19 -07001447 pthru->sge_count);
1448 return 0;
1449 }
1450
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001451 /*
1452 * Sense info specific
1453 */
1454 pthru->sense_len = SCSI_SENSE_BUFFERSIZE;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301455 pthru->sense_buf_phys_addr_hi =
1456 cpu_to_le32(upper_32_bits(cmd->sense_phys_addr));
1457 pthru->sense_buf_phys_addr_lo =
1458 cpu_to_le32(lower_32_bits(cmd->sense_phys_addr));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001459
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001460 /*
1461 * Compute the total number of frames this command consumes. FW uses
1462 * this number to pull sufficient number of frames from host memory.
1463 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001464 cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
bo yangd532dbe2008-03-17 03:36:43 -04001465 PTHRU_FRAME);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001466
1467 return cmd->frame_count;
1468}
1469
1470/**
1471 * megasas_build_ldio - Prepares IOs to logical devices
1472 * @instance: Adapter soft state
1473 * @scp: SCSI command
Anand Gadiyarfd589a82009-07-16 17:13:03 +02001474 * @cmd: Command to be prepared
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001475 *
1476 * Frames (and accompanying SGLs) for regular SCSI IOs use this function.
1477 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001478static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001479megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
1480 struct megasas_cmd *cmd)
1481{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001482 u32 device_id;
1483 u8 sc = scp->cmnd[0];
1484 u16 flags = 0;
1485 struct megasas_io_frame *ldio;
1486
Sumit.Saxena@avagotech.com4a5c8142015-04-23 16:30:39 +05301487 device_id = MEGASAS_DEV_INDEX(scp);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001488 ldio = (struct megasas_io_frame *)cmd->frame;
1489
Christoph Hellwig60ee6522018-10-10 19:31:25 +02001490 if (scp->sc_data_direction == DMA_TO_DEVICE)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001491 flags = MFI_FRAME_DIR_WRITE;
Christoph Hellwig60ee6522018-10-10 19:31:25 +02001492 else if (scp->sc_data_direction == DMA_FROM_DEVICE)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001493 flags = MFI_FRAME_DIR_READ;
1494
Yang, Bof4c9a132009-10-06 14:43:28 -06001495 if (instance->flag_ieee == 1) {
1496 flags |= MFI_FRAME_IEEE;
1497 }
1498
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001499 /*
Sumant Patrob1df99d2006-10-03 12:40:47 -07001500 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001501 */
1502 ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ;
1503 ldio->cmd_status = 0x0;
1504 ldio->scsi_status = 0x0;
1505 ldio->target_id = device_id;
1506 ldio->timeout = 0;
1507 ldio->reserved_0 = 0;
1508 ldio->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301509 ldio->flags = cpu_to_le16(flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001510 ldio->start_lba_hi = 0;
1511 ldio->access_byte = (scp->cmd_len != 6) ? scp->cmnd[1] : 0;
1512
1513 /*
1514 * 6-byte READ(0x08) or WRITE(0x0A) cdb
1515 */
1516 if (scp->cmd_len == 6) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301517 ldio->lba_count = cpu_to_le32((u32) scp->cmnd[4]);
1518 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[1] << 16) |
1519 ((u32) scp->cmnd[2] << 8) |
1520 (u32) scp->cmnd[3]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001521
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301522 ldio->start_lba_lo &= cpu_to_le32(0x1FFFFF);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001523 }
1524
1525 /*
1526 * 10-byte READ(0x28) or WRITE(0x2A) cdb
1527 */
1528 else if (scp->cmd_len == 10) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301529 ldio->lba_count = cpu_to_le32((u32) scp->cmnd[8] |
1530 ((u32) scp->cmnd[7] << 8));
1531 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[2] << 24) |
1532 ((u32) scp->cmnd[3] << 16) |
1533 ((u32) scp->cmnd[4] << 8) |
1534 (u32) scp->cmnd[5]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001535 }
1536
1537 /*
1538 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
1539 */
1540 else if (scp->cmd_len == 12) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301541 ldio->lba_count = cpu_to_le32(((u32) scp->cmnd[6] << 24) |
1542 ((u32) scp->cmnd[7] << 16) |
1543 ((u32) scp->cmnd[8] << 8) |
1544 (u32) scp->cmnd[9]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001545
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301546 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[2] << 24) |
1547 ((u32) scp->cmnd[3] << 16) |
1548 ((u32) scp->cmnd[4] << 8) |
1549 (u32) scp->cmnd[5]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001550 }
1551
1552 /*
1553 * 16-byte READ(0x88) or WRITE(0x8A) cdb
1554 */
1555 else if (scp->cmd_len == 16) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301556 ldio->lba_count = cpu_to_le32(((u32) scp->cmnd[10] << 24) |
1557 ((u32) scp->cmnd[11] << 16) |
1558 ((u32) scp->cmnd[12] << 8) |
1559 (u32) scp->cmnd[13]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001560
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301561 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[6] << 24) |
1562 ((u32) scp->cmnd[7] << 16) |
1563 ((u32) scp->cmnd[8] << 8) |
1564 (u32) scp->cmnd[9]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001565
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301566 ldio->start_lba_hi = cpu_to_le32(((u32) scp->cmnd[2] << 24) |
1567 ((u32) scp->cmnd[3] << 16) |
1568 ((u32) scp->cmnd[4] << 8) |
1569 (u32) scp->cmnd[5]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001570
1571 }
1572
1573 /*
1574 * Construct SGL
1575 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001576 if (instance->flag_ieee) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301577 ldio->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Yang, Bof4c9a132009-10-06 14:43:28 -06001578 ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
1579 &ldio->sgl);
1580 } else if (IS_DMA64) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301581 ldio->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001582 ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
1583 } else
1584 ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
1585
Yang, Bobdc6fb82009-12-06 08:30:19 -07001586 if (ldio->sge_count > instance->max_num_sge) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001587 dev_err(&instance->pdev->dev, "build_ld_io: sge_count = %x\n",
Yang, Bobdc6fb82009-12-06 08:30:19 -07001588 ldio->sge_count);
1589 return 0;
1590 }
1591
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001592 /*
1593 * Sense info specific
1594 */
1595 ldio->sense_len = SCSI_SENSE_BUFFERSIZE;
1596 ldio->sense_buf_phys_addr_hi = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301597 ldio->sense_buf_phys_addr_lo = cpu_to_le32(cmd->sense_phys_addr);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001598
Sumant Patrob1df99d2006-10-03 12:40:47 -07001599 /*
1600 * Compute the total number of frames this command consumes. FW uses
1601 * this number to pull sufficient number of frames from host memory.
1602 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001603 cmd->frame_count = megasas_get_frame_count(instance,
1604 ldio->sge_count, IO_FRAME);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001605
1606 return cmd->frame_count;
1607}
1608
1609/**
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301610 * megasas_cmd_type - Checks if the cmd is for logical drive/sysPD
1611 * and whether it's RW or non RW
Sumant Patrocb59aa62006-01-25 11:53:25 -08001612 * @scmd: SCSI command
adam radford0d490162010-12-14 19:17:17 -08001613 *
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001614 */
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301615inline int megasas_cmd_type(struct scsi_cmnd *cmd)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001616{
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301617 int ret;
1618
Sumant Patrocb59aa62006-01-25 11:53:25 -08001619 switch (cmd->cmnd[0]) {
1620 case READ_10:
1621 case WRITE_10:
1622 case READ_12:
1623 case WRITE_12:
1624 case READ_6:
1625 case WRITE_6:
1626 case READ_16:
1627 case WRITE_16:
Shivasharan S3cabd162017-02-10 00:59:05 -08001628 ret = (MEGASAS_IS_LOGICAL(cmd->device)) ?
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301629 READ_WRITE_LDIO : READ_WRITE_SYSPDIO;
1630 break;
Sumant Patrocb59aa62006-01-25 11:53:25 -08001631 default:
Shivasharan S3cabd162017-02-10 00:59:05 -08001632 ret = (MEGASAS_IS_LOGICAL(cmd->device)) ?
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301633 NON_READ_WRITE_LDIO : NON_READ_WRITE_SYSPDIO;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001634 }
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301635 return ret;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001636}
1637
Sumant Patro658dced2006-10-03 13:09:14 -07001638 /**
1639 * megasas_dump_pending_frames - Dumps the frame address of all pending cmds
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001640 * in FW
Sumant Patro658dced2006-10-03 13:09:14 -07001641 * @instance: Adapter soft state
1642 */
1643static inline void
1644megasas_dump_pending_frames(struct megasas_instance *instance)
1645{
1646 struct megasas_cmd *cmd;
1647 int i,n;
1648 union megasas_sgl *mfi_sgl;
1649 struct megasas_io_frame *ldio;
1650 struct megasas_pthru_frame *pthru;
1651 u32 sgcount;
Shivasharan S50b7f5a2017-02-10 00:59:25 -08001652 u16 max_cmd = instance->max_fw_cmds;
Sumant Patro658dced2006-10-03 13:09:14 -07001653
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001654 dev_err(&instance->pdev->dev, "[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
1655 dev_err(&instance->pdev->dev, "[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding));
Sumant Patro658dced2006-10-03 13:09:14 -07001656 if (IS_DMA64)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001657 dev_err(&instance->pdev->dev, "[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no);
Sumant Patro658dced2006-10-03 13:09:14 -07001658 else
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001659 dev_err(&instance->pdev->dev, "[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);
Sumant Patro658dced2006-10-03 13:09:14 -07001660
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001661 dev_err(&instance->pdev->dev, "[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
Sumant Patro658dced2006-10-03 13:09:14 -07001662 for (i = 0; i < max_cmd; i++) {
1663 cmd = instance->cmd_list[i];
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001664 if (!cmd->scmd)
Sumant Patro658dced2006-10-03 13:09:14 -07001665 continue;
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001666 dev_err(&instance->pdev->dev, "[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301667 if (megasas_cmd_type(cmd->scmd) == READ_WRITE_LDIO) {
Sumant Patro658dced2006-10-03 13:09:14 -07001668 ldio = (struct megasas_io_frame *)cmd->frame;
1669 mfi_sgl = &ldio->sgl;
1670 sgcount = ldio->sge_count;
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001671 dev_err(&instance->pdev->dev, "[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x,"
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301672 " lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",
1673 instance->host->host_no, cmd->frame_count, ldio->cmd, ldio->target_id,
1674 le32_to_cpu(ldio->start_lba_lo), le32_to_cpu(ldio->start_lba_hi),
1675 le32_to_cpu(ldio->sense_buf_phys_addr_lo), sgcount);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001676 } else {
Sumant Patro658dced2006-10-03 13:09:14 -07001677 pthru = (struct megasas_pthru_frame *) cmd->frame;
1678 mfi_sgl = &pthru->sgl;
1679 sgcount = pthru->sge_count;
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001680 dev_err(&instance->pdev->dev, "[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, "
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301681 "lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",
1682 instance->host->host_no, cmd->frame_count, pthru->cmd, pthru->target_id,
1683 pthru->lun, pthru->cdb_len, le32_to_cpu(pthru->data_xfer_len),
1684 le32_to_cpu(pthru->sense_buf_phys_addr_lo), sgcount);
Sumant Patro658dced2006-10-03 13:09:14 -07001685 }
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001686 if (megasas_dbg_lvl & MEGASAS_DBG_LVL) {
1687 for (n = 0; n < sgcount; n++) {
1688 if (IS_DMA64)
1689 dev_err(&instance->pdev->dev, "sgl len : 0x%x, sgl addr : 0x%llx\n",
1690 le32_to_cpu(mfi_sgl->sge64[n].length),
1691 le64_to_cpu(mfi_sgl->sge64[n].phys_addr));
1692 else
1693 dev_err(&instance->pdev->dev, "sgl len : 0x%x, sgl addr : 0x%x\n",
1694 le32_to_cpu(mfi_sgl->sge32[n].length),
1695 le32_to_cpu(mfi_sgl->sge32[n].phys_addr));
Sumant Patro658dced2006-10-03 13:09:14 -07001696 }
1697 }
Sumant Patro658dced2006-10-03 13:09:14 -07001698 } /*for max_cmd*/
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001699 dev_err(&instance->pdev->dev, "[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
Sumant Patro658dced2006-10-03 13:09:14 -07001700 for (i = 0; i < max_cmd; i++) {
1701
1702 cmd = instance->cmd_list[i];
1703
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001704 if (cmd->sync_cmd == 1)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001705 dev_err(&instance->pdev->dev, "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
Sumant Patro658dced2006-10-03 13:09:14 -07001706 }
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001707 dev_err(&instance->pdev->dev, "[%d]: Dumping Done\n\n",instance->host->host_no);
Sumant Patro658dced2006-10-03 13:09:14 -07001708}
1709
adam radfordcd50ba82010-12-21 10:23:23 -08001710u32
1711megasas_build_and_issue_cmd(struct megasas_instance *instance,
1712 struct scsi_cmnd *scmd)
1713{
1714 struct megasas_cmd *cmd;
1715 u32 frame_count;
1716
1717 cmd = megasas_get_cmd(instance);
1718 if (!cmd)
1719 return SCSI_MLQUEUE_HOST_BUSY;
1720
1721 /*
1722 * Logical drive command
1723 */
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301724 if (megasas_cmd_type(scmd) == READ_WRITE_LDIO)
adam radfordcd50ba82010-12-21 10:23:23 -08001725 frame_count = megasas_build_ldio(instance, scmd, cmd);
1726 else
1727 frame_count = megasas_build_dcdb(instance, scmd, cmd);
1728
1729 if (!frame_count)
1730 goto out_return_cmd;
1731
1732 cmd->scmd = scmd;
1733 scmd->SCp.ptr = (char *)cmd;
1734
1735 /*
1736 * Issue the command to the FW
1737 */
1738 atomic_inc(&instance->fw_outstanding);
1739
1740 instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
1741 cmd->frame_count-1, instance->reg_set);
adam radfordcd50ba82010-12-21 10:23:23 -08001742
1743 return 0;
1744out_return_cmd:
1745 megasas_return_cmd(instance, cmd);
Sumit Saxenaf9a9dee2016-01-28 21:04:29 +05301746 return SCSI_MLQUEUE_HOST_BUSY;
adam radfordcd50ba82010-12-21 10:23:23 -08001747}
1748
1749
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001750/**
1751 * megasas_queue_command - Queue entry point
1752 * @scmd: SCSI command to be queued
1753 * @done: Callback entry point
1754 */
1755static int
Sumit.Saxena@avagotech.comfb1a24f2014-09-12 18:57:38 +05301756megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001757{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001758 struct megasas_instance *instance;
Sumit Saxena18365b12016-01-28 21:04:25 +05301759 struct MR_PRIV_DEVICE *mr_device_priv_data;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001760
1761 instance = (struct megasas_instance *)
1762 scmd->device->host->hostdata;
Sumant Patroaf37acf2007-02-14 12:34:46 -08001763
Sumit.Saxena@avagotech.comaa008322014-11-17 15:24:08 +05301764 if (instance->unload == 1) {
1765 scmd->result = DID_NO_CONNECT << 16;
1766 scmd->scsi_done(scmd);
1767 return 0;
1768 }
1769
bo yang39a98552010-09-22 22:36:29 -04001770 if (instance->issuepend_done == 0)
Sumant Patroaf37acf2007-02-14 12:34:46 -08001771 return SCSI_MLQUEUE_HOST_BUSY;
1772
Sumit.Saxena@lsi.comb09e66d2013-05-22 12:29:28 +05301773
adam radford229fe472014-03-10 02:51:56 -07001774 /* Check for an mpio path and adjust behavior */
Sumit Saxena8a01a412016-01-28 21:04:32 +05301775 if (atomic_read(&instance->adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) {
adam radford229fe472014-03-10 02:51:56 -07001776 if (megasas_check_mpio_paths(instance, scmd) ==
Shivasharan Sf55cf472017-02-10 00:59:07 -08001777 (DID_REQUEUE << 16)) {
adam radford229fe472014-03-10 02:51:56 -07001778 return SCSI_MLQUEUE_HOST_BUSY;
1779 } else {
adam radford229fe472014-03-10 02:51:56 -07001780 scmd->result = DID_NO_CONNECT << 16;
Sumit.Saxena@avagotech.comfb1a24f2014-09-12 18:57:38 +05301781 scmd->scsi_done(scmd);
adam radford229fe472014-03-10 02:51:56 -07001782 return 0;
1783 }
1784 }
1785
Sumit Saxena8a01a412016-01-28 21:04:32 +05301786 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
adam radford229fe472014-03-10 02:51:56 -07001787 scmd->result = DID_NO_CONNECT << 16;
Sumit.Saxena@avagotech.comfb1a24f2014-09-12 18:57:38 +05301788 scmd->scsi_done(scmd);
Sumit.Saxena@lsi.comb09e66d2013-05-22 12:29:28 +05301789 return 0;
1790 }
1791
Sumit Saxena18365b12016-01-28 21:04:25 +05301792 mr_device_priv_data = scmd->device->hostdata;
1793 if (!mr_device_priv_data) {
Sumit Saxena18365b12016-01-28 21:04:25 +05301794 scmd->result = DID_NO_CONNECT << 16;
1795 scmd->scsi_done(scmd);
1796 return 0;
1797 }
1798
Sumit Saxena8a01a412016-01-28 21:04:32 +05301799 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
bo yang39a98552010-09-22 22:36:29 -04001800 return SCSI_MLQUEUE_HOST_BUSY;
bo yang39a98552010-09-22 22:36:29 -04001801
Sumit Saxena8a01a412016-01-28 21:04:32 +05301802 if (mr_device_priv_data->tm_busy)
Sumit Saxena18365b12016-01-28 21:04:25 +05301803 return SCSI_MLQUEUE_DEVICE_BUSY;
Sumit Saxena18365b12016-01-28 21:04:25 +05301804
bo yang39a98552010-09-22 22:36:29 -04001805
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001806 scmd->result = 0;
1807
Shivasharan S3cabd162017-02-10 00:59:05 -08001808 if (MEGASAS_IS_LOGICAL(scmd->device) &&
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05301809 (scmd->device->id >= instance->fw_supported_vd_count ||
1810 scmd->device->lun)) {
Sumant Patrocb59aa62006-01-25 11:53:25 -08001811 scmd->result = DID_BAD_TARGET << 16;
1812 goto out_done;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001813 }
1814
Shivasharan S3cabd162017-02-10 00:59:05 -08001815 if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) &&
1816 MEGASAS_IS_LOGICAL(scmd->device) &&
1817 (!instance->fw_sync_cache_support)) {
Sumant Patro02b01e02007-02-14 13:00:55 -08001818 scmd->result = DID_OK << 16;
1819 goto out_done;
Sumant Patro02b01e02007-02-14 13:00:55 -08001820 }
1821
Sumit Saxenaf9a9dee2016-01-28 21:04:29 +05301822 return instance->instancet->build_and_issue_cmd(instance, scmd);
Sumant Patrocb59aa62006-01-25 11:53:25 -08001823
Sumant Patrocb59aa62006-01-25 11:53:25 -08001824 out_done:
Sumit.Saxena@avagotech.comfb1a24f2014-09-12 18:57:38 +05301825 scmd->scsi_done(scmd);
Sumant Patrocb59aa62006-01-25 11:53:25 -08001826 return 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001827}
1828
Yang, Bo044833b2009-10-06 14:33:06 -06001829static struct megasas_instance *megasas_lookup_instance(u16 host_no)
1830{
1831 int i;
1832
1833 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
1834
1835 if ((megasas_mgmt_info.instance[i]) &&
1836 (megasas_mgmt_info.instance[i]->host->host_no == host_no))
1837 return megasas_mgmt_info.instance[i];
1838 }
1839
1840 return NULL;
1841}
1842
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301843/*
Shivasharan S15dd0382017-02-10 00:59:10 -08001844* megasas_set_dynamic_target_properties -
1845* Device property set by driver may not be static and it is required to be
1846* updated after OCR
1847*
1848* set tm_capable.
1849* set dma alignment (only for eedp protection enable vd).
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301850*
1851* @sdev: OS provided scsi device
1852*
1853* Returns void
1854*/
Shivasharan Se9495e22018-06-04 03:45:12 -07001855void megasas_set_dynamic_target_properties(struct scsi_device *sdev,
1856 bool is_target_prop)
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301857{
Shivasharan S15dd0382017-02-10 00:59:10 -08001858 u16 pd_index = 0, ld;
1859 u32 device_id;
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301860 struct megasas_instance *instance;
1861 struct fusion_context *fusion;
Sumit Saxena18365b12016-01-28 21:04:25 +05301862 struct MR_PRIV_DEVICE *mr_device_priv_data;
1863 struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301864 struct MR_LD_RAID *raid;
1865 struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
1866
1867 instance = megasas_lookup_instance(sdev->host->host_no);
1868 fusion = instance->ctrl_context;
Sumit Saxena18365b12016-01-28 21:04:25 +05301869 mr_device_priv_data = sdev->hostdata;
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301870
Shivasharan Sed981b82017-02-10 00:59:06 -08001871 if (!fusion || !mr_device_priv_data)
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301872 return;
1873
Shivasharan Sed981b82017-02-10 00:59:06 -08001874 if (MEGASAS_IS_LOGICAL(sdev)) {
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301875 device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL)
1876 + sdev->id;
1877 local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
1878 ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
Shivasharan Sed981b82017-02-10 00:59:06 -08001879 if (ld >= instance->fw_supported_vd_count)
1880 return;
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301881 raid = MR_LdRaidGet(ld, local_map_ptr);
1882
1883 if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER)
Shivasharan S15dd0382017-02-10 00:59:10 -08001884 blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
Shivasharan Sed981b82017-02-10 00:59:06 -08001885
Sumit Saxena18365b12016-01-28 21:04:25 +05301886 mr_device_priv_data->is_tm_capable =
1887 raid->capability.tmCapable;
Shivasharan Sed981b82017-02-10 00:59:06 -08001888 } else if (instance->use_seqnum_jbod_fp) {
1889 pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
Shivasharan S15dd0382017-02-10 00:59:10 -08001890 sdev->id;
Shivasharan Sed981b82017-02-10 00:59:06 -08001891 pd_sync = (void *)fusion->pd_seq_sync
1892 [(instance->pd_seq_map_id - 1) & 1];
1893 mr_device_priv_data->is_tm_capable =
Shivasharan S15dd0382017-02-10 00:59:10 -08001894 pd_sync->seq[pd_index].capability.tmCapable;
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301895 }
Shivasharan Se9495e22018-06-04 03:45:12 -07001896
1897 if (is_target_prop && instance->tgt_prop->reset_tmo) {
1898 /*
1899 * If FW provides a target reset timeout value, driver will use
1900 * it. If not set, fallback to default values.
1901 */
1902 mr_device_priv_data->target_reset_tmo =
1903 min_t(u8, instance->max_reset_tmo,
1904 instance->tgt_prop->reset_tmo);
1905 mr_device_priv_data->task_abort_tmo = instance->task_abort_tmo;
1906 } else {
1907 mr_device_priv_data->target_reset_tmo =
1908 MEGASAS_DEFAULT_TM_TIMEOUT;
1909 mr_device_priv_data->task_abort_tmo =
1910 MEGASAS_DEFAULT_TM_TIMEOUT;
1911 }
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301912}
1913
Shivasharan S15dd0382017-02-10 00:59:10 -08001914/*
1915 * megasas_set_nvme_device_properties -
1916 * set nomerges=2
1917 * set virtual page boundary = 4K (current mr_nvme_pg_size is 4K).
1918 * set maximum io transfer = MDTS of NVME device provided by MR firmware.
1919 *
1920 * MR firmware provides value in KB. Caller of this function converts
1921 * kb into bytes.
1922 *
1923 * e.a MDTS=5 means 2^5 * nvme page size. (In case of 4K page size,
1924 * MR firmware provides value 128 as (32 * 4K) = 128K.
1925 *
1926 * @sdev: scsi device
1927 * @max_io_size: maximum io transfer size
1928 *
1929 */
1930static inline void
1931megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size)
Sumit Saxena2216c302016-01-28 21:04:26 +05301932{
Sumit Saxena2216c302016-01-28 21:04:26 +05301933 struct megasas_instance *instance;
Shivasharan S15dd0382017-02-10 00:59:10 -08001934 u32 mr_nvme_pg_size;
1935
1936 instance = (struct megasas_instance *)sdev->host->hostdata;
1937 mr_nvme_pg_size = max_t(u32, instance->nvme_page_size,
1938 MR_DEFAULT_NVME_PAGE_SIZE);
1939
1940 blk_queue_max_hw_sectors(sdev->request_queue, (max_io_size / 512));
1941
Bart Van Assche8b904b52018-03-07 17:10:10 -08001942 blk_queue_flag_set(QUEUE_FLAG_NOMERGES, sdev->request_queue);
Shivasharan S15dd0382017-02-10 00:59:10 -08001943 blk_queue_virt_boundary(sdev->request_queue, mr_nvme_pg_size - 1);
1944}
1945
1946
1947/*
1948 * megasas_set_static_target_properties -
1949 * Device property set by driver are static and it is not required to be
1950 * updated after OCR.
1951 *
1952 * set io timeout
1953 * set device queue depth
1954 * set nvme device properties. see - megasas_set_nvme_device_properties
1955 *
1956 * @sdev: scsi device
Shivasharan S96188a82017-02-10 00:59:11 -08001957 * @is_target_prop true, if fw provided target properties.
Shivasharan S15dd0382017-02-10 00:59:10 -08001958 */
Shivasharan S96188a82017-02-10 00:59:11 -08001959static void megasas_set_static_target_properties(struct scsi_device *sdev,
1960 bool is_target_prop)
Shivasharan S15dd0382017-02-10 00:59:10 -08001961{
Shivasharan S15dd0382017-02-10 00:59:10 -08001962 u8 interface_type;
1963 u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN;
1964 u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB;
Shivasharan S96188a82017-02-10 00:59:11 -08001965 u32 tgt_device_qd;
Shivasharan S15dd0382017-02-10 00:59:10 -08001966 struct megasas_instance *instance;
1967 struct MR_PRIV_DEVICE *mr_device_priv_data;
Sumit Saxena2216c302016-01-28 21:04:26 +05301968
1969 instance = megasas_lookup_instance(sdev->host->host_no);
Shivasharan S15dd0382017-02-10 00:59:10 -08001970 mr_device_priv_data = sdev->hostdata;
1971 interface_type = mr_device_priv_data->interface_type;
Sumit Saxena2216c302016-01-28 21:04:26 +05301972
Shivasharan S15dd0382017-02-10 00:59:10 -08001973 /*
1974 * The RAID firmware may require extended timeouts.
1975 */
1976 blk_queue_rq_timeout(sdev->request_queue, scmd_timeout * HZ);
Sumit Saxena2216c302016-01-28 21:04:26 +05301977
Shivasharan S15dd0382017-02-10 00:59:10 -08001978 switch (interface_type) {
1979 case SAS_PD:
1980 device_qd = MEGASAS_SAS_QD;
1981 break;
1982 case SATA_PD:
1983 device_qd = MEGASAS_SATA_QD;
1984 break;
1985 case NVME_PD:
1986 device_qd = MEGASAS_NVME_QD;
1987 break;
Sumit Saxena2216c302016-01-28 21:04:26 +05301988 }
Shivasharan S15dd0382017-02-10 00:59:10 -08001989
Shivasharan S96188a82017-02-10 00:59:11 -08001990 if (is_target_prop) {
1991 tgt_device_qd = le32_to_cpu(instance->tgt_prop->device_qdepth);
1992 if (tgt_device_qd &&
1993 (tgt_device_qd <= instance->host->can_queue))
1994 device_qd = tgt_device_qd;
1995
1996 /* max_io_size_kb will be set to non zero for
1997 * nvme based vd and syspd.
1998 */
1999 max_io_size_kb = le32_to_cpu(instance->tgt_prop->max_io_size_kb);
2000 }
2001
Shivasharan S15dd0382017-02-10 00:59:10 -08002002 if (instance->nvme_page_size && max_io_size_kb)
2003 megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 10));
2004
2005 scsi_change_queue_depth(sdev, device_qd);
2006
Sumit Saxena2216c302016-01-28 21:04:26 +05302007}
2008
Sumit Saxena18365b12016-01-28 21:04:25 +05302009
Christoph Hellwig147aab62006-02-17 12:13:48 +01002010static int megasas_slave_configure(struct scsi_device *sdev)
2011{
Sumit Saxenaaed335e2015-11-05 21:17:37 +05302012 u16 pd_index = 0;
2013 struct megasas_instance *instance;
Shivasharan S96188a82017-02-10 00:59:11 -08002014 int ret_target_prop = DCMD_FAILED;
2015 bool is_target_prop = false;
Sumit Saxenaaed335e2015-11-05 21:17:37 +05302016
2017 instance = megasas_lookup_instance(sdev->host->host_no);
Sumit Saxena30845582016-03-10 02:14:37 -08002018 if (instance->pd_list_not_supported) {
Shivasharan S3cabd162017-02-10 00:59:05 -08002019 if (!MEGASAS_IS_LOGICAL(sdev) && sdev->type == TYPE_DISK) {
Sumit Saxenaaed335e2015-11-05 21:17:37 +05302020 pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
2021 sdev->id;
2022 if (instance->pd_list[pd_index].driveState !=
2023 MR_PD_STATE_SYSTEM)
2024 return -ENXIO;
2025 }
2026 }
Sumit Saxena18365b12016-01-28 21:04:25 +05302027
Shivasharan S149c5752018-01-05 05:27:42 -08002028 mutex_lock(&instance->reset_mutex);
Shivasharan S15dd0382017-02-10 00:59:10 -08002029 /* Send DCMD to Firmware and cache the information */
2030 if ((instance->pd_info) && !MEGASAS_IS_LOGICAL(sdev))
2031 megasas_get_pd_info(instance, sdev);
2032
Shivasharan S96188a82017-02-10 00:59:11 -08002033 /* Some ventura firmware may not have instance->nvme_page_size set.
2034 * Do not send MR_DCMD_DRV_GET_TARGET_PROP
2035 */
2036 if ((instance->tgt_prop) && (instance->nvme_page_size))
2037 ret_target_prop = megasas_get_target_prop(instance, sdev);
2038
2039 is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false;
2040 megasas_set_static_target_properties(sdev, is_target_prop);
Shivasharan S15dd0382017-02-10 00:59:10 -08002041
Shivasharan S15dd0382017-02-10 00:59:10 -08002042 /* This sdev property may change post OCR */
Shivasharan Se9495e22018-06-04 03:45:12 -07002043 megasas_set_dynamic_target_properties(sdev, is_target_prop);
2044
2045 mutex_unlock(&instance->reset_mutex);
Sumit.Saxena@avagotech.com07e38d92014-09-12 18:57:13 +05302046
Yang, Bo044833b2009-10-06 14:33:06 -06002047 return 0;
2048}
2049
2050static int megasas_slave_alloc(struct scsi_device *sdev)
2051{
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002052 u16 pd_index = 0;
Yang, Bo044833b2009-10-06 14:33:06 -06002053 struct megasas_instance *instance ;
Sumit Saxena18365b12016-01-28 21:04:25 +05302054 struct MR_PRIV_DEVICE *mr_device_priv_data;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002055
Yang, Bo044833b2009-10-06 14:33:06 -06002056 instance = megasas_lookup_instance(sdev->host->host_no);
Shivasharan S3cabd162017-02-10 00:59:05 -08002057 if (!MEGASAS_IS_LOGICAL(sdev)) {
Yang, Bo044833b2009-10-06 14:33:06 -06002058 /*
2059 * Open the OS scan to the SYSTEM PD
2060 */
2061 pd_index =
2062 (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
2063 sdev->id;
Sumit Saxena30845582016-03-10 02:14:37 -08002064 if ((instance->pd_list_not_supported ||
2065 instance->pd_list[pd_index].driveState ==
Sumit Saxenaaed335e2015-11-05 21:17:37 +05302066 MR_PD_STATE_SYSTEM)) {
Sumit Saxena18365b12016-01-28 21:04:25 +05302067 goto scan_target;
Yang, Bo044833b2009-10-06 14:33:06 -06002068 }
2069 return -ENXIO;
2070 }
Sumit Saxena18365b12016-01-28 21:04:25 +05302071
2072scan_target:
2073 mr_device_priv_data = kzalloc(sizeof(*mr_device_priv_data),
2074 GFP_KERNEL);
2075 if (!mr_device_priv_data)
2076 return -ENOMEM;
2077 sdev->hostdata = mr_device_priv_data;
Shivasharan S49524b32017-03-10 03:22:13 -08002078
2079 atomic_set(&mr_device_priv_data->r1_ldio_hint,
2080 instance->r1_ldio_hint_default);
Christoph Hellwig147aab62006-02-17 12:13:48 +01002081 return 0;
2082}
2083
Sumit Saxena18365b12016-01-28 21:04:25 +05302084static void megasas_slave_destroy(struct scsi_device *sdev)
2085{
2086 kfree(sdev->hostdata);
2087 sdev->hostdata = NULL;
2088}
2089
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302090/*
2091* megasas_complete_outstanding_ioctls - Complete outstanding ioctls after a
2092* kill adapter
2093* @instance: Adapter soft state
2094*
2095*/
kbuild test robot6a6981f2015-04-23 16:33:23 +05302096static void megasas_complete_outstanding_ioctls(struct megasas_instance *instance)
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302097{
2098 int i;
2099 struct megasas_cmd *cmd_mfi;
2100 struct megasas_cmd_fusion *cmd_fusion;
2101 struct fusion_context *fusion = instance->ctrl_context;
2102
2103 /* Find all outstanding ioctls */
2104 if (fusion) {
2105 for (i = 0; i < instance->max_fw_cmds; i++) {
2106 cmd_fusion = fusion->cmd_list[i];
2107 if (cmd_fusion->sync_cmd_idx != (u32)ULONG_MAX) {
2108 cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
2109 if (cmd_mfi->sync_cmd &&
Shivasharan Seb3fe262017-08-23 04:47:04 -07002110 (cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)) {
2111 cmd_mfi->frame->hdr.cmd_status =
2112 MFI_STAT_WRONG_STATE;
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302113 megasas_complete_cmd(instance,
2114 cmd_mfi, DID_OK);
Shivasharan Seb3fe262017-08-23 04:47:04 -07002115 }
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302116 }
2117 }
2118 } else {
2119 for (i = 0; i < instance->max_fw_cmds; i++) {
2120 cmd_mfi = instance->cmd_list[i];
2121 if (cmd_mfi->sync_cmd && cmd_mfi->frame->hdr.cmd !=
2122 MFI_CMD_ABORT)
2123 megasas_complete_cmd(instance, cmd_mfi, DID_OK);
2124 }
2125 }
2126}
2127
2128
adam radford9c915a82010-12-21 13:34:31 -08002129void megaraid_sas_kill_hba(struct megasas_instance *instance)
bo yang39a98552010-09-22 22:36:29 -04002130{
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302131 /* Set critical error to block I/O & ioctls in case caller didn't */
Sumit Saxena8a01a412016-01-28 21:04:32 +05302132 atomic_set(&instance->adprecovery, MEGASAS_HW_CRITICAL_ERROR);
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302133 /* Wait 1 second to ensure IO or ioctls in build have posted */
2134 msleep(1000);
bo yang39a98552010-09-22 22:36:29 -04002135 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302136 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
Shivasharan Se7d36b82017-10-19 02:48:50 -07002137 (instance->adapter_type != MFI_SERIES)) {
Shivasharan S5acad9b2018-10-16 23:37:47 -07002138 if (!instance->requestorId) {
2139 writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
2140 /* Flush */
2141 readl(&instance->reg_set->doorbell);
2142 }
Sumit Saxena8f67c8c2016-01-28 21:14:25 +05302143 if (instance->requestorId && instance->peerIsPresent)
adam radford229fe472014-03-10 02:51:56 -07002144 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
bo yang39a98552010-09-22 22:36:29 -04002145 } else {
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302146 writel(MFI_STOP_ADP,
2147 &instance->reg_set->inbound_doorbell);
adam radford9c915a82010-12-21 13:34:31 -08002148 }
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302149 /* Complete outstanding ioctls when adapter is killed */
2150 megasas_complete_outstanding_ioctls(instance);
adam radford9c915a82010-12-21 13:34:31 -08002151}
2152
2153 /**
2154 * megasas_check_and_restore_queue_depth - Check if queue depth needs to be
2155 * restored to max value
2156 * @instance: Adapter soft state
2157 *
2158 */
2159void
2160megasas_check_and_restore_queue_depth(struct megasas_instance *instance)
2161{
2162 unsigned long flags;
Sumit.Saxena@avagotech.comae09a6c2015-01-05 20:06:23 +05302163
adam radford9c915a82010-12-21 13:34:31 -08002164 if (instance->flag & MEGASAS_FW_BUSY
adam radfordc5daa6a2012-07-17 18:20:03 -07002165 && time_after(jiffies, instance->last_time + 5 * HZ)
2166 && atomic_read(&instance->fw_outstanding) <
2167 instance->throttlequeuedepth + 1) {
adam radford9c915a82010-12-21 13:34:31 -08002168
2169 spin_lock_irqsave(instance->host->host_lock, flags);
2170 instance->flag &= ~MEGASAS_FW_BUSY;
adam radford9c915a82010-12-21 13:34:31 -08002171
Sumit Saxena308ec452016-01-28 21:04:30 +05302172 instance->host->can_queue = instance->cur_can_queue;
adam radford9c915a82010-12-21 13:34:31 -08002173 spin_unlock_irqrestore(instance->host->host_lock, flags);
bo yang39a98552010-09-22 22:36:29 -04002174 }
2175}
2176
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002177/**
bo yang7343eb62007-11-09 04:35:44 -05002178 * megasas_complete_cmd_dpc - Returns FW's controller structure
2179 * @instance_addr: Address of adapter soft state
2180 *
2181 * Tasklet to complete cmds
2182 */
2183static void megasas_complete_cmd_dpc(unsigned long instance_addr)
2184{
2185 u32 producer;
2186 u32 consumer;
2187 u32 context;
2188 struct megasas_cmd *cmd;
2189 struct megasas_instance *instance =
2190 (struct megasas_instance *)instance_addr;
2191 unsigned long flags;
2192
2193 /* If we have already declared adapter dead, donot complete cmds */
Sumit Saxena8a01a412016-01-28 21:04:32 +05302194 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
bo yang7343eb62007-11-09 04:35:44 -05002195 return;
2196
2197 spin_lock_irqsave(&instance->completion_lock, flags);
2198
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302199 producer = le32_to_cpu(*instance->producer);
2200 consumer = le32_to_cpu(*instance->consumer);
bo yang7343eb62007-11-09 04:35:44 -05002201
2202 while (consumer != producer) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302203 context = le32_to_cpu(instance->reply_queue[consumer]);
bo yang39a98552010-09-22 22:36:29 -04002204 if (context >= instance->max_fw_cmds) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002205 dev_err(&instance->pdev->dev, "Unexpected context value %x\n",
bo yang39a98552010-09-22 22:36:29 -04002206 context);
2207 BUG();
2208 }
bo yang7343eb62007-11-09 04:35:44 -05002209
2210 cmd = instance->cmd_list[context];
2211
2212 megasas_complete_cmd(instance, cmd, DID_OK);
2213
2214 consumer++;
2215 if (consumer == (instance->max_fw_cmds + 1)) {
2216 consumer = 0;
2217 }
2218 }
2219
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302220 *instance->consumer = cpu_to_le32(producer);
bo yang7343eb62007-11-09 04:35:44 -05002221
2222 spin_unlock_irqrestore(&instance->completion_lock, flags);
2223
2224 /*
2225 * Check if we can restore can_queue
2226 */
adam radford9c915a82010-12-21 13:34:31 -08002227 megasas_check_and_restore_queue_depth(instance);
bo yang7343eb62007-11-09 04:35:44 -05002228}
2229
Kees Cookc251a7b2017-10-22 15:30:04 -07002230static void megasas_sriov_heartbeat_handler(struct timer_list *t);
2231
adam radford229fe472014-03-10 02:51:56 -07002232/**
Kees Cookc251a7b2017-10-22 15:30:04 -07002233 * megasas_start_timer - Initializes sriov heartbeat timer object
adam radford229fe472014-03-10 02:51:56 -07002234 * @instance: Adapter soft state
adam radford229fe472014-03-10 02:51:56 -07002235 *
2236 */
Kees Cookc251a7b2017-10-22 15:30:04 -07002237void megasas_start_timer(struct megasas_instance *instance)
adam radford229fe472014-03-10 02:51:56 -07002238{
Kees Cookc251a7b2017-10-22 15:30:04 -07002239 struct timer_list *timer = &instance->sriov_heartbeat_timer;
2240
2241 timer_setup(timer, megasas_sriov_heartbeat_handler, 0);
2242 timer->expires = jiffies + MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF;
adam radford229fe472014-03-10 02:51:56 -07002243 add_timer(timer);
2244}
2245
Yang, Bo707e09b2010-10-12 07:20:27 -06002246static void
2247megasas_internal_reset_defer_cmds(struct megasas_instance *instance);
2248
2249static void
2250process_fw_state_change_wq(struct work_struct *work);
2251
YueHaibing6764f512019-07-02 21:01:14 +08002252static void megasas_do_ocr(struct megasas_instance *instance)
Yang, Bo707e09b2010-10-12 07:20:27 -06002253{
2254 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
2255 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
2256 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302257 *instance->consumer = cpu_to_le32(MEGASAS_ADPRESET_INPROG_SIGN);
Yang, Bo707e09b2010-10-12 07:20:27 -06002258 }
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05302259 instance->instancet->disable_intr(instance);
Sumit Saxena8a01a412016-01-28 21:04:32 +05302260 atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_INFAULT);
Yang, Bo707e09b2010-10-12 07:20:27 -06002261 instance->issuepend_done = 0;
2262
2263 atomic_set(&instance->fw_outstanding, 0);
2264 megasas_internal_reset_defer_cmds(instance);
2265 process_fw_state_change_wq(&instance->work_init);
2266}
2267
Adam Radford4cbfea82014-07-09 15:17:56 -07002268static int megasas_get_ld_vf_affiliation_111(struct megasas_instance *instance,
2269 int initial)
adam radford229fe472014-03-10 02:51:56 -07002270{
2271 struct megasas_cmd *cmd;
2272 struct megasas_dcmd_frame *dcmd;
adam radford229fe472014-03-10 02:51:56 -07002273 struct MR_LD_VF_AFFILIATION_111 *new_affiliation_111 = NULL;
adam radford229fe472014-03-10 02:51:56 -07002274 dma_addr_t new_affiliation_111_h;
2275 int ld, retval = 0;
2276 u8 thisVf;
2277
2278 cmd = megasas_get_cmd(instance);
2279
2280 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002281 dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_get_ld_vf_affiliation_111:"
2282 "Failed to get cmd for scsi%d\n",
adam radford229fe472014-03-10 02:51:56 -07002283 instance->host->host_no);
2284 return -ENOMEM;
2285 }
2286
2287 dcmd = &cmd->frame->dcmd;
2288
Adam Radford4cbfea82014-07-09 15:17:56 -07002289 if (!instance->vf_affiliation_111) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002290 dev_warn(&instance->pdev->dev, "SR-IOV: Couldn't get LD/VF "
2291 "affiliation for scsi%d\n", instance->host->host_no);
adam radford229fe472014-03-10 02:51:56 -07002292 megasas_return_cmd(instance, cmd);
2293 return -ENOMEM;
2294 }
2295
2296 if (initial)
adam radford229fe472014-03-10 02:51:56 -07002297 memset(instance->vf_affiliation_111, 0,
2298 sizeof(struct MR_LD_VF_AFFILIATION_111));
adam radford229fe472014-03-10 02:51:56 -07002299 else {
Adam Radford4cbfea82014-07-09 15:17:56 -07002300 new_affiliation_111 =
Luis Chamberlain750afb02019-01-04 09:23:09 +01002301 dma_alloc_coherent(&instance->pdev->dev,
2302 sizeof(struct MR_LD_VF_AFFILIATION_111),
2303 &new_affiliation_111_h, GFP_KERNEL);
Adam Radford4cbfea82014-07-09 15:17:56 -07002304 if (!new_affiliation_111) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002305 dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate "
2306 "memory for new affiliation for scsi%d\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07002307 instance->host->host_no);
adam radford229fe472014-03-10 02:51:56 -07002308 megasas_return_cmd(instance, cmd);
2309 return -ENOMEM;
2310 }
adam radford229fe472014-03-10 02:51:56 -07002311 }
2312
2313 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2314
2315 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05302316 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
adam radford229fe472014-03-10 02:51:56 -07002317 dcmd->sge_count = 1;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302318 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_BOTH);
adam radford229fe472014-03-10 02:51:56 -07002319 dcmd->timeout = 0;
2320 dcmd->pad_0 = 0;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302321 dcmd->data_xfer_len =
2322 cpu_to_le32(sizeof(struct MR_LD_VF_AFFILIATION_111));
2323 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_VF_MAP_GET_ALL_LDS_111);
adam radford229fe472014-03-10 02:51:56 -07002324
Adam Radford4cbfea82014-07-09 15:17:56 -07002325 if (initial)
2326 dcmd->sgl.sge32[0].phys_addr =
Christoph Hellwig2213a462015-04-23 16:33:54 +05302327 cpu_to_le32(instance->vf_affiliation_111_h);
adam radford229fe472014-03-10 02:51:56 -07002328 else
Christoph Hellwig2213a462015-04-23 16:33:54 +05302329 dcmd->sgl.sge32[0].phys_addr =
2330 cpu_to_le32(new_affiliation_111_h);
Adam Radford4cbfea82014-07-09 15:17:56 -07002331
Christoph Hellwig2213a462015-04-23 16:33:54 +05302332 dcmd->sgl.sge32[0].length = cpu_to_le32(
2333 sizeof(struct MR_LD_VF_AFFILIATION_111));
adam radford229fe472014-03-10 02:51:56 -07002334
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002335 dev_warn(&instance->pdev->dev, "SR-IOV: Getting LD/VF affiliation for "
adam radford229fe472014-03-10 02:51:56 -07002336 "scsi%d\n", instance->host->host_no);
2337
Sumit Saxena6d40afb2016-01-28 21:04:23 +05302338 if (megasas_issue_blocked_cmd(instance, cmd, 0) != DCMD_SUCCESS) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002339 dev_warn(&instance->pdev->dev, "SR-IOV: LD/VF affiliation DCMD"
2340 " failed with status 0x%x for scsi%d\n",
adam radford229fe472014-03-10 02:51:56 -07002341 dcmd->cmd_status, instance->host->host_no);
2342 retval = 1; /* Do a scan if we couldn't get affiliation */
2343 goto out;
2344 }
2345
2346 if (!initial) {
Adam Radford4cbfea82014-07-09 15:17:56 -07002347 thisVf = new_affiliation_111->thisVf;
2348 for (ld = 0 ; ld < new_affiliation_111->vdCount; ld++)
2349 if (instance->vf_affiliation_111->map[ld].policy[thisVf] !=
2350 new_affiliation_111->map[ld].policy[thisVf]) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002351 dev_warn(&instance->pdev->dev, "SR-IOV: "
2352 "Got new LD/VF affiliation for scsi%d\n",
adam radford229fe472014-03-10 02:51:56 -07002353 instance->host->host_no);
Adam Radford4cbfea82014-07-09 15:17:56 -07002354 memcpy(instance->vf_affiliation_111,
2355 new_affiliation_111,
2356 sizeof(struct MR_LD_VF_AFFILIATION_111));
adam radford229fe472014-03-10 02:51:56 -07002357 retval = 1;
2358 goto out;
2359 }
Adam Radford4cbfea82014-07-09 15:17:56 -07002360 }
2361out:
2362 if (new_affiliation_111) {
Christoph Hellwig60ee6522018-10-10 19:31:25 +02002363 dma_free_coherent(&instance->pdev->dev,
Adam Radford4cbfea82014-07-09 15:17:56 -07002364 sizeof(struct MR_LD_VF_AFFILIATION_111),
2365 new_affiliation_111,
2366 new_affiliation_111_h);
2367 }
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05302368
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05302369 megasas_return_cmd(instance, cmd);
Adam Radford4cbfea82014-07-09 15:17:56 -07002370
2371 return retval;
2372}
2373
2374static int megasas_get_ld_vf_affiliation_12(struct megasas_instance *instance,
2375 int initial)
2376{
2377 struct megasas_cmd *cmd;
2378 struct megasas_dcmd_frame *dcmd;
2379 struct MR_LD_VF_AFFILIATION *new_affiliation = NULL;
2380 struct MR_LD_VF_MAP *newmap = NULL, *savedmap = NULL;
2381 dma_addr_t new_affiliation_h;
2382 int i, j, retval = 0, found = 0, doscan = 0;
2383 u8 thisVf;
2384
2385 cmd = megasas_get_cmd(instance);
2386
2387 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002388 dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_get_ld_vf_affiliation12: "
2389 "Failed to get cmd for scsi%d\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07002390 instance->host->host_no);
2391 return -ENOMEM;
2392 }
2393
2394 dcmd = &cmd->frame->dcmd;
2395
2396 if (!instance->vf_affiliation) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002397 dev_warn(&instance->pdev->dev, "SR-IOV: Couldn't get LD/VF "
2398 "affiliation for scsi%d\n", instance->host->host_no);
Adam Radford4cbfea82014-07-09 15:17:56 -07002399 megasas_return_cmd(instance, cmd);
2400 return -ENOMEM;
2401 }
2402
2403 if (initial)
2404 memset(instance->vf_affiliation, 0, (MAX_LOGICAL_DRIVES + 1) *
2405 sizeof(struct MR_LD_VF_AFFILIATION));
2406 else {
2407 new_affiliation =
Luis Chamberlain750afb02019-01-04 09:23:09 +01002408 dma_alloc_coherent(&instance->pdev->dev,
2409 (MAX_LOGICAL_DRIVES + 1) * sizeof(struct MR_LD_VF_AFFILIATION),
2410 &new_affiliation_h, GFP_KERNEL);
Adam Radford4cbfea82014-07-09 15:17:56 -07002411 if (!new_affiliation) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002412 dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate "
2413 "memory for new affiliation for scsi%d\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07002414 instance->host->host_no);
2415 megasas_return_cmd(instance, cmd);
2416 return -ENOMEM;
2417 }
Adam Radford4cbfea82014-07-09 15:17:56 -07002418 }
2419
2420 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2421
2422 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05302423 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
Adam Radford4cbfea82014-07-09 15:17:56 -07002424 dcmd->sge_count = 1;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302425 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_BOTH);
Adam Radford4cbfea82014-07-09 15:17:56 -07002426 dcmd->timeout = 0;
2427 dcmd->pad_0 = 0;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302428 dcmd->data_xfer_len = cpu_to_le32((MAX_LOGICAL_DRIVES + 1) *
2429 sizeof(struct MR_LD_VF_AFFILIATION));
2430 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_VF_MAP_GET_ALL_LDS);
Adam Radford4cbfea82014-07-09 15:17:56 -07002431
2432 if (initial)
Christoph Hellwig2213a462015-04-23 16:33:54 +05302433 dcmd->sgl.sge32[0].phys_addr =
2434 cpu_to_le32(instance->vf_affiliation_h);
Adam Radford4cbfea82014-07-09 15:17:56 -07002435 else
Christoph Hellwig2213a462015-04-23 16:33:54 +05302436 dcmd->sgl.sge32[0].phys_addr =
2437 cpu_to_le32(new_affiliation_h);
Adam Radford4cbfea82014-07-09 15:17:56 -07002438
Christoph Hellwig2213a462015-04-23 16:33:54 +05302439 dcmd->sgl.sge32[0].length = cpu_to_le32((MAX_LOGICAL_DRIVES + 1) *
2440 sizeof(struct MR_LD_VF_AFFILIATION));
Adam Radford4cbfea82014-07-09 15:17:56 -07002441
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002442 dev_warn(&instance->pdev->dev, "SR-IOV: Getting LD/VF affiliation for "
Adam Radford4cbfea82014-07-09 15:17:56 -07002443 "scsi%d\n", instance->host->host_no);
2444
Adam Radford4cbfea82014-07-09 15:17:56 -07002445
Sumit Saxena6d40afb2016-01-28 21:04:23 +05302446 if (megasas_issue_blocked_cmd(instance, cmd, 0) != DCMD_SUCCESS) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002447 dev_warn(&instance->pdev->dev, "SR-IOV: LD/VF affiliation DCMD"
2448 " failed with status 0x%x for scsi%d\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07002449 dcmd->cmd_status, instance->host->host_no);
2450 retval = 1; /* Do a scan if we couldn't get affiliation */
2451 goto out;
2452 }
2453
2454 if (!initial) {
2455 if (!new_affiliation->ldCount) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002456 dev_warn(&instance->pdev->dev, "SR-IOV: Got new LD/VF "
2457 "affiliation for passive path for scsi%d\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07002458 instance->host->host_no);
2459 retval = 1;
2460 goto out;
2461 }
2462 newmap = new_affiliation->map;
2463 savedmap = instance->vf_affiliation->map;
2464 thisVf = new_affiliation->thisVf;
2465 for (i = 0 ; i < new_affiliation->ldCount; i++) {
2466 found = 0;
2467 for (j = 0; j < instance->vf_affiliation->ldCount;
2468 j++) {
2469 if (newmap->ref.targetId ==
2470 savedmap->ref.targetId) {
2471 found = 1;
2472 if (newmap->policy[thisVf] !=
2473 savedmap->policy[thisVf]) {
2474 doscan = 1;
2475 goto out;
2476 }
adam radford229fe472014-03-10 02:51:56 -07002477 }
2478 savedmap = (struct MR_LD_VF_MAP *)
2479 ((unsigned char *)savedmap +
2480 savedmap->size);
Adam Radford4cbfea82014-07-09 15:17:56 -07002481 }
2482 if (!found && newmap->policy[thisVf] !=
2483 MR_LD_ACCESS_HIDDEN) {
2484 doscan = 1;
2485 goto out;
2486 }
2487 newmap = (struct MR_LD_VF_MAP *)
2488 ((unsigned char *)newmap + newmap->size);
2489 }
2490
2491 newmap = new_affiliation->map;
2492 savedmap = instance->vf_affiliation->map;
2493
2494 for (i = 0 ; i < instance->vf_affiliation->ldCount; i++) {
2495 found = 0;
2496 for (j = 0 ; j < new_affiliation->ldCount; j++) {
2497 if (savedmap->ref.targetId ==
2498 newmap->ref.targetId) {
2499 found = 1;
2500 if (savedmap->policy[thisVf] !=
2501 newmap->policy[thisVf]) {
2502 doscan = 1;
2503 goto out;
2504 }
2505 }
adam radford229fe472014-03-10 02:51:56 -07002506 newmap = (struct MR_LD_VF_MAP *)
2507 ((unsigned char *)newmap +
2508 newmap->size);
2509 }
Adam Radford4cbfea82014-07-09 15:17:56 -07002510 if (!found && savedmap->policy[thisVf] !=
2511 MR_LD_ACCESS_HIDDEN) {
2512 doscan = 1;
2513 goto out;
2514 }
2515 savedmap = (struct MR_LD_VF_MAP *)
2516 ((unsigned char *)savedmap +
2517 savedmap->size);
adam radford229fe472014-03-10 02:51:56 -07002518 }
2519 }
2520out:
Adam Radford4cbfea82014-07-09 15:17:56 -07002521 if (doscan) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002522 dev_warn(&instance->pdev->dev, "SR-IOV: Got new LD/VF "
2523 "affiliation for scsi%d\n", instance->host->host_no);
Adam Radford4cbfea82014-07-09 15:17:56 -07002524 memcpy(instance->vf_affiliation, new_affiliation,
2525 new_affiliation->size);
2526 retval = 1;
adam radford229fe472014-03-10 02:51:56 -07002527 }
Adam Radford4cbfea82014-07-09 15:17:56 -07002528
2529 if (new_affiliation)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02002530 dma_free_coherent(&instance->pdev->dev,
Adam Radford4cbfea82014-07-09 15:17:56 -07002531 (MAX_LOGICAL_DRIVES + 1) *
2532 sizeof(struct MR_LD_VF_AFFILIATION),
2533 new_affiliation, new_affiliation_h);
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05302534 megasas_return_cmd(instance, cmd);
adam radford229fe472014-03-10 02:51:56 -07002535
2536 return retval;
2537}
2538
Adam Radford4cbfea82014-07-09 15:17:56 -07002539/* This function will get the current SR-IOV LD/VF affiliation */
2540static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
2541 int initial)
2542{
2543 int retval;
2544
2545 if (instance->PlasmaFW111)
2546 retval = megasas_get_ld_vf_affiliation_111(instance, initial);
2547 else
2548 retval = megasas_get_ld_vf_affiliation_12(instance, initial);
2549 return retval;
2550}
2551
adam radford229fe472014-03-10 02:51:56 -07002552/* This function will tell FW to start the SR-IOV heartbeat */
2553int megasas_sriov_start_heartbeat(struct megasas_instance *instance,
2554 int initial)
2555{
2556 struct megasas_cmd *cmd;
2557 struct megasas_dcmd_frame *dcmd;
2558 int retval = 0;
2559
2560 cmd = megasas_get_cmd(instance);
2561
2562 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002563 dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_sriov_start_heartbeat: "
2564 "Failed to get cmd for scsi%d\n",
adam radford229fe472014-03-10 02:51:56 -07002565 instance->host->host_no);
2566 return -ENOMEM;
2567 }
2568
2569 dcmd = &cmd->frame->dcmd;
2570
2571 if (initial) {
2572 instance->hb_host_mem =
Luis Chamberlain750afb02019-01-04 09:23:09 +01002573 dma_alloc_coherent(&instance->pdev->dev,
2574 sizeof(struct MR_CTRL_HB_HOST_MEM),
2575 &instance->hb_host_mem_h,
2576 GFP_KERNEL);
adam radford229fe472014-03-10 02:51:56 -07002577 if (!instance->hb_host_mem) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002578 dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate"
2579 " memory for heartbeat host memory for scsi%d\n",
2580 instance->host->host_no);
adam radford229fe472014-03-10 02:51:56 -07002581 retval = -ENOMEM;
2582 goto out;
2583 }
adam radford229fe472014-03-10 02:51:56 -07002584 }
2585
2586 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2587
Christoph Hellwig2213a462015-04-23 16:33:54 +05302588 dcmd->mbox.s[0] = cpu_to_le16(sizeof(struct MR_CTRL_HB_HOST_MEM));
adam radford229fe472014-03-10 02:51:56 -07002589 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05302590 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
adam radford229fe472014-03-10 02:51:56 -07002591 dcmd->sge_count = 1;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302592 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_BOTH);
adam radford229fe472014-03-10 02:51:56 -07002593 dcmd->timeout = 0;
2594 dcmd->pad_0 = 0;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302595 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_CTRL_HB_HOST_MEM));
2596 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC);
Shivasharan S107a60d2017-10-19 02:49:05 -07002597
2598 megasas_set_dma_settings(instance, dcmd, instance->hb_host_mem_h,
2599 sizeof(struct MR_CTRL_HB_HOST_MEM));
adam radford229fe472014-03-10 02:51:56 -07002600
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002601 dev_warn(&instance->pdev->dev, "SR-IOV: Starting heartbeat for scsi%d\n",
adam radford229fe472014-03-10 02:51:56 -07002602 instance->host->host_no);
2603
Shivasharan Se7d36b82017-10-19 02:48:50 -07002604 if ((instance->adapter_type != MFI_SERIES) &&
2605 !instance->mask_interrupts)
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05302606 retval = megasas_issue_blocked_cmd(instance, cmd,
2607 MEGASAS_ROUTINE_WAIT_TIME_VF);
2608 else
2609 retval = megasas_issue_polled(instance, cmd);
adam radford229fe472014-03-10 02:51:56 -07002610
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05302611 if (retval) {
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05302612 dev_warn(&instance->pdev->dev, "SR-IOV: MR_DCMD_CTRL_SHARED_HOST"
2613 "_MEM_ALLOC DCMD %s for scsi%d\n",
2614 (dcmd->cmd_status == MFI_STAT_INVALID_STATUS) ?
2615 "timed out" : "failed", instance->host->host_no);
adam radford229fe472014-03-10 02:51:56 -07002616 retval = 1;
adam radford229fe472014-03-10 02:51:56 -07002617 }
2618
2619out:
2620 megasas_return_cmd(instance, cmd);
2621
2622 return retval;
2623}
2624
2625/* Handler for SR-IOV heartbeat */
Kees Cookc251a7b2017-10-22 15:30:04 -07002626static void megasas_sriov_heartbeat_handler(struct timer_list *t)
adam radford229fe472014-03-10 02:51:56 -07002627{
2628 struct megasas_instance *instance =
Kees Cookc251a7b2017-10-22 15:30:04 -07002629 from_timer(instance, t, sriov_heartbeat_timer);
adam radford229fe472014-03-10 02:51:56 -07002630
2631 if (instance->hb_host_mem->HB.fwCounter !=
2632 instance->hb_host_mem->HB.driverCounter) {
2633 instance->hb_host_mem->HB.driverCounter =
2634 instance->hb_host_mem->HB.fwCounter;
2635 mod_timer(&instance->sriov_heartbeat_timer,
2636 jiffies + MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
2637 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002638 dev_warn(&instance->pdev->dev, "SR-IOV: Heartbeat never "
adam radford229fe472014-03-10 02:51:56 -07002639 "completed for scsi%d\n", instance->host->host_no);
2640 schedule_work(&instance->work_init);
2641 }
2642}
2643
bo yang7343eb62007-11-09 04:35:44 -05002644/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002645 * megasas_wait_for_outstanding - Wait for all outstanding cmds
2646 * @instance: Adapter soft state
2647 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002648 * This function waits for up to MEGASAS_RESET_WAIT_TIME seconds for FW to
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002649 * complete all its outstanding commands. Returns error if one or more IOs
2650 * are pending after this time period. It also marks the controller dead.
2651 */
2652static int megasas_wait_for_outstanding(struct megasas_instance *instance)
2653{
Sumit Saxenaccc75072016-01-28 21:04:33 +05302654 int i, sl, outstanding;
bo yang39a98552010-09-22 22:36:29 -04002655 u32 reset_index;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002656 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
bo yang39a98552010-09-22 22:36:29 -04002657 unsigned long flags;
2658 struct list_head clist_local;
2659 struct megasas_cmd *reset_cmd;
Yang, Bo707e09b2010-10-12 07:20:27 -06002660 u32 fw_state;
bo yang39a98552010-09-22 22:36:29 -04002661
Sumit Saxenaccc75072016-01-28 21:04:33 +05302662 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
2663 dev_info(&instance->pdev->dev, "%s:%d HBA is killed.\n",
2664 __func__, __LINE__);
2665 return FAILED;
2666 }
bo yang39a98552010-09-22 22:36:29 -04002667
Sumit Saxena8a01a412016-01-28 21:04:32 +05302668 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
bo yang39a98552010-09-22 22:36:29 -04002669
2670 INIT_LIST_HEAD(&clist_local);
2671 spin_lock_irqsave(&instance->hba_lock, flags);
2672 list_splice_init(&instance->internal_reset_pending_q,
2673 &clist_local);
2674 spin_unlock_irqrestore(&instance->hba_lock, flags);
2675
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002676 dev_notice(&instance->pdev->dev, "HBA reset wait ...\n");
bo yang39a98552010-09-22 22:36:29 -04002677 for (i = 0; i < wait_time; i++) {
2678 msleep(1000);
Sumit Saxena8a01a412016-01-28 21:04:32 +05302679 if (atomic_read(&instance->adprecovery) == MEGASAS_HBA_OPERATIONAL)
bo yang39a98552010-09-22 22:36:29 -04002680 break;
2681 }
2682
Sumit Saxena8a01a412016-01-28 21:04:32 +05302683 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002684 dev_notice(&instance->pdev->dev, "reset: Stopping HBA.\n");
Sumit Saxena8a01a412016-01-28 21:04:32 +05302685 atomic_set(&instance->adprecovery, MEGASAS_HW_CRITICAL_ERROR);
bo yang39a98552010-09-22 22:36:29 -04002686 return FAILED;
2687 }
2688
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002689 reset_index = 0;
bo yang39a98552010-09-22 22:36:29 -04002690 while (!list_empty(&clist_local)) {
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002691 reset_cmd = list_entry((&clist_local)->next,
bo yang39a98552010-09-22 22:36:29 -04002692 struct megasas_cmd, list);
2693 list_del_init(&reset_cmd->list);
2694 if (reset_cmd->scmd) {
Shivasharan Sf55cf472017-02-10 00:59:07 -08002695 reset_cmd->scmd->result = DID_REQUEUE << 16;
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002696 dev_notice(&instance->pdev->dev, "%d:%p reset [%02x]\n",
bo yang39a98552010-09-22 22:36:29 -04002697 reset_index, reset_cmd,
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002698 reset_cmd->scmd->cmnd[0]);
bo yang39a98552010-09-22 22:36:29 -04002699
2700 reset_cmd->scmd->scsi_done(reset_cmd->scmd);
2701 megasas_return_cmd(instance, reset_cmd);
2702 } else if (reset_cmd->sync_cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002703 dev_notice(&instance->pdev->dev, "%p synch cmds"
bo yang39a98552010-09-22 22:36:29 -04002704 "reset queue\n",
2705 reset_cmd);
2706
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05302707 reset_cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
bo yang39a98552010-09-22 22:36:29 -04002708 instance->instancet->fire_cmd(instance,
2709 reset_cmd->frame_phys_addr,
2710 0, instance->reg_set);
2711 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002712 dev_notice(&instance->pdev->dev, "%p unexpected"
bo yang39a98552010-09-22 22:36:29 -04002713 "cmds lst\n",
2714 reset_cmd);
2715 }
2716 reset_index++;
2717 }
2718
2719 return SUCCESS;
2720 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002721
adam radfordc007b8b2012-07-17 18:20:24 -07002722 for (i = 0; i < resetwaittime; i++) {
Sumit Saxenaccc75072016-01-28 21:04:33 +05302723 outstanding = atomic_read(&instance->fw_outstanding);
Sumant Patroe4a082c2006-05-30 12:03:37 -07002724
2725 if (!outstanding)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002726 break;
2727
2728 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002729 dev_notice(&instance->pdev->dev, "[%2d]waiting for %d "
Sumant Patroe4a082c2006-05-30 12:03:37 -07002730 "commands to complete\n",i,outstanding);
bo yang7343eb62007-11-09 04:35:44 -05002731 /*
2732 * Call cmd completion routine. Cmd to be
2733 * be completed directly without depending on isr.
2734 */
2735 megasas_complete_cmd_dpc((unsigned long)instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002736 }
2737
2738 msleep(1000);
2739 }
2740
Yang, Bo707e09b2010-10-12 07:20:27 -06002741 i = 0;
Sumit Saxenaccc75072016-01-28 21:04:33 +05302742 outstanding = atomic_read(&instance->fw_outstanding);
Shivasharan Sde516372018-12-17 00:47:39 -08002743 fw_state = instance->instancet->read_fw_status_reg(instance) & MFI_STATE_MASK;
Yang, Bo707e09b2010-10-12 07:20:27 -06002744
Sumit Saxenaccc75072016-01-28 21:04:33 +05302745 if ((!outstanding && (fw_state == MFI_STATE_OPERATIONAL)))
2746 goto no_outstanding;
2747
2748 if (instance->disableOnlineCtrlReset)
2749 goto kill_hba_and_failed;
2750 do {
2751 if ((fw_state == MFI_STATE_FAULT) || atomic_read(&instance->fw_outstanding)) {
2752 dev_info(&instance->pdev->dev,
Colin Ian Kingefc372c2019-04-17 14:51:09 +01002753 "%s:%d waiting_for_outstanding: before issue OCR. FW state = 0x%x, outstanding 0x%x\n",
Sumit Saxenaccc75072016-01-28 21:04:33 +05302754 __func__, __LINE__, fw_state, atomic_read(&instance->fw_outstanding));
2755 if (i == 3)
2756 goto kill_hba_and_failed;
2757 megasas_do_ocr(instance);
2758
2759 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
2760 dev_info(&instance->pdev->dev, "%s:%d OCR failed and HBA is killed.\n",
2761 __func__, __LINE__);
2762 return FAILED;
2763 }
2764 dev_info(&instance->pdev->dev, "%s:%d waiting_for_outstanding: after issue OCR.\n",
2765 __func__, __LINE__);
2766
2767 for (sl = 0; sl < 10; sl++)
2768 msleep(500);
2769
2770 outstanding = atomic_read(&instance->fw_outstanding);
2771
Shivasharan Sde516372018-12-17 00:47:39 -08002772 fw_state = instance->instancet->read_fw_status_reg(instance) & MFI_STATE_MASK;
Sumit Saxenaccc75072016-01-28 21:04:33 +05302773 if ((!outstanding && (fw_state == MFI_STATE_OPERATIONAL)))
2774 goto no_outstanding;
Yang, Bo707e09b2010-10-12 07:20:27 -06002775 }
2776 i++;
2777 } while (i <= 3);
2778
Sumit Saxenaccc75072016-01-28 21:04:33 +05302779no_outstanding:
Yang, Bo707e09b2010-10-12 07:20:27 -06002780
Sumit Saxenaccc75072016-01-28 21:04:33 +05302781 dev_info(&instance->pdev->dev, "%s:%d no more pending commands remain after reset handling.\n",
2782 __func__, __LINE__);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002783 return SUCCESS;
Sumit Saxenaccc75072016-01-28 21:04:33 +05302784
2785kill_hba_and_failed:
2786
2787 /* Reset not supported, kill adapter */
2788 dev_info(&instance->pdev->dev, "%s:%d killing adapter scsi%d"
2789 " disableOnlineCtrlReset %d fw_outstanding %d \n",
2790 __func__, __LINE__, instance->host->host_no, instance->disableOnlineCtrlReset,
2791 atomic_read(&instance->fw_outstanding));
2792 megasas_dump_pending_frames(instance);
2793 megaraid_sas_kill_hba(instance);
2794
2795 return FAILED;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002796}
2797
2798/**
2799 * megasas_generic_reset - Generic reset routine
2800 * @scmd: Mid-layer SCSI command
2801 *
2802 * This routine implements a generic reset handler for device, bus and host
2803 * reset requests. Device, bus and host specific reset handlers can use this
2804 * function after they do their specific tasks.
2805 */
2806static int megasas_generic_reset(struct scsi_cmnd *scmd)
2807{
2808 int ret_val;
2809 struct megasas_instance *instance;
2810
2811 instance = (struct megasas_instance *)scmd->device->host->hostdata;
2812
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002813 scmd_printk(KERN_NOTICE, scmd, "megasas: RESET cmd=%x retries=%x\n",
2814 scmd->cmnd[0], scmd->retries);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002815
Sumit Saxena8a01a412016-01-28 21:04:32 +05302816 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002817 dev_err(&instance->pdev->dev, "cannot recover from previous reset failures\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002818 return FAILED;
2819 }
2820
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002821 ret_val = megasas_wait_for_outstanding(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002822 if (ret_val == SUCCESS)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002823 dev_notice(&instance->pdev->dev, "reset successful\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002824 else
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002825 dev_err(&instance->pdev->dev, "failed to do reset\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002826
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002827 return ret_val;
2828}
2829
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002830/**
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002831 * megasas_reset_timer - quiesce the adapter if required
2832 * @scmd: scsi cmnd
2833 *
2834 * Sets the FW busy flag and reduces the host->can_queue if the
2835 * cmd has not been completed within the timeout period.
2836 */
2837static enum
Jens Axboe242f9dc2008-09-14 05:55:09 -07002838blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002839{
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002840 struct megasas_instance *instance;
2841 unsigned long flags;
2842
2843 if (time_after(jiffies, scmd->jiffies_at_alloc +
Sumit Saxenae3d178c2016-01-28 21:04:34 +05302844 (scmd_timeout * 2) * HZ)) {
Christoph Hellwig66005932018-05-29 15:52:29 +02002845 return BLK_EH_DONE;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002846 }
2847
adam radfordf575c5d2011-10-13 16:01:12 -07002848 instance = (struct megasas_instance *)scmd->device->host->hostdata;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002849 if (!(instance->flag & MEGASAS_FW_BUSY)) {
2850 /* FW is busy, throttle IO */
2851 spin_lock_irqsave(instance->host->host_lock, flags);
2852
adam radfordc5daa6a2012-07-17 18:20:03 -07002853 instance->host->can_queue = instance->throttlequeuedepth;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002854 instance->last_time = jiffies;
2855 instance->flag |= MEGASAS_FW_BUSY;
2856
2857 spin_unlock_irqrestore(instance->host->host_lock, flags);
2858 }
Jens Axboe242f9dc2008-09-14 05:55:09 -07002859 return BLK_EH_RESET_TIMER;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002860}
2861
2862/**
Shivasharan S4fe55032019-05-07 10:05:39 -07002863 * megasas_dump - This function will print hexdump of provided buffer.
2864 * @buf: Buffer to be dumped
2865 * @sz: Size in bytes
2866 * @format: Different formats of dumping e.g. format=n will
2867 * cause only 'n' 32 bit words to be dumped in a single
2868 * line.
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002869 */
Shivasharan S96c96032019-05-07 10:05:37 -07002870inline void
Shivasharan S4fe55032019-05-07 10:05:39 -07002871megasas_dump(void *buf, int sz, int format)
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002872{
2873 int i;
Shivasharan S4fe55032019-05-07 10:05:39 -07002874 __le32 *buf_loc = (__le32 *)buf;
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002875
Shivasharan S4fe55032019-05-07 10:05:39 -07002876 for (i = 0; i < (sz / sizeof(__le32)); i++) {
2877 if ((i % format) == 0) {
2878 if (i != 0)
2879 printk(KERN_CONT "\n");
2880 printk(KERN_CONT "%08x: ", (i * 4));
2881 }
2882 printk(KERN_CONT "%08x ", le32_to_cpu(buf_loc[i]));
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002883 }
Shivasharan S4fe55032019-05-07 10:05:39 -07002884 printk(KERN_CONT "\n");
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002885}
2886
2887/**
Shivasharan S3d1d9eb2019-05-07 10:05:41 -07002888 * megasas_dump_reg_set - This function will print hexdump of register set
2889 * @buf: Buffer to be dumped
2890 * @sz: Size in bytes
2891 * @format: Different formats of dumping e.g. format=n will
2892 * cause only 'n' 32 bit words to be dumped in a
2893 * single line.
2894 */
2895inline void
2896megasas_dump_reg_set(void __iomem *reg_set)
2897{
2898 unsigned int i, sz = 256;
2899 u32 __iomem *reg = (u32 __iomem *)reg_set;
2900
2901 for (i = 0; i < (sz / sizeof(u32)); i++)
2902 printk("%08x: %08x\n", (i * 4), readl(&reg[i]));
2903}
2904
2905/**
Shivasharan S96c96032019-05-07 10:05:37 -07002906 * megasas_dump_fusion_io - This function will print key details
2907 * of SCSI IO
2908 * @scmd: SCSI command pointer of SCSI IO
2909 */
2910void
2911megasas_dump_fusion_io(struct scsi_cmnd *scmd)
2912{
2913 struct megasas_cmd_fusion *cmd;
2914 union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
2915 struct megasas_instance *instance;
2916
2917 cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr;
2918 instance = (struct megasas_instance *)scmd->device->host->hostdata;
2919
2920 scmd_printk(KERN_INFO, scmd,
2921 "scmd: (0x%p) retries: 0x%x allowed: 0x%x\n",
2922 scmd, scmd->retries, scmd->allowed);
2923 scsi_print_command(scmd);
2924
2925 if (cmd) {
2926 req_desc = (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)cmd->request_desc;
2927 scmd_printk(KERN_INFO, scmd, "Request descriptor details:\n");
2928 scmd_printk(KERN_INFO, scmd,
2929 "RequestFlags:0x%x MSIxIndex:0x%x SMID:0x%x LMID:0x%x DevHandle:0x%x\n",
2930 req_desc->SCSIIO.RequestFlags,
2931 req_desc->SCSIIO.MSIxIndex, req_desc->SCSIIO.SMID,
2932 req_desc->SCSIIO.LMID, req_desc->SCSIIO.DevHandle);
2933
2934 printk(KERN_INFO "IO request frame:\n");
2935 megasas_dump(cmd->io_request,
Shivasharan S4fe55032019-05-07 10:05:39 -07002936 MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE, 8);
Shivasharan S96c96032019-05-07 10:05:37 -07002937 printk(KERN_INFO "Chain frame:\n");
2938 megasas_dump(cmd->sg_frame,
Shivasharan S4fe55032019-05-07 10:05:39 -07002939 instance->max_chain_frame_sz, 8);
Shivasharan S96c96032019-05-07 10:05:37 -07002940 }
2941
2942}
2943
Shivasharan Scfb9a302019-05-07 10:05:40 -07002944/*
2945 * megasas_dump_sys_regs - This function will dump system registers through
2946 * sysfs.
2947 * @reg_set: Pointer to System register set.
2948 * @buf: Buffer to which output is to be written.
2949 * @return: Number of bytes written to buffer.
2950 */
2951static inline ssize_t
2952megasas_dump_sys_regs(void __iomem *reg_set, char *buf)
2953{
2954 unsigned int i, sz = 256;
2955 int bytes_wrote = 0;
2956 char *loc = (char *)buf;
2957 u32 __iomem *reg = (u32 __iomem *)reg_set;
2958
2959 for (i = 0; i < sz / sizeof(u32); i++) {
2960 bytes_wrote += snprintf(loc + bytes_wrote, PAGE_SIZE,
2961 "%08x: %08x\n", (i * 4),
2962 readl(&reg[i]));
2963 }
2964 return bytes_wrote;
2965}
2966
Shivasharan S96c96032019-05-07 10:05:37 -07002967/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002968 * megasas_reset_bus_host - Bus & host reset handler entry point
2969 */
2970static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
2971{
2972 int ret;
adam radford9c915a82010-12-21 13:34:31 -08002973 struct megasas_instance *instance;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002974
adam radford9c915a82010-12-21 13:34:31 -08002975 instance = (struct megasas_instance *)scmd->device->host->hostdata;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002976
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002977 scmd_printk(KERN_INFO, scmd,
Shivasharan S96c96032019-05-07 10:05:37 -07002978 "OCR is requested due to IO timeout!!\n");
2979
2980 scmd_printk(KERN_INFO, scmd,
2981 "SCSI host state: %d SCSI host busy: %d FW outstanding: %d\n",
2982 scmd->device->host->shost_state,
Ming Leic84b0232018-06-24 22:03:26 +08002983 scsi_host_busy(scmd->device->host),
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002984 atomic_read(&instance->fw_outstanding));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002985 /*
Uwe Zeisberger80682fa2006-03-22 00:21:33 +01002986 * First wait for all commands to complete
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002987 */
Shivasharan Se7d36b82017-10-19 02:48:50 -07002988 if (instance->adapter_type == MFI_SERIES) {
2989 ret = megasas_generic_reset(scmd);
2990 } else {
Shivasharan S96c96032019-05-07 10:05:37 -07002991 megasas_dump_fusion_io(scmd);
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002992 ret = megasas_reset_fusion(scmd->device->host,
2993 SCSIIO_TIMEOUT_OCR);
Shivasharan Se7d36b82017-10-19 02:48:50 -07002994 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002995
2996 return ret;
2997}
2998
2999/**
Sumit Saxenabd23d4a2016-04-15 00:23:32 -07003000 * megasas_task_abort - Issues task abort request to firmware
3001 * (supported only for fusion adapters)
3002 * @scmd: SCSI command pointer
3003 */
3004static int megasas_task_abort(struct scsi_cmnd *scmd)
3005{
3006 int ret;
3007 struct megasas_instance *instance;
3008
3009 instance = (struct megasas_instance *)scmd->device->host->hostdata;
3010
Shivasharan Se7d36b82017-10-19 02:48:50 -07003011 if (instance->adapter_type != MFI_SERIES)
Sumit Saxenabd23d4a2016-04-15 00:23:32 -07003012 ret = megasas_task_abort_fusion(scmd);
3013 else {
3014 sdev_printk(KERN_NOTICE, scmd->device, "TASK ABORT not supported\n");
3015 ret = FAILED;
3016 }
3017
3018 return ret;
3019}
3020
3021/**
3022 * megasas_reset_target: Issues target reset request to firmware
3023 * (supported only for fusion adapters)
3024 * @scmd: SCSI command pointer
3025 */
3026static int megasas_reset_target(struct scsi_cmnd *scmd)
3027{
3028 int ret;
3029 struct megasas_instance *instance;
3030
3031 instance = (struct megasas_instance *)scmd->device->host->hostdata;
3032
Shivasharan Se7d36b82017-10-19 02:48:50 -07003033 if (instance->adapter_type != MFI_SERIES)
Sumit Saxenabd23d4a2016-04-15 00:23:32 -07003034 ret = megasas_reset_target_fusion(scmd);
3035 else {
3036 sdev_printk(KERN_NOTICE, scmd->device, "TARGET RESET not supported\n");
3037 ret = FAILED;
3038 }
3039
3040 return ret;
3041}
3042
3043/**
Sumant Patrocf62a0a2007-02-14 12:41:55 -08003044 * megasas_bios_param - Returns disk geometry for a disk
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003045 * @sdev: device handle
Sumant Patrocf62a0a2007-02-14 12:41:55 -08003046 * @bdev: block device
3047 * @capacity: drive capacity
3048 * @geom: geometry parameters
3049 */
3050static int
3051megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
3052 sector_t capacity, int geom[])
3053{
3054 int heads;
3055 int sectors;
3056 sector_t cylinders;
3057 unsigned long tmp;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003058
Sumant Patrocf62a0a2007-02-14 12:41:55 -08003059 /* Default heads (64) & sectors (32) */
3060 heads = 64;
3061 sectors = 32;
3062
3063 tmp = heads * sectors;
3064 cylinders = capacity;
3065
3066 sector_div(cylinders, tmp);
3067
3068 /*
3069 * Handle extended translation size for logical drives > 1Gb
3070 */
3071
3072 if (capacity >= 0x200000) {
3073 heads = 255;
3074 sectors = 63;
3075 tmp = heads*sectors;
3076 cylinders = capacity;
3077 sector_div(cylinders, tmp);
3078 }
3079
3080 geom[0] = heads;
3081 geom[1] = sectors;
3082 geom[2] = cylinders;
3083
3084 return 0;
3085}
3086
Yang, Bo7e8a75f2009-10-06 14:50:17 -06003087static void megasas_aen_polling(struct work_struct *work);
3088
Sumant Patrocf62a0a2007-02-14 12:41:55 -08003089/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003090 * megasas_service_aen - Processes an event notification
3091 * @instance: Adapter soft state
3092 * @cmd: AEN command completed by the ISR
3093 *
3094 * For AEN, driver sends a command down to FW that is held by the FW till an
3095 * event occurs. When an event of interest occurs, FW completes the command
3096 * that it was previously holding.
3097 *
3098 * This routines sends SIGIO signal to processes that have registered with the
3099 * driver for AEN.
3100 */
3101static void
3102megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
3103{
Yang, Boc3518832009-10-06 14:18:02 -06003104 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003105
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003106 /*
3107 * Don't signal app if it is just an aborted previously registered aen
3108 */
Yang, Boc3518832009-10-06 14:18:02 -06003109 if ((!cmd->abort_aen) && (instance->unload == 0)) {
3110 spin_lock_irqsave(&poll_aen_lock, flags);
3111 megasas_poll_wait_aen = 1;
3112 spin_unlock_irqrestore(&poll_aen_lock, flags);
3113 wake_up(&megasas_poll_wait);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003114 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
Yang, Boc3518832009-10-06 14:18:02 -06003115 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003116 else
3117 cmd->abort_aen = 0;
3118
3119 instance->aen_cmd = NULL;
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05303120
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05303121 megasas_return_cmd(instance, cmd);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06003122
bo yang39a98552010-09-22 22:36:29 -04003123 if ((instance->unload == 0) &&
3124 ((instance->issuepend_done == 1))) {
Yang, Bo7e8a75f2009-10-06 14:50:17 -06003125 struct megasas_aen_event *ev;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003126
Yang, Bo7e8a75f2009-10-06 14:50:17 -06003127 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3128 if (!ev) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003129 dev_err(&instance->pdev->dev, "megasas_service_aen: out of memory\n");
Yang, Bo7e8a75f2009-10-06 14:50:17 -06003130 } else {
3131 ev->instance = instance;
3132 instance->ev = ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08003133 INIT_DELAYED_WORK(&ev->hotplug_work,
3134 megasas_aen_polling);
3135 schedule_delayed_work(&ev->hotplug_work, 0);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06003136 }
3137 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003138}
3139
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303140static ssize_t
Tomas Henzld6354682019-05-29 18:00:41 +02003141fw_crash_buffer_store(struct device *cdev,
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303142 struct device_attribute *attr, const char *buf, size_t count)
3143{
3144 struct Scsi_Host *shost = class_to_shost(cdev);
3145 struct megasas_instance *instance =
3146 (struct megasas_instance *) shost->hostdata;
3147 int val = 0;
3148 unsigned long flags;
3149
3150 if (kstrtoint(buf, 0, &val) != 0)
3151 return -EINVAL;
3152
3153 spin_lock_irqsave(&instance->crashdump_lock, flags);
3154 instance->fw_crash_buffer_offset = val;
3155 spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3156 return strlen(buf);
3157}
3158
3159static ssize_t
Tomas Henzld6354682019-05-29 18:00:41 +02003160fw_crash_buffer_show(struct device *cdev,
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303161 struct device_attribute *attr, char *buf)
3162{
3163 struct Scsi_Host *shost = class_to_shost(cdev);
3164 struct megasas_instance *instance =
3165 (struct megasas_instance *) shost->hostdata;
3166 u32 size;
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303167 unsigned long dmachunk = CRASH_DMA_BUF_SIZE;
3168 unsigned long src_addr;
3169 unsigned long flags;
3170 u32 buff_offset;
3171
3172 spin_lock_irqsave(&instance->crashdump_lock, flags);
3173 buff_offset = instance->fw_crash_buffer_offset;
3174 if (!instance->crash_dump_buf &&
3175 !((instance->fw_crash_state == AVAILABLE) ||
3176 (instance->fw_crash_state == COPYING))) {
3177 dev_err(&instance->pdev->dev,
3178 "Firmware crash dump is not available\n");
3179 spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3180 return -EINVAL;
3181 }
3182
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003183 if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) {
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303184 dev_err(&instance->pdev->dev,
3185 "Firmware crash dump offset is out of range\n");
3186 spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3187 return 0;
3188 }
3189
3190 size = (instance->fw_crash_buffer_size * dmachunk) - buff_offset;
3191 size = (size >= PAGE_SIZE) ? (PAGE_SIZE - 1) : size;
3192
3193 src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] +
3194 (buff_offset % dmachunk);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003195 memcpy(buf, (void *)src_addr, size);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303196 spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3197
3198 return size;
3199}
3200
3201static ssize_t
Tomas Henzld6354682019-05-29 18:00:41 +02003202fw_crash_buffer_size_show(struct device *cdev,
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303203 struct device_attribute *attr, char *buf)
3204{
3205 struct Scsi_Host *shost = class_to_shost(cdev);
3206 struct megasas_instance *instance =
3207 (struct megasas_instance *) shost->hostdata;
3208
3209 return snprintf(buf, PAGE_SIZE, "%ld\n", (unsigned long)
3210 ((instance->fw_crash_buffer_size) * 1024 * 1024)/PAGE_SIZE);
3211}
3212
3213static ssize_t
Tomas Henzld6354682019-05-29 18:00:41 +02003214fw_crash_state_store(struct device *cdev,
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303215 struct device_attribute *attr, const char *buf, size_t count)
3216{
3217 struct Scsi_Host *shost = class_to_shost(cdev);
3218 struct megasas_instance *instance =
3219 (struct megasas_instance *) shost->hostdata;
3220 int val = 0;
3221 unsigned long flags;
3222
3223 if (kstrtoint(buf, 0, &val) != 0)
3224 return -EINVAL;
3225
3226 if ((val <= AVAILABLE || val > COPY_ERROR)) {
3227 dev_err(&instance->pdev->dev, "application updates invalid "
3228 "firmware crash state\n");
3229 return -EINVAL;
3230 }
3231
3232 instance->fw_crash_state = val;
3233
3234 if ((val == COPIED) || (val == COPY_ERROR)) {
3235 spin_lock_irqsave(&instance->crashdump_lock, flags);
3236 megasas_free_host_crash_buffer(instance);
3237 spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3238 if (val == COPY_ERROR)
3239 dev_info(&instance->pdev->dev, "application failed to "
3240 "copy Firmware crash dump\n");
3241 else
3242 dev_info(&instance->pdev->dev, "Firmware crash dump "
3243 "copied successfully\n");
3244 }
3245 return strlen(buf);
3246}
3247
3248static ssize_t
Tomas Henzld6354682019-05-29 18:00:41 +02003249fw_crash_state_show(struct device *cdev,
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303250 struct device_attribute *attr, char *buf)
3251{
3252 struct Scsi_Host *shost = class_to_shost(cdev);
3253 struct megasas_instance *instance =
3254 (struct megasas_instance *) shost->hostdata;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003255
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303256 return snprintf(buf, PAGE_SIZE, "%d\n", instance->fw_crash_state);
3257}
3258
3259static ssize_t
Tomas Henzld6354682019-05-29 18:00:41 +02003260page_size_show(struct device *cdev,
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303261 struct device_attribute *attr, char *buf)
3262{
3263 return snprintf(buf, PAGE_SIZE, "%ld\n", (unsigned long)PAGE_SIZE - 1);
3264}
3265
Sumit Saxena308ec452016-01-28 21:04:30 +05303266static ssize_t
Tomas Henzld6354682019-05-29 18:00:41 +02003267ldio_outstanding_show(struct device *cdev, struct device_attribute *attr,
Sumit Saxena308ec452016-01-28 21:04:30 +05303268 char *buf)
3269{
3270 struct Scsi_Host *shost = class_to_shost(cdev);
3271 struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata;
3272
3273 return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&instance->ldio_outstanding));
3274}
3275
Shivasharan S88d155c2018-01-05 05:27:46 -08003276static ssize_t
Tomas Henzld6354682019-05-29 18:00:41 +02003277fw_cmds_outstanding_show(struct device *cdev,
Shivasharan S88d155c2018-01-05 05:27:46 -08003278 struct device_attribute *attr, char *buf)
3279{
3280 struct Scsi_Host *shost = class_to_shost(cdev);
3281 struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata;
3282
3283 return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&instance->fw_outstanding));
3284}
3285
Shivasharan Scfb9a302019-05-07 10:05:40 -07003286static ssize_t
Tomas Henzld6354682019-05-29 18:00:41 +02003287dump_system_regs_show(struct device *cdev,
Shivasharan Scfb9a302019-05-07 10:05:40 -07003288 struct device_attribute *attr, char *buf)
3289{
3290 struct Scsi_Host *shost = class_to_shost(cdev);
3291 struct megasas_instance *instance =
3292 (struct megasas_instance *)shost->hostdata;
3293
3294 return megasas_dump_sys_regs(instance->reg_set, buf);
3295}
3296
Shivasharan Sa6024a92019-05-07 10:05:43 -07003297static ssize_t
Tomas Henzld6354682019-05-29 18:00:41 +02003298raid_map_id_show(struct device *cdev, struct device_attribute *attr,
Shivasharan Sa6024a92019-05-07 10:05:43 -07003299 char *buf)
3300{
3301 struct Scsi_Host *shost = class_to_shost(cdev);
3302 struct megasas_instance *instance =
3303 (struct megasas_instance *)shost->hostdata;
3304
3305 return snprintf(buf, PAGE_SIZE, "%ld\n",
3306 (unsigned long)instance->map_id);
3307}
3308
Tomas Henzld6354682019-05-29 18:00:41 +02003309static DEVICE_ATTR_RW(fw_crash_buffer);
3310static DEVICE_ATTR_RO(fw_crash_buffer_size);
3311static DEVICE_ATTR_RW(fw_crash_state);
3312static DEVICE_ATTR_RO(page_size);
3313static DEVICE_ATTR_RO(ldio_outstanding);
3314static DEVICE_ATTR_RO(fw_cmds_outstanding);
3315static DEVICE_ATTR_RO(dump_system_regs);
3316static DEVICE_ATTR_RO(raid_map_id);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303317
YueHaibing6764f512019-07-02 21:01:14 +08003318static struct device_attribute *megaraid_host_attrs[] = {
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303319 &dev_attr_fw_crash_buffer_size,
3320 &dev_attr_fw_crash_buffer,
3321 &dev_attr_fw_crash_state,
3322 &dev_attr_page_size,
Sumit Saxena308ec452016-01-28 21:04:30 +05303323 &dev_attr_ldio_outstanding,
Shivasharan S88d155c2018-01-05 05:27:46 -08003324 &dev_attr_fw_cmds_outstanding,
Shivasharan Scfb9a302019-05-07 10:05:40 -07003325 &dev_attr_dump_system_regs,
Shivasharan Sa6024a92019-05-07 10:05:43 -07003326 &dev_attr_raid_map_id,
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303327 NULL,
3328};
3329
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003330/*
3331 * Scsi host template for megaraid_sas driver
3332 */
3333static struct scsi_host_template megasas_template = {
3334
3335 .module = THIS_MODULE,
Sumit.Saxena@avagotech.com43cd7fe2015-04-23 16:31:39 +05303336 .name = "Avago SAS based MegaRAID driver",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003337 .proc_name = "megaraid_sas",
Christoph Hellwig147aab62006-02-17 12:13:48 +01003338 .slave_configure = megasas_slave_configure,
Yang, Bo044833b2009-10-06 14:33:06 -06003339 .slave_alloc = megasas_slave_alloc,
Sumit Saxena18365b12016-01-28 21:04:25 +05303340 .slave_destroy = megasas_slave_destroy,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003341 .queuecommand = megasas_queue_command,
Sumit Saxenabd23d4a2016-04-15 00:23:32 -07003342 .eh_target_reset_handler = megasas_reset_target,
3343 .eh_abort_handler = megasas_task_abort,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003344 .eh_host_reset_handler = megasas_reset_bus_host,
Sumant Patro05e9ebb2007-05-17 05:47:51 -07003345 .eh_timed_out = megasas_reset_timer,
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303346 .shost_attrs = megaraid_host_attrs,
Sumant Patrocf62a0a2007-02-14 12:41:55 -08003347 .bios_param = megasas_bios_param,
Christoph Hellwigdb5ed4d2014-11-13 15:08:42 +01003348 .change_queue_depth = scsi_change_queue_depth,
Martin K. Petersen54b2b502013-10-23 06:25:40 -04003349 .no_write_same = 1,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003350};
3351
3352/**
3353 * megasas_complete_int_cmd - Completes an internal command
3354 * @instance: Adapter soft state
3355 * @cmd: Command to be completed
3356 *
3357 * The megasas_issue_blocked_cmd() function waits for a command to complete
3358 * after it issues a command. This function wakes up that waiting routine by
3359 * calling wake_up() on the wait queue.
3360 */
3361static void
3362megasas_complete_int_cmd(struct megasas_instance *instance,
3363 struct megasas_cmd *cmd)
3364{
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05303365 cmd->cmd_status_drv = cmd->frame->io.cmd_status;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003366 wake_up(&instance->int_cmd_wait_q);
3367}
3368
3369/**
3370 * megasas_complete_abort - Completes aborting a command
3371 * @instance: Adapter soft state
3372 * @cmd: Cmd that was issued to abort another cmd
3373 *
adam radford0d490162010-12-14 19:17:17 -08003374 * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
3375 * after it issues an abort on a previously issued command. This function
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003376 * wakes up all functions waiting on the same wait queue.
3377 */
3378static void
3379megasas_complete_abort(struct megasas_instance *instance,
3380 struct megasas_cmd *cmd)
3381{
3382 if (cmd->sync_cmd) {
3383 cmd->sync_cmd = 0;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05303384 cmd->cmd_status_drv = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003385 wake_up(&instance->abort_cmd_wait_q);
3386 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003387}
3388
3389/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003390 * megasas_complete_cmd - Completes a command
3391 * @instance: Adapter soft state
3392 * @cmd: Command to be completed
adam radford0d490162010-12-14 19:17:17 -08003393 * @alt_status: If non-zero, use this value as status to
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003394 * SCSI mid-layer instead of the value returned
3395 * by the FW. This should be used if caller wants
3396 * an alternate status (as in the case of aborted
3397 * commands)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003398 */
adam radford9c915a82010-12-21 13:34:31 -08003399void
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003400megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
3401 u8 alt_status)
3402{
3403 int exception = 0;
3404 struct megasas_header *hdr = &cmd->frame->hdr;
Yang, Boc3518832009-10-06 14:18:02 -06003405 unsigned long flags;
adam radford9c915a82010-12-21 13:34:31 -08003406 struct fusion_context *fusion = instance->ctrl_context;
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05303407 u32 opcode, status;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003408
bo yang39a98552010-09-22 22:36:29 -04003409 /* flag for the retry reset */
3410 cmd->retry_for_fw_reset = 0;
3411
Sumant Patro05e9ebb2007-05-17 05:47:51 -07003412 if (cmd->scmd)
3413 cmd->scmd->SCp.ptr = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003414
3415 switch (hdr->cmd) {
adam radforde5f93a32011-10-08 18:15:19 -07003416 case MFI_CMD_INVALID:
3417 /* Some older 1068 controller FW may keep a pended
3418 MR_DCMD_CTRL_EVENT_GET_INFO left over from the main kernel
3419 when booting the kdump kernel. Ignore this command to
3420 prevent a kernel panic on shutdown of the kdump kernel. */
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003421 dev_warn(&instance->pdev->dev, "MFI_CMD_INVALID command "
3422 "completed\n");
3423 dev_warn(&instance->pdev->dev, "If you have a controller "
3424 "other than PERC5, please upgrade your firmware\n");
adam radforde5f93a32011-10-08 18:15:19 -07003425 break;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003426 case MFI_CMD_PD_SCSI_IO:
3427 case MFI_CMD_LD_SCSI_IO:
3428
3429 /*
3430 * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been
3431 * issued either through an IO path or an IOCTL path. If it
3432 * was via IOCTL, we will send it to internal completion.
3433 */
3434 if (cmd->sync_cmd) {
3435 cmd->sync_cmd = 0;
3436 megasas_complete_int_cmd(instance, cmd);
3437 break;
3438 }
Gustavo A. R. Silva8d07f7d2018-11-27 22:32:27 -06003439 /* fall through */
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003440
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003441 case MFI_CMD_LD_READ:
3442 case MFI_CMD_LD_WRITE:
3443
3444 if (alt_status) {
3445 cmd->scmd->result = alt_status << 16;
3446 exception = 1;
3447 }
3448
3449 if (exception) {
3450
Sumant Patroe4a082c2006-05-30 12:03:37 -07003451 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003452
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09003453 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003454 cmd->scmd->scsi_done(cmd->scmd);
3455 megasas_return_cmd(instance, cmd);
3456
3457 break;
3458 }
3459
3460 switch (hdr->cmd_status) {
3461
3462 case MFI_STAT_OK:
3463 cmd->scmd->result = DID_OK << 16;
3464 break;
3465
3466 case MFI_STAT_SCSI_IO_FAILED:
3467 case MFI_STAT_LD_INIT_IN_PROGRESS:
3468 cmd->scmd->result =
3469 (DID_ERROR << 16) | hdr->scsi_status;
3470 break;
3471
3472 case MFI_STAT_SCSI_DONE_WITH_ERROR:
3473
3474 cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status;
3475
3476 if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) {
3477 memset(cmd->scmd->sense_buffer, 0,
3478 SCSI_SENSE_BUFFERSIZE);
3479 memcpy(cmd->scmd->sense_buffer, cmd->sense,
3480 hdr->sense_len);
3481
3482 cmd->scmd->result |= DRIVER_SENSE << 24;
3483 }
3484
3485 break;
3486
3487 case MFI_STAT_LD_OFFLINE:
3488 case MFI_STAT_DEVICE_NOT_FOUND:
3489 cmd->scmd->result = DID_BAD_TARGET << 16;
3490 break;
3491
3492 default:
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003493 dev_printk(KERN_DEBUG, &instance->pdev->dev, "MFI FW status %#x\n",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003494 hdr->cmd_status);
3495 cmd->scmd->result = DID_ERROR << 16;
3496 break;
3497 }
3498
Sumant Patroe4a082c2006-05-30 12:03:37 -07003499 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003500
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09003501 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003502 cmd->scmd->scsi_done(cmd->scmd);
3503 megasas_return_cmd(instance, cmd);
3504
3505 break;
3506
3507 case MFI_CMD_SMP:
3508 case MFI_CMD_STP:
Shivasharan Sf870bcb2018-01-05 05:33:04 -08003509 case MFI_CMD_NVME:
Chandrakanth Patil58136852019-06-25 16:34:30 +05303510 case MFI_CMD_TOOLBOX:
Shivasharan S82add4e2017-10-19 02:49:02 -07003511 megasas_complete_int_cmd(instance, cmd);
3512 break;
3513
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003514 case MFI_CMD_DCMD:
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303515 opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
adam radford9c915a82010-12-21 13:34:31 -08003516 /* Check for LD map update */
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303517 if ((opcode == MR_DCMD_LD_MAP_GET_INFO)
3518 && (cmd->frame->dcmd.mbox.b[1] == 1)) {
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05303519 fusion->fast_path_io = 0;
adam radford9c915a82010-12-21 13:34:31 -08003520 spin_lock_irqsave(instance->host->host_lock, flags);
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003521 status = cmd->frame->hdr.cmd_status;
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05303522 instance->map_update_cmd = NULL;
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003523 if (status != MFI_STAT_OK) {
3524 if (status != MFI_STAT_NOT_FOUND)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003525 dev_warn(&instance->pdev->dev, "map syncfailed, status = 0x%x\n",
adam radford9c915a82010-12-21 13:34:31 -08003526 cmd->frame->hdr.cmd_status);
3527 else {
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05303528 megasas_return_cmd(instance, cmd);
adam radford9c915a82010-12-21 13:34:31 -08003529 spin_unlock_irqrestore(
3530 instance->host->host_lock,
3531 flags);
3532 break;
3533 }
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003534 }
3535
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05303536 megasas_return_cmd(instance, cmd);
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05303537
3538 /*
3539 * Set fast path IO to ZERO.
3540 * Validate Map will set proper value.
3541 * Meanwhile all IOs will go as LD IO.
3542 */
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003543 if (status == MFI_STAT_OK &&
3544 (MR_ValidateMapInfo(instance, (instance->map_id + 1)))) {
3545 instance->map_id++;
adam radford9c915a82010-12-21 13:34:31 -08003546 fusion->fast_path_io = 1;
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003547 } else {
adam radford9c915a82010-12-21 13:34:31 -08003548 fusion->fast_path_io = 0;
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003549 }
3550
adam radford9c915a82010-12-21 13:34:31 -08003551 megasas_sync_map_info(instance);
3552 spin_unlock_irqrestore(instance->host->host_lock,
3553 flags);
3554 break;
3555 }
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303556 if (opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
3557 opcode == MR_DCMD_CTRL_EVENT_GET) {
Yang, Boc3518832009-10-06 14:18:02 -06003558 spin_lock_irqsave(&poll_aen_lock, flags);
3559 megasas_poll_wait_aen = 0;
3560 spin_unlock_irqrestore(&poll_aen_lock, flags);
3561 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003562
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05303563 /* FW has an updated PD sequence */
3564 if ((opcode == MR_DCMD_SYSTEM_PD_MAP_GET_INFO) &&
3565 (cmd->frame->dcmd.mbox.b[0] == 1)) {
3566
3567 spin_lock_irqsave(instance->host->host_lock, flags);
3568 status = cmd->frame->hdr.cmd_status;
3569 instance->jbod_seq_cmd = NULL;
3570 megasas_return_cmd(instance, cmd);
3571
3572 if (status == MFI_STAT_OK) {
3573 instance->pd_seq_map_id++;
3574 /* Re-register a pd sync seq num cmd */
3575 if (megasas_sync_pd_seq_num(instance, true))
3576 instance->use_seqnum_jbod_fp = false;
3577 } else
3578 instance->use_seqnum_jbod_fp = false;
3579
3580 spin_unlock_irqrestore(instance->host->host_lock, flags);
3581 break;
3582 }
3583
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003584 /*
3585 * See if got an event notification
3586 */
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303587 if (opcode == MR_DCMD_CTRL_EVENT_WAIT)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003588 megasas_service_aen(instance, cmd);
3589 else
3590 megasas_complete_int_cmd(instance, cmd);
3591
3592 break;
3593
3594 case MFI_CMD_ABORT:
3595 /*
3596 * Cmd issued to abort another cmd returned
3597 */
3598 megasas_complete_abort(instance, cmd);
3599 break;
3600
3601 default:
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003602 dev_info(&instance->pdev->dev, "Unknown command completed! [0x%X]\n",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003603 hdr->cmd);
Shivasharan S82add4e2017-10-19 02:49:02 -07003604 megasas_complete_int_cmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003605 break;
3606 }
3607}
3608
3609/**
bo yang39a98552010-09-22 22:36:29 -04003610 * megasas_issue_pending_cmds_again - issue all pending cmds
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003611 * in FW again because of the fw reset
bo yang39a98552010-09-22 22:36:29 -04003612 * @instance: Adapter soft state
3613 */
3614static inline void
3615megasas_issue_pending_cmds_again(struct megasas_instance *instance)
3616{
3617 struct megasas_cmd *cmd;
3618 struct list_head clist_local;
3619 union megasas_evt_class_locale class_locale;
3620 unsigned long flags;
3621 u32 seq_num;
3622
3623 INIT_LIST_HEAD(&clist_local);
3624 spin_lock_irqsave(&instance->hba_lock, flags);
3625 list_splice_init(&instance->internal_reset_pending_q, &clist_local);
3626 spin_unlock_irqrestore(&instance->hba_lock, flags);
3627
3628 while (!list_empty(&clist_local)) {
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003629 cmd = list_entry((&clist_local)->next,
bo yang39a98552010-09-22 22:36:29 -04003630 struct megasas_cmd, list);
3631 list_del_init(&cmd->list);
3632
3633 if (cmd->sync_cmd || cmd->scmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003634 dev_notice(&instance->pdev->dev, "command %p, %p:%d"
3635 "detected to be pending while HBA reset\n",
bo yang39a98552010-09-22 22:36:29 -04003636 cmd, cmd->scmd, cmd->sync_cmd);
3637
3638 cmd->retry_for_fw_reset++;
3639
3640 if (cmd->retry_for_fw_reset == 3) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003641 dev_notice(&instance->pdev->dev, "cmd %p, %p:%d"
bo yang39a98552010-09-22 22:36:29 -04003642 "was tried multiple times during reset."
3643 "Shutting down the HBA\n",
3644 cmd, cmd->scmd, cmd->sync_cmd);
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05303645 instance->instancet->disable_intr(instance);
3646 atomic_set(&instance->fw_reset_no_pci_access, 1);
bo yang39a98552010-09-22 22:36:29 -04003647 megaraid_sas_kill_hba(instance);
bo yang39a98552010-09-22 22:36:29 -04003648 return;
3649 }
3650 }
3651
3652 if (cmd->sync_cmd == 1) {
3653 if (cmd->scmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003654 dev_notice(&instance->pdev->dev, "unexpected"
bo yang39a98552010-09-22 22:36:29 -04003655 "cmd attached to internal command!\n");
3656 }
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003657 dev_notice(&instance->pdev->dev, "%p synchronous cmd"
bo yang39a98552010-09-22 22:36:29 -04003658 "on the internal reset queue,"
3659 "issue it again.\n", cmd);
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05303660 cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
bo yang39a98552010-09-22 22:36:29 -04003661 instance->instancet->fire_cmd(instance,
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003662 cmd->frame_phys_addr,
bo yang39a98552010-09-22 22:36:29 -04003663 0, instance->reg_set);
3664 } else if (cmd->scmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003665 dev_notice(&instance->pdev->dev, "%p scsi cmd [%02x]"
bo yang39a98552010-09-22 22:36:29 -04003666 "detected on the internal queue, issue again.\n",
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04003667 cmd, cmd->scmd->cmnd[0]);
bo yang39a98552010-09-22 22:36:29 -04003668
3669 atomic_inc(&instance->fw_outstanding);
3670 instance->instancet->fire_cmd(instance,
3671 cmd->frame_phys_addr,
3672 cmd->frame_count-1, instance->reg_set);
3673 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003674 dev_notice(&instance->pdev->dev, "%p unexpected cmd on the"
bo yang39a98552010-09-22 22:36:29 -04003675 "internal reset defer list while re-issue!!\n",
3676 cmd);
3677 }
3678 }
3679
3680 if (instance->aen_cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003681 dev_notice(&instance->pdev->dev, "aen_cmd in def process\n");
bo yang39a98552010-09-22 22:36:29 -04003682 megasas_return_cmd(instance, instance->aen_cmd);
3683
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003684 instance->aen_cmd = NULL;
bo yang39a98552010-09-22 22:36:29 -04003685 }
3686
3687 /*
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003688 * Initiate AEN (Asynchronous Event Notification)
3689 */
bo yang39a98552010-09-22 22:36:29 -04003690 seq_num = instance->last_seq_num;
3691 class_locale.members.reserved = 0;
3692 class_locale.members.locale = MR_EVT_LOCALE_ALL;
3693 class_locale.members.class = MR_EVT_CLASS_DEBUG;
3694
3695 megasas_register_aen(instance, seq_num, class_locale.word);
3696}
3697
3698/**
3699 * Move the internal reset pending commands to a deferred queue.
3700 *
3701 * We move the commands pending at internal reset time to a
3702 * pending queue. This queue would be flushed after successful
3703 * completion of the internal reset sequence. if the internal reset
3704 * did not complete in time, the kernel reset handler would flush
3705 * these commands.
3706 **/
3707static void
3708megasas_internal_reset_defer_cmds(struct megasas_instance *instance)
3709{
3710 struct megasas_cmd *cmd;
3711 int i;
Shivasharan S50b7f5a2017-02-10 00:59:25 -08003712 u16 max_cmd = instance->max_fw_cmds;
bo yang39a98552010-09-22 22:36:29 -04003713 u32 defer_index;
3714 unsigned long flags;
3715
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003716 defer_index = 0;
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05303717 spin_lock_irqsave(&instance->mfi_pool_lock, flags);
bo yang39a98552010-09-22 22:36:29 -04003718 for (i = 0; i < max_cmd; i++) {
3719 cmd = instance->cmd_list[i];
3720 if (cmd->sync_cmd == 1 || cmd->scmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003721 dev_notice(&instance->pdev->dev, "moving cmd[%d]:%p:%d:%p"
bo yang39a98552010-09-22 22:36:29 -04003722 "on the defer queue as internal\n",
3723 defer_index, cmd, cmd->sync_cmd, cmd->scmd);
3724
3725 if (!list_empty(&cmd->list)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003726 dev_notice(&instance->pdev->dev, "ERROR while"
bo yang39a98552010-09-22 22:36:29 -04003727 " moving this cmd:%p, %d %p, it was"
3728 "discovered on some list?\n",
3729 cmd, cmd->sync_cmd, cmd->scmd);
3730
3731 list_del_init(&cmd->list);
3732 }
3733 defer_index++;
3734 list_add_tail(&cmd->list,
3735 &instance->internal_reset_pending_q);
3736 }
3737 }
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05303738 spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
bo yang39a98552010-09-22 22:36:29 -04003739}
3740
3741
3742static void
3743process_fw_state_change_wq(struct work_struct *work)
3744{
3745 struct megasas_instance *instance =
3746 container_of(work, struct megasas_instance, work_init);
3747 u32 wait;
3748 unsigned long flags;
3749
Sumit Saxena8a01a412016-01-28 21:04:32 +05303750 if (atomic_read(&instance->adprecovery) != MEGASAS_ADPRESET_SM_INFAULT) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003751 dev_notice(&instance->pdev->dev, "error, recovery st %x\n",
Sumit Saxena8a01a412016-01-28 21:04:32 +05303752 atomic_read(&instance->adprecovery));
bo yang39a98552010-09-22 22:36:29 -04003753 return ;
3754 }
3755
Sumit Saxena8a01a412016-01-28 21:04:32 +05303756 if (atomic_read(&instance->adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003757 dev_notice(&instance->pdev->dev, "FW detected to be in fault"
bo yang39a98552010-09-22 22:36:29 -04003758 "state, restarting it...\n");
3759
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303760 instance->instancet->disable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04003761 atomic_set(&instance->fw_outstanding, 0);
3762
3763 atomic_set(&instance->fw_reset_no_pci_access, 1);
3764 instance->instancet->adp_reset(instance, instance->reg_set);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003765 atomic_set(&instance->fw_reset_no_pci_access, 0);
bo yang39a98552010-09-22 22:36:29 -04003766
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003767 dev_notice(&instance->pdev->dev, "FW restarted successfully,"
bo yang39a98552010-09-22 22:36:29 -04003768 "initiating next stage...\n");
3769
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003770 dev_notice(&instance->pdev->dev, "HBA recovery state machine,"
bo yang39a98552010-09-22 22:36:29 -04003771 "state 2 starting...\n");
3772
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003773 /* waiting for about 20 second before start the second init */
bo yang39a98552010-09-22 22:36:29 -04003774 for (wait = 0; wait < 30; wait++) {
3775 msleep(1000);
3776 }
3777
adam radford058a8fa2011-10-08 18:14:27 -07003778 if (megasas_transition_to_ready(instance, 1)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003779 dev_notice(&instance->pdev->dev, "adapter not ready\n");
bo yang39a98552010-09-22 22:36:29 -04003780
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05303781 atomic_set(&instance->fw_reset_no_pci_access, 1);
bo yang39a98552010-09-22 22:36:29 -04003782 megaraid_sas_kill_hba(instance);
bo yang39a98552010-09-22 22:36:29 -04003783 return ;
3784 }
3785
3786 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
3787 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
3788 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)
3789 ) {
3790 *instance->consumer = *instance->producer;
3791 } else {
3792 *instance->consumer = 0;
3793 *instance->producer = 0;
3794 }
3795
3796 megasas_issue_init_mfi(instance);
3797
3798 spin_lock_irqsave(&instance->hba_lock, flags);
Sumit Saxena8a01a412016-01-28 21:04:32 +05303799 atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
bo yang39a98552010-09-22 22:36:29 -04003800 spin_unlock_irqrestore(&instance->hba_lock, flags);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303801 instance->instancet->enable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04003802
3803 megasas_issue_pending_cmds_again(instance);
3804 instance->issuepend_done = 1;
3805 }
bo yang39a98552010-09-22 22:36:29 -04003806}
3807
3808/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003809 * megasas_deplete_reply_queue - Processes all completed commands
3810 * @instance: Adapter soft state
3811 * @alt_status: Alternate status to be returned to
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003812 * SCSI mid-layer instead of the status
3813 * returned by the FW
bo yang39a98552010-09-22 22:36:29 -04003814 * Note: this must be called with hba lock held
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003815 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08003816static int
bo yang39a98552010-09-22 22:36:29 -04003817megasas_deplete_reply_queue(struct megasas_instance *instance,
3818 u8 alt_status)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003819{
bo yang39a98552010-09-22 22:36:29 -04003820 u32 mfiStatus;
3821 u32 fw_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003822
bo yang39a98552010-09-22 22:36:29 -04003823 if ((mfiStatus = instance->instancet->check_reset(instance,
3824 instance->reg_set)) == 1) {
3825 return IRQ_HANDLED;
3826 }
3827
Shivasharan Sde516372018-12-17 00:47:39 -08003828 mfiStatus = instance->instancet->clear_intr(instance);
3829 if (mfiStatus == 0) {
adam radforde1419192011-02-24 20:56:21 -08003830 /* Hardware may not set outbound_intr_status in MSI-X mode */
adam radfordc8e858f2011-10-08 18:15:13 -07003831 if (!instance->msix_vectors)
adam radforde1419192011-02-24 20:56:21 -08003832 return IRQ_NONE;
bo yang39a98552010-09-22 22:36:29 -04003833 }
3834
3835 instance->mfiStatus = mfiStatus;
3836
3837 if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) {
3838 fw_state = instance->instancet->read_fw_status_reg(
Shivasharan Sde516372018-12-17 00:47:39 -08003839 instance) & MFI_STATE_MASK;
bo yang39a98552010-09-22 22:36:29 -04003840
3841 if (fw_state != MFI_STATE_FAULT) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003842 dev_notice(&instance->pdev->dev, "fw state:%x\n",
bo yang39a98552010-09-22 22:36:29 -04003843 fw_state);
3844 }
3845
3846 if ((fw_state == MFI_STATE_FAULT) &&
3847 (instance->disableOnlineCtrlReset == 0)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003848 dev_notice(&instance->pdev->dev, "wait adp restart\n");
bo yang39a98552010-09-22 22:36:29 -04003849
3850 if ((instance->pdev->device ==
3851 PCI_DEVICE_ID_LSI_SAS1064R) ||
3852 (instance->pdev->device ==
3853 PCI_DEVICE_ID_DELL_PERC5) ||
3854 (instance->pdev->device ==
3855 PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
3856
3857 *instance->consumer =
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303858 cpu_to_le32(MEGASAS_ADPRESET_INPROG_SIGN);
bo yang39a98552010-09-22 22:36:29 -04003859 }
3860
3861
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303862 instance->instancet->disable_intr(instance);
Sumit Saxena8a01a412016-01-28 21:04:32 +05303863 atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_INFAULT);
bo yang39a98552010-09-22 22:36:29 -04003864 instance->issuepend_done = 0;
3865
3866 atomic_set(&instance->fw_outstanding, 0);
3867 megasas_internal_reset_defer_cmds(instance);
3868
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003869 dev_notice(&instance->pdev->dev, "fwState=%x, stage:%d\n",
Sumit Saxena8a01a412016-01-28 21:04:32 +05303870 fw_state, atomic_read(&instance->adprecovery));
bo yang39a98552010-09-22 22:36:29 -04003871
3872 schedule_work(&instance->work_init);
3873 return IRQ_HANDLED;
3874
3875 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003876 dev_notice(&instance->pdev->dev, "fwstate:%x, dis_OCR=%x\n",
bo yang39a98552010-09-22 22:36:29 -04003877 fw_state, instance->disableOnlineCtrlReset);
3878 }
3879 }
3880
Sumant Patro5d018ad2006-10-03 13:13:18 -07003881 tasklet_schedule(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003882 return IRQ_HANDLED;
3883}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003884/**
3885 * megasas_isr - isr entry point
3886 */
David Howells7d12e782006-10-05 14:55:46 +01003887static irqreturn_t megasas_isr(int irq, void *devp)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003888{
adam radfordc8e858f2011-10-08 18:15:13 -07003889 struct megasas_irq_context *irq_context = devp;
3890 struct megasas_instance *instance = irq_context->instance;
bo yang39a98552010-09-22 22:36:29 -04003891 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003892 irqreturn_t rc;
bo yang39a98552010-09-22 22:36:29 -04003893
adam radfordc8e858f2011-10-08 18:15:13 -07003894 if (atomic_read(&instance->fw_reset_no_pci_access))
bo yang39a98552010-09-22 22:36:29 -04003895 return IRQ_HANDLED;
3896
bo yang39a98552010-09-22 22:36:29 -04003897 spin_lock_irqsave(&instance->hba_lock, flags);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003898 rc = megasas_deplete_reply_queue(instance, DID_OK);
bo yang39a98552010-09-22 22:36:29 -04003899 spin_unlock_irqrestore(&instance->hba_lock, flags);
3900
3901 return rc;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003902}
3903
3904/**
3905 * megasas_transition_to_ready - Move the FW to READY state
Sumant Patro1341c932006-01-25 12:02:40 -08003906 * @instance: Adapter soft state
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003907 *
3908 * During the initialization, FW passes can potentially be in any one of
3909 * several possible states. If the FW in operational, waiting-for-handshake
3910 * states, driver must take steps to bring it to ready state. Otherwise, it
3911 * has to wait for the ready state.
3912 */
adam radford9c915a82010-12-21 13:34:31 -08003913int
adam radford058a8fa2011-10-08 18:14:27 -07003914megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003915{
3916 int i;
3917 u8 max_wait;
3918 u32 fw_state;
Yang, Bo7218df62009-10-06 14:52:20 -06003919 u32 abs_state, curr_abs_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003920
Shivasharan Sde516372018-12-17 00:47:39 -08003921 abs_state = instance->instancet->read_fw_status_reg(instance);
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02003922 fw_state = abs_state & MFI_STATE_MASK;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003923
Sumant Patroe3bbff92006-10-03 12:28:49 -07003924 if (fw_state != MFI_STATE_READY)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003925 dev_info(&instance->pdev->dev, "Waiting for FW to come to ready"
adam radford0d490162010-12-14 19:17:17 -08003926 " state\n");
Sumant Patroe3bbff92006-10-03 12:28:49 -07003927
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003928 while (fw_state != MFI_STATE_READY) {
3929
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003930 switch (fw_state) {
3931
3932 case MFI_STATE_FAULT:
Shivasharan Sb6661342019-05-07 10:05:44 -07003933 dev_printk(KERN_ERR, &instance->pdev->dev,
3934 "FW in FAULT state, Fault code:0x%x subcode:0x%x func:%s\n",
3935 abs_state & MFI_STATE_FAULT_CODE,
3936 abs_state & MFI_STATE_FAULT_SUBCODE, __func__);
adam radford058a8fa2011-10-08 18:14:27 -07003937 if (ocr) {
3938 max_wait = MEGASAS_RESET_WAIT_TIME;
adam radford058a8fa2011-10-08 18:14:27 -07003939 break;
Shivasharan S3d1d9eb2019-05-07 10:05:41 -07003940 } else {
3941 dev_printk(KERN_DEBUG, &instance->pdev->dev, "System Register set:\n");
3942 megasas_dump_reg_set(instance->reg_set);
adam radford058a8fa2011-10-08 18:14:27 -07003943 return -ENODEV;
Shivasharan S3d1d9eb2019-05-07 10:05:41 -07003944 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003945
3946 case MFI_STATE_WAIT_HANDSHAKE:
3947 /*
3948 * Set the CLR bit in inbound doorbell
3949 */
Yang, Bo0c79e682009-10-06 14:47:35 -06003950 if ((instance->pdev->device ==
Yang, Bo87911122009-10-06 14:31:54 -06003951 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3952 (instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003953 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
Shivasharan Se7d36b82017-10-19 02:48:50 -07003954 (instance->adapter_type != MFI_SERIES))
Yang, Bo87911122009-10-06 14:31:54 -06003955 writel(
3956 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
adam radford9c915a82010-12-21 13:34:31 -08003957 &instance->reg_set->doorbell);
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05303958 else
Yang, Bo87911122009-10-06 14:31:54 -06003959 writel(
3960 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
3961 &instance->reg_set->inbound_doorbell);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003962
Yang, Bo7218df62009-10-06 14:52:20 -06003963 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003964 break;
3965
Sumant Patroe3bbff92006-10-03 12:28:49 -07003966 case MFI_STATE_BOOT_MESSAGE_PENDING:
Yang, Bo87911122009-10-06 14:31:54 -06003967 if ((instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003968 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3969 (instance->pdev->device ==
3970 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
Shivasharan Se7d36b82017-10-19 02:48:50 -07003971 (instance->adapter_type != MFI_SERIES))
Yang, Bo87911122009-10-06 14:31:54 -06003972 writel(MFI_INIT_HOTPLUG,
adam radford9c915a82010-12-21 13:34:31 -08003973 &instance->reg_set->doorbell);
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05303974 else
Yang, Bo87911122009-10-06 14:31:54 -06003975 writel(MFI_INIT_HOTPLUG,
3976 &instance->reg_set->inbound_doorbell);
Sumant Patroe3bbff92006-10-03 12:28:49 -07003977
Yang, Bo7218df62009-10-06 14:52:20 -06003978 max_wait = MEGASAS_RESET_WAIT_TIME;
Sumant Patroe3bbff92006-10-03 12:28:49 -07003979 break;
3980
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003981 case MFI_STATE_OPERATIONAL:
3982 /*
Sumant Patroe3bbff92006-10-03 12:28:49 -07003983 * Bring it to READY state; assuming max wait 10 secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003984 */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303985 instance->instancet->disable_intr(instance);
Yang, Bo87911122009-10-06 14:31:54 -06003986 if ((instance->pdev->device ==
3987 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3988 (instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003989 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
Shivasharan Se7d36b82017-10-19 02:48:50 -07003990 (instance->adapter_type != MFI_SERIES)) {
Yang, Bo87911122009-10-06 14:31:54 -06003991 writel(MFI_RESET_FLAGS,
adam radford9c915a82010-12-21 13:34:31 -08003992 &instance->reg_set->doorbell);
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05303993
Shivasharan Se7d36b82017-10-19 02:48:50 -07003994 if (instance->adapter_type != MFI_SERIES) {
adam radford9c915a82010-12-21 13:34:31 -08003995 for (i = 0; i < (10 * 1000); i += 20) {
Shivasharan S272652f2018-12-17 00:47:40 -08003996 if (megasas_readl(
3997 instance,
adam radford9c915a82010-12-21 13:34:31 -08003998 &instance->
3999 reg_set->
4000 doorbell) & 1)
4001 msleep(20);
4002 else
4003 break;
4004 }
4005 }
Yang, Bo87911122009-10-06 14:31:54 -06004006 } else
4007 writel(MFI_RESET_FLAGS,
4008 &instance->reg_set->inbound_doorbell);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004009
Yang, Bo7218df62009-10-06 14:52:20 -06004010 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004011 break;
4012
4013 case MFI_STATE_UNDEFINED:
4014 /*
4015 * This state should not last for more than 2 seconds
4016 */
Yang, Bo7218df62009-10-06 14:52:20 -06004017 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004018 break;
4019
4020 case MFI_STATE_BB_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06004021 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004022 break;
4023
4024 case MFI_STATE_FW_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06004025 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004026 break;
4027
4028 case MFI_STATE_FW_INIT_2:
Yang, Bo7218df62009-10-06 14:52:20 -06004029 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004030 break;
4031
4032 case MFI_STATE_DEVICE_SCAN:
Yang, Bo7218df62009-10-06 14:52:20 -06004033 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004034 break;
4035
4036 case MFI_STATE_FLUSH_CACHE:
Yang, Bo7218df62009-10-06 14:52:20 -06004037 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004038 break;
4039
4040 default:
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004041 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Unknown state 0x%x\n",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004042 fw_state);
Shivasharan S3d1d9eb2019-05-07 10:05:41 -07004043 dev_printk(KERN_DEBUG, &instance->pdev->dev, "System Register set:\n");
4044 megasas_dump_reg_set(instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004045 return -ENODEV;
4046 }
4047
4048 /*
4049 * The cur_state should not last for more than max_wait secs
4050 */
Steve Sistare31b6a052019-03-01 06:46:28 -08004051 for (i = 0; i < max_wait * 50; i++) {
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02004052 curr_abs_state = instance->instancet->
Shivasharan Sde516372018-12-17 00:47:39 -08004053 read_fw_status_reg(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004054
Yang, Bo7218df62009-10-06 14:52:20 -06004055 if (abs_state == curr_abs_state) {
Steve Sistare31b6a052019-03-01 06:46:28 -08004056 msleep(20);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004057 } else
4058 break;
4059 }
4060
4061 /*
4062 * Return error if fw_state hasn't changed after max_wait
4063 */
Yang, Bo7218df62009-10-06 14:52:20 -06004064 if (curr_abs_state == abs_state) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004065 dev_printk(KERN_DEBUG, &instance->pdev->dev, "FW state [%d] hasn't changed "
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004066 "in %d secs\n", fw_state, max_wait);
Shivasharan S3d1d9eb2019-05-07 10:05:41 -07004067 dev_printk(KERN_DEBUG, &instance->pdev->dev, "System Register set:\n");
4068 megasas_dump_reg_set(instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004069 return -ENODEV;
4070 }
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02004071
4072 abs_state = curr_abs_state;
4073 fw_state = curr_abs_state & MFI_STATE_MASK;
bo yang39a98552010-09-22 22:36:29 -04004074 }
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004075 dev_info(&instance->pdev->dev, "FW now in Ready state\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004076
4077 return 0;
4078}
4079
4080/**
4081 * megasas_teardown_frame_pool - Destroy the cmd frame DMA pool
4082 * @instance: Adapter soft state
4083 */
4084static void megasas_teardown_frame_pool(struct megasas_instance *instance)
4085{
4086 int i;
Shivasharan S50b7f5a2017-02-10 00:59:25 -08004087 u16 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004088 struct megasas_cmd *cmd;
4089
4090 if (!instance->frame_dma_pool)
4091 return;
4092
4093 /*
4094 * Return all frames to pool
4095 */
4096 for (i = 0; i < max_cmd; i++) {
4097
4098 cmd = instance->cmd_list[i];
4099
4100 if (cmd->frame)
Romain Perierfc69d862017-07-06 10:13:06 +02004101 dma_pool_free(instance->frame_dma_pool, cmd->frame,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004102 cmd->frame_phys_addr);
4103
4104 if (cmd->sense)
Romain Perierfc69d862017-07-06 10:13:06 +02004105 dma_pool_free(instance->sense_dma_pool, cmd->sense,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004106 cmd->sense_phys_addr);
4107 }
4108
4109 /*
4110 * Now destroy the pool itself
4111 */
Romain Perierfc69d862017-07-06 10:13:06 +02004112 dma_pool_destroy(instance->frame_dma_pool);
4113 dma_pool_destroy(instance->sense_dma_pool);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004114
4115 instance->frame_dma_pool = NULL;
4116 instance->sense_dma_pool = NULL;
4117}
4118
4119/**
4120 * megasas_create_frame_pool - Creates DMA pool for cmd frames
4121 * @instance: Adapter soft state
4122 *
4123 * Each command packet has an embedded DMA memory buffer that is used for
4124 * filling MFI frame and the SG list that immediately follows the frame. This
4125 * function creates those DMA memory buffers for each command packet by using
4126 * PCI pool facility.
4127 */
4128static int megasas_create_frame_pool(struct megasas_instance *instance)
4129{
4130 int i;
Shivasharan S50b7f5a2017-02-10 00:59:25 -08004131 u16 max_cmd;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004132 u32 frame_count;
4133 struct megasas_cmd *cmd;
4134
adam radford9c915a82010-12-21 13:34:31 -08004135 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004136
4137 /*
Sumit.Saxena@avagotech.com200aed52015-01-05 20:05:58 +05304138 * For MFI controllers.
4139 * max_num_sge = 60
4140 * max_sge_sz = 16 byte (sizeof megasas_sge_skinny)
4141 * Total 960 byte (15 MFI frame of 64 byte)
4142 *
4143 * Fusion adapter require only 3 extra frame.
4144 * max_num_sge = 16 (defined as MAX_IOCTL_SGE)
4145 * max_sge_sz = 12 byte (sizeof megasas_sge64)
4146 * Total 192 byte (3 MFI frame of 64 byte)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004147 */
Shivasharan Se7d36b82017-10-19 02:48:50 -07004148 frame_count = (instance->adapter_type == MFI_SERIES) ?
4149 (15 + 1) : (3 + 1);
Shivasharan S21c34002017-02-10 00:59:28 -08004150 instance->mfi_frame_size = MEGAMFI_FRAME_SIZE * frame_count;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004151 /*
4152 * Use DMA pool facility provided by PCI layer
4153 */
Romain Perierfc69d862017-07-06 10:13:06 +02004154 instance->frame_dma_pool = dma_pool_create("megasas frame pool",
4155 &instance->pdev->dev,
4156 instance->mfi_frame_size, 256, 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004157
4158 if (!instance->frame_dma_pool) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004159 dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup frame pool\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004160 return -ENOMEM;
4161 }
4162
Romain Perierfc69d862017-07-06 10:13:06 +02004163 instance->sense_dma_pool = dma_pool_create("megasas sense pool",
4164 &instance->pdev->dev, 128,
4165 4, 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004166
4167 if (!instance->sense_dma_pool) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004168 dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup sense pool\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004169
Romain Perierfc69d862017-07-06 10:13:06 +02004170 dma_pool_destroy(instance->frame_dma_pool);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004171 instance->frame_dma_pool = NULL;
4172
4173 return -ENOMEM;
4174 }
4175
4176 /*
4177 * Allocate and attach a frame to each of the commands in cmd_list.
4178 * By making cmd->index as the context instead of the &cmd, we can
4179 * always use 32bit context regardless of the architecture
4180 */
4181 for (i = 0; i < max_cmd; i++) {
4182
4183 cmd = instance->cmd_list[i];
4184
Souptick Joarder61b142a2018-02-15 21:55:06 +05304185 cmd->frame = dma_pool_zalloc(instance->frame_dma_pool,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004186 GFP_KERNEL, &cmd->frame_phys_addr);
4187
Romain Perierfc69d862017-07-06 10:13:06 +02004188 cmd->sense = dma_pool_alloc(instance->sense_dma_pool,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004189 GFP_KERNEL, &cmd->sense_phys_addr);
4190
4191 /*
4192 * megasas_teardown_frame_pool() takes care of freeing
4193 * whatever has been allocated
4194 */
4195 if (!cmd->frame || !cmd->sense) {
Romain Perierfc69d862017-07-06 10:13:06 +02004196 dev_printk(KERN_DEBUG, &instance->pdev->dev, "dma_pool_alloc failed\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004197 megasas_teardown_frame_pool(instance);
4198 return -ENOMEM;
4199 }
4200
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304201 cmd->frame->io.context = cpu_to_le32(cmd->index);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004202 cmd->frame->io.pad_0 = 0;
Shivasharan Se7d36b82017-10-19 02:48:50 -07004203 if ((instance->adapter_type == MFI_SERIES) && reset_devices)
adam radforde5f93a32011-10-08 18:15:19 -07004204 cmd->frame->hdr.cmd = MFI_CMD_INVALID;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004205 }
4206
4207 return 0;
4208}
4209
4210/**
4211 * megasas_free_cmds - Free all the cmds in the free cmd pool
4212 * @instance: Adapter soft state
4213 */
adam radford9c915a82010-12-21 13:34:31 -08004214void megasas_free_cmds(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004215{
4216 int i;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05004217
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004218 /* First free the MFI frame pool */
4219 megasas_teardown_frame_pool(instance);
4220
4221 /* Free all the commands in the cmd_list */
adam radford9c915a82010-12-21 13:34:31 -08004222 for (i = 0; i < instance->max_mfi_cmds; i++)
4223
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004224 kfree(instance->cmd_list[i]);
4225
4226 /* Free the cmd_list buffer itself */
4227 kfree(instance->cmd_list);
4228 instance->cmd_list = NULL;
4229
4230 INIT_LIST_HEAD(&instance->cmd_pool);
4231}
4232
4233/**
4234 * megasas_alloc_cmds - Allocates the command packets
4235 * @instance: Adapter soft state
4236 *
4237 * Each command that is issued to the FW, whether IO commands from the OS or
4238 * internal commands like IOCTLs, are wrapped in local data structure called
4239 * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to
4240 * the FW.
4241 *
4242 * Each frame has a 32-bit field called context (tag). This context is used
4243 * to get back the megasas_cmd from the frame when a frame gets completed in
4244 * the ISR. Typically the address of the megasas_cmd itself would be used as
4245 * the context. But we wanted to keep the differences between 32 and 64 bit
4246 * systems to the mininum. We always use 32 bit integers for the context. In
4247 * this driver, the 32 bit values are the indices into an array cmd_list.
4248 * This array is used only to look up the megasas_cmd given the context. The
4249 * free commands themselves are maintained in a linked list called cmd_pool.
4250 */
adam radford9c915a82010-12-21 13:34:31 -08004251int megasas_alloc_cmds(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004252{
4253 int i;
4254 int j;
Shivasharan S50b7f5a2017-02-10 00:59:25 -08004255 u16 max_cmd;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004256 struct megasas_cmd *cmd;
4257
adam radford9c915a82010-12-21 13:34:31 -08004258 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004259
4260 /*
4261 * instance->cmd_list is an array of struct megasas_cmd pointers.
4262 * Allocate the dynamic array first and then allocate individual
4263 * commands.
4264 */
Yoann Padioleaudd00cc42007-07-19 01:49:03 -07004265 instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004266
4267 if (!instance->cmd_list) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004268 dev_printk(KERN_DEBUG, &instance->pdev->dev, "out of memory\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004269 return -ENOMEM;
4270 }
4271
adam radford9c915a82010-12-21 13:34:31 -08004272 memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) *max_cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004273
4274 for (i = 0; i < max_cmd; i++) {
4275 instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd),
4276 GFP_KERNEL);
4277
4278 if (!instance->cmd_list[i]) {
4279
4280 for (j = 0; j < i; j++)
4281 kfree(instance->cmd_list[j]);
4282
4283 kfree(instance->cmd_list);
4284 instance->cmd_list = NULL;
4285
4286 return -ENOMEM;
4287 }
4288 }
4289
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004290 for (i = 0; i < max_cmd; i++) {
4291 cmd = instance->cmd_list[i];
4292 memset(cmd, 0, sizeof(struct megasas_cmd));
4293 cmd->index = i;
bo yang39a98552010-09-22 22:36:29 -04004294 cmd->scmd = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004295 cmd->instance = instance;
4296
4297 list_add_tail(&cmd->list, &instance->cmd_pool);
4298 }
4299
4300 /*
4301 * Create a frame pool and assign one frame to each cmd
4302 */
4303 if (megasas_create_frame_pool(instance)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004304 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Error creating frame DMA pool\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004305 megasas_free_cmds(instance);
Jason Yanbcf3b672019-02-15 19:50:27 +08004306 return -ENOMEM;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004307 }
4308
4309 return 0;
4310}
4311
Yang, Bo81e403c2009-10-06 14:27:54 -06004312/*
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304313 * dcmd_timeout_ocr_possible - Check if OCR is possible based on Driver/FW state.
4314 * @instance: Adapter soft state
4315 *
4316 * Return 0 for only Fusion adapter, if driver load/unload is not in progress
4317 * or FW is not under OCR.
4318 */
4319inline int
4320dcmd_timeout_ocr_possible(struct megasas_instance *instance) {
4321
Shivasharan Se7d36b82017-10-19 02:48:50 -07004322 if (instance->adapter_type == MFI_SERIES)
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304323 return KILL_ADAPTER;
4324 else if (instance->unload ||
4325 test_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags))
4326 return IGNORE_TIMEOUT;
4327 else
4328 return INITIATE_OCR;
4329}
4330
Shivasharan S15dd0382017-02-10 00:59:10 -08004331static void
4332megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev)
Sumit Saxena2216c302016-01-28 21:04:26 +05304333{
4334 int ret;
4335 struct megasas_cmd *cmd;
4336 struct megasas_dcmd_frame *dcmd;
4337
Shivasharan S15dd0382017-02-10 00:59:10 -08004338 struct MR_PRIV_DEVICE *mr_device_priv_data;
4339 u16 device_id = 0;
4340
4341 device_id = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id;
Sumit Saxena2216c302016-01-28 21:04:26 +05304342 cmd = megasas_get_cmd(instance);
4343
4344 if (!cmd) {
4345 dev_err(&instance->pdev->dev, "Failed to get cmd %s\n", __func__);
Shivasharan S15dd0382017-02-10 00:59:10 -08004346 return;
Sumit Saxena2216c302016-01-28 21:04:26 +05304347 }
4348
4349 dcmd = &cmd->frame->dcmd;
4350
4351 memset(instance->pd_info, 0, sizeof(*instance->pd_info));
4352 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4353
4354 dcmd->mbox.s[0] = cpu_to_le16(device_id);
4355 dcmd->cmd = MFI_CMD_DCMD;
4356 dcmd->cmd_status = 0xFF;
4357 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07004358 dcmd->flags = MFI_FRAME_DIR_READ;
Sumit Saxena2216c302016-01-28 21:04:26 +05304359 dcmd->timeout = 0;
4360 dcmd->pad_0 = 0;
4361 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_PD_INFO));
4362 dcmd->opcode = cpu_to_le32(MR_DCMD_PD_GET_INFO);
Sumit Saxena2216c302016-01-28 21:04:26 +05304363
Shivasharan S107a60d2017-10-19 02:49:05 -07004364 megasas_set_dma_settings(instance, dcmd, instance->pd_info_h,
4365 sizeof(struct MR_PD_INFO));
Sumit Saxena2216c302016-01-28 21:04:26 +05304366
Shivasharan Se7d36b82017-10-19 02:48:50 -07004367 if ((instance->adapter_type != MFI_SERIES) &&
4368 !instance->mask_interrupts)
Sumit Saxena2216c302016-01-28 21:04:26 +05304369 ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
4370 else
4371 ret = megasas_issue_polled(instance, cmd);
4372
4373 switch (ret) {
4374 case DCMD_SUCCESS:
Shivasharan S15dd0382017-02-10 00:59:10 -08004375 mr_device_priv_data = sdev->hostdata;
4376 le16_to_cpus((u16 *)&instance->pd_info->state.ddf.pdType);
4377 mr_device_priv_data->interface_type =
Sumit Saxena2216c302016-01-28 21:04:26 +05304378 instance->pd_info->state.ddf.pdType.intf;
4379 break;
4380
4381 case DCMD_TIMEOUT:
4382
4383 switch (dcmd_timeout_ocr_possible(instance)) {
4384 case INITIATE_OCR:
4385 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05304386 mutex_unlock(&instance->reset_mutex);
Sumit Saxena2216c302016-01-28 21:04:26 +05304387 megasas_reset_fusion(instance->host,
4388 MFI_IO_TIMEOUT_OCR);
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05304389 mutex_lock(&instance->reset_mutex);
Sumit Saxena2216c302016-01-28 21:04:26 +05304390 break;
4391 case KILL_ADAPTER:
4392 megaraid_sas_kill_hba(instance);
4393 break;
4394 case IGNORE_TIMEOUT:
4395 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
4396 __func__, __LINE__);
4397 break;
4398 }
4399
4400 break;
4401 }
4402
4403 if (ret != DCMD_TIMEOUT)
4404 megasas_return_cmd(instance, cmd);
4405
Shivasharan S15dd0382017-02-10 00:59:10 -08004406 return;
Sumit Saxena2216c302016-01-28 21:04:26 +05304407}
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304408/*
Yang, Bo81e403c2009-10-06 14:27:54 -06004409 * megasas_get_pd_list_info - Returns FW's pd_list structure
4410 * @instance: Adapter soft state
4411 * @pd_list: pd_list structure
4412 *
4413 * Issues an internal command (DCMD) to get the FW's controller PD
4414 * list structure. This information is mainly used to find out SYSTEM
4415 * supported by the FW.
4416 */
4417static int
4418megasas_get_pd_list(struct megasas_instance *instance)
4419{
4420 int ret = 0, pd_index = 0;
4421 struct megasas_cmd *cmd;
4422 struct megasas_dcmd_frame *dcmd;
4423 struct MR_PD_LIST *ci;
4424 struct MR_PD_ADDRESS *pd_addr;
Yang, Bo81e403c2009-10-06 14:27:54 -06004425
Sumit Saxenad9083162016-07-08 03:30:16 -07004426 if (instance->pd_list_not_supported) {
4427 dev_info(&instance->pdev->dev, "MR_DCMD_PD_LIST_QUERY "
4428 "not supported by firmware\n");
4429 return ret;
4430 }
4431
Shivasharan S9b3d0282017-10-19 02:48:56 -07004432 ci = instance->pd_list_buf;
Shivasharan S9b3d0282017-10-19 02:48:56 -07004433
Yang, Bo81e403c2009-10-06 14:27:54 -06004434 cmd = megasas_get_cmd(instance);
4435
4436 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004437 dev_printk(KERN_DEBUG, &instance->pdev->dev, "(get_pd_list): Failed to get cmd\n");
Yang, Bo81e403c2009-10-06 14:27:54 -06004438 return -ENOMEM;
4439 }
4440
4441 dcmd = &cmd->frame->dcmd;
4442
Yang, Bo81e403c2009-10-06 14:27:54 -06004443 memset(ci, 0, sizeof(*ci));
4444 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4445
4446 dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
4447 dcmd->mbox.b[1] = 0;
4448 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05304449 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
Yang, Bo81e403c2009-10-06 14:27:54 -06004450 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07004451 dcmd->flags = MFI_FRAME_DIR_READ;
Yang, Bo81e403c2009-10-06 14:27:54 -06004452 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004453 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304454 dcmd->data_xfer_len = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST));
4455 dcmd->opcode = cpu_to_le32(MR_DCMD_PD_LIST_QUERY);
Yang, Bo81e403c2009-10-06 14:27:54 -06004456
Shivasharan S107a60d2017-10-19 02:49:05 -07004457 megasas_set_dma_settings(instance, dcmd, instance->pd_list_buf_h,
4458 (MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST)));
Yang, Bo81e403c2009-10-06 14:27:54 -06004459
Shivasharan Se7d36b82017-10-19 02:48:50 -07004460 if ((instance->adapter_type != MFI_SERIES) &&
4461 !instance->mask_interrupts)
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304462 ret = megasas_issue_blocked_cmd(instance, cmd,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304463 MFI_IO_TIMEOUT_SECS);
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304464 else
4465 ret = megasas_issue_polled(instance, cmd);
Yang, Bo81e403c2009-10-06 14:27:54 -06004466
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304467 switch (ret) {
4468 case DCMD_FAILED:
Sumit Saxena30845582016-03-10 02:14:37 -08004469 dev_info(&instance->pdev->dev, "MR_DCMD_PD_LIST_QUERY "
4470 "failed/not supported by firmware\n");
4471
Shivasharan Se7d36b82017-10-19 02:48:50 -07004472 if (instance->adapter_type != MFI_SERIES)
Sumit Saxena30845582016-03-10 02:14:37 -08004473 megaraid_sas_kill_hba(instance);
4474 else
4475 instance->pd_list_not_supported = 1;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304476 break;
4477 case DCMD_TIMEOUT:
Yang, Bo81e403c2009-10-06 14:27:54 -06004478
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304479 switch (dcmd_timeout_ocr_possible(instance)) {
4480 case INITIATE_OCR:
4481 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4482 /*
4483 * DCMD failed from AEN path.
4484 * AEN path already hold reset_mutex to avoid PCI access
4485 * while OCR is in progress.
4486 */
4487 mutex_unlock(&instance->reset_mutex);
4488 megasas_reset_fusion(instance->host,
4489 MFI_IO_TIMEOUT_OCR);
4490 mutex_lock(&instance->reset_mutex);
4491 break;
4492 case KILL_ADAPTER:
4493 megaraid_sas_kill_hba(instance);
4494 break;
4495 case IGNORE_TIMEOUT:
4496 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d \n",
4497 __func__, __LINE__);
4498 break;
4499 }
Yang, Bo81e403c2009-10-06 14:27:54 -06004500
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304501 break;
4502
4503 case DCMD_SUCCESS:
4504 pd_addr = ci->addr;
Shivasharan S0a11c0b2019-05-07 10:05:47 -07004505 if (megasas_dbg_lvl & LD_PD_DEBUG)
4506 dev_info(&instance->pdev->dev, "%s, sysPD count: 0x%x\n",
4507 __func__, le32_to_cpu(ci->count));
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304508
4509 if ((le32_to_cpu(ci->count) >
4510 (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL)))
4511 break;
Yang, Bo81e403c2009-10-06 14:27:54 -06004512
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05304513 memset(instance->local_pd_list, 0,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304514 MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
Yang, Bo81e403c2009-10-06 14:27:54 -06004515
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304516 for (pd_index = 0; pd_index < le32_to_cpu(ci->count); pd_index++) {
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05304517 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].tid =
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304518 le16_to_cpu(pd_addr->deviceId);
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05304519 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveType =
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304520 pd_addr->scsiDevType;
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05304521 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveState =
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304522 MR_PD_STATE_SYSTEM;
Shivasharan S0a11c0b2019-05-07 10:05:47 -07004523 if (megasas_dbg_lvl & LD_PD_DEBUG)
4524 dev_info(&instance->pdev->dev,
4525 "PD%d: targetID: 0x%03x deviceType:0x%x\n",
4526 pd_index, le16_to_cpu(pd_addr->deviceId),
4527 pd_addr->scsiDevType);
Yang, Bo81e403c2009-10-06 14:27:54 -06004528 pd_addr++;
4529 }
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304530
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05304531 memcpy(instance->pd_list, instance->local_pd_list,
4532 sizeof(instance->pd_list));
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304533 break;
4534
Yang, Bo81e403c2009-10-06 14:27:54 -06004535 }
4536
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304537 if (ret != DCMD_TIMEOUT)
4538 megasas_return_cmd(instance, cmd);
Yang, Bo81e403c2009-10-06 14:27:54 -06004539
4540 return ret;
4541}
4542
Yang, Bobdc6fb82009-12-06 08:30:19 -07004543/*
4544 * megasas_get_ld_list_info - Returns FW's ld_list structure
4545 * @instance: Adapter soft state
4546 * @ld_list: ld_list structure
4547 *
4548 * Issues an internal command (DCMD) to get the FW's controller PD
4549 * list structure. This information is mainly used to find out SYSTEM
4550 * supported by the FW.
4551 */
4552static int
4553megasas_get_ld_list(struct megasas_instance *instance)
4554{
4555 int ret = 0, ld_index = 0, ids = 0;
4556 struct megasas_cmd *cmd;
4557 struct megasas_dcmd_frame *dcmd;
4558 struct MR_LD_LIST *ci;
4559 dma_addr_t ci_h = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304560 u32 ld_count;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004561
Shivasharan S9b3d0282017-10-19 02:48:56 -07004562 ci = instance->ld_list_buf;
4563 ci_h = instance->ld_list_buf_h;
4564
Yang, Bobdc6fb82009-12-06 08:30:19 -07004565 cmd = megasas_get_cmd(instance);
4566
4567 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004568 dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_get_ld_list: Failed to get cmd\n");
Yang, Bobdc6fb82009-12-06 08:30:19 -07004569 return -ENOMEM;
4570 }
4571
4572 dcmd = &cmd->frame->dcmd;
4573
Yang, Bobdc6fb82009-12-06 08:30:19 -07004574 memset(ci, 0, sizeof(*ci));
4575 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4576
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05304577 if (instance->supportmax256vd)
4578 dcmd->mbox.b[0] = 1;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004579 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05304580 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004581 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07004582 dcmd->flags = MFI_FRAME_DIR_READ;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004583 dcmd->timeout = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304584 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_LIST));
4585 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_GET_LIST);
Yang, Bobdc6fb82009-12-06 08:30:19 -07004586 dcmd->pad_0 = 0;
4587
Shivasharan S107a60d2017-10-19 02:49:05 -07004588 megasas_set_dma_settings(instance, dcmd, ci_h,
4589 sizeof(struct MR_LD_LIST));
4590
Shivasharan Se7d36b82017-10-19 02:48:50 -07004591 if ((instance->adapter_type != MFI_SERIES) &&
4592 !instance->mask_interrupts)
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304593 ret = megasas_issue_blocked_cmd(instance, cmd,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304594 MFI_IO_TIMEOUT_SECS);
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304595 else
4596 ret = megasas_issue_polled(instance, cmd);
4597
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304598 ld_count = le32_to_cpu(ci->ldCount);
4599
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304600 switch (ret) {
4601 case DCMD_FAILED:
4602 megaraid_sas_kill_hba(instance);
4603 break;
4604 case DCMD_TIMEOUT:
Yang, Bobdc6fb82009-12-06 08:30:19 -07004605
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304606 switch (dcmd_timeout_ocr_possible(instance)) {
4607 case INITIATE_OCR:
4608 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4609 /*
4610 * DCMD failed from AEN path.
4611 * AEN path already hold reset_mutex to avoid PCI access
4612 * while OCR is in progress.
4613 */
4614 mutex_unlock(&instance->reset_mutex);
4615 megasas_reset_fusion(instance->host,
4616 MFI_IO_TIMEOUT_OCR);
4617 mutex_lock(&instance->reset_mutex);
4618 break;
4619 case KILL_ADAPTER:
4620 megaraid_sas_kill_hba(instance);
4621 break;
4622 case IGNORE_TIMEOUT:
4623 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
4624 __func__, __LINE__);
4625 break;
4626 }
4627
4628 break;
4629
4630 case DCMD_SUCCESS:
Shivasharan S0a11c0b2019-05-07 10:05:47 -07004631 if (megasas_dbg_lvl & LD_PD_DEBUG)
4632 dev_info(&instance->pdev->dev, "%s, LD count: 0x%x\n",
4633 __func__, ld_count);
4634
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304635 if (ld_count > instance->fw_supported_vd_count)
4636 break;
4637
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05304638 memset(instance->ld_ids, 0xff, MAX_LOGICAL_DRIVES_EXT);
Yang, Bobdc6fb82009-12-06 08:30:19 -07004639
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304640 for (ld_index = 0; ld_index < ld_count; ld_index++) {
Yang, Bobdc6fb82009-12-06 08:30:19 -07004641 if (ci->ldList[ld_index].state != 0) {
4642 ids = ci->ldList[ld_index].ref.targetId;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304643 instance->ld_ids[ids] = ci->ldList[ld_index].ref.targetId;
Shivasharan S0a11c0b2019-05-07 10:05:47 -07004644 if (megasas_dbg_lvl & LD_PD_DEBUG)
4645 dev_info(&instance->pdev->dev,
4646 "LD%d: targetID: 0x%03x\n",
4647 ld_index, ids);
Yang, Bobdc6fb82009-12-06 08:30:19 -07004648 }
4649 }
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304650
4651 break;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004652 }
4653
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304654 if (ret != DCMD_TIMEOUT)
4655 megasas_return_cmd(instance, cmd);
4656
Yang, Bobdc6fb82009-12-06 08:30:19 -07004657 return ret;
4658}
4659
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004660/**
adam radford21c9e162013-09-06 15:27:14 -07004661 * megasas_ld_list_query - Returns FW's ld_list structure
4662 * @instance: Adapter soft state
4663 * @ld_list: ld_list structure
4664 *
4665 * Issues an internal command (DCMD) to get the FW's controller PD
4666 * list structure. This information is mainly used to find out SYSTEM
4667 * supported by the FW.
4668 */
4669static int
4670megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
4671{
4672 int ret = 0, ld_index = 0, ids = 0;
4673 struct megasas_cmd *cmd;
4674 struct megasas_dcmd_frame *dcmd;
4675 struct MR_LD_TARGETID_LIST *ci;
4676 dma_addr_t ci_h = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304677 u32 tgtid_count;
adam radford21c9e162013-09-06 15:27:14 -07004678
Shivasharan S9b3d0282017-10-19 02:48:56 -07004679 ci = instance->ld_targetid_list_buf;
4680 ci_h = instance->ld_targetid_list_buf_h;
4681
adam radford21c9e162013-09-06 15:27:14 -07004682 cmd = megasas_get_cmd(instance);
4683
4684 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004685 dev_warn(&instance->pdev->dev,
4686 "megasas_ld_list_query: Failed to get cmd\n");
adam radford21c9e162013-09-06 15:27:14 -07004687 return -ENOMEM;
4688 }
4689
4690 dcmd = &cmd->frame->dcmd;
4691
adam radford21c9e162013-09-06 15:27:14 -07004692 memset(ci, 0, sizeof(*ci));
4693 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4694
4695 dcmd->mbox.b[0] = query_type;
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05304696 if (instance->supportmax256vd)
4697 dcmd->mbox.b[2] = 1;
adam radford21c9e162013-09-06 15:27:14 -07004698
4699 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05304700 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
adam radford21c9e162013-09-06 15:27:14 -07004701 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07004702 dcmd->flags = MFI_FRAME_DIR_READ;
adam radford21c9e162013-09-06 15:27:14 -07004703 dcmd->timeout = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304704 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST));
4705 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_LIST_QUERY);
adam radford21c9e162013-09-06 15:27:14 -07004706 dcmd->pad_0 = 0;
4707
Shivasharan S107a60d2017-10-19 02:49:05 -07004708 megasas_set_dma_settings(instance, dcmd, ci_h,
4709 sizeof(struct MR_LD_TARGETID_LIST));
4710
Shivasharan Se7d36b82017-10-19 02:48:50 -07004711 if ((instance->adapter_type != MFI_SERIES) &&
4712 !instance->mask_interrupts)
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304713 ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304714 else
4715 ret = megasas_issue_polled(instance, cmd);
adam radford21c9e162013-09-06 15:27:14 -07004716
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304717 switch (ret) {
4718 case DCMD_FAILED:
4719 dev_info(&instance->pdev->dev,
4720 "DCMD not supported by firmware - %s %d\n",
4721 __func__, __LINE__);
4722 ret = megasas_get_ld_list(instance);
4723 break;
4724 case DCMD_TIMEOUT:
4725 switch (dcmd_timeout_ocr_possible(instance)) {
4726 case INITIATE_OCR:
4727 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4728 /*
4729 * DCMD failed from AEN path.
4730 * AEN path already hold reset_mutex to avoid PCI access
4731 * while OCR is in progress.
4732 */
4733 mutex_unlock(&instance->reset_mutex);
4734 megasas_reset_fusion(instance->host,
4735 MFI_IO_TIMEOUT_OCR);
4736 mutex_lock(&instance->reset_mutex);
4737 break;
4738 case KILL_ADAPTER:
4739 megaraid_sas_kill_hba(instance);
4740 break;
4741 case IGNORE_TIMEOUT:
4742 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
4743 __func__, __LINE__);
4744 break;
4745 }
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304746
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304747 break;
4748 case DCMD_SUCCESS:
4749 tgtid_count = le32_to_cpu(ci->count);
4750
Shivasharan S0a11c0b2019-05-07 10:05:47 -07004751 if (megasas_dbg_lvl & LD_PD_DEBUG)
4752 dev_info(&instance->pdev->dev, "%s, LD count: 0x%x\n",
4753 __func__, tgtid_count);
4754
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304755 if ((tgtid_count > (instance->fw_supported_vd_count)))
4756 break;
4757
adam radford21c9e162013-09-06 15:27:14 -07004758 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304759 for (ld_index = 0; ld_index < tgtid_count; ld_index++) {
adam radford21c9e162013-09-06 15:27:14 -07004760 ids = ci->targetId[ld_index];
4761 instance->ld_ids[ids] = ci->targetId[ld_index];
Shivasharan S0a11c0b2019-05-07 10:05:47 -07004762 if (megasas_dbg_lvl & LD_PD_DEBUG)
4763 dev_info(&instance->pdev->dev, "LD%d: targetID: 0x%03x\n",
4764 ld_index, ci->targetId[ld_index]);
adam radford21c9e162013-09-06 15:27:14 -07004765 }
4766
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304767 break;
adam radford21c9e162013-09-06 15:27:14 -07004768 }
4769
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304770 if (ret != DCMD_TIMEOUT)
4771 megasas_return_cmd(instance, cmd);
adam radford21c9e162013-09-06 15:27:14 -07004772
4773 return ret;
4774}
4775
Shivasharan Sf6fe5732019-01-29 01:38:14 -08004776/**
4777 * dcmd.opcode - MR_DCMD_CTRL_DEVICE_LIST_GET
4778 * dcmd.mbox - reserved
4779 * dcmd.sge IN - ptr to return MR_HOST_DEVICE_LIST structure
4780 * Desc: This DCMD will return the combined device list
4781 * Status: MFI_STAT_OK - List returned successfully
4782 * MFI_STAT_INVALID_CMD - Firmware support for the feature has been
4783 * disabled
4784 * @instance: Adapter soft state
4785 * @is_probe: Driver probe check
4786 * Return: 0 if DCMD succeeded
4787 * non-zero if failed
4788 */
YueHaibing7c3f8ca2019-04-13 22:21:38 +08004789static int
Shivasharan Sf6fe5732019-01-29 01:38:14 -08004790megasas_host_device_list_query(struct megasas_instance *instance,
4791 bool is_probe)
4792{
4793 int ret, i, target_id;
4794 struct megasas_cmd *cmd;
4795 struct megasas_dcmd_frame *dcmd;
4796 struct MR_HOST_DEVICE_LIST *ci;
4797 u32 count;
4798 dma_addr_t ci_h;
4799
4800 ci = instance->host_device_list_buf;
4801 ci_h = instance->host_device_list_buf_h;
4802
4803 cmd = megasas_get_cmd(instance);
4804
4805 if (!cmd) {
4806 dev_warn(&instance->pdev->dev,
4807 "%s: failed to get cmd\n",
4808 __func__);
4809 return -ENOMEM;
4810 }
4811
4812 dcmd = &cmd->frame->dcmd;
4813
4814 memset(ci, 0, sizeof(*ci));
4815 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4816
4817 dcmd->mbox.b[0] = is_probe ? 0 : 1;
4818 dcmd->cmd = MFI_CMD_DCMD;
4819 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
4820 dcmd->sge_count = 1;
4821 dcmd->flags = MFI_FRAME_DIR_READ;
4822 dcmd->timeout = 0;
4823 dcmd->pad_0 = 0;
4824 dcmd->data_xfer_len = cpu_to_le32(HOST_DEVICE_LIST_SZ);
4825 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_DEVICE_LIST_GET);
4826
4827 megasas_set_dma_settings(instance, dcmd, ci_h, HOST_DEVICE_LIST_SZ);
4828
4829 if (!instance->mask_interrupts) {
4830 ret = megasas_issue_blocked_cmd(instance, cmd,
4831 MFI_IO_TIMEOUT_SECS);
4832 } else {
4833 ret = megasas_issue_polled(instance, cmd);
4834 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4835 }
4836
4837 switch (ret) {
4838 case DCMD_SUCCESS:
4839 /* Fill the internal pd_list and ld_ids array based on
4840 * targetIds returned by FW
4841 */
4842 count = le32_to_cpu(ci->count);
4843
Chandrakanth Patila4413a52019-06-25 16:34:27 +05304844 if (count > (MEGASAS_MAX_PD + MAX_LOGICAL_DRIVES_EXT))
4845 break;
4846
Shivasharan S0a11c0b2019-05-07 10:05:47 -07004847 if (megasas_dbg_lvl & LD_PD_DEBUG)
4848 dev_info(&instance->pdev->dev, "%s, Device count: 0x%x\n",
4849 __func__, count);
4850
Shivasharan Sf6fe5732019-01-29 01:38:14 -08004851 memset(instance->local_pd_list, 0,
4852 MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
4853 memset(instance->ld_ids, 0xff, MAX_LOGICAL_DRIVES_EXT);
4854 for (i = 0; i < count; i++) {
4855 target_id = le16_to_cpu(ci->host_device_list[i].target_id);
4856 if (ci->host_device_list[i].flags.u.bits.is_sys_pd) {
4857 instance->local_pd_list[target_id].tid = target_id;
4858 instance->local_pd_list[target_id].driveType =
4859 ci->host_device_list[i].scsi_type;
4860 instance->local_pd_list[target_id].driveState =
4861 MR_PD_STATE_SYSTEM;
Shivasharan S0a11c0b2019-05-07 10:05:47 -07004862 if (megasas_dbg_lvl & LD_PD_DEBUG)
4863 dev_info(&instance->pdev->dev,
4864 "Device %d: PD targetID: 0x%03x deviceType:0x%x\n",
4865 i, target_id, ci->host_device_list[i].scsi_type);
Shivasharan Sf6fe5732019-01-29 01:38:14 -08004866 } else {
4867 instance->ld_ids[target_id] = target_id;
Shivasharan S0a11c0b2019-05-07 10:05:47 -07004868 if (megasas_dbg_lvl & LD_PD_DEBUG)
4869 dev_info(&instance->pdev->dev,
4870 "Device %d: LD targetID: 0x%03x\n",
4871 i, target_id);
Shivasharan Sf6fe5732019-01-29 01:38:14 -08004872 }
4873 }
4874
4875 memcpy(instance->pd_list, instance->local_pd_list,
4876 sizeof(instance->pd_list));
4877 break;
4878
4879 case DCMD_TIMEOUT:
4880 switch (dcmd_timeout_ocr_possible(instance)) {
4881 case INITIATE_OCR:
4882 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05304883 mutex_unlock(&instance->reset_mutex);
Shivasharan Sf6fe5732019-01-29 01:38:14 -08004884 megasas_reset_fusion(instance->host,
4885 MFI_IO_TIMEOUT_OCR);
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05304886 mutex_lock(&instance->reset_mutex);
Shivasharan Sf6fe5732019-01-29 01:38:14 -08004887 break;
4888 case KILL_ADAPTER:
4889 megaraid_sas_kill_hba(instance);
4890 break;
4891 case IGNORE_TIMEOUT:
4892 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
4893 __func__, __LINE__);
4894 break;
4895 }
4896 break;
4897 case DCMD_FAILED:
4898 dev_err(&instance->pdev->dev,
4899 "%s: MR_DCMD_CTRL_DEVICE_LIST_GET failed\n",
4900 __func__);
4901 break;
4902 }
4903
4904 if (ret != DCMD_TIMEOUT)
4905 megasas_return_cmd(instance, cmd);
4906
4907 return ret;
4908}
4909
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304910/*
4911 * megasas_update_ext_vd_details : Update details w.r.t Extended VD
4912 * instance : Controller's instance
4913*/
4914static void megasas_update_ext_vd_details(struct megasas_instance *instance)
4915{
4916 struct fusion_context *fusion;
Sasikumar Chandrasekarand8893442017-01-10 18:20:48 -05004917 u32 ventura_map_sz = 0;
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304918
4919 fusion = instance->ctrl_context;
4920 /* For MFI based controllers return dummy success */
4921 if (!fusion)
4922 return;
4923
4924 instance->supportmax256vd =
Shivasharan S9ad18a92017-10-19 02:48:57 -07004925 instance->ctrl_info_buf->adapterOperations3.supportMaxExtLDs;
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304926 /* Below is additional check to address future FW enhancement */
Shivasharan S9ad18a92017-10-19 02:48:57 -07004927 if (instance->ctrl_info_buf->max_lds > 64)
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304928 instance->supportmax256vd = 1;
4929
4930 instance->drv_supported_vd_count = MEGASAS_MAX_LD_CHANNELS
4931 * MEGASAS_MAX_DEV_PER_CHANNEL;
4932 instance->drv_supported_pd_count = MEGASAS_MAX_PD_CHANNELS
4933 * MEGASAS_MAX_DEV_PER_CHANNEL;
4934 if (instance->supportmax256vd) {
4935 instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT;
4936 instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
4937 } else {
4938 instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
4939 instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
4940 }
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05304941
4942 dev_info(&instance->pdev->dev,
Shivasharan Scba67d92018-10-16 23:37:56 -07004943 "FW provided supportMaxExtLDs: %d\tmax_lds: %d\n",
4944 instance->ctrl_info_buf->adapterOperations3.supportMaxExtLDs ? 1 : 0,
4945 instance->ctrl_info_buf->max_lds);
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304946
Sasikumar Chandrasekarand8893442017-01-10 18:20:48 -05004947 if (instance->max_raid_mapsize) {
4948 ventura_map_sz = instance->max_raid_mapsize *
4949 MR_MIN_MAP_SIZE; /* 64k */
4950 fusion->current_map_sz = ventura_map_sz;
4951 fusion->max_map_sz = ventura_map_sz;
4952 } else {
4953 fusion->old_map_sz = sizeof(struct MR_FW_RAID_MAP) +
4954 (sizeof(struct MR_LD_SPAN_MAP) *
4955 (instance->fw_supported_vd_count - 1));
4956 fusion->new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT);
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304957
Sasikumar Chandrasekarand8893442017-01-10 18:20:48 -05004958 fusion->max_map_sz =
4959 max(fusion->old_map_sz, fusion->new_map_sz);
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304960
Sasikumar Chandrasekarand8893442017-01-10 18:20:48 -05004961 if (instance->supportmax256vd)
4962 fusion->current_map_sz = fusion->new_map_sz;
4963 else
4964 fusion->current_map_sz = fusion->old_map_sz;
4965 }
4966 /* irrespective of FW raid maps, driver raid map is constant */
4967 fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL);
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304968}
4969
Shivasharan Sf0c21df2018-10-16 23:37:40 -07004970/*
4971 * dcmd.opcode - MR_DCMD_CTRL_SNAPDUMP_GET_PROPERTIES
4972 * dcmd.hdr.length - number of bytes to read
4973 * dcmd.sge - Ptr to MR_SNAPDUMP_PROPERTIES
4974 * Desc: Fill in snapdump properties
4975 * Status: MFI_STAT_OK- Command successful
4976 */
4977void megasas_get_snapdump_properties(struct megasas_instance *instance)
4978{
4979 int ret = 0;
4980 struct megasas_cmd *cmd;
4981 struct megasas_dcmd_frame *dcmd;
4982 struct MR_SNAPDUMP_PROPERTIES *ci;
4983 dma_addr_t ci_h = 0;
4984
4985 ci = instance->snapdump_prop;
4986 ci_h = instance->snapdump_prop_h;
4987
4988 if (!ci)
4989 return;
4990
4991 cmd = megasas_get_cmd(instance);
4992
4993 if (!cmd) {
4994 dev_dbg(&instance->pdev->dev, "Failed to get a free cmd\n");
4995 return;
4996 }
4997
4998 dcmd = &cmd->frame->dcmd;
4999
5000 memset(ci, 0, sizeof(*ci));
5001 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
5002
5003 dcmd->cmd = MFI_CMD_DCMD;
5004 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
5005 dcmd->sge_count = 1;
5006 dcmd->flags = MFI_FRAME_DIR_READ;
5007 dcmd->timeout = 0;
5008 dcmd->pad_0 = 0;
5009 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_SNAPDUMP_PROPERTIES));
5010 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SNAPDUMP_GET_PROPERTIES);
5011
5012 megasas_set_dma_settings(instance, dcmd, ci_h,
5013 sizeof(struct MR_SNAPDUMP_PROPERTIES));
5014
5015 if (!instance->mask_interrupts) {
5016 ret = megasas_issue_blocked_cmd(instance, cmd,
5017 MFI_IO_TIMEOUT_SECS);
5018 } else {
5019 ret = megasas_issue_polled(instance, cmd);
5020 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
5021 }
5022
5023 switch (ret) {
5024 case DCMD_SUCCESS:
5025 instance->snapdump_wait_time =
5026 min_t(u8, ci->trigger_min_num_sec_before_ocr,
5027 MEGASAS_MAX_SNAP_DUMP_WAIT_TIME);
5028 break;
5029
5030 case DCMD_TIMEOUT:
5031 switch (dcmd_timeout_ocr_possible(instance)) {
5032 case INITIATE_OCR:
5033 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05305034 mutex_unlock(&instance->reset_mutex);
Shivasharan Sf0c21df2018-10-16 23:37:40 -07005035 megasas_reset_fusion(instance->host,
5036 MFI_IO_TIMEOUT_OCR);
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05305037 mutex_lock(&instance->reset_mutex);
Shivasharan Sf0c21df2018-10-16 23:37:40 -07005038 break;
5039 case KILL_ADAPTER:
5040 megaraid_sas_kill_hba(instance);
5041 break;
5042 case IGNORE_TIMEOUT:
5043 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
5044 __func__, __LINE__);
5045 break;
5046 }
5047 }
5048
5049 if (ret != DCMD_TIMEOUT)
5050 megasas_return_cmd(instance, cmd);
5051}
5052
adam radford21c9e162013-09-06 15:27:14 -07005053/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005054 * megasas_get_controller_info - Returns FW's controller structure
5055 * @instance: Adapter soft state
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005056 *
5057 * Issues an internal command (DCMD) to get the FW's controller structure.
5058 * This information is mainly used to find out the maximum IO transfer per
5059 * command supported by the FW.
5060 */
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305061int
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05305062megasas_get_ctrl_info(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005063{
5064 int ret = 0;
5065 struct megasas_cmd *cmd;
5066 struct megasas_dcmd_frame *dcmd;
5067 struct megasas_ctrl_info *ci;
5068 dma_addr_t ci_h = 0;
5069
Shivasharan S9b3d0282017-10-19 02:48:56 -07005070 ci = instance->ctrl_info_buf;
5071 ci_h = instance->ctrl_info_buf_h;
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05305072
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005073 cmd = megasas_get_cmd(instance);
5074
5075 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005076 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a free cmd\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005077 return -ENOMEM;
5078 }
5079
5080 dcmd = &cmd->frame->dcmd;
5081
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005082 memset(ci, 0, sizeof(*ci));
5083 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
5084
5085 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05305086 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005087 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07005088 dcmd->flags = MFI_FRAME_DIR_READ;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005089 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07005090 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305091 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_ctrl_info));
5092 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_GET_INFO);
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305093 dcmd->mbox.b[0] = 1;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005094
Shivasharan S107a60d2017-10-19 02:49:05 -07005095 megasas_set_dma_settings(instance, dcmd, ci_h,
5096 sizeof(struct megasas_ctrl_info));
5097
Shivasharan Se7d36b82017-10-19 02:48:50 -07005098 if ((instance->adapter_type != MFI_SERIES) &&
Shivasharan S54b28042018-01-05 05:27:47 -08005099 !instance->mask_interrupts) {
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305100 ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
Shivasharan S54b28042018-01-05 05:27:47 -08005101 } else {
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05305102 ret = megasas_issue_polled(instance, cmd);
Shivasharan S54b28042018-01-05 05:27:47 -08005103 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
5104 }
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05305105
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305106 switch (ret) {
5107 case DCMD_SUCCESS:
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305108 /* Save required controller information in
5109 * CPU endianness format.
5110 */
Shivasharan S9ad18a92017-10-19 02:48:57 -07005111 le32_to_cpus((u32 *)&ci->properties.OnOffProperties);
Shivasharan Sf0c21df2018-10-16 23:37:40 -07005112 le16_to_cpus((u16 *)&ci->properties.on_off_properties2);
Shivasharan S9ad18a92017-10-19 02:48:57 -07005113 le32_to_cpus((u32 *)&ci->adapterOperations2);
5114 le32_to_cpus((u32 *)&ci->adapterOperations3);
5115 le16_to_cpus((u16 *)&ci->adapter_operations4);
Chandrakanth Patil58136852019-06-25 16:34:30 +05305116 le32_to_cpus((u32 *)&ci->adapter_operations5);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305117
5118 /* Update the latest Ext VD info.
5119 * From Init path, store current firmware details.
5120 * From OCR path, detect any firmware properties changes.
5121 * in case of Firmware upgrade without system reboot.
5122 */
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05305123 megasas_update_ext_vd_details(instance);
Chandrakanth Patil59db5a92019-06-25 16:34:26 +05305124 instance->support_seqnum_jbod_fp =
Shivasharan S9ad18a92017-10-19 02:48:57 -07005125 ci->adapterOperations3.useSeqNumJbodFP;
Sasikumar Chandrasekaranede7c3c2017-01-10 18:20:52 -05005126 instance->support_morethan256jbod =
Shivasharan S9ad18a92017-10-19 02:48:57 -07005127 ci->adapter_operations4.support_pd_map_target_id;
Shivasharan Sf870bcb2018-01-05 05:33:04 -08005128 instance->support_nvme_passthru =
5129 ci->adapter_operations4.support_nvme_passthru;
Chandrakanth Patil58136852019-06-25 16:34:30 +05305130 instance->support_pci_lane_margining =
5131 ci->adapter_operations5.support_pci_lane_margining;
Shivasharan Se9495e22018-06-04 03:45:12 -07005132 instance->task_abort_tmo = ci->TaskAbortTO;
5133 instance->max_reset_tmo = ci->MaxResetTO;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305134
5135 /*Check whether controller is iMR or MR */
Shivasharan S9ad18a92017-10-19 02:48:57 -07005136 instance->is_imr = (ci->memory_size ? 0 : 1);
Shivasharan Sf0c21df2018-10-16 23:37:40 -07005137
5138 instance->snapdump_wait_time =
5139 (ci->properties.on_off_properties2.enable_snap_dump ?
5140 MEGASAS_DEFAULT_SNAP_DUMP_WAIT_TIME : 0);
5141
Shivasharan Sf6fe5732019-01-29 01:38:14 -08005142 instance->enable_fw_dev_list =
5143 ci->properties.on_off_properties2.enable_fw_dev_list;
5144
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05305145 dev_info(&instance->pdev->dev,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305146 "controller type\t: %s(%dMB)\n",
5147 instance->is_imr ? "iMR" : "MR",
Shivasharan S9ad18a92017-10-19 02:48:57 -07005148 le16_to_cpu(ci->memory_size));
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305149
sumit.saxena@avagotech.comc4bd2652015-10-15 13:40:14 +05305150 instance->disableOnlineCtrlReset =
Shivasharan S9ad18a92017-10-19 02:48:57 -07005151 ci->properties.OnOffProperties.disableOnlineCtrlReset;
sumit.saxena@avagotech.com32222512015-10-15 13:40:24 +05305152 instance->secure_jbod_support =
Shivasharan S9ad18a92017-10-19 02:48:57 -07005153 ci->adapterOperations3.supportSecurityonJBOD;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305154 dev_info(&instance->pdev->dev, "Online Controller Reset(OCR)\t: %s\n",
5155 instance->disableOnlineCtrlReset ? "Disabled" : "Enabled");
sumit.saxena@avagotech.com32222512015-10-15 13:40:24 +05305156 dev_info(&instance->pdev->dev, "Secure JBOD support\t: %s\n",
5157 instance->secure_jbod_support ? "Yes" : "No");
Shivasharan Sf870bcb2018-01-05 05:33:04 -08005158 dev_info(&instance->pdev->dev, "NVMe passthru support\t: %s\n",
5159 instance->support_nvme_passthru ? "Yes" : "No");
Shivasharan Se9495e22018-06-04 03:45:12 -07005160 dev_info(&instance->pdev->dev,
5161 "FW provided TM TaskAbort/Reset timeout\t: %d secs/%d secs\n",
5162 instance->task_abort_tmo, instance->max_reset_tmo);
Chandrakanth Patil59db5a92019-06-25 16:34:26 +05305163 dev_info(&instance->pdev->dev, "JBOD sequence map support\t: %s\n",
5164 instance->support_seqnum_jbod_fp ? "Yes" : "No");
Chandrakanth Patil58136852019-06-25 16:34:30 +05305165 dev_info(&instance->pdev->dev, "PCI Lane Margining support\t: %s\n",
5166 instance->support_pci_lane_margining ? "Yes" : "No");
Shivasharan Se9495e22018-06-04 03:45:12 -07005167
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305168 break;
5169
5170 case DCMD_TIMEOUT:
5171 switch (dcmd_timeout_ocr_possible(instance)) {
5172 case INITIATE_OCR:
5173 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05305174 mutex_unlock(&instance->reset_mutex);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305175 megasas_reset_fusion(instance->host,
5176 MFI_IO_TIMEOUT_OCR);
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05305177 mutex_lock(&instance->reset_mutex);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305178 break;
5179 case KILL_ADAPTER:
5180 megaraid_sas_kill_hba(instance);
5181 break;
5182 case IGNORE_TIMEOUT:
5183 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
5184 __func__, __LINE__);
5185 break;
5186 }
Shivasharan S2747e6b2018-06-04 03:45:09 -07005187 break;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305188 case DCMD_FAILED:
5189 megaraid_sas_kill_hba(instance);
5190 break;
5191
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05305192 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005193
Shivasharan S2747e6b2018-06-04 03:45:09 -07005194 if (ret != DCMD_TIMEOUT)
5195 megasas_return_cmd(instance, cmd);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305196
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005197 return ret;
5198}
5199
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05305200/*
5201 * megasas_set_crash_dump_params - Sends address of crash dump DMA buffer
5202 * to firmware
5203 *
5204 * @instance: Adapter soft state
5205 * @crash_buf_state - tell FW to turn ON/OFF crash dump feature
5206 MR_CRASH_BUF_TURN_OFF = 0
5207 MR_CRASH_BUF_TURN_ON = 1
5208 * @return 0 on success non-zero on failure.
5209 * Issues an internal command (DCMD) to set parameters for crash dump feature.
5210 * Driver will send address of crash dump DMA buffer and set mbox to tell FW
5211 * that driver supports crash dump feature. This DCMD will be sent only if
5212 * crash dump feature is supported by the FW.
5213 *
5214 */
5215int megasas_set_crash_dump_params(struct megasas_instance *instance,
5216 u8 crash_buf_state)
5217{
5218 int ret = 0;
5219 struct megasas_cmd *cmd;
5220 struct megasas_dcmd_frame *dcmd;
5221
5222 cmd = megasas_get_cmd(instance);
5223
5224 if (!cmd) {
5225 dev_err(&instance->pdev->dev, "Failed to get a free cmd\n");
5226 return -ENOMEM;
5227 }
5228
5229
5230 dcmd = &cmd->frame->dcmd;
5231
5232 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
5233 dcmd->mbox.b[0] = crash_buf_state;
5234 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05305235 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05305236 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07005237 dcmd->flags = MFI_FRAME_DIR_NONE;
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05305238 dcmd->timeout = 0;
5239 dcmd->pad_0 = 0;
5240 dcmd->data_xfer_len = cpu_to_le32(CRASH_DMA_BUF_SIZE);
5241 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SET_CRASH_DUMP_PARAMS);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05305242
Shivasharan S107a60d2017-10-19 02:49:05 -07005243 megasas_set_dma_settings(instance, dcmd, instance->crash_dump_h,
5244 CRASH_DMA_BUF_SIZE);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05305245
Shivasharan Se7d36b82017-10-19 02:48:50 -07005246 if ((instance->adapter_type != MFI_SERIES) &&
5247 !instance->mask_interrupts)
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305248 ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05305249 else
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05305250 ret = megasas_issue_polled(instance, cmd);
5251
Sumit Saxena6d40afb2016-01-28 21:04:23 +05305252 if (ret == DCMD_TIMEOUT) {
5253 switch (dcmd_timeout_ocr_possible(instance)) {
5254 case INITIATE_OCR:
5255 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
5256 megasas_reset_fusion(instance->host,
5257 MFI_IO_TIMEOUT_OCR);
5258 break;
5259 case KILL_ADAPTER:
5260 megaraid_sas_kill_hba(instance);
5261 break;
5262 case IGNORE_TIMEOUT:
5263 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
5264 __func__, __LINE__);
5265 break;
5266 }
5267 } else
5268 megasas_return_cmd(instance, cmd);
5269
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05305270 return ret;
5271}
5272
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005273/**
bo yang31ea7082007-11-07 12:09:50 -05005274 * megasas_issue_init_mfi - Initializes the FW
5275 * @instance: Adapter soft state
5276 *
5277 * Issues the INIT MFI cmd
5278 */
5279static int
5280megasas_issue_init_mfi(struct megasas_instance *instance)
5281{
Christoph Hellwig9ab9ed382015-04-23 16:32:54 +05305282 __le32 context;
bo yang31ea7082007-11-07 12:09:50 -05005283 struct megasas_cmd *cmd;
bo yang31ea7082007-11-07 12:09:50 -05005284 struct megasas_init_frame *init_frame;
5285 struct megasas_init_queue_info *initq_info;
5286 dma_addr_t init_frame_h;
5287 dma_addr_t initq_info_h;
5288
5289 /*
5290 * Prepare a init frame. Note the init frame points to queue info
5291 * structure. Each frame has SGL allocated after first 64 bytes. For
5292 * this frame - since we don't need any SGL - we use SGL's space as
5293 * queue info structure
5294 *
5295 * We will not get a NULL command below. We just created the pool.
5296 */
5297 cmd = megasas_get_cmd(instance);
5298
5299 init_frame = (struct megasas_init_frame *)cmd->frame;
5300 initq_info = (struct megasas_init_queue_info *)
5301 ((unsigned long)init_frame + 64);
5302
5303 init_frame_h = cmd->frame_phys_addr;
5304 initq_info_h = init_frame_h + 64;
5305
5306 context = init_frame->context;
5307 memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
5308 memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
5309 init_frame->context = context;
5310
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305311 initq_info->reply_queue_entries = cpu_to_le32(instance->max_fw_cmds + 1);
5312 initq_info->reply_queue_start_phys_addr_lo = cpu_to_le32(instance->reply_queue_h);
bo yang31ea7082007-11-07 12:09:50 -05005313
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305314 initq_info->producer_index_phys_addr_lo = cpu_to_le32(instance->producer_h);
5315 initq_info->consumer_index_phys_addr_lo = cpu_to_le32(instance->consumer_h);
bo yang31ea7082007-11-07 12:09:50 -05005316
5317 init_frame->cmd = MFI_CMD_INIT;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05305318 init_frame->cmd_status = MFI_STAT_INVALID_STATUS;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305319 init_frame->queue_info_new_phys_addr_lo =
5320 cpu_to_le32(lower_32_bits(initq_info_h));
5321 init_frame->queue_info_new_phys_addr_hi =
5322 cpu_to_le32(upper_32_bits(initq_info_h));
bo yang31ea7082007-11-07 12:09:50 -05005323
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305324 init_frame->data_xfer_len = cpu_to_le32(sizeof(struct megasas_init_queue_info));
bo yang31ea7082007-11-07 12:09:50 -05005325
5326 /*
5327 * disable the intr before firing the init frame to FW
5328 */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305329 instance->instancet->disable_intr(instance);
bo yang31ea7082007-11-07 12:09:50 -05005330
5331 /*
5332 * Issue the init frame in polled mode
5333 */
5334
5335 if (megasas_issue_polled(instance, cmd)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005336 dev_err(&instance->pdev->dev, "Failed to init firmware\n");
bo yang31ea7082007-11-07 12:09:50 -05005337 megasas_return_cmd(instance, cmd);
5338 goto fail_fw_init;
5339 }
5340
5341 megasas_return_cmd(instance, cmd);
5342
5343 return 0;
5344
5345fail_fw_init:
5346 return -EINVAL;
5347}
5348
adam radfordcd50ba82010-12-21 10:23:23 -08005349static u32
5350megasas_init_adapter_mfi(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005351{
5352 u32 context_sz;
5353 u32 reply_q_sz;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005354
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005355 /*
5356 * Get various operational parameters from status register
5357 */
Shivasharan Sde516372018-12-17 00:47:39 -08005358 instance->max_fw_cmds = instance->instancet->read_fw_status_reg(instance) & 0x00FFFF;
Sumant Patroe3bbff92006-10-03 12:28:49 -07005359 /*
5360 * Reduce the max supported cmds by 1. This is to ensure that the
5361 * reply_q_sz (1 more than the max cmd that driver may send)
5362 * does not exceed max cmds that the FW can support
5363 */
5364 instance->max_fw_cmds = instance->max_fw_cmds-1;
adam radford9c915a82010-12-21 13:34:31 -08005365 instance->max_mfi_cmds = instance->max_fw_cmds;
Shivasharan Sde516372018-12-17 00:47:39 -08005366 instance->max_num_sge = (instance->instancet->read_fw_status_reg(instance) & 0xFF0000) >>
Sumant Patro1341c932006-01-25 12:02:40 -08005367 0x10;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005368 /*
Sumit.Saxena@avagotech.comf26ac3a2015-04-23 16:30:54 +05305369 * For MFI skinny adapters, MEGASAS_SKINNY_INT_CMDS commands
5370 * are reserved for IOCTL + driver's internal DCMDs.
5371 */
5372 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
5373 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
5374 instance->max_scsi_cmds = (instance->max_fw_cmds -
5375 MEGASAS_SKINNY_INT_CMDS);
5376 sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
5377 } else {
5378 instance->max_scsi_cmds = (instance->max_fw_cmds -
5379 MEGASAS_INT_CMDS);
5380 sema_init(&instance->ioctl_sem, (MEGASAS_MFI_IOCTL_CMDS));
5381 }
5382
Sumit Saxena308ec452016-01-28 21:04:30 +05305383 instance->cur_can_queue = instance->max_scsi_cmds;
Sumit.Saxena@avagotech.comf26ac3a2015-04-23 16:30:54 +05305384 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005385 * Create a pool of commands
5386 */
5387 if (megasas_alloc_cmds(instance))
5388 goto fail_alloc_cmds;
5389
5390 /*
5391 * Allocate memory for reply queue. Length of reply queue should
5392 * be _one_ more than the maximum commands handled by the firmware.
5393 *
5394 * Note: When FW completes commands, it places corresponding contex
5395 * values in this circular reply queue. This circular queue is a fairly
5396 * typical producer-consumer queue. FW is the producer (of completed
5397 * commands) and the driver is the consumer.
5398 */
5399 context_sz = sizeof(u32);
5400 reply_q_sz = context_sz * (instance->max_fw_cmds + 1);
5401
Christoph Hellwig60ee6522018-10-10 19:31:25 +02005402 instance->reply_queue = dma_alloc_coherent(&instance->pdev->dev,
5403 reply_q_sz, &instance->reply_queue_h, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005404
5405 if (!instance->reply_queue) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005406 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Out of DMA mem for reply queue\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005407 goto fail_reply_queue;
5408 }
5409
bo yang31ea7082007-11-07 12:09:50 -05005410 if (megasas_issue_init_mfi(instance))
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005411 goto fail_fw_init;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005412
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05305413 if (megasas_get_ctrl_info(instance)) {
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305414 dev_err(&instance->pdev->dev, "(%d): Could get controller info "
5415 "Fail from %s %d\n", instance->unique_id,
5416 __func__, __LINE__);
5417 goto fail_fw_init;
5418 }
5419
bo yang39a98552010-09-22 22:36:29 -04005420 instance->fw_support_ieee = 0;
5421 instance->fw_support_ieee =
Shivasharan Sde516372018-12-17 00:47:39 -08005422 (instance->instancet->read_fw_status_reg(instance) &
bo yang39a98552010-09-22 22:36:29 -04005423 0x04000000);
5424
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005425 dev_notice(&instance->pdev->dev, "megasas_init_mfi: fw_support_ieee=%d",
bo yang39a98552010-09-22 22:36:29 -04005426 instance->fw_support_ieee);
5427
5428 if (instance->fw_support_ieee)
5429 instance->flag_ieee = 1;
5430
adam radfordcd50ba82010-12-21 10:23:23 -08005431 return 0;
5432
5433fail_fw_init:
5434
Christoph Hellwig60ee6522018-10-10 19:31:25 +02005435 dma_free_coherent(&instance->pdev->dev, reply_q_sz,
adam radfordcd50ba82010-12-21 10:23:23 -08005436 instance->reply_queue, instance->reply_queue_h);
5437fail_reply_queue:
5438 megasas_free_cmds(instance);
5439
5440fail_alloc_cmds:
adam radfordcd50ba82010-12-21 10:23:23 -08005441 return 1;
5442}
5443
Shivasharan S62a04f82019-05-07 10:05:35 -07005444static
5445void megasas_setup_irq_poll(struct megasas_instance *instance)
5446{
5447 struct megasas_irq_context *irq_ctx;
5448 u32 count, i;
5449
5450 count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
5451
5452 /* Initialize IRQ poll */
5453 for (i = 0; i < count; i++) {
5454 irq_ctx = &instance->irq_context[i];
5455 irq_ctx->os_irq = pci_irq_vector(instance->pdev, i);
5456 irq_ctx->irq_poll_scheduled = false;
5457 irq_poll_init(&irq_ctx->irqpoll,
5458 instance->threshold_reply_count,
5459 megasas_irqpoll);
5460 }
5461}
5462
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305463/*
Hannes Reineckefad119b2016-12-02 12:52:23 +01005464 * megasas_setup_irqs_ioapic - register legacy interrupts.
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305465 * @instance: Adapter soft state
5466 *
5467 * Do not enable interrupt, only setup ISRs.
5468 *
5469 * Return 0 on success.
5470 */
5471static int
5472megasas_setup_irqs_ioapic(struct megasas_instance *instance)
5473{
5474 struct pci_dev *pdev;
5475
5476 pdev = instance->pdev;
5477 instance->irq_context[0].instance = instance;
5478 instance->irq_context[0].MSIxIndex = 0;
Hannes Reineckefad119b2016-12-02 12:52:23 +01005479 if (request_irq(pci_irq_vector(pdev, 0),
5480 instance->instancet->service_isr, IRQF_SHARED,
5481 "megasas", &instance->irq_context[0])) {
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305482 dev_err(&instance->pdev->dev,
5483 "Failed to register IRQ from %s %d\n",
5484 __func__, __LINE__);
5485 return -1;
5486 }
Chandrakanth Patil299ee422019-06-25 16:34:35 +05305487 instance->perf_mode = MR_LATENCY_PERF_MODE;
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305488 instance->low_latency_index_start = 0;
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305489 return 0;
5490}
5491
5492/**
5493 * megasas_setup_irqs_msix - register MSI-x interrupts.
5494 * @instance: Adapter soft state
5495 * @is_probe: Driver probe check
5496 *
5497 * Do not enable interrupt, only setup ISRs.
5498 *
5499 * Return 0 on success.
5500 */
5501static int
5502megasas_setup_irqs_msix(struct megasas_instance *instance, u8 is_probe)
5503{
Hannes Reineckefad119b2016-12-02 12:52:23 +01005504 int i, j;
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305505 struct pci_dev *pdev;
5506
5507 pdev = instance->pdev;
5508
5509 /* Try MSI-x */
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305510 for (i = 0; i < instance->msix_vectors; i++) {
5511 instance->irq_context[i].instance = instance;
5512 instance->irq_context[i].MSIxIndex = i;
Hannes Reineckefad119b2016-12-02 12:52:23 +01005513 if (request_irq(pci_irq_vector(pdev, i),
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305514 instance->instancet->service_isr, 0, "megasas",
5515 &instance->irq_context[i])) {
5516 dev_err(&instance->pdev->dev,
5517 "Failed to register IRQ for vector %d.\n", i);
Hannes Reineckefad119b2016-12-02 12:52:23 +01005518 for (j = 0; j < i; j++)
5519 free_irq(pci_irq_vector(pdev, j),
5520 &instance->irq_context[j]);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305521 /* Retry irq register for IO_APIC*/
5522 instance->msix_vectors = 0;
Shivasharan S1d15d902019-05-07 10:05:36 -07005523 instance->msix_load_balance = false;
Shivasharan S64ff64b2017-03-10 03:22:12 -08005524 if (is_probe) {
5525 pci_free_irq_vectors(instance->pdev);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305526 return megasas_setup_irqs_ioapic(instance);
Shivasharan S64ff64b2017-03-10 03:22:12 -08005527 } else {
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305528 return -1;
Shivasharan S64ff64b2017-03-10 03:22:12 -08005529 }
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305530 }
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305531 }
Shivasharan S1d15d902019-05-07 10:05:36 -07005532
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305533 return 0;
5534}
5535
5536/*
5537 * megasas_destroy_irqs- unregister interrupts.
5538 * @instance: Adapter soft state
5539 * return: void
5540 */
5541static void
5542megasas_destroy_irqs(struct megasas_instance *instance) {
5543
5544 int i;
Shivasharan S62a04f82019-05-07 10:05:35 -07005545 int count;
5546 struct megasas_irq_context *irq_ctx;
5547
5548 count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
5549 if (instance->adapter_type != MFI_SERIES) {
5550 for (i = 0; i < count; i++) {
5551 irq_ctx = &instance->irq_context[i];
5552 irq_poll_disable(&irq_ctx->irqpoll);
5553 }
5554 }
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305555
5556 if (instance->msix_vectors)
5557 for (i = 0; i < instance->msix_vectors; i++) {
Hannes Reineckefad119b2016-12-02 12:52:23 +01005558 free_irq(pci_irq_vector(instance->pdev, i),
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305559 &instance->irq_context[i]);
5560 }
5561 else
Hannes Reineckefad119b2016-12-02 12:52:23 +01005562 free_irq(pci_irq_vector(instance->pdev, 0),
5563 &instance->irq_context[0]);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305564}
5565
adam radfordcd50ba82010-12-21 10:23:23 -08005566/**
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05305567 * megasas_setup_jbod_map - setup jbod map for FP seq_number.
5568 * @instance: Adapter soft state
5569 * @is_probe: Driver probe check
5570 *
5571 * Return 0 on success.
5572 */
5573void
5574megasas_setup_jbod_map(struct megasas_instance *instance)
5575{
5576 int i;
5577 struct fusion_context *fusion = instance->ctrl_context;
5578 u32 pd_seq_map_sz;
5579
5580 pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
5581 (sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1));
5582
Chandrakanth Patil59db5a92019-06-25 16:34:26 +05305583 instance->use_seqnum_jbod_fp =
5584 instance->support_seqnum_jbod_fp;
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05305585 if (reset_devices || !fusion ||
Chandrakanth Patil59db5a92019-06-25 16:34:26 +05305586 !instance->support_seqnum_jbod_fp) {
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05305587 dev_info(&instance->pdev->dev,
Chandrakanth Patil59db5a92019-06-25 16:34:26 +05305588 "JBOD sequence map is disabled %s %d\n",
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05305589 __func__, __LINE__);
5590 instance->use_seqnum_jbod_fp = false;
5591 return;
5592 }
5593
5594 if (fusion->pd_seq_sync[0])
5595 goto skip_alloc;
5596
5597 for (i = 0; i < JBOD_MAPS_COUNT; i++) {
5598 fusion->pd_seq_sync[i] = dma_alloc_coherent
5599 (&instance->pdev->dev, pd_seq_map_sz,
5600 &fusion->pd_seq_phys[i], GFP_KERNEL);
5601 if (!fusion->pd_seq_sync[i]) {
5602 dev_err(&instance->pdev->dev,
5603 "Failed to allocate memory from %s %d\n",
5604 __func__, __LINE__);
5605 if (i == 1) {
5606 dma_free_coherent(&instance->pdev->dev,
5607 pd_seq_map_sz, fusion->pd_seq_sync[0],
5608 fusion->pd_seq_phys[0]);
5609 fusion->pd_seq_sync[0] = NULL;
5610 }
5611 instance->use_seqnum_jbod_fp = false;
5612 return;
5613 }
5614 }
5615
5616skip_alloc:
5617 if (!megasas_sync_pd_seq_num(instance, false) &&
5618 !megasas_sync_pd_seq_num(instance, true))
5619 instance->use_seqnum_jbod_fp = true;
5620 else
5621 instance->use_seqnum_jbod_fp = false;
5622}
5623
Ming Leiadbe5522018-03-13 17:42:40 +08005624static void megasas_setup_reply_map(struct megasas_instance *instance)
5625{
5626 const struct cpumask *mask;
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305627 unsigned int queue, cpu, low_latency_index_start;
Ming Leiadbe5522018-03-13 17:42:40 +08005628
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305629 low_latency_index_start = instance->low_latency_index_start;
5630
5631 for (queue = low_latency_index_start; queue < instance->msix_vectors; queue++) {
Ming Leiadbe5522018-03-13 17:42:40 +08005632 mask = pci_irq_get_affinity(instance->pdev, queue);
5633 if (!mask)
5634 goto fallback;
5635
5636 for_each_cpu(cpu, mask)
5637 instance->reply_map[cpu] = queue;
5638 }
5639 return;
5640
5641fallback:
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305642 queue = low_latency_index_start;
5643 for_each_possible_cpu(cpu) {
5644 instance->reply_map[cpu] = queue;
5645 if (queue == (instance->msix_vectors - 1))
5646 queue = low_latency_index_start;
5647 else
5648 queue++;
5649 }
Ming Leiadbe5522018-03-13 17:42:40 +08005650}
5651
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05305652/**
Shivasharan Sdaa06812019-01-29 01:38:12 -08005653 * megasas_get_device_list - Get the PD and LD device list from FW.
5654 * @instance: Adapter soft state
5655 * @return: Success or failure
5656 *
5657 * Issue DCMDs to Firmware to get the PD and LD list.
Shivasharan Sf6fe5732019-01-29 01:38:14 -08005658 * Based on the FW support, driver sends the HOST_DEVICE_LIST or combination
5659 * of PD_LIST/LD_LIST_QUERY DCMDs to get the device list.
Shivasharan Sdaa06812019-01-29 01:38:12 -08005660 */
5661static
5662int megasas_get_device_list(struct megasas_instance *instance)
5663{
5664 memset(instance->pd_list, 0,
5665 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
5666 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
5667
Shivasharan Sf6fe5732019-01-29 01:38:14 -08005668 if (instance->enable_fw_dev_list) {
5669 if (megasas_host_device_list_query(instance, true))
5670 return FAILED;
5671 } else {
5672 if (megasas_get_pd_list(instance) < 0) {
5673 dev_err(&instance->pdev->dev, "failed to get PD list\n");
5674 return FAILED;
5675 }
Shivasharan Sdaa06812019-01-29 01:38:12 -08005676
Shivasharan Sf6fe5732019-01-29 01:38:14 -08005677 if (megasas_ld_list_query(instance,
5678 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) {
5679 dev_err(&instance->pdev->dev, "failed to get LD list\n");
5680 return FAILED;
5681 }
Shivasharan Sdaa06812019-01-29 01:38:12 -08005682 }
5683
5684 return SUCCESS;
5685}
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305686
Chandrakanth Patilf0b9e7b2019-06-25 16:34:33 +05305687/**
5688 * megasas_set_high_iops_queue_affinity_hint - Set affinity hint for high IOPS queues
5689 * @instance: Adapter soft state
5690 * return: void
5691 */
5692static inline void
5693megasas_set_high_iops_queue_affinity_hint(struct megasas_instance *instance)
5694{
5695 int i;
5696 int local_numa_node;
5697
Chandrakanth Patil299ee422019-06-25 16:34:35 +05305698 if (instance->perf_mode == MR_BALANCED_PERF_MODE) {
Chandrakanth Patilf0b9e7b2019-06-25 16:34:33 +05305699 local_numa_node = dev_to_node(&instance->pdev->dev);
5700
5701 for (i = 0; i < instance->low_latency_index_start; i++)
5702 irq_set_affinity_hint(pci_irq_vector(instance->pdev, i),
5703 cpumask_of_node(local_numa_node));
5704 }
5705}
5706
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305707static int
5708__megasas_alloc_irq_vectors(struct megasas_instance *instance)
5709{
5710 int i, irq_flags;
5711 struct irq_affinity desc = { .pre_vectors = instance->low_latency_index_start };
5712 struct irq_affinity *descp = &desc;
5713
5714 irq_flags = PCI_IRQ_MSIX;
5715
5716 if (instance->smp_affinity_enable)
5717 irq_flags |= PCI_IRQ_AFFINITY;
5718 else
5719 descp = NULL;
5720
5721 i = pci_alloc_irq_vectors_affinity(instance->pdev,
5722 instance->low_latency_index_start,
5723 instance->msix_vectors, irq_flags, descp);
5724
5725 return i;
5726}
5727
5728/**
5729 * megasas_alloc_irq_vectors - Allocate IRQ vectors/enable MSI-x vectors
5730 * @instance: Adapter soft state
5731 * return: void
5732 */
5733static void
5734megasas_alloc_irq_vectors(struct megasas_instance *instance)
5735{
5736 int i;
5737 unsigned int num_msix_req;
5738
5739 i = __megasas_alloc_irq_vectors(instance);
5740
Chandrakanth Patil299ee422019-06-25 16:34:35 +05305741 if ((instance->perf_mode == MR_BALANCED_PERF_MODE) &&
5742 (i != instance->msix_vectors)) {
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305743 if (instance->msix_vectors)
5744 pci_free_irq_vectors(instance->pdev);
5745 /* Disable Balanced IOPS mode and try realloc vectors */
Chandrakanth Patil299ee422019-06-25 16:34:35 +05305746 instance->perf_mode = MR_LATENCY_PERF_MODE;
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305747 instance->low_latency_index_start = 1;
5748 num_msix_req = num_online_cpus() + instance->low_latency_index_start;
5749
5750 instance->msix_vectors = min(num_msix_req,
5751 instance->msix_vectors);
5752
5753 i = __megasas_alloc_irq_vectors(instance);
5754
5755 }
5756
5757 dev_info(&instance->pdev->dev,
5758 "requested/available msix %d/%d\n", instance->msix_vectors, i);
5759
5760 if (i > 0)
5761 instance->msix_vectors = i;
5762 else
5763 instance->msix_vectors = 0;
5764
Chandrakanth Patilf0b9e7b2019-06-25 16:34:33 +05305765 if (instance->smp_affinity_enable)
5766 megasas_set_high_iops_queue_affinity_hint(instance);
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305767}
5768
Shivasharan Sdaa06812019-01-29 01:38:12 -08005769/**
adam radfordcd50ba82010-12-21 10:23:23 -08005770 * megasas_init_fw - Initializes the FW
5771 * @instance: Adapter soft state
5772 *
5773 * This is the main function for initializing firmware
5774 */
5775
5776static int megasas_init_fw(struct megasas_instance *instance)
5777{
5778 u32 max_sectors_1;
Shivasharan S15dd0382017-02-10 00:59:10 -08005779 u32 max_sectors_2, tmp_sectors, msix_enable;
Shivasharan S81b76452018-10-16 23:37:51 -07005780 u32 scratch_pad_1, scratch_pad_2, scratch_pad_3, status_reg;
Ben Collins11f8a7b2013-09-13 12:46:44 -04005781 resource_size_t base_addr;
Shivasharan S9a598712019-05-07 10:05:42 -07005782 void *base_addr_phys;
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305783 struct megasas_ctrl_info *ctrl_info = NULL;
adam radfordcd50ba82010-12-21 10:23:23 -08005784 unsigned long bar_list;
Shivasharan Sce884182019-05-07 10:05:48 -07005785 int i, j, loop;
adam radford229fe472014-03-10 02:51:56 -07005786 struct IOV_111 *iovPtr;
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305787 struct fusion_context *fusion;
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305788 bool intr_coalescing;
5789 unsigned int num_msix_req;
Chandrakanth Patil299ee422019-06-25 16:34:35 +05305790 u16 lnksta, speed;
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305791
5792 fusion = instance->ctrl_context;
adam radfordcd50ba82010-12-21 10:23:23 -08005793
5794 /* Find first memory bar */
5795 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
Christophe JAILLET51f90392016-08-21 10:28:25 +02005796 instance->bar = find_first_bit(&bar_list, BITS_PER_LONG);
Yinghai Lue7f85162016-08-05 23:37:34 -07005797 if (pci_request_selected_regions(instance->pdev, 1<<instance->bar,
adam radfordcd50ba82010-12-21 10:23:23 -08005798 "megasas: LSI")) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005799 dev_printk(KERN_DEBUG, &instance->pdev->dev, "IO memory region busy!\n");
adam radfordcd50ba82010-12-21 10:23:23 -08005800 return -EBUSY;
5801 }
5802
Ben Collins11f8a7b2013-09-13 12:46:44 -04005803 base_addr = pci_resource_start(instance->pdev, instance->bar);
5804 instance->reg_set = ioremap_nocache(base_addr, 8192);
adam radfordcd50ba82010-12-21 10:23:23 -08005805
5806 if (!instance->reg_set) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005807 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to map IO mem\n");
adam radfordcd50ba82010-12-21 10:23:23 -08005808 goto fail_ioremap;
5809 }
5810
Shivasharan S9a598712019-05-07 10:05:42 -07005811 base_addr_phys = &base_addr;
5812 dev_printk(KERN_DEBUG, &instance->pdev->dev,
5813 "BAR:0x%lx BAR's base_addr(phys):%pa mapped virt_addr:0x%p\n",
5814 instance->bar, base_addr_phys, instance->reg_set);
5815
Shivasharan Se7d36b82017-10-19 02:48:50 -07005816 if (instance->adapter_type != MFI_SERIES)
adam radford9c915a82010-12-21 13:34:31 -08005817 instance->instancet = &megasas_instance_template_fusion;
Sasikumar Chandrasekaran9581ebe2017-01-10 18:20:49 -05005818 else {
5819 switch (instance->pdev->device) {
5820 case PCI_DEVICE_ID_LSI_SAS1078R:
5821 case PCI_DEVICE_ID_LSI_SAS1078DE:
5822 instance->instancet = &megasas_instance_template_ppc;
5823 break;
5824 case PCI_DEVICE_ID_LSI_SAS1078GEN2:
5825 case PCI_DEVICE_ID_LSI_SAS0079GEN2:
5826 instance->instancet = &megasas_instance_template_gen2;
5827 break;
5828 case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
5829 case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
5830 instance->instancet = &megasas_instance_template_skinny;
5831 break;
5832 case PCI_DEVICE_ID_LSI_SAS1064R:
5833 case PCI_DEVICE_ID_DELL_PERC5:
5834 default:
5835 instance->instancet = &megasas_instance_template_xscale;
5836 instance->pd_list_not_supported = 1;
5837 break;
5838 }
adam radfordcd50ba82010-12-21 10:23:23 -08005839 }
5840
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05305841 if (megasas_transition_to_ready(instance, 0)) {
Shivasharan S78409d42019-05-07 10:05:34 -07005842 dev_info(&instance->pdev->dev,
5843 "Failed to transition controller to ready from %s!\n",
5844 __func__);
Shivasharan Sf10fb852019-05-07 10:05:32 -07005845 if (instance->adapter_type != MFI_SERIES) {
Shivasharan Sde93b402018-10-16 23:37:42 -07005846 status_reg = instance->instancet->read_fw_status_reg(
Shivasharan Sde516372018-12-17 00:47:39 -08005847 instance);
Shivasharan Sf10fb852019-05-07 10:05:32 -07005848 if (status_reg & MFI_RESET_ADAPTER) {
Shivasharan S78409d42019-05-07 10:05:34 -07005849 if (megasas_adp_reset_wait_for_ready
5850 (instance, true, 0) == FAILED)
Shivasharan Sf10fb852019-05-07 10:05:32 -07005851 goto fail_ready_state;
5852 } else {
5853 goto fail_ready_state;
5854 }
5855 } else {
Shivasharan Sde93b402018-10-16 23:37:42 -07005856 atomic_set(&instance->fw_reset_no_pci_access, 1);
5857 instance->instancet->adp_reset
5858 (instance, instance->reg_set);
5859 atomic_set(&instance->fw_reset_no_pci_access, 0);
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05305860
Shivasharan Sde93b402018-10-16 23:37:42 -07005861 /*waiting for about 30 second before retry*/
5862 ssleep(30);
5863
5864 if (megasas_transition_to_ready(instance, 0))
5865 goto fail_ready_state;
Shivasharan Sde93b402018-10-16 23:37:42 -07005866 }
Shivasharan S78409d42019-05-07 10:05:34 -07005867
5868 dev_info(&instance->pdev->dev,
5869 "FW restarted successfully from %s!\n",
5870 __func__);
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05305871 }
adam radfordcd50ba82010-12-21 10:23:23 -08005872
Shivasharan Se5d65b42017-10-19 02:48:59 -07005873 megasas_init_ctrl_params(instance);
5874
Shivasharan S107a60d2017-10-19 02:49:05 -07005875 if (megasas_set_dma_mask(instance))
Shivasharan Se5d65b42017-10-19 02:48:59 -07005876 goto fail_ready_state;
5877
5878 if (megasas_alloc_ctrl_mem(instance))
5879 goto fail_alloc_dma_buf;
5880
5881 if (megasas_alloc_ctrl_dma_buffers(instance))
5882 goto fail_alloc_dma_buf;
5883
5884 fusion = instance->ctrl_context;
5885
Shivasharan S630d42b2018-12-17 00:47:37 -08005886 if (instance->adapter_type >= VENTURA_SERIES) {
Shivasharan S81b76452018-10-16 23:37:51 -07005887 scratch_pad_2 =
Shivasharan S272652f2018-12-17 00:47:40 -08005888 megasas_readl(instance,
5889 &instance->reg_set->outbound_scratch_pad_2);
Shivasharan S81b76452018-10-16 23:37:51 -07005890 instance->max_raid_mapsize = ((scratch_pad_2 >>
Sasikumar Chandrasekarand8893442017-01-10 18:20:48 -05005891 MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) &
5892 MR_MAX_RAID_MAP_SIZE_MASK);
5893 }
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305894
Chandrakanth Patil7fc55702019-06-25 16:34:29 +05305895 switch (instance->adapter_type) {
5896 case VENTURA_SERIES:
Chandrakanth Patil49f2bf12019-06-25 16:34:28 +05305897 fusion->pcie_bw_limitation = true;
Chandrakanth Patil7fc55702019-06-25 16:34:29 +05305898 break;
5899 case AERO_SERIES:
5900 fusion->r56_div_offload = true;
5901 break;
5902 default:
5903 break;
5904 }
Chandrakanth Patil49f2bf12019-06-25 16:34:28 +05305905
adam radford3f1abce2011-05-11 18:33:47 -07005906 /* Check if MSI-X is supported while in ready state */
Shivasharan Sde516372018-12-17 00:47:39 -08005907 msix_enable = (instance->instancet->read_fw_status_reg(instance) &
adam radford3f1abce2011-05-11 18:33:47 -07005908 0x4000000) >> 0x1a;
adam radfordc8e858f2011-10-08 18:15:13 -07005909 if (msix_enable && !msix_disable) {
Hannes Reineckefad119b2016-12-02 12:52:23 +01005910
Shivasharan S272652f2018-12-17 00:47:40 -08005911 scratch_pad_1 = megasas_readl
5912 (instance, &instance->reg_set->outbound_scratch_pad_1);
adam radfordc8e858f2011-10-08 18:15:13 -07005913 /* Check max MSI-X vectors */
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305914 if (fusion) {
Shivasharan Sc3651782017-10-19 02:48:48 -07005915 if (instance->adapter_type == THUNDERBOLT_SERIES) {
5916 /* Thunderbolt Series*/
Shivasharan S81b76452018-10-16 23:37:51 -07005917 instance->msix_vectors = (scratch_pad_1
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305918 & MR_MAX_REPLY_QUEUES_OFFSET) + 1;
Shivasharan Se29c3222018-10-16 23:37:46 -07005919 } else {
Shivasharan S81b76452018-10-16 23:37:51 -07005920 instance->msix_vectors = ((scratch_pad_1
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305921 & MR_MAX_REPLY_QUEUES_EXT_OFFSET)
5922 >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
Shivasharan Se29c3222018-10-16 23:37:46 -07005923
5924 /*
5925 * For Invader series, > 8 MSI-x vectors
5926 * supported by FW/HW implies combined
5927 * reply queue mode is enabled.
5928 * For Ventura series, > 16 MSI-x vectors
5929 * supported by FW/HW implies combined
5930 * reply queue mode is enabled.
5931 */
5932 switch (instance->adapter_type) {
5933 case INVADER_SERIES:
5934 if (instance->msix_vectors > 8)
5935 instance->msix_combined = true;
5936 break;
Shivasharan S154a7cd2018-12-17 00:47:38 -08005937 case AERO_SERIES:
Shivasharan Se29c3222018-10-16 23:37:46 -07005938 case VENTURA_SERIES:
5939 if (instance->msix_vectors > 16)
5940 instance->msix_combined = true;
5941 break;
5942 }
Sasikumar Chandrasekaran2493c672017-01-10 18:20:44 -05005943
Sumit Saxena179ac142016-01-28 21:04:28 +05305944 if (rdpq_enable)
Shivasharan S81b76452018-10-16 23:37:51 -07005945 instance->is_rdpq = (scratch_pad_1 & MR_RDPQ_MODE_OFFSET) ?
Sumit Saxena179ac142016-01-28 21:04:28 +05305946 1 : 0;
Shivasharan S1d15d902019-05-07 10:05:36 -07005947
5948 if (!instance->msix_combined) {
5949 instance->msix_load_balance = true;
5950 instance->smp_affinity_enable = false;
5951 }
5952
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305953 /* Save 1-15 reply post index address to local memory
5954 * Index 0 is already saved from reg offset
5955 * MPI2_REPLY_POST_HOST_INDEX_OFFSET
5956 */
5957 for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
5958 instance->reply_post_host_index_addr[loop] =
5959 (u32 __iomem *)
5960 ((u8 __iomem *)instance->reg_set +
5961 MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
5962 + (loop * 0x10));
5963 }
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305964 }
Shivasharan Sce884182019-05-07 10:05:48 -07005965
5966 dev_info(&instance->pdev->dev,
5967 "firmware supports msix\t: (%d)",
5968 instance->msix_vectors);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305969 if (msix_vectors)
5970 instance->msix_vectors = min(msix_vectors,
5971 instance->msix_vectors);
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305972 } else /* MFI adapters */
adam radfordc8e858f2011-10-08 18:15:13 -07005973 instance->msix_vectors = 1;
Shivasharan S1d15d902019-05-07 10:05:36 -07005974
Chandrakanth Patil132147d2019-06-25 16:34:31 +05305975
5976 /*
5977 * For Aero (if some conditions are met), driver will configure a
5978 * few additional reply queues with interrupt coalescing enabled.
5979 * These queues with interrupt coalescing enabled are called
5980 * High IOPS queues and rest of reply queues (based on number of
5981 * logical CPUs) are termed as Low latency queues.
5982 *
5983 * Total Number of reply queues = High IOPS queues + low latency queues
5984 *
5985 * For rest of fusion adapters, 1 additional reply queue will be
5986 * reserved for management commands, rest of reply queues
5987 * (based on number of logical CPUs) will be used for IOs and
5988 * referenced as IO queues.
5989 * Total Number of reply queues = 1 + IO queues
5990 *
5991 * MFI adapters supports single MSI-x so single reply queue
5992 * will be used for IO and management commands.
5993 */
5994
5995 intr_coalescing = (scratch_pad_1 & MR_INTR_COALESCING_SUPPORT_OFFSET) ?
5996 true : false;
5997 if (intr_coalescing &&
5998 (num_online_cpus() >= MR_HIGH_IOPS_QUEUE_COUNT) &&
5999 (instance->msix_vectors == MEGASAS_MAX_MSIX_QUEUES))
Chandrakanth Patil299ee422019-06-25 16:34:35 +05306000 instance->perf_mode = MR_BALANCED_PERF_MODE;
Chandrakanth Patil132147d2019-06-25 16:34:31 +05306001 else
Chandrakanth Patil299ee422019-06-25 16:34:35 +05306002 instance->perf_mode = MR_LATENCY_PERF_MODE;
Chandrakanth Patil132147d2019-06-25 16:34:31 +05306003
Chandrakanth Patil299ee422019-06-25 16:34:35 +05306004
6005 if (instance->adapter_type == AERO_SERIES) {
6006 pcie_capability_read_word(instance->pdev, PCI_EXP_LNKSTA, &lnksta);
6007 speed = lnksta & PCI_EXP_LNKSTA_CLS;
6008
6009 /*
6010 * For Aero, if PCIe link speed is <16 GT/s, then driver should operate
6011 * in latency perf mode and enable R1 PCI bandwidth algorithm
6012 */
6013 if (speed < 0x4) {
6014 instance->perf_mode = MR_LATENCY_PERF_MODE;
6015 fusion->pcie_bw_limitation = true;
6016 }
6017
6018 /*
6019 * Performance mode settings provided through module parameter-perf_mode will
6020 * take affect only for:
6021 * 1. Aero family of adapters.
6022 * 2. When user sets module parameter- perf_mode in range of 0-2.
6023 */
6024 if ((perf_mode >= MR_BALANCED_PERF_MODE) &&
6025 (perf_mode <= MR_LATENCY_PERF_MODE))
6026 instance->perf_mode = perf_mode;
6027 /*
6028 * If intr coalescing is not supported by controller FW, then IOPS
6029 * and Balanced modes are not feasible.
6030 */
6031 if (!intr_coalescing)
6032 instance->perf_mode = MR_LATENCY_PERF_MODE;
6033
6034 }
6035
6036 if (instance->perf_mode == MR_BALANCED_PERF_MODE)
Chandrakanth Patil132147d2019-06-25 16:34:31 +05306037 instance->low_latency_index_start =
6038 MR_HIGH_IOPS_QUEUE_COUNT;
6039 else
6040 instance->low_latency_index_start = 1;
6041
6042 num_msix_req = num_online_cpus() + instance->low_latency_index_start;
6043
6044 instance->msix_vectors = min(num_msix_req,
6045 instance->msix_vectors);
6046
6047 megasas_alloc_irq_vectors(instance);
6048 if (!instance->msix_vectors)
Shivasharan S1d15d902019-05-07 10:05:36 -07006049 instance->msix_load_balance = false;
adam radfordc8e858f2011-10-08 18:15:13 -07006050 }
Sasikumar Chandrasekaran2493c672017-01-10 18:20:44 -05006051 /*
6052 * MSI-X host index 0 is common for all adapter.
6053 * It is used for all MPT based Adapters.
6054 */
6055 if (instance->msix_combined) {
6056 instance->reply_post_host_index_addr[0] =
6057 (u32 *)((u8 *)instance->reg_set +
6058 MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET);
6059 } else {
6060 instance->reply_post_host_index_addr[0] =
6061 (u32 *)((u8 *)instance->reg_set +
6062 MPI2_REPLY_POST_HOST_INDEX_OFFSET);
6063 }
6064
Shivasharan S64ff64b2017-03-10 03:22:12 -08006065 if (!instance->msix_vectors) {
6066 i = pci_alloc_irq_vectors(instance->pdev, 1, 1, PCI_IRQ_LEGACY);
6067 if (i < 0)
Shivasharan S8a25fa12018-10-16 23:37:44 -07006068 goto fail_init_adapter;
Shivasharan S64ff64b2017-03-10 03:22:12 -08006069 }
adam radford3f1abce2011-05-11 18:33:47 -07006070
Ming Leiadbe5522018-03-13 17:42:40 +08006071 megasas_setup_reply_map(instance);
6072
Tomas Henzl258c3af2015-06-02 16:09:46 +05306073 dev_info(&instance->pdev->dev,
Tomas Henzl258c3af2015-06-02 16:09:46 +05306074 "current msix/online cpus\t: (%d/%d)\n",
6075 instance->msix_vectors, (unsigned int)num_online_cpus());
Sumit Saxena179ac142016-01-28 21:04:28 +05306076 dev_info(&instance->pdev->dev,
6077 "RDPQ mode\t: (%s)\n", instance->is_rdpq ? "enabled" : "disabled");
Tomas Henzl258c3af2015-06-02 16:09:46 +05306078
sumit.saxena@avagotech.com91626c22015-10-15 13:40:34 +05306079 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
6080 (unsigned long)instance);
6081
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05306082 /*
6083 * Below are default value for legacy Firmware.
6084 * non-fusion based controllers
6085 */
6086 instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
6087 instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
adam radfordcd50ba82010-12-21 10:23:23 -08006088 /* Get operational params, sge flags, send init cmd to controller */
6089 if (instance->instancet->init_adapter(instance))
adam radfordeb1b1232011-02-24 20:55:56 -08006090 goto fail_init_adapter;
adam radfordcd50ba82010-12-21 10:23:23 -08006091
Shivasharan S630d42b2018-12-17 00:47:37 -08006092 if (instance->adapter_type >= VENTURA_SERIES) {
Shivasharan S81b76452018-10-16 23:37:51 -07006093 scratch_pad_3 =
Shivasharan S272652f2018-12-17 00:47:40 -08006094 megasas_readl(instance,
6095 &instance->reg_set->outbound_scratch_pad_3);
Shivasharan S81b76452018-10-16 23:37:51 -07006096 if ((scratch_pad_3 & MR_NVME_PAGE_SIZE_MASK) >=
Shivasharan S15dd0382017-02-10 00:59:10 -08006097 MR_DEFAULT_NVME_PAGE_SHIFT)
6098 instance->nvme_page_size =
Shivasharan S81b76452018-10-16 23:37:51 -07006099 (1 << (scratch_pad_3 & MR_NVME_PAGE_SIZE_MASK));
Shivasharan S15dd0382017-02-10 00:59:10 -08006100
6101 dev_info(&instance->pdev->dev,
6102 "NVME page size\t: (%d)\n", instance->nvme_page_size);
6103 }
6104
Tomas Henzl18103ef2016-11-01 17:32:02 +01006105 if (instance->msix_vectors ?
6106 megasas_setup_irqs_msix(instance, 1) :
6107 megasas_setup_irqs_ioapic(instance))
6108 goto fail_init_adapter;
Tomas Henzl258c3af2015-06-02 16:09:46 +05306109
Shivasharan S62a04f82019-05-07 10:05:35 -07006110 if (instance->adapter_type != MFI_SERIES)
6111 megasas_setup_irq_poll(instance);
6112
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05306113 instance->instancet->enable_intr(instance);
adam radfordcd50ba82010-12-21 10:23:23 -08006114
Andy Lutomirski13f30772016-05-03 10:24:31 -07006115 dev_info(&instance->pdev->dev, "INIT adapter done\n");
adam radfordcd50ba82010-12-21 10:23:23 -08006116
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05306117 megasas_setup_jbod_map(instance);
6118
Shivasharan Sdaa06812019-01-29 01:38:12 -08006119 if (megasas_get_device_list(instance) != SUCCESS) {
6120 dev_err(&instance->pdev->dev,
6121 "%s: megasas_get_device_list failed\n",
6122 __func__);
Shivasharan S72bff2d2017-02-10 00:59:33 -08006123 goto fail_get_ld_pd_list;
Hannes Reinecke58968fc2014-01-16 11:25:36 +01006124 }
Yang, Bo81e403c2009-10-06 14:27:54 -06006125
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05006126 /* stream detection initialization */
Shivasharan S630d42b2018-12-17 00:47:37 -08006127 if (instance->adapter_type >= VENTURA_SERIES) {
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05006128 fusion->stream_detect_by_ld =
Kees Cook6396bb22018-06-12 14:03:40 -07006129 kcalloc(MAX_LOGICAL_DRIVES_EXT,
6130 sizeof(struct LD_STREAM_DETECT *),
6131 GFP_KERNEL);
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05006132 if (!fusion->stream_detect_by_ld) {
6133 dev_err(&instance->pdev->dev,
Shivasharan S41064f12017-02-10 00:59:37 -08006134 "unable to allocate stream detection for pool of LDs\n");
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05006135 goto fail_get_ld_pd_list;
6136 }
6137 for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) {
6138 fusion->stream_detect_by_ld[i] =
Shivasharan Se05ee4e2018-01-05 05:27:36 -08006139 kzalloc(sizeof(struct LD_STREAM_DETECT),
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05006140 GFP_KERNEL);
6141 if (!fusion->stream_detect_by_ld[i]) {
6142 dev_err(&instance->pdev->dev,
6143 "unable to allocate stream detect by LD\n ");
6144 for (j = 0; j < i; ++j)
6145 kfree(fusion->stream_detect_by_ld[j]);
6146 kfree(fusion->stream_detect_by_ld);
6147 fusion->stream_detect_by_ld = NULL;
6148 goto fail_get_ld_pd_list;
6149 }
6150 fusion->stream_detect_by_ld[i]->mru_bit_map
6151 = MR_STREAM_BITMAP;
6152 }
6153 }
6154
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006155 /*
6156 * Compute the max allowed sectors per IO: The controller info has two
6157 * limits on max sectors. Driver should use the minimum of these two.
6158 *
6159 * 1 << stripe_sz_ops.min = max sectors per strip
6160 *
6161 * Note that older firmwares ( < FW ver 30) didn't report information
6162 * to calculate max_sectors_1. So the number ended up as zero always.
6163 */
bo yang14faea92007-11-09 04:14:00 -05006164 tmp_sectors = 0;
Shivasharan S9ad18a92017-10-19 02:48:57 -07006165 ctrl_info = instance->ctrl_info_buf;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006166
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05306167 max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
6168 le16_to_cpu(ctrl_info->max_strips_per_io);
6169 max_sectors_2 = le32_to_cpu(ctrl_info->max_request_size);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006170
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05006171 tmp_sectors = min_t(u32, max_sectors_1, max_sectors_2);
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05306172
Sumit Saxena8f67c8c2016-01-28 21:14:25 +05306173 instance->peerIsPresent = ctrl_info->cluster.peerIsPresent;
6174 instance->passive = ctrl_info->cluster.passive;
6175 memcpy(instance->clusterId, ctrl_info->clusterId, sizeof(instance->clusterId));
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05306176 instance->UnevenSpanSupport =
6177 ctrl_info->adapterOperations2.supportUnevenSpans;
6178 if (instance->UnevenSpanSupport) {
6179 struct fusion_context *fusion = instance->ctrl_context;
Shivasharan S5f19f7c2018-01-05 05:27:44 -08006180 if (MR_ValidateMapInfo(instance, instance->map_id))
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05306181 fusion->fast_path_io = 1;
6182 else
6183 fusion->fast_path_io = 0;
6184
6185 }
6186 if (ctrl_info->host_interface.SRIOV) {
sumit.saxena@avagotech.com92bb6502015-08-31 17:24:11 +05306187 instance->requestorId = ctrl_info->iov.requestorId;
6188 if (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) {
6189 if (!ctrl_info->adapterOperations2.activePassive)
6190 instance->PlasmaFW111 = 1;
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05306191
sumit.saxena@avagotech.com92bb6502015-08-31 17:24:11 +05306192 dev_info(&instance->pdev->dev, "SR-IOV: firmware type: %s\n",
6193 instance->PlasmaFW111 ? "1.11" : "new");
6194
6195 if (instance->PlasmaFW111) {
6196 iovPtr = (struct IOV_111 *)
6197 ((unsigned char *)ctrl_info + IOV_111_OFFSET);
6198 instance->requestorId = iovPtr->requestorId;
6199 }
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05306200 }
sumit.saxena@avagotech.com92bb6502015-08-31 17:24:11 +05306201 dev_info(&instance->pdev->dev, "SRIOV: VF requestorId %d\n",
6202 instance->requestorId);
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05306203 }
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05306204
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05306205 instance->crash_dump_fw_support =
6206 ctrl_info->adapterOperations3.supportCrashDump;
6207 instance->crash_dump_drv_support =
6208 (instance->crash_dump_fw_support &&
6209 instance->crash_dump_buf);
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05306210 if (instance->crash_dump_drv_support)
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05306211 megasas_set_crash_dump_params(instance,
6212 MR_CRASH_BUF_TURN_OFF);
adam radford229fe472014-03-10 02:51:56 -07006213
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05306214 else {
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05306215 if (instance->crash_dump_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006216 dma_free_coherent(&instance->pdev->dev,
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05306217 CRASH_DMA_BUF_SIZE,
6218 instance->crash_dump_buf,
6219 instance->crash_dump_h);
6220 instance->crash_dump_buf = NULL;
bo yang14faea92007-11-09 04:14:00 -05006221 }
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05306222
Shivasharan Sf0c21df2018-10-16 23:37:40 -07006223 if (instance->snapdump_wait_time) {
6224 megasas_get_snapdump_properties(instance);
6225 dev_info(&instance->pdev->dev, "Snap dump wait time\t: %d\n",
6226 instance->snapdump_wait_time);
6227 }
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05306228
6229 dev_info(&instance->pdev->dev,
6230 "pci id\t\t: (0x%04x)/(0x%04x)/(0x%04x)/(0x%04x)\n",
6231 le16_to_cpu(ctrl_info->pci.vendor_id),
6232 le16_to_cpu(ctrl_info->pci.device_id),
6233 le16_to_cpu(ctrl_info->pci.sub_vendor_id),
6234 le16_to_cpu(ctrl_info->pci.sub_device_id));
6235 dev_info(&instance->pdev->dev, "unevenspan support : %s\n",
6236 instance->UnevenSpanSupport ? "yes" : "no");
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05306237 dev_info(&instance->pdev->dev, "firmware crash dump : %s\n",
6238 instance->crash_dump_drv_support ? "yes" : "no");
Chandrakanth Patil59db5a92019-06-25 16:34:26 +05306239 dev_info(&instance->pdev->dev, "JBOD sequence map : %s\n",
6240 instance->use_seqnum_jbod_fp ? "enabled" : "disabled");
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05306241
bo yang14faea92007-11-09 04:14:00 -05006242 instance->max_sectors_per_req = instance->max_num_sge *
sumit.saxena@avagotech.com357ae962015-10-15 13:40:04 +05306243 SGE_BUFFER_SIZE / 512;
bo yang14faea92007-11-09 04:14:00 -05006244 if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
6245 instance->max_sectors_per_req = tmp_sectors;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006246
Sumit.Saxena@avagotech.comae09a6c2015-01-05 20:06:23 +05306247 /* Check for valid throttlequeuedepth module parameter */
6248 if (throttlequeuedepth &&
6249 throttlequeuedepth <= instance->max_scsi_cmds)
6250 instance->throttlequeuedepth = throttlequeuedepth;
6251 else
6252 instance->throttlequeuedepth =
6253 MEGASAS_THROTTLE_QUEUE_DEPTH;
6254
Shivasharan Se636a7a2017-08-23 04:46:56 -07006255 if ((resetwaittime < 1) ||
6256 (resetwaittime > MEGASAS_RESET_WAIT_TIME))
Sumit Saxenae3d178c2016-01-28 21:04:34 +05306257 resetwaittime = MEGASAS_RESET_WAIT_TIME;
6258
6259 if ((scmd_timeout < 10) || (scmd_timeout > MEGASAS_DEFAULT_CMD_TIMEOUT))
6260 scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT;
bo yangad84db22007-11-09 04:40:16 -05006261
adam radford229fe472014-03-10 02:51:56 -07006262 /* Launch SR-IOV heartbeat timer */
6263 if (instance->requestorId) {
Shivasharan S2e47e4e2018-10-16 23:37:48 -07006264 if (!megasas_sriov_start_heartbeat(instance, 1)) {
Kees Cookc251a7b2017-10-22 15:30:04 -07006265 megasas_start_timer(instance);
Shivasharan S2e47e4e2018-10-16 23:37:48 -07006266 } else {
adam radford229fe472014-03-10 02:51:56 -07006267 instance->skip_heartbeat_timer_del = 1;
Shivasharan S2e47e4e2018-10-16 23:37:48 -07006268 goto fail_get_ld_pd_list;
6269 }
adam radford229fe472014-03-10 02:51:56 -07006270 }
6271
Shivasharan S3f6194a2018-10-16 23:37:39 -07006272 /*
6273 * Create and start watchdog thread which will monitor
6274 * controller state every 1 sec and trigger OCR when
6275 * it enters fault state
6276 */
6277 if (instance->adapter_type != MFI_SERIES)
6278 if (megasas_fusion_start_watchdog(instance) != SUCCESS)
6279 goto fail_start_watchdog;
6280
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006281 return 0;
6282
Shivasharan S3f6194a2018-10-16 23:37:39 -07006283fail_start_watchdog:
6284 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
6285 del_timer_sync(&instance->sriov_heartbeat_timer);
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05006286fail_get_ld_pd_list:
6287 instance->instancet->disable_intr(instance);
Hannes Reineckefad119b2016-12-02 12:52:23 +01006288 megasas_destroy_irqs(instance);
Shivasharan S8a25fa12018-10-16 23:37:44 -07006289fail_init_adapter:
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05306290 if (instance->msix_vectors)
Hannes Reineckefad119b2016-12-02 12:52:23 +01006291 pci_free_irq_vectors(instance->pdev);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05306292 instance->msix_vectors = 0;
Shivasharan Se5d65b42017-10-19 02:48:59 -07006293fail_alloc_dma_buf:
6294 megasas_free_ctrl_dma_buffers(instance);
6295 megasas_free_ctrl_mem(instance);
adam radfordcd50ba82010-12-21 10:23:23 -08006296fail_ready_state:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006297 iounmap(instance->reg_set);
6298
Shivasharan S72bff2d2017-02-10 00:59:33 -08006299fail_ioremap:
Yinghai Lue7f85162016-08-05 23:37:34 -07006300 pci_release_selected_regions(instance->pdev, 1<<instance->bar);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006301
Shivasharan S72bff2d2017-02-10 00:59:33 -08006302 dev_err(&instance->pdev->dev, "Failed from %s %d\n",
6303 __func__, __LINE__);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006304 return -EINVAL;
6305}
6306
6307/**
6308 * megasas_release_mfi - Reverses the FW initialization
Geert Uytterhoeven4b63b282015-03-03 11:58:07 +01006309 * @instance: Adapter soft state
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006310 */
6311static void megasas_release_mfi(struct megasas_instance *instance)
6312{
adam radford9c915a82010-12-21 13:34:31 -08006313 u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006314
adam radford9c915a82010-12-21 13:34:31 -08006315 if (instance->reply_queue)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006316 dma_free_coherent(&instance->pdev->dev, reply_q_sz,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006317 instance->reply_queue, instance->reply_queue_h);
6318
6319 megasas_free_cmds(instance);
6320
6321 iounmap(instance->reg_set);
6322
Yinghai Lue7f85162016-08-05 23:37:34 -07006323 pci_release_selected_regions(instance->pdev, 1<<instance->bar);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006324}
6325
6326/**
6327 * megasas_get_seq_num - Gets latest event sequence numbers
6328 * @instance: Adapter soft state
6329 * @eli: FW event log sequence numbers information
6330 *
6331 * FW maintains a log of all events in a non-volatile area. Upper layers would
6332 * usually find out the latest sequence number of the events, the seq number at
6333 * the boot etc. They would "read" all the events below the latest seq number
6334 * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq
6335 * number), they would subsribe to AEN (asynchronous event notification) and
6336 * wait for the events to happen.
6337 */
6338static int
6339megasas_get_seq_num(struct megasas_instance *instance,
6340 struct megasas_evt_log_info *eli)
6341{
6342 struct megasas_cmd *cmd;
6343 struct megasas_dcmd_frame *dcmd;
6344 struct megasas_evt_log_info *el_info;
6345 dma_addr_t el_info_h = 0;
Shivasharan Sb051cc62018-01-05 05:27:38 -08006346 int ret;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006347
6348 cmd = megasas_get_cmd(instance);
6349
6350 if (!cmd) {
6351 return -ENOMEM;
6352 }
6353
6354 dcmd = &cmd->frame->dcmd;
Luis Chamberlain750afb02019-01-04 09:23:09 +01006355 el_info = dma_alloc_coherent(&instance->pdev->dev,
6356 sizeof(struct megasas_evt_log_info),
6357 &el_info_h, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006358 if (!el_info) {
6359 megasas_return_cmd(instance, cmd);
6360 return -ENOMEM;
6361 }
6362
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006363 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
6364
6365 dcmd->cmd = MFI_CMD_DCMD;
6366 dcmd->cmd_status = 0x0;
6367 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07006368 dcmd->flags = MFI_FRAME_DIR_READ;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006369 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07006370 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306371 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_log_info));
6372 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_EVENT_GET_INFO);
Shivasharan S107a60d2017-10-19 02:49:05 -07006373
6374 megasas_set_dma_settings(instance, dcmd, el_info_h,
6375 sizeof(struct megasas_evt_log_info));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006376
Shivasharan Sb051cc62018-01-05 05:27:38 -08006377 ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
6378 if (ret != DCMD_SUCCESS) {
6379 dev_err(&instance->pdev->dev, "Failed from %s %d\n",
6380 __func__, __LINE__);
6381 goto dcmd_failed;
6382 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006383
Shivasharan Sb051cc62018-01-05 05:27:38 -08006384 /*
6385 * Copy the data back into callers buffer
6386 */
6387 eli->newest_seq_num = el_info->newest_seq_num;
6388 eli->oldest_seq_num = el_info->oldest_seq_num;
6389 eli->clear_seq_num = el_info->clear_seq_num;
6390 eli->shutdown_seq_num = el_info->shutdown_seq_num;
6391 eli->boot_seq_num = el_info->boot_seq_num;
6392
6393dcmd_failed:
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006394 dma_free_coherent(&instance->pdev->dev,
6395 sizeof(struct megasas_evt_log_info),
6396 el_info, el_info_h);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006397
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05306398 megasas_return_cmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006399
Shivasharan Sb051cc62018-01-05 05:27:38 -08006400 return ret;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006401}
6402
6403/**
6404 * megasas_register_aen - Registers for asynchronous event notification
6405 * @instance: Adapter soft state
6406 * @seq_num: The starting sequence number
6407 * @class_locale: Class of the event
6408 *
6409 * This function subscribes for AEN for events beyond the @seq_num. It requests
6410 * to be notified if and only if the event is of type @class_locale
6411 */
6412static int
6413megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
6414 u32 class_locale_word)
6415{
6416 int ret_val;
6417 struct megasas_cmd *cmd;
6418 struct megasas_dcmd_frame *dcmd;
6419 union megasas_evt_class_locale curr_aen;
6420 union megasas_evt_class_locale prev_aen;
6421
6422 /*
6423 * If there an AEN pending already (aen_cmd), check if the
6424 * class_locale of that pending AEN is inclusive of the new
6425 * AEN request we currently have. If it is, then we don't have
6426 * to do anything. In other words, whichever events the current
6427 * AEN request is subscribing to, have already been subscribed
6428 * to.
6429 *
6430 * If the old_cmd is _not_ inclusive, then we have to abort
6431 * that command, form a class_locale that is superset of both
6432 * old and current and re-issue to the FW
6433 */
6434
6435 curr_aen.word = class_locale_word;
6436
6437 if (instance->aen_cmd) {
6438
Christoph Hellwiga9555532015-04-23 16:34:24 +05306439 prev_aen.word =
6440 le32_to_cpu(instance->aen_cmd->frame->dcmd.mbox.w[1]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006441
Shivasharan S91b3d9f2017-08-23 04:47:01 -07006442 if ((curr_aen.members.class < MFI_EVT_CLASS_DEBUG) ||
6443 (curr_aen.members.class > MFI_EVT_CLASS_DEAD)) {
6444 dev_info(&instance->pdev->dev,
6445 "%s %d out of range class %d send by application\n",
6446 __func__, __LINE__, curr_aen.members.class);
6447 return 0;
6448 }
6449
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006450 /*
6451 * A class whose enum value is smaller is inclusive of all
6452 * higher values. If a PROGRESS (= -1) was previously
6453 * registered, then a new registration requests for higher
6454 * classes need not be sent to FW. They are automatically
6455 * included.
6456 *
6457 * Locale numbers don't have such hierarchy. They are bitmap
6458 * values
6459 */
6460 if ((prev_aen.members.class <= curr_aen.members.class) &&
Sumit.Saxena@lsi.com3993a862013-09-16 15:18:06 +05306461 !((prev_aen.members.locale & curr_aen.members.locale) ^
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006462 curr_aen.members.locale)) {
6463 /*
6464 * Previously issued event registration includes
6465 * current request. Nothing to do.
6466 */
6467 return 0;
6468 } else {
Sumit.Saxena@lsi.com3993a862013-09-16 15:18:06 +05306469 curr_aen.members.locale |= prev_aen.members.locale;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006470
6471 if (prev_aen.members.class < curr_aen.members.class)
6472 curr_aen.members.class = prev_aen.members.class;
6473
6474 instance->aen_cmd->abort_aen = 1;
6475 ret_val = megasas_issue_blocked_abort_cmd(instance,
6476 instance->
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05306477 aen_cmd, 30);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006478
6479 if (ret_val) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05006480 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to abort "
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006481 "previous AEN command\n");
6482 return ret_val;
6483 }
6484 }
6485 }
6486
6487 cmd = megasas_get_cmd(instance);
6488
6489 if (!cmd)
6490 return -ENOMEM;
6491
6492 dcmd = &cmd->frame->dcmd;
6493
6494 memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail));
6495
6496 /*
6497 * Prepare DCMD for aen registration
6498 */
6499 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
6500
6501 dcmd->cmd = MFI_CMD_DCMD;
6502 dcmd->cmd_status = 0x0;
6503 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07006504 dcmd->flags = MFI_FRAME_DIR_READ;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006505 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07006506 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306507 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_detail));
6508 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_EVENT_WAIT);
6509 dcmd->mbox.w[0] = cpu_to_le32(seq_num);
bo yang39a98552010-09-22 22:36:29 -04006510 instance->last_seq_num = seq_num;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306511 dcmd->mbox.w[1] = cpu_to_le32(curr_aen.word);
Shivasharan S107a60d2017-10-19 02:49:05 -07006512
6513 megasas_set_dma_settings(instance, dcmd, instance->evt_detail_h,
6514 sizeof(struct megasas_evt_detail));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006515
Yang, Bof4c9a132009-10-06 14:43:28 -06006516 if (instance->aen_cmd != NULL) {
6517 megasas_return_cmd(instance, cmd);
6518 return 0;
6519 }
6520
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006521 /*
6522 * Store reference to the cmd used to register for AEN. When an
6523 * application wants us to register for AEN, we have to abort this
6524 * cmd and re-register with a new EVENT LOCALE supplied by that app
6525 */
6526 instance->aen_cmd = cmd;
6527
6528 /*
6529 * Issue the aen registration frame
6530 */
adam radford9c915a82010-12-21 13:34:31 -08006531 instance->instancet->issue_dcmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006532
6533 return 0;
6534}
6535
Shivasharan S96188a82017-02-10 00:59:11 -08006536/* megasas_get_target_prop - Send DCMD with below details to firmware.
6537 *
6538 * This DCMD will fetch few properties of LD/system PD defined
6539 * in MR_TARGET_DEV_PROPERTIES. eg. Queue Depth, MDTS value.
6540 *
6541 * DCMD send by drivers whenever new target is added to the OS.
6542 *
6543 * dcmd.opcode - MR_DCMD_DEV_GET_TARGET_PROP
6544 * dcmd.mbox.b[0] - DCMD is to be fired for LD or system PD.
6545 * 0 = system PD, 1 = LD.
6546 * dcmd.mbox.s[1] - TargetID for LD/system PD.
6547 * dcmd.sge IN - Pointer to return MR_TARGET_DEV_PROPERTIES.
6548 *
6549 * @instance: Adapter soft state
6550 * @sdev: OS provided scsi device
6551 *
6552 * Returns 0 on success non-zero on failure.
6553 */
Shivasharan Se9495e22018-06-04 03:45:12 -07006554int
Shivasharan S96188a82017-02-10 00:59:11 -08006555megasas_get_target_prop(struct megasas_instance *instance,
6556 struct scsi_device *sdev)
6557{
6558 int ret;
6559 struct megasas_cmd *cmd;
6560 struct megasas_dcmd_frame *dcmd;
6561 u16 targetId = (sdev->channel % 2) + sdev->id;
6562
6563 cmd = megasas_get_cmd(instance);
6564
6565 if (!cmd) {
6566 dev_err(&instance->pdev->dev,
6567 "Failed to get cmd %s\n", __func__);
6568 return -ENOMEM;
6569 }
6570
6571 dcmd = &cmd->frame->dcmd;
6572
6573 memset(instance->tgt_prop, 0, sizeof(*instance->tgt_prop));
6574 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
6575 dcmd->mbox.b[0] = MEGASAS_IS_LOGICAL(sdev);
6576
6577 dcmd->mbox.s[1] = cpu_to_le16(targetId);
6578 dcmd->cmd = MFI_CMD_DCMD;
6579 dcmd->cmd_status = 0xFF;
6580 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07006581 dcmd->flags = MFI_FRAME_DIR_READ;
Shivasharan S96188a82017-02-10 00:59:11 -08006582 dcmd->timeout = 0;
6583 dcmd->pad_0 = 0;
6584 dcmd->data_xfer_len =
6585 cpu_to_le32(sizeof(struct MR_TARGET_PROPERTIES));
6586 dcmd->opcode = cpu_to_le32(MR_DCMD_DRV_GET_TARGET_PROP);
Shivasharan S96188a82017-02-10 00:59:11 -08006587
Shivasharan S107a60d2017-10-19 02:49:05 -07006588 megasas_set_dma_settings(instance, dcmd, instance->tgt_prop_h,
6589 sizeof(struct MR_TARGET_PROPERTIES));
Shivasharan S96188a82017-02-10 00:59:11 -08006590
Shivasharan Se7d36b82017-10-19 02:48:50 -07006591 if ((instance->adapter_type != MFI_SERIES) &&
6592 !instance->mask_interrupts)
Shivasharan S96188a82017-02-10 00:59:11 -08006593 ret = megasas_issue_blocked_cmd(instance,
6594 cmd, MFI_IO_TIMEOUT_SECS);
6595 else
6596 ret = megasas_issue_polled(instance, cmd);
6597
6598 switch (ret) {
6599 case DCMD_TIMEOUT:
6600 switch (dcmd_timeout_ocr_possible(instance)) {
6601 case INITIATE_OCR:
6602 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05306603 mutex_unlock(&instance->reset_mutex);
Shivasharan S96188a82017-02-10 00:59:11 -08006604 megasas_reset_fusion(instance->host,
6605 MFI_IO_TIMEOUT_OCR);
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05306606 mutex_lock(&instance->reset_mutex);
Shivasharan S96188a82017-02-10 00:59:11 -08006607 break;
6608 case KILL_ADAPTER:
6609 megaraid_sas_kill_hba(instance);
6610 break;
6611 case IGNORE_TIMEOUT:
6612 dev_info(&instance->pdev->dev,
6613 "Ignore DCMD timeout: %s %d\n",
6614 __func__, __LINE__);
6615 break;
6616 }
6617 break;
6618
6619 default:
6620 megasas_return_cmd(instance, cmd);
6621 }
6622 if (ret != DCMD_SUCCESS)
6623 dev_err(&instance->pdev->dev,
6624 "return from %s %d return value %d\n",
6625 __func__, __LINE__, ret);
6626
6627 return ret;
6628}
6629
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006630/**
6631 * megasas_start_aen - Subscribes to AEN during driver load time
6632 * @instance: Adapter soft state
6633 */
6634static int megasas_start_aen(struct megasas_instance *instance)
6635{
6636 struct megasas_evt_log_info eli;
6637 union megasas_evt_class_locale class_locale;
6638
6639 /*
6640 * Get the latest sequence number from FW
6641 */
6642 memset(&eli, 0, sizeof(eli));
6643
6644 if (megasas_get_seq_num(instance, &eli))
6645 return -1;
6646
6647 /*
6648 * Register AEN with FW for latest sequence number plus 1
6649 */
6650 class_locale.members.reserved = 0;
6651 class_locale.members.locale = MR_EVT_LOCALE_ALL;
6652 class_locale.members.class = MR_EVT_CLASS_DEBUG;
6653
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306654 return megasas_register_aen(instance,
Christoph Hellwig48100b02015-04-23 16:33:24 +05306655 le32_to_cpu(eli.newest_seq_num) + 1,
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306656 class_locale.word);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006657}
6658
6659/**
6660 * megasas_io_attach - Attaches this driver to SCSI mid-layer
6661 * @instance: Adapter soft state
6662 */
6663static int megasas_io_attach(struct megasas_instance *instance)
6664{
6665 struct Scsi_Host *host = instance->host;
6666
6667 /*
6668 * Export parameters required by SCSI mid-layer
6669 */
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006670 host->unique_id = instance->unique_id;
Sumit.Saxena@avagotech.comae09a6c2015-01-05 20:06:23 +05306671 host->can_queue = instance->max_scsi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006672 host->this_id = instance->init_id;
6673 host->sg_tablesize = instance->max_num_sge;
adam radford42a8d2b2011-02-24 20:57:09 -08006674
6675 if (instance->fw_support_ieee)
6676 instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE;
6677
Yang, Bo1fd10682010-10-12 07:18:50 -06006678 /*
6679 * Check if the module parameter value for max_sectors can be used
6680 */
6681 if (max_sectors && max_sectors < instance->max_sectors_per_req)
6682 instance->max_sectors_per_req = max_sectors;
6683 else {
6684 if (max_sectors) {
6685 if (((instance->pdev->device ==
6686 PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
6687 (instance->pdev->device ==
6688 PCI_DEVICE_ID_LSI_SAS0079GEN2)) &&
6689 (max_sectors <= MEGASAS_MAX_SECTORS)) {
6690 instance->max_sectors_per_req = max_sectors;
6691 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05006692 dev_info(&instance->pdev->dev, "max_sectors should be > 0"
Yang, Bo1fd10682010-10-12 07:18:50 -06006693 "and <= %d (or < 1MB for GEN2 controller)\n",
6694 instance->max_sectors_per_req);
6695 }
6696 }
6697 }
6698
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006699 host->max_sectors = instance->max_sectors_per_req;
adam radford9c915a82010-12-21 13:34:31 -08006700 host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006701 host->max_channel = MEGASAS_MAX_CHANNELS - 1;
6702 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
6703 host->max_lun = MEGASAS_MAX_LUN;
Joshua Giles122da302006-02-03 15:34:17 -08006704 host->max_cmd_len = 16;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006705
6706 /*
6707 * Notify the mid-layer about the new controller
6708 */
6709 if (scsi_add_host(host, &instance->pdev->dev)) {
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05306710 dev_err(&instance->pdev->dev,
6711 "Failed to add host from %s %d\n",
6712 __func__, __LINE__);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006713 return -ENODEV;
6714 }
6715
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006716 return 0;
6717}
6718
Shivasharan S107a60d2017-10-19 02:49:05 -07006719/**
6720 * megasas_set_dma_mask - Set DMA mask for supported controllers
6721 *
6722 * @instance: Adapter soft state
6723 * Description:
6724 *
Shivasharan S894169d2018-12-18 05:59:54 -08006725 * For Ventura, driver/FW will operate in 63bit DMA addresses.
Shivasharan S107a60d2017-10-19 02:49:05 -07006726 *
6727 * For invader-
6728 * By default, driver/FW will operate in 32bit DMA addresses
6729 * for consistent DMA mapping but if 32 bit consistent
Shivasharan S894169d2018-12-18 05:59:54 -08006730 * DMA mask fails, driver will try with 63 bit consistent
6731 * mask provided FW is true 63bit DMA capable
Shivasharan S107a60d2017-10-19 02:49:05 -07006732 *
6733 * For older controllers(Thunderbolt and MFI based adapters)-
6734 * driver/FW will operate in 32 bit consistent DMA addresses.
6735 */
bo yang31ea7082007-11-07 12:09:50 -05006736static int
Shivasharan S107a60d2017-10-19 02:49:05 -07006737megasas_set_dma_mask(struct megasas_instance *instance)
bo yang31ea7082007-11-07 12:09:50 -05006738{
Shivasharan S107a60d2017-10-19 02:49:05 -07006739 u64 consistent_mask;
6740 struct pci_dev *pdev;
Shivasharan S81b76452018-10-16 23:37:51 -07006741 u32 scratch_pad_1;
bo yang31ea7082007-11-07 12:09:50 -05006742
Shivasharan S107a60d2017-10-19 02:49:05 -07006743 pdev = instance->pdev;
Shivasharan S630d42b2018-12-17 00:47:37 -08006744 consistent_mask = (instance->adapter_type >= VENTURA_SERIES) ?
Shivasharan S894169d2018-12-18 05:59:54 -08006745 DMA_BIT_MASK(63) : DMA_BIT_MASK(32);
Shivasharan S107a60d2017-10-19 02:49:05 -07006746
6747 if (IS_DMA64) {
Shivasharan S894169d2018-12-18 05:59:54 -08006748 if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(63)) &&
Shivasharan S107a60d2017-10-19 02:49:05 -07006749 dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
6750 goto fail_set_dma_mask;
6751
Shivasharan S894169d2018-12-18 05:59:54 -08006752 if ((*pdev->dev.dma_mask == DMA_BIT_MASK(63)) &&
Shivasharan S107a60d2017-10-19 02:49:05 -07006753 (dma_set_coherent_mask(&pdev->dev, consistent_mask) &&
6754 dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))) {
6755 /*
6756 * If 32 bit DMA mask fails, then try for 64 bit mask
6757 * for FW capable of handling 64 bit DMA.
6758 */
Shivasharan S272652f2018-12-17 00:47:40 -08006759 scratch_pad_1 = megasas_readl
6760 (instance, &instance->reg_set->outbound_scratch_pad_1);
Shivasharan S107a60d2017-10-19 02:49:05 -07006761
Shivasharan S81b76452018-10-16 23:37:51 -07006762 if (!(scratch_pad_1 & MR_CAN_HANDLE_64_BIT_DMA_OFFSET))
Shivasharan S107a60d2017-10-19 02:49:05 -07006763 goto fail_set_dma_mask;
6764 else if (dma_set_mask_and_coherent(&pdev->dev,
Shivasharan S894169d2018-12-18 05:59:54 -08006765 DMA_BIT_MASK(63)))
bo yang31ea7082007-11-07 12:09:50 -05006766 goto fail_set_dma_mask;
6767 }
Shivasharan S107a60d2017-10-19 02:49:05 -07006768 } else if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
6769 goto fail_set_dma_mask;
6770
6771 if (pdev->dev.coherent_dma_mask == DMA_BIT_MASK(32))
6772 instance->consistent_mask_64bit = false;
6773 else
6774 instance->consistent_mask_64bit = true;
6775
6776 dev_info(&pdev->dev, "%s bit DMA mask and %s bit consistent mask\n",
Tomas Henzld1f38d92019-01-02 16:07:25 +01006777 ((*pdev->dev.dma_mask == DMA_BIT_MASK(63)) ? "63" : "32"),
Shivasharan S894169d2018-12-18 05:59:54 -08006778 (instance->consistent_mask_64bit ? "63" : "32"));
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306779
bo yang31ea7082007-11-07 12:09:50 -05006780 return 0;
6781
6782fail_set_dma_mask:
Shivasharan S107a60d2017-10-19 02:49:05 -07006783 dev_err(&pdev->dev, "Failed to set DMA mask\n");
6784 return -1;
6785
bo yang31ea7082007-11-07 12:09:50 -05006786}
6787
Shivasharan Sc3651782017-10-19 02:48:48 -07006788/*
6789 * megasas_set_adapter_type - Set adapter type.
6790 * Supported controllers can be divided in
Shivasharan S154a7cd2018-12-17 00:47:38 -08006791 * different categories-
6792 * enum MR_ADAPTER_TYPE {
6793 * MFI_SERIES = 1,
6794 * THUNDERBOLT_SERIES = 2,
6795 * INVADER_SERIES = 3,
6796 * VENTURA_SERIES = 4,
6797 * AERO_SERIES = 5,
6798 * };
Shivasharan Sc3651782017-10-19 02:48:48 -07006799 * @instance: Adapter soft state
6800 * return: void
6801 */
6802static inline void megasas_set_adapter_type(struct megasas_instance *instance)
6803{
Shivasharan S754f1ba2017-10-19 02:48:49 -07006804 if ((instance->pdev->vendor == PCI_VENDOR_ID_DELL) &&
6805 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5)) {
Shivasharan Sc3651782017-10-19 02:48:48 -07006806 instance->adapter_type = MFI_SERIES;
Shivasharan S754f1ba2017-10-19 02:48:49 -07006807 } else {
6808 switch (instance->pdev->device) {
Shivasharan S469f72d2018-11-09 09:47:20 -08006809 case PCI_DEVICE_ID_LSI_AERO_10E1:
6810 case PCI_DEVICE_ID_LSI_AERO_10E2:
6811 case PCI_DEVICE_ID_LSI_AERO_10E5:
6812 case PCI_DEVICE_ID_LSI_AERO_10E6:
Shivasharan S154a7cd2018-12-17 00:47:38 -08006813 instance->adapter_type = AERO_SERIES;
6814 break;
Shivasharan S754f1ba2017-10-19 02:48:49 -07006815 case PCI_DEVICE_ID_LSI_VENTURA:
6816 case PCI_DEVICE_ID_LSI_CRUSADER:
6817 case PCI_DEVICE_ID_LSI_HARPOON:
6818 case PCI_DEVICE_ID_LSI_TOMCAT:
6819 case PCI_DEVICE_ID_LSI_VENTURA_4PORT:
6820 case PCI_DEVICE_ID_LSI_CRUSADER_4PORT:
6821 instance->adapter_type = VENTURA_SERIES;
6822 break;
6823 case PCI_DEVICE_ID_LSI_FUSION:
6824 case PCI_DEVICE_ID_LSI_PLASMA:
6825 instance->adapter_type = THUNDERBOLT_SERIES;
6826 break;
6827 case PCI_DEVICE_ID_LSI_INVADER:
6828 case PCI_DEVICE_ID_LSI_INTRUDER:
6829 case PCI_DEVICE_ID_LSI_INTRUDER_24:
6830 case PCI_DEVICE_ID_LSI_CUTLASS_52:
6831 case PCI_DEVICE_ID_LSI_CUTLASS_53:
6832 case PCI_DEVICE_ID_LSI_FURY:
6833 instance->adapter_type = INVADER_SERIES;
6834 break;
6835 default: /* For all other supported controllers */
6836 instance->adapter_type = MFI_SERIES;
6837 break;
6838 }
Shivasharan Sc3651782017-10-19 02:48:48 -07006839 }
6840}
6841
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006842static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance)
6843{
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006844 instance->producer = dma_alloc_coherent(&instance->pdev->dev,
6845 sizeof(u32), &instance->producer_h, GFP_KERNEL);
6846 instance->consumer = dma_alloc_coherent(&instance->pdev->dev,
6847 sizeof(u32), &instance->consumer_h, GFP_KERNEL);
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006848
6849 if (!instance->producer || !instance->consumer) {
6850 dev_err(&instance->pdev->dev,
6851 "Failed to allocate memory for producer, consumer\n");
6852 return -1;
6853 }
6854
6855 *instance->producer = 0;
6856 *instance->consumer = 0;
6857 return 0;
6858}
6859
6860/**
6861 * megasas_alloc_ctrl_mem - Allocate per controller memory for core data
6862 * structures which are not common across MFI
6863 * adapters and fusion adapters.
6864 * For MFI based adapters, allocate producer and
6865 * consumer buffers. For fusion adapters, allocate
6866 * memory for fusion context.
6867 * @instance: Adapter soft state
6868 * return: 0 for SUCCESS
6869 */
6870static int megasas_alloc_ctrl_mem(struct megasas_instance *instance)
6871{
Kees Cook6396bb22018-06-12 14:03:40 -07006872 instance->reply_map = kcalloc(nr_cpu_ids, sizeof(unsigned int),
Ming Leiadbe5522018-03-13 17:42:40 +08006873 GFP_KERNEL);
6874 if (!instance->reply_map)
6875 return -ENOMEM;
6876
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006877 switch (instance->adapter_type) {
6878 case MFI_SERIES:
6879 if (megasas_alloc_mfi_ctrl_mem(instance))
Ming Leiadbe5522018-03-13 17:42:40 +08006880 goto fail;
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006881 break;
Shivasharan S154a7cd2018-12-17 00:47:38 -08006882 case AERO_SERIES:
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006883 case VENTURA_SERIES:
6884 case THUNDERBOLT_SERIES:
6885 case INVADER_SERIES:
6886 if (megasas_alloc_fusion_context(instance))
Ming Leiadbe5522018-03-13 17:42:40 +08006887 goto fail;
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006888 break;
6889 }
6890
6891 return 0;
Ming Leiadbe5522018-03-13 17:42:40 +08006892 fail:
6893 kfree(instance->reply_map);
6894 instance->reply_map = NULL;
6895 return -ENOMEM;
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006896}
6897
6898/*
6899 * megasas_free_ctrl_mem - Free fusion context for fusion adapters and
6900 * producer, consumer buffers for MFI adapters
6901 *
6902 * @instance - Adapter soft instance
6903 *
6904 */
6905static inline void megasas_free_ctrl_mem(struct megasas_instance *instance)
6906{
Ming Leiadbe5522018-03-13 17:42:40 +08006907 kfree(instance->reply_map);
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006908 if (instance->adapter_type == MFI_SERIES) {
6909 if (instance->producer)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006910 dma_free_coherent(&instance->pdev->dev, sizeof(u32),
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006911 instance->producer,
6912 instance->producer_h);
6913 if (instance->consumer)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006914 dma_free_coherent(&instance->pdev->dev, sizeof(u32),
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006915 instance->consumer,
6916 instance->consumer_h);
6917 } else {
6918 megasas_free_fusion_context(instance);
6919 }
6920}
6921
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006922/**
Shivasharan S1b4bed22017-10-19 02:48:55 -07006923 * megasas_alloc_ctrl_dma_buffers - Allocate consistent DMA buffers during
6924 * driver load time
6925 *
6926 * @instance- Adapter soft instance
6927 * @return- O for SUCCESS
6928 */
6929static inline
6930int megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance)
6931{
6932 struct pci_dev *pdev = instance->pdev;
Shivasharan S9b3d0282017-10-19 02:48:56 -07006933 struct fusion_context *fusion = instance->ctrl_context;
Shivasharan S1b4bed22017-10-19 02:48:55 -07006934
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006935 instance->evt_detail = dma_alloc_coherent(&pdev->dev,
6936 sizeof(struct megasas_evt_detail),
6937 &instance->evt_detail_h, GFP_KERNEL);
Shivasharan S1b4bed22017-10-19 02:48:55 -07006938
6939 if (!instance->evt_detail) {
6940 dev_err(&instance->pdev->dev,
6941 "Failed to allocate event detail buffer\n");
6942 return -ENOMEM;
6943 }
6944
Shivasharan S9b3d0282017-10-19 02:48:56 -07006945 if (fusion) {
6946 fusion->ioc_init_request =
6947 dma_alloc_coherent(&pdev->dev,
6948 sizeof(struct MPI2_IOC_INIT_REQUEST),
6949 &fusion->ioc_init_request_phys,
6950 GFP_KERNEL);
6951
6952 if (!fusion->ioc_init_request) {
6953 dev_err(&pdev->dev,
6954 "Failed to allocate PD list buffer\n");
6955 return -ENOMEM;
6956 }
Shivasharan Sf0c21df2018-10-16 23:37:40 -07006957
6958 instance->snapdump_prop = dma_alloc_coherent(&pdev->dev,
6959 sizeof(struct MR_SNAPDUMP_PROPERTIES),
6960 &instance->snapdump_prop_h, GFP_KERNEL);
6961
6962 if (!instance->snapdump_prop)
6963 dev_err(&pdev->dev,
6964 "Failed to allocate snapdump properties buffer\n");
Shivasharan Sf6fe5732019-01-29 01:38:14 -08006965
6966 instance->host_device_list_buf = dma_alloc_coherent(&pdev->dev,
6967 HOST_DEVICE_LIST_SZ,
6968 &instance->host_device_list_buf_h,
6969 GFP_KERNEL);
6970
6971 if (!instance->host_device_list_buf) {
6972 dev_err(&pdev->dev,
6973 "Failed to allocate targetid list buffer\n");
6974 return -ENOMEM;
6975 }
6976
Shivasharan S9b3d0282017-10-19 02:48:56 -07006977 }
6978
6979 instance->pd_list_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006980 dma_alloc_coherent(&pdev->dev,
Shivasharan S9b3d0282017-10-19 02:48:56 -07006981 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006982 &instance->pd_list_buf_h, GFP_KERNEL);
Shivasharan S9b3d0282017-10-19 02:48:56 -07006983
6984 if (!instance->pd_list_buf) {
6985 dev_err(&pdev->dev, "Failed to allocate PD list buffer\n");
6986 return -ENOMEM;
6987 }
6988
6989 instance->ctrl_info_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006990 dma_alloc_coherent(&pdev->dev,
Shivasharan S9b3d0282017-10-19 02:48:56 -07006991 sizeof(struct megasas_ctrl_info),
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006992 &instance->ctrl_info_buf_h, GFP_KERNEL);
Shivasharan S9b3d0282017-10-19 02:48:56 -07006993
6994 if (!instance->ctrl_info_buf) {
6995 dev_err(&pdev->dev,
6996 "Failed to allocate controller info buffer\n");
6997 return -ENOMEM;
6998 }
6999
7000 instance->ld_list_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007001 dma_alloc_coherent(&pdev->dev,
Shivasharan S9b3d0282017-10-19 02:48:56 -07007002 sizeof(struct MR_LD_LIST),
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007003 &instance->ld_list_buf_h, GFP_KERNEL);
Shivasharan S9b3d0282017-10-19 02:48:56 -07007004
7005 if (!instance->ld_list_buf) {
7006 dev_err(&pdev->dev, "Failed to allocate LD list buffer\n");
7007 return -ENOMEM;
7008 }
7009
7010 instance->ld_targetid_list_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007011 dma_alloc_coherent(&pdev->dev,
7012 sizeof(struct MR_LD_TARGETID_LIST),
7013 &instance->ld_targetid_list_buf_h, GFP_KERNEL);
Shivasharan S9b3d0282017-10-19 02:48:56 -07007014
7015 if (!instance->ld_targetid_list_buf) {
7016 dev_err(&pdev->dev,
7017 "Failed to allocate LD targetid list buffer\n");
7018 return -ENOMEM;
7019 }
7020
Shivasharan S1b4bed22017-10-19 02:48:55 -07007021 if (!reset_devices) {
7022 instance->system_info_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007023 dma_alloc_coherent(&pdev->dev,
7024 sizeof(struct MR_DRV_SYSTEM_INFO),
7025 &instance->system_info_h, GFP_KERNEL);
Shivasharan S1b4bed22017-10-19 02:48:55 -07007026 instance->pd_info =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007027 dma_alloc_coherent(&pdev->dev,
7028 sizeof(struct MR_PD_INFO),
7029 &instance->pd_info_h, GFP_KERNEL);
Shivasharan S1b4bed22017-10-19 02:48:55 -07007030 instance->tgt_prop =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007031 dma_alloc_coherent(&pdev->dev,
7032 sizeof(struct MR_TARGET_PROPERTIES),
7033 &instance->tgt_prop_h, GFP_KERNEL);
Shivasharan S1b4bed22017-10-19 02:48:55 -07007034 instance->crash_dump_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007035 dma_alloc_coherent(&pdev->dev, CRASH_DMA_BUF_SIZE,
7036 &instance->crash_dump_h, GFP_KERNEL);
Shivasharan S1b4bed22017-10-19 02:48:55 -07007037
7038 if (!instance->system_info_buf)
7039 dev_err(&instance->pdev->dev,
7040 "Failed to allocate system info buffer\n");
7041
7042 if (!instance->pd_info)
7043 dev_err(&instance->pdev->dev,
7044 "Failed to allocate pd_info buffer\n");
7045
7046 if (!instance->tgt_prop)
7047 dev_err(&instance->pdev->dev,
7048 "Failed to allocate tgt_prop buffer\n");
7049
7050 if (!instance->crash_dump_buf)
7051 dev_err(&instance->pdev->dev,
7052 "Failed to allocate crash dump buffer\n");
7053 }
7054
7055 return 0;
7056}
7057
7058/*
7059 * megasas_free_ctrl_dma_buffers - Free consistent DMA buffers allocated
7060 * during driver load time
7061 *
7062 * @instance- Adapter soft instance
7063 *
7064 */
7065static inline
7066void megasas_free_ctrl_dma_buffers(struct megasas_instance *instance)
7067{
7068 struct pci_dev *pdev = instance->pdev;
Shivasharan S9b3d0282017-10-19 02:48:56 -07007069 struct fusion_context *fusion = instance->ctrl_context;
Shivasharan S1b4bed22017-10-19 02:48:55 -07007070
7071 if (instance->evt_detail)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007072 dma_free_coherent(&pdev->dev, sizeof(struct megasas_evt_detail),
Shivasharan S1b4bed22017-10-19 02:48:55 -07007073 instance->evt_detail,
7074 instance->evt_detail_h);
7075
Shivasharan S9b3d0282017-10-19 02:48:56 -07007076 if (fusion && fusion->ioc_init_request)
7077 dma_free_coherent(&pdev->dev,
7078 sizeof(struct MPI2_IOC_INIT_REQUEST),
7079 fusion->ioc_init_request,
7080 fusion->ioc_init_request_phys);
7081
7082 if (instance->pd_list_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007083 dma_free_coherent(&pdev->dev,
Shivasharan S9b3d0282017-10-19 02:48:56 -07007084 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
7085 instance->pd_list_buf,
7086 instance->pd_list_buf_h);
7087
7088 if (instance->ld_list_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007089 dma_free_coherent(&pdev->dev, sizeof(struct MR_LD_LIST),
Shivasharan S9b3d0282017-10-19 02:48:56 -07007090 instance->ld_list_buf,
7091 instance->ld_list_buf_h);
7092
7093 if (instance->ld_targetid_list_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007094 dma_free_coherent(&pdev->dev, sizeof(struct MR_LD_TARGETID_LIST),
Shivasharan S9b3d0282017-10-19 02:48:56 -07007095 instance->ld_targetid_list_buf,
7096 instance->ld_targetid_list_buf_h);
7097
7098 if (instance->ctrl_info_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007099 dma_free_coherent(&pdev->dev, sizeof(struct megasas_ctrl_info),
Shivasharan S9b3d0282017-10-19 02:48:56 -07007100 instance->ctrl_info_buf,
7101 instance->ctrl_info_buf_h);
7102
Shivasharan S1b4bed22017-10-19 02:48:55 -07007103 if (instance->system_info_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007104 dma_free_coherent(&pdev->dev, sizeof(struct MR_DRV_SYSTEM_INFO),
Shivasharan S1b4bed22017-10-19 02:48:55 -07007105 instance->system_info_buf,
7106 instance->system_info_h);
7107
7108 if (instance->pd_info)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007109 dma_free_coherent(&pdev->dev, sizeof(struct MR_PD_INFO),
Shivasharan S1b4bed22017-10-19 02:48:55 -07007110 instance->pd_info, instance->pd_info_h);
7111
7112 if (instance->tgt_prop)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007113 dma_free_coherent(&pdev->dev, sizeof(struct MR_TARGET_PROPERTIES),
Shivasharan S1b4bed22017-10-19 02:48:55 -07007114 instance->tgt_prop, instance->tgt_prop_h);
7115
7116 if (instance->crash_dump_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007117 dma_free_coherent(&pdev->dev, CRASH_DMA_BUF_SIZE,
Shivasharan S1b4bed22017-10-19 02:48:55 -07007118 instance->crash_dump_buf,
7119 instance->crash_dump_h);
Shivasharan Sf0c21df2018-10-16 23:37:40 -07007120
7121 if (instance->snapdump_prop)
7122 dma_free_coherent(&pdev->dev,
7123 sizeof(struct MR_SNAPDUMP_PROPERTIES),
7124 instance->snapdump_prop,
7125 instance->snapdump_prop_h);
Shivasharan Sf6fe5732019-01-29 01:38:14 -08007126
7127 if (instance->host_device_list_buf)
7128 dma_free_coherent(&pdev->dev,
7129 HOST_DEVICE_LIST_SZ,
7130 instance->host_device_list_buf,
7131 instance->host_device_list_buf_h);
7132
Shivasharan S1b4bed22017-10-19 02:48:55 -07007133}
7134
Shivasharan S7535f272017-10-19 02:48:58 -07007135/*
7136 * megasas_init_ctrl_params - Initialize controller's instance
7137 * parameters before FW init
7138 * @instance - Adapter soft instance
7139 * @return - void
7140 */
7141static inline void megasas_init_ctrl_params(struct megasas_instance *instance)
7142{
7143 instance->fw_crash_state = UNAVAILABLE;
7144
7145 megasas_poll_wait_aen = 0;
7146 instance->issuepend_done = 1;
7147 atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
7148
7149 /*
7150 * Initialize locks and queues
7151 */
7152 INIT_LIST_HEAD(&instance->cmd_pool);
7153 INIT_LIST_HEAD(&instance->internal_reset_pending_q);
7154
7155 atomic_set(&instance->fw_outstanding, 0);
Shivasharan S1d15d902019-05-07 10:05:36 -07007156 atomic64_set(&instance->total_io_count, 0);
Shivasharan S7535f272017-10-19 02:48:58 -07007157
7158 init_waitqueue_head(&instance->int_cmd_wait_q);
7159 init_waitqueue_head(&instance->abort_cmd_wait_q);
7160
7161 spin_lock_init(&instance->crashdump_lock);
7162 spin_lock_init(&instance->mfi_pool_lock);
7163 spin_lock_init(&instance->hba_lock);
7164 spin_lock_init(&instance->stream_lock);
7165 spin_lock_init(&instance->completion_lock);
7166
Shivasharan S7535f272017-10-19 02:48:58 -07007167 mutex_init(&instance->reset_mutex);
7168
7169 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
7170 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY))
7171 instance->flag_ieee = 1;
7172
7173 megasas_dbg_lvl = 0;
7174 instance->flag = 0;
7175 instance->unload = 1;
7176 instance->last_time = 0;
7177 instance->disableOnlineCtrlReset = 1;
7178 instance->UnevenSpanSupport = 0;
Shivasharan S1d15d902019-05-07 10:05:36 -07007179 instance->smp_affinity_enable = smp_affinity_enable ? true : false;
7180 instance->msix_load_balance = false;
Shivasharan S7535f272017-10-19 02:48:58 -07007181
Shivasharan S3f6194a2018-10-16 23:37:39 -07007182 if (instance->adapter_type != MFI_SERIES)
Shivasharan S7535f272017-10-19 02:48:58 -07007183 INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
Shivasharan S3f6194a2018-10-16 23:37:39 -07007184 else
Shivasharan S7535f272017-10-19 02:48:58 -07007185 INIT_WORK(&instance->work_init, process_fw_state_change_wq);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007186}
7187
7188/**
7189 * megasas_probe_one - PCI hotplug entry point
7190 * @pdev: PCI device structure
adam radford0d490162010-12-14 19:17:17 -08007191 * @id: PCI ids of supported hotplugged adapter
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007192 */
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08007193static int megasas_probe_one(struct pci_dev *pdev,
7194 const struct pci_device_id *id)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007195{
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05307196 int rval, pos;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007197 struct Scsi_Host *host;
7198 struct megasas_instance *instance;
adam radford66192dfe2011-02-24 20:56:28 -08007199 u16 control = 0;
7200
Shivasharan S469f72d2018-11-09 09:47:20 -08007201 switch (pdev->device) {
Chandrakanth Patildd807692019-06-25 16:34:20 +05307202 case PCI_DEVICE_ID_LSI_AERO_10E0:
7203 case PCI_DEVICE_ID_LSI_AERO_10E3:
7204 case PCI_DEVICE_ID_LSI_AERO_10E4:
7205 case PCI_DEVICE_ID_LSI_AERO_10E7:
7206 dev_err(&pdev->dev, "Adapter is in non secure mode\n");
7207 return 1;
Shivasharan S469f72d2018-11-09 09:47:20 -08007208 case PCI_DEVICE_ID_LSI_AERO_10E1:
7209 case PCI_DEVICE_ID_LSI_AERO_10E5:
7210 dev_info(&pdev->dev, "Adapter is in configurable secure mode\n");
7211 break;
7212 }
7213
adam radford66192dfe2011-02-24 20:56:28 -08007214 /* Reset MSI-X in the kdump kernel */
7215 if (reset_devices) {
7216 pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
7217 if (pos) {
Bjorn Helgaas99369062013-04-17 18:08:44 -06007218 pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS,
adam radford66192dfe2011-02-24 20:56:28 -08007219 &control);
7220 if (control & PCI_MSIX_FLAGS_ENABLE) {
7221 dev_info(&pdev->dev, "resetting MSI-X\n");
7222 pci_write_config_word(pdev,
Bjorn Helgaas99369062013-04-17 18:08:44 -06007223 pos + PCI_MSIX_FLAGS,
adam radford66192dfe2011-02-24 20:56:28 -08007224 control &
7225 ~PCI_MSIX_FLAGS_ENABLE);
7226 }
7227 }
7228 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007229
7230 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007231 * PCI prepping: enable device set bus mastering and dma mask
7232 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09007233 rval = pci_enable_device_mem(pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007234
7235 if (rval) {
7236 return rval;
7237 }
7238
7239 pci_set_master(pdev);
7240
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007241 host = scsi_host_alloc(&megasas_template,
7242 sizeof(struct megasas_instance));
7243
7244 if (!host) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007245 dev_printk(KERN_DEBUG, &pdev->dev, "scsi_host_alloc failed\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007246 goto fail_alloc_instance;
7247 }
7248
7249 instance = (struct megasas_instance *)host->hostdata;
7250 memset(instance, 0, sizeof(*instance));
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007251 atomic_set(&instance->fw_reset_no_pci_access, 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007252
7253 /*
7254 * Initialize PCI related and misc parameters
7255 */
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007256 instance->pdev = pdev;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007257 instance->host = host;
7258 instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
7259 instance->init_id = MEGASAS_DEFAULT_INIT_ID;
7260
Shivasharan Sc3651782017-10-19 02:48:48 -07007261 megasas_set_adapter_type(instance);
Sumant Patro658dced2006-10-03 13:09:14 -07007262
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007263 /*
adam radford0a770662011-02-24 20:56:12 -08007264 * Initialize MFI Firmware
7265 */
7266 if (megasas_init_fw(instance))
7267 goto fail_init_mfi;
7268
adam radford229fe472014-03-10 02:51:56 -07007269 if (instance->requestorId) {
7270 if (instance->PlasmaFW111) {
7271 instance->vf_affiliation_111 =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007272 dma_alloc_coherent(&pdev->dev,
7273 sizeof(struct MR_LD_VF_AFFILIATION_111),
7274 &instance->vf_affiliation_111_h,
7275 GFP_KERNEL);
adam radford229fe472014-03-10 02:51:56 -07007276 if (!instance->vf_affiliation_111)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007277 dev_warn(&pdev->dev, "Can't allocate "
adam radford229fe472014-03-10 02:51:56 -07007278 "memory for VF affiliation buffer\n");
7279 } else {
7280 instance->vf_affiliation =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007281 dma_alloc_coherent(&pdev->dev,
7282 (MAX_LOGICAL_DRIVES + 1) *
7283 sizeof(struct MR_LD_VF_AFFILIATION),
7284 &instance->vf_affiliation_h,
7285 GFP_KERNEL);
adam radford229fe472014-03-10 02:51:56 -07007286 if (!instance->vf_affiliation)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007287 dev_warn(&pdev->dev, "Can't allocate "
adam radford229fe472014-03-10 02:51:56 -07007288 "memory for VF affiliation buffer\n");
7289 }
7290 }
7291
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007292 /*
7293 * Store instance in PCI softstate
7294 */
7295 pci_set_drvdata(pdev, instance);
7296
7297 /*
7298 * Add this controller to megasas_mgmt_info structure so that it
7299 * can be exported to management applications
7300 */
7301 megasas_mgmt_info.count++;
7302 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance;
7303 megasas_mgmt_info.max_index++;
7304
7305 /*
adam radford541f90b2011-05-11 18:34:29 -07007306 * Register with SCSI mid-layer
7307 */
7308 if (megasas_io_attach(instance))
7309 goto fail_io_attach;
7310
7311 instance->unload = 0;
Sumit.Saxena@avagotech.comaa008322014-11-17 15:24:08 +05307312 /*
7313 * Trigger SCSI to scan our drives
7314 */
Shivasharan Sf6fe5732019-01-29 01:38:14 -08007315 if (!instance->enable_fw_dev_list ||
7316 (instance->host_device_list_buf->count > 0))
7317 scsi_scan_host(host);
adam radford541f90b2011-05-11 18:34:29 -07007318
7319 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007320 * Initiate AEN (Asynchronous Event Notification)
7321 */
7322 if (megasas_start_aen(instance)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007323 dev_printk(KERN_DEBUG, &pdev->dev, "start aen failed\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007324 goto fail_start_aen;
7325 }
7326
Shivasharan Sba535722019-05-07 10:05:49 -07007327 megasas_setup_debugfs(instance);
7328
Adam Radford9ea81f82014-07-09 15:17:57 -07007329 /* Get current SR-IOV LD/VF affiliation */
7330 if (instance->requestorId)
7331 megasas_get_ld_vf_affiliation(instance, 1);
7332
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007333 return 0;
7334
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007335fail_start_aen:
7336fail_io_attach:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007337 megasas_mgmt_info.count--;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007338 megasas_mgmt_info.max_index--;
weiping zhang61f0c3c2017-08-08 01:26:57 +08007339 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007340
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05307341 instance->instancet->disable_intr(instance);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05307342 megasas_destroy_irqs(instance);
7343
Shivasharan Se7d36b82017-10-19 02:48:50 -07007344 if (instance->adapter_type != MFI_SERIES)
adam radfordeb1b1232011-02-24 20:55:56 -08007345 megasas_release_fusion(instance);
7346 else
7347 megasas_release_mfi(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07007348 if (instance->msix_vectors)
Hannes Reineckefad119b2016-12-02 12:52:23 +01007349 pci_free_irq_vectors(instance->pdev);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05307350fail_init_mfi:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007351 scsi_host_put(host);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007352fail_alloc_instance:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007353 pci_disable_device(pdev);
7354
7355 return -ENODEV;
7356}
7357
7358/**
7359 * megasas_flush_cache - Requests FW to flush all its caches
7360 * @instance: Adapter soft state
7361 */
7362static void megasas_flush_cache(struct megasas_instance *instance)
7363{
7364 struct megasas_cmd *cmd;
7365 struct megasas_dcmd_frame *dcmd;
7366
Sumit Saxena8a01a412016-01-28 21:04:32 +05307367 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
bo yang39a98552010-09-22 22:36:29 -04007368 return;
7369
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007370 cmd = megasas_get_cmd(instance);
7371
7372 if (!cmd)
7373 return;
7374
7375 dcmd = &cmd->frame->dcmd;
7376
7377 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
7378
7379 dcmd->cmd = MFI_CMD_DCMD;
7380 dcmd->cmd_status = 0x0;
7381 dcmd->sge_count = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05307382 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007383 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07007384 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007385 dcmd->data_xfer_len = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05307386 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_CACHE_FLUSH);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007387 dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
7388
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307389 if (megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS)
7390 != DCMD_SUCCESS) {
7391 dev_err(&instance->pdev->dev,
7392 "return from %s %d\n", __func__, __LINE__);
7393 return;
7394 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007395
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05307396 megasas_return_cmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007397}
7398
7399/**
7400 * megasas_shutdown_controller - Instructs FW to shutdown the controller
7401 * @instance: Adapter soft state
bo yang31ea7082007-11-07 12:09:50 -05007402 * @opcode: Shutdown/Hibernate
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007403 */
bo yang31ea7082007-11-07 12:09:50 -05007404static void megasas_shutdown_controller(struct megasas_instance *instance,
7405 u32 opcode)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007406{
7407 struct megasas_cmd *cmd;
7408 struct megasas_dcmd_frame *dcmd;
7409
Sumit Saxena8a01a412016-01-28 21:04:32 +05307410 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
bo yang39a98552010-09-22 22:36:29 -04007411 return;
7412
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007413 cmd = megasas_get_cmd(instance);
7414
7415 if (!cmd)
7416 return;
7417
7418 if (instance->aen_cmd)
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05307419 megasas_issue_blocked_abort_cmd(instance,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307420 instance->aen_cmd, MFI_IO_TIMEOUT_SECS);
adam radford9c915a82010-12-21 13:34:31 -08007421 if (instance->map_update_cmd)
7422 megasas_issue_blocked_abort_cmd(instance,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307423 instance->map_update_cmd, MFI_IO_TIMEOUT_SECS);
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05307424 if (instance->jbod_seq_cmd)
7425 megasas_issue_blocked_abort_cmd(instance,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307426 instance->jbod_seq_cmd, MFI_IO_TIMEOUT_SECS);
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05307427
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007428 dcmd = &cmd->frame->dcmd;
7429
7430 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
7431
7432 dcmd->cmd = MFI_CMD_DCMD;
7433 dcmd->cmd_status = 0x0;
7434 dcmd->sge_count = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05307435 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007436 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07007437 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007438 dcmd->data_xfer_len = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05307439 dcmd->opcode = cpu_to_le32(opcode);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007440
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307441 if (megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS)
7442 != DCMD_SUCCESS) {
7443 dev_err(&instance->pdev->dev,
7444 "return from %s %d\n", __func__, __LINE__);
7445 return;
7446 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007447
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05307448 megasas_return_cmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007449}
7450
Jiri Slaby33139b22008-05-01 17:56:02 +02007451#ifdef CONFIG_PM
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007452/**
bo yangad84db22007-11-09 04:40:16 -05007453 * megasas_suspend - driver suspend entry point
7454 * @pdev: PCI device structure
bo yang31ea7082007-11-07 12:09:50 -05007455 * @state: PCI power state to suspend routine
7456 */
Jiri Slaby33139b22008-05-01 17:56:02 +02007457static int
bo yang31ea7082007-11-07 12:09:50 -05007458megasas_suspend(struct pci_dev *pdev, pm_message_t state)
7459{
bo yang31ea7082007-11-07 12:09:50 -05007460 struct megasas_instance *instance;
7461
7462 instance = pci_get_drvdata(pdev);
Chandrakanth Patildd807692019-06-25 16:34:20 +05307463
7464 if (!instance)
7465 return 0;
7466
Yang, Bo0c79e682009-10-06 14:47:35 -06007467 instance->unload = 1;
bo yang31ea7082007-11-07 12:09:50 -05007468
Shivasharan Sf7331f12019-05-07 10:05:46 -07007469 dev_info(&pdev->dev, "%s is called\n", __func__);
7470
adam radford229fe472014-03-10 02:51:56 -07007471 /* Shutdown SR-IOV heartbeat timer */
7472 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
7473 del_timer_sync(&instance->sriov_heartbeat_timer);
7474
Shivasharan S3f6194a2018-10-16 23:37:39 -07007475 /* Stop the FW fault detection watchdog */
7476 if (instance->adapter_type != MFI_SERIES)
7477 megasas_fusion_stop_watchdog(instance);
7478
bo yang31ea7082007-11-07 12:09:50 -05007479 megasas_flush_cache(instance);
7480 megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007481
7482 /* cancel the delayed work if this work still in queue */
7483 if (instance->ev != NULL) {
7484 struct megasas_aen_event *ev = instance->ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08007485 cancel_delayed_work_sync(&ev->hotplug_work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007486 instance->ev = NULL;
7487 }
7488
bo yang31ea7082007-11-07 12:09:50 -05007489 tasklet_kill(&instance->isr_tasklet);
7490
7491 pci_set_drvdata(instance->pdev, instance);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05307492 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07007493
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05307494 megasas_destroy_irqs(instance);
7495
adam radfordc8e858f2011-10-08 18:15:13 -07007496 if (instance->msix_vectors)
Hannes Reineckefad119b2016-12-02 12:52:23 +01007497 pci_free_irq_vectors(instance->pdev);
bo yang31ea7082007-11-07 12:09:50 -05007498
7499 pci_save_state(pdev);
7500 pci_disable_device(pdev);
7501
7502 pci_set_power_state(pdev, pci_choose_state(pdev, state));
7503
7504 return 0;
7505}
7506
7507/**
7508 * megasas_resume- driver resume entry point
7509 * @pdev: PCI device structure
7510 */
Jiri Slaby33139b22008-05-01 17:56:02 +02007511static int
bo yang31ea7082007-11-07 12:09:50 -05007512megasas_resume(struct pci_dev *pdev)
7513{
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05307514 int rval;
bo yang31ea7082007-11-07 12:09:50 -05007515 struct Scsi_Host *host;
7516 struct megasas_instance *instance;
Hannes Reineckefad119b2016-12-02 12:52:23 +01007517 int irq_flags = PCI_IRQ_LEGACY;
bo yang31ea7082007-11-07 12:09:50 -05007518
7519 instance = pci_get_drvdata(pdev);
Chandrakanth Patildd807692019-06-25 16:34:20 +05307520
7521 if (!instance)
7522 return 0;
7523
bo yang31ea7082007-11-07 12:09:50 -05007524 host = instance->host;
7525 pci_set_power_state(pdev, PCI_D0);
7526 pci_enable_wake(pdev, PCI_D0, 0);
7527 pci_restore_state(pdev);
7528
Shivasharan Sf7331f12019-05-07 10:05:46 -07007529 dev_info(&pdev->dev, "%s is called\n", __func__);
bo yang31ea7082007-11-07 12:09:50 -05007530 /*
7531 * PCI prepping: enable device set bus mastering and dma mask
7532 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09007533 rval = pci_enable_device_mem(pdev);
bo yang31ea7082007-11-07 12:09:50 -05007534
7535 if (rval) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007536 dev_err(&pdev->dev, "Enable device failed\n");
bo yang31ea7082007-11-07 12:09:50 -05007537 return rval;
7538 }
7539
7540 pci_set_master(pdev);
7541
Shivasharan S107a60d2017-10-19 02:49:05 -07007542 /*
7543 * We expect the FW state to be READY
7544 */
7545 if (megasas_transition_to_ready(instance, 0))
7546 goto fail_ready_state;
7547
7548 if (megasas_set_dma_mask(instance))
bo yang31ea7082007-11-07 12:09:50 -05007549 goto fail_set_dma_mask;
7550
7551 /*
7552 * Initialize MFI Firmware
7553 */
7554
bo yang31ea7082007-11-07 12:09:50 -05007555 atomic_set(&instance->fw_outstanding, 0);
Shivasharan S41fae9a2018-01-05 05:27:39 -08007556 atomic_set(&instance->ldio_outstanding, 0);
bo yang31ea7082007-11-07 12:09:50 -05007557
adam radford3f1abce2011-05-11 18:33:47 -07007558 /* Now re-enable MSI-X */
Hannes Reineckefad119b2016-12-02 12:52:23 +01007559 if (instance->msix_vectors) {
7560 irq_flags = PCI_IRQ_MSIX;
Shivasharan S1d15d902019-05-07 10:05:36 -07007561 if (instance->smp_affinity_enable)
Hannes Reineckefad119b2016-12-02 12:52:23 +01007562 irq_flags |= PCI_IRQ_AFFINITY;
7563 }
7564 rval = pci_alloc_irq_vectors(instance->pdev, 1,
7565 instance->msix_vectors ?
7566 instance->msix_vectors : 1, irq_flags);
7567 if (rval < 0)
Alexander Gordeevdd088122014-08-18 08:01:43 +02007568 goto fail_reenable_msix;
adam radford3f1abce2011-05-11 18:33:47 -07007569
Ming Leiadbe5522018-03-13 17:42:40 +08007570 megasas_setup_reply_map(instance);
7571
Shivasharan Se7d36b82017-10-19 02:48:50 -07007572 if (instance->adapter_type != MFI_SERIES) {
adam radford9c915a82010-12-21 13:34:31 -08007573 megasas_reset_reply_desc(instance);
7574 if (megasas_ioc_init_fusion(instance)) {
7575 megasas_free_cmds(instance);
7576 megasas_free_cmds_fusion(instance);
7577 goto fail_init_mfi;
7578 }
7579 if (!megasas_get_map_info(instance))
7580 megasas_sync_map_info(instance);
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05307581 } else {
adam radford9c915a82010-12-21 13:34:31 -08007582 *instance->producer = 0;
7583 *instance->consumer = 0;
7584 if (megasas_issue_init_mfi(instance))
7585 goto fail_init_mfi;
adam radford9c915a82010-12-21 13:34:31 -08007586 }
bo yang31ea7082007-11-07 12:09:50 -05007587
Shivasharan Sc3b10a52018-06-04 03:45:10 -07007588 if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS)
7589 goto fail_init_mfi;
7590
adam radford9c915a82010-12-21 13:34:31 -08007591 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
7592 (unsigned long)instance);
bo yang31ea7082007-11-07 12:09:50 -05007593
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05307594 if (instance->msix_vectors ?
7595 megasas_setup_irqs_msix(instance, 0) :
7596 megasas_setup_irqs_ioapic(instance))
7597 goto fail_init_mfi;
bo yang31ea7082007-11-07 12:09:50 -05007598
Shivasharan S62a04f82019-05-07 10:05:35 -07007599 if (instance->adapter_type != MFI_SERIES)
7600 megasas_setup_irq_poll(instance);
7601
adam radford229fe472014-03-10 02:51:56 -07007602 /* Re-launch SR-IOV heartbeat timer */
7603 if (instance->requestorId) {
7604 if (!megasas_sriov_start_heartbeat(instance, 0))
Kees Cookc251a7b2017-10-22 15:30:04 -07007605 megasas_start_timer(instance);
Sumit.Saxena@avagotech.com5765c5b2015-04-23 16:32:09 +05307606 else {
adam radford229fe472014-03-10 02:51:56 -07007607 instance->skip_heartbeat_timer_del = 1;
Sumit.Saxena@avagotech.com5765c5b2015-04-23 16:32:09 +05307608 goto fail_init_mfi;
7609 }
adam radford229fe472014-03-10 02:51:56 -07007610 }
7611
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05307612 instance->instancet->enable_intr(instance);
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05307613 megasas_setup_jbod_map(instance);
Yang, Bo0c79e682009-10-06 14:47:35 -06007614 instance->unload = 0;
7615
adam radford541f90b2011-05-11 18:34:29 -07007616 /*
7617 * Initiate AEN (Asynchronous Event Notification)
7618 */
7619 if (megasas_start_aen(instance))
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007620 dev_err(&instance->pdev->dev, "Start AEN failed\n");
adam radford541f90b2011-05-11 18:34:29 -07007621
Shivasharan S3f6194a2018-10-16 23:37:39 -07007622 /* Re-launch FW fault watchdog */
7623 if (instance->adapter_type != MFI_SERIES)
7624 if (megasas_fusion_start_watchdog(instance) != SUCCESS)
7625 goto fail_start_watchdog;
7626
bo yang31ea7082007-11-07 12:09:50 -05007627 return 0;
7628
Shivasharan S3f6194a2018-10-16 23:37:39 -07007629fail_start_watchdog:
7630 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
7631 del_timer_sync(&instance->sriov_heartbeat_timer);
bo yang31ea7082007-11-07 12:09:50 -05007632fail_init_mfi:
Shivasharan S1b4bed22017-10-19 02:48:55 -07007633 megasas_free_ctrl_dma_buffers(instance);
Shivasharan S49a7a4a2017-10-19 02:48:54 -07007634 megasas_free_ctrl_mem(instance);
bo yang31ea7082007-11-07 12:09:50 -05007635 scsi_host_put(host);
7636
Shivasharan S107a60d2017-10-19 02:49:05 -07007637fail_reenable_msix:
bo yang31ea7082007-11-07 12:09:50 -05007638fail_set_dma_mask:
7639fail_ready_state:
7640
7641 pci_disable_device(pdev);
7642
7643 return -ENODEV;
7644}
Jiri Slaby33139b22008-05-01 17:56:02 +02007645#else
7646#define megasas_suspend NULL
7647#define megasas_resume NULL
7648#endif
bo yang31ea7082007-11-07 12:09:50 -05007649
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007650static inline int
7651megasas_wait_for_adapter_operational(struct megasas_instance *instance)
7652{
7653 int wait_time = MEGASAS_RESET_WAIT_TIME * 2;
7654 int i;
Shivasharan S9c9db8b2018-06-04 03:45:11 -07007655 u8 adp_state;
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007656
7657 for (i = 0; i < wait_time; i++) {
Shivasharan S9c9db8b2018-06-04 03:45:11 -07007658 adp_state = atomic_read(&instance->adprecovery);
7659 if ((adp_state == MEGASAS_HBA_OPERATIONAL) ||
7660 (adp_state == MEGASAS_HW_CRITICAL_ERROR))
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007661 break;
7662
7663 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL))
7664 dev_notice(&instance->pdev->dev, "waiting for controller reset to finish\n");
7665
7666 msleep(1000);
7667 }
7668
Shivasharan S9c9db8b2018-06-04 03:45:11 -07007669 if (adp_state != MEGASAS_HBA_OPERATIONAL) {
7670 dev_info(&instance->pdev->dev,
7671 "%s HBA failed to become operational, adp_state %d\n",
7672 __func__, adp_state);
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007673 return 1;
7674 }
7675
7676 return 0;
7677}
7678
bo yang31ea7082007-11-07 12:09:50 -05007679/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007680 * megasas_detach_one - PCI hot"un"plug entry point
7681 * @pdev: PCI device structure
7682 */
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08007683static void megasas_detach_one(struct pci_dev *pdev)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007684{
7685 int i;
7686 struct Scsi_Host *host;
7687 struct megasas_instance *instance;
adam radford9c915a82010-12-21 13:34:31 -08007688 struct fusion_context *fusion;
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05307689 u32 pd_seq_map_sz;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007690
7691 instance = pci_get_drvdata(pdev);
Chandrakanth Patildd807692019-06-25 16:34:20 +05307692
7693 if (!instance)
7694 return;
7695
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007696 host = instance->host;
adam radford9c915a82010-12-21 13:34:31 -08007697 fusion = instance->ctrl_context;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007698
adam radford229fe472014-03-10 02:51:56 -07007699 /* Shutdown SR-IOV heartbeat timer */
7700 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
7701 del_timer_sync(&instance->sriov_heartbeat_timer);
7702
Shivasharan S3f6194a2018-10-16 23:37:39 -07007703 /* Stop the FW fault detection watchdog */
7704 if (instance->adapter_type != MFI_SERIES)
7705 megasas_fusion_stop_watchdog(instance);
7706
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307707 if (instance->fw_crash_state != UNAVAILABLE)
7708 megasas_free_host_crash_buffer(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007709 scsi_remove_host(instance->host);
Shivasharan Sf3f79202018-01-05 05:27:41 -08007710 instance->unload = 1;
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007711
7712 if (megasas_wait_for_adapter_operational(instance))
7713 goto skip_firing_dcmds;
7714
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007715 megasas_flush_cache(instance);
bo yang31ea7082007-11-07 12:09:50 -05007716 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007717
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007718skip_firing_dcmds:
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007719 /* cancel the delayed work if this work still in queue*/
7720 if (instance->ev != NULL) {
7721 struct megasas_aen_event *ev = instance->ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08007722 cancel_delayed_work_sync(&ev->hotplug_work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007723 instance->ev = NULL;
7724 }
7725
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05307726 /* cancel all wait events */
7727 wake_up_all(&instance->int_cmd_wait_q);
7728
Sumant Patro5d018ad2006-10-03 13:13:18 -07007729 tasklet_kill(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007730
7731 /*
7732 * Take the instance off the instance array. Note that we will not
7733 * decrement the max_index. We let this array be sparse array
7734 */
7735 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
7736 if (megasas_mgmt_info.instance[i] == instance) {
7737 megasas_mgmt_info.count--;
7738 megasas_mgmt_info.instance[i] = NULL;
7739
7740 break;
7741 }
7742 }
7743
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05307744 instance->instancet->disable_intr(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007745
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05307746 megasas_destroy_irqs(instance);
7747
adam radfordc8e858f2011-10-08 18:15:13 -07007748 if (instance->msix_vectors)
Hannes Reineckefad119b2016-12-02 12:52:23 +01007749 pci_free_irq_vectors(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007750
Shivasharan S630d42b2018-12-17 00:47:37 -08007751 if (instance->adapter_type >= VENTURA_SERIES) {
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05007752 for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i)
7753 kfree(fusion->stream_detect_by_ld[i]);
7754 kfree(fusion->stream_detect_by_ld);
7755 fusion->stream_detect_by_ld = NULL;
7756 }
7757
7758
Shivasharan Se7d36b82017-10-19 02:48:50 -07007759 if (instance->adapter_type != MFI_SERIES) {
adam radford9c915a82010-12-21 13:34:31 -08007760 megasas_release_fusion(instance);
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05307761 pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
7762 (sizeof(struct MR_PD_CFG_SEQ) *
7763 (MAX_PHYSICAL_DEVICES - 1));
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05307764 for (i = 0; i < 2 ; i++) {
adam radford9c915a82010-12-21 13:34:31 -08007765 if (fusion->ld_map[i])
7766 dma_free_coherent(&instance->pdev->dev,
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05307767 fusion->max_map_sz,
adam radford9c915a82010-12-21 13:34:31 -08007768 fusion->ld_map[i],
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05307769 fusion->ld_map_phys[i]);
Shivasharan Sdef3e8d2017-08-23 04:47:03 -07007770 if (fusion->ld_drv_map[i]) {
7771 if (is_vmalloc_addr(fusion->ld_drv_map[i]))
7772 vfree(fusion->ld_drv_map[i]);
7773 else
7774 free_pages((ulong)fusion->ld_drv_map[i],
7775 fusion->drv_map_pages);
7776 }
7777
Maurizio Lombardi546e5592016-01-22 13:41:42 +01007778 if (fusion->pd_seq_sync[i])
7779 dma_free_coherent(&instance->pdev->dev,
7780 pd_seq_map_sz,
7781 fusion->pd_seq_sync[i],
7782 fusion->pd_seq_phys[i]);
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05307783 }
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05307784 } else {
adam radford9c915a82010-12-21 13:34:31 -08007785 megasas_release_mfi(instance);
adam radford9c915a82010-12-21 13:34:31 -08007786 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007787
adam radford229fe472014-03-10 02:51:56 -07007788 if (instance->vf_affiliation)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007789 dma_free_coherent(&pdev->dev, (MAX_LOGICAL_DRIVES + 1) *
adam radford229fe472014-03-10 02:51:56 -07007790 sizeof(struct MR_LD_VF_AFFILIATION),
7791 instance->vf_affiliation,
7792 instance->vf_affiliation_h);
7793
7794 if (instance->vf_affiliation_111)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007795 dma_free_coherent(&pdev->dev,
adam radford229fe472014-03-10 02:51:56 -07007796 sizeof(struct MR_LD_VF_AFFILIATION_111),
7797 instance->vf_affiliation_111,
7798 instance->vf_affiliation_111_h);
7799
7800 if (instance->hb_host_mem)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007801 dma_free_coherent(&pdev->dev, sizeof(struct MR_CTRL_HB_HOST_MEM),
adam radford229fe472014-03-10 02:51:56 -07007802 instance->hb_host_mem,
7803 instance->hb_host_mem_h);
7804
Shivasharan S1b4bed22017-10-19 02:48:55 -07007805 megasas_free_ctrl_dma_buffers(instance);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307806
Shivasharan S49a7a4a2017-10-19 02:48:54 -07007807 megasas_free_ctrl_mem(instance);
Sumit.Saxena@avagotech.com5765c5b2015-04-23 16:32:09 +05307808
Shivasharan Sba535722019-05-07 10:05:49 -07007809 megasas_destroy_debugfs(instance);
7810
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007811 scsi_host_put(host);
7812
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007813 pci_disable_device(pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007814}
7815
7816/**
7817 * megasas_shutdown - Shutdown entry point
7818 * @device: Generic device structure
7819 */
7820static void megasas_shutdown(struct pci_dev *pdev)
7821{
7822 struct megasas_instance *instance = pci_get_drvdata(pdev);
adam radfordc8e858f2011-10-08 18:15:13 -07007823
Chandrakanth Patildd807692019-06-25 16:34:20 +05307824 if (!instance)
7825 return;
7826
Yang, Bo0c79e682009-10-06 14:47:35 -06007827 instance->unload = 1;
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007828
7829 if (megasas_wait_for_adapter_operational(instance))
7830 goto skip_firing_dcmds;
7831
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007832 megasas_flush_cache(instance);
Yang, Bo530e6fc2008-08-10 12:42:37 -07007833 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007834
7835skip_firing_dcmds:
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05307836 instance->instancet->disable_intr(instance);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05307837 megasas_destroy_irqs(instance);
7838
adam radfordc8e858f2011-10-08 18:15:13 -07007839 if (instance->msix_vectors)
Hannes Reineckefad119b2016-12-02 12:52:23 +01007840 pci_free_irq_vectors(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007841}
7842
7843/**
7844 * megasas_mgmt_open - char node "open" entry point
7845 */
7846static int megasas_mgmt_open(struct inode *inode, struct file *filep)
7847{
7848 /*
7849 * Allow only those users with admin rights
7850 */
7851 if (!capable(CAP_SYS_ADMIN))
7852 return -EACCES;
7853
7854 return 0;
7855}
7856
7857/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007858 * megasas_mgmt_fasync - Async notifier registration from applications
7859 *
7860 * This function adds the calling process to a driver global queue. When an
7861 * event occurs, SIGIO will be sent to all processes in this queue.
7862 */
7863static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
7864{
7865 int rc;
7866
Arjan van de Ven0b950672006-01-11 13:16:10 +01007867 mutex_lock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007868
7869 rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
7870
Arjan van de Ven0b950672006-01-11 13:16:10 +01007871 mutex_unlock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007872
7873 if (rc >= 0) {
7874 /* For sanity check when we get ioctl */
7875 filep->private_data = filep;
7876 return 0;
7877 }
7878
7879 printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc);
7880
7881 return rc;
7882}
7883
7884/**
Yang, Boc3518832009-10-06 14:18:02 -06007885 * megasas_mgmt_poll - char node "poll" entry point
7886 * */
Al Viroafc9a422017-07-03 06:39:46 -04007887static __poll_t megasas_mgmt_poll(struct file *file, poll_table *wait)
Yang, Boc3518832009-10-06 14:18:02 -06007888{
Al Viroafc9a422017-07-03 06:39:46 -04007889 __poll_t mask;
Yang, Boc3518832009-10-06 14:18:02 -06007890 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007891
Yang, Boc3518832009-10-06 14:18:02 -06007892 poll_wait(file, &megasas_poll_wait, wait);
7893 spin_lock_irqsave(&poll_aen_lock, flags);
7894 if (megasas_poll_wait_aen)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08007895 mask = (EPOLLIN | EPOLLRDNORM);
Yang, Boc3518832009-10-06 14:18:02 -06007896 else
7897 mask = 0;
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05307898 megasas_poll_wait_aen = 0;
Yang, Boc3518832009-10-06 14:18:02 -06007899 spin_unlock_irqrestore(&poll_aen_lock, flags);
7900 return mask;
7901}
7902
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307903/*
7904 * megasas_set_crash_dump_params_ioctl:
7905 * Send CRASH_DUMP_MODE DCMD to all controllers
7906 * @cmd: MFI command frame
7907 */
7908
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007909static int megasas_set_crash_dump_params_ioctl(struct megasas_cmd *cmd)
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307910{
7911 struct megasas_instance *local_instance;
7912 int i, error = 0;
7913 int crash_support;
7914
7915 crash_support = cmd->frame->dcmd.mbox.w[0];
7916
7917 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
7918 local_instance = megasas_mgmt_info.instance[i];
7919 if (local_instance && local_instance->crash_dump_drv_support) {
Sumit Saxena8a01a412016-01-28 21:04:32 +05307920 if ((atomic_read(&local_instance->adprecovery) ==
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307921 MEGASAS_HBA_OPERATIONAL) &&
7922 !megasas_set_crash_dump_params(local_instance,
7923 crash_support)) {
7924 local_instance->crash_dump_app_support =
7925 crash_support;
7926 dev_info(&local_instance->pdev->dev,
7927 "Application firmware crash "
7928 "dump mode set success\n");
7929 error = 0;
7930 } else {
7931 dev_info(&local_instance->pdev->dev,
7932 "Application firmware crash "
7933 "dump mode set failed\n");
7934 error = -1;
7935 }
7936 }
7937 }
7938 return error;
7939}
7940
Yang, Boc3518832009-10-06 14:18:02 -06007941/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007942 * megasas_mgmt_fw_ioctl - Issues management ioctls to FW
7943 * @instance: Adapter soft state
7944 * @argp: User's ioctl packet
7945 */
7946static int
7947megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
7948 struct megasas_iocpacket __user * user_ioc,
7949 struct megasas_iocpacket *ioc)
7950{
Shivasharan S107a60d2017-10-19 02:49:05 -07007951 struct megasas_sge64 *kern_sge64 = NULL;
7952 struct megasas_sge32 *kern_sge32 = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007953 struct megasas_cmd *cmd;
7954 void *kbuff_arr[MAX_IOCTL_SGE];
7955 dma_addr_t buf_handle = 0;
7956 int error = 0, i;
7957 void *sense = NULL;
7958 dma_addr_t sense_handle;
Yang, Bo7b2519a2009-10-06 14:52:20 -06007959 unsigned long *sense_ptr;
Shivasharan S82add4e2017-10-19 02:49:02 -07007960 u32 opcode = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007961
7962 memset(kbuff_arr, 0, sizeof(kbuff_arr));
7963
7964 if (ioc->sge_count > MAX_IOCTL_SGE) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007965 dev_printk(KERN_DEBUG, &instance->pdev->dev, "SGE count [%d] > max limit [%d]\n",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007966 ioc->sge_count, MAX_IOCTL_SGE);
7967 return -EINVAL;
7968 }
7969
Shivasharan Sf870bcb2018-01-05 05:33:04 -08007970 if ((ioc->frame.hdr.cmd >= MFI_CMD_OP_COUNT) ||
7971 ((ioc->frame.hdr.cmd == MFI_CMD_NVME) &&
Chandrakanth Patil58136852019-06-25 16:34:30 +05307972 !instance->support_nvme_passthru) ||
7973 ((ioc->frame.hdr.cmd == MFI_CMD_TOOLBOX) &&
7974 !instance->support_pci_lane_margining)) {
Shivasharan S82add4e2017-10-19 02:49:02 -07007975 dev_err(&instance->pdev->dev,
7976 "Received invalid ioctl command 0x%x\n",
7977 ioc->frame.hdr.cmd);
7978 return -ENOTSUPP;
7979 }
7980
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007981 cmd = megasas_get_cmd(instance);
7982 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007983 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a cmd packet\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007984 return -ENOMEM;
7985 }
7986
7987 /*
7988 * User's IOCTL packet has 2 frames (maximum). Copy those two
7989 * frames into our cmd's frames. cmd->frame's context will get
7990 * overwritten when we copy from user's frames. So set that value
7991 * alone separately
7992 */
7993 memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05307994 cmd->frame->hdr.context = cpu_to_le32(cmd->index);
Yang, Boc3518832009-10-06 14:18:02 -06007995 cmd->frame->hdr.pad_0 = 0;
Shivasharan S107a60d2017-10-19 02:49:05 -07007996
7997 cmd->frame->hdr.flags &= (~MFI_FRAME_IEEE);
7998
7999 if (instance->consistent_mask_64bit)
8000 cmd->frame->hdr.flags |= cpu_to_le16((MFI_FRAME_SGL64 |
8001 MFI_FRAME_SENSE64));
8002 else
8003 cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_SGL64 |
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05308004 MFI_FRAME_SENSE64));
Shivasharan S82add4e2017-10-19 02:49:02 -07008005
8006 if (cmd->frame->hdr.cmd == MFI_CMD_DCMD)
8007 opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008008
Shivasharan S8823abe2017-08-23 04:47:00 -07008009 if (opcode == MR_DCMD_CTRL_SHUTDOWN) {
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05308010 mutex_lock(&instance->reset_mutex);
Shivasharan S95c06082017-02-10 00:59:23 -08008011 if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) {
8012 megasas_return_cmd(instance, cmd);
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05308013 mutex_unlock(&instance->reset_mutex);
Shivasharan S95c06082017-02-10 00:59:23 -08008014 return -1;
8015 }
Chandrakanth Patil7fa31742019-06-25 16:34:23 +05308016 mutex_unlock(&instance->reset_mutex);
Shivasharan S95c06082017-02-10 00:59:23 -08008017 }
8018
Shivasharan S8823abe2017-08-23 04:47:00 -07008019 if (opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) {
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05308020 error = megasas_set_crash_dump_params_ioctl(cmd);
8021 megasas_return_cmd(instance, cmd);
8022 return error;
8023 }
8024
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008025 /*
8026 * The management interface between applications and the fw uses
8027 * MFI frames. E.g, RAID configuration changes, LD property changes
8028 * etc are accomplishes through different kinds of MFI frames. The
8029 * driver needs to care only about substituting user buffers with
8030 * kernel buffers in SGLs. The location of SGL is embedded in the
8031 * struct iocpacket itself.
8032 */
Shivasharan S107a60d2017-10-19 02:49:05 -07008033 if (instance->consistent_mask_64bit)
8034 kern_sge64 = (struct megasas_sge64 *)
8035 ((unsigned long)cmd->frame + ioc->sgl_off);
8036 else
8037 kern_sge32 = (struct megasas_sge32 *)
8038 ((unsigned long)cmd->frame + ioc->sgl_off);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008039
8040 /*
8041 * For each user buffer, create a mirror buffer and copy in
8042 */
8043 for (i = 0; i < ioc->sge_count; i++) {
Bjørn Mork98cb7e42011-01-19 10:01:14 +01008044 if (!ioc->sgl[i].iov_len)
8045 continue;
8046
Sumant Patro9f35fa82007-02-14 12:55:45 -08008047 kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008048 ioc->sgl[i].iov_len,
Sumant Patro9f35fa82007-02-14 12:55:45 -08008049 &buf_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008050 if (!kbuff_arr[i]) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05008051 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc "
8052 "kernel SGL buffer for IOCTL\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008053 error = -ENOMEM;
8054 goto out;
8055 }
8056
8057 /*
8058 * We don't change the dma_coherent_mask, so
Christoph Hellwig60ee6522018-10-10 19:31:25 +02008059 * dma_alloc_coherent only returns 32bit addresses
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008060 */
Shivasharan S107a60d2017-10-19 02:49:05 -07008061 if (instance->consistent_mask_64bit) {
8062 kern_sge64[i].phys_addr = cpu_to_le64(buf_handle);
8063 kern_sge64[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
8064 } else {
8065 kern_sge32[i].phys_addr = cpu_to_le32(buf_handle);
8066 kern_sge32[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
8067 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008068
8069 /*
8070 * We created a kernel buffer corresponding to the
8071 * user buffer. Now copy in from the user buffer
8072 */
8073 if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base,
8074 (u32) (ioc->sgl[i].iov_len))) {
8075 error = -EFAULT;
8076 goto out;
8077 }
8078 }
8079
8080 if (ioc->sense_len) {
Sumant Patro9f35fa82007-02-14 12:55:45 -08008081 sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,
8082 &sense_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008083 if (!sense) {
8084 error = -ENOMEM;
8085 goto out;
8086 }
8087
8088 sense_ptr =
Yang, Bo7b2519a2009-10-06 14:52:20 -06008089 (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
Shivasharan S107a60d2017-10-19 02:49:05 -07008090 if (instance->consistent_mask_64bit)
8091 *sense_ptr = cpu_to_le64(sense_handle);
8092 else
8093 *sense_ptr = cpu_to_le32(sense_handle);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008094 }
8095
8096 /*
8097 * Set the sync_cmd flag so that the ISR knows not to complete this
8098 * cmd to the SCSI mid-layer
8099 */
8100 cmd->sync_cmd = 1;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05308101 if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) {
8102 cmd->sync_cmd = 0;
8103 dev_err(&instance->pdev->dev,
Shivasharan S82add4e2017-10-19 02:49:02 -07008104 "return -EBUSY from %s %d cmd 0x%x opcode 0x%x cmd->cmd_status_drv 0x%x\n",
8105 __func__, __LINE__, cmd->frame->hdr.cmd, opcode,
8106 cmd->cmd_status_drv);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05308107 return -EBUSY;
8108 }
8109
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008110 cmd->sync_cmd = 0;
8111
Sumit.Saxena@avagotech.comaa008322014-11-17 15:24:08 +05308112 if (instance->unload == 1) {
8113 dev_info(&instance->pdev->dev, "Driver unload is in progress "
8114 "don't submit data to application\n");
8115 goto out;
8116 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008117 /*
8118 * copy out the kernel buffers to user buffers
8119 */
8120 for (i = 0; i < ioc->sge_count; i++) {
8121 if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i],
8122 ioc->sgl[i].iov_len)) {
8123 error = -EFAULT;
8124 goto out;
8125 }
8126 }
8127
8128 /*
8129 * copy out the sense
8130 */
8131 if (ioc->sense_len) {
8132 /*
bo yangb70a41e2008-03-18 03:13:06 -04008133 * sense_ptr points to the location that has the user
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008134 * sense buffer address
8135 */
Yang, Bo7b2519a2009-10-06 14:52:20 -06008136 sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
8137 ioc->sense_off);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008138
Shivasharan S318aaef2017-02-10 00:59:22 -08008139 if (copy_to_user((void __user *)((unsigned long)
8140 get_unaligned((unsigned long *)sense_ptr)),
bo yangb70a41e2008-03-18 03:13:06 -04008141 sense, ioc->sense_len)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05008142 dev_err(&instance->pdev->dev, "Failed to copy out to user "
bo yangb10c36a2007-11-09 04:28:47 -05008143 "sense data\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008144 error = -EFAULT;
8145 goto out;
8146 }
8147 }
8148
8149 /*
8150 * copy the status codes returned by the fw
8151 */
8152 if (copy_to_user(&user_ioc->frame.hdr.cmd_status,
8153 &cmd->frame->hdr.cmd_status, sizeof(u8))) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05008154 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Error copying out cmd_status\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008155 error = -EFAULT;
8156 }
8157
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05008158out:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008159 if (sense) {
Sumant Patro9f35fa82007-02-14 12:55:45 -08008160 dma_free_coherent(&instance->pdev->dev, ioc->sense_len,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008161 sense, sense_handle);
8162 }
8163
Bjørn Mork7a6a7312012-11-21 09:54:48 +01008164 for (i = 0; i < ioc->sge_count; i++) {
Arnd Bergmann3deb9432016-03-14 15:29:45 +01008165 if (kbuff_arr[i]) {
Shivasharan S107a60d2017-10-19 02:49:05 -07008166 if (instance->consistent_mask_64bit)
8167 dma_free_coherent(&instance->pdev->dev,
8168 le32_to_cpu(kern_sge64[i].length),
8169 kbuff_arr[i],
8170 le64_to_cpu(kern_sge64[i].phys_addr));
8171 else
8172 dma_free_coherent(&instance->pdev->dev,
8173 le32_to_cpu(kern_sge32[i].length),
8174 kbuff_arr[i],
8175 le32_to_cpu(kern_sge32[i].phys_addr));
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05308176 kbuff_arr[i] = NULL;
Arnd Bergmann3deb9432016-03-14 15:29:45 +01008177 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008178 }
8179
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05308180 megasas_return_cmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008181 return error;
8182}
8183
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008184static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
8185{
8186 struct megasas_iocpacket __user *user_ioc =
8187 (struct megasas_iocpacket __user *)arg;
8188 struct megasas_iocpacket *ioc;
8189 struct megasas_instance *instance;
8190 int error;
8191
Markus Elfring709ab232016-08-21 10:39:04 +02008192 ioc = memdup_user(user_ioc, sizeof(*ioc));
8193 if (IS_ERR(ioc))
8194 return PTR_ERR(ioc);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008195
8196 instance = megasas_lookup_instance(ioc->host_no);
8197 if (!instance) {
8198 error = -ENODEV;
8199 goto out_kfree_ioc;
8200 }
8201
adam radford229fe472014-03-10 02:51:56 -07008202 /* Block ioctls in VF mode */
8203 if (instance->requestorId && !allow_vf_ioctls) {
8204 error = -ENODEV;
8205 goto out_kfree_ioc;
8206 }
8207
Sumit Saxena8a01a412016-01-28 21:04:32 +05308208 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05008209 dev_err(&instance->pdev->dev, "Controller in crit error\n");
Yang, Bo0c79e682009-10-06 14:47:35 -06008210 error = -ENODEV;
8211 goto out_kfree_ioc;
8212 }
8213
8214 if (instance->unload == 1) {
8215 error = -ENODEV;
8216 goto out_kfree_ioc;
8217 }
8218
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008219 if (down_interruptible(&instance->ioctl_sem)) {
8220 error = -ERESTARTSYS;
8221 goto out_kfree_ioc;
8222 }
bo yang39a98552010-09-22 22:36:29 -04008223
Shivasharan S619831f2018-01-05 05:27:43 -08008224 if (megasas_wait_for_adapter_operational(instance)) {
bo yang39a98552010-09-22 22:36:29 -04008225 error = -ENODEV;
Dan Carpenterc64e4832013-04-16 10:44:19 +03008226 goto out_up;
bo yang39a98552010-09-22 22:36:29 -04008227 }
bo yang39a98552010-09-22 22:36:29 -04008228
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008229 error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05008230out_up:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008231 up(&instance->ioctl_sem);
8232
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05008233out_kfree_ioc:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008234 kfree(ioc);
8235 return error;
8236}
8237
8238static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
8239{
8240 struct megasas_instance *instance;
8241 struct megasas_aen aen;
8242 int error;
8243
8244 if (file->private_data != file) {
8245 printk(KERN_DEBUG "megasas: fasync_helper was not "
8246 "called first\n");
8247 return -EINVAL;
8248 }
8249
8250 if (copy_from_user(&aen, (void __user *)arg, sizeof(aen)))
8251 return -EFAULT;
8252
8253 instance = megasas_lookup_instance(aen.host_no);
8254
8255 if (!instance)
8256 return -ENODEV;
8257
Sumit Saxena8a01a412016-01-28 21:04:32 +05308258 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
bo yang39a98552010-09-22 22:36:29 -04008259 return -ENODEV;
Yang, Bo0c79e682009-10-06 14:47:35 -06008260 }
8261
8262 if (instance->unload == 1) {
8263 return -ENODEV;
8264 }
8265
Shivasharan S619831f2018-01-05 05:27:43 -08008266 if (megasas_wait_for_adapter_operational(instance))
bo yang39a98552010-09-22 22:36:29 -04008267 return -ENODEV;
bo yang39a98552010-09-22 22:36:29 -04008268
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308269 mutex_lock(&instance->reset_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008270 error = megasas_register_aen(instance, aen.seq_num,
8271 aen.class_locale_word);
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308272 mutex_unlock(&instance->reset_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008273 return error;
8274}
8275
8276/**
8277 * megasas_mgmt_ioctl - char node ioctl entry point
8278 */
8279static long
8280megasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
8281{
8282 switch (cmd) {
8283 case MEGASAS_IOC_FIRMWARE:
8284 return megasas_mgmt_ioctl_fw(file, arg);
8285
8286 case MEGASAS_IOC_GET_AEN:
8287 return megasas_mgmt_ioctl_aen(file, arg);
8288 }
8289
8290 return -ENOTTY;
8291}
8292
8293#ifdef CONFIG_COMPAT
8294static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
8295{
8296 struct compat_megasas_iocpacket __user *cioc =
8297 (struct compat_megasas_iocpacket __user *)arg;
8298 struct megasas_iocpacket __user *ioc =
8299 compat_alloc_user_space(sizeof(struct megasas_iocpacket));
8300 int i;
8301 int error = 0;
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01008302 compat_uptr_t ptr;
sumit.saxena@avagotech.com323c4a02015-10-15 13:40:54 +05308303 u32 local_sense_off;
8304 u32 local_sense_len;
Sumit Saxenaea1c9282016-01-28 21:14:26 +05308305 u32 user_sense_off;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008306
Jeff Garzik83aabc12006-10-04 06:34:03 -04008307 if (clear_user(ioc, sizeof(*ioc)))
8308 return -EFAULT;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008309
8310 if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) ||
8311 copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) ||
8312 copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) ||
8313 copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) ||
8314 copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) ||
8315 copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
8316 return -EFAULT;
8317
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01008318 /*
8319 * The sense_ptr is used in megasas_mgmt_fw_ioctl only when
8320 * sense_len is not null, so prepare the 64bit value under
8321 * the same condition.
8322 */
Sumit Saxenaea1c9282016-01-28 21:14:26 +05308323 if (get_user(local_sense_off, &ioc->sense_off) ||
8324 get_user(local_sense_len, &ioc->sense_len) ||
8325 get_user(user_sense_off, &cioc->sense_off))
sumit.saxena@avagotech.com323c4a02015-10-15 13:40:54 +05308326 return -EFAULT;
8327
Wenwen Wang47db7872018-10-06 13:34:21 -05008328 if (local_sense_off != user_sense_off)
8329 return -EINVAL;
8330
sumit.saxena@avagotech.com323c4a02015-10-15 13:40:54 +05308331 if (local_sense_len) {
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01008332 void __user **sense_ioc_ptr =
Sumit Saxenaea1c9282016-01-28 21:14:26 +05308333 (void __user **)((u8 *)((unsigned long)&ioc->frame.raw) + local_sense_off);
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01008334 compat_uptr_t *sense_cioc_ptr =
Sumit Saxenaea1c9282016-01-28 21:14:26 +05308335 (compat_uptr_t *)(((unsigned long)&cioc->frame.raw) + user_sense_off);
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01008336 if (get_user(ptr, sense_cioc_ptr) ||
8337 put_user(compat_ptr(ptr), sense_ioc_ptr))
8338 return -EFAULT;
8339 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008340
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01008341 for (i = 0; i < MAX_IOCTL_SGE; i++) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008342 if (get_user(ptr, &cioc->sgl[i].iov_base) ||
8343 put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
8344 copy_in_user(&ioc->sgl[i].iov_len,
8345 &cioc->sgl[i].iov_len, sizeof(compat_size_t)))
8346 return -EFAULT;
8347 }
8348
8349 error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc);
8350
8351 if (copy_in_user(&cioc->frame.hdr.cmd_status,
8352 &ioc->frame.hdr.cmd_status, sizeof(u8))) {
8353 printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n");
8354 return -EFAULT;
8355 }
8356 return error;
8357}
8358
8359static long
8360megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd,
8361 unsigned long arg)
8362{
8363 switch (cmd) {
Sumant Patrocb59aa62006-01-25 11:53:25 -08008364 case MEGASAS_IOC_FIRMWARE32:
8365 return megasas_mgmt_compat_ioctl_fw(file, arg);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008366 case MEGASAS_IOC_GET_AEN:
8367 return megasas_mgmt_ioctl_aen(file, arg);
8368 }
8369
8370 return -ENOTTY;
8371}
8372#endif
8373
8374/*
8375 * File operations structure for management interface
8376 */
Arjan van de Ven00977a52007-02-12 00:55:34 -08008377static const struct file_operations megasas_mgmt_fops = {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008378 .owner = THIS_MODULE,
8379 .open = megasas_mgmt_open,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008380 .fasync = megasas_mgmt_fasync,
8381 .unlocked_ioctl = megasas_mgmt_ioctl,
Yang, Boc3518832009-10-06 14:18:02 -06008382 .poll = megasas_mgmt_poll,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008383#ifdef CONFIG_COMPAT
8384 .compat_ioctl = megasas_mgmt_compat_ioctl,
8385#endif
Arnd Bergmann6038f372010-08-15 18:52:59 +02008386 .llseek = noop_llseek,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008387};
8388
8389/*
8390 * PCI hotplug support registration structure
8391 */
8392static struct pci_driver megasas_pci_driver = {
8393
8394 .name = "megaraid_sas",
8395 .id_table = megasas_pci_table,
8396 .probe = megasas_probe_one,
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08008397 .remove = megasas_detach_one,
bo yang31ea7082007-11-07 12:09:50 -05008398 .suspend = megasas_suspend,
8399 .resume = megasas_resume,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008400 .shutdown = megasas_shutdown,
8401};
8402
8403/*
8404 * Sysfs driver attributes
8405 */
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008406static ssize_t version_show(struct device_driver *dd, char *buf)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008407{
8408 return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n",
8409 MEGASAS_VERSION);
8410}
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008411static DRIVER_ATTR_RO(version);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008412
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008413static ssize_t release_date_show(struct device_driver *dd, char *buf)
Sumit.Saxena@avagotech.com09fced12015-04-23 16:31:54 +05308414{
8415 return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n",
8416 MEGASAS_RELDATE);
8417}
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008418static DRIVER_ATTR_RO(release_date);
Sumit.Saxena@avagotech.com09fced12015-04-23 16:31:54 +05308419
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008420static ssize_t support_poll_for_event_show(struct device_driver *dd, char *buf)
Yang, Bo72c4fd32009-10-06 14:20:59 -06008421{
8422 return sprintf(buf, "%u\n", support_poll_for_event);
8423}
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008424static DRIVER_ATTR_RO(support_poll_for_event);
Yang, Bo72c4fd32009-10-06 14:20:59 -06008425
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008426static ssize_t support_device_change_show(struct device_driver *dd, char *buf)
Yang, Bo837f5fe2010-10-11 06:59:20 -06008427{
8428 return sprintf(buf, "%u\n", support_device_change);
8429}
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008430static DRIVER_ATTR_RO(support_device_change);
Yang, Bo837f5fe2010-10-11 06:59:20 -06008431
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008432static ssize_t dbg_lvl_show(struct device_driver *dd, char *buf)
Sumant Patro658dced2006-10-03 13:09:14 -07008433{
bo yangad84db22007-11-09 04:40:16 -05008434 return sprintf(buf, "%u\n", megasas_dbg_lvl);
Sumant Patro658dced2006-10-03 13:09:14 -07008435}
8436
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008437static ssize_t dbg_lvl_store(struct device_driver *dd, const char *buf,
8438 size_t count)
Sumant Patro658dced2006-10-03 13:09:14 -07008439{
8440 int retval = count;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05008441
8442 if (sscanf(buf, "%u", &megasas_dbg_lvl) < 1) {
Sumant Patro658dced2006-10-03 13:09:14 -07008443 printk(KERN_ERR "megasas: could not set dbg_lvl\n");
8444 retval = -EINVAL;
8445 }
8446 return retval;
8447}
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02008448static DRIVER_ATTR_RW(dbg_lvl);
bo yangad84db22007-11-09 04:40:16 -05008449
Shivasharan Sf870bcb2018-01-05 05:33:04 -08008450static ssize_t
8451support_nvme_encapsulation_show(struct device_driver *dd, char *buf)
8452{
8453 return sprintf(buf, "%u\n", support_nvme_encapsulation);
8454}
8455
8456static DRIVER_ATTR_RO(support_nvme_encapsulation);
8457
Chandrakanth Patil58136852019-06-25 16:34:30 +05308458static ssize_t
8459support_pci_lane_margining_show(struct device_driver *dd, char *buf)
8460{
8461 return sprintf(buf, "%u\n", support_pci_lane_margining);
8462}
8463
8464static DRIVER_ATTR_RO(support_pci_lane_margining);
8465
Shivasharan Sb4a42212017-02-10 00:59:16 -08008466static inline void megasas_remove_scsi_device(struct scsi_device *sdev)
8467{
8468 sdev_printk(KERN_INFO, sdev, "SCSI device is removed\n");
8469 scsi_remove_device(sdev);
8470 scsi_device_put(sdev);
8471}
8472
Shivasharan S44abbaf2019-01-29 01:38:13 -08008473/**
8474 * megasas_update_device_list - Update the PD and LD device list from FW
8475 * after an AEN event notification
8476 * @instance: Adapter soft state
8477 * @event_type: Indicates type of event (PD or LD event)
8478 *
8479 * @return: Success or failure
8480 *
8481 * Issue DCMDs to Firmware to update the internal device list in driver.
Shivasharan Sf6fe5732019-01-29 01:38:14 -08008482 * Based on the FW support, driver sends the HOST_DEVICE_LIST or combination
8483 * of PD_LIST/LD_LIST_QUERY DCMDs to get the device list.
Shivasharan S44abbaf2019-01-29 01:38:13 -08008484 */
8485static
8486int megasas_update_device_list(struct megasas_instance *instance,
8487 int event_type)
8488{
8489 int dcmd_ret = DCMD_SUCCESS;
8490
Shivasharan Sf6fe5732019-01-29 01:38:14 -08008491 if (instance->enable_fw_dev_list) {
8492 dcmd_ret = megasas_host_device_list_query(instance, false);
Shivasharan S44abbaf2019-01-29 01:38:13 -08008493 if (dcmd_ret != DCMD_SUCCESS)
8494 goto out;
Shivasharan Sf6fe5732019-01-29 01:38:14 -08008495 } else {
8496 if (event_type & SCAN_PD_CHANNEL) {
8497 dcmd_ret = megasas_get_pd_list(instance);
Shivasharan S44abbaf2019-01-29 01:38:13 -08008498
Shivasharan S44abbaf2019-01-29 01:38:13 -08008499 if (dcmd_ret != DCMD_SUCCESS)
8500 goto out;
8501 }
Shivasharan Sf6fe5732019-01-29 01:38:14 -08008502
8503 if (event_type & SCAN_VD_CHANNEL) {
8504 if (!instance->requestorId ||
8505 (instance->requestorId &&
8506 megasas_get_ld_vf_affiliation(instance, 0))) {
8507 dcmd_ret = megasas_ld_list_query(instance,
8508 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST);
8509 if (dcmd_ret != DCMD_SUCCESS)
8510 goto out;
8511 }
8512 }
Shivasharan S44abbaf2019-01-29 01:38:13 -08008513 }
8514
8515out:
8516 return dcmd_ret;
8517}
8518
8519/**
8520 * megasas_add_remove_devices - Add/remove devices to SCSI mid-layer
8521 * after an AEN event notification
8522 * @instance: Adapter soft state
8523 * @scan_type: Indicates type of devices (PD/LD) to add
8524 * @return void
8525 */
8526static
8527void megasas_add_remove_devices(struct megasas_instance *instance,
8528 int scan_type)
8529{
8530 int i, j;
8531 u16 pd_index = 0;
8532 u16 ld_index = 0;
Shivasharan Sf6fe5732019-01-29 01:38:14 -08008533 u16 channel = 0, id = 0;
Shivasharan S44abbaf2019-01-29 01:38:13 -08008534 struct Scsi_Host *host;
8535 struct scsi_device *sdev1;
Shivasharan Sf6fe5732019-01-29 01:38:14 -08008536 struct MR_HOST_DEVICE_LIST *targetid_list = NULL;
8537 struct MR_HOST_DEVICE_LIST_ENTRY *targetid_entry = NULL;
Shivasharan S44abbaf2019-01-29 01:38:13 -08008538
8539 host = instance->host;
8540
Shivasharan Sf6fe5732019-01-29 01:38:14 -08008541 if (instance->enable_fw_dev_list) {
8542 targetid_list = instance->host_device_list_buf;
8543 for (i = 0; i < targetid_list->count; i++) {
8544 targetid_entry = &targetid_list->host_device_list[i];
8545 if (targetid_entry->flags.u.bits.is_sys_pd) {
8546 channel = le16_to_cpu(targetid_entry->target_id) /
8547 MEGASAS_MAX_DEV_PER_CHANNEL;
8548 id = le16_to_cpu(targetid_entry->target_id) %
8549 MEGASAS_MAX_DEV_PER_CHANNEL;
8550 } else {
8551 channel = MEGASAS_MAX_PD_CHANNELS +
8552 (le16_to_cpu(targetid_entry->target_id) /
8553 MEGASAS_MAX_DEV_PER_CHANNEL);
8554 id = le16_to_cpu(targetid_entry->target_id) %
8555 MEGASAS_MAX_DEV_PER_CHANNEL;
8556 }
8557 sdev1 = scsi_device_lookup(host, channel, id, 0);
8558 if (!sdev1) {
8559 scsi_add_device(host, channel, id, 0);
8560 } else {
8561 scsi_device_put(sdev1);
8562 }
8563 }
8564 }
8565
Shivasharan S44abbaf2019-01-29 01:38:13 -08008566 if (scan_type & SCAN_PD_CHANNEL) {
8567 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
8568 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
8569 pd_index = i * MEGASAS_MAX_DEV_PER_CHANNEL + j;
8570 sdev1 = scsi_device_lookup(host, i, j, 0);
8571 if (instance->pd_list[pd_index].driveState ==
8572 MR_PD_STATE_SYSTEM) {
8573 if (!sdev1)
8574 scsi_add_device(host, i, j, 0);
8575 else
8576 scsi_device_put(sdev1);
8577 } else {
8578 if (sdev1)
8579 megasas_remove_scsi_device(sdev1);
8580 }
8581 }
8582 }
8583 }
8584
8585 if (scan_type & SCAN_VD_CHANNEL) {
8586 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
8587 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
8588 ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
8589 sdev1 = scsi_device_lookup(host,
8590 MEGASAS_MAX_PD_CHANNELS + i, j, 0);
8591 if (instance->ld_ids[ld_index] != 0xff) {
8592 if (!sdev1)
8593 scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
8594 else
8595 scsi_device_put(sdev1);
8596 } else {
8597 if (sdev1)
8598 megasas_remove_scsi_device(sdev1);
8599 }
8600 }
8601 }
8602 }
8603
8604}
8605
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008606static void
8607megasas_aen_polling(struct work_struct *work)
8608{
8609 struct megasas_aen_event *ev =
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08008610 container_of(work, struct megasas_aen_event, hotplug_work.work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008611 struct megasas_instance *instance = ev->instance;
8612 union megasas_evt_class_locale class_locale;
Shivasharan S44abbaf2019-01-29 01:38:13 -08008613 int event_type = 0;
YueHaibingde192122019-05-25 20:42:02 +08008614 u32 seq_num;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008615 int error;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05308616 u8 dcmd_ret = DCMD_SUCCESS;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008617
8618 if (!instance) {
8619 printk(KERN_ERR "invalid instance!\n");
8620 kfree(ev);
8621 return;
8622 }
adam radford229fe472014-03-10 02:51:56 -07008623
adam radford229fe472014-03-10 02:51:56 -07008624 /* Don't run the event workqueue thread if OCR is running */
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308625 mutex_lock(&instance->reset_mutex);
adam radford229fe472014-03-10 02:51:56 -07008626
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008627 instance->ev = NULL;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008628 if (instance->evt_detail) {
sumit.saxena@avagotech.com714f5172015-08-31 17:23:51 +05308629 megasas_decode_evt(instance);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008630
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05308631 switch (le32_to_cpu(instance->evt_detail->code)) {
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308632
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008633 case MR_EVT_PD_INSERTED:
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308634 case MR_EVT_PD_REMOVED:
Shivasharan S44abbaf2019-01-29 01:38:13 -08008635 event_type = SCAN_PD_CHANNEL;
Yang, Boc9786842009-12-06 08:39:25 -07008636 break;
8637
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308638 case MR_EVT_LD_OFFLINE:
8639 case MR_EVT_CFG_CLEARED:
8640 case MR_EVT_LD_DELETED:
8641 case MR_EVT_LD_CREATED:
Shivasharan S44abbaf2019-01-29 01:38:13 -08008642 event_type = SCAN_VD_CHANNEL;
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308643 break;
8644
8645 case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
8646 case MR_EVT_FOREIGN_CFG_IMPORTED:
8647 case MR_EVT_LD_STATE_CHANGE:
Shivasharan S44abbaf2019-01-29 01:38:13 -08008648 event_type = SCAN_PD_CHANNEL | SCAN_VD_CHANNEL;
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308649 dev_info(&instance->pdev->dev, "scanning for scsi%d...\n",
8650 instance->host->host_no);
8651 break;
8652
8653 case MR_EVT_CTRL_PROP_CHANGED:
Shivasharan Sf0c21df2018-10-16 23:37:40 -07008654 dcmd_ret = megasas_get_ctrl_info(instance);
8655 if (dcmd_ret == DCMD_SUCCESS &&
8656 instance->snapdump_wait_time) {
8657 megasas_get_snapdump_properties(instance);
8658 dev_info(&instance->pdev->dev,
8659 "Snap dump wait time\t: %d\n",
8660 instance->snapdump_wait_time);
8661 }
8662 break;
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308663 default:
Shivasharan S44abbaf2019-01-29 01:38:13 -08008664 event_type = 0;
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308665 break;
8666 }
8667 } else {
8668 dev_err(&instance->pdev->dev, "invalid evt_detail!\n");
8669 mutex_unlock(&instance->reset_mutex);
8670 kfree(ev);
8671 return;
8672 }
8673
Shivasharan S44abbaf2019-01-29 01:38:13 -08008674 if (event_type)
8675 dcmd_ret = megasas_update_device_list(instance, event_type);
8676
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308677 mutex_unlock(&instance->reset_mutex);
8678
Shivasharan S44abbaf2019-01-29 01:38:13 -08008679 if (event_type && dcmd_ret == DCMD_SUCCESS)
8680 megasas_add_remove_devices(instance, event_type);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008681
Sumit Saxena6d40afb2016-01-28 21:04:23 +05308682 if (dcmd_ret == DCMD_SUCCESS)
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308683 seq_num = le32_to_cpu(instance->evt_detail->seq_num) + 1;
8684 else
8685 seq_num = instance->last_seq_num;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008686
8687 /* Register AEN with FW for latest sequence number plus 1 */
8688 class_locale.members.reserved = 0;
8689 class_locale.members.locale = MR_EVT_LOCALE_ALL;
8690 class_locale.members.class = MR_EVT_CLASS_DEBUG;
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308691
8692 if (instance->aen_cmd != NULL) {
8693 kfree(ev);
8694 return;
8695 }
8696
8697 mutex_lock(&instance->reset_mutex);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008698 error = megasas_register_aen(instance, seq_num,
8699 class_locale.word);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008700 if (error)
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308701 dev_err(&instance->pdev->dev,
8702 "register aen failed error %x\n", error);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008703
Sumit Saxena11c71cb2016-01-28 21:04:22 +05308704 mutex_unlock(&instance->reset_mutex);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06008705 kfree(ev);
8706}
8707
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008708/**
8709 * megasas_init - Driver load entry point
8710 */
8711static int __init megasas_init(void)
8712{
8713 int rval;
8714
8715 /*
Sumit Saxenac3e385a2016-04-15 00:23:30 -07008716 * Booted in kdump kernel, minimize memory footprints by
8717 * disabling few features
8718 */
8719 if (reset_devices) {
8720 msix_vectors = 1;
8721 rdpq_enable = 0;
8722 dual_qdepth_disable = 1;
8723 }
8724
8725 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008726 * Announce driver version and other information
8727 */
Sumit.Saxena@avagotech.comd98a6de2014-11-17 15:23:58 +05308728 pr_info("megasas: %s\n", MEGASAS_VERSION);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008729
Kashyap Desaibd8d6dd2012-07-17 18:20:44 -07008730 spin_lock_init(&poll_aen_lock);
8731
Yang, Bo72c4fd32009-10-06 14:20:59 -06008732 support_poll_for_event = 2;
Yang, Bo837f5fe2010-10-11 06:59:20 -06008733 support_device_change = 1;
Shivasharan Sf870bcb2018-01-05 05:33:04 -08008734 support_nvme_encapsulation = true;
Chandrakanth Patil58136852019-06-25 16:34:30 +05308735 support_pci_lane_margining = true;
Yang, Bo72c4fd32009-10-06 14:20:59 -06008736
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008737 memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
8738
8739 /*
8740 * Register character device node
8741 */
8742 rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops);
8743
8744 if (rval < 0) {
8745 printk(KERN_DEBUG "megasas: failed to open device node\n");
8746 return rval;
8747 }
8748
8749 megasas_mgmt_majorno = rval;
8750
Shivasharan Sba535722019-05-07 10:05:49 -07008751 megasas_init_debugfs();
8752
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008753 /*
8754 * Register ourselves as PCI hotplug module
8755 */
Michal Piotrowski4041b9c2006-08-17 13:28:22 +00008756 rval = pci_register_driver(&megasas_pci_driver);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008757
8758 if (rval) {
Masanari Iida6774def2014-11-05 22:26:48 +09008759 printk(KERN_DEBUG "megasas: PCI hotplug registration failed \n");
Jeff Garzik83aabc12006-10-04 06:34:03 -04008760 goto err_pcidrv;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008761 }
8762
Jeff Garzik83aabc12006-10-04 06:34:03 -04008763 rval = driver_create_file(&megasas_pci_driver.driver,
8764 &driver_attr_version);
8765 if (rval)
8766 goto err_dcf_attr_ver;
Yang, Bo72c4fd32009-10-06 14:20:59 -06008767
8768 rval = driver_create_file(&megasas_pci_driver.driver,
Sumit.Saxena@avagotech.com09fced12015-04-23 16:31:54 +05308769 &driver_attr_release_date);
8770 if (rval)
8771 goto err_dcf_rel_date;
8772
8773 rval = driver_create_file(&megasas_pci_driver.driver,
Yang, Bo72c4fd32009-10-06 14:20:59 -06008774 &driver_attr_support_poll_for_event);
8775 if (rval)
8776 goto err_dcf_support_poll_for_event;
8777
Jeff Garzik83aabc12006-10-04 06:34:03 -04008778 rval = driver_create_file(&megasas_pci_driver.driver,
8779 &driver_attr_dbg_lvl);
8780 if (rval)
8781 goto err_dcf_dbg_lvl;
bo yangad84db22007-11-09 04:40:16 -05008782 rval = driver_create_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06008783 &driver_attr_support_device_change);
8784 if (rval)
8785 goto err_dcf_support_device_change;
8786
Shivasharan Sf870bcb2018-01-05 05:33:04 -08008787 rval = driver_create_file(&megasas_pci_driver.driver,
8788 &driver_attr_support_nvme_encapsulation);
8789 if (rval)
8790 goto err_dcf_support_nvme_encapsulation;
8791
Chandrakanth Patil58136852019-06-25 16:34:30 +05308792 rval = driver_create_file(&megasas_pci_driver.driver,
8793 &driver_attr_support_pci_lane_margining);
8794 if (rval)
8795 goto err_dcf_support_pci_lane_margining;
8796
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008797 return rval;
bo yangad84db22007-11-09 04:40:16 -05008798
Chandrakanth Patil58136852019-06-25 16:34:30 +05308799err_dcf_support_pci_lane_margining:
8800 driver_remove_file(&megasas_pci_driver.driver,
8801 &driver_attr_support_nvme_encapsulation);
8802
Shivasharan Sf870bcb2018-01-05 05:33:04 -08008803err_dcf_support_nvme_encapsulation:
8804 driver_remove_file(&megasas_pci_driver.driver,
8805 &driver_attr_support_device_change);
8806
Yang, Bo837f5fe2010-10-11 06:59:20 -06008807err_dcf_support_device_change:
8808 driver_remove_file(&megasas_pci_driver.driver,
bo yangad84db22007-11-09 04:40:16 -05008809 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04008810err_dcf_dbg_lvl:
8811 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo72c4fd32009-10-06 14:20:59 -06008812 &driver_attr_support_poll_for_event);
Yang, Bo72c4fd32009-10-06 14:20:59 -06008813err_dcf_support_poll_for_event:
Sumit.Saxena@avagotech.com09fced12015-04-23 16:31:54 +05308814 driver_remove_file(&megasas_pci_driver.driver,
8815 &driver_attr_release_date);
8816err_dcf_rel_date:
Jeff Garzik83aabc12006-10-04 06:34:03 -04008817 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
8818err_dcf_attr_ver:
8819 pci_unregister_driver(&megasas_pci_driver);
8820err_pcidrv:
Shivasharan Sba535722019-05-07 10:05:49 -07008821 megasas_exit_debugfs();
Jeff Garzik83aabc12006-10-04 06:34:03 -04008822 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
adam radford0d490162010-12-14 19:17:17 -08008823 return rval;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008824}
8825
8826/**
8827 * megasas_exit - Driver unload entry point
8828 */
8829static void __exit megasas_exit(void)
8830{
Sumant Patro658dced2006-10-03 13:09:14 -07008831 driver_remove_file(&megasas_pci_driver.driver,
8832 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04008833 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06008834 &driver_attr_support_poll_for_event);
8835 driver_remove_file(&megasas_pci_driver.driver,
8836 &driver_attr_support_device_change);
Sumit.Saxena@avagotech.com09fced12015-04-23 16:31:54 +05308837 driver_remove_file(&megasas_pci_driver.driver,
8838 &driver_attr_release_date);
Jeff Garzik83aabc12006-10-04 06:34:03 -04008839 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
Shivasharan Sf870bcb2018-01-05 05:33:04 -08008840 driver_remove_file(&megasas_pci_driver.driver,
8841 &driver_attr_support_nvme_encapsulation);
Chandrakanth Patil58136852019-06-25 16:34:30 +05308842 driver_remove_file(&megasas_pci_driver.driver,
8843 &driver_attr_support_pci_lane_margining);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008844
8845 pci_unregister_driver(&megasas_pci_driver);
Shivasharan Sba535722019-05-07 10:05:49 -07008846 megasas_exit_debugfs();
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008847 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
8848}
8849
8850module_init(megasas_init);
8851module_exit(megasas_exit);