blob: 975c8a384ad1bb4b503d712e6964850330a59241 [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>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040051
52#include <scsi/scsi.h>
53#include <scsi/scsi_cmnd.h>
54#include <scsi/scsi_device.h>
55#include <scsi/scsi_host.h>
adam radford4bcde502011-07-26 15:42:52 -070056#include <scsi/scsi_tcq.h>
adam radford9c915a82010-12-21 13:34:31 -080057#include "megaraid_sas_fusion.h"
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040058#include "megaraid_sas.h"
59
bo yangad84db22007-11-09 04:40:16 -050060/*
Yang, Bo1fd10682010-10-12 07:18:50 -060061 * Number of sectors per IO command
62 * Will be set in megasas_init_mfi if user does not provide
63 */
64static unsigned int max_sectors;
65module_param_named(max_sectors, max_sectors, int, 0);
66MODULE_PARM_DESC(max_sectors,
67 "Maximum number of sectors per IO command");
68
adam radford80d9da92010-12-21 10:17:40 -080069static int msix_disable;
70module_param(msix_disable, int, S_IRUGO);
71MODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0");
72
adam radford079eadd2012-10-01 19:26:59 -070073static unsigned int msix_vectors;
74module_param(msix_vectors, int, S_IRUGO);
75MODULE_PARM_DESC(msix_vectors, "MSI-X max vector count. Default: Set by FW");
76
adam radford229fe472014-03-10 02:51:56 -070077static int allow_vf_ioctls;
78module_param(allow_vf_ioctls, int, S_IRUGO);
79MODULE_PARM_DESC(allow_vf_ioctls, "Allow ioctls in SR-IOV VF mode. Default: 0");
80
Sumit.Saxena@avagotech.comae09a6c2015-01-05 20:06:23 +053081static unsigned int throttlequeuedepth = MEGASAS_THROTTLE_QUEUE_DEPTH;
adam radfordc5daa6a2012-07-17 18:20:03 -070082module_param(throttlequeuedepth, int, S_IRUGO);
83MODULE_PARM_DESC(throttlequeuedepth,
84 "Adapter queue depth when throttled due to I/O timeout. Default: 16");
85
Sumit Saxenae3d178c2016-01-28 21:04:34 +053086unsigned int resetwaittime = MEGASAS_RESET_WAIT_TIME;
adam radfordc007b8b2012-07-17 18:20:24 -070087module_param(resetwaittime, int, S_IRUGO);
Shivasharan S14013712018-10-16 23:37:45 -070088MODULE_PARM_DESC(resetwaittime, "Wait time in (1-180s) after I/O timeout before resetting adapter. Default: 180s");
adam radfordc007b8b2012-07-17 18:20:24 -070089
Sumit.Saxena@avagotech.comac951362014-09-12 18:57:48 +053090int smp_affinity_enable = 1;
91module_param(smp_affinity_enable, int, S_IRUGO);
Colin Ian King55d9a1d2018-04-29 13:25:32 +010092MODULE_PARM_DESC(smp_affinity_enable, "SMP affinity feature enable/disable Default: enable(1)");
Sumit.Saxena@avagotech.comac951362014-09-12 18:57:48 +053093
Sumit Saxena179ac142016-01-28 21:04:28 +053094int rdpq_enable = 1;
95module_param(rdpq_enable, int, S_IRUGO);
Shivasharan S14013712018-10-16 23:37:45 -070096MODULE_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 +053097
Sumit Saxena308ec452016-01-28 21:04:30 +053098unsigned int dual_qdepth_disable;
99module_param(dual_qdepth_disable, int, S_IRUGO);
100MODULE_PARM_DESC(dual_qdepth_disable, "Disable dual queue depth feature. Default: 0");
101
Sumit Saxenae3d178c2016-01-28 21:04:34 +0530102unsigned int scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT;
103module_param(scmd_timeout, int, S_IRUGO);
104MODULE_PARM_DESC(scmd_timeout, "scsi command timeout (10-90s), default 90s. See megasas_reset_timer.");
105
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400106MODULE_LICENSE("GPL");
107MODULE_VERSION(MEGASAS_VERSION);
Shivasharan S365597c2018-10-16 23:37:43 -0700108MODULE_AUTHOR("megaraidlinux.pdl@broadcom.com");
109MODULE_DESCRIPTION("Broadcom MegaRAID SAS Driver");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400110
adam radford058a8fa2011-10-08 18:14:27 -0700111int megasas_transition_to_ready(struct megasas_instance *instance, int ocr);
bo yang39a98552010-09-22 22:36:29 -0400112static int megasas_get_pd_list(struct megasas_instance *instance);
adam radford21c9e162013-09-06 15:27:14 -0700113static int megasas_ld_list_query(struct megasas_instance *instance,
114 u8 query_type);
bo yang39a98552010-09-22 22:36:29 -0400115static int megasas_issue_init_mfi(struct megasas_instance *instance);
116static int megasas_register_aen(struct megasas_instance *instance,
117 u32 seq_num, u32 class_locale_word);
Shivasharan S15dd0382017-02-10 00:59:10 -0800118static void megasas_get_pd_info(struct megasas_instance *instance,
119 struct scsi_device *sdev);
Shivasharan Se9495e22018-06-04 03:45:12 -0700120
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400121/*
122 * PCI ID table for all supported controllers
123 */
124static struct pci_device_id megasas_pci_table[] = {
125
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200126 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064R)},
127 /* xscale IOP */
128 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
129 /* ppc IOP */
bo yangaf7a5642008-03-17 04:13:07 -0400130 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)},
131 /* ppc IOP */
Yang, Bo6610a6b2008-08-10 12:42:38 -0700132 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)},
133 /* gen2*/
134 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
135 /* gen2*/
Yang, Bo87911122009-10-06 14:31:54 -0600136 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
137 /* skinny*/
138 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
139 /* skinny*/
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200140 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
141 /* xscale IOP, vega */
142 {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
143 /* xscale IOP */
adam radford9c915a82010-12-21 13:34:31 -0800144 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FUSION)},
145 /* Fusion */
adam radford229fe472014-03-10 02:51:56 -0700146 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_PLASMA)},
147 /* Plasma */
adam radford36807e62011-10-08 18:15:06 -0700148 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INVADER)},
149 /* Invader */
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +0530150 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FURY)},
151 /* Fury */
sumit.saxena@avagotech.com90c204b2015-10-15 13:39:44 +0530152 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INTRUDER)},
153 /* Intruder */
154 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INTRUDER_24)},
155 /* Intruder 24 port*/
sumit.saxena@avagotech.com7364d342015-10-15 13:39:54 +0530156 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_52)},
157 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_53)},
Sasikumar Chandrasekaran45f4f2e2017-01-10 18:20:43 -0500158 /* VENTURA */
159 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA)},
Shivasharan S754f1ba2017-10-19 02:48:49 -0700160 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CRUSADER)},
Sasikumar Chandrasekaran45f4f2e2017-01-10 18:20:43 -0500161 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_HARPOON)},
162 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_TOMCAT)},
163 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA_4PORT)},
164 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CRUSADER_4PORT)},
Shivasharan S469f72d2018-11-09 09:47:20 -0800165 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E1)},
166 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E2)},
167 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E5)},
168 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_AERO_10E6)},
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200169 {}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400170};
171
172MODULE_DEVICE_TABLE(pci, megasas_pci_table);
173
174static int megasas_mgmt_majorno;
adam radford229fe472014-03-10 02:51:56 -0700175struct megasas_mgmt_info megasas_mgmt_info;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400176static struct fasync_struct *megasas_async_queue;
Arjan van de Ven0b950672006-01-11 13:16:10 +0100177static DEFINE_MUTEX(megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400178
Yang, Boc3518832009-10-06 14:18:02 -0600179static int megasas_poll_wait_aen;
180static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
Yang, Bo72c4fd32009-10-06 14:20:59 -0600181static u32 support_poll_for_event;
adam radford9c915a82010-12-21 13:34:31 -0800182u32 megasas_dbg_lvl;
Yang, Bo837f5fe2010-10-11 06:59:20 -0600183static u32 support_device_change;
Shivasharan Sf870bcb2018-01-05 05:33:04 -0800184static bool support_nvme_encapsulation;
Sumant Patro658dced2006-10-03 13:09:14 -0700185
Yang, Boc3518832009-10-06 14:18:02 -0600186/* define lock for aen poll */
187spinlock_t poll_aen_lock;
188
adam radford9c915a82010-12-21 13:34:31 -0800189void
bo yang7343eb62007-11-09 04:35:44 -0500190megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
191 u8 alt_status);
adam radfordebf054b2011-02-24 20:57:15 -0800192static u32
193megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs);
194static int
195megasas_adp_reset_gen2(struct megasas_instance *instance,
196 struct megasas_register_set __iomem *reg_set);
adam radfordcd50ba82010-12-21 10:23:23 -0800197static irqreturn_t megasas_isr(int irq, void *devp);
198static u32
199megasas_init_adapter_mfi(struct megasas_instance *instance);
200u32
201megasas_build_and_issue_cmd(struct megasas_instance *instance,
202 struct scsi_cmnd *scmd);
203static void megasas_complete_cmd_dpc(unsigned long instance_addr);
adam radford9c915a82010-12-21 13:34:31 -0800204int
adam radford229fe472014-03-10 02:51:56 -0700205wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
206 int seconds);
adam radford9c915a82010-12-21 13:34:31 -0800207void megasas_fusion_ocr_wq(struct work_struct *work);
adam radford229fe472014-03-10 02:51:56 -0700208static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
209 int initial);
Shivasharan Se5d65b42017-10-19 02:48:59 -0700210static int
Shivasharan S107a60d2017-10-19 02:49:05 -0700211megasas_set_dma_mask(struct megasas_instance *instance);
Shivasharan Se5d65b42017-10-19 02:48:59 -0700212static int
213megasas_alloc_ctrl_mem(struct megasas_instance *instance);
214static inline void
215megasas_free_ctrl_mem(struct megasas_instance *instance);
216static inline int
217megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance);
218static inline void
219megasas_free_ctrl_dma_buffers(struct megasas_instance *instance);
220static inline void
221megasas_init_ctrl_params(struct megasas_instance *instance);
adam radfordcd50ba82010-12-21 10:23:23 -0800222
Shivasharan S107a60d2017-10-19 02:49:05 -0700223/**
224 * megasas_set_dma_settings - Populate DMA address, length and flags for DCMDs
225 * @instance: Adapter soft state
226 * @dcmd: DCMD frame inside MFI command
227 * @dma_addr: DMA address of buffer to be passed to FW
228 * @dma_len: Length of DMA buffer to be passed to FW
229 * @return: void
230 */
231void megasas_set_dma_settings(struct megasas_instance *instance,
232 struct megasas_dcmd_frame *dcmd,
233 dma_addr_t dma_addr, u32 dma_len)
234{
235 if (instance->consistent_mask_64bit) {
236 dcmd->sgl.sge64[0].phys_addr = cpu_to_le64(dma_addr);
237 dcmd->sgl.sge64[0].length = cpu_to_le32(dma_len);
238 dcmd->flags = cpu_to_le16(dcmd->flags | MFI_FRAME_SGL64);
239
240 } else {
241 dcmd->sgl.sge32[0].phys_addr =
242 cpu_to_le32(lower_32_bits(dma_addr));
243 dcmd->sgl.sge32[0].length = cpu_to_le32(dma_len);
244 dcmd->flags = cpu_to_le16(dcmd->flags);
245 }
246}
adam radfordcd50ba82010-12-21 10:23:23 -0800247
Shivasharan Sf4fc2092017-02-10 00:59:09 -0800248void
adam radfordcd50ba82010-12-21 10:23:23 -0800249megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
250{
251 instance->instancet->fire_cmd(instance,
252 cmd->frame_phys_addr, 0, instance->reg_set);
Shivasharan Sf4fc2092017-02-10 00:59:09 -0800253 return;
adam radfordcd50ba82010-12-21 10:23:23 -0800254}
bo yang7343eb62007-11-09 04:35:44 -0500255
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400256/**
257 * megasas_get_cmd - Get a command from the free pool
258 * @instance: Adapter soft state
259 *
260 * Returns a free command from the pool
261 */
adam radford9c915a82010-12-21 13:34:31 -0800262struct megasas_cmd *megasas_get_cmd(struct megasas_instance
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400263 *instance)
264{
265 unsigned long flags;
266 struct megasas_cmd *cmd = NULL;
267
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +0530268 spin_lock_irqsave(&instance->mfi_pool_lock, flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400269
270 if (!list_empty(&instance->cmd_pool)) {
271 cmd = list_entry((&instance->cmd_pool)->next,
272 struct megasas_cmd, list);
273 list_del_init(&cmd->list);
274 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500275 dev_err(&instance->pdev->dev, "Command pool empty!\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400276 }
277
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +0530278 spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400279 return cmd;
280}
281
282/**
283 * megasas_return_cmd - Return a cmd to free command pool
284 * @instance: Adapter soft state
285 * @cmd: Command packet to be returned to free command pool
286 */
Andi Kleen68b43742017-05-08 15:58:53 -0700287void
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400288megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
289{
290 unsigned long flags;
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +0530291 u32 blk_tags;
292 struct megasas_cmd_fusion *cmd_fusion;
293 struct fusion_context *fusion = instance->ctrl_context;
294
295 /* This flag is used only for fusion adapter.
296 * Wait for Interrupt for Polled mode DCMD
297 */
298 if (cmd->flags & DRV_DCMD_POLLED_MODE)
299 return;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400300
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +0530301 spin_lock_irqsave(&instance->mfi_pool_lock, flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400302
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +0530303 if (fusion) {
304 blk_tags = instance->max_scsi_cmds + cmd->index;
305 cmd_fusion = fusion->cmd_list[blk_tags];
306 megasas_return_cmd_fusion(instance, cmd_fusion);
307 }
308 cmd->scmd = NULL;
309 cmd->frame_count = 0;
310 cmd->flags = 0;
Shivasharan S21c34002017-02-10 00:59:28 -0800311 memset(cmd->frame, 0, instance->mfi_frame_size);
312 cmd->frame->io.context = cpu_to_le32(cmd->index);
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +0530313 if (!fusion && reset_devices)
314 cmd->frame->hdr.cmd = MFI_CMD_INVALID;
315 list_add(&cmd->list, (&instance->cmd_pool)->next);
316
317 spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
318
319}
Sumant Patro1341c932006-01-25 12:02:40 -0800320
sumit.saxena@avagotech.com714f5172015-08-31 17:23:51 +0530321static const char *
322format_timestamp(uint32_t timestamp)
323{
324 static char buffer[32];
325
326 if ((timestamp & 0xff000000) == 0xff000000)
327 snprintf(buffer, sizeof(buffer), "boot + %us", timestamp &
328 0x00ffffff);
329 else
330 snprintf(buffer, sizeof(buffer), "%us", timestamp);
331 return buffer;
332}
333
334static const char *
335format_class(int8_t class)
336{
337 static char buffer[6];
338
339 switch (class) {
340 case MFI_EVT_CLASS_DEBUG:
341 return "debug";
342 case MFI_EVT_CLASS_PROGRESS:
343 return "progress";
344 case MFI_EVT_CLASS_INFO:
345 return "info";
346 case MFI_EVT_CLASS_WARNING:
347 return "WARN";
348 case MFI_EVT_CLASS_CRITICAL:
349 return "CRIT";
350 case MFI_EVT_CLASS_FATAL:
351 return "FATAL";
352 case MFI_EVT_CLASS_DEAD:
353 return "DEAD";
354 default:
355 snprintf(buffer, sizeof(buffer), "%d", class);
356 return buffer;
357 }
358}
359
360/**
361 * megasas_decode_evt: Decode FW AEN event and print critical event
362 * for information.
363 * @instance: Adapter soft state
364 */
365static void
366megasas_decode_evt(struct megasas_instance *instance)
367{
368 struct megasas_evt_detail *evt_detail = instance->evt_detail;
369 union megasas_evt_class_locale class_locale;
370 class_locale.word = le32_to_cpu(evt_detail->cl.word);
371
372 if (class_locale.members.class >= MFI_EVT_CLASS_CRITICAL)
373 dev_info(&instance->pdev->dev, "%d (%s/0x%04x/%s) - %s\n",
374 le32_to_cpu(evt_detail->seq_num),
375 format_timestamp(le32_to_cpu(evt_detail->time_stamp)),
376 (class_locale.members.locale),
377 format_class(class_locale.members.class),
378 evt_detail->description);
379}
380
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400381/**
adam radford0d490162010-12-14 19:17:17 -0800382* The following functions are defined for xscale
Sumant Patro1341c932006-01-25 12:02:40 -0800383* (deviceid : 1064R, PERC5) controllers
384*/
385
386/**
387 * megasas_enable_intr_xscale - Enables interrupts
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400388 * @regs: MFI register set
389 */
390static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530391megasas_enable_intr_xscale(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400392{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530393 struct megasas_register_set __iomem *regs;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500394
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530395 regs = instance->reg_set;
bo yang39a98552010-09-22 22:36:29 -0400396 writel(0, &(regs)->outbound_intr_mask);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400397
398 /* Dummy readl to force pci flush */
399 readl(&regs->outbound_intr_mask);
400}
401
402/**
Sumant Patrob274cab2006-10-03 12:52:12 -0700403 * megasas_disable_intr_xscale -Disables interrupt
404 * @regs: MFI register set
405 */
406static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530407megasas_disable_intr_xscale(struct megasas_instance *instance)
Sumant Patrob274cab2006-10-03 12:52:12 -0700408{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530409 struct megasas_register_set __iomem *regs;
Sumant Patrob274cab2006-10-03 12:52:12 -0700410 u32 mask = 0x1f;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500411
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530412 regs = instance->reg_set;
Sumant Patrob274cab2006-10-03 12:52:12 -0700413 writel(mask, &regs->outbound_intr_mask);
414 /* Dummy readl to force pci flush */
415 readl(&regs->outbound_intr_mask);
416}
417
418/**
Sumant Patro1341c932006-01-25 12:02:40 -0800419 * megasas_read_fw_status_reg_xscale - returns the current FW status value
420 * @regs: MFI register set
421 */
422static u32
423megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs)
424{
425 return readl(&(regs)->outbound_msg_0);
426}
427/**
428 * megasas_clear_interrupt_xscale - Check & clear interrupt
429 * @regs: MFI register set
430 */
adam radford0d490162010-12-14 19:17:17 -0800431static int
Sumant Patro1341c932006-01-25 12:02:40 -0800432megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
433{
434 u32 status;
bo yang39a98552010-09-22 22:36:29 -0400435 u32 mfiStatus = 0;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500436
Sumant Patro1341c932006-01-25 12:02:40 -0800437 /*
438 * Check if it is our interrupt
439 */
440 status = readl(&regs->outbound_intr_status);
441
bo yang39a98552010-09-22 22:36:29 -0400442 if (status & MFI_OB_INTR_STATUS_MASK)
443 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
444 if (status & MFI_XSCALE_OMR0_CHANGE_INTERRUPT)
445 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
Sumant Patro1341c932006-01-25 12:02:40 -0800446
447 /*
448 * Clear the interrupt by writing back the same value
449 */
bo yang39a98552010-09-22 22:36:29 -0400450 if (mfiStatus)
451 writel(status, &regs->outbound_intr_status);
Sumant Patro1341c932006-01-25 12:02:40 -0800452
Yang, Bo06f579d2008-08-10 12:42:37 -0700453 /* Dummy readl to force pci flush */
454 readl(&regs->outbound_intr_status);
455
bo yang39a98552010-09-22 22:36:29 -0400456 return mfiStatus;
Sumant Patro1341c932006-01-25 12:02:40 -0800457}
458
459/**
460 * megasas_fire_cmd_xscale - Sends command to the FW
461 * @frame_phys_addr : Physical address of cmd
462 * @frame_count : Number of frames for the command
463 * @regs : MFI register set
464 */
adam radford0d490162010-12-14 19:17:17 -0800465static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600466megasas_fire_cmd_xscale(struct megasas_instance *instance,
467 dma_addr_t frame_phys_addr,
468 u32 frame_count,
469 struct megasas_register_set __iomem *regs)
Sumant Patro1341c932006-01-25 12:02:40 -0800470{
bo yang39a98552010-09-22 22:36:29 -0400471 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500472
bo yang39a98552010-09-22 22:36:29 -0400473 spin_lock_irqsave(&instance->hba_lock, flags);
Sumant Patro1341c932006-01-25 12:02:40 -0800474 writel((frame_phys_addr >> 3)|(frame_count),
475 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400476 spin_unlock_irqrestore(&instance->hba_lock, flags);
477}
478
479/**
480 * megasas_adp_reset_xscale - For controller reset
481 * @regs: MFI register set
482 */
483static int
484megasas_adp_reset_xscale(struct megasas_instance *instance,
485 struct megasas_register_set __iomem *regs)
486{
487 u32 i;
488 u32 pcidata;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500489
bo yang39a98552010-09-22 22:36:29 -0400490 writel(MFI_ADP_RESET, &regs->inbound_doorbell);
491
492 for (i = 0; i < 3; i++)
493 msleep(1000); /* sleep for 3 secs */
494 pcidata = 0;
495 pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata);
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500496 dev_notice(&instance->pdev->dev, "pcidata = %x\n", pcidata);
bo yang39a98552010-09-22 22:36:29 -0400497 if (pcidata & 0x2) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500498 dev_notice(&instance->pdev->dev, "mfi 1068 offset read=%x\n", pcidata);
bo yang39a98552010-09-22 22:36:29 -0400499 pcidata &= ~0x2;
500 pci_write_config_dword(instance->pdev,
501 MFI_1068_PCSR_OFFSET, pcidata);
502
503 for (i = 0; i < 2; i++)
504 msleep(1000); /* need to wait 2 secs again */
505
506 pcidata = 0;
507 pci_read_config_dword(instance->pdev,
508 MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata);
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500509 dev_notice(&instance->pdev->dev, "1068 offset handshake read=%x\n", pcidata);
bo yang39a98552010-09-22 22:36:29 -0400510 if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500511 dev_notice(&instance->pdev->dev, "1068 offset pcidt=%x\n", pcidata);
bo yang39a98552010-09-22 22:36:29 -0400512 pcidata = 0;
513 pci_write_config_dword(instance->pdev,
514 MFI_1068_FW_HANDSHAKE_OFFSET, pcidata);
515 }
516 }
517 return 0;
518}
519
520/**
521 * megasas_check_reset_xscale - For controller reset check
522 * @regs: MFI register set
523 */
524static int
525megasas_check_reset_xscale(struct megasas_instance *instance,
526 struct megasas_register_set __iomem *regs)
527{
Sumit Saxena8a01a412016-01-28 21:04:32 +0530528 if ((atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) &&
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +0530529 (le32_to_cpu(*instance->consumer) ==
530 MEGASAS_ADPRESET_INPROG_SIGN))
bo yang39a98552010-09-22 22:36:29 -0400531 return 1;
bo yang39a98552010-09-22 22:36:29 -0400532 return 0;
Sumant Patro1341c932006-01-25 12:02:40 -0800533}
534
535static struct megasas_instance_template megasas_instance_template_xscale = {
536
537 .fire_cmd = megasas_fire_cmd_xscale,
538 .enable_intr = megasas_enable_intr_xscale,
Sumant Patrob274cab2006-10-03 12:52:12 -0700539 .disable_intr = megasas_disable_intr_xscale,
Sumant Patro1341c932006-01-25 12:02:40 -0800540 .clear_intr = megasas_clear_intr_xscale,
541 .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
bo yang39a98552010-09-22 22:36:29 -0400542 .adp_reset = megasas_adp_reset_xscale,
543 .check_reset = megasas_check_reset_xscale,
adam radfordcd50ba82010-12-21 10:23:23 -0800544 .service_isr = megasas_isr,
545 .tasklet = megasas_complete_cmd_dpc,
546 .init_adapter = megasas_init_adapter_mfi,
547 .build_and_issue_cmd = megasas_build_and_issue_cmd,
548 .issue_dcmd = megasas_issue_dcmd,
Sumant Patro1341c932006-01-25 12:02:40 -0800549};
550
551/**
adam radford0d490162010-12-14 19:17:17 -0800552* This is the end of set of functions & definitions specific
Sumant Patro1341c932006-01-25 12:02:40 -0800553* to xscale (deviceid : 1064R, PERC5) controllers
554*/
555
556/**
adam radford0d490162010-12-14 19:17:17 -0800557* The following functions are defined for ppc (deviceid : 0x60)
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500558* controllers
Sumant Patrof9876f02006-02-03 15:34:35 -0800559*/
560
561/**
562 * megasas_enable_intr_ppc - Enables interrupts
563 * @regs: MFI register set
564 */
565static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530566megasas_enable_intr_ppc(struct megasas_instance *instance)
Sumant Patrof9876f02006-02-03 15:34:35 -0800567{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530568 struct megasas_register_set __iomem *regs;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500569
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530570 regs = instance->reg_set;
Sumant Patrof9876f02006-02-03 15:34:35 -0800571 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
adam radford0d490162010-12-14 19:17:17 -0800572
bo yang39a98552010-09-22 22:36:29 -0400573 writel(~0x80000000, &(regs)->outbound_intr_mask);
Sumant Patrof9876f02006-02-03 15:34:35 -0800574
575 /* Dummy readl to force pci flush */
576 readl(&regs->outbound_intr_mask);
577}
578
579/**
Sumant Patrob274cab2006-10-03 12:52:12 -0700580 * megasas_disable_intr_ppc - Disable interrupt
581 * @regs: MFI register set
582 */
583static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530584megasas_disable_intr_ppc(struct megasas_instance *instance)
Sumant Patrob274cab2006-10-03 12:52:12 -0700585{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530586 struct megasas_register_set __iomem *regs;
Sumant Patrob274cab2006-10-03 12:52:12 -0700587 u32 mask = 0xFFFFFFFF;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500588
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530589 regs = instance->reg_set;
Sumant Patrob274cab2006-10-03 12:52:12 -0700590 writel(mask, &regs->outbound_intr_mask);
591 /* Dummy readl to force pci flush */
592 readl(&regs->outbound_intr_mask);
593}
594
595/**
Sumant Patrof9876f02006-02-03 15:34:35 -0800596 * megasas_read_fw_status_reg_ppc - returns the current FW status value
597 * @regs: MFI register set
598 */
599static u32
600megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)
601{
Shivasharan S81b76452018-10-16 23:37:51 -0700602 return readl(&(regs)->outbound_scratch_pad_0);
Sumant Patrof9876f02006-02-03 15:34:35 -0800603}
604
605/**
606 * megasas_clear_interrupt_ppc - Check & clear interrupt
607 * @regs: MFI register set
608 */
adam radford0d490162010-12-14 19:17:17 -0800609static int
Sumant Patrof9876f02006-02-03 15:34:35 -0800610megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
611{
adam radford3cc6851f92011-05-11 18:34:52 -0700612 u32 status, mfiStatus = 0;
613
Sumant Patrof9876f02006-02-03 15:34:35 -0800614 /*
615 * Check if it is our interrupt
616 */
617 status = readl(&regs->outbound_intr_status);
618
adam radford3cc6851f92011-05-11 18:34:52 -0700619 if (status & MFI_REPLY_1078_MESSAGE_INTERRUPT)
620 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
621
622 if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT)
623 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
Sumant Patrof9876f02006-02-03 15:34:35 -0800624
625 /*
626 * Clear the interrupt by writing back the same value
627 */
628 writel(status, &regs->outbound_doorbell_clear);
629
Yang, Bo06f579d2008-08-10 12:42:37 -0700630 /* Dummy readl to force pci flush */
631 readl(&regs->outbound_doorbell_clear);
632
adam radford3cc6851f92011-05-11 18:34:52 -0700633 return mfiStatus;
Sumant Patrof9876f02006-02-03 15:34:35 -0800634}
adam radford3cc6851f92011-05-11 18:34:52 -0700635
Sumant Patrof9876f02006-02-03 15:34:35 -0800636/**
637 * megasas_fire_cmd_ppc - Sends command to the FW
638 * @frame_phys_addr : Physical address of cmd
639 * @frame_count : Number of frames for the command
640 * @regs : MFI register set
641 */
adam radford0d490162010-12-14 19:17:17 -0800642static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600643megasas_fire_cmd_ppc(struct megasas_instance *instance,
644 dma_addr_t frame_phys_addr,
645 u32 frame_count,
646 struct megasas_register_set __iomem *regs)
Sumant Patrof9876f02006-02-03 15:34:35 -0800647{
bo yang39a98552010-09-22 22:36:29 -0400648 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500649
bo yang39a98552010-09-22 22:36:29 -0400650 spin_lock_irqsave(&instance->hba_lock, flags);
adam radford0d490162010-12-14 19:17:17 -0800651 writel((frame_phys_addr | (frame_count<<1))|1,
Sumant Patrof9876f02006-02-03 15:34:35 -0800652 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400653 spin_unlock_irqrestore(&instance->hba_lock, flags);
Sumant Patrof9876f02006-02-03 15:34:35 -0800654}
655
bo yang39a98552010-09-22 22:36:29 -0400656/**
bo yang39a98552010-09-22 22:36:29 -0400657 * megasas_check_reset_ppc - For controller reset check
658 * @regs: MFI register set
659 */
660static int
661megasas_check_reset_ppc(struct megasas_instance *instance,
662 struct megasas_register_set __iomem *regs)
663{
Sumit Saxena8a01a412016-01-28 21:04:32 +0530664 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
adam radford3cc6851f92011-05-11 18:34:52 -0700665 return 1;
666
bo yang39a98552010-09-22 22:36:29 -0400667 return 0;
668}
adam radford3cc6851f92011-05-11 18:34:52 -0700669
Sumant Patrof9876f02006-02-03 15:34:35 -0800670static struct megasas_instance_template megasas_instance_template_ppc = {
adam radford0d490162010-12-14 19:17:17 -0800671
Sumant Patrof9876f02006-02-03 15:34:35 -0800672 .fire_cmd = megasas_fire_cmd_ppc,
673 .enable_intr = megasas_enable_intr_ppc,
Sumant Patrob274cab2006-10-03 12:52:12 -0700674 .disable_intr = megasas_disable_intr_ppc,
Sumant Patrof9876f02006-02-03 15:34:35 -0800675 .clear_intr = megasas_clear_intr_ppc,
676 .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
adam radford3cc6851f92011-05-11 18:34:52 -0700677 .adp_reset = megasas_adp_reset_xscale,
bo yang39a98552010-09-22 22:36:29 -0400678 .check_reset = megasas_check_reset_ppc,
adam radfordcd50ba82010-12-21 10:23:23 -0800679 .service_isr = megasas_isr,
680 .tasklet = megasas_complete_cmd_dpc,
681 .init_adapter = megasas_init_adapter_mfi,
682 .build_and_issue_cmd = megasas_build_and_issue_cmd,
683 .issue_dcmd = megasas_issue_dcmd,
Sumant Patrof9876f02006-02-03 15:34:35 -0800684};
685
686/**
Yang, Bo87911122009-10-06 14:31:54 -0600687 * megasas_enable_intr_skinny - Enables interrupts
688 * @regs: MFI register set
689 */
690static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530691megasas_enable_intr_skinny(struct megasas_instance *instance)
Yang, Bo87911122009-10-06 14:31:54 -0600692{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530693 struct megasas_register_set __iomem *regs;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500694
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530695 regs = instance->reg_set;
Yang, Bo87911122009-10-06 14:31:54 -0600696 writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
697
698 writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
699
700 /* Dummy readl to force pci flush */
701 readl(&regs->outbound_intr_mask);
702}
703
704/**
705 * megasas_disable_intr_skinny - Disables interrupt
706 * @regs: MFI register set
707 */
708static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530709megasas_disable_intr_skinny(struct megasas_instance *instance)
Yang, Bo87911122009-10-06 14:31:54 -0600710{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530711 struct megasas_register_set __iomem *regs;
Yang, Bo87911122009-10-06 14:31:54 -0600712 u32 mask = 0xFFFFFFFF;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500713
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530714 regs = instance->reg_set;
Yang, Bo87911122009-10-06 14:31:54 -0600715 writel(mask, &regs->outbound_intr_mask);
716 /* Dummy readl to force pci flush */
717 readl(&regs->outbound_intr_mask);
718}
719
720/**
721 * megasas_read_fw_status_reg_skinny - returns the current FW status value
722 * @regs: MFI register set
723 */
724static u32
725megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
726{
Shivasharan S81b76452018-10-16 23:37:51 -0700727 return readl(&(regs)->outbound_scratch_pad_0);
Yang, Bo87911122009-10-06 14:31:54 -0600728}
729
730/**
731 * megasas_clear_interrupt_skinny - Check & clear interrupt
732 * @regs: MFI register set
733 */
734static int
735megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
736{
737 u32 status;
adam radfordebf054b2011-02-24 20:57:15 -0800738 u32 mfiStatus = 0;
739
Yang, Bo87911122009-10-06 14:31:54 -0600740 /*
741 * Check if it is our interrupt
742 */
743 status = readl(&regs->outbound_intr_status);
744
745 if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
bo yang39a98552010-09-22 22:36:29 -0400746 return 0;
Yang, Bo87911122009-10-06 14:31:54 -0600747 }
748
749 /*
adam radfordebf054b2011-02-24 20:57:15 -0800750 * Check if it is our interrupt
751 */
James Georgasa3fda7d2013-06-26 12:03:19 -0600752 if ((megasas_read_fw_status_reg_skinny(regs) & MFI_STATE_MASK) ==
adam radfordebf054b2011-02-24 20:57:15 -0800753 MFI_STATE_FAULT) {
754 mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
755 } else
756 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
757
758 /*
Yang, Bo87911122009-10-06 14:31:54 -0600759 * Clear the interrupt by writing back the same value
760 */
761 writel(status, &regs->outbound_intr_status);
762
763 /*
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500764 * dummy read to flush PCI
765 */
Yang, Bo87911122009-10-06 14:31:54 -0600766 readl(&regs->outbound_intr_status);
767
adam radfordebf054b2011-02-24 20:57:15 -0800768 return mfiStatus;
Yang, Bo87911122009-10-06 14:31:54 -0600769}
770
771/**
772 * megasas_fire_cmd_skinny - Sends command to the FW
773 * @frame_phys_addr : Physical address of cmd
774 * @frame_count : Number of frames for the command
775 * @regs : MFI register set
776 */
777static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600778megasas_fire_cmd_skinny(struct megasas_instance *instance,
779 dma_addr_t frame_phys_addr,
780 u32 frame_count,
Yang, Bo87911122009-10-06 14:31:54 -0600781 struct megasas_register_set __iomem *regs)
782{
Yang, Bo0c79e682009-10-06 14:47:35 -0600783 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500784
bo yang39a98552010-09-22 22:36:29 -0400785 spin_lock_irqsave(&instance->hba_lock, flags);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +0530786 writel(upper_32_bits(frame_phys_addr),
787 &(regs)->inbound_high_queue_port);
788 writel((lower_32_bits(frame_phys_addr) | (frame_count<<1))|1,
789 &(regs)->inbound_low_queue_port);
Tomas Henzlb99dbe52016-02-01 15:12:04 +0100790 mmiowb();
bo yang39a98552010-09-22 22:36:29 -0400791 spin_unlock_irqrestore(&instance->hba_lock, flags);
792}
793
794/**
bo yang39a98552010-09-22 22:36:29 -0400795 * megasas_check_reset_skinny - For controller reset check
796 * @regs: MFI register set
797 */
798static int
799megasas_check_reset_skinny(struct megasas_instance *instance,
800 struct megasas_register_set __iomem *regs)
801{
Sumit Saxena8a01a412016-01-28 21:04:32 +0530802 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
adam radford3cc6851f92011-05-11 18:34:52 -0700803 return 1;
804
bo yang39a98552010-09-22 22:36:29 -0400805 return 0;
Yang, Bo87911122009-10-06 14:31:54 -0600806}
807
808static struct megasas_instance_template megasas_instance_template_skinny = {
809
810 .fire_cmd = megasas_fire_cmd_skinny,
811 .enable_intr = megasas_enable_intr_skinny,
812 .disable_intr = megasas_disable_intr_skinny,
813 .clear_intr = megasas_clear_intr_skinny,
814 .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
adam radfordebf054b2011-02-24 20:57:15 -0800815 .adp_reset = megasas_adp_reset_gen2,
bo yang39a98552010-09-22 22:36:29 -0400816 .check_reset = megasas_check_reset_skinny,
adam radfordcd50ba82010-12-21 10:23:23 -0800817 .service_isr = megasas_isr,
818 .tasklet = megasas_complete_cmd_dpc,
819 .init_adapter = megasas_init_adapter_mfi,
820 .build_and_issue_cmd = megasas_build_and_issue_cmd,
821 .issue_dcmd = megasas_issue_dcmd,
Yang, Bo87911122009-10-06 14:31:54 -0600822};
823
824
825/**
Yang, Bo6610a6b2008-08-10 12:42:38 -0700826* The following functions are defined for gen2 (deviceid : 0x78 0x79)
827* controllers
828*/
829
830/**
831 * megasas_enable_intr_gen2 - Enables interrupts
832 * @regs: MFI register set
833 */
834static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530835megasas_enable_intr_gen2(struct megasas_instance *instance)
Yang, Bo6610a6b2008-08-10 12:42:38 -0700836{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530837 struct megasas_register_set __iomem *regs;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500838
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530839 regs = instance->reg_set;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700840 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
841
842 /* write ~0x00000005 (4 & 1) to the intr mask*/
843 writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
844
845 /* Dummy readl to force pci flush */
846 readl(&regs->outbound_intr_mask);
847}
848
849/**
850 * megasas_disable_intr_gen2 - Disables interrupt
851 * @regs: MFI register set
852 */
853static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530854megasas_disable_intr_gen2(struct megasas_instance *instance)
Yang, Bo6610a6b2008-08-10 12:42:38 -0700855{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530856 struct megasas_register_set __iomem *regs;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700857 u32 mask = 0xFFFFFFFF;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500858
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530859 regs = instance->reg_set;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700860 writel(mask, &regs->outbound_intr_mask);
861 /* Dummy readl to force pci flush */
862 readl(&regs->outbound_intr_mask);
863}
864
865/**
866 * megasas_read_fw_status_reg_gen2 - returns the current FW status value
867 * @regs: MFI register set
868 */
869static u32
870megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs)
871{
Shivasharan S81b76452018-10-16 23:37:51 -0700872 return readl(&(regs)->outbound_scratch_pad_0);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700873}
874
875/**
876 * megasas_clear_interrupt_gen2 - Check & clear interrupt
877 * @regs: MFI register set
878 */
879static int
880megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
881{
882 u32 status;
bo yang39a98552010-09-22 22:36:29 -0400883 u32 mfiStatus = 0;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500884
Yang, Bo6610a6b2008-08-10 12:42:38 -0700885 /*
886 * Check if it is our interrupt
887 */
888 status = readl(&regs->outbound_intr_status);
889
Sumit.Saxena@lsi.comb5bccad2013-05-22 12:29:54 +0530890 if (status & MFI_INTR_FLAG_REPLY_MESSAGE) {
bo yang39a98552010-09-22 22:36:29 -0400891 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
892 }
893 if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) {
894 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
895 }
Yang, Bo6610a6b2008-08-10 12:42:38 -0700896
897 /*
898 * Clear the interrupt by writing back the same value
899 */
bo yang39a98552010-09-22 22:36:29 -0400900 if (mfiStatus)
901 writel(status, &regs->outbound_doorbell_clear);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700902
903 /* Dummy readl to force pci flush */
904 readl(&regs->outbound_intr_status);
905
bo yang39a98552010-09-22 22:36:29 -0400906 return mfiStatus;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700907}
908/**
909 * megasas_fire_cmd_gen2 - Sends command to the FW
910 * @frame_phys_addr : Physical address of cmd
911 * @frame_count : Number of frames for the command
912 * @regs : MFI register set
913 */
914static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600915megasas_fire_cmd_gen2(struct megasas_instance *instance,
916 dma_addr_t frame_phys_addr,
917 u32 frame_count,
Yang, Bo6610a6b2008-08-10 12:42:38 -0700918 struct megasas_register_set __iomem *regs)
919{
bo yang39a98552010-09-22 22:36:29 -0400920 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500921
bo yang39a98552010-09-22 22:36:29 -0400922 spin_lock_irqsave(&instance->hba_lock, flags);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700923 writel((frame_phys_addr | (frame_count<<1))|1,
924 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400925 spin_unlock_irqrestore(&instance->hba_lock, flags);
926}
927
928/**
929 * megasas_adp_reset_gen2 - For controller reset
930 * @regs: MFI register set
931 */
932static int
933megasas_adp_reset_gen2(struct megasas_instance *instance,
934 struct megasas_register_set __iomem *reg_set)
935{
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500936 u32 retry = 0 ;
937 u32 HostDiag;
938 u32 __iomem *seq_offset = &reg_set->seq_offset;
939 u32 __iomem *hostdiag_offset = &reg_set->host_diag;
bo yang39a98552010-09-22 22:36:29 -0400940
adam radfordebf054b2011-02-24 20:57:15 -0800941 if (instance->instancet == &megasas_instance_template_skinny) {
942 seq_offset = &reg_set->fusion_seq_offset;
943 hostdiag_offset = &reg_set->fusion_host_diag;
944 }
945
946 writel(0, seq_offset);
947 writel(4, seq_offset);
948 writel(0xb, seq_offset);
949 writel(2, seq_offset);
950 writel(7, seq_offset);
951 writel(0xd, seq_offset);
952
bo yang39a98552010-09-22 22:36:29 -0400953 msleep(1000);
954
adam radfordebf054b2011-02-24 20:57:15 -0800955 HostDiag = (u32)readl(hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400956
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500957 while (!(HostDiag & DIAG_WRITE_ENABLE)) {
bo yang39a98552010-09-22 22:36:29 -0400958 msleep(100);
adam radfordebf054b2011-02-24 20:57:15 -0800959 HostDiag = (u32)readl(hostdiag_offset);
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500960 dev_notice(&instance->pdev->dev, "RESETGEN2: retry=%x, hostdiag=%x\n",
bo yang39a98552010-09-22 22:36:29 -0400961 retry, HostDiag);
962
963 if (retry++ >= 100)
964 return 1;
965
966 }
967
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500968 dev_notice(&instance->pdev->dev, "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag);
bo yang39a98552010-09-22 22:36:29 -0400969
adam radfordebf054b2011-02-24 20:57:15 -0800970 writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400971
972 ssleep(10);
973
adam radfordebf054b2011-02-24 20:57:15 -0800974 HostDiag = (u32)readl(hostdiag_offset);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -0500975 while (HostDiag & DIAG_RESET_ADAPTER) {
bo yang39a98552010-09-22 22:36:29 -0400976 msleep(100);
adam radfordebf054b2011-02-24 20:57:15 -0800977 HostDiag = (u32)readl(hostdiag_offset);
Bjorn Helgaas1be18252015-07-07 15:52:34 -0500978 dev_notice(&instance->pdev->dev, "RESET_GEN2: retry=%x, hostdiag=%x\n",
bo yang39a98552010-09-22 22:36:29 -0400979 retry, HostDiag);
980
981 if (retry++ >= 1000)
982 return 1;
983
984 }
985 return 0;
986}
987
988/**
989 * megasas_check_reset_gen2 - For controller reset check
990 * @regs: MFI register set
991 */
992static int
993megasas_check_reset_gen2(struct megasas_instance *instance,
994 struct megasas_register_set __iomem *regs)
995{
Sumit Saxena8a01a412016-01-28 21:04:32 +0530996 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
Yang, Bo707e09b2010-10-12 07:20:27 -0600997 return 1;
Yang, Bo707e09b2010-10-12 07:20:27 -0600998
bo yang39a98552010-09-22 22:36:29 -0400999 return 0;
Yang, Bo6610a6b2008-08-10 12:42:38 -07001000}
1001
1002static struct megasas_instance_template megasas_instance_template_gen2 = {
1003
1004 .fire_cmd = megasas_fire_cmd_gen2,
1005 .enable_intr = megasas_enable_intr_gen2,
1006 .disable_intr = megasas_disable_intr_gen2,
1007 .clear_intr = megasas_clear_intr_gen2,
1008 .read_fw_status_reg = megasas_read_fw_status_reg_gen2,
bo yang39a98552010-09-22 22:36:29 -04001009 .adp_reset = megasas_adp_reset_gen2,
1010 .check_reset = megasas_check_reset_gen2,
adam radfordcd50ba82010-12-21 10:23:23 -08001011 .service_isr = megasas_isr,
1012 .tasklet = megasas_complete_cmd_dpc,
1013 .init_adapter = megasas_init_adapter_mfi,
1014 .build_and_issue_cmd = megasas_build_and_issue_cmd,
1015 .issue_dcmd = megasas_issue_dcmd,
Yang, Bo6610a6b2008-08-10 12:42:38 -07001016};
1017
1018/**
Sumant Patrof9876f02006-02-03 15:34:35 -08001019* This is the end of set of functions & definitions
bo yang39a98552010-09-22 22:36:29 -04001020* specific to gen2 (deviceid : 0x78, 0x79) controllers
Sumant Patrof9876f02006-02-03 15:34:35 -08001021*/
1022
adam radford9c915a82010-12-21 13:34:31 -08001023/*
1024 * Template added for TB (Fusion)
1025 */
1026extern struct megasas_instance_template megasas_instance_template_fusion;
1027
Sumant Patrof9876f02006-02-03 15:34:35 -08001028/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001029 * megasas_issue_polled - Issues a polling command
1030 * @instance: Adapter soft state
adam radford0d490162010-12-14 19:17:17 -08001031 * @cmd: Command packet to be issued
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001032 *
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301033 * For polling, MFI requires the cmd_status to be set to MFI_STAT_INVALID_STATUS before posting.
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001034 */
adam radford9c915a82010-12-21 13:34:31 -08001035int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001036megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
1037{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001038 struct megasas_header *frame_hdr = &cmd->frame->hdr;
1039
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301040 frame_hdr->cmd_status = MFI_STAT_INVALID_STATUS;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301041 frame_hdr->flags |= cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001042
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001043 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301044 dev_err(&instance->pdev->dev, "Failed from %s %d\n",
1045 __func__, __LINE__);
1046 return DCMD_NOT_FIRED;
1047 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001048
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001049 instance->instancet->issue_dcmd(instance, cmd);
1050
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301051 return wait_and_poll(instance, cmd, instance->requestorId ?
1052 MEGASAS_ROUTINE_WAIT_TIME_VF : MFI_IO_TIMEOUT_SECS);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001053}
1054
1055/**
1056 * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds
1057 * @instance: Adapter soft state
1058 * @cmd: Command to be issued
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301059 * @timeout: Timeout in seconds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001060 *
1061 * This function waits on an event for the command to be returned from ISR.
Sumant Patro2a3681e2006-10-03 13:19:21 -07001062 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001063 * Used to issue ioctl commands.
1064 */
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05301065int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001066megasas_issue_blocked_cmd(struct megasas_instance *instance,
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301067 struct megasas_cmd *cmd, int timeout)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001068{
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301069 int ret = 0;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301070 cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001071
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001072 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301073 dev_err(&instance->pdev->dev, "Failed from %s %d\n",
1074 __func__, __LINE__);
1075 return DCMD_NOT_FIRED;
1076 }
1077
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001078 instance->instancet->issue_dcmd(instance, cmd);
1079
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301080 if (timeout) {
1081 ret = wait_event_timeout(instance->int_cmd_wait_q,
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301082 cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301083 if (!ret) {
1084 dev_err(&instance->pdev->dev, "Failed from %s %d DCMD Timed out\n",
1085 __func__, __LINE__);
1086 return DCMD_TIMEOUT;
1087 }
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301088 } else
1089 wait_event(instance->int_cmd_wait_q,
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301090 cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001091
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301092 return (cmd->cmd_status_drv == MFI_STAT_OK) ?
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301093 DCMD_SUCCESS : DCMD_FAILED;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001094}
1095
1096/**
1097 * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd
1098 * @instance: Adapter soft state
1099 * @cmd_to_abort: Previously issued cmd to be aborted
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301100 * @timeout: Timeout in seconds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001101 *
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301102 * MFI firmware can abort previously issued AEN comamnd (automatic event
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001103 * notification). The megasas_issue_blocked_abort_cmd() issues such abort
Sumant Patro2a3681e2006-10-03 13:19:21 -07001104 * cmd and waits for return status.
1105 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001106 */
1107static int
1108megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301109 struct megasas_cmd *cmd_to_abort, int timeout)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001110{
1111 struct megasas_cmd *cmd;
1112 struct megasas_abort_frame *abort_fr;
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301113 int ret = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001114
1115 cmd = megasas_get_cmd(instance);
1116
1117 if (!cmd)
1118 return -1;
1119
1120 abort_fr = &cmd->frame->abort;
1121
1122 /*
1123 * Prepare and issue the abort frame
1124 */
1125 abort_fr->cmd = MFI_CMD_ABORT;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301126 abort_fr->cmd_status = MFI_STAT_INVALID_STATUS;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301127 abort_fr->flags = cpu_to_le16(0);
1128 abort_fr->abort_context = cpu_to_le32(cmd_to_abort->index);
1129 abort_fr->abort_mfi_phys_addr_lo =
1130 cpu_to_le32(lower_32_bits(cmd_to_abort->frame_phys_addr));
1131 abort_fr->abort_mfi_phys_addr_hi =
1132 cpu_to_le32(upper_32_bits(cmd_to_abort->frame_phys_addr));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001133
1134 cmd->sync_cmd = 1;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301135 cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001136
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001137 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301138 dev_err(&instance->pdev->dev, "Failed from %s %d\n",
1139 __func__, __LINE__);
1140 return DCMD_NOT_FIRED;
1141 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001142
Shivasharan Sf4fc2092017-02-10 00:59:09 -08001143 instance->instancet->issue_dcmd(instance, cmd);
1144
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301145 if (timeout) {
1146 ret = wait_event_timeout(instance->abort_cmd_wait_q,
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301147 cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ);
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301148 if (!ret) {
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301149 dev_err(&instance->pdev->dev, "Failed from %s %d Abort Timed out\n",
1150 __func__, __LINE__);
1151 return DCMD_TIMEOUT;
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301152 }
1153 } else
1154 wait_event(instance->abort_cmd_wait_q,
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05301155 cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS);
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05301156
bo yang39a98552010-09-22 22:36:29 -04001157 cmd->sync_cmd = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001158
1159 megasas_return_cmd(instance, cmd);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05301160 return (cmd->cmd_status_drv == MFI_STAT_OK) ?
1161 DCMD_SUCCESS : DCMD_FAILED;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001162}
1163
1164/**
1165 * megasas_make_sgl32 - Prepares 32-bit SGL
1166 * @instance: Adapter soft state
1167 * @scp: SCSI command from the mid-layer
1168 * @mfi_sgl: SGL to be filled in
1169 *
1170 * If successful, this function returns the number of SG elements. Otherwise,
1171 * it returnes -1.
1172 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001173static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001174megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp,
1175 union megasas_sgl *mfi_sgl)
1176{
1177 int i;
1178 int sge_count;
1179 struct scatterlist *os_sgl;
1180
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001181 sge_count = scsi_dma_map(scp);
1182 BUG_ON(sge_count < 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001183
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001184 if (sge_count) {
1185 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301186 mfi_sgl->sge32[i].length = cpu_to_le32(sg_dma_len(os_sgl));
1187 mfi_sgl->sge32[i].phys_addr = cpu_to_le32(sg_dma_address(os_sgl));
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001188 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001189 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001190 return sge_count;
1191}
1192
1193/**
1194 * megasas_make_sgl64 - Prepares 64-bit SGL
1195 * @instance: Adapter soft state
1196 * @scp: SCSI command from the mid-layer
1197 * @mfi_sgl: SGL to be filled in
1198 *
1199 * If successful, this function returns the number of SG elements. Otherwise,
1200 * it returnes -1.
1201 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001202static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001203megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
1204 union megasas_sgl *mfi_sgl)
1205{
1206 int i;
1207 int sge_count;
1208 struct scatterlist *os_sgl;
1209
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001210 sge_count = scsi_dma_map(scp);
1211 BUG_ON(sge_count < 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001212
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001213 if (sge_count) {
1214 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301215 mfi_sgl->sge64[i].length = cpu_to_le32(sg_dma_len(os_sgl));
1216 mfi_sgl->sge64[i].phys_addr = cpu_to_le64(sg_dma_address(os_sgl));
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001217 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001218 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001219 return sge_count;
1220}
1221
Yang, Bof4c9a132009-10-06 14:43:28 -06001222/**
1223 * megasas_make_sgl_skinny - Prepares IEEE 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 */
1231static int
1232megasas_make_sgl_skinny(struct megasas_instance *instance,
1233 struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
1234{
1235 int i;
1236 int sge_count;
1237 struct scatterlist *os_sgl;
1238
1239 sge_count = scsi_dma_map(scp);
1240
1241 if (sge_count) {
1242 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301243 mfi_sgl->sge_skinny[i].length =
1244 cpu_to_le32(sg_dma_len(os_sgl));
Yang, Bof4c9a132009-10-06 14:43:28 -06001245 mfi_sgl->sge_skinny[i].phys_addr =
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301246 cpu_to_le64(sg_dma_address(os_sgl));
1247 mfi_sgl->sge_skinny[i].flag = cpu_to_le32(0);
Yang, Bof4c9a132009-10-06 14:43:28 -06001248 }
1249 }
1250 return sge_count;
1251}
1252
Sumant Patrob1df99d2006-10-03 12:40:47 -07001253 /**
1254 * megasas_get_frame_count - Computes the number of frames
bo yangd532dbe2008-03-17 03:36:43 -04001255 * @frame_type : type of frame- io or pthru frame
Sumant Patrob1df99d2006-10-03 12:40:47 -07001256 * @sge_count : number of sg elements
1257 *
1258 * Returns the number of frames required for numnber of sge's (sge_count)
1259 */
1260
Yang, Bof4c9a132009-10-06 14:43:28 -06001261static u32 megasas_get_frame_count(struct megasas_instance *instance,
1262 u8 sge_count, u8 frame_type)
Sumant Patrob1df99d2006-10-03 12:40:47 -07001263{
1264 int num_cnt;
1265 int sge_bytes;
1266 u32 sge_sz;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001267 u32 frame_count = 0;
Sumant Patrob1df99d2006-10-03 12:40:47 -07001268
1269 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
1270 sizeof(struct megasas_sge32);
1271
Yang, Bof4c9a132009-10-06 14:43:28 -06001272 if (instance->flag_ieee) {
1273 sge_sz = sizeof(struct megasas_sge_skinny);
1274 }
1275
Sumant Patrob1df99d2006-10-03 12:40:47 -07001276 /*
bo yangd532dbe2008-03-17 03:36:43 -04001277 * Main frame can contain 2 SGEs for 64-bit SGLs and
1278 * 3 SGEs for 32-bit SGLs for ldio &
1279 * 1 SGEs for 64-bit SGLs and
1280 * 2 SGEs for 32-bit SGLs for pthru frame
1281 */
1282 if (unlikely(frame_type == PTHRU_FRAME)) {
Yang, Bof4c9a132009-10-06 14:43:28 -06001283 if (instance->flag_ieee == 1) {
1284 num_cnt = sge_count - 1;
1285 } else if (IS_DMA64)
bo yangd532dbe2008-03-17 03:36:43 -04001286 num_cnt = sge_count - 1;
1287 else
1288 num_cnt = sge_count - 2;
1289 } else {
Yang, Bof4c9a132009-10-06 14:43:28 -06001290 if (instance->flag_ieee == 1) {
1291 num_cnt = sge_count - 1;
1292 } else if (IS_DMA64)
bo yangd532dbe2008-03-17 03:36:43 -04001293 num_cnt = sge_count - 2;
1294 else
1295 num_cnt = sge_count - 3;
1296 }
Sumant Patrob1df99d2006-10-03 12:40:47 -07001297
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001298 if (num_cnt > 0) {
Sumant Patrob1df99d2006-10-03 12:40:47 -07001299 sge_bytes = sge_sz * num_cnt;
1300
1301 frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
1302 ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ;
1303 }
1304 /* Main frame */
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001305 frame_count += 1;
Sumant Patrob1df99d2006-10-03 12:40:47 -07001306
1307 if (frame_count > 7)
1308 frame_count = 8;
1309 return frame_count;
1310}
1311
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001312/**
1313 * megasas_build_dcdb - Prepares a direct cdb (DCDB) command
1314 * @instance: Adapter soft state
1315 * @scp: SCSI command
1316 * @cmd: Command to be prepared in
1317 *
1318 * This function prepares CDB commands. These are typcially pass-through
1319 * commands to the devices.
1320 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001321static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001322megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
1323 struct megasas_cmd *cmd)
1324{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001325 u32 is_logical;
1326 u32 device_id;
1327 u16 flags = 0;
1328 struct megasas_pthru_frame *pthru;
1329
Shivasharan S3cabd162017-02-10 00:59:05 -08001330 is_logical = MEGASAS_IS_LOGICAL(scp->device);
Sumit.Saxena@avagotech.com4a5c8142015-04-23 16:30:39 +05301331 device_id = MEGASAS_DEV_INDEX(scp);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001332 pthru = (struct megasas_pthru_frame *)cmd->frame;
1333
Christoph Hellwig60ee6522018-10-10 19:31:25 +02001334 if (scp->sc_data_direction == DMA_TO_DEVICE)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001335 flags = MFI_FRAME_DIR_WRITE;
Christoph Hellwig60ee6522018-10-10 19:31:25 +02001336 else if (scp->sc_data_direction == DMA_FROM_DEVICE)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001337 flags = MFI_FRAME_DIR_READ;
Christoph Hellwig60ee6522018-10-10 19:31:25 +02001338 else if (scp->sc_data_direction == DMA_NONE)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001339 flags = MFI_FRAME_DIR_NONE;
1340
Yang, Bof4c9a132009-10-06 14:43:28 -06001341 if (instance->flag_ieee == 1) {
1342 flags |= MFI_FRAME_IEEE;
1343 }
1344
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001345 /*
1346 * Prepare the DCDB frame
1347 */
1348 pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO;
1349 pthru->cmd_status = 0x0;
1350 pthru->scsi_status = 0x0;
1351 pthru->target_id = device_id;
1352 pthru->lun = scp->device->lun;
1353 pthru->cdb_len = scp->cmd_len;
1354 pthru->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07001355 pthru->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301356 pthru->flags = cpu_to_le16(flags);
1357 pthru->data_xfer_len = cpu_to_le32(scsi_bufflen(scp));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001358
1359 memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
1360
1361 /*
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001362 * If the command is for the tape device, set the
1363 * pthru timeout to the os layer timeout value.
1364 */
Yang, Bo8d568252009-10-06 14:12:21 -06001365 if (scp->device->type == TYPE_TAPE) {
1366 if ((scp->request->timeout / HZ) > 0xFFFF)
Christoph Hellwigc6f5bf82015-04-23 16:33:09 +05301367 pthru->timeout = cpu_to_le16(0xFFFF);
Yang, Bo8d568252009-10-06 14:12:21 -06001368 else
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301369 pthru->timeout = cpu_to_le16(scp->request->timeout / HZ);
Yang, Bo8d568252009-10-06 14:12:21 -06001370 }
1371
1372 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001373 * Construct SGL
1374 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001375 if (instance->flag_ieee == 1) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301376 pthru->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Yang, Bof4c9a132009-10-06 14:43:28 -06001377 pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
1378 &pthru->sgl);
1379 } else if (IS_DMA64) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301380 pthru->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001381 pthru->sge_count = megasas_make_sgl64(instance, scp,
1382 &pthru->sgl);
1383 } else
1384 pthru->sge_count = megasas_make_sgl32(instance, scp,
1385 &pthru->sgl);
1386
Yang, Bobdc6fb82009-12-06 08:30:19 -07001387 if (pthru->sge_count > instance->max_num_sge) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001388 dev_err(&instance->pdev->dev, "DCDB too many SGE NUM=%x\n",
Yang, Bobdc6fb82009-12-06 08:30:19 -07001389 pthru->sge_count);
1390 return 0;
1391 }
1392
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001393 /*
1394 * Sense info specific
1395 */
1396 pthru->sense_len = SCSI_SENSE_BUFFERSIZE;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301397 pthru->sense_buf_phys_addr_hi =
1398 cpu_to_le32(upper_32_bits(cmd->sense_phys_addr));
1399 pthru->sense_buf_phys_addr_lo =
1400 cpu_to_le32(lower_32_bits(cmd->sense_phys_addr));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001401
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001402 /*
1403 * Compute the total number of frames this command consumes. FW uses
1404 * this number to pull sufficient number of frames from host memory.
1405 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001406 cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
bo yangd532dbe2008-03-17 03:36:43 -04001407 PTHRU_FRAME);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001408
1409 return cmd->frame_count;
1410}
1411
1412/**
1413 * megasas_build_ldio - Prepares IOs to logical devices
1414 * @instance: Adapter soft state
1415 * @scp: SCSI command
Anand Gadiyarfd589a82009-07-16 17:13:03 +02001416 * @cmd: Command to be prepared
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001417 *
1418 * Frames (and accompanying SGLs) for regular SCSI IOs use this function.
1419 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001420static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001421megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
1422 struct megasas_cmd *cmd)
1423{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001424 u32 device_id;
1425 u8 sc = scp->cmnd[0];
1426 u16 flags = 0;
1427 struct megasas_io_frame *ldio;
1428
Sumit.Saxena@avagotech.com4a5c8142015-04-23 16:30:39 +05301429 device_id = MEGASAS_DEV_INDEX(scp);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001430 ldio = (struct megasas_io_frame *)cmd->frame;
1431
Christoph Hellwig60ee6522018-10-10 19:31:25 +02001432 if (scp->sc_data_direction == DMA_TO_DEVICE)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001433 flags = MFI_FRAME_DIR_WRITE;
Christoph Hellwig60ee6522018-10-10 19:31:25 +02001434 else if (scp->sc_data_direction == DMA_FROM_DEVICE)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001435 flags = MFI_FRAME_DIR_READ;
1436
Yang, Bof4c9a132009-10-06 14:43:28 -06001437 if (instance->flag_ieee == 1) {
1438 flags |= MFI_FRAME_IEEE;
1439 }
1440
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001441 /*
Sumant Patrob1df99d2006-10-03 12:40:47 -07001442 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001443 */
1444 ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ;
1445 ldio->cmd_status = 0x0;
1446 ldio->scsi_status = 0x0;
1447 ldio->target_id = device_id;
1448 ldio->timeout = 0;
1449 ldio->reserved_0 = 0;
1450 ldio->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301451 ldio->flags = cpu_to_le16(flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001452 ldio->start_lba_hi = 0;
1453 ldio->access_byte = (scp->cmd_len != 6) ? scp->cmnd[1] : 0;
1454
1455 /*
1456 * 6-byte READ(0x08) or WRITE(0x0A) cdb
1457 */
1458 if (scp->cmd_len == 6) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301459 ldio->lba_count = cpu_to_le32((u32) scp->cmnd[4]);
1460 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[1] << 16) |
1461 ((u32) scp->cmnd[2] << 8) |
1462 (u32) scp->cmnd[3]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001463
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301464 ldio->start_lba_lo &= cpu_to_le32(0x1FFFFF);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001465 }
1466
1467 /*
1468 * 10-byte READ(0x28) or WRITE(0x2A) cdb
1469 */
1470 else if (scp->cmd_len == 10) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301471 ldio->lba_count = cpu_to_le32((u32) scp->cmnd[8] |
1472 ((u32) scp->cmnd[7] << 8));
1473 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[2] << 24) |
1474 ((u32) scp->cmnd[3] << 16) |
1475 ((u32) scp->cmnd[4] << 8) |
1476 (u32) scp->cmnd[5]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001477 }
1478
1479 /*
1480 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
1481 */
1482 else if (scp->cmd_len == 12) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301483 ldio->lba_count = cpu_to_le32(((u32) scp->cmnd[6] << 24) |
1484 ((u32) scp->cmnd[7] << 16) |
1485 ((u32) scp->cmnd[8] << 8) |
1486 (u32) scp->cmnd[9]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001487
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301488 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[2] << 24) |
1489 ((u32) scp->cmnd[3] << 16) |
1490 ((u32) scp->cmnd[4] << 8) |
1491 (u32) scp->cmnd[5]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001492 }
1493
1494 /*
1495 * 16-byte READ(0x88) or WRITE(0x8A) cdb
1496 */
1497 else if (scp->cmd_len == 16) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301498 ldio->lba_count = cpu_to_le32(((u32) scp->cmnd[10] << 24) |
1499 ((u32) scp->cmnd[11] << 16) |
1500 ((u32) scp->cmnd[12] << 8) |
1501 (u32) scp->cmnd[13]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001502
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301503 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[6] << 24) |
1504 ((u32) scp->cmnd[7] << 16) |
1505 ((u32) scp->cmnd[8] << 8) |
1506 (u32) scp->cmnd[9]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001507
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301508 ldio->start_lba_hi = cpu_to_le32(((u32) scp->cmnd[2] << 24) |
1509 ((u32) scp->cmnd[3] << 16) |
1510 ((u32) scp->cmnd[4] << 8) |
1511 (u32) scp->cmnd[5]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001512
1513 }
1514
1515 /*
1516 * Construct SGL
1517 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001518 if (instance->flag_ieee) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301519 ldio->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Yang, Bof4c9a132009-10-06 14:43:28 -06001520 ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
1521 &ldio->sgl);
1522 } else if (IS_DMA64) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301523 ldio->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001524 ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
1525 } else
1526 ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
1527
Yang, Bobdc6fb82009-12-06 08:30:19 -07001528 if (ldio->sge_count > instance->max_num_sge) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001529 dev_err(&instance->pdev->dev, "build_ld_io: sge_count = %x\n",
Yang, Bobdc6fb82009-12-06 08:30:19 -07001530 ldio->sge_count);
1531 return 0;
1532 }
1533
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001534 /*
1535 * Sense info specific
1536 */
1537 ldio->sense_len = SCSI_SENSE_BUFFERSIZE;
1538 ldio->sense_buf_phys_addr_hi = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301539 ldio->sense_buf_phys_addr_lo = cpu_to_le32(cmd->sense_phys_addr);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001540
Sumant Patrob1df99d2006-10-03 12:40:47 -07001541 /*
1542 * Compute the total number of frames this command consumes. FW uses
1543 * this number to pull sufficient number of frames from host memory.
1544 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001545 cmd->frame_count = megasas_get_frame_count(instance,
1546 ldio->sge_count, IO_FRAME);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001547
1548 return cmd->frame_count;
1549}
1550
1551/**
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301552 * megasas_cmd_type - Checks if the cmd is for logical drive/sysPD
1553 * and whether it's RW or non RW
Sumant Patrocb59aa62006-01-25 11:53:25 -08001554 * @scmd: SCSI command
adam radford0d490162010-12-14 19:17:17 -08001555 *
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001556 */
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301557inline int megasas_cmd_type(struct scsi_cmnd *cmd)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001558{
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301559 int ret;
1560
Sumant Patrocb59aa62006-01-25 11:53:25 -08001561 switch (cmd->cmnd[0]) {
1562 case READ_10:
1563 case WRITE_10:
1564 case READ_12:
1565 case WRITE_12:
1566 case READ_6:
1567 case WRITE_6:
1568 case READ_16:
1569 case WRITE_16:
Shivasharan S3cabd162017-02-10 00:59:05 -08001570 ret = (MEGASAS_IS_LOGICAL(cmd->device)) ?
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301571 READ_WRITE_LDIO : READ_WRITE_SYSPDIO;
1572 break;
Sumant Patrocb59aa62006-01-25 11:53:25 -08001573 default:
Shivasharan S3cabd162017-02-10 00:59:05 -08001574 ret = (MEGASAS_IS_LOGICAL(cmd->device)) ?
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301575 NON_READ_WRITE_LDIO : NON_READ_WRITE_SYSPDIO;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001576 }
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301577 return ret;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001578}
1579
Sumant Patro658dced2006-10-03 13:09:14 -07001580 /**
1581 * megasas_dump_pending_frames - Dumps the frame address of all pending cmds
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001582 * in FW
Sumant Patro658dced2006-10-03 13:09:14 -07001583 * @instance: Adapter soft state
1584 */
1585static inline void
1586megasas_dump_pending_frames(struct megasas_instance *instance)
1587{
1588 struct megasas_cmd *cmd;
1589 int i,n;
1590 union megasas_sgl *mfi_sgl;
1591 struct megasas_io_frame *ldio;
1592 struct megasas_pthru_frame *pthru;
1593 u32 sgcount;
Shivasharan S50b7f5a2017-02-10 00:59:25 -08001594 u16 max_cmd = instance->max_fw_cmds;
Sumant Patro658dced2006-10-03 13:09:14 -07001595
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001596 dev_err(&instance->pdev->dev, "[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
1597 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 -07001598 if (IS_DMA64)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001599 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 -07001600 else
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001601 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 -07001602
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001603 dev_err(&instance->pdev->dev, "[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
Sumant Patro658dced2006-10-03 13:09:14 -07001604 for (i = 0; i < max_cmd; i++) {
1605 cmd = instance->cmd_list[i];
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001606 if (!cmd->scmd)
Sumant Patro658dced2006-10-03 13:09:14 -07001607 continue;
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001608 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 +05301609 if (megasas_cmd_type(cmd->scmd) == READ_WRITE_LDIO) {
Sumant Patro658dced2006-10-03 13:09:14 -07001610 ldio = (struct megasas_io_frame *)cmd->frame;
1611 mfi_sgl = &ldio->sgl;
1612 sgcount = ldio->sge_count;
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001613 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 +05301614 " lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",
1615 instance->host->host_no, cmd->frame_count, ldio->cmd, ldio->target_id,
1616 le32_to_cpu(ldio->start_lba_lo), le32_to_cpu(ldio->start_lba_hi),
1617 le32_to_cpu(ldio->sense_buf_phys_addr_lo), sgcount);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001618 } else {
Sumant Patro658dced2006-10-03 13:09:14 -07001619 pthru = (struct megasas_pthru_frame *) cmd->frame;
1620 mfi_sgl = &pthru->sgl;
1621 sgcount = pthru->sge_count;
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001622 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 +05301623 "lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",
1624 instance->host->host_no, cmd->frame_count, pthru->cmd, pthru->target_id,
1625 pthru->lun, pthru->cdb_len, le32_to_cpu(pthru->data_xfer_len),
1626 le32_to_cpu(pthru->sense_buf_phys_addr_lo), sgcount);
Sumant Patro658dced2006-10-03 13:09:14 -07001627 }
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001628 if (megasas_dbg_lvl & MEGASAS_DBG_LVL) {
1629 for (n = 0; n < sgcount; n++) {
1630 if (IS_DMA64)
1631 dev_err(&instance->pdev->dev, "sgl len : 0x%x, sgl addr : 0x%llx\n",
1632 le32_to_cpu(mfi_sgl->sge64[n].length),
1633 le64_to_cpu(mfi_sgl->sge64[n].phys_addr));
1634 else
1635 dev_err(&instance->pdev->dev, "sgl len : 0x%x, sgl addr : 0x%x\n",
1636 le32_to_cpu(mfi_sgl->sge32[n].length),
1637 le32_to_cpu(mfi_sgl->sge32[n].phys_addr));
Sumant Patro658dced2006-10-03 13:09:14 -07001638 }
1639 }
Sumant Patro658dced2006-10-03 13:09:14 -07001640 } /*for max_cmd*/
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001641 dev_err(&instance->pdev->dev, "[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
Sumant Patro658dced2006-10-03 13:09:14 -07001642 for (i = 0; i < max_cmd; i++) {
1643
1644 cmd = instance->cmd_list[i];
1645
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001646 if (cmd->sync_cmd == 1)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001647 dev_err(&instance->pdev->dev, "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
Sumant Patro658dced2006-10-03 13:09:14 -07001648 }
Bjorn Helgaas1be18252015-07-07 15:52:34 -05001649 dev_err(&instance->pdev->dev, "[%d]: Dumping Done\n\n",instance->host->host_no);
Sumant Patro658dced2006-10-03 13:09:14 -07001650}
1651
adam radfordcd50ba82010-12-21 10:23:23 -08001652u32
1653megasas_build_and_issue_cmd(struct megasas_instance *instance,
1654 struct scsi_cmnd *scmd)
1655{
1656 struct megasas_cmd *cmd;
1657 u32 frame_count;
1658
1659 cmd = megasas_get_cmd(instance);
1660 if (!cmd)
1661 return SCSI_MLQUEUE_HOST_BUSY;
1662
1663 /*
1664 * Logical drive command
1665 */
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05301666 if (megasas_cmd_type(scmd) == READ_WRITE_LDIO)
adam radfordcd50ba82010-12-21 10:23:23 -08001667 frame_count = megasas_build_ldio(instance, scmd, cmd);
1668 else
1669 frame_count = megasas_build_dcdb(instance, scmd, cmd);
1670
1671 if (!frame_count)
1672 goto out_return_cmd;
1673
1674 cmd->scmd = scmd;
1675 scmd->SCp.ptr = (char *)cmd;
1676
1677 /*
1678 * Issue the command to the FW
1679 */
1680 atomic_inc(&instance->fw_outstanding);
1681
1682 instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
1683 cmd->frame_count-1, instance->reg_set);
adam radfordcd50ba82010-12-21 10:23:23 -08001684
1685 return 0;
1686out_return_cmd:
1687 megasas_return_cmd(instance, cmd);
Sumit Saxenaf9a9dee2016-01-28 21:04:29 +05301688 return SCSI_MLQUEUE_HOST_BUSY;
adam radfordcd50ba82010-12-21 10:23:23 -08001689}
1690
1691
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001692/**
1693 * megasas_queue_command - Queue entry point
1694 * @scmd: SCSI command to be queued
1695 * @done: Callback entry point
1696 */
1697static int
Sumit.Saxena@avagotech.comfb1a24f2014-09-12 18:57:38 +05301698megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001699{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001700 struct megasas_instance *instance;
Sumit Saxena18365b12016-01-28 21:04:25 +05301701 struct MR_PRIV_DEVICE *mr_device_priv_data;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001702
1703 instance = (struct megasas_instance *)
1704 scmd->device->host->hostdata;
Sumant Patroaf37acf2007-02-14 12:34:46 -08001705
Sumit.Saxena@avagotech.comaa008322014-11-17 15:24:08 +05301706 if (instance->unload == 1) {
1707 scmd->result = DID_NO_CONNECT << 16;
1708 scmd->scsi_done(scmd);
1709 return 0;
1710 }
1711
bo yang39a98552010-09-22 22:36:29 -04001712 if (instance->issuepend_done == 0)
Sumant Patroaf37acf2007-02-14 12:34:46 -08001713 return SCSI_MLQUEUE_HOST_BUSY;
1714
Sumit.Saxena@lsi.comb09e66d2013-05-22 12:29:28 +05301715
adam radford229fe472014-03-10 02:51:56 -07001716 /* Check for an mpio path and adjust behavior */
Sumit Saxena8a01a412016-01-28 21:04:32 +05301717 if (atomic_read(&instance->adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) {
adam radford229fe472014-03-10 02:51:56 -07001718 if (megasas_check_mpio_paths(instance, scmd) ==
Shivasharan Sf55cf472017-02-10 00:59:07 -08001719 (DID_REQUEUE << 16)) {
adam radford229fe472014-03-10 02:51:56 -07001720 return SCSI_MLQUEUE_HOST_BUSY;
1721 } else {
adam radford229fe472014-03-10 02:51:56 -07001722 scmd->result = DID_NO_CONNECT << 16;
Sumit.Saxena@avagotech.comfb1a24f2014-09-12 18:57:38 +05301723 scmd->scsi_done(scmd);
adam radford229fe472014-03-10 02:51:56 -07001724 return 0;
1725 }
1726 }
1727
Sumit Saxena8a01a412016-01-28 21:04:32 +05301728 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
adam radford229fe472014-03-10 02:51:56 -07001729 scmd->result = DID_NO_CONNECT << 16;
Sumit.Saxena@avagotech.comfb1a24f2014-09-12 18:57:38 +05301730 scmd->scsi_done(scmd);
Sumit.Saxena@lsi.comb09e66d2013-05-22 12:29:28 +05301731 return 0;
1732 }
1733
Sumit Saxena18365b12016-01-28 21:04:25 +05301734 mr_device_priv_data = scmd->device->hostdata;
1735 if (!mr_device_priv_data) {
Sumit Saxena18365b12016-01-28 21:04:25 +05301736 scmd->result = DID_NO_CONNECT << 16;
1737 scmd->scsi_done(scmd);
1738 return 0;
1739 }
1740
Sumit Saxena8a01a412016-01-28 21:04:32 +05301741 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
bo yang39a98552010-09-22 22:36:29 -04001742 return SCSI_MLQUEUE_HOST_BUSY;
bo yang39a98552010-09-22 22:36:29 -04001743
Sumit Saxena8a01a412016-01-28 21:04:32 +05301744 if (mr_device_priv_data->tm_busy)
Sumit Saxena18365b12016-01-28 21:04:25 +05301745 return SCSI_MLQUEUE_DEVICE_BUSY;
Sumit Saxena18365b12016-01-28 21:04:25 +05301746
bo yang39a98552010-09-22 22:36:29 -04001747
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001748 scmd->result = 0;
1749
Shivasharan S3cabd162017-02-10 00:59:05 -08001750 if (MEGASAS_IS_LOGICAL(scmd->device) &&
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05301751 (scmd->device->id >= instance->fw_supported_vd_count ||
1752 scmd->device->lun)) {
Sumant Patrocb59aa62006-01-25 11:53:25 -08001753 scmd->result = DID_BAD_TARGET << 16;
1754 goto out_done;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001755 }
1756
Shivasharan S3cabd162017-02-10 00:59:05 -08001757 if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) &&
1758 MEGASAS_IS_LOGICAL(scmd->device) &&
1759 (!instance->fw_sync_cache_support)) {
Sumant Patro02b01e02007-02-14 13:00:55 -08001760 scmd->result = DID_OK << 16;
1761 goto out_done;
Sumant Patro02b01e02007-02-14 13:00:55 -08001762 }
1763
Sumit Saxenaf9a9dee2016-01-28 21:04:29 +05301764 return instance->instancet->build_and_issue_cmd(instance, scmd);
Sumant Patrocb59aa62006-01-25 11:53:25 -08001765
Sumant Patrocb59aa62006-01-25 11:53:25 -08001766 out_done:
Sumit.Saxena@avagotech.comfb1a24f2014-09-12 18:57:38 +05301767 scmd->scsi_done(scmd);
Sumant Patrocb59aa62006-01-25 11:53:25 -08001768 return 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001769}
1770
Yang, Bo044833b2009-10-06 14:33:06 -06001771static struct megasas_instance *megasas_lookup_instance(u16 host_no)
1772{
1773 int i;
1774
1775 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
1776
1777 if ((megasas_mgmt_info.instance[i]) &&
1778 (megasas_mgmt_info.instance[i]->host->host_no == host_no))
1779 return megasas_mgmt_info.instance[i];
1780 }
1781
1782 return NULL;
1783}
1784
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301785/*
Shivasharan S15dd0382017-02-10 00:59:10 -08001786* megasas_set_dynamic_target_properties -
1787* Device property set by driver may not be static and it is required to be
1788* updated after OCR
1789*
1790* set tm_capable.
1791* set dma alignment (only for eedp protection enable vd).
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301792*
1793* @sdev: OS provided scsi device
1794*
1795* Returns void
1796*/
Shivasharan Se9495e22018-06-04 03:45:12 -07001797void megasas_set_dynamic_target_properties(struct scsi_device *sdev,
1798 bool is_target_prop)
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301799{
Shivasharan S15dd0382017-02-10 00:59:10 -08001800 u16 pd_index = 0, ld;
1801 u32 device_id;
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301802 struct megasas_instance *instance;
1803 struct fusion_context *fusion;
Sumit Saxena18365b12016-01-28 21:04:25 +05301804 struct MR_PRIV_DEVICE *mr_device_priv_data;
1805 struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301806 struct MR_LD_RAID *raid;
1807 struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
1808
1809 instance = megasas_lookup_instance(sdev->host->host_no);
1810 fusion = instance->ctrl_context;
Sumit Saxena18365b12016-01-28 21:04:25 +05301811 mr_device_priv_data = sdev->hostdata;
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301812
Shivasharan Sed981b82017-02-10 00:59:06 -08001813 if (!fusion || !mr_device_priv_data)
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301814 return;
1815
Shivasharan Sed981b82017-02-10 00:59:06 -08001816 if (MEGASAS_IS_LOGICAL(sdev)) {
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301817 device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL)
1818 + sdev->id;
1819 local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
1820 ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
Shivasharan Sed981b82017-02-10 00:59:06 -08001821 if (ld >= instance->fw_supported_vd_count)
1822 return;
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301823 raid = MR_LdRaidGet(ld, local_map_ptr);
1824
1825 if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER)
Shivasharan S15dd0382017-02-10 00:59:10 -08001826 blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
Shivasharan Sed981b82017-02-10 00:59:06 -08001827
Sumit Saxena18365b12016-01-28 21:04:25 +05301828 mr_device_priv_data->is_tm_capable =
1829 raid->capability.tmCapable;
Shivasharan Sed981b82017-02-10 00:59:06 -08001830 } else if (instance->use_seqnum_jbod_fp) {
1831 pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
Shivasharan S15dd0382017-02-10 00:59:10 -08001832 sdev->id;
Shivasharan Sed981b82017-02-10 00:59:06 -08001833 pd_sync = (void *)fusion->pd_seq_sync
1834 [(instance->pd_seq_map_id - 1) & 1];
1835 mr_device_priv_data->is_tm_capable =
Shivasharan S15dd0382017-02-10 00:59:10 -08001836 pd_sync->seq[pd_index].capability.tmCapable;
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301837 }
Shivasharan Se9495e22018-06-04 03:45:12 -07001838
1839 if (is_target_prop && instance->tgt_prop->reset_tmo) {
1840 /*
1841 * If FW provides a target reset timeout value, driver will use
1842 * it. If not set, fallback to default values.
1843 */
1844 mr_device_priv_data->target_reset_tmo =
1845 min_t(u8, instance->max_reset_tmo,
1846 instance->tgt_prop->reset_tmo);
1847 mr_device_priv_data->task_abort_tmo = instance->task_abort_tmo;
1848 } else {
1849 mr_device_priv_data->target_reset_tmo =
1850 MEGASAS_DEFAULT_TM_TIMEOUT;
1851 mr_device_priv_data->task_abort_tmo =
1852 MEGASAS_DEFAULT_TM_TIMEOUT;
1853 }
sumit.saxena@avagotech.com0b48d122015-10-15 13:40:44 +05301854}
1855
Shivasharan S15dd0382017-02-10 00:59:10 -08001856/*
1857 * megasas_set_nvme_device_properties -
1858 * set nomerges=2
1859 * set virtual page boundary = 4K (current mr_nvme_pg_size is 4K).
1860 * set maximum io transfer = MDTS of NVME device provided by MR firmware.
1861 *
1862 * MR firmware provides value in KB. Caller of this function converts
1863 * kb into bytes.
1864 *
1865 * e.a MDTS=5 means 2^5 * nvme page size. (In case of 4K page size,
1866 * MR firmware provides value 128 as (32 * 4K) = 128K.
1867 *
1868 * @sdev: scsi device
1869 * @max_io_size: maximum io transfer size
1870 *
1871 */
1872static inline void
1873megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size)
Sumit Saxena2216c302016-01-28 21:04:26 +05301874{
Sumit Saxena2216c302016-01-28 21:04:26 +05301875 struct megasas_instance *instance;
Shivasharan S15dd0382017-02-10 00:59:10 -08001876 u32 mr_nvme_pg_size;
1877
1878 instance = (struct megasas_instance *)sdev->host->hostdata;
1879 mr_nvme_pg_size = max_t(u32, instance->nvme_page_size,
1880 MR_DEFAULT_NVME_PAGE_SIZE);
1881
1882 blk_queue_max_hw_sectors(sdev->request_queue, (max_io_size / 512));
1883
Bart Van Assche8b904b52018-03-07 17:10:10 -08001884 blk_queue_flag_set(QUEUE_FLAG_NOMERGES, sdev->request_queue);
Shivasharan S15dd0382017-02-10 00:59:10 -08001885 blk_queue_virt_boundary(sdev->request_queue, mr_nvme_pg_size - 1);
1886}
1887
1888
1889/*
1890 * megasas_set_static_target_properties -
1891 * Device property set by driver are static and it is not required to be
1892 * updated after OCR.
1893 *
1894 * set io timeout
1895 * set device queue depth
1896 * set nvme device properties. see - megasas_set_nvme_device_properties
1897 *
1898 * @sdev: scsi device
Shivasharan S96188a82017-02-10 00:59:11 -08001899 * @is_target_prop true, if fw provided target properties.
Shivasharan S15dd0382017-02-10 00:59:10 -08001900 */
Shivasharan S96188a82017-02-10 00:59:11 -08001901static void megasas_set_static_target_properties(struct scsi_device *sdev,
1902 bool is_target_prop)
Shivasharan S15dd0382017-02-10 00:59:10 -08001903{
1904 u16 target_index = 0;
1905 u8 interface_type;
1906 u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN;
1907 u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB;
Shivasharan S96188a82017-02-10 00:59:11 -08001908 u32 tgt_device_qd;
Shivasharan S15dd0382017-02-10 00:59:10 -08001909 struct megasas_instance *instance;
1910 struct MR_PRIV_DEVICE *mr_device_priv_data;
Sumit Saxena2216c302016-01-28 21:04:26 +05301911
1912 instance = megasas_lookup_instance(sdev->host->host_no);
Shivasharan S15dd0382017-02-10 00:59:10 -08001913 mr_device_priv_data = sdev->hostdata;
1914 interface_type = mr_device_priv_data->interface_type;
Sumit Saxena2216c302016-01-28 21:04:26 +05301915
Shivasharan S15dd0382017-02-10 00:59:10 -08001916 /*
1917 * The RAID firmware may require extended timeouts.
1918 */
1919 blk_queue_rq_timeout(sdev->request_queue, scmd_timeout * HZ);
Sumit Saxena2216c302016-01-28 21:04:26 +05301920
Shivasharan S15dd0382017-02-10 00:59:10 -08001921 target_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id;
Sumit Saxena2216c302016-01-28 21:04:26 +05301922
Shivasharan S15dd0382017-02-10 00:59:10 -08001923 switch (interface_type) {
1924 case SAS_PD:
1925 device_qd = MEGASAS_SAS_QD;
1926 break;
1927 case SATA_PD:
1928 device_qd = MEGASAS_SATA_QD;
1929 break;
1930 case NVME_PD:
1931 device_qd = MEGASAS_NVME_QD;
1932 break;
Sumit Saxena2216c302016-01-28 21:04:26 +05301933 }
Shivasharan S15dd0382017-02-10 00:59:10 -08001934
Shivasharan S96188a82017-02-10 00:59:11 -08001935 if (is_target_prop) {
1936 tgt_device_qd = le32_to_cpu(instance->tgt_prop->device_qdepth);
1937 if (tgt_device_qd &&
1938 (tgt_device_qd <= instance->host->can_queue))
1939 device_qd = tgt_device_qd;
1940
1941 /* max_io_size_kb will be set to non zero for
1942 * nvme based vd and syspd.
1943 */
1944 max_io_size_kb = le32_to_cpu(instance->tgt_prop->max_io_size_kb);
1945 }
1946
Shivasharan S15dd0382017-02-10 00:59:10 -08001947 if (instance->nvme_page_size && max_io_size_kb)
1948 megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 10));
1949
1950 scsi_change_queue_depth(sdev, device_qd);
1951
Sumit Saxena2216c302016-01-28 21:04:26 +05301952}
1953
Sumit Saxena18365b12016-01-28 21:04:25 +05301954
Christoph Hellwig147aab62006-02-17 12:13:48 +01001955static int megasas_slave_configure(struct scsi_device *sdev)
1956{
Sumit Saxenaaed335e2015-11-05 21:17:37 +05301957 u16 pd_index = 0;
1958 struct megasas_instance *instance;
Shivasharan S96188a82017-02-10 00:59:11 -08001959 int ret_target_prop = DCMD_FAILED;
1960 bool is_target_prop = false;
Sumit Saxenaaed335e2015-11-05 21:17:37 +05301961
1962 instance = megasas_lookup_instance(sdev->host->host_no);
Sumit Saxena30845582016-03-10 02:14:37 -08001963 if (instance->pd_list_not_supported) {
Shivasharan S3cabd162017-02-10 00:59:05 -08001964 if (!MEGASAS_IS_LOGICAL(sdev) && sdev->type == TYPE_DISK) {
Sumit Saxenaaed335e2015-11-05 21:17:37 +05301965 pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
1966 sdev->id;
1967 if (instance->pd_list[pd_index].driveState !=
1968 MR_PD_STATE_SYSTEM)
1969 return -ENXIO;
1970 }
1971 }
Sumit Saxena18365b12016-01-28 21:04:25 +05301972
Shivasharan S149c5752018-01-05 05:27:42 -08001973 mutex_lock(&instance->reset_mutex);
Shivasharan S15dd0382017-02-10 00:59:10 -08001974 /* Send DCMD to Firmware and cache the information */
1975 if ((instance->pd_info) && !MEGASAS_IS_LOGICAL(sdev))
1976 megasas_get_pd_info(instance, sdev);
1977
Shivasharan S96188a82017-02-10 00:59:11 -08001978 /* Some ventura firmware may not have instance->nvme_page_size set.
1979 * Do not send MR_DCMD_DRV_GET_TARGET_PROP
1980 */
1981 if ((instance->tgt_prop) && (instance->nvme_page_size))
1982 ret_target_prop = megasas_get_target_prop(instance, sdev);
1983
1984 is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false;
1985 megasas_set_static_target_properties(sdev, is_target_prop);
Shivasharan S15dd0382017-02-10 00:59:10 -08001986
Shivasharan S15dd0382017-02-10 00:59:10 -08001987 /* This sdev property may change post OCR */
Shivasharan Se9495e22018-06-04 03:45:12 -07001988 megasas_set_dynamic_target_properties(sdev, is_target_prop);
1989
1990 mutex_unlock(&instance->reset_mutex);
Sumit.Saxena@avagotech.com07e38d92014-09-12 18:57:13 +05301991
Yang, Bo044833b2009-10-06 14:33:06 -06001992 return 0;
1993}
1994
1995static int megasas_slave_alloc(struct scsi_device *sdev)
1996{
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05001997 u16 pd_index = 0;
Yang, Bo044833b2009-10-06 14:33:06 -06001998 struct megasas_instance *instance ;
Sumit Saxena18365b12016-01-28 21:04:25 +05301999 struct MR_PRIV_DEVICE *mr_device_priv_data;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002000
Yang, Bo044833b2009-10-06 14:33:06 -06002001 instance = megasas_lookup_instance(sdev->host->host_no);
Shivasharan S3cabd162017-02-10 00:59:05 -08002002 if (!MEGASAS_IS_LOGICAL(sdev)) {
Yang, Bo044833b2009-10-06 14:33:06 -06002003 /*
2004 * Open the OS scan to the SYSTEM PD
2005 */
2006 pd_index =
2007 (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
2008 sdev->id;
Sumit Saxena30845582016-03-10 02:14:37 -08002009 if ((instance->pd_list_not_supported ||
2010 instance->pd_list[pd_index].driveState ==
Sumit Saxenaaed335e2015-11-05 21:17:37 +05302011 MR_PD_STATE_SYSTEM)) {
Sumit Saxena18365b12016-01-28 21:04:25 +05302012 goto scan_target;
Yang, Bo044833b2009-10-06 14:33:06 -06002013 }
2014 return -ENXIO;
2015 }
Sumit Saxena18365b12016-01-28 21:04:25 +05302016
2017scan_target:
2018 mr_device_priv_data = kzalloc(sizeof(*mr_device_priv_data),
2019 GFP_KERNEL);
2020 if (!mr_device_priv_data)
2021 return -ENOMEM;
2022 sdev->hostdata = mr_device_priv_data;
Shivasharan S49524b32017-03-10 03:22:13 -08002023
2024 atomic_set(&mr_device_priv_data->r1_ldio_hint,
2025 instance->r1_ldio_hint_default);
Christoph Hellwig147aab62006-02-17 12:13:48 +01002026 return 0;
2027}
2028
Sumit Saxena18365b12016-01-28 21:04:25 +05302029static void megasas_slave_destroy(struct scsi_device *sdev)
2030{
2031 kfree(sdev->hostdata);
2032 sdev->hostdata = NULL;
2033}
2034
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302035/*
2036* megasas_complete_outstanding_ioctls - Complete outstanding ioctls after a
2037* kill adapter
2038* @instance: Adapter soft state
2039*
2040*/
kbuild test robot6a6981f2015-04-23 16:33:23 +05302041static void megasas_complete_outstanding_ioctls(struct megasas_instance *instance)
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302042{
2043 int i;
2044 struct megasas_cmd *cmd_mfi;
2045 struct megasas_cmd_fusion *cmd_fusion;
2046 struct fusion_context *fusion = instance->ctrl_context;
2047
2048 /* Find all outstanding ioctls */
2049 if (fusion) {
2050 for (i = 0; i < instance->max_fw_cmds; i++) {
2051 cmd_fusion = fusion->cmd_list[i];
2052 if (cmd_fusion->sync_cmd_idx != (u32)ULONG_MAX) {
2053 cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
2054 if (cmd_mfi->sync_cmd &&
Shivasharan Seb3fe262017-08-23 04:47:04 -07002055 (cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)) {
2056 cmd_mfi->frame->hdr.cmd_status =
2057 MFI_STAT_WRONG_STATE;
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302058 megasas_complete_cmd(instance,
2059 cmd_mfi, DID_OK);
Shivasharan Seb3fe262017-08-23 04:47:04 -07002060 }
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302061 }
2062 }
2063 } else {
2064 for (i = 0; i < instance->max_fw_cmds; i++) {
2065 cmd_mfi = instance->cmd_list[i];
2066 if (cmd_mfi->sync_cmd && cmd_mfi->frame->hdr.cmd !=
2067 MFI_CMD_ABORT)
2068 megasas_complete_cmd(instance, cmd_mfi, DID_OK);
2069 }
2070 }
2071}
2072
2073
adam radford9c915a82010-12-21 13:34:31 -08002074void megaraid_sas_kill_hba(struct megasas_instance *instance)
bo yang39a98552010-09-22 22:36:29 -04002075{
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302076 /* Set critical error to block I/O & ioctls in case caller didn't */
Sumit Saxena8a01a412016-01-28 21:04:32 +05302077 atomic_set(&instance->adprecovery, MEGASAS_HW_CRITICAL_ERROR);
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302078 /* Wait 1 second to ensure IO or ioctls in build have posted */
2079 msleep(1000);
bo yang39a98552010-09-22 22:36:29 -04002080 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302081 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
Shivasharan Se7d36b82017-10-19 02:48:50 -07002082 (instance->adapter_type != MFI_SERIES)) {
Shivasharan S5acad9b2018-10-16 23:37:47 -07002083 if (!instance->requestorId) {
2084 writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
2085 /* Flush */
2086 readl(&instance->reg_set->doorbell);
2087 }
Sumit Saxena8f67c8c2016-01-28 21:14:25 +05302088 if (instance->requestorId && instance->peerIsPresent)
adam radford229fe472014-03-10 02:51:56 -07002089 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
bo yang39a98552010-09-22 22:36:29 -04002090 } else {
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302091 writel(MFI_STOP_ADP,
2092 &instance->reg_set->inbound_doorbell);
adam radford9c915a82010-12-21 13:34:31 -08002093 }
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05302094 /* Complete outstanding ioctls when adapter is killed */
2095 megasas_complete_outstanding_ioctls(instance);
adam radford9c915a82010-12-21 13:34:31 -08002096}
2097
2098 /**
2099 * megasas_check_and_restore_queue_depth - Check if queue depth needs to be
2100 * restored to max value
2101 * @instance: Adapter soft state
2102 *
2103 */
2104void
2105megasas_check_and_restore_queue_depth(struct megasas_instance *instance)
2106{
2107 unsigned long flags;
Sumit.Saxena@avagotech.comae09a6c2015-01-05 20:06:23 +05302108
adam radford9c915a82010-12-21 13:34:31 -08002109 if (instance->flag & MEGASAS_FW_BUSY
adam radfordc5daa6a2012-07-17 18:20:03 -07002110 && time_after(jiffies, instance->last_time + 5 * HZ)
2111 && atomic_read(&instance->fw_outstanding) <
2112 instance->throttlequeuedepth + 1) {
adam radford9c915a82010-12-21 13:34:31 -08002113
2114 spin_lock_irqsave(instance->host->host_lock, flags);
2115 instance->flag &= ~MEGASAS_FW_BUSY;
adam radford9c915a82010-12-21 13:34:31 -08002116
Sumit Saxena308ec452016-01-28 21:04:30 +05302117 instance->host->can_queue = instance->cur_can_queue;
adam radford9c915a82010-12-21 13:34:31 -08002118 spin_unlock_irqrestore(instance->host->host_lock, flags);
bo yang39a98552010-09-22 22:36:29 -04002119 }
2120}
2121
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002122/**
bo yang7343eb62007-11-09 04:35:44 -05002123 * megasas_complete_cmd_dpc - Returns FW's controller structure
2124 * @instance_addr: Address of adapter soft state
2125 *
2126 * Tasklet to complete cmds
2127 */
2128static void megasas_complete_cmd_dpc(unsigned long instance_addr)
2129{
2130 u32 producer;
2131 u32 consumer;
2132 u32 context;
2133 struct megasas_cmd *cmd;
2134 struct megasas_instance *instance =
2135 (struct megasas_instance *)instance_addr;
2136 unsigned long flags;
2137
2138 /* If we have already declared adapter dead, donot complete cmds */
Sumit Saxena8a01a412016-01-28 21:04:32 +05302139 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
bo yang7343eb62007-11-09 04:35:44 -05002140 return;
2141
2142 spin_lock_irqsave(&instance->completion_lock, flags);
2143
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302144 producer = le32_to_cpu(*instance->producer);
2145 consumer = le32_to_cpu(*instance->consumer);
bo yang7343eb62007-11-09 04:35:44 -05002146
2147 while (consumer != producer) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302148 context = le32_to_cpu(instance->reply_queue[consumer]);
bo yang39a98552010-09-22 22:36:29 -04002149 if (context >= instance->max_fw_cmds) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002150 dev_err(&instance->pdev->dev, "Unexpected context value %x\n",
bo yang39a98552010-09-22 22:36:29 -04002151 context);
2152 BUG();
2153 }
bo yang7343eb62007-11-09 04:35:44 -05002154
2155 cmd = instance->cmd_list[context];
2156
2157 megasas_complete_cmd(instance, cmd, DID_OK);
2158
2159 consumer++;
2160 if (consumer == (instance->max_fw_cmds + 1)) {
2161 consumer = 0;
2162 }
2163 }
2164
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302165 *instance->consumer = cpu_to_le32(producer);
bo yang7343eb62007-11-09 04:35:44 -05002166
2167 spin_unlock_irqrestore(&instance->completion_lock, flags);
2168
2169 /*
2170 * Check if we can restore can_queue
2171 */
adam radford9c915a82010-12-21 13:34:31 -08002172 megasas_check_and_restore_queue_depth(instance);
bo yang7343eb62007-11-09 04:35:44 -05002173}
2174
Kees Cookc251a7b2017-10-22 15:30:04 -07002175static void megasas_sriov_heartbeat_handler(struct timer_list *t);
2176
adam radford229fe472014-03-10 02:51:56 -07002177/**
Kees Cookc251a7b2017-10-22 15:30:04 -07002178 * megasas_start_timer - Initializes sriov heartbeat timer object
adam radford229fe472014-03-10 02:51:56 -07002179 * @instance: Adapter soft state
adam radford229fe472014-03-10 02:51:56 -07002180 *
2181 */
Kees Cookc251a7b2017-10-22 15:30:04 -07002182void megasas_start_timer(struct megasas_instance *instance)
adam radford229fe472014-03-10 02:51:56 -07002183{
Kees Cookc251a7b2017-10-22 15:30:04 -07002184 struct timer_list *timer = &instance->sriov_heartbeat_timer;
2185
2186 timer_setup(timer, megasas_sriov_heartbeat_handler, 0);
2187 timer->expires = jiffies + MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF;
adam radford229fe472014-03-10 02:51:56 -07002188 add_timer(timer);
2189}
2190
Yang, Bo707e09b2010-10-12 07:20:27 -06002191static void
2192megasas_internal_reset_defer_cmds(struct megasas_instance *instance);
2193
2194static void
2195process_fw_state_change_wq(struct work_struct *work);
2196
2197void megasas_do_ocr(struct megasas_instance *instance)
2198{
2199 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
2200 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
2201 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302202 *instance->consumer = cpu_to_le32(MEGASAS_ADPRESET_INPROG_SIGN);
Yang, Bo707e09b2010-10-12 07:20:27 -06002203 }
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05302204 instance->instancet->disable_intr(instance);
Sumit Saxena8a01a412016-01-28 21:04:32 +05302205 atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_INFAULT);
Yang, Bo707e09b2010-10-12 07:20:27 -06002206 instance->issuepend_done = 0;
2207
2208 atomic_set(&instance->fw_outstanding, 0);
2209 megasas_internal_reset_defer_cmds(instance);
2210 process_fw_state_change_wq(&instance->work_init);
2211}
2212
Adam Radford4cbfea82014-07-09 15:17:56 -07002213static int megasas_get_ld_vf_affiliation_111(struct megasas_instance *instance,
2214 int initial)
adam radford229fe472014-03-10 02:51:56 -07002215{
2216 struct megasas_cmd *cmd;
2217 struct megasas_dcmd_frame *dcmd;
adam radford229fe472014-03-10 02:51:56 -07002218 struct MR_LD_VF_AFFILIATION_111 *new_affiliation_111 = NULL;
adam radford229fe472014-03-10 02:51:56 -07002219 dma_addr_t new_affiliation_111_h;
2220 int ld, retval = 0;
2221 u8 thisVf;
2222
2223 cmd = megasas_get_cmd(instance);
2224
2225 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002226 dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_get_ld_vf_affiliation_111:"
2227 "Failed to get cmd for scsi%d\n",
adam radford229fe472014-03-10 02:51:56 -07002228 instance->host->host_no);
2229 return -ENOMEM;
2230 }
2231
2232 dcmd = &cmd->frame->dcmd;
2233
Adam Radford4cbfea82014-07-09 15:17:56 -07002234 if (!instance->vf_affiliation_111) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002235 dev_warn(&instance->pdev->dev, "SR-IOV: Couldn't get LD/VF "
2236 "affiliation for scsi%d\n", instance->host->host_no);
adam radford229fe472014-03-10 02:51:56 -07002237 megasas_return_cmd(instance, cmd);
2238 return -ENOMEM;
2239 }
2240
2241 if (initial)
adam radford229fe472014-03-10 02:51:56 -07002242 memset(instance->vf_affiliation_111, 0,
2243 sizeof(struct MR_LD_VF_AFFILIATION_111));
adam radford229fe472014-03-10 02:51:56 -07002244 else {
Adam Radford4cbfea82014-07-09 15:17:56 -07002245 new_affiliation_111 =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02002246 dma_zalloc_coherent(&instance->pdev->dev,
Himanshu Jha3c6c1222018-04-06 02:02:10 -07002247 sizeof(struct MR_LD_VF_AFFILIATION_111),
Christoph Hellwig60ee6522018-10-10 19:31:25 +02002248 &new_affiliation_111_h, GFP_KERNEL);
Adam Radford4cbfea82014-07-09 15:17:56 -07002249 if (!new_affiliation_111) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002250 dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate "
2251 "memory for new affiliation for scsi%d\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07002252 instance->host->host_no);
adam radford229fe472014-03-10 02:51:56 -07002253 megasas_return_cmd(instance, cmd);
2254 return -ENOMEM;
2255 }
adam radford229fe472014-03-10 02:51:56 -07002256 }
2257
2258 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2259
2260 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05302261 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
adam radford229fe472014-03-10 02:51:56 -07002262 dcmd->sge_count = 1;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302263 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_BOTH);
adam radford229fe472014-03-10 02:51:56 -07002264 dcmd->timeout = 0;
2265 dcmd->pad_0 = 0;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302266 dcmd->data_xfer_len =
2267 cpu_to_le32(sizeof(struct MR_LD_VF_AFFILIATION_111));
2268 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_VF_MAP_GET_ALL_LDS_111);
adam radford229fe472014-03-10 02:51:56 -07002269
Adam Radford4cbfea82014-07-09 15:17:56 -07002270 if (initial)
2271 dcmd->sgl.sge32[0].phys_addr =
Christoph Hellwig2213a462015-04-23 16:33:54 +05302272 cpu_to_le32(instance->vf_affiliation_111_h);
adam radford229fe472014-03-10 02:51:56 -07002273 else
Christoph Hellwig2213a462015-04-23 16:33:54 +05302274 dcmd->sgl.sge32[0].phys_addr =
2275 cpu_to_le32(new_affiliation_111_h);
Adam Radford4cbfea82014-07-09 15:17:56 -07002276
Christoph Hellwig2213a462015-04-23 16:33:54 +05302277 dcmd->sgl.sge32[0].length = cpu_to_le32(
2278 sizeof(struct MR_LD_VF_AFFILIATION_111));
adam radford229fe472014-03-10 02:51:56 -07002279
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002280 dev_warn(&instance->pdev->dev, "SR-IOV: Getting LD/VF affiliation for "
adam radford229fe472014-03-10 02:51:56 -07002281 "scsi%d\n", instance->host->host_no);
2282
Sumit Saxena6d40afb2016-01-28 21:04:23 +05302283 if (megasas_issue_blocked_cmd(instance, cmd, 0) != DCMD_SUCCESS) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002284 dev_warn(&instance->pdev->dev, "SR-IOV: LD/VF affiliation DCMD"
2285 " failed with status 0x%x for scsi%d\n",
adam radford229fe472014-03-10 02:51:56 -07002286 dcmd->cmd_status, instance->host->host_no);
2287 retval = 1; /* Do a scan if we couldn't get affiliation */
2288 goto out;
2289 }
2290
2291 if (!initial) {
Adam Radford4cbfea82014-07-09 15:17:56 -07002292 thisVf = new_affiliation_111->thisVf;
2293 for (ld = 0 ; ld < new_affiliation_111->vdCount; ld++)
2294 if (instance->vf_affiliation_111->map[ld].policy[thisVf] !=
2295 new_affiliation_111->map[ld].policy[thisVf]) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002296 dev_warn(&instance->pdev->dev, "SR-IOV: "
2297 "Got new LD/VF affiliation for scsi%d\n",
adam radford229fe472014-03-10 02:51:56 -07002298 instance->host->host_no);
Adam Radford4cbfea82014-07-09 15:17:56 -07002299 memcpy(instance->vf_affiliation_111,
2300 new_affiliation_111,
2301 sizeof(struct MR_LD_VF_AFFILIATION_111));
adam radford229fe472014-03-10 02:51:56 -07002302 retval = 1;
2303 goto out;
2304 }
Adam Radford4cbfea82014-07-09 15:17:56 -07002305 }
2306out:
2307 if (new_affiliation_111) {
Christoph Hellwig60ee6522018-10-10 19:31:25 +02002308 dma_free_coherent(&instance->pdev->dev,
Adam Radford4cbfea82014-07-09 15:17:56 -07002309 sizeof(struct MR_LD_VF_AFFILIATION_111),
2310 new_affiliation_111,
2311 new_affiliation_111_h);
2312 }
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05302313
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05302314 megasas_return_cmd(instance, cmd);
Adam Radford4cbfea82014-07-09 15:17:56 -07002315
2316 return retval;
2317}
2318
2319static int megasas_get_ld_vf_affiliation_12(struct megasas_instance *instance,
2320 int initial)
2321{
2322 struct megasas_cmd *cmd;
2323 struct megasas_dcmd_frame *dcmd;
2324 struct MR_LD_VF_AFFILIATION *new_affiliation = NULL;
2325 struct MR_LD_VF_MAP *newmap = NULL, *savedmap = NULL;
2326 dma_addr_t new_affiliation_h;
2327 int i, j, retval = 0, found = 0, doscan = 0;
2328 u8 thisVf;
2329
2330 cmd = megasas_get_cmd(instance);
2331
2332 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002333 dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_get_ld_vf_affiliation12: "
2334 "Failed to get cmd for scsi%d\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07002335 instance->host->host_no);
2336 return -ENOMEM;
2337 }
2338
2339 dcmd = &cmd->frame->dcmd;
2340
2341 if (!instance->vf_affiliation) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002342 dev_warn(&instance->pdev->dev, "SR-IOV: Couldn't get LD/VF "
2343 "affiliation for scsi%d\n", instance->host->host_no);
Adam Radford4cbfea82014-07-09 15:17:56 -07002344 megasas_return_cmd(instance, cmd);
2345 return -ENOMEM;
2346 }
2347
2348 if (initial)
2349 memset(instance->vf_affiliation, 0, (MAX_LOGICAL_DRIVES + 1) *
2350 sizeof(struct MR_LD_VF_AFFILIATION));
2351 else {
2352 new_affiliation =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02002353 dma_zalloc_coherent(&instance->pdev->dev,
Himanshu Jha3c6c1222018-04-06 02:02:10 -07002354 (MAX_LOGICAL_DRIVES + 1) *
2355 sizeof(struct MR_LD_VF_AFFILIATION),
Christoph Hellwig60ee6522018-10-10 19:31:25 +02002356 &new_affiliation_h, GFP_KERNEL);
Adam Radford4cbfea82014-07-09 15:17:56 -07002357 if (!new_affiliation) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002358 dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate "
2359 "memory for new affiliation for scsi%d\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07002360 instance->host->host_no);
2361 megasas_return_cmd(instance, cmd);
2362 return -ENOMEM;
2363 }
Adam Radford4cbfea82014-07-09 15:17:56 -07002364 }
2365
2366 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2367
2368 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05302369 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
Adam Radford4cbfea82014-07-09 15:17:56 -07002370 dcmd->sge_count = 1;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302371 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_BOTH);
Adam Radford4cbfea82014-07-09 15:17:56 -07002372 dcmd->timeout = 0;
2373 dcmd->pad_0 = 0;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302374 dcmd->data_xfer_len = cpu_to_le32((MAX_LOGICAL_DRIVES + 1) *
2375 sizeof(struct MR_LD_VF_AFFILIATION));
2376 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_VF_MAP_GET_ALL_LDS);
Adam Radford4cbfea82014-07-09 15:17:56 -07002377
2378 if (initial)
Christoph Hellwig2213a462015-04-23 16:33:54 +05302379 dcmd->sgl.sge32[0].phys_addr =
2380 cpu_to_le32(instance->vf_affiliation_h);
Adam Radford4cbfea82014-07-09 15:17:56 -07002381 else
Christoph Hellwig2213a462015-04-23 16:33:54 +05302382 dcmd->sgl.sge32[0].phys_addr =
2383 cpu_to_le32(new_affiliation_h);
Adam Radford4cbfea82014-07-09 15:17:56 -07002384
Christoph Hellwig2213a462015-04-23 16:33:54 +05302385 dcmd->sgl.sge32[0].length = cpu_to_le32((MAX_LOGICAL_DRIVES + 1) *
2386 sizeof(struct MR_LD_VF_AFFILIATION));
Adam Radford4cbfea82014-07-09 15:17:56 -07002387
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002388 dev_warn(&instance->pdev->dev, "SR-IOV: Getting LD/VF affiliation for "
Adam Radford4cbfea82014-07-09 15:17:56 -07002389 "scsi%d\n", instance->host->host_no);
2390
Adam Radford4cbfea82014-07-09 15:17:56 -07002391
Sumit Saxena6d40afb2016-01-28 21:04:23 +05302392 if (megasas_issue_blocked_cmd(instance, cmd, 0) != DCMD_SUCCESS) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002393 dev_warn(&instance->pdev->dev, "SR-IOV: LD/VF affiliation DCMD"
2394 " failed with status 0x%x for scsi%d\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07002395 dcmd->cmd_status, instance->host->host_no);
2396 retval = 1; /* Do a scan if we couldn't get affiliation */
2397 goto out;
2398 }
2399
2400 if (!initial) {
2401 if (!new_affiliation->ldCount) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002402 dev_warn(&instance->pdev->dev, "SR-IOV: Got new LD/VF "
2403 "affiliation for passive path for scsi%d\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07002404 instance->host->host_no);
2405 retval = 1;
2406 goto out;
2407 }
2408 newmap = new_affiliation->map;
2409 savedmap = instance->vf_affiliation->map;
2410 thisVf = new_affiliation->thisVf;
2411 for (i = 0 ; i < new_affiliation->ldCount; i++) {
2412 found = 0;
2413 for (j = 0; j < instance->vf_affiliation->ldCount;
2414 j++) {
2415 if (newmap->ref.targetId ==
2416 savedmap->ref.targetId) {
2417 found = 1;
2418 if (newmap->policy[thisVf] !=
2419 savedmap->policy[thisVf]) {
2420 doscan = 1;
2421 goto out;
2422 }
adam radford229fe472014-03-10 02:51:56 -07002423 }
2424 savedmap = (struct MR_LD_VF_MAP *)
2425 ((unsigned char *)savedmap +
2426 savedmap->size);
Adam Radford4cbfea82014-07-09 15:17:56 -07002427 }
2428 if (!found && newmap->policy[thisVf] !=
2429 MR_LD_ACCESS_HIDDEN) {
2430 doscan = 1;
2431 goto out;
2432 }
2433 newmap = (struct MR_LD_VF_MAP *)
2434 ((unsigned char *)newmap + newmap->size);
2435 }
2436
2437 newmap = new_affiliation->map;
2438 savedmap = instance->vf_affiliation->map;
2439
2440 for (i = 0 ; i < instance->vf_affiliation->ldCount; i++) {
2441 found = 0;
2442 for (j = 0 ; j < new_affiliation->ldCount; j++) {
2443 if (savedmap->ref.targetId ==
2444 newmap->ref.targetId) {
2445 found = 1;
2446 if (savedmap->policy[thisVf] !=
2447 newmap->policy[thisVf]) {
2448 doscan = 1;
2449 goto out;
2450 }
2451 }
adam radford229fe472014-03-10 02:51:56 -07002452 newmap = (struct MR_LD_VF_MAP *)
2453 ((unsigned char *)newmap +
2454 newmap->size);
2455 }
Adam Radford4cbfea82014-07-09 15:17:56 -07002456 if (!found && savedmap->policy[thisVf] !=
2457 MR_LD_ACCESS_HIDDEN) {
2458 doscan = 1;
2459 goto out;
2460 }
2461 savedmap = (struct MR_LD_VF_MAP *)
2462 ((unsigned char *)savedmap +
2463 savedmap->size);
adam radford229fe472014-03-10 02:51:56 -07002464 }
2465 }
2466out:
Adam Radford4cbfea82014-07-09 15:17:56 -07002467 if (doscan) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002468 dev_warn(&instance->pdev->dev, "SR-IOV: Got new LD/VF "
2469 "affiliation for scsi%d\n", instance->host->host_no);
Adam Radford4cbfea82014-07-09 15:17:56 -07002470 memcpy(instance->vf_affiliation, new_affiliation,
2471 new_affiliation->size);
2472 retval = 1;
adam radford229fe472014-03-10 02:51:56 -07002473 }
Adam Radford4cbfea82014-07-09 15:17:56 -07002474
2475 if (new_affiliation)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02002476 dma_free_coherent(&instance->pdev->dev,
Adam Radford4cbfea82014-07-09 15:17:56 -07002477 (MAX_LOGICAL_DRIVES + 1) *
2478 sizeof(struct MR_LD_VF_AFFILIATION),
2479 new_affiliation, new_affiliation_h);
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05302480 megasas_return_cmd(instance, cmd);
adam radford229fe472014-03-10 02:51:56 -07002481
2482 return retval;
2483}
2484
Adam Radford4cbfea82014-07-09 15:17:56 -07002485/* This function will get the current SR-IOV LD/VF affiliation */
2486static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
2487 int initial)
2488{
2489 int retval;
2490
2491 if (instance->PlasmaFW111)
2492 retval = megasas_get_ld_vf_affiliation_111(instance, initial);
2493 else
2494 retval = megasas_get_ld_vf_affiliation_12(instance, initial);
2495 return retval;
2496}
2497
adam radford229fe472014-03-10 02:51:56 -07002498/* This function will tell FW to start the SR-IOV heartbeat */
2499int megasas_sriov_start_heartbeat(struct megasas_instance *instance,
2500 int initial)
2501{
2502 struct megasas_cmd *cmd;
2503 struct megasas_dcmd_frame *dcmd;
2504 int retval = 0;
2505
2506 cmd = megasas_get_cmd(instance);
2507
2508 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002509 dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_sriov_start_heartbeat: "
2510 "Failed to get cmd for scsi%d\n",
adam radford229fe472014-03-10 02:51:56 -07002511 instance->host->host_no);
2512 return -ENOMEM;
2513 }
2514
2515 dcmd = &cmd->frame->dcmd;
2516
2517 if (initial) {
2518 instance->hb_host_mem =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02002519 dma_zalloc_coherent(&instance->pdev->dev,
Joe Perches7c845eb2014-08-08 14:24:46 -07002520 sizeof(struct MR_CTRL_HB_HOST_MEM),
Christoph Hellwig60ee6522018-10-10 19:31:25 +02002521 &instance->hb_host_mem_h, GFP_KERNEL);
adam radford229fe472014-03-10 02:51:56 -07002522 if (!instance->hb_host_mem) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002523 dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate"
2524 " memory for heartbeat host memory for scsi%d\n",
2525 instance->host->host_no);
adam radford229fe472014-03-10 02:51:56 -07002526 retval = -ENOMEM;
2527 goto out;
2528 }
adam radford229fe472014-03-10 02:51:56 -07002529 }
2530
2531 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2532
Christoph Hellwig2213a462015-04-23 16:33:54 +05302533 dcmd->mbox.s[0] = cpu_to_le16(sizeof(struct MR_CTRL_HB_HOST_MEM));
adam radford229fe472014-03-10 02:51:56 -07002534 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05302535 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
adam radford229fe472014-03-10 02:51:56 -07002536 dcmd->sge_count = 1;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302537 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_BOTH);
adam radford229fe472014-03-10 02:51:56 -07002538 dcmd->timeout = 0;
2539 dcmd->pad_0 = 0;
Christoph Hellwig2213a462015-04-23 16:33:54 +05302540 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_CTRL_HB_HOST_MEM));
2541 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC);
Shivasharan S107a60d2017-10-19 02:49:05 -07002542
2543 megasas_set_dma_settings(instance, dcmd, instance->hb_host_mem_h,
2544 sizeof(struct MR_CTRL_HB_HOST_MEM));
adam radford229fe472014-03-10 02:51:56 -07002545
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002546 dev_warn(&instance->pdev->dev, "SR-IOV: Starting heartbeat for scsi%d\n",
adam radford229fe472014-03-10 02:51:56 -07002547 instance->host->host_no);
2548
Shivasharan Se7d36b82017-10-19 02:48:50 -07002549 if ((instance->adapter_type != MFI_SERIES) &&
2550 !instance->mask_interrupts)
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05302551 retval = megasas_issue_blocked_cmd(instance, cmd,
2552 MEGASAS_ROUTINE_WAIT_TIME_VF);
2553 else
2554 retval = megasas_issue_polled(instance, cmd);
adam radford229fe472014-03-10 02:51:56 -07002555
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05302556 if (retval) {
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05302557 dev_warn(&instance->pdev->dev, "SR-IOV: MR_DCMD_CTRL_SHARED_HOST"
2558 "_MEM_ALLOC DCMD %s for scsi%d\n",
2559 (dcmd->cmd_status == MFI_STAT_INVALID_STATUS) ?
2560 "timed out" : "failed", instance->host->host_no);
adam radford229fe472014-03-10 02:51:56 -07002561 retval = 1;
adam radford229fe472014-03-10 02:51:56 -07002562 }
2563
2564out:
2565 megasas_return_cmd(instance, cmd);
2566
2567 return retval;
2568}
2569
2570/* Handler for SR-IOV heartbeat */
Kees Cookc251a7b2017-10-22 15:30:04 -07002571static void megasas_sriov_heartbeat_handler(struct timer_list *t)
adam radford229fe472014-03-10 02:51:56 -07002572{
2573 struct megasas_instance *instance =
Kees Cookc251a7b2017-10-22 15:30:04 -07002574 from_timer(instance, t, sriov_heartbeat_timer);
adam radford229fe472014-03-10 02:51:56 -07002575
2576 if (instance->hb_host_mem->HB.fwCounter !=
2577 instance->hb_host_mem->HB.driverCounter) {
2578 instance->hb_host_mem->HB.driverCounter =
2579 instance->hb_host_mem->HB.fwCounter;
2580 mod_timer(&instance->sriov_heartbeat_timer,
2581 jiffies + MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
2582 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002583 dev_warn(&instance->pdev->dev, "SR-IOV: Heartbeat never "
adam radford229fe472014-03-10 02:51:56 -07002584 "completed for scsi%d\n", instance->host->host_no);
2585 schedule_work(&instance->work_init);
2586 }
2587}
2588
bo yang7343eb62007-11-09 04:35:44 -05002589/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002590 * megasas_wait_for_outstanding - Wait for all outstanding cmds
2591 * @instance: Adapter soft state
2592 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002593 * This function waits for up to MEGASAS_RESET_WAIT_TIME seconds for FW to
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002594 * complete all its outstanding commands. Returns error if one or more IOs
2595 * are pending after this time period. It also marks the controller dead.
2596 */
2597static int megasas_wait_for_outstanding(struct megasas_instance *instance)
2598{
Sumit Saxenaccc75072016-01-28 21:04:33 +05302599 int i, sl, outstanding;
bo yang39a98552010-09-22 22:36:29 -04002600 u32 reset_index;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002601 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
bo yang39a98552010-09-22 22:36:29 -04002602 unsigned long flags;
2603 struct list_head clist_local;
2604 struct megasas_cmd *reset_cmd;
Yang, Bo707e09b2010-10-12 07:20:27 -06002605 u32 fw_state;
bo yang39a98552010-09-22 22:36:29 -04002606
Sumit Saxenaccc75072016-01-28 21:04:33 +05302607 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
2608 dev_info(&instance->pdev->dev, "%s:%d HBA is killed.\n",
2609 __func__, __LINE__);
2610 return FAILED;
2611 }
bo yang39a98552010-09-22 22:36:29 -04002612
Sumit Saxena8a01a412016-01-28 21:04:32 +05302613 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
bo yang39a98552010-09-22 22:36:29 -04002614
2615 INIT_LIST_HEAD(&clist_local);
2616 spin_lock_irqsave(&instance->hba_lock, flags);
2617 list_splice_init(&instance->internal_reset_pending_q,
2618 &clist_local);
2619 spin_unlock_irqrestore(&instance->hba_lock, flags);
2620
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002621 dev_notice(&instance->pdev->dev, "HBA reset wait ...\n");
bo yang39a98552010-09-22 22:36:29 -04002622 for (i = 0; i < wait_time; i++) {
2623 msleep(1000);
Sumit Saxena8a01a412016-01-28 21:04:32 +05302624 if (atomic_read(&instance->adprecovery) == MEGASAS_HBA_OPERATIONAL)
bo yang39a98552010-09-22 22:36:29 -04002625 break;
2626 }
2627
Sumit Saxena8a01a412016-01-28 21:04:32 +05302628 if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002629 dev_notice(&instance->pdev->dev, "reset: Stopping HBA.\n");
Sumit Saxena8a01a412016-01-28 21:04:32 +05302630 atomic_set(&instance->adprecovery, MEGASAS_HW_CRITICAL_ERROR);
bo yang39a98552010-09-22 22:36:29 -04002631 return FAILED;
2632 }
2633
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002634 reset_index = 0;
bo yang39a98552010-09-22 22:36:29 -04002635 while (!list_empty(&clist_local)) {
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002636 reset_cmd = list_entry((&clist_local)->next,
bo yang39a98552010-09-22 22:36:29 -04002637 struct megasas_cmd, list);
2638 list_del_init(&reset_cmd->list);
2639 if (reset_cmd->scmd) {
Shivasharan Sf55cf472017-02-10 00:59:07 -08002640 reset_cmd->scmd->result = DID_REQUEUE << 16;
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002641 dev_notice(&instance->pdev->dev, "%d:%p reset [%02x]\n",
bo yang39a98552010-09-22 22:36:29 -04002642 reset_index, reset_cmd,
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002643 reset_cmd->scmd->cmnd[0]);
bo yang39a98552010-09-22 22:36:29 -04002644
2645 reset_cmd->scmd->scsi_done(reset_cmd->scmd);
2646 megasas_return_cmd(instance, reset_cmd);
2647 } else if (reset_cmd->sync_cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002648 dev_notice(&instance->pdev->dev, "%p synch cmds"
bo yang39a98552010-09-22 22:36:29 -04002649 "reset queue\n",
2650 reset_cmd);
2651
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05302652 reset_cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
bo yang39a98552010-09-22 22:36:29 -04002653 instance->instancet->fire_cmd(instance,
2654 reset_cmd->frame_phys_addr,
2655 0, instance->reg_set);
2656 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002657 dev_notice(&instance->pdev->dev, "%p unexpected"
bo yang39a98552010-09-22 22:36:29 -04002658 "cmds lst\n",
2659 reset_cmd);
2660 }
2661 reset_index++;
2662 }
2663
2664 return SUCCESS;
2665 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002666
adam radfordc007b8b2012-07-17 18:20:24 -07002667 for (i = 0; i < resetwaittime; i++) {
Sumit Saxenaccc75072016-01-28 21:04:33 +05302668 outstanding = atomic_read(&instance->fw_outstanding);
Sumant Patroe4a082c2006-05-30 12:03:37 -07002669
2670 if (!outstanding)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002671 break;
2672
2673 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002674 dev_notice(&instance->pdev->dev, "[%2d]waiting for %d "
Sumant Patroe4a082c2006-05-30 12:03:37 -07002675 "commands to complete\n",i,outstanding);
bo yang7343eb62007-11-09 04:35:44 -05002676 /*
2677 * Call cmd completion routine. Cmd to be
2678 * be completed directly without depending on isr.
2679 */
2680 megasas_complete_cmd_dpc((unsigned long)instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002681 }
2682
2683 msleep(1000);
2684 }
2685
Yang, Bo707e09b2010-10-12 07:20:27 -06002686 i = 0;
Sumit Saxenaccc75072016-01-28 21:04:33 +05302687 outstanding = atomic_read(&instance->fw_outstanding);
2688 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
Yang, Bo707e09b2010-10-12 07:20:27 -06002689
Sumit Saxenaccc75072016-01-28 21:04:33 +05302690 if ((!outstanding && (fw_state == MFI_STATE_OPERATIONAL)))
2691 goto no_outstanding;
2692
2693 if (instance->disableOnlineCtrlReset)
2694 goto kill_hba_and_failed;
2695 do {
2696 if ((fw_state == MFI_STATE_FAULT) || atomic_read(&instance->fw_outstanding)) {
2697 dev_info(&instance->pdev->dev,
2698 "%s:%d waiting_for_outstanding: before issue OCR. FW state = 0x%x, oustanding 0x%x\n",
2699 __func__, __LINE__, fw_state, atomic_read(&instance->fw_outstanding));
2700 if (i == 3)
2701 goto kill_hba_and_failed;
2702 megasas_do_ocr(instance);
2703
2704 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
2705 dev_info(&instance->pdev->dev, "%s:%d OCR failed and HBA is killed.\n",
2706 __func__, __LINE__);
2707 return FAILED;
2708 }
2709 dev_info(&instance->pdev->dev, "%s:%d waiting_for_outstanding: after issue OCR.\n",
2710 __func__, __LINE__);
2711
2712 for (sl = 0; sl < 10; sl++)
2713 msleep(500);
2714
2715 outstanding = atomic_read(&instance->fw_outstanding);
2716
2717 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
2718 if ((!outstanding && (fw_state == MFI_STATE_OPERATIONAL)))
2719 goto no_outstanding;
Yang, Bo707e09b2010-10-12 07:20:27 -06002720 }
2721 i++;
2722 } while (i <= 3);
2723
Sumit Saxenaccc75072016-01-28 21:04:33 +05302724no_outstanding:
Yang, Bo707e09b2010-10-12 07:20:27 -06002725
Sumit Saxenaccc75072016-01-28 21:04:33 +05302726 dev_info(&instance->pdev->dev, "%s:%d no more pending commands remain after reset handling.\n",
2727 __func__, __LINE__);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002728 return SUCCESS;
Sumit Saxenaccc75072016-01-28 21:04:33 +05302729
2730kill_hba_and_failed:
2731
2732 /* Reset not supported, kill adapter */
2733 dev_info(&instance->pdev->dev, "%s:%d killing adapter scsi%d"
2734 " disableOnlineCtrlReset %d fw_outstanding %d \n",
2735 __func__, __LINE__, instance->host->host_no, instance->disableOnlineCtrlReset,
2736 atomic_read(&instance->fw_outstanding));
2737 megasas_dump_pending_frames(instance);
2738 megaraid_sas_kill_hba(instance);
2739
2740 return FAILED;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002741}
2742
2743/**
2744 * megasas_generic_reset - Generic reset routine
2745 * @scmd: Mid-layer SCSI command
2746 *
2747 * This routine implements a generic reset handler for device, bus and host
2748 * reset requests. Device, bus and host specific reset handlers can use this
2749 * function after they do their specific tasks.
2750 */
2751static int megasas_generic_reset(struct scsi_cmnd *scmd)
2752{
2753 int ret_val;
2754 struct megasas_instance *instance;
2755
2756 instance = (struct megasas_instance *)scmd->device->host->hostdata;
2757
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002758 scmd_printk(KERN_NOTICE, scmd, "megasas: RESET cmd=%x retries=%x\n",
2759 scmd->cmnd[0], scmd->retries);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002760
Sumit Saxena8a01a412016-01-28 21:04:32 +05302761 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002762 dev_err(&instance->pdev->dev, "cannot recover from previous reset failures\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002763 return FAILED;
2764 }
2765
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002766 ret_val = megasas_wait_for_outstanding(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002767 if (ret_val == SUCCESS)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002768 dev_notice(&instance->pdev->dev, "reset successful\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002769 else
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002770 dev_err(&instance->pdev->dev, "failed to do reset\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002771
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002772 return ret_val;
2773}
2774
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002775/**
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002776 * megasas_reset_timer - quiesce the adapter if required
2777 * @scmd: scsi cmnd
2778 *
2779 * Sets the FW busy flag and reduces the host->can_queue if the
2780 * cmd has not been completed within the timeout period.
2781 */
2782static enum
Jens Axboe242f9dc2008-09-14 05:55:09 -07002783blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002784{
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002785 struct megasas_instance *instance;
2786 unsigned long flags;
2787
2788 if (time_after(jiffies, scmd->jiffies_at_alloc +
Sumit Saxenae3d178c2016-01-28 21:04:34 +05302789 (scmd_timeout * 2) * HZ)) {
Christoph Hellwig66005932018-05-29 15:52:29 +02002790 return BLK_EH_DONE;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002791 }
2792
adam radfordf575c5d2011-10-13 16:01:12 -07002793 instance = (struct megasas_instance *)scmd->device->host->hostdata;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002794 if (!(instance->flag & MEGASAS_FW_BUSY)) {
2795 /* FW is busy, throttle IO */
2796 spin_lock_irqsave(instance->host->host_lock, flags);
2797
adam radfordc5daa6a2012-07-17 18:20:03 -07002798 instance->host->can_queue = instance->throttlequeuedepth;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002799 instance->last_time = jiffies;
2800 instance->flag |= MEGASAS_FW_BUSY;
2801
2802 spin_unlock_irqrestore(instance->host->host_lock, flags);
2803 }
Jens Axboe242f9dc2008-09-14 05:55:09 -07002804 return BLK_EH_RESET_TIMER;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002805}
2806
2807/**
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002808 * megasas_dump_frame - This function will dump MPT/MFI frame
2809 */
2810static inline void
2811megasas_dump_frame(void *mpi_request, int sz)
2812{
2813 int i;
2814 __le32 *mfp = (__le32 *)mpi_request;
2815
2816 printk(KERN_INFO "IO request frame:\n\t");
Dan Carpenter40a4c2c2017-02-14 19:38:55 +03002817 for (i = 0; i < sz / sizeof(__le32); i++) {
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002818 if (i && ((i % 8) == 0))
2819 printk("\n\t");
2820 printk("%08x ", le32_to_cpu(mfp[i]));
2821 }
2822 printk("\n");
2823}
2824
2825/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002826 * megasas_reset_bus_host - Bus & host reset handler entry point
2827 */
2828static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
2829{
2830 int ret;
adam radford9c915a82010-12-21 13:34:31 -08002831 struct megasas_instance *instance;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002832
adam radford9c915a82010-12-21 13:34:31 -08002833 instance = (struct megasas_instance *)scmd->device->host->hostdata;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002834
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002835 scmd_printk(KERN_INFO, scmd,
2836 "Controller reset is requested due to IO timeout\n"
2837 "SCSI command pointer: (%p)\t SCSI host state: %d\t"
2838 " SCSI host busy: %d\t FW outstanding: %d\n",
2839 scmd, scmd->device->host->shost_state,
Ming Leic84b0232018-06-24 22:03:26 +08002840 scsi_host_busy(scmd->device->host),
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002841 atomic_read(&instance->fw_outstanding));
2842
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002843 /*
Uwe Zeisberger80682fa2006-03-22 00:21:33 +01002844 * First wait for all commands to complete
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002845 */
Shivasharan Se7d36b82017-10-19 02:48:50 -07002846 if (instance->adapter_type == MFI_SERIES) {
2847 ret = megasas_generic_reset(scmd);
2848 } else {
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002849 struct megasas_cmd_fusion *cmd;
2850 cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr;
2851 if (cmd)
2852 megasas_dump_frame(cmd->io_request,
Shivasharan S5dd977e2017-08-23 04:47:07 -07002853 MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE);
Shivasharan Sdef0eab2017-02-10 00:59:15 -08002854 ret = megasas_reset_fusion(scmd->device->host,
2855 SCSIIO_TIMEOUT_OCR);
Shivasharan Se7d36b82017-10-19 02:48:50 -07002856 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002857
2858 return ret;
2859}
2860
2861/**
Sumit Saxenabd23d4a2016-04-15 00:23:32 -07002862 * megasas_task_abort - Issues task abort request to firmware
2863 * (supported only for fusion adapters)
2864 * @scmd: SCSI command pointer
2865 */
2866static int megasas_task_abort(struct scsi_cmnd *scmd)
2867{
2868 int ret;
2869 struct megasas_instance *instance;
2870
2871 instance = (struct megasas_instance *)scmd->device->host->hostdata;
2872
Shivasharan Se7d36b82017-10-19 02:48:50 -07002873 if (instance->adapter_type != MFI_SERIES)
Sumit Saxenabd23d4a2016-04-15 00:23:32 -07002874 ret = megasas_task_abort_fusion(scmd);
2875 else {
2876 sdev_printk(KERN_NOTICE, scmd->device, "TASK ABORT not supported\n");
2877 ret = FAILED;
2878 }
2879
2880 return ret;
2881}
2882
2883/**
2884 * megasas_reset_target: Issues target reset request to firmware
2885 * (supported only for fusion adapters)
2886 * @scmd: SCSI command pointer
2887 */
2888static int megasas_reset_target(struct scsi_cmnd *scmd)
2889{
2890 int ret;
2891 struct megasas_instance *instance;
2892
2893 instance = (struct megasas_instance *)scmd->device->host->hostdata;
2894
Shivasharan Se7d36b82017-10-19 02:48:50 -07002895 if (instance->adapter_type != MFI_SERIES)
Sumit Saxenabd23d4a2016-04-15 00:23:32 -07002896 ret = megasas_reset_target_fusion(scmd);
2897 else {
2898 sdev_printk(KERN_NOTICE, scmd->device, "TARGET RESET not supported\n");
2899 ret = FAILED;
2900 }
2901
2902 return ret;
2903}
2904
2905/**
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002906 * megasas_bios_param - Returns disk geometry for a disk
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002907 * @sdev: device handle
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002908 * @bdev: block device
2909 * @capacity: drive capacity
2910 * @geom: geometry parameters
2911 */
2912static int
2913megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
2914 sector_t capacity, int geom[])
2915{
2916 int heads;
2917 int sectors;
2918 sector_t cylinders;
2919 unsigned long tmp;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002920
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002921 /* Default heads (64) & sectors (32) */
2922 heads = 64;
2923 sectors = 32;
2924
2925 tmp = heads * sectors;
2926 cylinders = capacity;
2927
2928 sector_div(cylinders, tmp);
2929
2930 /*
2931 * Handle extended translation size for logical drives > 1Gb
2932 */
2933
2934 if (capacity >= 0x200000) {
2935 heads = 255;
2936 sectors = 63;
2937 tmp = heads*sectors;
2938 cylinders = capacity;
2939 sector_div(cylinders, tmp);
2940 }
2941
2942 geom[0] = heads;
2943 geom[1] = sectors;
2944 geom[2] = cylinders;
2945
2946 return 0;
2947}
2948
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002949static void megasas_aen_polling(struct work_struct *work);
2950
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002951/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002952 * megasas_service_aen - Processes an event notification
2953 * @instance: Adapter soft state
2954 * @cmd: AEN command completed by the ISR
2955 *
2956 * For AEN, driver sends a command down to FW that is held by the FW till an
2957 * event occurs. When an event of interest occurs, FW completes the command
2958 * that it was previously holding.
2959 *
2960 * This routines sends SIGIO signal to processes that have registered with the
2961 * driver for AEN.
2962 */
2963static void
2964megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
2965{
Yang, Boc3518832009-10-06 14:18:02 -06002966 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002967
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002968 /*
2969 * Don't signal app if it is just an aborted previously registered aen
2970 */
Yang, Boc3518832009-10-06 14:18:02 -06002971 if ((!cmd->abort_aen) && (instance->unload == 0)) {
2972 spin_lock_irqsave(&poll_aen_lock, flags);
2973 megasas_poll_wait_aen = 1;
2974 spin_unlock_irqrestore(&poll_aen_lock, flags);
2975 wake_up(&megasas_poll_wait);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002976 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
Yang, Boc3518832009-10-06 14:18:02 -06002977 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002978 else
2979 cmd->abort_aen = 0;
2980
2981 instance->aen_cmd = NULL;
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05302982
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05302983 megasas_return_cmd(instance, cmd);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002984
bo yang39a98552010-09-22 22:36:29 -04002985 if ((instance->unload == 0) &&
2986 ((instance->issuepend_done == 1))) {
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002987 struct megasas_aen_event *ev;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05002988
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002989 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2990 if (!ev) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05002991 dev_err(&instance->pdev->dev, "megasas_service_aen: out of memory\n");
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002992 } else {
2993 ev->instance = instance;
2994 instance->ev = ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08002995 INIT_DELAYED_WORK(&ev->hotplug_work,
2996 megasas_aen_polling);
2997 schedule_delayed_work(&ev->hotplug_work, 0);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002998 }
2999 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003000}
3001
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303002static ssize_t
3003megasas_fw_crash_buffer_store(struct device *cdev,
3004 struct device_attribute *attr, const char *buf, size_t count)
3005{
3006 struct Scsi_Host *shost = class_to_shost(cdev);
3007 struct megasas_instance *instance =
3008 (struct megasas_instance *) shost->hostdata;
3009 int val = 0;
3010 unsigned long flags;
3011
3012 if (kstrtoint(buf, 0, &val) != 0)
3013 return -EINVAL;
3014
3015 spin_lock_irqsave(&instance->crashdump_lock, flags);
3016 instance->fw_crash_buffer_offset = val;
3017 spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3018 return strlen(buf);
3019}
3020
3021static ssize_t
3022megasas_fw_crash_buffer_show(struct device *cdev,
3023 struct device_attribute *attr, char *buf)
3024{
3025 struct Scsi_Host *shost = class_to_shost(cdev);
3026 struct megasas_instance *instance =
3027 (struct megasas_instance *) shost->hostdata;
3028 u32 size;
3029 unsigned long buff_addr;
3030 unsigned long dmachunk = CRASH_DMA_BUF_SIZE;
3031 unsigned long src_addr;
3032 unsigned long flags;
3033 u32 buff_offset;
3034
3035 spin_lock_irqsave(&instance->crashdump_lock, flags);
3036 buff_offset = instance->fw_crash_buffer_offset;
3037 if (!instance->crash_dump_buf &&
3038 !((instance->fw_crash_state == AVAILABLE) ||
3039 (instance->fw_crash_state == COPYING))) {
3040 dev_err(&instance->pdev->dev,
3041 "Firmware crash dump is not available\n");
3042 spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3043 return -EINVAL;
3044 }
3045
3046 buff_addr = (unsigned long) buf;
3047
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003048 if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) {
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303049 dev_err(&instance->pdev->dev,
3050 "Firmware crash dump offset is out of range\n");
3051 spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3052 return 0;
3053 }
3054
3055 size = (instance->fw_crash_buffer_size * dmachunk) - buff_offset;
3056 size = (size >= PAGE_SIZE) ? (PAGE_SIZE - 1) : size;
3057
3058 src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] +
3059 (buff_offset % dmachunk);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003060 memcpy(buf, (void *)src_addr, size);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303061 spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3062
3063 return size;
3064}
3065
3066static ssize_t
3067megasas_fw_crash_buffer_size_show(struct device *cdev,
3068 struct device_attribute *attr, char *buf)
3069{
3070 struct Scsi_Host *shost = class_to_shost(cdev);
3071 struct megasas_instance *instance =
3072 (struct megasas_instance *) shost->hostdata;
3073
3074 return snprintf(buf, PAGE_SIZE, "%ld\n", (unsigned long)
3075 ((instance->fw_crash_buffer_size) * 1024 * 1024)/PAGE_SIZE);
3076}
3077
3078static ssize_t
3079megasas_fw_crash_state_store(struct device *cdev,
3080 struct device_attribute *attr, const char *buf, size_t count)
3081{
3082 struct Scsi_Host *shost = class_to_shost(cdev);
3083 struct megasas_instance *instance =
3084 (struct megasas_instance *) shost->hostdata;
3085 int val = 0;
3086 unsigned long flags;
3087
3088 if (kstrtoint(buf, 0, &val) != 0)
3089 return -EINVAL;
3090
3091 if ((val <= AVAILABLE || val > COPY_ERROR)) {
3092 dev_err(&instance->pdev->dev, "application updates invalid "
3093 "firmware crash state\n");
3094 return -EINVAL;
3095 }
3096
3097 instance->fw_crash_state = val;
3098
3099 if ((val == COPIED) || (val == COPY_ERROR)) {
3100 spin_lock_irqsave(&instance->crashdump_lock, flags);
3101 megasas_free_host_crash_buffer(instance);
3102 spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3103 if (val == COPY_ERROR)
3104 dev_info(&instance->pdev->dev, "application failed to "
3105 "copy Firmware crash dump\n");
3106 else
3107 dev_info(&instance->pdev->dev, "Firmware crash dump "
3108 "copied successfully\n");
3109 }
3110 return strlen(buf);
3111}
3112
3113static ssize_t
3114megasas_fw_crash_state_show(struct device *cdev,
3115 struct device_attribute *attr, char *buf)
3116{
3117 struct Scsi_Host *shost = class_to_shost(cdev);
3118 struct megasas_instance *instance =
3119 (struct megasas_instance *) shost->hostdata;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003120
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303121 return snprintf(buf, PAGE_SIZE, "%d\n", instance->fw_crash_state);
3122}
3123
3124static ssize_t
3125megasas_page_size_show(struct device *cdev,
3126 struct device_attribute *attr, char *buf)
3127{
3128 return snprintf(buf, PAGE_SIZE, "%ld\n", (unsigned long)PAGE_SIZE - 1);
3129}
3130
Sumit Saxena308ec452016-01-28 21:04:30 +05303131static ssize_t
3132megasas_ldio_outstanding_show(struct device *cdev, struct device_attribute *attr,
3133 char *buf)
3134{
3135 struct Scsi_Host *shost = class_to_shost(cdev);
3136 struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata;
3137
3138 return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&instance->ldio_outstanding));
3139}
3140
Shivasharan S88d155c2018-01-05 05:27:46 -08003141static ssize_t
3142megasas_fw_cmds_outstanding_show(struct device *cdev,
3143 struct device_attribute *attr, char *buf)
3144{
3145 struct Scsi_Host *shost = class_to_shost(cdev);
3146 struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata;
3147
3148 return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&instance->fw_outstanding));
3149}
3150
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303151static DEVICE_ATTR(fw_crash_buffer, S_IRUGO | S_IWUSR,
3152 megasas_fw_crash_buffer_show, megasas_fw_crash_buffer_store);
3153static DEVICE_ATTR(fw_crash_buffer_size, S_IRUGO,
3154 megasas_fw_crash_buffer_size_show, NULL);
3155static DEVICE_ATTR(fw_crash_state, S_IRUGO | S_IWUSR,
3156 megasas_fw_crash_state_show, megasas_fw_crash_state_store);
3157static DEVICE_ATTR(page_size, S_IRUGO,
3158 megasas_page_size_show, NULL);
Sumit Saxena308ec452016-01-28 21:04:30 +05303159static DEVICE_ATTR(ldio_outstanding, S_IRUGO,
3160 megasas_ldio_outstanding_show, NULL);
Shivasharan S88d155c2018-01-05 05:27:46 -08003161static DEVICE_ATTR(fw_cmds_outstanding, S_IRUGO,
3162 megasas_fw_cmds_outstanding_show, NULL);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303163
3164struct device_attribute *megaraid_host_attrs[] = {
3165 &dev_attr_fw_crash_buffer_size,
3166 &dev_attr_fw_crash_buffer,
3167 &dev_attr_fw_crash_state,
3168 &dev_attr_page_size,
Sumit Saxena308ec452016-01-28 21:04:30 +05303169 &dev_attr_ldio_outstanding,
Shivasharan S88d155c2018-01-05 05:27:46 -08003170 &dev_attr_fw_cmds_outstanding,
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303171 NULL,
3172};
3173
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003174/*
3175 * Scsi host template for megaraid_sas driver
3176 */
3177static struct scsi_host_template megasas_template = {
3178
3179 .module = THIS_MODULE,
Sumit.Saxena@avagotech.com43cd7fe2015-04-23 16:31:39 +05303180 .name = "Avago SAS based MegaRAID driver",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003181 .proc_name = "megaraid_sas",
Christoph Hellwig147aab62006-02-17 12:13:48 +01003182 .slave_configure = megasas_slave_configure,
Yang, Bo044833b2009-10-06 14:33:06 -06003183 .slave_alloc = megasas_slave_alloc,
Sumit Saxena18365b12016-01-28 21:04:25 +05303184 .slave_destroy = megasas_slave_destroy,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003185 .queuecommand = megasas_queue_command,
Sumit Saxenabd23d4a2016-04-15 00:23:32 -07003186 .eh_target_reset_handler = megasas_reset_target,
3187 .eh_abort_handler = megasas_task_abort,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003188 .eh_host_reset_handler = megasas_reset_bus_host,
Sumant Patro05e9ebb2007-05-17 05:47:51 -07003189 .eh_timed_out = megasas_reset_timer,
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05303190 .shost_attrs = megaraid_host_attrs,
Sumant Patrocf62a0a2007-02-14 12:41:55 -08003191 .bios_param = megasas_bios_param,
Christoph Hellwigdb5ed4d2014-11-13 15:08:42 +01003192 .change_queue_depth = scsi_change_queue_depth,
Martin K. Petersen54b2b502013-10-23 06:25:40 -04003193 .no_write_same = 1,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003194};
3195
3196/**
3197 * megasas_complete_int_cmd - Completes an internal command
3198 * @instance: Adapter soft state
3199 * @cmd: Command to be completed
3200 *
3201 * The megasas_issue_blocked_cmd() function waits for a command to complete
3202 * after it issues a command. This function wakes up that waiting routine by
3203 * calling wake_up() on the wait queue.
3204 */
3205static void
3206megasas_complete_int_cmd(struct megasas_instance *instance,
3207 struct megasas_cmd *cmd)
3208{
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05303209 cmd->cmd_status_drv = cmd->frame->io.cmd_status;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003210 wake_up(&instance->int_cmd_wait_q);
3211}
3212
3213/**
3214 * megasas_complete_abort - Completes aborting a command
3215 * @instance: Adapter soft state
3216 * @cmd: Cmd that was issued to abort another cmd
3217 *
adam radford0d490162010-12-14 19:17:17 -08003218 * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
3219 * after it issues an abort on a previously issued command. This function
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003220 * wakes up all functions waiting on the same wait queue.
3221 */
3222static void
3223megasas_complete_abort(struct megasas_instance *instance,
3224 struct megasas_cmd *cmd)
3225{
3226 if (cmd->sync_cmd) {
3227 cmd->sync_cmd = 0;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05303228 cmd->cmd_status_drv = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003229 wake_up(&instance->abort_cmd_wait_q);
3230 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003231}
3232
3233/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003234 * megasas_complete_cmd - Completes a command
3235 * @instance: Adapter soft state
3236 * @cmd: Command to be completed
adam radford0d490162010-12-14 19:17:17 -08003237 * @alt_status: If non-zero, use this value as status to
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003238 * SCSI mid-layer instead of the value returned
3239 * by the FW. This should be used if caller wants
3240 * an alternate status (as in the case of aborted
3241 * commands)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003242 */
adam radford9c915a82010-12-21 13:34:31 -08003243void
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003244megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
3245 u8 alt_status)
3246{
3247 int exception = 0;
3248 struct megasas_header *hdr = &cmd->frame->hdr;
Yang, Boc3518832009-10-06 14:18:02 -06003249 unsigned long flags;
adam radford9c915a82010-12-21 13:34:31 -08003250 struct fusion_context *fusion = instance->ctrl_context;
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05303251 u32 opcode, status;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003252
bo yang39a98552010-09-22 22:36:29 -04003253 /* flag for the retry reset */
3254 cmd->retry_for_fw_reset = 0;
3255
Sumant Patro05e9ebb2007-05-17 05:47:51 -07003256 if (cmd->scmd)
3257 cmd->scmd->SCp.ptr = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003258
3259 switch (hdr->cmd) {
adam radforde5f93a32011-10-08 18:15:19 -07003260 case MFI_CMD_INVALID:
3261 /* Some older 1068 controller FW may keep a pended
3262 MR_DCMD_CTRL_EVENT_GET_INFO left over from the main kernel
3263 when booting the kdump kernel. Ignore this command to
3264 prevent a kernel panic on shutdown of the kdump kernel. */
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003265 dev_warn(&instance->pdev->dev, "MFI_CMD_INVALID command "
3266 "completed\n");
3267 dev_warn(&instance->pdev->dev, "If you have a controller "
3268 "other than PERC5, please upgrade your firmware\n");
adam radforde5f93a32011-10-08 18:15:19 -07003269 break;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003270 case MFI_CMD_PD_SCSI_IO:
3271 case MFI_CMD_LD_SCSI_IO:
3272
3273 /*
3274 * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been
3275 * issued either through an IO path or an IOCTL path. If it
3276 * was via IOCTL, we will send it to internal completion.
3277 */
3278 if (cmd->sync_cmd) {
3279 cmd->sync_cmd = 0;
3280 megasas_complete_int_cmd(instance, cmd);
3281 break;
3282 }
Gustavo A. R. Silva8d07f7d2018-11-27 22:32:27 -06003283 /* fall through */
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003284
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003285 case MFI_CMD_LD_READ:
3286 case MFI_CMD_LD_WRITE:
3287
3288 if (alt_status) {
3289 cmd->scmd->result = alt_status << 16;
3290 exception = 1;
3291 }
3292
3293 if (exception) {
3294
Sumant Patroe4a082c2006-05-30 12:03:37 -07003295 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003296
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09003297 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003298 cmd->scmd->scsi_done(cmd->scmd);
3299 megasas_return_cmd(instance, cmd);
3300
3301 break;
3302 }
3303
3304 switch (hdr->cmd_status) {
3305
3306 case MFI_STAT_OK:
3307 cmd->scmd->result = DID_OK << 16;
3308 break;
3309
3310 case MFI_STAT_SCSI_IO_FAILED:
3311 case MFI_STAT_LD_INIT_IN_PROGRESS:
3312 cmd->scmd->result =
3313 (DID_ERROR << 16) | hdr->scsi_status;
3314 break;
3315
3316 case MFI_STAT_SCSI_DONE_WITH_ERROR:
3317
3318 cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status;
3319
3320 if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) {
3321 memset(cmd->scmd->sense_buffer, 0,
3322 SCSI_SENSE_BUFFERSIZE);
3323 memcpy(cmd->scmd->sense_buffer, cmd->sense,
3324 hdr->sense_len);
3325
3326 cmd->scmd->result |= DRIVER_SENSE << 24;
3327 }
3328
3329 break;
3330
3331 case MFI_STAT_LD_OFFLINE:
3332 case MFI_STAT_DEVICE_NOT_FOUND:
3333 cmd->scmd->result = DID_BAD_TARGET << 16;
3334 break;
3335
3336 default:
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003337 dev_printk(KERN_DEBUG, &instance->pdev->dev, "MFI FW status %#x\n",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003338 hdr->cmd_status);
3339 cmd->scmd->result = DID_ERROR << 16;
3340 break;
3341 }
3342
Sumant Patroe4a082c2006-05-30 12:03:37 -07003343 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003344
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09003345 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003346 cmd->scmd->scsi_done(cmd->scmd);
3347 megasas_return_cmd(instance, cmd);
3348
3349 break;
3350
3351 case MFI_CMD_SMP:
3352 case MFI_CMD_STP:
Shivasharan Sf870bcb2018-01-05 05:33:04 -08003353 case MFI_CMD_NVME:
Shivasharan S82add4e2017-10-19 02:49:02 -07003354 megasas_complete_int_cmd(instance, cmd);
3355 break;
3356
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003357 case MFI_CMD_DCMD:
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303358 opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
adam radford9c915a82010-12-21 13:34:31 -08003359 /* Check for LD map update */
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303360 if ((opcode == MR_DCMD_LD_MAP_GET_INFO)
3361 && (cmd->frame->dcmd.mbox.b[1] == 1)) {
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05303362 fusion->fast_path_io = 0;
adam radford9c915a82010-12-21 13:34:31 -08003363 spin_lock_irqsave(instance->host->host_lock, flags);
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003364 status = cmd->frame->hdr.cmd_status;
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05303365 instance->map_update_cmd = NULL;
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003366 if (status != MFI_STAT_OK) {
3367 if (status != MFI_STAT_NOT_FOUND)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003368 dev_warn(&instance->pdev->dev, "map syncfailed, status = 0x%x\n",
adam radford9c915a82010-12-21 13:34:31 -08003369 cmd->frame->hdr.cmd_status);
3370 else {
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05303371 megasas_return_cmd(instance, cmd);
adam radford9c915a82010-12-21 13:34:31 -08003372 spin_unlock_irqrestore(
3373 instance->host->host_lock,
3374 flags);
3375 break;
3376 }
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003377 }
3378
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05303379 megasas_return_cmd(instance, cmd);
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05303380
3381 /*
3382 * Set fast path IO to ZERO.
3383 * Validate Map will set proper value.
3384 * Meanwhile all IOs will go as LD IO.
3385 */
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003386 if (status == MFI_STAT_OK &&
3387 (MR_ValidateMapInfo(instance, (instance->map_id + 1)))) {
3388 instance->map_id++;
adam radford9c915a82010-12-21 13:34:31 -08003389 fusion->fast_path_io = 1;
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003390 } else {
adam radford9c915a82010-12-21 13:34:31 -08003391 fusion->fast_path_io = 0;
Shivasharan S5f19f7c2018-01-05 05:27:44 -08003392 }
3393
adam radford9c915a82010-12-21 13:34:31 -08003394 megasas_sync_map_info(instance);
3395 spin_unlock_irqrestore(instance->host->host_lock,
3396 flags);
3397 break;
3398 }
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303399 if (opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
3400 opcode == MR_DCMD_CTRL_EVENT_GET) {
Yang, Boc3518832009-10-06 14:18:02 -06003401 spin_lock_irqsave(&poll_aen_lock, flags);
3402 megasas_poll_wait_aen = 0;
3403 spin_unlock_irqrestore(&poll_aen_lock, flags);
3404 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003405
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05303406 /* FW has an updated PD sequence */
3407 if ((opcode == MR_DCMD_SYSTEM_PD_MAP_GET_INFO) &&
3408 (cmd->frame->dcmd.mbox.b[0] == 1)) {
3409
3410 spin_lock_irqsave(instance->host->host_lock, flags);
3411 status = cmd->frame->hdr.cmd_status;
3412 instance->jbod_seq_cmd = NULL;
3413 megasas_return_cmd(instance, cmd);
3414
3415 if (status == MFI_STAT_OK) {
3416 instance->pd_seq_map_id++;
3417 /* Re-register a pd sync seq num cmd */
3418 if (megasas_sync_pd_seq_num(instance, true))
3419 instance->use_seqnum_jbod_fp = false;
3420 } else
3421 instance->use_seqnum_jbod_fp = false;
3422
3423 spin_unlock_irqrestore(instance->host->host_lock, flags);
3424 break;
3425 }
3426
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003427 /*
3428 * See if got an event notification
3429 */
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303430 if (opcode == MR_DCMD_CTRL_EVENT_WAIT)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003431 megasas_service_aen(instance, cmd);
3432 else
3433 megasas_complete_int_cmd(instance, cmd);
3434
3435 break;
3436
3437 case MFI_CMD_ABORT:
3438 /*
3439 * Cmd issued to abort another cmd returned
3440 */
3441 megasas_complete_abort(instance, cmd);
3442 break;
3443
3444 default:
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003445 dev_info(&instance->pdev->dev, "Unknown command completed! [0x%X]\n",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003446 hdr->cmd);
Shivasharan S82add4e2017-10-19 02:49:02 -07003447 megasas_complete_int_cmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003448 break;
3449 }
3450}
3451
3452/**
bo yang39a98552010-09-22 22:36:29 -04003453 * megasas_issue_pending_cmds_again - issue all pending cmds
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003454 * in FW again because of the fw reset
bo yang39a98552010-09-22 22:36:29 -04003455 * @instance: Adapter soft state
3456 */
3457static inline void
3458megasas_issue_pending_cmds_again(struct megasas_instance *instance)
3459{
3460 struct megasas_cmd *cmd;
3461 struct list_head clist_local;
3462 union megasas_evt_class_locale class_locale;
3463 unsigned long flags;
3464 u32 seq_num;
3465
3466 INIT_LIST_HEAD(&clist_local);
3467 spin_lock_irqsave(&instance->hba_lock, flags);
3468 list_splice_init(&instance->internal_reset_pending_q, &clist_local);
3469 spin_unlock_irqrestore(&instance->hba_lock, flags);
3470
3471 while (!list_empty(&clist_local)) {
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003472 cmd = list_entry((&clist_local)->next,
bo yang39a98552010-09-22 22:36:29 -04003473 struct megasas_cmd, list);
3474 list_del_init(&cmd->list);
3475
3476 if (cmd->sync_cmd || cmd->scmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003477 dev_notice(&instance->pdev->dev, "command %p, %p:%d"
3478 "detected to be pending while HBA reset\n",
bo yang39a98552010-09-22 22:36:29 -04003479 cmd, cmd->scmd, cmd->sync_cmd);
3480
3481 cmd->retry_for_fw_reset++;
3482
3483 if (cmd->retry_for_fw_reset == 3) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003484 dev_notice(&instance->pdev->dev, "cmd %p, %p:%d"
bo yang39a98552010-09-22 22:36:29 -04003485 "was tried multiple times during reset."
3486 "Shutting down the HBA\n",
3487 cmd, cmd->scmd, cmd->sync_cmd);
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05303488 instance->instancet->disable_intr(instance);
3489 atomic_set(&instance->fw_reset_no_pci_access, 1);
bo yang39a98552010-09-22 22:36:29 -04003490 megaraid_sas_kill_hba(instance);
bo yang39a98552010-09-22 22:36:29 -04003491 return;
3492 }
3493 }
3494
3495 if (cmd->sync_cmd == 1) {
3496 if (cmd->scmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003497 dev_notice(&instance->pdev->dev, "unexpected"
bo yang39a98552010-09-22 22:36:29 -04003498 "cmd attached to internal command!\n");
3499 }
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003500 dev_notice(&instance->pdev->dev, "%p synchronous cmd"
bo yang39a98552010-09-22 22:36:29 -04003501 "on the internal reset queue,"
3502 "issue it again.\n", cmd);
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05303503 cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
bo yang39a98552010-09-22 22:36:29 -04003504 instance->instancet->fire_cmd(instance,
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003505 cmd->frame_phys_addr,
bo yang39a98552010-09-22 22:36:29 -04003506 0, instance->reg_set);
3507 } else if (cmd->scmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003508 dev_notice(&instance->pdev->dev, "%p scsi cmd [%02x]"
bo yang39a98552010-09-22 22:36:29 -04003509 "detected on the internal queue, issue again.\n",
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04003510 cmd, cmd->scmd->cmnd[0]);
bo yang39a98552010-09-22 22:36:29 -04003511
3512 atomic_inc(&instance->fw_outstanding);
3513 instance->instancet->fire_cmd(instance,
3514 cmd->frame_phys_addr,
3515 cmd->frame_count-1, instance->reg_set);
3516 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003517 dev_notice(&instance->pdev->dev, "%p unexpected cmd on the"
bo yang39a98552010-09-22 22:36:29 -04003518 "internal reset defer list while re-issue!!\n",
3519 cmd);
3520 }
3521 }
3522
3523 if (instance->aen_cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003524 dev_notice(&instance->pdev->dev, "aen_cmd in def process\n");
bo yang39a98552010-09-22 22:36:29 -04003525 megasas_return_cmd(instance, instance->aen_cmd);
3526
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003527 instance->aen_cmd = NULL;
bo yang39a98552010-09-22 22:36:29 -04003528 }
3529
3530 /*
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003531 * Initiate AEN (Asynchronous Event Notification)
3532 */
bo yang39a98552010-09-22 22:36:29 -04003533 seq_num = instance->last_seq_num;
3534 class_locale.members.reserved = 0;
3535 class_locale.members.locale = MR_EVT_LOCALE_ALL;
3536 class_locale.members.class = MR_EVT_CLASS_DEBUG;
3537
3538 megasas_register_aen(instance, seq_num, class_locale.word);
3539}
3540
3541/**
3542 * Move the internal reset pending commands to a deferred queue.
3543 *
3544 * We move the commands pending at internal reset time to a
3545 * pending queue. This queue would be flushed after successful
3546 * completion of the internal reset sequence. if the internal reset
3547 * did not complete in time, the kernel reset handler would flush
3548 * these commands.
3549 **/
3550static void
3551megasas_internal_reset_defer_cmds(struct megasas_instance *instance)
3552{
3553 struct megasas_cmd *cmd;
3554 int i;
Shivasharan S50b7f5a2017-02-10 00:59:25 -08003555 u16 max_cmd = instance->max_fw_cmds;
bo yang39a98552010-09-22 22:36:29 -04003556 u32 defer_index;
3557 unsigned long flags;
3558
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003559 defer_index = 0;
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05303560 spin_lock_irqsave(&instance->mfi_pool_lock, flags);
bo yang39a98552010-09-22 22:36:29 -04003561 for (i = 0; i < max_cmd; i++) {
3562 cmd = instance->cmd_list[i];
3563 if (cmd->sync_cmd == 1 || cmd->scmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003564 dev_notice(&instance->pdev->dev, "moving cmd[%d]:%p:%d:%p"
bo yang39a98552010-09-22 22:36:29 -04003565 "on the defer queue as internal\n",
3566 defer_index, cmd, cmd->sync_cmd, cmd->scmd);
3567
3568 if (!list_empty(&cmd->list)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003569 dev_notice(&instance->pdev->dev, "ERROR while"
bo yang39a98552010-09-22 22:36:29 -04003570 " moving this cmd:%p, %d %p, it was"
3571 "discovered on some list?\n",
3572 cmd, cmd->sync_cmd, cmd->scmd);
3573
3574 list_del_init(&cmd->list);
3575 }
3576 defer_index++;
3577 list_add_tail(&cmd->list,
3578 &instance->internal_reset_pending_q);
3579 }
3580 }
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05303581 spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
bo yang39a98552010-09-22 22:36:29 -04003582}
3583
3584
3585static void
3586process_fw_state_change_wq(struct work_struct *work)
3587{
3588 struct megasas_instance *instance =
3589 container_of(work, struct megasas_instance, work_init);
3590 u32 wait;
3591 unsigned long flags;
3592
Sumit Saxena8a01a412016-01-28 21:04:32 +05303593 if (atomic_read(&instance->adprecovery) != MEGASAS_ADPRESET_SM_INFAULT) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003594 dev_notice(&instance->pdev->dev, "error, recovery st %x\n",
Sumit Saxena8a01a412016-01-28 21:04:32 +05303595 atomic_read(&instance->adprecovery));
bo yang39a98552010-09-22 22:36:29 -04003596 return ;
3597 }
3598
Sumit Saxena8a01a412016-01-28 21:04:32 +05303599 if (atomic_read(&instance->adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003600 dev_notice(&instance->pdev->dev, "FW detected to be in fault"
bo yang39a98552010-09-22 22:36:29 -04003601 "state, restarting it...\n");
3602
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303603 instance->instancet->disable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04003604 atomic_set(&instance->fw_outstanding, 0);
3605
3606 atomic_set(&instance->fw_reset_no_pci_access, 1);
3607 instance->instancet->adp_reset(instance, instance->reg_set);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003608 atomic_set(&instance->fw_reset_no_pci_access, 0);
bo yang39a98552010-09-22 22:36:29 -04003609
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003610 dev_notice(&instance->pdev->dev, "FW restarted successfully,"
bo yang39a98552010-09-22 22:36:29 -04003611 "initiating next stage...\n");
3612
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003613 dev_notice(&instance->pdev->dev, "HBA recovery state machine,"
bo yang39a98552010-09-22 22:36:29 -04003614 "state 2 starting...\n");
3615
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003616 /* waiting for about 20 second before start the second init */
bo yang39a98552010-09-22 22:36:29 -04003617 for (wait = 0; wait < 30; wait++) {
3618 msleep(1000);
3619 }
3620
adam radford058a8fa2011-10-08 18:14:27 -07003621 if (megasas_transition_to_ready(instance, 1)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003622 dev_notice(&instance->pdev->dev, "adapter not ready\n");
bo yang39a98552010-09-22 22:36:29 -04003623
Sumit.Saxena@avagotech.comc8dd61e2015-01-05 20:06:18 +05303624 atomic_set(&instance->fw_reset_no_pci_access, 1);
bo yang39a98552010-09-22 22:36:29 -04003625 megaraid_sas_kill_hba(instance);
bo yang39a98552010-09-22 22:36:29 -04003626 return ;
3627 }
3628
3629 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
3630 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
3631 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)
3632 ) {
3633 *instance->consumer = *instance->producer;
3634 } else {
3635 *instance->consumer = 0;
3636 *instance->producer = 0;
3637 }
3638
3639 megasas_issue_init_mfi(instance);
3640
3641 spin_lock_irqsave(&instance->hba_lock, flags);
Sumit Saxena8a01a412016-01-28 21:04:32 +05303642 atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
bo yang39a98552010-09-22 22:36:29 -04003643 spin_unlock_irqrestore(&instance->hba_lock, flags);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303644 instance->instancet->enable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04003645
3646 megasas_issue_pending_cmds_again(instance);
3647 instance->issuepend_done = 1;
3648 }
bo yang39a98552010-09-22 22:36:29 -04003649}
3650
3651/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003652 * megasas_deplete_reply_queue - Processes all completed commands
3653 * @instance: Adapter soft state
3654 * @alt_status: Alternate status to be returned to
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003655 * SCSI mid-layer instead of the status
3656 * returned by the FW
bo yang39a98552010-09-22 22:36:29 -04003657 * Note: this must be called with hba lock held
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003658 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08003659static int
bo yang39a98552010-09-22 22:36:29 -04003660megasas_deplete_reply_queue(struct megasas_instance *instance,
3661 u8 alt_status)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003662{
bo yang39a98552010-09-22 22:36:29 -04003663 u32 mfiStatus;
3664 u32 fw_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003665
bo yang39a98552010-09-22 22:36:29 -04003666 if ((mfiStatus = instance->instancet->check_reset(instance,
3667 instance->reg_set)) == 1) {
3668 return IRQ_HANDLED;
3669 }
3670
3671 if ((mfiStatus = instance->instancet->clear_intr(
3672 instance->reg_set)
3673 ) == 0) {
adam radforde1419192011-02-24 20:56:21 -08003674 /* Hardware may not set outbound_intr_status in MSI-X mode */
adam radfordc8e858f2011-10-08 18:15:13 -07003675 if (!instance->msix_vectors)
adam radforde1419192011-02-24 20:56:21 -08003676 return IRQ_NONE;
bo yang39a98552010-09-22 22:36:29 -04003677 }
3678
3679 instance->mfiStatus = mfiStatus;
3680
3681 if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) {
3682 fw_state = instance->instancet->read_fw_status_reg(
3683 instance->reg_set) & MFI_STATE_MASK;
3684
3685 if (fw_state != MFI_STATE_FAULT) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003686 dev_notice(&instance->pdev->dev, "fw state:%x\n",
bo yang39a98552010-09-22 22:36:29 -04003687 fw_state);
3688 }
3689
3690 if ((fw_state == MFI_STATE_FAULT) &&
3691 (instance->disableOnlineCtrlReset == 0)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003692 dev_notice(&instance->pdev->dev, "wait adp restart\n");
bo yang39a98552010-09-22 22:36:29 -04003693
3694 if ((instance->pdev->device ==
3695 PCI_DEVICE_ID_LSI_SAS1064R) ||
3696 (instance->pdev->device ==
3697 PCI_DEVICE_ID_DELL_PERC5) ||
3698 (instance->pdev->device ==
3699 PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
3700
3701 *instance->consumer =
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303702 cpu_to_le32(MEGASAS_ADPRESET_INPROG_SIGN);
bo yang39a98552010-09-22 22:36:29 -04003703 }
3704
3705
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303706 instance->instancet->disable_intr(instance);
Sumit Saxena8a01a412016-01-28 21:04:32 +05303707 atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_INFAULT);
bo yang39a98552010-09-22 22:36:29 -04003708 instance->issuepend_done = 0;
3709
3710 atomic_set(&instance->fw_outstanding, 0);
3711 megasas_internal_reset_defer_cmds(instance);
3712
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003713 dev_notice(&instance->pdev->dev, "fwState=%x, stage:%d\n",
Sumit Saxena8a01a412016-01-28 21:04:32 +05303714 fw_state, atomic_read(&instance->adprecovery));
bo yang39a98552010-09-22 22:36:29 -04003715
3716 schedule_work(&instance->work_init);
3717 return IRQ_HANDLED;
3718
3719 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003720 dev_notice(&instance->pdev->dev, "fwstate:%x, dis_OCR=%x\n",
bo yang39a98552010-09-22 22:36:29 -04003721 fw_state, instance->disableOnlineCtrlReset);
3722 }
3723 }
3724
Sumant Patro5d018ad2006-10-03 13:13:18 -07003725 tasklet_schedule(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003726 return IRQ_HANDLED;
3727}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003728/**
3729 * megasas_isr - isr entry point
3730 */
David Howells7d12e782006-10-05 14:55:46 +01003731static irqreturn_t megasas_isr(int irq, void *devp)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003732{
adam radfordc8e858f2011-10-08 18:15:13 -07003733 struct megasas_irq_context *irq_context = devp;
3734 struct megasas_instance *instance = irq_context->instance;
bo yang39a98552010-09-22 22:36:29 -04003735 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003736 irqreturn_t rc;
bo yang39a98552010-09-22 22:36:29 -04003737
adam radfordc8e858f2011-10-08 18:15:13 -07003738 if (atomic_read(&instance->fw_reset_no_pci_access))
bo yang39a98552010-09-22 22:36:29 -04003739 return IRQ_HANDLED;
3740
bo yang39a98552010-09-22 22:36:29 -04003741 spin_lock_irqsave(&instance->hba_lock, flags);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003742 rc = megasas_deplete_reply_queue(instance, DID_OK);
bo yang39a98552010-09-22 22:36:29 -04003743 spin_unlock_irqrestore(&instance->hba_lock, flags);
3744
3745 return rc;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003746}
3747
3748/**
3749 * megasas_transition_to_ready - Move the FW to READY state
Sumant Patro1341c932006-01-25 12:02:40 -08003750 * @instance: Adapter soft state
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003751 *
3752 * During the initialization, FW passes can potentially be in any one of
3753 * several possible states. If the FW in operational, waiting-for-handshake
3754 * states, driver must take steps to bring it to ready state. Otherwise, it
3755 * has to wait for the ready state.
3756 */
adam radford9c915a82010-12-21 13:34:31 -08003757int
adam radford058a8fa2011-10-08 18:14:27 -07003758megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003759{
3760 int i;
3761 u8 max_wait;
3762 u32 fw_state;
3763 u32 cur_state;
Yang, Bo7218df62009-10-06 14:52:20 -06003764 u32 abs_state, curr_abs_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003765
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02003766 abs_state = instance->instancet->read_fw_status_reg(instance->reg_set);
3767 fw_state = abs_state & MFI_STATE_MASK;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003768
Sumant Patroe3bbff92006-10-03 12:28:49 -07003769 if (fw_state != MFI_STATE_READY)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003770 dev_info(&instance->pdev->dev, "Waiting for FW to come to ready"
adam radford0d490162010-12-14 19:17:17 -08003771 " state\n");
Sumant Patroe3bbff92006-10-03 12:28:49 -07003772
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003773 while (fw_state != MFI_STATE_READY) {
3774
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003775 switch (fw_state) {
3776
3777 case MFI_STATE_FAULT:
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003778 dev_printk(KERN_DEBUG, &instance->pdev->dev, "FW in FAULT state!!\n");
adam radford058a8fa2011-10-08 18:14:27 -07003779 if (ocr) {
3780 max_wait = MEGASAS_RESET_WAIT_TIME;
3781 cur_state = MFI_STATE_FAULT;
3782 break;
3783 } else
3784 return -ENODEV;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003785
3786 case MFI_STATE_WAIT_HANDSHAKE:
3787 /*
3788 * Set the CLR bit in inbound doorbell
3789 */
Yang, Bo0c79e682009-10-06 14:47:35 -06003790 if ((instance->pdev->device ==
Yang, Bo87911122009-10-06 14:31:54 -06003791 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3792 (instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003793 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
Shivasharan Se7d36b82017-10-19 02:48:50 -07003794 (instance->adapter_type != MFI_SERIES))
Yang, Bo87911122009-10-06 14:31:54 -06003795 writel(
3796 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
adam radford9c915a82010-12-21 13:34:31 -08003797 &instance->reg_set->doorbell);
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05303798 else
Yang, Bo87911122009-10-06 14:31:54 -06003799 writel(
3800 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
3801 &instance->reg_set->inbound_doorbell);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003802
Yang, Bo7218df62009-10-06 14:52:20 -06003803 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003804 cur_state = MFI_STATE_WAIT_HANDSHAKE;
3805 break;
3806
Sumant Patroe3bbff92006-10-03 12:28:49 -07003807 case MFI_STATE_BOOT_MESSAGE_PENDING:
Yang, Bo87911122009-10-06 14:31:54 -06003808 if ((instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003809 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3810 (instance->pdev->device ==
3811 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
Shivasharan Se7d36b82017-10-19 02:48:50 -07003812 (instance->adapter_type != MFI_SERIES))
Yang, Bo87911122009-10-06 14:31:54 -06003813 writel(MFI_INIT_HOTPLUG,
adam radford9c915a82010-12-21 13:34:31 -08003814 &instance->reg_set->doorbell);
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05303815 else
Yang, Bo87911122009-10-06 14:31:54 -06003816 writel(MFI_INIT_HOTPLUG,
3817 &instance->reg_set->inbound_doorbell);
Sumant Patroe3bbff92006-10-03 12:28:49 -07003818
Yang, Bo7218df62009-10-06 14:52:20 -06003819 max_wait = MEGASAS_RESET_WAIT_TIME;
Sumant Patroe3bbff92006-10-03 12:28:49 -07003820 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
3821 break;
3822
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003823 case MFI_STATE_OPERATIONAL:
3824 /*
Sumant Patroe3bbff92006-10-03 12:28:49 -07003825 * Bring it to READY state; assuming max wait 10 secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003826 */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303827 instance->instancet->disable_intr(instance);
Yang, Bo87911122009-10-06 14:31:54 -06003828 if ((instance->pdev->device ==
3829 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3830 (instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003831 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
Shivasharan Se7d36b82017-10-19 02:48:50 -07003832 (instance->adapter_type != MFI_SERIES)) {
Yang, Bo87911122009-10-06 14:31:54 -06003833 writel(MFI_RESET_FLAGS,
adam radford9c915a82010-12-21 13:34:31 -08003834 &instance->reg_set->doorbell);
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05303835
Shivasharan Se7d36b82017-10-19 02:48:50 -07003836 if (instance->adapter_type != MFI_SERIES) {
adam radford9c915a82010-12-21 13:34:31 -08003837 for (i = 0; i < (10 * 1000); i += 20) {
3838 if (readl(
3839 &instance->
3840 reg_set->
3841 doorbell) & 1)
3842 msleep(20);
3843 else
3844 break;
3845 }
3846 }
Yang, Bo87911122009-10-06 14:31:54 -06003847 } else
3848 writel(MFI_RESET_FLAGS,
3849 &instance->reg_set->inbound_doorbell);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003850
Yang, Bo7218df62009-10-06 14:52:20 -06003851 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003852 cur_state = MFI_STATE_OPERATIONAL;
3853 break;
3854
3855 case MFI_STATE_UNDEFINED:
3856 /*
3857 * This state should not last for more than 2 seconds
3858 */
Yang, Bo7218df62009-10-06 14:52:20 -06003859 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003860 cur_state = MFI_STATE_UNDEFINED;
3861 break;
3862
3863 case MFI_STATE_BB_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06003864 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003865 cur_state = MFI_STATE_BB_INIT;
3866 break;
3867
3868 case MFI_STATE_FW_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06003869 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003870 cur_state = MFI_STATE_FW_INIT;
3871 break;
3872
3873 case MFI_STATE_FW_INIT_2:
Yang, Bo7218df62009-10-06 14:52:20 -06003874 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003875 cur_state = MFI_STATE_FW_INIT_2;
3876 break;
3877
3878 case MFI_STATE_DEVICE_SCAN:
Yang, Bo7218df62009-10-06 14:52:20 -06003879 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003880 cur_state = MFI_STATE_DEVICE_SCAN;
3881 break;
3882
3883 case MFI_STATE_FLUSH_CACHE:
Yang, Bo7218df62009-10-06 14:52:20 -06003884 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003885 cur_state = MFI_STATE_FLUSH_CACHE;
3886 break;
3887
3888 default:
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003889 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Unknown state 0x%x\n",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003890 fw_state);
3891 return -ENODEV;
3892 }
3893
3894 /*
3895 * The cur_state should not last for more than max_wait secs
3896 */
Shivasharan S9155cf32018-10-16 23:37:41 -07003897 for (i = 0; i < max_wait; i++) {
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02003898 curr_abs_state = instance->instancet->
3899 read_fw_status_reg(instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003900
Yang, Bo7218df62009-10-06 14:52:20 -06003901 if (abs_state == curr_abs_state) {
Shivasharan S9155cf32018-10-16 23:37:41 -07003902 msleep(1000);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003903 } else
3904 break;
3905 }
3906
3907 /*
3908 * Return error if fw_state hasn't changed after max_wait
3909 */
Yang, Bo7218df62009-10-06 14:52:20 -06003910 if (curr_abs_state == abs_state) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003911 dev_printk(KERN_DEBUG, &instance->pdev->dev, "FW state [%d] hasn't changed "
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003912 "in %d secs\n", fw_state, max_wait);
3913 return -ENODEV;
3914 }
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02003915
3916 abs_state = curr_abs_state;
3917 fw_state = curr_abs_state & MFI_STATE_MASK;
bo yang39a98552010-09-22 22:36:29 -04003918 }
Bjorn Helgaas1be18252015-07-07 15:52:34 -05003919 dev_info(&instance->pdev->dev, "FW now in Ready state\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003920
3921 return 0;
3922}
3923
3924/**
3925 * megasas_teardown_frame_pool - Destroy the cmd frame DMA pool
3926 * @instance: Adapter soft state
3927 */
3928static void megasas_teardown_frame_pool(struct megasas_instance *instance)
3929{
3930 int i;
Shivasharan S50b7f5a2017-02-10 00:59:25 -08003931 u16 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003932 struct megasas_cmd *cmd;
3933
3934 if (!instance->frame_dma_pool)
3935 return;
3936
3937 /*
3938 * Return all frames to pool
3939 */
3940 for (i = 0; i < max_cmd; i++) {
3941
3942 cmd = instance->cmd_list[i];
3943
3944 if (cmd->frame)
Romain Perierfc69d862017-07-06 10:13:06 +02003945 dma_pool_free(instance->frame_dma_pool, cmd->frame,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003946 cmd->frame_phys_addr);
3947
3948 if (cmd->sense)
Romain Perierfc69d862017-07-06 10:13:06 +02003949 dma_pool_free(instance->sense_dma_pool, cmd->sense,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003950 cmd->sense_phys_addr);
3951 }
3952
3953 /*
3954 * Now destroy the pool itself
3955 */
Romain Perierfc69d862017-07-06 10:13:06 +02003956 dma_pool_destroy(instance->frame_dma_pool);
3957 dma_pool_destroy(instance->sense_dma_pool);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003958
3959 instance->frame_dma_pool = NULL;
3960 instance->sense_dma_pool = NULL;
3961}
3962
3963/**
3964 * megasas_create_frame_pool - Creates DMA pool for cmd frames
3965 * @instance: Adapter soft state
3966 *
3967 * Each command packet has an embedded DMA memory buffer that is used for
3968 * filling MFI frame and the SG list that immediately follows the frame. This
3969 * function creates those DMA memory buffers for each command packet by using
3970 * PCI pool facility.
3971 */
3972static int megasas_create_frame_pool(struct megasas_instance *instance)
3973{
3974 int i;
Shivasharan S50b7f5a2017-02-10 00:59:25 -08003975 u16 max_cmd;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003976 u32 sge_sz;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003977 u32 frame_count;
3978 struct megasas_cmd *cmd;
3979
adam radford9c915a82010-12-21 13:34:31 -08003980 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003981
3982 /*
3983 * Size of our frame is 64 bytes for MFI frame, followed by max SG
3984 * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer
3985 */
3986 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
3987 sizeof(struct megasas_sge32);
3988
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05003989 if (instance->flag_ieee)
Yang, Bof4c9a132009-10-06 14:43:28 -06003990 sge_sz = sizeof(struct megasas_sge_skinny);
Yang, Bof4c9a132009-10-06 14:43:28 -06003991
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003992 /*
Sumit.Saxena@avagotech.com200aed52015-01-05 20:05:58 +05303993 * For MFI controllers.
3994 * max_num_sge = 60
3995 * max_sge_sz = 16 byte (sizeof megasas_sge_skinny)
3996 * Total 960 byte (15 MFI frame of 64 byte)
3997 *
3998 * Fusion adapter require only 3 extra frame.
3999 * max_num_sge = 16 (defined as MAX_IOCTL_SGE)
4000 * max_sge_sz = 12 byte (sizeof megasas_sge64)
4001 * Total 192 byte (3 MFI frame of 64 byte)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004002 */
Shivasharan Se7d36b82017-10-19 02:48:50 -07004003 frame_count = (instance->adapter_type == MFI_SERIES) ?
4004 (15 + 1) : (3 + 1);
Shivasharan S21c34002017-02-10 00:59:28 -08004005 instance->mfi_frame_size = MEGAMFI_FRAME_SIZE * frame_count;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004006 /*
4007 * Use DMA pool facility provided by PCI layer
4008 */
Romain Perierfc69d862017-07-06 10:13:06 +02004009 instance->frame_dma_pool = dma_pool_create("megasas frame pool",
4010 &instance->pdev->dev,
4011 instance->mfi_frame_size, 256, 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004012
4013 if (!instance->frame_dma_pool) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004014 dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup frame pool\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004015 return -ENOMEM;
4016 }
4017
Romain Perierfc69d862017-07-06 10:13:06 +02004018 instance->sense_dma_pool = dma_pool_create("megasas sense pool",
4019 &instance->pdev->dev, 128,
4020 4, 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004021
4022 if (!instance->sense_dma_pool) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004023 dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup sense pool\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004024
Romain Perierfc69d862017-07-06 10:13:06 +02004025 dma_pool_destroy(instance->frame_dma_pool);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004026 instance->frame_dma_pool = NULL;
4027
4028 return -ENOMEM;
4029 }
4030
4031 /*
4032 * Allocate and attach a frame to each of the commands in cmd_list.
4033 * By making cmd->index as the context instead of the &cmd, we can
4034 * always use 32bit context regardless of the architecture
4035 */
4036 for (i = 0; i < max_cmd; i++) {
4037
4038 cmd = instance->cmd_list[i];
4039
Souptick Joarder61b142a2018-02-15 21:55:06 +05304040 cmd->frame = dma_pool_zalloc(instance->frame_dma_pool,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004041 GFP_KERNEL, &cmd->frame_phys_addr);
4042
Romain Perierfc69d862017-07-06 10:13:06 +02004043 cmd->sense = dma_pool_alloc(instance->sense_dma_pool,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004044 GFP_KERNEL, &cmd->sense_phys_addr);
4045
4046 /*
4047 * megasas_teardown_frame_pool() takes care of freeing
4048 * whatever has been allocated
4049 */
4050 if (!cmd->frame || !cmd->sense) {
Romain Perierfc69d862017-07-06 10:13:06 +02004051 dev_printk(KERN_DEBUG, &instance->pdev->dev, "dma_pool_alloc failed\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004052 megasas_teardown_frame_pool(instance);
4053 return -ENOMEM;
4054 }
4055
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304056 cmd->frame->io.context = cpu_to_le32(cmd->index);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004057 cmd->frame->io.pad_0 = 0;
Shivasharan Se7d36b82017-10-19 02:48:50 -07004058 if ((instance->adapter_type == MFI_SERIES) && reset_devices)
adam radforde5f93a32011-10-08 18:15:19 -07004059 cmd->frame->hdr.cmd = MFI_CMD_INVALID;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004060 }
4061
4062 return 0;
4063}
4064
4065/**
4066 * megasas_free_cmds - Free all the cmds in the free cmd pool
4067 * @instance: Adapter soft state
4068 */
adam radford9c915a82010-12-21 13:34:31 -08004069void megasas_free_cmds(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004070{
4071 int i;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05004072
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004073 /* First free the MFI frame pool */
4074 megasas_teardown_frame_pool(instance);
4075
4076 /* Free all the commands in the cmd_list */
adam radford9c915a82010-12-21 13:34:31 -08004077 for (i = 0; i < instance->max_mfi_cmds; i++)
4078
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004079 kfree(instance->cmd_list[i]);
4080
4081 /* Free the cmd_list buffer itself */
4082 kfree(instance->cmd_list);
4083 instance->cmd_list = NULL;
4084
4085 INIT_LIST_HEAD(&instance->cmd_pool);
4086}
4087
4088/**
4089 * megasas_alloc_cmds - Allocates the command packets
4090 * @instance: Adapter soft state
4091 *
4092 * Each command that is issued to the FW, whether IO commands from the OS or
4093 * internal commands like IOCTLs, are wrapped in local data structure called
4094 * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to
4095 * the FW.
4096 *
4097 * Each frame has a 32-bit field called context (tag). This context is used
4098 * to get back the megasas_cmd from the frame when a frame gets completed in
4099 * the ISR. Typically the address of the megasas_cmd itself would be used as
4100 * the context. But we wanted to keep the differences between 32 and 64 bit
4101 * systems to the mininum. We always use 32 bit integers for the context. In
4102 * this driver, the 32 bit values are the indices into an array cmd_list.
4103 * This array is used only to look up the megasas_cmd given the context. The
4104 * free commands themselves are maintained in a linked list called cmd_pool.
4105 */
adam radford9c915a82010-12-21 13:34:31 -08004106int megasas_alloc_cmds(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004107{
4108 int i;
4109 int j;
Shivasharan S50b7f5a2017-02-10 00:59:25 -08004110 u16 max_cmd;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004111 struct megasas_cmd *cmd;
4112
adam radford9c915a82010-12-21 13:34:31 -08004113 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004114
4115 /*
4116 * instance->cmd_list is an array of struct megasas_cmd pointers.
4117 * Allocate the dynamic array first and then allocate individual
4118 * commands.
4119 */
Yoann Padioleaudd00cc42007-07-19 01:49:03 -07004120 instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004121
4122 if (!instance->cmd_list) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004123 dev_printk(KERN_DEBUG, &instance->pdev->dev, "out of memory\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004124 return -ENOMEM;
4125 }
4126
adam radford9c915a82010-12-21 13:34:31 -08004127 memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) *max_cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004128
4129 for (i = 0; i < max_cmd; i++) {
4130 instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd),
4131 GFP_KERNEL);
4132
4133 if (!instance->cmd_list[i]) {
4134
4135 for (j = 0; j < i; j++)
4136 kfree(instance->cmd_list[j]);
4137
4138 kfree(instance->cmd_list);
4139 instance->cmd_list = NULL;
4140
4141 return -ENOMEM;
4142 }
4143 }
4144
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004145 for (i = 0; i < max_cmd; i++) {
4146 cmd = instance->cmd_list[i];
4147 memset(cmd, 0, sizeof(struct megasas_cmd));
4148 cmd->index = i;
bo yang39a98552010-09-22 22:36:29 -04004149 cmd->scmd = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004150 cmd->instance = instance;
4151
4152 list_add_tail(&cmd->list, &instance->cmd_pool);
4153 }
4154
4155 /*
4156 * Create a frame pool and assign one frame to each cmd
4157 */
4158 if (megasas_create_frame_pool(instance)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004159 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Error creating frame DMA pool\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004160 megasas_free_cmds(instance);
4161 }
4162
4163 return 0;
4164}
4165
Yang, Bo81e403c2009-10-06 14:27:54 -06004166/*
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304167 * dcmd_timeout_ocr_possible - Check if OCR is possible based on Driver/FW state.
4168 * @instance: Adapter soft state
4169 *
4170 * Return 0 for only Fusion adapter, if driver load/unload is not in progress
4171 * or FW is not under OCR.
4172 */
4173inline int
4174dcmd_timeout_ocr_possible(struct megasas_instance *instance) {
4175
Shivasharan Se7d36b82017-10-19 02:48:50 -07004176 if (instance->adapter_type == MFI_SERIES)
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304177 return KILL_ADAPTER;
4178 else if (instance->unload ||
4179 test_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags))
4180 return IGNORE_TIMEOUT;
4181 else
4182 return INITIATE_OCR;
4183}
4184
Shivasharan S15dd0382017-02-10 00:59:10 -08004185static void
4186megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev)
Sumit Saxena2216c302016-01-28 21:04:26 +05304187{
4188 int ret;
4189 struct megasas_cmd *cmd;
4190 struct megasas_dcmd_frame *dcmd;
4191
Shivasharan S15dd0382017-02-10 00:59:10 -08004192 struct MR_PRIV_DEVICE *mr_device_priv_data;
4193 u16 device_id = 0;
4194
4195 device_id = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id;
Sumit Saxena2216c302016-01-28 21:04:26 +05304196 cmd = megasas_get_cmd(instance);
4197
4198 if (!cmd) {
4199 dev_err(&instance->pdev->dev, "Failed to get cmd %s\n", __func__);
Shivasharan S15dd0382017-02-10 00:59:10 -08004200 return;
Sumit Saxena2216c302016-01-28 21:04:26 +05304201 }
4202
4203 dcmd = &cmd->frame->dcmd;
4204
4205 memset(instance->pd_info, 0, sizeof(*instance->pd_info));
4206 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4207
4208 dcmd->mbox.s[0] = cpu_to_le16(device_id);
4209 dcmd->cmd = MFI_CMD_DCMD;
4210 dcmd->cmd_status = 0xFF;
4211 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07004212 dcmd->flags = MFI_FRAME_DIR_READ;
Sumit Saxena2216c302016-01-28 21:04:26 +05304213 dcmd->timeout = 0;
4214 dcmd->pad_0 = 0;
4215 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_PD_INFO));
4216 dcmd->opcode = cpu_to_le32(MR_DCMD_PD_GET_INFO);
Sumit Saxena2216c302016-01-28 21:04:26 +05304217
Shivasharan S107a60d2017-10-19 02:49:05 -07004218 megasas_set_dma_settings(instance, dcmd, instance->pd_info_h,
4219 sizeof(struct MR_PD_INFO));
Sumit Saxena2216c302016-01-28 21:04:26 +05304220
Shivasharan Se7d36b82017-10-19 02:48:50 -07004221 if ((instance->adapter_type != MFI_SERIES) &&
4222 !instance->mask_interrupts)
Sumit Saxena2216c302016-01-28 21:04:26 +05304223 ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
4224 else
4225 ret = megasas_issue_polled(instance, cmd);
4226
4227 switch (ret) {
4228 case DCMD_SUCCESS:
Shivasharan S15dd0382017-02-10 00:59:10 -08004229 mr_device_priv_data = sdev->hostdata;
4230 le16_to_cpus((u16 *)&instance->pd_info->state.ddf.pdType);
4231 mr_device_priv_data->interface_type =
Sumit Saxena2216c302016-01-28 21:04:26 +05304232 instance->pd_info->state.ddf.pdType.intf;
4233 break;
4234
4235 case DCMD_TIMEOUT:
4236
4237 switch (dcmd_timeout_ocr_possible(instance)) {
4238 case INITIATE_OCR:
4239 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4240 megasas_reset_fusion(instance->host,
4241 MFI_IO_TIMEOUT_OCR);
4242 break;
4243 case KILL_ADAPTER:
4244 megaraid_sas_kill_hba(instance);
4245 break;
4246 case IGNORE_TIMEOUT:
4247 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
4248 __func__, __LINE__);
4249 break;
4250 }
4251
4252 break;
4253 }
4254
4255 if (ret != DCMD_TIMEOUT)
4256 megasas_return_cmd(instance, cmd);
4257
Shivasharan S15dd0382017-02-10 00:59:10 -08004258 return;
Sumit Saxena2216c302016-01-28 21:04:26 +05304259}
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304260/*
Yang, Bo81e403c2009-10-06 14:27:54 -06004261 * megasas_get_pd_list_info - Returns FW's pd_list structure
4262 * @instance: Adapter soft state
4263 * @pd_list: pd_list structure
4264 *
4265 * Issues an internal command (DCMD) to get the FW's controller PD
4266 * list structure. This information is mainly used to find out SYSTEM
4267 * supported by the FW.
4268 */
4269static int
4270megasas_get_pd_list(struct megasas_instance *instance)
4271{
4272 int ret = 0, pd_index = 0;
4273 struct megasas_cmd *cmd;
4274 struct megasas_dcmd_frame *dcmd;
4275 struct MR_PD_LIST *ci;
4276 struct MR_PD_ADDRESS *pd_addr;
4277 dma_addr_t ci_h = 0;
4278
Sumit Saxenad9083162016-07-08 03:30:16 -07004279 if (instance->pd_list_not_supported) {
4280 dev_info(&instance->pdev->dev, "MR_DCMD_PD_LIST_QUERY "
4281 "not supported by firmware\n");
4282 return ret;
4283 }
4284
Shivasharan S9b3d0282017-10-19 02:48:56 -07004285 ci = instance->pd_list_buf;
4286 ci_h = instance->pd_list_buf_h;
4287
Yang, Bo81e403c2009-10-06 14:27:54 -06004288 cmd = megasas_get_cmd(instance);
4289
4290 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004291 dev_printk(KERN_DEBUG, &instance->pdev->dev, "(get_pd_list): Failed to get cmd\n");
Yang, Bo81e403c2009-10-06 14:27:54 -06004292 return -ENOMEM;
4293 }
4294
4295 dcmd = &cmd->frame->dcmd;
4296
Yang, Bo81e403c2009-10-06 14:27:54 -06004297 memset(ci, 0, sizeof(*ci));
4298 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4299
4300 dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
4301 dcmd->mbox.b[1] = 0;
4302 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05304303 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
Yang, Bo81e403c2009-10-06 14:27:54 -06004304 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07004305 dcmd->flags = MFI_FRAME_DIR_READ;
Yang, Bo81e403c2009-10-06 14:27:54 -06004306 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004307 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304308 dcmd->data_xfer_len = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST));
4309 dcmd->opcode = cpu_to_le32(MR_DCMD_PD_LIST_QUERY);
Yang, Bo81e403c2009-10-06 14:27:54 -06004310
Shivasharan S107a60d2017-10-19 02:49:05 -07004311 megasas_set_dma_settings(instance, dcmd, instance->pd_list_buf_h,
4312 (MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST)));
Yang, Bo81e403c2009-10-06 14:27:54 -06004313
Shivasharan Se7d36b82017-10-19 02:48:50 -07004314 if ((instance->adapter_type != MFI_SERIES) &&
4315 !instance->mask_interrupts)
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304316 ret = megasas_issue_blocked_cmd(instance, cmd,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304317 MFI_IO_TIMEOUT_SECS);
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304318 else
4319 ret = megasas_issue_polled(instance, cmd);
Yang, Bo81e403c2009-10-06 14:27:54 -06004320
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304321 switch (ret) {
4322 case DCMD_FAILED:
Sumit Saxena30845582016-03-10 02:14:37 -08004323 dev_info(&instance->pdev->dev, "MR_DCMD_PD_LIST_QUERY "
4324 "failed/not supported by firmware\n");
4325
Shivasharan Se7d36b82017-10-19 02:48:50 -07004326 if (instance->adapter_type != MFI_SERIES)
Sumit Saxena30845582016-03-10 02:14:37 -08004327 megaraid_sas_kill_hba(instance);
4328 else
4329 instance->pd_list_not_supported = 1;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304330 break;
4331 case DCMD_TIMEOUT:
Yang, Bo81e403c2009-10-06 14:27:54 -06004332
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304333 switch (dcmd_timeout_ocr_possible(instance)) {
4334 case INITIATE_OCR:
4335 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4336 /*
4337 * DCMD failed from AEN path.
4338 * AEN path already hold reset_mutex to avoid PCI access
4339 * while OCR is in progress.
4340 */
4341 mutex_unlock(&instance->reset_mutex);
4342 megasas_reset_fusion(instance->host,
4343 MFI_IO_TIMEOUT_OCR);
4344 mutex_lock(&instance->reset_mutex);
4345 break;
4346 case KILL_ADAPTER:
4347 megaraid_sas_kill_hba(instance);
4348 break;
4349 case IGNORE_TIMEOUT:
4350 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d \n",
4351 __func__, __LINE__);
4352 break;
4353 }
Yang, Bo81e403c2009-10-06 14:27:54 -06004354
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304355 break;
4356
4357 case DCMD_SUCCESS:
4358 pd_addr = ci->addr;
4359
4360 if ((le32_to_cpu(ci->count) >
4361 (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL)))
4362 break;
Yang, Bo81e403c2009-10-06 14:27:54 -06004363
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05304364 memset(instance->local_pd_list, 0,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304365 MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
Yang, Bo81e403c2009-10-06 14:27:54 -06004366
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304367 for (pd_index = 0; pd_index < le32_to_cpu(ci->count); pd_index++) {
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05304368 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].tid =
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304369 le16_to_cpu(pd_addr->deviceId);
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05304370 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveType =
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304371 pd_addr->scsiDevType;
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05304372 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveState =
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304373 MR_PD_STATE_SYSTEM;
Yang, Bo81e403c2009-10-06 14:27:54 -06004374 pd_addr++;
4375 }
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304376
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05304377 memcpy(instance->pd_list, instance->local_pd_list,
4378 sizeof(instance->pd_list));
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304379 break;
4380
Yang, Bo81e403c2009-10-06 14:27:54 -06004381 }
4382
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304383 if (ret != DCMD_TIMEOUT)
4384 megasas_return_cmd(instance, cmd);
Yang, Bo81e403c2009-10-06 14:27:54 -06004385
4386 return ret;
4387}
4388
Yang, Bobdc6fb82009-12-06 08:30:19 -07004389/*
4390 * megasas_get_ld_list_info - Returns FW's ld_list structure
4391 * @instance: Adapter soft state
4392 * @ld_list: ld_list structure
4393 *
4394 * Issues an internal command (DCMD) to get the FW's controller PD
4395 * list structure. This information is mainly used to find out SYSTEM
4396 * supported by the FW.
4397 */
4398static int
4399megasas_get_ld_list(struct megasas_instance *instance)
4400{
4401 int ret = 0, ld_index = 0, ids = 0;
4402 struct megasas_cmd *cmd;
4403 struct megasas_dcmd_frame *dcmd;
4404 struct MR_LD_LIST *ci;
4405 dma_addr_t ci_h = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304406 u32 ld_count;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004407
Shivasharan S9b3d0282017-10-19 02:48:56 -07004408 ci = instance->ld_list_buf;
4409 ci_h = instance->ld_list_buf_h;
4410
Yang, Bobdc6fb82009-12-06 08:30:19 -07004411 cmd = megasas_get_cmd(instance);
4412
4413 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004414 dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_get_ld_list: Failed to get cmd\n");
Yang, Bobdc6fb82009-12-06 08:30:19 -07004415 return -ENOMEM;
4416 }
4417
4418 dcmd = &cmd->frame->dcmd;
4419
Yang, Bobdc6fb82009-12-06 08:30:19 -07004420 memset(ci, 0, sizeof(*ci));
4421 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4422
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05304423 if (instance->supportmax256vd)
4424 dcmd->mbox.b[0] = 1;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004425 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05304426 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004427 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07004428 dcmd->flags = MFI_FRAME_DIR_READ;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004429 dcmd->timeout = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304430 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_LIST));
4431 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_GET_LIST);
Yang, Bobdc6fb82009-12-06 08:30:19 -07004432 dcmd->pad_0 = 0;
4433
Shivasharan S107a60d2017-10-19 02:49:05 -07004434 megasas_set_dma_settings(instance, dcmd, ci_h,
4435 sizeof(struct MR_LD_LIST));
4436
Shivasharan Se7d36b82017-10-19 02:48:50 -07004437 if ((instance->adapter_type != MFI_SERIES) &&
4438 !instance->mask_interrupts)
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304439 ret = megasas_issue_blocked_cmd(instance, cmd,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304440 MFI_IO_TIMEOUT_SECS);
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304441 else
4442 ret = megasas_issue_polled(instance, cmd);
4443
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304444 ld_count = le32_to_cpu(ci->ldCount);
4445
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304446 switch (ret) {
4447 case DCMD_FAILED:
4448 megaraid_sas_kill_hba(instance);
4449 break;
4450 case DCMD_TIMEOUT:
Yang, Bobdc6fb82009-12-06 08:30:19 -07004451
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304452 switch (dcmd_timeout_ocr_possible(instance)) {
4453 case INITIATE_OCR:
4454 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4455 /*
4456 * DCMD failed from AEN path.
4457 * AEN path already hold reset_mutex to avoid PCI access
4458 * while OCR is in progress.
4459 */
4460 mutex_unlock(&instance->reset_mutex);
4461 megasas_reset_fusion(instance->host,
4462 MFI_IO_TIMEOUT_OCR);
4463 mutex_lock(&instance->reset_mutex);
4464 break;
4465 case KILL_ADAPTER:
4466 megaraid_sas_kill_hba(instance);
4467 break;
4468 case IGNORE_TIMEOUT:
4469 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
4470 __func__, __LINE__);
4471 break;
4472 }
4473
4474 break;
4475
4476 case DCMD_SUCCESS:
4477 if (ld_count > instance->fw_supported_vd_count)
4478 break;
4479
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05304480 memset(instance->ld_ids, 0xff, MAX_LOGICAL_DRIVES_EXT);
Yang, Bobdc6fb82009-12-06 08:30:19 -07004481
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304482 for (ld_index = 0; ld_index < ld_count; ld_index++) {
Yang, Bobdc6fb82009-12-06 08:30:19 -07004483 if (ci->ldList[ld_index].state != 0) {
4484 ids = ci->ldList[ld_index].ref.targetId;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304485 instance->ld_ids[ids] = ci->ldList[ld_index].ref.targetId;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004486 }
4487 }
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304488
4489 break;
Yang, Bobdc6fb82009-12-06 08:30:19 -07004490 }
4491
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304492 if (ret != DCMD_TIMEOUT)
4493 megasas_return_cmd(instance, cmd);
4494
Yang, Bobdc6fb82009-12-06 08:30:19 -07004495 return ret;
4496}
4497
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004498/**
adam radford21c9e162013-09-06 15:27:14 -07004499 * megasas_ld_list_query - Returns FW's ld_list structure
4500 * @instance: Adapter soft state
4501 * @ld_list: ld_list structure
4502 *
4503 * Issues an internal command (DCMD) to get the FW's controller PD
4504 * list structure. This information is mainly used to find out SYSTEM
4505 * supported by the FW.
4506 */
4507static int
4508megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
4509{
4510 int ret = 0, ld_index = 0, ids = 0;
4511 struct megasas_cmd *cmd;
4512 struct megasas_dcmd_frame *dcmd;
4513 struct MR_LD_TARGETID_LIST *ci;
4514 dma_addr_t ci_h = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304515 u32 tgtid_count;
adam radford21c9e162013-09-06 15:27:14 -07004516
Shivasharan S9b3d0282017-10-19 02:48:56 -07004517 ci = instance->ld_targetid_list_buf;
4518 ci_h = instance->ld_targetid_list_buf_h;
4519
adam radford21c9e162013-09-06 15:27:14 -07004520 cmd = megasas_get_cmd(instance);
4521
4522 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004523 dev_warn(&instance->pdev->dev,
4524 "megasas_ld_list_query: Failed to get cmd\n");
adam radford21c9e162013-09-06 15:27:14 -07004525 return -ENOMEM;
4526 }
4527
4528 dcmd = &cmd->frame->dcmd;
4529
adam radford21c9e162013-09-06 15:27:14 -07004530 memset(ci, 0, sizeof(*ci));
4531 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4532
4533 dcmd->mbox.b[0] = query_type;
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05304534 if (instance->supportmax256vd)
4535 dcmd->mbox.b[2] = 1;
adam radford21c9e162013-09-06 15:27:14 -07004536
4537 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05304538 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
adam radford21c9e162013-09-06 15:27:14 -07004539 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07004540 dcmd->flags = MFI_FRAME_DIR_READ;
adam radford21c9e162013-09-06 15:27:14 -07004541 dcmd->timeout = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304542 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST));
4543 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_LIST_QUERY);
adam radford21c9e162013-09-06 15:27:14 -07004544 dcmd->pad_0 = 0;
4545
Shivasharan S107a60d2017-10-19 02:49:05 -07004546 megasas_set_dma_settings(instance, dcmd, ci_h,
4547 sizeof(struct MR_LD_TARGETID_LIST));
4548
Shivasharan Se7d36b82017-10-19 02:48:50 -07004549 if ((instance->adapter_type != MFI_SERIES) &&
4550 !instance->mask_interrupts)
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304551 ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304552 else
4553 ret = megasas_issue_polled(instance, cmd);
adam radford21c9e162013-09-06 15:27:14 -07004554
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304555 switch (ret) {
4556 case DCMD_FAILED:
4557 dev_info(&instance->pdev->dev,
4558 "DCMD not supported by firmware - %s %d\n",
4559 __func__, __LINE__);
4560 ret = megasas_get_ld_list(instance);
4561 break;
4562 case DCMD_TIMEOUT:
4563 switch (dcmd_timeout_ocr_possible(instance)) {
4564 case INITIATE_OCR:
4565 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4566 /*
4567 * DCMD failed from AEN path.
4568 * AEN path already hold reset_mutex to avoid PCI access
4569 * while OCR is in progress.
4570 */
4571 mutex_unlock(&instance->reset_mutex);
4572 megasas_reset_fusion(instance->host,
4573 MFI_IO_TIMEOUT_OCR);
4574 mutex_lock(&instance->reset_mutex);
4575 break;
4576 case KILL_ADAPTER:
4577 megaraid_sas_kill_hba(instance);
4578 break;
4579 case IGNORE_TIMEOUT:
4580 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
4581 __func__, __LINE__);
4582 break;
4583 }
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304584
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304585 break;
4586 case DCMD_SUCCESS:
4587 tgtid_count = le32_to_cpu(ci->count);
4588
4589 if ((tgtid_count > (instance->fw_supported_vd_count)))
4590 break;
4591
adam radford21c9e162013-09-06 15:27:14 -07004592 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304593 for (ld_index = 0; ld_index < tgtid_count; ld_index++) {
adam radford21c9e162013-09-06 15:27:14 -07004594 ids = ci->targetId[ld_index];
4595 instance->ld_ids[ids] = ci->targetId[ld_index];
4596 }
4597
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304598 break;
adam radford21c9e162013-09-06 15:27:14 -07004599 }
4600
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304601 if (ret != DCMD_TIMEOUT)
4602 megasas_return_cmd(instance, cmd);
adam radford21c9e162013-09-06 15:27:14 -07004603
4604 return ret;
4605}
4606
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304607/*
4608 * megasas_update_ext_vd_details : Update details w.r.t Extended VD
4609 * instance : Controller's instance
4610*/
4611static void megasas_update_ext_vd_details(struct megasas_instance *instance)
4612{
4613 struct fusion_context *fusion;
Sasikumar Chandrasekarand8893442017-01-10 18:20:48 -05004614 u32 ventura_map_sz = 0;
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304615
4616 fusion = instance->ctrl_context;
4617 /* For MFI based controllers return dummy success */
4618 if (!fusion)
4619 return;
4620
4621 instance->supportmax256vd =
Shivasharan S9ad18a92017-10-19 02:48:57 -07004622 instance->ctrl_info_buf->adapterOperations3.supportMaxExtLDs;
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304623 /* Below is additional check to address future FW enhancement */
Shivasharan S9ad18a92017-10-19 02:48:57 -07004624 if (instance->ctrl_info_buf->max_lds > 64)
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304625 instance->supportmax256vd = 1;
4626
4627 instance->drv_supported_vd_count = MEGASAS_MAX_LD_CHANNELS
4628 * MEGASAS_MAX_DEV_PER_CHANNEL;
4629 instance->drv_supported_pd_count = MEGASAS_MAX_PD_CHANNELS
4630 * MEGASAS_MAX_DEV_PER_CHANNEL;
4631 if (instance->supportmax256vd) {
4632 instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT;
4633 instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
4634 } else {
4635 instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
4636 instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
4637 }
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05304638
4639 dev_info(&instance->pdev->dev,
Shivasharan Scba67d92018-10-16 23:37:56 -07004640 "FW provided supportMaxExtLDs: %d\tmax_lds: %d\n",
4641 instance->ctrl_info_buf->adapterOperations3.supportMaxExtLDs ? 1 : 0,
4642 instance->ctrl_info_buf->max_lds);
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304643
Sasikumar Chandrasekarand8893442017-01-10 18:20:48 -05004644 if (instance->max_raid_mapsize) {
4645 ventura_map_sz = instance->max_raid_mapsize *
4646 MR_MIN_MAP_SIZE; /* 64k */
4647 fusion->current_map_sz = ventura_map_sz;
4648 fusion->max_map_sz = ventura_map_sz;
4649 } else {
4650 fusion->old_map_sz = sizeof(struct MR_FW_RAID_MAP) +
4651 (sizeof(struct MR_LD_SPAN_MAP) *
4652 (instance->fw_supported_vd_count - 1));
4653 fusion->new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT);
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304654
Sasikumar Chandrasekarand8893442017-01-10 18:20:48 -05004655 fusion->max_map_sz =
4656 max(fusion->old_map_sz, fusion->new_map_sz);
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304657
Sasikumar Chandrasekarand8893442017-01-10 18:20:48 -05004658 if (instance->supportmax256vd)
4659 fusion->current_map_sz = fusion->new_map_sz;
4660 else
4661 fusion->current_map_sz = fusion->old_map_sz;
4662 }
4663 /* irrespective of FW raid maps, driver raid map is constant */
4664 fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL);
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304665}
4666
Shivasharan Sf0c21df2018-10-16 23:37:40 -07004667/*
4668 * dcmd.opcode - MR_DCMD_CTRL_SNAPDUMP_GET_PROPERTIES
4669 * dcmd.hdr.length - number of bytes to read
4670 * dcmd.sge - Ptr to MR_SNAPDUMP_PROPERTIES
4671 * Desc: Fill in snapdump properties
4672 * Status: MFI_STAT_OK- Command successful
4673 */
4674void megasas_get_snapdump_properties(struct megasas_instance *instance)
4675{
4676 int ret = 0;
4677 struct megasas_cmd *cmd;
4678 struct megasas_dcmd_frame *dcmd;
4679 struct MR_SNAPDUMP_PROPERTIES *ci;
4680 dma_addr_t ci_h = 0;
4681
4682 ci = instance->snapdump_prop;
4683 ci_h = instance->snapdump_prop_h;
4684
4685 if (!ci)
4686 return;
4687
4688 cmd = megasas_get_cmd(instance);
4689
4690 if (!cmd) {
4691 dev_dbg(&instance->pdev->dev, "Failed to get a free cmd\n");
4692 return;
4693 }
4694
4695 dcmd = &cmd->frame->dcmd;
4696
4697 memset(ci, 0, sizeof(*ci));
4698 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4699
4700 dcmd->cmd = MFI_CMD_DCMD;
4701 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
4702 dcmd->sge_count = 1;
4703 dcmd->flags = MFI_FRAME_DIR_READ;
4704 dcmd->timeout = 0;
4705 dcmd->pad_0 = 0;
4706 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_SNAPDUMP_PROPERTIES));
4707 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SNAPDUMP_GET_PROPERTIES);
4708
4709 megasas_set_dma_settings(instance, dcmd, ci_h,
4710 sizeof(struct MR_SNAPDUMP_PROPERTIES));
4711
4712 if (!instance->mask_interrupts) {
4713 ret = megasas_issue_blocked_cmd(instance, cmd,
4714 MFI_IO_TIMEOUT_SECS);
4715 } else {
4716 ret = megasas_issue_polled(instance, cmd);
4717 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4718 }
4719
4720 switch (ret) {
4721 case DCMD_SUCCESS:
4722 instance->snapdump_wait_time =
4723 min_t(u8, ci->trigger_min_num_sec_before_ocr,
4724 MEGASAS_MAX_SNAP_DUMP_WAIT_TIME);
4725 break;
4726
4727 case DCMD_TIMEOUT:
4728 switch (dcmd_timeout_ocr_possible(instance)) {
4729 case INITIATE_OCR:
4730 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4731 megasas_reset_fusion(instance->host,
4732 MFI_IO_TIMEOUT_OCR);
4733 break;
4734 case KILL_ADAPTER:
4735 megaraid_sas_kill_hba(instance);
4736 break;
4737 case IGNORE_TIMEOUT:
4738 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
4739 __func__, __LINE__);
4740 break;
4741 }
4742 }
4743
4744 if (ret != DCMD_TIMEOUT)
4745 megasas_return_cmd(instance, cmd);
4746}
4747
adam radford21c9e162013-09-06 15:27:14 -07004748/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004749 * megasas_get_controller_info - Returns FW's controller structure
4750 * @instance: Adapter soft state
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004751 *
4752 * Issues an internal command (DCMD) to get the FW's controller structure.
4753 * This information is mainly used to find out the maximum IO transfer per
4754 * command supported by the FW.
4755 */
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05304756int
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304757megasas_get_ctrl_info(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004758{
4759 int ret = 0;
4760 struct megasas_cmd *cmd;
4761 struct megasas_dcmd_frame *dcmd;
4762 struct megasas_ctrl_info *ci;
4763 dma_addr_t ci_h = 0;
4764
Shivasharan S9b3d0282017-10-19 02:48:56 -07004765 ci = instance->ctrl_info_buf;
4766 ci_h = instance->ctrl_info_buf_h;
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304767
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004768 cmd = megasas_get_cmd(instance);
4769
4770 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05004771 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a free cmd\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004772 return -ENOMEM;
4773 }
4774
4775 dcmd = &cmd->frame->dcmd;
4776
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004777 memset(ci, 0, sizeof(*ci));
4778 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4779
4780 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05304781 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004782 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07004783 dcmd->flags = MFI_FRAME_DIR_READ;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004784 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004785 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304786 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_ctrl_info));
4787 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_GET_INFO);
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05304788 dcmd->mbox.b[0] = 1;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004789
Shivasharan S107a60d2017-10-19 02:49:05 -07004790 megasas_set_dma_settings(instance, dcmd, ci_h,
4791 sizeof(struct megasas_ctrl_info));
4792
Shivasharan Se7d36b82017-10-19 02:48:50 -07004793 if ((instance->adapter_type != MFI_SERIES) &&
Shivasharan S54b28042018-01-05 05:27:47 -08004794 !instance->mask_interrupts) {
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304795 ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
Shivasharan S54b28042018-01-05 05:27:47 -08004796 } else {
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304797 ret = megasas_issue_polled(instance, cmd);
Shivasharan S54b28042018-01-05 05:27:47 -08004798 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4799 }
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304800
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304801 switch (ret) {
4802 case DCMD_SUCCESS:
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304803 /* Save required controller information in
4804 * CPU endianness format.
4805 */
Shivasharan S9ad18a92017-10-19 02:48:57 -07004806 le32_to_cpus((u32 *)&ci->properties.OnOffProperties);
Shivasharan Sf0c21df2018-10-16 23:37:40 -07004807 le16_to_cpus((u16 *)&ci->properties.on_off_properties2);
Shivasharan S9ad18a92017-10-19 02:48:57 -07004808 le32_to_cpus((u32 *)&ci->adapterOperations2);
4809 le32_to_cpus((u32 *)&ci->adapterOperations3);
4810 le16_to_cpus((u16 *)&ci->adapter_operations4);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304811
4812 /* Update the latest Ext VD info.
4813 * From Init path, store current firmware details.
4814 * From OCR path, detect any firmware properties changes.
4815 * in case of Firmware upgrade without system reboot.
4816 */
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304817 megasas_update_ext_vd_details(instance);
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05304818 instance->use_seqnum_jbod_fp =
Shivasharan S9ad18a92017-10-19 02:48:57 -07004819 ci->adapterOperations3.useSeqNumJbodFP;
Sasikumar Chandrasekaranede7c3c2017-01-10 18:20:52 -05004820 instance->support_morethan256jbod =
Shivasharan S9ad18a92017-10-19 02:48:57 -07004821 ci->adapter_operations4.support_pd_map_target_id;
Shivasharan Sf870bcb2018-01-05 05:33:04 -08004822 instance->support_nvme_passthru =
4823 ci->adapter_operations4.support_nvme_passthru;
Shivasharan Se9495e22018-06-04 03:45:12 -07004824 instance->task_abort_tmo = ci->TaskAbortTO;
4825 instance->max_reset_tmo = ci->MaxResetTO;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304826
4827 /*Check whether controller is iMR or MR */
Shivasharan S9ad18a92017-10-19 02:48:57 -07004828 instance->is_imr = (ci->memory_size ? 0 : 1);
Shivasharan Sf0c21df2018-10-16 23:37:40 -07004829
4830 instance->snapdump_wait_time =
4831 (ci->properties.on_off_properties2.enable_snap_dump ?
4832 MEGASAS_DEFAULT_SNAP_DUMP_WAIT_TIME : 0);
4833
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05304834 dev_info(&instance->pdev->dev,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304835 "controller type\t: %s(%dMB)\n",
4836 instance->is_imr ? "iMR" : "MR",
Shivasharan S9ad18a92017-10-19 02:48:57 -07004837 le16_to_cpu(ci->memory_size));
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304838
sumit.saxena@avagotech.comc4bd2652015-10-15 13:40:14 +05304839 instance->disableOnlineCtrlReset =
Shivasharan S9ad18a92017-10-19 02:48:57 -07004840 ci->properties.OnOffProperties.disableOnlineCtrlReset;
sumit.saxena@avagotech.com32222512015-10-15 13:40:24 +05304841 instance->secure_jbod_support =
Shivasharan S9ad18a92017-10-19 02:48:57 -07004842 ci->adapterOperations3.supportSecurityonJBOD;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304843 dev_info(&instance->pdev->dev, "Online Controller Reset(OCR)\t: %s\n",
4844 instance->disableOnlineCtrlReset ? "Disabled" : "Enabled");
sumit.saxena@avagotech.com32222512015-10-15 13:40:24 +05304845 dev_info(&instance->pdev->dev, "Secure JBOD support\t: %s\n",
4846 instance->secure_jbod_support ? "Yes" : "No");
Shivasharan Sf870bcb2018-01-05 05:33:04 -08004847 dev_info(&instance->pdev->dev, "NVMe passthru support\t: %s\n",
4848 instance->support_nvme_passthru ? "Yes" : "No");
Shivasharan Se9495e22018-06-04 03:45:12 -07004849 dev_info(&instance->pdev->dev,
4850 "FW provided TM TaskAbort/Reset timeout\t: %d secs/%d secs\n",
4851 instance->task_abort_tmo, instance->max_reset_tmo);
4852
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304853 break;
4854
4855 case DCMD_TIMEOUT:
4856 switch (dcmd_timeout_ocr_possible(instance)) {
4857 case INITIATE_OCR:
4858 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4859 megasas_reset_fusion(instance->host,
4860 MFI_IO_TIMEOUT_OCR);
4861 break;
4862 case KILL_ADAPTER:
4863 megaraid_sas_kill_hba(instance);
4864 break;
4865 case IGNORE_TIMEOUT:
4866 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
4867 __func__, __LINE__);
4868 break;
4869 }
Shivasharan S2747e6b2018-06-04 03:45:09 -07004870 break;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304871 case DCMD_FAILED:
4872 megaraid_sas_kill_hba(instance);
4873 break;
4874
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05304875 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004876
Shivasharan S2747e6b2018-06-04 03:45:09 -07004877 if (ret != DCMD_TIMEOUT)
4878 megasas_return_cmd(instance, cmd);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304879
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004880 return ret;
4881}
4882
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05304883/*
4884 * megasas_set_crash_dump_params - Sends address of crash dump DMA buffer
4885 * to firmware
4886 *
4887 * @instance: Adapter soft state
4888 * @crash_buf_state - tell FW to turn ON/OFF crash dump feature
4889 MR_CRASH_BUF_TURN_OFF = 0
4890 MR_CRASH_BUF_TURN_ON = 1
4891 * @return 0 on success non-zero on failure.
4892 * Issues an internal command (DCMD) to set parameters for crash dump feature.
4893 * Driver will send address of crash dump DMA buffer and set mbox to tell FW
4894 * that driver supports crash dump feature. This DCMD will be sent only if
4895 * crash dump feature is supported by the FW.
4896 *
4897 */
4898int megasas_set_crash_dump_params(struct megasas_instance *instance,
4899 u8 crash_buf_state)
4900{
4901 int ret = 0;
4902 struct megasas_cmd *cmd;
4903 struct megasas_dcmd_frame *dcmd;
4904
4905 cmd = megasas_get_cmd(instance);
4906
4907 if (!cmd) {
4908 dev_err(&instance->pdev->dev, "Failed to get a free cmd\n");
4909 return -ENOMEM;
4910 }
4911
4912
4913 dcmd = &cmd->frame->dcmd;
4914
4915 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4916 dcmd->mbox.b[0] = crash_buf_state;
4917 dcmd->cmd = MFI_CMD_DCMD;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05304918 dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05304919 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07004920 dcmd->flags = MFI_FRAME_DIR_NONE;
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05304921 dcmd->timeout = 0;
4922 dcmd->pad_0 = 0;
4923 dcmd->data_xfer_len = cpu_to_le32(CRASH_DMA_BUF_SIZE);
4924 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SET_CRASH_DUMP_PARAMS);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05304925
Shivasharan S107a60d2017-10-19 02:49:05 -07004926 megasas_set_dma_settings(instance, dcmd, instance->crash_dump_h,
4927 CRASH_DMA_BUF_SIZE);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05304928
Shivasharan Se7d36b82017-10-19 02:48:50 -07004929 if ((instance->adapter_type != MFI_SERIES) &&
4930 !instance->mask_interrupts)
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304931 ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05304932 else
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05304933 ret = megasas_issue_polled(instance, cmd);
4934
Sumit Saxena6d40afb2016-01-28 21:04:23 +05304935 if (ret == DCMD_TIMEOUT) {
4936 switch (dcmd_timeout_ocr_possible(instance)) {
4937 case INITIATE_OCR:
4938 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
4939 megasas_reset_fusion(instance->host,
4940 MFI_IO_TIMEOUT_OCR);
4941 break;
4942 case KILL_ADAPTER:
4943 megaraid_sas_kill_hba(instance);
4944 break;
4945 case IGNORE_TIMEOUT:
4946 dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
4947 __func__, __LINE__);
4948 break;
4949 }
4950 } else
4951 megasas_return_cmd(instance, cmd);
4952
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05304953 return ret;
4954}
4955
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004956/**
bo yang31ea7082007-11-07 12:09:50 -05004957 * megasas_issue_init_mfi - Initializes the FW
4958 * @instance: Adapter soft state
4959 *
4960 * Issues the INIT MFI cmd
4961 */
4962static int
4963megasas_issue_init_mfi(struct megasas_instance *instance)
4964{
Christoph Hellwig9ab9ed382015-04-23 16:32:54 +05304965 __le32 context;
bo yang31ea7082007-11-07 12:09:50 -05004966 struct megasas_cmd *cmd;
bo yang31ea7082007-11-07 12:09:50 -05004967 struct megasas_init_frame *init_frame;
4968 struct megasas_init_queue_info *initq_info;
4969 dma_addr_t init_frame_h;
4970 dma_addr_t initq_info_h;
4971
4972 /*
4973 * Prepare a init frame. Note the init frame points to queue info
4974 * structure. Each frame has SGL allocated after first 64 bytes. For
4975 * this frame - since we don't need any SGL - we use SGL's space as
4976 * queue info structure
4977 *
4978 * We will not get a NULL command below. We just created the pool.
4979 */
4980 cmd = megasas_get_cmd(instance);
4981
4982 init_frame = (struct megasas_init_frame *)cmd->frame;
4983 initq_info = (struct megasas_init_queue_info *)
4984 ((unsigned long)init_frame + 64);
4985
4986 init_frame_h = cmd->frame_phys_addr;
4987 initq_info_h = init_frame_h + 64;
4988
4989 context = init_frame->context;
4990 memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
4991 memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
4992 init_frame->context = context;
4993
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304994 initq_info->reply_queue_entries = cpu_to_le32(instance->max_fw_cmds + 1);
4995 initq_info->reply_queue_start_phys_addr_lo = cpu_to_le32(instance->reply_queue_h);
bo yang31ea7082007-11-07 12:09:50 -05004996
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304997 initq_info->producer_index_phys_addr_lo = cpu_to_le32(instance->producer_h);
4998 initq_info->consumer_index_phys_addr_lo = cpu_to_le32(instance->consumer_h);
bo yang31ea7082007-11-07 12:09:50 -05004999
5000 init_frame->cmd = MFI_CMD_INIT;
Sumit.Saxena@avagotech.com2be2a982015-05-06 19:01:02 +05305001 init_frame->cmd_status = MFI_STAT_INVALID_STATUS;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305002 init_frame->queue_info_new_phys_addr_lo =
5003 cpu_to_le32(lower_32_bits(initq_info_h));
5004 init_frame->queue_info_new_phys_addr_hi =
5005 cpu_to_le32(upper_32_bits(initq_info_h));
bo yang31ea7082007-11-07 12:09:50 -05005006
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305007 init_frame->data_xfer_len = cpu_to_le32(sizeof(struct megasas_init_queue_info));
bo yang31ea7082007-11-07 12:09:50 -05005008
5009 /*
5010 * disable the intr before firing the init frame to FW
5011 */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305012 instance->instancet->disable_intr(instance);
bo yang31ea7082007-11-07 12:09:50 -05005013
5014 /*
5015 * Issue the init frame in polled mode
5016 */
5017
5018 if (megasas_issue_polled(instance, cmd)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005019 dev_err(&instance->pdev->dev, "Failed to init firmware\n");
bo yang31ea7082007-11-07 12:09:50 -05005020 megasas_return_cmd(instance, cmd);
5021 goto fail_fw_init;
5022 }
5023
5024 megasas_return_cmd(instance, cmd);
5025
5026 return 0;
5027
5028fail_fw_init:
5029 return -EINVAL;
5030}
5031
adam radfordcd50ba82010-12-21 10:23:23 -08005032static u32
5033megasas_init_adapter_mfi(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005034{
adam radfordcd50ba82010-12-21 10:23:23 -08005035 struct megasas_register_set __iomem *reg_set;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005036 u32 context_sz;
5037 u32 reply_q_sz;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005038
5039 reg_set = instance->reg_set;
5040
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005041 /*
5042 * Get various operational parameters from status register
5043 */
Sumant Patro1341c932006-01-25 12:02:40 -08005044 instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
Sumant Patroe3bbff92006-10-03 12:28:49 -07005045 /*
5046 * Reduce the max supported cmds by 1. This is to ensure that the
5047 * reply_q_sz (1 more than the max cmd that driver may send)
5048 * does not exceed max cmds that the FW can support
5049 */
5050 instance->max_fw_cmds = instance->max_fw_cmds-1;
adam radford9c915a82010-12-21 13:34:31 -08005051 instance->max_mfi_cmds = instance->max_fw_cmds;
adam radford0d490162010-12-14 19:17:17 -08005052 instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
Sumant Patro1341c932006-01-25 12:02:40 -08005053 0x10;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005054 /*
Sumit.Saxena@avagotech.comf26ac3a2015-04-23 16:30:54 +05305055 * For MFI skinny adapters, MEGASAS_SKINNY_INT_CMDS commands
5056 * are reserved for IOCTL + driver's internal DCMDs.
5057 */
5058 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
5059 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
5060 instance->max_scsi_cmds = (instance->max_fw_cmds -
5061 MEGASAS_SKINNY_INT_CMDS);
5062 sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
5063 } else {
5064 instance->max_scsi_cmds = (instance->max_fw_cmds -
5065 MEGASAS_INT_CMDS);
5066 sema_init(&instance->ioctl_sem, (MEGASAS_MFI_IOCTL_CMDS));
5067 }
5068
Sumit Saxena308ec452016-01-28 21:04:30 +05305069 instance->cur_can_queue = instance->max_scsi_cmds;
Sumit.Saxena@avagotech.comf26ac3a2015-04-23 16:30:54 +05305070 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005071 * Create a pool of commands
5072 */
5073 if (megasas_alloc_cmds(instance))
5074 goto fail_alloc_cmds;
5075
5076 /*
5077 * Allocate memory for reply queue. Length of reply queue should
5078 * be _one_ more than the maximum commands handled by the firmware.
5079 *
5080 * Note: When FW completes commands, it places corresponding contex
5081 * values in this circular reply queue. This circular queue is a fairly
5082 * typical producer-consumer queue. FW is the producer (of completed
5083 * commands) and the driver is the consumer.
5084 */
5085 context_sz = sizeof(u32);
5086 reply_q_sz = context_sz * (instance->max_fw_cmds + 1);
5087
Christoph Hellwig60ee6522018-10-10 19:31:25 +02005088 instance->reply_queue = dma_alloc_coherent(&instance->pdev->dev,
5089 reply_q_sz, &instance->reply_queue_h, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005090
5091 if (!instance->reply_queue) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005092 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Out of DMA mem for reply queue\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005093 goto fail_reply_queue;
5094 }
5095
bo yang31ea7082007-11-07 12:09:50 -05005096 if (megasas_issue_init_mfi(instance))
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005097 goto fail_fw_init;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005098
Sumit.Saxena@avagotech.comd009b572014-11-17 15:24:13 +05305099 if (megasas_get_ctrl_info(instance)) {
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305100 dev_err(&instance->pdev->dev, "(%d): Could get controller info "
5101 "Fail from %s %d\n", instance->unique_id,
5102 __func__, __LINE__);
5103 goto fail_fw_init;
5104 }
5105
bo yang39a98552010-09-22 22:36:29 -04005106 instance->fw_support_ieee = 0;
5107 instance->fw_support_ieee =
5108 (instance->instancet->read_fw_status_reg(reg_set) &
5109 0x04000000);
5110
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005111 dev_notice(&instance->pdev->dev, "megasas_init_mfi: fw_support_ieee=%d",
bo yang39a98552010-09-22 22:36:29 -04005112 instance->fw_support_ieee);
5113
5114 if (instance->fw_support_ieee)
5115 instance->flag_ieee = 1;
5116
adam radfordcd50ba82010-12-21 10:23:23 -08005117 return 0;
5118
5119fail_fw_init:
5120
Christoph Hellwig60ee6522018-10-10 19:31:25 +02005121 dma_free_coherent(&instance->pdev->dev, reply_q_sz,
adam radfordcd50ba82010-12-21 10:23:23 -08005122 instance->reply_queue, instance->reply_queue_h);
5123fail_reply_queue:
5124 megasas_free_cmds(instance);
5125
5126fail_alloc_cmds:
adam radfordcd50ba82010-12-21 10:23:23 -08005127 return 1;
5128}
5129
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305130/*
Hannes Reineckefad119b2016-12-02 12:52:23 +01005131 * megasas_setup_irqs_ioapic - register legacy interrupts.
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305132 * @instance: Adapter soft state
5133 *
5134 * Do not enable interrupt, only setup ISRs.
5135 *
5136 * Return 0 on success.
5137 */
5138static int
5139megasas_setup_irqs_ioapic(struct megasas_instance *instance)
5140{
5141 struct pci_dev *pdev;
5142
5143 pdev = instance->pdev;
5144 instance->irq_context[0].instance = instance;
5145 instance->irq_context[0].MSIxIndex = 0;
Hannes Reineckefad119b2016-12-02 12:52:23 +01005146 if (request_irq(pci_irq_vector(pdev, 0),
5147 instance->instancet->service_isr, IRQF_SHARED,
5148 "megasas", &instance->irq_context[0])) {
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305149 dev_err(&instance->pdev->dev,
5150 "Failed to register IRQ from %s %d\n",
5151 __func__, __LINE__);
5152 return -1;
5153 }
5154 return 0;
5155}
5156
5157/**
5158 * megasas_setup_irqs_msix - register MSI-x interrupts.
5159 * @instance: Adapter soft state
5160 * @is_probe: Driver probe check
5161 *
5162 * Do not enable interrupt, only setup ISRs.
5163 *
5164 * Return 0 on success.
5165 */
5166static int
5167megasas_setup_irqs_msix(struct megasas_instance *instance, u8 is_probe)
5168{
Hannes Reineckefad119b2016-12-02 12:52:23 +01005169 int i, j;
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305170 struct pci_dev *pdev;
5171
5172 pdev = instance->pdev;
5173
5174 /* Try MSI-x */
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305175 for (i = 0; i < instance->msix_vectors; i++) {
5176 instance->irq_context[i].instance = instance;
5177 instance->irq_context[i].MSIxIndex = i;
Hannes Reineckefad119b2016-12-02 12:52:23 +01005178 if (request_irq(pci_irq_vector(pdev, i),
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305179 instance->instancet->service_isr, 0, "megasas",
5180 &instance->irq_context[i])) {
5181 dev_err(&instance->pdev->dev,
5182 "Failed to register IRQ for vector %d.\n", i);
Hannes Reineckefad119b2016-12-02 12:52:23 +01005183 for (j = 0; j < i; j++)
5184 free_irq(pci_irq_vector(pdev, j),
5185 &instance->irq_context[j]);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305186 /* Retry irq register for IO_APIC*/
5187 instance->msix_vectors = 0;
Shivasharan S64ff64b2017-03-10 03:22:12 -08005188 if (is_probe) {
5189 pci_free_irq_vectors(instance->pdev);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305190 return megasas_setup_irqs_ioapic(instance);
Shivasharan S64ff64b2017-03-10 03:22:12 -08005191 } else {
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305192 return -1;
Shivasharan S64ff64b2017-03-10 03:22:12 -08005193 }
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305194 }
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305195 }
5196 return 0;
5197}
5198
5199/*
5200 * megasas_destroy_irqs- unregister interrupts.
5201 * @instance: Adapter soft state
5202 * return: void
5203 */
5204static void
5205megasas_destroy_irqs(struct megasas_instance *instance) {
5206
5207 int i;
5208
5209 if (instance->msix_vectors)
5210 for (i = 0; i < instance->msix_vectors; i++) {
Hannes Reineckefad119b2016-12-02 12:52:23 +01005211 free_irq(pci_irq_vector(instance->pdev, i),
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305212 &instance->irq_context[i]);
5213 }
5214 else
Hannes Reineckefad119b2016-12-02 12:52:23 +01005215 free_irq(pci_irq_vector(instance->pdev, 0),
5216 &instance->irq_context[0]);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305217}
5218
adam radfordcd50ba82010-12-21 10:23:23 -08005219/**
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05305220 * megasas_setup_jbod_map - setup jbod map for FP seq_number.
5221 * @instance: Adapter soft state
5222 * @is_probe: Driver probe check
5223 *
5224 * Return 0 on success.
5225 */
5226void
5227megasas_setup_jbod_map(struct megasas_instance *instance)
5228{
5229 int i;
5230 struct fusion_context *fusion = instance->ctrl_context;
5231 u32 pd_seq_map_sz;
5232
5233 pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
5234 (sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1));
5235
5236 if (reset_devices || !fusion ||
Shivasharan S9ad18a92017-10-19 02:48:57 -07005237 !instance->ctrl_info_buf->adapterOperations3.useSeqNumJbodFP) {
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05305238 dev_info(&instance->pdev->dev,
5239 "Jbod map is not supported %s %d\n",
5240 __func__, __LINE__);
5241 instance->use_seqnum_jbod_fp = false;
5242 return;
5243 }
5244
5245 if (fusion->pd_seq_sync[0])
5246 goto skip_alloc;
5247
5248 for (i = 0; i < JBOD_MAPS_COUNT; i++) {
5249 fusion->pd_seq_sync[i] = dma_alloc_coherent
5250 (&instance->pdev->dev, pd_seq_map_sz,
5251 &fusion->pd_seq_phys[i], GFP_KERNEL);
5252 if (!fusion->pd_seq_sync[i]) {
5253 dev_err(&instance->pdev->dev,
5254 "Failed to allocate memory from %s %d\n",
5255 __func__, __LINE__);
5256 if (i == 1) {
5257 dma_free_coherent(&instance->pdev->dev,
5258 pd_seq_map_sz, fusion->pd_seq_sync[0],
5259 fusion->pd_seq_phys[0]);
5260 fusion->pd_seq_sync[0] = NULL;
5261 }
5262 instance->use_seqnum_jbod_fp = false;
5263 return;
5264 }
5265 }
5266
5267skip_alloc:
5268 if (!megasas_sync_pd_seq_num(instance, false) &&
5269 !megasas_sync_pd_seq_num(instance, true))
5270 instance->use_seqnum_jbod_fp = true;
5271 else
5272 instance->use_seqnum_jbod_fp = false;
5273}
5274
Ming Leiadbe5522018-03-13 17:42:40 +08005275static void megasas_setup_reply_map(struct megasas_instance *instance)
5276{
5277 const struct cpumask *mask;
5278 unsigned int queue, cpu;
5279
5280 for (queue = 0; queue < instance->msix_vectors; queue++) {
5281 mask = pci_irq_get_affinity(instance->pdev, queue);
5282 if (!mask)
5283 goto fallback;
5284
5285 for_each_cpu(cpu, mask)
5286 instance->reply_map[cpu] = queue;
5287 }
5288 return;
5289
5290fallback:
5291 for_each_possible_cpu(cpu)
5292 instance->reply_map[cpu] = cpu % instance->msix_vectors;
5293}
5294
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05305295/**
adam radfordcd50ba82010-12-21 10:23:23 -08005296 * megasas_init_fw - Initializes the FW
5297 * @instance: Adapter soft state
5298 *
5299 * This is the main function for initializing firmware
5300 */
5301
5302static int megasas_init_fw(struct megasas_instance *instance)
5303{
5304 u32 max_sectors_1;
Shivasharan S15dd0382017-02-10 00:59:10 -08005305 u32 max_sectors_2, tmp_sectors, msix_enable;
Shivasharan S81b76452018-10-16 23:37:51 -07005306 u32 scratch_pad_1, scratch_pad_2, scratch_pad_3, status_reg;
Ben Collins11f8a7b2013-09-13 12:46:44 -04005307 resource_size_t base_addr;
adam radfordcd50ba82010-12-21 10:23:23 -08005308 struct megasas_register_set __iomem *reg_set;
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305309 struct megasas_ctrl_info *ctrl_info = NULL;
adam radfordcd50ba82010-12-21 10:23:23 -08005310 unsigned long bar_list;
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05005311 int i, j, loop, fw_msix_count = 0;
adam radford229fe472014-03-10 02:51:56 -07005312 struct IOV_111 *iovPtr;
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305313 struct fusion_context *fusion;
Shivasharan Sde93b402018-10-16 23:37:42 -07005314 bool do_adp_reset = true;
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305315
5316 fusion = instance->ctrl_context;
adam radfordcd50ba82010-12-21 10:23:23 -08005317
5318 /* Find first memory bar */
5319 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
Christophe JAILLET51f90392016-08-21 10:28:25 +02005320 instance->bar = find_first_bit(&bar_list, BITS_PER_LONG);
Yinghai Lue7f85162016-08-05 23:37:34 -07005321 if (pci_request_selected_regions(instance->pdev, 1<<instance->bar,
adam radfordcd50ba82010-12-21 10:23:23 -08005322 "megasas: LSI")) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005323 dev_printk(KERN_DEBUG, &instance->pdev->dev, "IO memory region busy!\n");
adam radfordcd50ba82010-12-21 10:23:23 -08005324 return -EBUSY;
5325 }
5326
Ben Collins11f8a7b2013-09-13 12:46:44 -04005327 base_addr = pci_resource_start(instance->pdev, instance->bar);
5328 instance->reg_set = ioremap_nocache(base_addr, 8192);
adam radfordcd50ba82010-12-21 10:23:23 -08005329
5330 if (!instance->reg_set) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005331 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to map IO mem\n");
adam radfordcd50ba82010-12-21 10:23:23 -08005332 goto fail_ioremap;
5333 }
5334
5335 reg_set = instance->reg_set;
5336
Shivasharan Se7d36b82017-10-19 02:48:50 -07005337 if (instance->adapter_type != MFI_SERIES)
adam radford9c915a82010-12-21 13:34:31 -08005338 instance->instancet = &megasas_instance_template_fusion;
Sasikumar Chandrasekaran9581ebe2017-01-10 18:20:49 -05005339 else {
5340 switch (instance->pdev->device) {
5341 case PCI_DEVICE_ID_LSI_SAS1078R:
5342 case PCI_DEVICE_ID_LSI_SAS1078DE:
5343 instance->instancet = &megasas_instance_template_ppc;
5344 break;
5345 case PCI_DEVICE_ID_LSI_SAS1078GEN2:
5346 case PCI_DEVICE_ID_LSI_SAS0079GEN2:
5347 instance->instancet = &megasas_instance_template_gen2;
5348 break;
5349 case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
5350 case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
5351 instance->instancet = &megasas_instance_template_skinny;
5352 break;
5353 case PCI_DEVICE_ID_LSI_SAS1064R:
5354 case PCI_DEVICE_ID_DELL_PERC5:
5355 default:
5356 instance->instancet = &megasas_instance_template_xscale;
5357 instance->pd_list_not_supported = 1;
5358 break;
5359 }
adam radfordcd50ba82010-12-21 10:23:23 -08005360 }
5361
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05305362 if (megasas_transition_to_ready(instance, 0)) {
Shivasharan Sde93b402018-10-16 23:37:42 -07005363 if (instance->adapter_type >= INVADER_SERIES) {
5364 status_reg = instance->instancet->read_fw_status_reg(
5365 instance->reg_set);
5366 do_adp_reset = status_reg & MFI_RESET_ADAPTER;
5367 }
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05305368
Shivasharan Sde93b402018-10-16 23:37:42 -07005369 if (do_adp_reset) {
5370 atomic_set(&instance->fw_reset_no_pci_access, 1);
5371 instance->instancet->adp_reset
5372 (instance, instance->reg_set);
5373 atomic_set(&instance->fw_reset_no_pci_access, 0);
5374 dev_info(&instance->pdev->dev,
5375 "FW restarted successfully from %s!\n",
5376 __func__);
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05305377
Shivasharan Sde93b402018-10-16 23:37:42 -07005378 /*waiting for about 30 second before retry*/
5379 ssleep(30);
5380
5381 if (megasas_transition_to_ready(instance, 0))
5382 goto fail_ready_state;
5383 } else {
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05305384 goto fail_ready_state;
Shivasharan Sde93b402018-10-16 23:37:42 -07005385 }
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05305386 }
adam radfordcd50ba82010-12-21 10:23:23 -08005387
Shivasharan Se5d65b42017-10-19 02:48:59 -07005388 megasas_init_ctrl_params(instance);
5389
Shivasharan S107a60d2017-10-19 02:49:05 -07005390 if (megasas_set_dma_mask(instance))
Shivasharan Se5d65b42017-10-19 02:48:59 -07005391 goto fail_ready_state;
5392
5393 if (megasas_alloc_ctrl_mem(instance))
5394 goto fail_alloc_dma_buf;
5395
5396 if (megasas_alloc_ctrl_dma_buffers(instance))
5397 goto fail_alloc_dma_buf;
5398
5399 fusion = instance->ctrl_context;
5400
Shivasharan S630d42b2018-12-17 00:47:37 -08005401 if (instance->adapter_type >= VENTURA_SERIES) {
Shivasharan S81b76452018-10-16 23:37:51 -07005402 scratch_pad_2 =
5403 readl(&instance->reg_set->outbound_scratch_pad_2);
5404 instance->max_raid_mapsize = ((scratch_pad_2 >>
Sasikumar Chandrasekarand8893442017-01-10 18:20:48 -05005405 MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) &
5406 MR_MAX_RAID_MAP_SIZE_MASK);
5407 }
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305408
adam radford3f1abce2011-05-11 18:33:47 -07005409 /* Check if MSI-X is supported while in ready state */
5410 msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
5411 0x4000000) >> 0x1a;
adam radfordc8e858f2011-10-08 18:15:13 -07005412 if (msix_enable && !msix_disable) {
Hannes Reineckefad119b2016-12-02 12:52:23 +01005413 int irq_flags = PCI_IRQ_MSIX;
5414
Shivasharan S81b76452018-10-16 23:37:51 -07005415 scratch_pad_1 = readl
5416 (&instance->reg_set->outbound_scratch_pad_1);
adam radfordc8e858f2011-10-08 18:15:13 -07005417 /* Check max MSI-X vectors */
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305418 if (fusion) {
Shivasharan Sc3651782017-10-19 02:48:48 -07005419 if (instance->adapter_type == THUNDERBOLT_SERIES) {
5420 /* Thunderbolt Series*/
Shivasharan S81b76452018-10-16 23:37:51 -07005421 instance->msix_vectors = (scratch_pad_1
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305422 & MR_MAX_REPLY_QUEUES_OFFSET) + 1;
5423 fw_msix_count = instance->msix_vectors;
Shivasharan Se29c3222018-10-16 23:37:46 -07005424 } else {
Shivasharan S81b76452018-10-16 23:37:51 -07005425 instance->msix_vectors = ((scratch_pad_1
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305426 & MR_MAX_REPLY_QUEUES_EXT_OFFSET)
5427 >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
Shivasharan Se29c3222018-10-16 23:37:46 -07005428
5429 /*
5430 * For Invader series, > 8 MSI-x vectors
5431 * supported by FW/HW implies combined
5432 * reply queue mode is enabled.
5433 * For Ventura series, > 16 MSI-x vectors
5434 * supported by FW/HW implies combined
5435 * reply queue mode is enabled.
5436 */
5437 switch (instance->adapter_type) {
5438 case INVADER_SERIES:
5439 if (instance->msix_vectors > 8)
5440 instance->msix_combined = true;
5441 break;
5442 case VENTURA_SERIES:
5443 if (instance->msix_vectors > 16)
5444 instance->msix_combined = true;
5445 break;
5446 }
Sasikumar Chandrasekaran2493c672017-01-10 18:20:44 -05005447
Sumit Saxena179ac142016-01-28 21:04:28 +05305448 if (rdpq_enable)
Shivasharan S81b76452018-10-16 23:37:51 -07005449 instance->is_rdpq = (scratch_pad_1 & MR_RDPQ_MODE_OFFSET) ?
Sumit Saxena179ac142016-01-28 21:04:28 +05305450 1 : 0;
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305451 fw_msix_count = instance->msix_vectors;
5452 /* Save 1-15 reply post index address to local memory
5453 * Index 0 is already saved from reg offset
5454 * MPI2_REPLY_POST_HOST_INDEX_OFFSET
5455 */
5456 for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
5457 instance->reply_post_host_index_addr[loop] =
5458 (u32 __iomem *)
5459 ((u8 __iomem *)instance->reg_set +
5460 MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
5461 + (loop * 0x10));
5462 }
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305463 }
5464 if (msix_vectors)
5465 instance->msix_vectors = min(msix_vectors,
5466 instance->msix_vectors);
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05305467 } else /* MFI adapters */
adam radfordc8e858f2011-10-08 18:15:13 -07005468 instance->msix_vectors = 1;
5469 /* Don't bother allocating more MSI-X vectors than cpus */
5470 instance->msix_vectors = min(instance->msix_vectors,
5471 (unsigned int)num_online_cpus());
Hannes Reineckefad119b2016-12-02 12:52:23 +01005472 if (smp_affinity_enable)
5473 irq_flags |= PCI_IRQ_AFFINITY;
5474 i = pci_alloc_irq_vectors(instance->pdev, 1,
5475 instance->msix_vectors, irq_flags);
Jiang Liuc12de882014-11-03 20:44:20 +08005476 if (i > 0)
Alexander Gordeev8ae80ed2014-08-18 08:01:44 +02005477 instance->msix_vectors = i;
5478 else
adam radfordc8e858f2011-10-08 18:15:13 -07005479 instance->msix_vectors = 0;
5480 }
Sasikumar Chandrasekaran2493c672017-01-10 18:20:44 -05005481 /*
5482 * MSI-X host index 0 is common for all adapter.
5483 * It is used for all MPT based Adapters.
5484 */
5485 if (instance->msix_combined) {
5486 instance->reply_post_host_index_addr[0] =
5487 (u32 *)((u8 *)instance->reg_set +
5488 MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET);
5489 } else {
5490 instance->reply_post_host_index_addr[0] =
5491 (u32 *)((u8 *)instance->reg_set +
5492 MPI2_REPLY_POST_HOST_INDEX_OFFSET);
5493 }
5494
Shivasharan S64ff64b2017-03-10 03:22:12 -08005495 if (!instance->msix_vectors) {
5496 i = pci_alloc_irq_vectors(instance->pdev, 1, 1, PCI_IRQ_LEGACY);
5497 if (i < 0)
Shivasharan S8a25fa12018-10-16 23:37:44 -07005498 goto fail_init_adapter;
Shivasharan S64ff64b2017-03-10 03:22:12 -08005499 }
adam radford3f1abce2011-05-11 18:33:47 -07005500
Ming Leiadbe5522018-03-13 17:42:40 +08005501 megasas_setup_reply_map(instance);
5502
Tomas Henzl258c3af2015-06-02 16:09:46 +05305503 dev_info(&instance->pdev->dev,
5504 "firmware supports msix\t: (%d)", fw_msix_count);
5505 dev_info(&instance->pdev->dev,
5506 "current msix/online cpus\t: (%d/%d)\n",
5507 instance->msix_vectors, (unsigned int)num_online_cpus());
Sumit Saxena179ac142016-01-28 21:04:28 +05305508 dev_info(&instance->pdev->dev,
5509 "RDPQ mode\t: (%s)\n", instance->is_rdpq ? "enabled" : "disabled");
Tomas Henzl258c3af2015-06-02 16:09:46 +05305510
sumit.saxena@avagotech.com91626c22015-10-15 13:40:34 +05305511 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
5512 (unsigned long)instance);
5513
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305514 /*
5515 * Below are default value for legacy Firmware.
5516 * non-fusion based controllers
5517 */
5518 instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
5519 instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
adam radfordcd50ba82010-12-21 10:23:23 -08005520 /* Get operational params, sge flags, send init cmd to controller */
5521 if (instance->instancet->init_adapter(instance))
adam radfordeb1b1232011-02-24 20:55:56 -08005522 goto fail_init_adapter;
adam radfordcd50ba82010-12-21 10:23:23 -08005523
Shivasharan S630d42b2018-12-17 00:47:37 -08005524 if (instance->adapter_type >= VENTURA_SERIES) {
Shivasharan S81b76452018-10-16 23:37:51 -07005525 scratch_pad_3 =
5526 readl(&instance->reg_set->outbound_scratch_pad_3);
5527 if ((scratch_pad_3 & MR_NVME_PAGE_SIZE_MASK) >=
Shivasharan S15dd0382017-02-10 00:59:10 -08005528 MR_DEFAULT_NVME_PAGE_SHIFT)
5529 instance->nvme_page_size =
Shivasharan S81b76452018-10-16 23:37:51 -07005530 (1 << (scratch_pad_3 & MR_NVME_PAGE_SIZE_MASK));
Shivasharan S15dd0382017-02-10 00:59:10 -08005531
5532 dev_info(&instance->pdev->dev,
5533 "NVME page size\t: (%d)\n", instance->nvme_page_size);
5534 }
5535
Tomas Henzl18103ef2016-11-01 17:32:02 +01005536 if (instance->msix_vectors ?
5537 megasas_setup_irqs_msix(instance, 1) :
5538 megasas_setup_irqs_ioapic(instance))
5539 goto fail_init_adapter;
Tomas Henzl258c3af2015-06-02 16:09:46 +05305540
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305541 instance->instancet->enable_intr(instance);
adam radfordcd50ba82010-12-21 10:23:23 -08005542
Andy Lutomirski13f30772016-05-03 10:24:31 -07005543 dev_info(&instance->pdev->dev, "INIT adapter done\n");
adam radfordcd50ba82010-12-21 10:23:23 -08005544
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05305545 megasas_setup_jbod_map(instance);
5546
bo yang39a98552010-09-22 22:36:29 -04005547 /** for passthrough
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05005548 * the following function will get the PD LIST.
5549 */
5550 memset(instance->pd_list, 0,
Yang, Bo81e403c2009-10-06 14:27:54 -06005551 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
Hannes Reinecke58968fc2014-01-16 11:25:36 +01005552 if (megasas_get_pd_list(instance) < 0) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005553 dev_err(&instance->pdev->dev, "failed to get PD list\n");
Shivasharan S72bff2d2017-02-10 00:59:33 -08005554 goto fail_get_ld_pd_list;
Hannes Reinecke58968fc2014-01-16 11:25:36 +01005555 }
Yang, Bo81e403c2009-10-06 14:27:54 -06005556
Yang, Bobdc6fb82009-12-06 08:30:19 -07005557 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05005558
5559 /* stream detection initialization */
Shivasharan S630d42b2018-12-17 00:47:37 -08005560 if (instance->adapter_type >= VENTURA_SERIES) {
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05005561 fusion->stream_detect_by_ld =
Kees Cook6396bb22018-06-12 14:03:40 -07005562 kcalloc(MAX_LOGICAL_DRIVES_EXT,
5563 sizeof(struct LD_STREAM_DETECT *),
5564 GFP_KERNEL);
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05005565 if (!fusion->stream_detect_by_ld) {
5566 dev_err(&instance->pdev->dev,
Shivasharan S41064f12017-02-10 00:59:37 -08005567 "unable to allocate stream detection for pool of LDs\n");
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05005568 goto fail_get_ld_pd_list;
5569 }
5570 for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) {
5571 fusion->stream_detect_by_ld[i] =
Shivasharan Se05ee4e2018-01-05 05:27:36 -08005572 kzalloc(sizeof(struct LD_STREAM_DETECT),
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05005573 GFP_KERNEL);
5574 if (!fusion->stream_detect_by_ld[i]) {
5575 dev_err(&instance->pdev->dev,
5576 "unable to allocate stream detect by LD\n ");
5577 for (j = 0; j < i; ++j)
5578 kfree(fusion->stream_detect_by_ld[j]);
5579 kfree(fusion->stream_detect_by_ld);
5580 fusion->stream_detect_by_ld = NULL;
5581 goto fail_get_ld_pd_list;
5582 }
5583 fusion->stream_detect_by_ld[i]->mru_bit_map
5584 = MR_STREAM_BITMAP;
5585 }
5586 }
5587
adam radford21c9e162013-09-06 15:27:14 -07005588 if (megasas_ld_list_query(instance,
5589 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
Shivasharan S72bff2d2017-02-10 00:59:33 -08005590 goto fail_get_ld_pd_list;
Yang, Bobdc6fb82009-12-06 08:30:19 -07005591
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005592 /*
5593 * Compute the max allowed sectors per IO: The controller info has two
5594 * limits on max sectors. Driver should use the minimum of these two.
5595 *
5596 * 1 << stripe_sz_ops.min = max sectors per strip
5597 *
5598 * Note that older firmwares ( < FW ver 30) didn't report information
5599 * to calculate max_sectors_1. So the number ended up as zero always.
5600 */
bo yang14faea92007-11-09 04:14:00 -05005601 tmp_sectors = 0;
Shivasharan S9ad18a92017-10-19 02:48:57 -07005602 ctrl_info = instance->ctrl_info_buf;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005603
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305604 max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
5605 le16_to_cpu(ctrl_info->max_strips_per_io);
5606 max_sectors_2 = le32_to_cpu(ctrl_info->max_request_size);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005607
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05005608 tmp_sectors = min_t(u32, max_sectors_1, max_sectors_2);
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05305609
Sumit Saxena8f67c8c2016-01-28 21:14:25 +05305610 instance->peerIsPresent = ctrl_info->cluster.peerIsPresent;
5611 instance->passive = ctrl_info->cluster.passive;
5612 memcpy(instance->clusterId, ctrl_info->clusterId, sizeof(instance->clusterId));
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305613 instance->UnevenSpanSupport =
5614 ctrl_info->adapterOperations2.supportUnevenSpans;
5615 if (instance->UnevenSpanSupport) {
5616 struct fusion_context *fusion = instance->ctrl_context;
Shivasharan S5f19f7c2018-01-05 05:27:44 -08005617 if (MR_ValidateMapInfo(instance, instance->map_id))
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305618 fusion->fast_path_io = 1;
5619 else
5620 fusion->fast_path_io = 0;
5621
5622 }
5623 if (ctrl_info->host_interface.SRIOV) {
sumit.saxena@avagotech.com92bb6502015-08-31 17:24:11 +05305624 instance->requestorId = ctrl_info->iov.requestorId;
5625 if (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) {
5626 if (!ctrl_info->adapterOperations2.activePassive)
5627 instance->PlasmaFW111 = 1;
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305628
sumit.saxena@avagotech.com92bb6502015-08-31 17:24:11 +05305629 dev_info(&instance->pdev->dev, "SR-IOV: firmware type: %s\n",
5630 instance->PlasmaFW111 ? "1.11" : "new");
5631
5632 if (instance->PlasmaFW111) {
5633 iovPtr = (struct IOV_111 *)
5634 ((unsigned char *)ctrl_info + IOV_111_OFFSET);
5635 instance->requestorId = iovPtr->requestorId;
5636 }
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05305637 }
sumit.saxena@avagotech.com92bb6502015-08-31 17:24:11 +05305638 dev_info(&instance->pdev->dev, "SRIOV: VF requestorId %d\n",
5639 instance->requestorId);
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305640 }
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05305641
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305642 instance->crash_dump_fw_support =
5643 ctrl_info->adapterOperations3.supportCrashDump;
5644 instance->crash_dump_drv_support =
5645 (instance->crash_dump_fw_support &&
5646 instance->crash_dump_buf);
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05305647 if (instance->crash_dump_drv_support)
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305648 megasas_set_crash_dump_params(instance,
5649 MR_CRASH_BUF_TURN_OFF);
adam radford229fe472014-03-10 02:51:56 -07005650
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05305651 else {
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305652 if (instance->crash_dump_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02005653 dma_free_coherent(&instance->pdev->dev,
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05305654 CRASH_DMA_BUF_SIZE,
5655 instance->crash_dump_buf,
5656 instance->crash_dump_h);
5657 instance->crash_dump_buf = NULL;
bo yang14faea92007-11-09 04:14:00 -05005658 }
Sumit.Saxena@avagotech.com7497cde2015-01-05 20:06:03 +05305659
Shivasharan Sf0c21df2018-10-16 23:37:40 -07005660 if (instance->snapdump_wait_time) {
5661 megasas_get_snapdump_properties(instance);
5662 dev_info(&instance->pdev->dev, "Snap dump wait time\t: %d\n",
5663 instance->snapdump_wait_time);
5664 }
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05305665
5666 dev_info(&instance->pdev->dev,
5667 "pci id\t\t: (0x%04x)/(0x%04x)/(0x%04x)/(0x%04x)\n",
5668 le16_to_cpu(ctrl_info->pci.vendor_id),
5669 le16_to_cpu(ctrl_info->pci.device_id),
5670 le16_to_cpu(ctrl_info->pci.sub_vendor_id),
5671 le16_to_cpu(ctrl_info->pci.sub_device_id));
5672 dev_info(&instance->pdev->dev, "unevenspan support : %s\n",
5673 instance->UnevenSpanSupport ? "yes" : "no");
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05305674 dev_info(&instance->pdev->dev, "firmware crash dump : %s\n",
5675 instance->crash_dump_drv_support ? "yes" : "no");
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05305676 dev_info(&instance->pdev->dev, "jbod sync map : %s\n",
5677 instance->use_seqnum_jbod_fp ? "yes" : "no");
Sumit.Saxena@avagotech.comd88da092015-04-23 16:31:09 +05305678
bo yang14faea92007-11-09 04:14:00 -05005679 instance->max_sectors_per_req = instance->max_num_sge *
sumit.saxena@avagotech.com357ae962015-10-15 13:40:04 +05305680 SGE_BUFFER_SIZE / 512;
bo yang14faea92007-11-09 04:14:00 -05005681 if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
5682 instance->max_sectors_per_req = tmp_sectors;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005683
Sumit.Saxena@avagotech.comae09a6c2015-01-05 20:06:23 +05305684 /* Check for valid throttlequeuedepth module parameter */
5685 if (throttlequeuedepth &&
5686 throttlequeuedepth <= instance->max_scsi_cmds)
5687 instance->throttlequeuedepth = throttlequeuedepth;
5688 else
5689 instance->throttlequeuedepth =
5690 MEGASAS_THROTTLE_QUEUE_DEPTH;
5691
Shivasharan Se636a7a2017-08-23 04:46:56 -07005692 if ((resetwaittime < 1) ||
5693 (resetwaittime > MEGASAS_RESET_WAIT_TIME))
Sumit Saxenae3d178c2016-01-28 21:04:34 +05305694 resetwaittime = MEGASAS_RESET_WAIT_TIME;
5695
5696 if ((scmd_timeout < 10) || (scmd_timeout > MEGASAS_DEFAULT_CMD_TIMEOUT))
5697 scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT;
bo yangad84db22007-11-09 04:40:16 -05005698
adam radford229fe472014-03-10 02:51:56 -07005699 /* Launch SR-IOV heartbeat timer */
5700 if (instance->requestorId) {
Shivasharan S2e47e4e2018-10-16 23:37:48 -07005701 if (!megasas_sriov_start_heartbeat(instance, 1)) {
Kees Cookc251a7b2017-10-22 15:30:04 -07005702 megasas_start_timer(instance);
Shivasharan S2e47e4e2018-10-16 23:37:48 -07005703 } else {
adam radford229fe472014-03-10 02:51:56 -07005704 instance->skip_heartbeat_timer_del = 1;
Shivasharan S2e47e4e2018-10-16 23:37:48 -07005705 goto fail_get_ld_pd_list;
5706 }
adam radford229fe472014-03-10 02:51:56 -07005707 }
5708
Shivasharan S3f6194a2018-10-16 23:37:39 -07005709 /*
5710 * Create and start watchdog thread which will monitor
5711 * controller state every 1 sec and trigger OCR when
5712 * it enters fault state
5713 */
5714 if (instance->adapter_type != MFI_SERIES)
5715 if (megasas_fusion_start_watchdog(instance) != SUCCESS)
5716 goto fail_start_watchdog;
5717
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005718 return 0;
5719
Shivasharan S3f6194a2018-10-16 23:37:39 -07005720fail_start_watchdog:
5721 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
5722 del_timer_sync(&instance->sriov_heartbeat_timer);
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05005723fail_get_ld_pd_list:
5724 instance->instancet->disable_intr(instance);
Hannes Reineckefad119b2016-12-02 12:52:23 +01005725 megasas_destroy_irqs(instance);
Shivasharan S8a25fa12018-10-16 23:37:44 -07005726fail_init_adapter:
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305727 if (instance->msix_vectors)
Hannes Reineckefad119b2016-12-02 12:52:23 +01005728 pci_free_irq_vectors(instance->pdev);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05305729 instance->msix_vectors = 0;
Shivasharan Se5d65b42017-10-19 02:48:59 -07005730fail_alloc_dma_buf:
5731 megasas_free_ctrl_dma_buffers(instance);
5732 megasas_free_ctrl_mem(instance);
adam radfordcd50ba82010-12-21 10:23:23 -08005733fail_ready_state:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005734 iounmap(instance->reg_set);
5735
Shivasharan S72bff2d2017-02-10 00:59:33 -08005736fail_ioremap:
Yinghai Lue7f85162016-08-05 23:37:34 -07005737 pci_release_selected_regions(instance->pdev, 1<<instance->bar);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005738
Shivasharan S72bff2d2017-02-10 00:59:33 -08005739 dev_err(&instance->pdev->dev, "Failed from %s %d\n",
5740 __func__, __LINE__);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005741 return -EINVAL;
5742}
5743
5744/**
5745 * megasas_release_mfi - Reverses the FW initialization
Geert Uytterhoeven4b63b282015-03-03 11:58:07 +01005746 * @instance: Adapter soft state
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005747 */
5748static void megasas_release_mfi(struct megasas_instance *instance)
5749{
adam radford9c915a82010-12-21 13:34:31 -08005750 u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005751
adam radford9c915a82010-12-21 13:34:31 -08005752 if (instance->reply_queue)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02005753 dma_free_coherent(&instance->pdev->dev, reply_q_sz,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005754 instance->reply_queue, instance->reply_queue_h);
5755
5756 megasas_free_cmds(instance);
5757
5758 iounmap(instance->reg_set);
5759
Yinghai Lue7f85162016-08-05 23:37:34 -07005760 pci_release_selected_regions(instance->pdev, 1<<instance->bar);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005761}
5762
5763/**
5764 * megasas_get_seq_num - Gets latest event sequence numbers
5765 * @instance: Adapter soft state
5766 * @eli: FW event log sequence numbers information
5767 *
5768 * FW maintains a log of all events in a non-volatile area. Upper layers would
5769 * usually find out the latest sequence number of the events, the seq number at
5770 * the boot etc. They would "read" all the events below the latest seq number
5771 * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq
5772 * number), they would subsribe to AEN (asynchronous event notification) and
5773 * wait for the events to happen.
5774 */
5775static int
5776megasas_get_seq_num(struct megasas_instance *instance,
5777 struct megasas_evt_log_info *eli)
5778{
5779 struct megasas_cmd *cmd;
5780 struct megasas_dcmd_frame *dcmd;
5781 struct megasas_evt_log_info *el_info;
5782 dma_addr_t el_info_h = 0;
Shivasharan Sb051cc62018-01-05 05:27:38 -08005783 int ret;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005784
5785 cmd = megasas_get_cmd(instance);
5786
5787 if (!cmd) {
5788 return -ENOMEM;
5789 }
5790
5791 dcmd = &cmd->frame->dcmd;
Christoph Hellwig60ee6522018-10-10 19:31:25 +02005792 el_info = dma_zalloc_coherent(&instance->pdev->dev,
5793 sizeof(struct megasas_evt_log_info), &el_info_h,
5794 GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005795 if (!el_info) {
5796 megasas_return_cmd(instance, cmd);
5797 return -ENOMEM;
5798 }
5799
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005800 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
5801
5802 dcmd->cmd = MFI_CMD_DCMD;
5803 dcmd->cmd_status = 0x0;
5804 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07005805 dcmd->flags = MFI_FRAME_DIR_READ;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005806 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07005807 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305808 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_log_info));
5809 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_EVENT_GET_INFO);
Shivasharan S107a60d2017-10-19 02:49:05 -07005810
5811 megasas_set_dma_settings(instance, dcmd, el_info_h,
5812 sizeof(struct megasas_evt_log_info));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005813
Shivasharan Sb051cc62018-01-05 05:27:38 -08005814 ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
5815 if (ret != DCMD_SUCCESS) {
5816 dev_err(&instance->pdev->dev, "Failed from %s %d\n",
5817 __func__, __LINE__);
5818 goto dcmd_failed;
5819 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005820
Shivasharan Sb051cc62018-01-05 05:27:38 -08005821 /*
5822 * Copy the data back into callers buffer
5823 */
5824 eli->newest_seq_num = el_info->newest_seq_num;
5825 eli->oldest_seq_num = el_info->oldest_seq_num;
5826 eli->clear_seq_num = el_info->clear_seq_num;
5827 eli->shutdown_seq_num = el_info->shutdown_seq_num;
5828 eli->boot_seq_num = el_info->boot_seq_num;
5829
5830dcmd_failed:
Christoph Hellwig60ee6522018-10-10 19:31:25 +02005831 dma_free_coherent(&instance->pdev->dev,
5832 sizeof(struct megasas_evt_log_info),
5833 el_info, el_info_h);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005834
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05305835 megasas_return_cmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005836
Shivasharan Sb051cc62018-01-05 05:27:38 -08005837 return ret;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005838}
5839
5840/**
5841 * megasas_register_aen - Registers for asynchronous event notification
5842 * @instance: Adapter soft state
5843 * @seq_num: The starting sequence number
5844 * @class_locale: Class of the event
5845 *
5846 * This function subscribes for AEN for events beyond the @seq_num. It requests
5847 * to be notified if and only if the event is of type @class_locale
5848 */
5849static int
5850megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
5851 u32 class_locale_word)
5852{
5853 int ret_val;
5854 struct megasas_cmd *cmd;
5855 struct megasas_dcmd_frame *dcmd;
5856 union megasas_evt_class_locale curr_aen;
5857 union megasas_evt_class_locale prev_aen;
5858
5859 /*
5860 * If there an AEN pending already (aen_cmd), check if the
5861 * class_locale of that pending AEN is inclusive of the new
5862 * AEN request we currently have. If it is, then we don't have
5863 * to do anything. In other words, whichever events the current
5864 * AEN request is subscribing to, have already been subscribed
5865 * to.
5866 *
5867 * If the old_cmd is _not_ inclusive, then we have to abort
5868 * that command, form a class_locale that is superset of both
5869 * old and current and re-issue to the FW
5870 */
5871
5872 curr_aen.word = class_locale_word;
5873
5874 if (instance->aen_cmd) {
5875
Christoph Hellwiga9555532015-04-23 16:34:24 +05305876 prev_aen.word =
5877 le32_to_cpu(instance->aen_cmd->frame->dcmd.mbox.w[1]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005878
Shivasharan S91b3d9f2017-08-23 04:47:01 -07005879 if ((curr_aen.members.class < MFI_EVT_CLASS_DEBUG) ||
5880 (curr_aen.members.class > MFI_EVT_CLASS_DEAD)) {
5881 dev_info(&instance->pdev->dev,
5882 "%s %d out of range class %d send by application\n",
5883 __func__, __LINE__, curr_aen.members.class);
5884 return 0;
5885 }
5886
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005887 /*
5888 * A class whose enum value is smaller is inclusive of all
5889 * higher values. If a PROGRESS (= -1) was previously
5890 * registered, then a new registration requests for higher
5891 * classes need not be sent to FW. They are automatically
5892 * included.
5893 *
5894 * Locale numbers don't have such hierarchy. They are bitmap
5895 * values
5896 */
5897 if ((prev_aen.members.class <= curr_aen.members.class) &&
Sumit.Saxena@lsi.com3993a862013-09-16 15:18:06 +05305898 !((prev_aen.members.locale & curr_aen.members.locale) ^
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005899 curr_aen.members.locale)) {
5900 /*
5901 * Previously issued event registration includes
5902 * current request. Nothing to do.
5903 */
5904 return 0;
5905 } else {
Sumit.Saxena@lsi.com3993a862013-09-16 15:18:06 +05305906 curr_aen.members.locale |= prev_aen.members.locale;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005907
5908 if (prev_aen.members.class < curr_aen.members.class)
5909 curr_aen.members.class = prev_aen.members.class;
5910
5911 instance->aen_cmd->abort_aen = 1;
5912 ret_val = megasas_issue_blocked_abort_cmd(instance,
5913 instance->
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305914 aen_cmd, 30);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005915
5916 if (ret_val) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05005917 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to abort "
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005918 "previous AEN command\n");
5919 return ret_val;
5920 }
5921 }
5922 }
5923
5924 cmd = megasas_get_cmd(instance);
5925
5926 if (!cmd)
5927 return -ENOMEM;
5928
5929 dcmd = &cmd->frame->dcmd;
5930
5931 memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail));
5932
5933 /*
5934 * Prepare DCMD for aen registration
5935 */
5936 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
5937
5938 dcmd->cmd = MFI_CMD_DCMD;
5939 dcmd->cmd_status = 0x0;
5940 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07005941 dcmd->flags = MFI_FRAME_DIR_READ;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005942 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07005943 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305944 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_detail));
5945 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_EVENT_WAIT);
5946 dcmd->mbox.w[0] = cpu_to_le32(seq_num);
bo yang39a98552010-09-22 22:36:29 -04005947 instance->last_seq_num = seq_num;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305948 dcmd->mbox.w[1] = cpu_to_le32(curr_aen.word);
Shivasharan S107a60d2017-10-19 02:49:05 -07005949
5950 megasas_set_dma_settings(instance, dcmd, instance->evt_detail_h,
5951 sizeof(struct megasas_evt_detail));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005952
Yang, Bof4c9a132009-10-06 14:43:28 -06005953 if (instance->aen_cmd != NULL) {
5954 megasas_return_cmd(instance, cmd);
5955 return 0;
5956 }
5957
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005958 /*
5959 * Store reference to the cmd used to register for AEN. When an
5960 * application wants us to register for AEN, we have to abort this
5961 * cmd and re-register with a new EVENT LOCALE supplied by that app
5962 */
5963 instance->aen_cmd = cmd;
5964
5965 /*
5966 * Issue the aen registration frame
5967 */
adam radford9c915a82010-12-21 13:34:31 -08005968 instance->instancet->issue_dcmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005969
5970 return 0;
5971}
5972
Shivasharan S96188a82017-02-10 00:59:11 -08005973/* megasas_get_target_prop - Send DCMD with below details to firmware.
5974 *
5975 * This DCMD will fetch few properties of LD/system PD defined
5976 * in MR_TARGET_DEV_PROPERTIES. eg. Queue Depth, MDTS value.
5977 *
5978 * DCMD send by drivers whenever new target is added to the OS.
5979 *
5980 * dcmd.opcode - MR_DCMD_DEV_GET_TARGET_PROP
5981 * dcmd.mbox.b[0] - DCMD is to be fired for LD or system PD.
5982 * 0 = system PD, 1 = LD.
5983 * dcmd.mbox.s[1] - TargetID for LD/system PD.
5984 * dcmd.sge IN - Pointer to return MR_TARGET_DEV_PROPERTIES.
5985 *
5986 * @instance: Adapter soft state
5987 * @sdev: OS provided scsi device
5988 *
5989 * Returns 0 on success non-zero on failure.
5990 */
Shivasharan Se9495e22018-06-04 03:45:12 -07005991int
Shivasharan S96188a82017-02-10 00:59:11 -08005992megasas_get_target_prop(struct megasas_instance *instance,
5993 struct scsi_device *sdev)
5994{
5995 int ret;
5996 struct megasas_cmd *cmd;
5997 struct megasas_dcmd_frame *dcmd;
5998 u16 targetId = (sdev->channel % 2) + sdev->id;
5999
6000 cmd = megasas_get_cmd(instance);
6001
6002 if (!cmd) {
6003 dev_err(&instance->pdev->dev,
6004 "Failed to get cmd %s\n", __func__);
6005 return -ENOMEM;
6006 }
6007
6008 dcmd = &cmd->frame->dcmd;
6009
6010 memset(instance->tgt_prop, 0, sizeof(*instance->tgt_prop));
6011 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
6012 dcmd->mbox.b[0] = MEGASAS_IS_LOGICAL(sdev);
6013
6014 dcmd->mbox.s[1] = cpu_to_le16(targetId);
6015 dcmd->cmd = MFI_CMD_DCMD;
6016 dcmd->cmd_status = 0xFF;
6017 dcmd->sge_count = 1;
Shivasharan S107a60d2017-10-19 02:49:05 -07006018 dcmd->flags = MFI_FRAME_DIR_READ;
Shivasharan S96188a82017-02-10 00:59:11 -08006019 dcmd->timeout = 0;
6020 dcmd->pad_0 = 0;
6021 dcmd->data_xfer_len =
6022 cpu_to_le32(sizeof(struct MR_TARGET_PROPERTIES));
6023 dcmd->opcode = cpu_to_le32(MR_DCMD_DRV_GET_TARGET_PROP);
Shivasharan S96188a82017-02-10 00:59:11 -08006024
Shivasharan S107a60d2017-10-19 02:49:05 -07006025 megasas_set_dma_settings(instance, dcmd, instance->tgt_prop_h,
6026 sizeof(struct MR_TARGET_PROPERTIES));
Shivasharan S96188a82017-02-10 00:59:11 -08006027
Shivasharan Se7d36b82017-10-19 02:48:50 -07006028 if ((instance->adapter_type != MFI_SERIES) &&
6029 !instance->mask_interrupts)
Shivasharan S96188a82017-02-10 00:59:11 -08006030 ret = megasas_issue_blocked_cmd(instance,
6031 cmd, MFI_IO_TIMEOUT_SECS);
6032 else
6033 ret = megasas_issue_polled(instance, cmd);
6034
6035 switch (ret) {
6036 case DCMD_TIMEOUT:
6037 switch (dcmd_timeout_ocr_possible(instance)) {
6038 case INITIATE_OCR:
6039 cmd->flags |= DRV_DCMD_SKIP_REFIRE;
6040 megasas_reset_fusion(instance->host,
6041 MFI_IO_TIMEOUT_OCR);
6042 break;
6043 case KILL_ADAPTER:
6044 megaraid_sas_kill_hba(instance);
6045 break;
6046 case IGNORE_TIMEOUT:
6047 dev_info(&instance->pdev->dev,
6048 "Ignore DCMD timeout: %s %d\n",
6049 __func__, __LINE__);
6050 break;
6051 }
6052 break;
6053
6054 default:
6055 megasas_return_cmd(instance, cmd);
6056 }
6057 if (ret != DCMD_SUCCESS)
6058 dev_err(&instance->pdev->dev,
6059 "return from %s %d return value %d\n",
6060 __func__, __LINE__, ret);
6061
6062 return ret;
6063}
6064
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006065/**
6066 * megasas_start_aen - Subscribes to AEN during driver load time
6067 * @instance: Adapter soft state
6068 */
6069static int megasas_start_aen(struct megasas_instance *instance)
6070{
6071 struct megasas_evt_log_info eli;
6072 union megasas_evt_class_locale class_locale;
6073
6074 /*
6075 * Get the latest sequence number from FW
6076 */
6077 memset(&eli, 0, sizeof(eli));
6078
6079 if (megasas_get_seq_num(instance, &eli))
6080 return -1;
6081
6082 /*
6083 * Register AEN with FW for latest sequence number plus 1
6084 */
6085 class_locale.members.reserved = 0;
6086 class_locale.members.locale = MR_EVT_LOCALE_ALL;
6087 class_locale.members.class = MR_EVT_CLASS_DEBUG;
6088
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306089 return megasas_register_aen(instance,
Christoph Hellwig48100b02015-04-23 16:33:24 +05306090 le32_to_cpu(eli.newest_seq_num) + 1,
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306091 class_locale.word);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006092}
6093
6094/**
6095 * megasas_io_attach - Attaches this driver to SCSI mid-layer
6096 * @instance: Adapter soft state
6097 */
6098static int megasas_io_attach(struct megasas_instance *instance)
6099{
6100 struct Scsi_Host *host = instance->host;
6101
6102 /*
6103 * Export parameters required by SCSI mid-layer
6104 */
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006105 host->unique_id = instance->unique_id;
Sumit.Saxena@avagotech.comae09a6c2015-01-05 20:06:23 +05306106 host->can_queue = instance->max_scsi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006107 host->this_id = instance->init_id;
6108 host->sg_tablesize = instance->max_num_sge;
adam radford42a8d2b2011-02-24 20:57:09 -08006109
6110 if (instance->fw_support_ieee)
6111 instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE;
6112
Yang, Bo1fd10682010-10-12 07:18:50 -06006113 /*
6114 * Check if the module parameter value for max_sectors can be used
6115 */
6116 if (max_sectors && max_sectors < instance->max_sectors_per_req)
6117 instance->max_sectors_per_req = max_sectors;
6118 else {
6119 if (max_sectors) {
6120 if (((instance->pdev->device ==
6121 PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
6122 (instance->pdev->device ==
6123 PCI_DEVICE_ID_LSI_SAS0079GEN2)) &&
6124 (max_sectors <= MEGASAS_MAX_SECTORS)) {
6125 instance->max_sectors_per_req = max_sectors;
6126 } else {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05006127 dev_info(&instance->pdev->dev, "max_sectors should be > 0"
Yang, Bo1fd10682010-10-12 07:18:50 -06006128 "and <= %d (or < 1MB for GEN2 controller)\n",
6129 instance->max_sectors_per_req);
6130 }
6131 }
6132 }
6133
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006134 host->max_sectors = instance->max_sectors_per_req;
adam radford9c915a82010-12-21 13:34:31 -08006135 host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006136 host->max_channel = MEGASAS_MAX_CHANNELS - 1;
6137 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
6138 host->max_lun = MEGASAS_MAX_LUN;
Joshua Giles122da302006-02-03 15:34:17 -08006139 host->max_cmd_len = 16;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006140
6141 /*
6142 * Notify the mid-layer about the new controller
6143 */
6144 if (scsi_add_host(host, &instance->pdev->dev)) {
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05306145 dev_err(&instance->pdev->dev,
6146 "Failed to add host from %s %d\n",
6147 __func__, __LINE__);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006148 return -ENODEV;
6149 }
6150
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006151 return 0;
6152}
6153
Shivasharan S107a60d2017-10-19 02:49:05 -07006154/**
6155 * megasas_set_dma_mask - Set DMA mask for supported controllers
6156 *
6157 * @instance: Adapter soft state
6158 * Description:
6159 *
6160 * For Ventura, driver/FW will operate in 64bit DMA addresses.
6161 *
6162 * For invader-
6163 * By default, driver/FW will operate in 32bit DMA addresses
6164 * for consistent DMA mapping but if 32 bit consistent
6165 * DMA mask fails, driver will try with 64 bit consistent
6166 * mask provided FW is true 64bit DMA capable
6167 *
6168 * For older controllers(Thunderbolt and MFI based adapters)-
6169 * driver/FW will operate in 32 bit consistent DMA addresses.
6170 */
bo yang31ea7082007-11-07 12:09:50 -05006171static int
Shivasharan S107a60d2017-10-19 02:49:05 -07006172megasas_set_dma_mask(struct megasas_instance *instance)
bo yang31ea7082007-11-07 12:09:50 -05006173{
Shivasharan S107a60d2017-10-19 02:49:05 -07006174 u64 consistent_mask;
6175 struct pci_dev *pdev;
Shivasharan S81b76452018-10-16 23:37:51 -07006176 u32 scratch_pad_1;
bo yang31ea7082007-11-07 12:09:50 -05006177
Shivasharan S107a60d2017-10-19 02:49:05 -07006178 pdev = instance->pdev;
Shivasharan S630d42b2018-12-17 00:47:37 -08006179 consistent_mask = (instance->adapter_type >= VENTURA_SERIES) ?
Shivasharan S107a60d2017-10-19 02:49:05 -07006180 DMA_BIT_MASK(64) : DMA_BIT_MASK(32);
6181
6182 if (IS_DMA64) {
6183 if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
6184 dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
6185 goto fail_set_dma_mask;
6186
6187 if ((*pdev->dev.dma_mask == DMA_BIT_MASK(64)) &&
6188 (dma_set_coherent_mask(&pdev->dev, consistent_mask) &&
6189 dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))) {
6190 /*
6191 * If 32 bit DMA mask fails, then try for 64 bit mask
6192 * for FW capable of handling 64 bit DMA.
6193 */
Shivasharan S81b76452018-10-16 23:37:51 -07006194 scratch_pad_1 = readl
6195 (&instance->reg_set->outbound_scratch_pad_1);
Shivasharan S107a60d2017-10-19 02:49:05 -07006196
Shivasharan S81b76452018-10-16 23:37:51 -07006197 if (!(scratch_pad_1 & MR_CAN_HANDLE_64_BIT_DMA_OFFSET))
Shivasharan S107a60d2017-10-19 02:49:05 -07006198 goto fail_set_dma_mask;
6199 else if (dma_set_mask_and_coherent(&pdev->dev,
6200 DMA_BIT_MASK(64)))
bo yang31ea7082007-11-07 12:09:50 -05006201 goto fail_set_dma_mask;
6202 }
Shivasharan S107a60d2017-10-19 02:49:05 -07006203 } else if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
6204 goto fail_set_dma_mask;
6205
6206 if (pdev->dev.coherent_dma_mask == DMA_BIT_MASK(32))
6207 instance->consistent_mask_64bit = false;
6208 else
6209 instance->consistent_mask_64bit = true;
6210
6211 dev_info(&pdev->dev, "%s bit DMA mask and %s bit consistent mask\n",
6212 ((*pdev->dev.dma_mask == DMA_BIT_MASK(64)) ? "64" : "32"),
6213 (instance->consistent_mask_64bit ? "64" : "32"));
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306214
bo yang31ea7082007-11-07 12:09:50 -05006215 return 0;
6216
6217fail_set_dma_mask:
Shivasharan S107a60d2017-10-19 02:49:05 -07006218 dev_err(&pdev->dev, "Failed to set DMA mask\n");
6219 return -1;
6220
bo yang31ea7082007-11-07 12:09:50 -05006221}
6222
Shivasharan Sc3651782017-10-19 02:48:48 -07006223/*
6224 * megasas_set_adapter_type - Set adapter type.
6225 * Supported controllers can be divided in
6226 * 4 categories- enum MR_ADAPTER_TYPE {
6227 * MFI_SERIES = 1,
6228 * THUNDERBOLT_SERIES = 2,
6229 * INVADER_SERIES = 3,
6230 * VENTURA_SERIES = 4,
6231 * };
6232 * @instance: Adapter soft state
6233 * return: void
6234 */
6235static inline void megasas_set_adapter_type(struct megasas_instance *instance)
6236{
Shivasharan S754f1ba2017-10-19 02:48:49 -07006237 if ((instance->pdev->vendor == PCI_VENDOR_ID_DELL) &&
6238 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5)) {
Shivasharan Sc3651782017-10-19 02:48:48 -07006239 instance->adapter_type = MFI_SERIES;
Shivasharan S754f1ba2017-10-19 02:48:49 -07006240 } else {
6241 switch (instance->pdev->device) {
Shivasharan S469f72d2018-11-09 09:47:20 -08006242 case PCI_DEVICE_ID_LSI_AERO_10E1:
6243 case PCI_DEVICE_ID_LSI_AERO_10E2:
6244 case PCI_DEVICE_ID_LSI_AERO_10E5:
6245 case PCI_DEVICE_ID_LSI_AERO_10E6:
Shivasharan S754f1ba2017-10-19 02:48:49 -07006246 case PCI_DEVICE_ID_LSI_VENTURA:
6247 case PCI_DEVICE_ID_LSI_CRUSADER:
6248 case PCI_DEVICE_ID_LSI_HARPOON:
6249 case PCI_DEVICE_ID_LSI_TOMCAT:
6250 case PCI_DEVICE_ID_LSI_VENTURA_4PORT:
6251 case PCI_DEVICE_ID_LSI_CRUSADER_4PORT:
6252 instance->adapter_type = VENTURA_SERIES;
6253 break;
6254 case PCI_DEVICE_ID_LSI_FUSION:
6255 case PCI_DEVICE_ID_LSI_PLASMA:
6256 instance->adapter_type = THUNDERBOLT_SERIES;
6257 break;
6258 case PCI_DEVICE_ID_LSI_INVADER:
6259 case PCI_DEVICE_ID_LSI_INTRUDER:
6260 case PCI_DEVICE_ID_LSI_INTRUDER_24:
6261 case PCI_DEVICE_ID_LSI_CUTLASS_52:
6262 case PCI_DEVICE_ID_LSI_CUTLASS_53:
6263 case PCI_DEVICE_ID_LSI_FURY:
6264 instance->adapter_type = INVADER_SERIES;
6265 break;
6266 default: /* For all other supported controllers */
6267 instance->adapter_type = MFI_SERIES;
6268 break;
6269 }
Shivasharan Sc3651782017-10-19 02:48:48 -07006270 }
6271}
6272
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006273static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance)
6274{
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006275 instance->producer = dma_alloc_coherent(&instance->pdev->dev,
6276 sizeof(u32), &instance->producer_h, GFP_KERNEL);
6277 instance->consumer = dma_alloc_coherent(&instance->pdev->dev,
6278 sizeof(u32), &instance->consumer_h, GFP_KERNEL);
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006279
6280 if (!instance->producer || !instance->consumer) {
6281 dev_err(&instance->pdev->dev,
6282 "Failed to allocate memory for producer, consumer\n");
6283 return -1;
6284 }
6285
6286 *instance->producer = 0;
6287 *instance->consumer = 0;
6288 return 0;
6289}
6290
6291/**
6292 * megasas_alloc_ctrl_mem - Allocate per controller memory for core data
6293 * structures which are not common across MFI
6294 * adapters and fusion adapters.
6295 * For MFI based adapters, allocate producer and
6296 * consumer buffers. For fusion adapters, allocate
6297 * memory for fusion context.
6298 * @instance: Adapter soft state
6299 * return: 0 for SUCCESS
6300 */
6301static int megasas_alloc_ctrl_mem(struct megasas_instance *instance)
6302{
Kees Cook6396bb22018-06-12 14:03:40 -07006303 instance->reply_map = kcalloc(nr_cpu_ids, sizeof(unsigned int),
Ming Leiadbe5522018-03-13 17:42:40 +08006304 GFP_KERNEL);
6305 if (!instance->reply_map)
6306 return -ENOMEM;
6307
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006308 switch (instance->adapter_type) {
6309 case MFI_SERIES:
6310 if (megasas_alloc_mfi_ctrl_mem(instance))
Ming Leiadbe5522018-03-13 17:42:40 +08006311 goto fail;
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006312 break;
6313 case VENTURA_SERIES:
6314 case THUNDERBOLT_SERIES:
6315 case INVADER_SERIES:
6316 if (megasas_alloc_fusion_context(instance))
Ming Leiadbe5522018-03-13 17:42:40 +08006317 goto fail;
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006318 break;
6319 }
6320
6321 return 0;
Ming Leiadbe5522018-03-13 17:42:40 +08006322 fail:
6323 kfree(instance->reply_map);
6324 instance->reply_map = NULL;
6325 return -ENOMEM;
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006326}
6327
6328/*
6329 * megasas_free_ctrl_mem - Free fusion context for fusion adapters and
6330 * producer, consumer buffers for MFI adapters
6331 *
6332 * @instance - Adapter soft instance
6333 *
6334 */
6335static inline void megasas_free_ctrl_mem(struct megasas_instance *instance)
6336{
Ming Leiadbe5522018-03-13 17:42:40 +08006337 kfree(instance->reply_map);
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006338 if (instance->adapter_type == MFI_SERIES) {
6339 if (instance->producer)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006340 dma_free_coherent(&instance->pdev->dev, sizeof(u32),
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006341 instance->producer,
6342 instance->producer_h);
6343 if (instance->consumer)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006344 dma_free_coherent(&instance->pdev->dev, sizeof(u32),
Shivasharan S49a7a4a2017-10-19 02:48:54 -07006345 instance->consumer,
6346 instance->consumer_h);
6347 } else {
6348 megasas_free_fusion_context(instance);
6349 }
6350}
6351
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006352/**
Shivasharan S1b4bed22017-10-19 02:48:55 -07006353 * megasas_alloc_ctrl_dma_buffers - Allocate consistent DMA buffers during
6354 * driver load time
6355 *
6356 * @instance- Adapter soft instance
6357 * @return- O for SUCCESS
6358 */
6359static inline
6360int megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance)
6361{
6362 struct pci_dev *pdev = instance->pdev;
Shivasharan S9b3d0282017-10-19 02:48:56 -07006363 struct fusion_context *fusion = instance->ctrl_context;
Shivasharan S1b4bed22017-10-19 02:48:55 -07006364
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006365 instance->evt_detail = dma_alloc_coherent(&pdev->dev,
6366 sizeof(struct megasas_evt_detail),
6367 &instance->evt_detail_h, GFP_KERNEL);
Shivasharan S1b4bed22017-10-19 02:48:55 -07006368
6369 if (!instance->evt_detail) {
6370 dev_err(&instance->pdev->dev,
6371 "Failed to allocate event detail buffer\n");
6372 return -ENOMEM;
6373 }
6374
Shivasharan S9b3d0282017-10-19 02:48:56 -07006375 if (fusion) {
6376 fusion->ioc_init_request =
6377 dma_alloc_coherent(&pdev->dev,
6378 sizeof(struct MPI2_IOC_INIT_REQUEST),
6379 &fusion->ioc_init_request_phys,
6380 GFP_KERNEL);
6381
6382 if (!fusion->ioc_init_request) {
6383 dev_err(&pdev->dev,
6384 "Failed to allocate PD list buffer\n");
6385 return -ENOMEM;
6386 }
Shivasharan Sf0c21df2018-10-16 23:37:40 -07006387
6388 instance->snapdump_prop = dma_alloc_coherent(&pdev->dev,
6389 sizeof(struct MR_SNAPDUMP_PROPERTIES),
6390 &instance->snapdump_prop_h, GFP_KERNEL);
6391
6392 if (!instance->snapdump_prop)
6393 dev_err(&pdev->dev,
6394 "Failed to allocate snapdump properties buffer\n");
Shivasharan S9b3d0282017-10-19 02:48:56 -07006395 }
6396
6397 instance->pd_list_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006398 dma_alloc_coherent(&pdev->dev,
Shivasharan S9b3d0282017-10-19 02:48:56 -07006399 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006400 &instance->pd_list_buf_h, GFP_KERNEL);
Shivasharan S9b3d0282017-10-19 02:48:56 -07006401
6402 if (!instance->pd_list_buf) {
6403 dev_err(&pdev->dev, "Failed to allocate PD list buffer\n");
6404 return -ENOMEM;
6405 }
6406
6407 instance->ctrl_info_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006408 dma_alloc_coherent(&pdev->dev,
Shivasharan S9b3d0282017-10-19 02:48:56 -07006409 sizeof(struct megasas_ctrl_info),
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006410 &instance->ctrl_info_buf_h, GFP_KERNEL);
Shivasharan S9b3d0282017-10-19 02:48:56 -07006411
6412 if (!instance->ctrl_info_buf) {
6413 dev_err(&pdev->dev,
6414 "Failed to allocate controller info buffer\n");
6415 return -ENOMEM;
6416 }
6417
6418 instance->ld_list_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006419 dma_alloc_coherent(&pdev->dev,
Shivasharan S9b3d0282017-10-19 02:48:56 -07006420 sizeof(struct MR_LD_LIST),
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006421 &instance->ld_list_buf_h, GFP_KERNEL);
Shivasharan S9b3d0282017-10-19 02:48:56 -07006422
6423 if (!instance->ld_list_buf) {
6424 dev_err(&pdev->dev, "Failed to allocate LD list buffer\n");
6425 return -ENOMEM;
6426 }
6427
6428 instance->ld_targetid_list_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006429 dma_alloc_coherent(&pdev->dev,
6430 sizeof(struct MR_LD_TARGETID_LIST),
6431 &instance->ld_targetid_list_buf_h, GFP_KERNEL);
Shivasharan S9b3d0282017-10-19 02:48:56 -07006432
6433 if (!instance->ld_targetid_list_buf) {
6434 dev_err(&pdev->dev,
6435 "Failed to allocate LD targetid list buffer\n");
6436 return -ENOMEM;
6437 }
6438
Shivasharan S1b4bed22017-10-19 02:48:55 -07006439 if (!reset_devices) {
6440 instance->system_info_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006441 dma_alloc_coherent(&pdev->dev,
6442 sizeof(struct MR_DRV_SYSTEM_INFO),
6443 &instance->system_info_h, GFP_KERNEL);
Shivasharan S1b4bed22017-10-19 02:48:55 -07006444 instance->pd_info =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006445 dma_alloc_coherent(&pdev->dev,
6446 sizeof(struct MR_PD_INFO),
6447 &instance->pd_info_h, GFP_KERNEL);
Shivasharan S1b4bed22017-10-19 02:48:55 -07006448 instance->tgt_prop =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006449 dma_alloc_coherent(&pdev->dev,
6450 sizeof(struct MR_TARGET_PROPERTIES),
6451 &instance->tgt_prop_h, GFP_KERNEL);
Shivasharan S1b4bed22017-10-19 02:48:55 -07006452 instance->crash_dump_buf =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006453 dma_alloc_coherent(&pdev->dev, CRASH_DMA_BUF_SIZE,
6454 &instance->crash_dump_h, GFP_KERNEL);
Shivasharan S1b4bed22017-10-19 02:48:55 -07006455
6456 if (!instance->system_info_buf)
6457 dev_err(&instance->pdev->dev,
6458 "Failed to allocate system info buffer\n");
6459
6460 if (!instance->pd_info)
6461 dev_err(&instance->pdev->dev,
6462 "Failed to allocate pd_info buffer\n");
6463
6464 if (!instance->tgt_prop)
6465 dev_err(&instance->pdev->dev,
6466 "Failed to allocate tgt_prop buffer\n");
6467
6468 if (!instance->crash_dump_buf)
6469 dev_err(&instance->pdev->dev,
6470 "Failed to allocate crash dump buffer\n");
6471 }
6472
6473 return 0;
6474}
6475
6476/*
6477 * megasas_free_ctrl_dma_buffers - Free consistent DMA buffers allocated
6478 * during driver load time
6479 *
6480 * @instance- Adapter soft instance
6481 *
6482 */
6483static inline
6484void megasas_free_ctrl_dma_buffers(struct megasas_instance *instance)
6485{
6486 struct pci_dev *pdev = instance->pdev;
Shivasharan S9b3d0282017-10-19 02:48:56 -07006487 struct fusion_context *fusion = instance->ctrl_context;
Shivasharan S1b4bed22017-10-19 02:48:55 -07006488
6489 if (instance->evt_detail)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006490 dma_free_coherent(&pdev->dev, sizeof(struct megasas_evt_detail),
Shivasharan S1b4bed22017-10-19 02:48:55 -07006491 instance->evt_detail,
6492 instance->evt_detail_h);
6493
Shivasharan S9b3d0282017-10-19 02:48:56 -07006494 if (fusion && fusion->ioc_init_request)
6495 dma_free_coherent(&pdev->dev,
6496 sizeof(struct MPI2_IOC_INIT_REQUEST),
6497 fusion->ioc_init_request,
6498 fusion->ioc_init_request_phys);
6499
6500 if (instance->pd_list_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006501 dma_free_coherent(&pdev->dev,
Shivasharan S9b3d0282017-10-19 02:48:56 -07006502 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
6503 instance->pd_list_buf,
6504 instance->pd_list_buf_h);
6505
6506 if (instance->ld_list_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006507 dma_free_coherent(&pdev->dev, sizeof(struct MR_LD_LIST),
Shivasharan S9b3d0282017-10-19 02:48:56 -07006508 instance->ld_list_buf,
6509 instance->ld_list_buf_h);
6510
6511 if (instance->ld_targetid_list_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006512 dma_free_coherent(&pdev->dev, sizeof(struct MR_LD_TARGETID_LIST),
Shivasharan S9b3d0282017-10-19 02:48:56 -07006513 instance->ld_targetid_list_buf,
6514 instance->ld_targetid_list_buf_h);
6515
6516 if (instance->ctrl_info_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006517 dma_free_coherent(&pdev->dev, sizeof(struct megasas_ctrl_info),
Shivasharan S9b3d0282017-10-19 02:48:56 -07006518 instance->ctrl_info_buf,
6519 instance->ctrl_info_buf_h);
6520
Shivasharan S1b4bed22017-10-19 02:48:55 -07006521 if (instance->system_info_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006522 dma_free_coherent(&pdev->dev, sizeof(struct MR_DRV_SYSTEM_INFO),
Shivasharan S1b4bed22017-10-19 02:48:55 -07006523 instance->system_info_buf,
6524 instance->system_info_h);
6525
6526 if (instance->pd_info)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006527 dma_free_coherent(&pdev->dev, sizeof(struct MR_PD_INFO),
Shivasharan S1b4bed22017-10-19 02:48:55 -07006528 instance->pd_info, instance->pd_info_h);
6529
6530 if (instance->tgt_prop)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006531 dma_free_coherent(&pdev->dev, sizeof(struct MR_TARGET_PROPERTIES),
Shivasharan S1b4bed22017-10-19 02:48:55 -07006532 instance->tgt_prop, instance->tgt_prop_h);
6533
6534 if (instance->crash_dump_buf)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006535 dma_free_coherent(&pdev->dev, CRASH_DMA_BUF_SIZE,
Shivasharan S1b4bed22017-10-19 02:48:55 -07006536 instance->crash_dump_buf,
6537 instance->crash_dump_h);
Shivasharan Sf0c21df2018-10-16 23:37:40 -07006538
6539 if (instance->snapdump_prop)
6540 dma_free_coherent(&pdev->dev,
6541 sizeof(struct MR_SNAPDUMP_PROPERTIES),
6542 instance->snapdump_prop,
6543 instance->snapdump_prop_h);
Shivasharan S1b4bed22017-10-19 02:48:55 -07006544}
6545
Shivasharan S7535f272017-10-19 02:48:58 -07006546/*
6547 * megasas_init_ctrl_params - Initialize controller's instance
6548 * parameters before FW init
6549 * @instance - Adapter soft instance
6550 * @return - void
6551 */
6552static inline void megasas_init_ctrl_params(struct megasas_instance *instance)
6553{
6554 instance->fw_crash_state = UNAVAILABLE;
6555
6556 megasas_poll_wait_aen = 0;
6557 instance->issuepend_done = 1;
6558 atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
6559
6560 /*
6561 * Initialize locks and queues
6562 */
6563 INIT_LIST_HEAD(&instance->cmd_pool);
6564 INIT_LIST_HEAD(&instance->internal_reset_pending_q);
6565
6566 atomic_set(&instance->fw_outstanding, 0);
6567
6568 init_waitqueue_head(&instance->int_cmd_wait_q);
6569 init_waitqueue_head(&instance->abort_cmd_wait_q);
6570
6571 spin_lock_init(&instance->crashdump_lock);
6572 spin_lock_init(&instance->mfi_pool_lock);
6573 spin_lock_init(&instance->hba_lock);
6574 spin_lock_init(&instance->stream_lock);
6575 spin_lock_init(&instance->completion_lock);
6576
Shivasharan S7535f272017-10-19 02:48:58 -07006577 mutex_init(&instance->reset_mutex);
6578
6579 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
6580 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY))
6581 instance->flag_ieee = 1;
6582
6583 megasas_dbg_lvl = 0;
6584 instance->flag = 0;
6585 instance->unload = 1;
6586 instance->last_time = 0;
6587 instance->disableOnlineCtrlReset = 1;
6588 instance->UnevenSpanSupport = 0;
6589
Shivasharan S3f6194a2018-10-16 23:37:39 -07006590 if (instance->adapter_type != MFI_SERIES)
Shivasharan S7535f272017-10-19 02:48:58 -07006591 INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
Shivasharan S3f6194a2018-10-16 23:37:39 -07006592 else
Shivasharan S7535f272017-10-19 02:48:58 -07006593 INIT_WORK(&instance->work_init, process_fw_state_change_wq);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006594}
6595
6596/**
6597 * megasas_probe_one - PCI hotplug entry point
6598 * @pdev: PCI device structure
adam radford0d490162010-12-14 19:17:17 -08006599 * @id: PCI ids of supported hotplugged adapter
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006600 */
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08006601static int megasas_probe_one(struct pci_dev *pdev,
6602 const struct pci_device_id *id)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006603{
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05306604 int rval, pos;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006605 struct Scsi_Host *host;
6606 struct megasas_instance *instance;
adam radford66192dfe2011-02-24 20:56:28 -08006607 u16 control = 0;
6608
Shivasharan S469f72d2018-11-09 09:47:20 -08006609 switch (pdev->device) {
6610 case PCI_DEVICE_ID_LSI_AERO_10E1:
6611 case PCI_DEVICE_ID_LSI_AERO_10E5:
6612 dev_info(&pdev->dev, "Adapter is in configurable secure mode\n");
6613 break;
6614 }
6615
adam radford66192dfe2011-02-24 20:56:28 -08006616 /* Reset MSI-X in the kdump kernel */
6617 if (reset_devices) {
6618 pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
6619 if (pos) {
Bjorn Helgaas99369062013-04-17 18:08:44 -06006620 pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS,
adam radford66192dfe2011-02-24 20:56:28 -08006621 &control);
6622 if (control & PCI_MSIX_FLAGS_ENABLE) {
6623 dev_info(&pdev->dev, "resetting MSI-X\n");
6624 pci_write_config_word(pdev,
Bjorn Helgaas99369062013-04-17 18:08:44 -06006625 pos + PCI_MSIX_FLAGS,
adam radford66192dfe2011-02-24 20:56:28 -08006626 control &
6627 ~PCI_MSIX_FLAGS_ENABLE);
6628 }
6629 }
6630 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006631
6632 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006633 * PCI prepping: enable device set bus mastering and dma mask
6634 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09006635 rval = pci_enable_device_mem(pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006636
6637 if (rval) {
6638 return rval;
6639 }
6640
6641 pci_set_master(pdev);
6642
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006643 host = scsi_host_alloc(&megasas_template,
6644 sizeof(struct megasas_instance));
6645
6646 if (!host) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05006647 dev_printk(KERN_DEBUG, &pdev->dev, "scsi_host_alloc failed\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006648 goto fail_alloc_instance;
6649 }
6650
6651 instance = (struct megasas_instance *)host->hostdata;
6652 memset(instance, 0, sizeof(*instance));
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05006653 atomic_set(&instance->fw_reset_no_pci_access, 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006654
6655 /*
6656 * Initialize PCI related and misc parameters
6657 */
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006658 instance->pdev = pdev;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006659 instance->host = host;
6660 instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
6661 instance->init_id = MEGASAS_DEFAULT_INIT_ID;
6662
Shivasharan Sc3651782017-10-19 02:48:48 -07006663 megasas_set_adapter_type(instance);
Sumant Patro658dced2006-10-03 13:09:14 -07006664
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006665 /*
adam radford0a770662011-02-24 20:56:12 -08006666 * Initialize MFI Firmware
6667 */
6668 if (megasas_init_fw(instance))
6669 goto fail_init_mfi;
6670
adam radford229fe472014-03-10 02:51:56 -07006671 if (instance->requestorId) {
6672 if (instance->PlasmaFW111) {
6673 instance->vf_affiliation_111 =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006674 dma_alloc_coherent(&pdev->dev,
6675 sizeof(struct MR_LD_VF_AFFILIATION_111),
6676 &instance->vf_affiliation_111_h,
6677 GFP_KERNEL);
adam radford229fe472014-03-10 02:51:56 -07006678 if (!instance->vf_affiliation_111)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05006679 dev_warn(&pdev->dev, "Can't allocate "
adam radford229fe472014-03-10 02:51:56 -07006680 "memory for VF affiliation buffer\n");
6681 } else {
6682 instance->vf_affiliation =
Christoph Hellwig60ee6522018-10-10 19:31:25 +02006683 dma_alloc_coherent(&pdev->dev,
6684 (MAX_LOGICAL_DRIVES + 1) *
6685 sizeof(struct MR_LD_VF_AFFILIATION),
6686 &instance->vf_affiliation_h,
6687 GFP_KERNEL);
adam radford229fe472014-03-10 02:51:56 -07006688 if (!instance->vf_affiliation)
Bjorn Helgaas1be18252015-07-07 15:52:34 -05006689 dev_warn(&pdev->dev, "Can't allocate "
adam radford229fe472014-03-10 02:51:56 -07006690 "memory for VF affiliation buffer\n");
6691 }
6692 }
6693
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006694 /*
6695 * Store instance in PCI softstate
6696 */
6697 pci_set_drvdata(pdev, instance);
6698
6699 /*
6700 * Add this controller to megasas_mgmt_info structure so that it
6701 * can be exported to management applications
6702 */
6703 megasas_mgmt_info.count++;
6704 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance;
6705 megasas_mgmt_info.max_index++;
6706
6707 /*
adam radford541f90b2011-05-11 18:34:29 -07006708 * Register with SCSI mid-layer
6709 */
6710 if (megasas_io_attach(instance))
6711 goto fail_io_attach;
6712
6713 instance->unload = 0;
Sumit.Saxena@avagotech.comaa008322014-11-17 15:24:08 +05306714 /*
6715 * Trigger SCSI to scan our drives
6716 */
6717 scsi_scan_host(host);
adam radford541f90b2011-05-11 18:34:29 -07006718
6719 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006720 * Initiate AEN (Asynchronous Event Notification)
6721 */
6722 if (megasas_start_aen(instance)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05006723 dev_printk(KERN_DEBUG, &pdev->dev, "start aen failed\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006724 goto fail_start_aen;
6725 }
6726
Adam Radford9ea81f82014-07-09 15:17:57 -07006727 /* Get current SR-IOV LD/VF affiliation */
6728 if (instance->requestorId)
6729 megasas_get_ld_vf_affiliation(instance, 1);
6730
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006731 return 0;
6732
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05006733fail_start_aen:
6734fail_io_attach:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006735 megasas_mgmt_info.count--;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006736 megasas_mgmt_info.max_index--;
weiping zhang61f0c3c2017-08-08 01:26:57 +08006737 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006738
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05306739 instance->instancet->disable_intr(instance);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05306740 megasas_destroy_irqs(instance);
6741
Shivasharan Se7d36b82017-10-19 02:48:50 -07006742 if (instance->adapter_type != MFI_SERIES)
adam radfordeb1b1232011-02-24 20:55:56 -08006743 megasas_release_fusion(instance);
6744 else
6745 megasas_release_mfi(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07006746 if (instance->msix_vectors)
Hannes Reineckefad119b2016-12-02 12:52:23 +01006747 pci_free_irq_vectors(instance->pdev);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05306748fail_init_mfi:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006749 scsi_host_put(host);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05006750fail_alloc_instance:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006751 pci_disable_device(pdev);
6752
6753 return -ENODEV;
6754}
6755
6756/**
6757 * megasas_flush_cache - Requests FW to flush all its caches
6758 * @instance: Adapter soft state
6759 */
6760static void megasas_flush_cache(struct megasas_instance *instance)
6761{
6762 struct megasas_cmd *cmd;
6763 struct megasas_dcmd_frame *dcmd;
6764
Sumit Saxena8a01a412016-01-28 21:04:32 +05306765 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
bo yang39a98552010-09-22 22:36:29 -04006766 return;
6767
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006768 cmd = megasas_get_cmd(instance);
6769
6770 if (!cmd)
6771 return;
6772
6773 dcmd = &cmd->frame->dcmd;
6774
6775 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
6776
6777 dcmd->cmd = MFI_CMD_DCMD;
6778 dcmd->cmd_status = 0x0;
6779 dcmd->sge_count = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306780 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006781 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07006782 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006783 dcmd->data_xfer_len = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306784 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_CACHE_FLUSH);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006785 dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
6786
Sumit Saxena6d40afb2016-01-28 21:04:23 +05306787 if (megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS)
6788 != DCMD_SUCCESS) {
6789 dev_err(&instance->pdev->dev,
6790 "return from %s %d\n", __func__, __LINE__);
6791 return;
6792 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006793
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05306794 megasas_return_cmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006795}
6796
6797/**
6798 * megasas_shutdown_controller - Instructs FW to shutdown the controller
6799 * @instance: Adapter soft state
bo yang31ea7082007-11-07 12:09:50 -05006800 * @opcode: Shutdown/Hibernate
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006801 */
bo yang31ea7082007-11-07 12:09:50 -05006802static void megasas_shutdown_controller(struct megasas_instance *instance,
6803 u32 opcode)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006804{
6805 struct megasas_cmd *cmd;
6806 struct megasas_dcmd_frame *dcmd;
6807
Sumit Saxena8a01a412016-01-28 21:04:32 +05306808 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
bo yang39a98552010-09-22 22:36:29 -04006809 return;
6810
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006811 cmd = megasas_get_cmd(instance);
6812
6813 if (!cmd)
6814 return;
6815
6816 if (instance->aen_cmd)
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05306817 megasas_issue_blocked_abort_cmd(instance,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05306818 instance->aen_cmd, MFI_IO_TIMEOUT_SECS);
adam radford9c915a82010-12-21 13:34:31 -08006819 if (instance->map_update_cmd)
6820 megasas_issue_blocked_abort_cmd(instance,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05306821 instance->map_update_cmd, MFI_IO_TIMEOUT_SECS);
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05306822 if (instance->jbod_seq_cmd)
6823 megasas_issue_blocked_abort_cmd(instance,
Sumit Saxena6d40afb2016-01-28 21:04:23 +05306824 instance->jbod_seq_cmd, MFI_IO_TIMEOUT_SECS);
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05306825
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006826 dcmd = &cmd->frame->dcmd;
6827
6828 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
6829
6830 dcmd->cmd = MFI_CMD_DCMD;
6831 dcmd->cmd_status = 0x0;
6832 dcmd->sge_count = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306833 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006834 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07006835 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006836 dcmd->data_xfer_len = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306837 dcmd->opcode = cpu_to_le32(opcode);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006838
Sumit Saxena6d40afb2016-01-28 21:04:23 +05306839 if (megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS)
6840 != DCMD_SUCCESS) {
6841 dev_err(&instance->pdev->dev,
6842 "return from %s %d\n", __func__, __LINE__);
6843 return;
6844 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006845
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05306846 megasas_return_cmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006847}
6848
Jiri Slaby33139b22008-05-01 17:56:02 +02006849#ifdef CONFIG_PM
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006850/**
bo yangad84db22007-11-09 04:40:16 -05006851 * megasas_suspend - driver suspend entry point
6852 * @pdev: PCI device structure
bo yang31ea7082007-11-07 12:09:50 -05006853 * @state: PCI power state to suspend routine
6854 */
Jiri Slaby33139b22008-05-01 17:56:02 +02006855static int
bo yang31ea7082007-11-07 12:09:50 -05006856megasas_suspend(struct pci_dev *pdev, pm_message_t state)
6857{
6858 struct Scsi_Host *host;
6859 struct megasas_instance *instance;
6860
6861 instance = pci_get_drvdata(pdev);
6862 host = instance->host;
Yang, Bo0c79e682009-10-06 14:47:35 -06006863 instance->unload = 1;
bo yang31ea7082007-11-07 12:09:50 -05006864
adam radford229fe472014-03-10 02:51:56 -07006865 /* Shutdown SR-IOV heartbeat timer */
6866 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
6867 del_timer_sync(&instance->sriov_heartbeat_timer);
6868
Shivasharan S3f6194a2018-10-16 23:37:39 -07006869 /* Stop the FW fault detection watchdog */
6870 if (instance->adapter_type != MFI_SERIES)
6871 megasas_fusion_stop_watchdog(instance);
6872
bo yang31ea7082007-11-07 12:09:50 -05006873 megasas_flush_cache(instance);
6874 megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006875
6876 /* cancel the delayed work if this work still in queue */
6877 if (instance->ev != NULL) {
6878 struct megasas_aen_event *ev = instance->ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08006879 cancel_delayed_work_sync(&ev->hotplug_work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006880 instance->ev = NULL;
6881 }
6882
bo yang31ea7082007-11-07 12:09:50 -05006883 tasklet_kill(&instance->isr_tasklet);
6884
6885 pci_set_drvdata(instance->pdev, instance);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05306886 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07006887
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05306888 megasas_destroy_irqs(instance);
6889
adam radfordc8e858f2011-10-08 18:15:13 -07006890 if (instance->msix_vectors)
Hannes Reineckefad119b2016-12-02 12:52:23 +01006891 pci_free_irq_vectors(instance->pdev);
bo yang31ea7082007-11-07 12:09:50 -05006892
6893 pci_save_state(pdev);
6894 pci_disable_device(pdev);
6895
6896 pci_set_power_state(pdev, pci_choose_state(pdev, state));
6897
6898 return 0;
6899}
6900
6901/**
6902 * megasas_resume- driver resume entry point
6903 * @pdev: PCI device structure
6904 */
Jiri Slaby33139b22008-05-01 17:56:02 +02006905static int
bo yang31ea7082007-11-07 12:09:50 -05006906megasas_resume(struct pci_dev *pdev)
6907{
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05306908 int rval;
bo yang31ea7082007-11-07 12:09:50 -05006909 struct Scsi_Host *host;
6910 struct megasas_instance *instance;
Hannes Reineckefad119b2016-12-02 12:52:23 +01006911 int irq_flags = PCI_IRQ_LEGACY;
bo yang31ea7082007-11-07 12:09:50 -05006912
6913 instance = pci_get_drvdata(pdev);
6914 host = instance->host;
6915 pci_set_power_state(pdev, PCI_D0);
6916 pci_enable_wake(pdev, PCI_D0, 0);
6917 pci_restore_state(pdev);
6918
6919 /*
6920 * PCI prepping: enable device set bus mastering and dma mask
6921 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09006922 rval = pci_enable_device_mem(pdev);
bo yang31ea7082007-11-07 12:09:50 -05006923
6924 if (rval) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05006925 dev_err(&pdev->dev, "Enable device failed\n");
bo yang31ea7082007-11-07 12:09:50 -05006926 return rval;
6927 }
6928
6929 pci_set_master(pdev);
6930
Shivasharan S107a60d2017-10-19 02:49:05 -07006931 /*
6932 * We expect the FW state to be READY
6933 */
6934 if (megasas_transition_to_ready(instance, 0))
6935 goto fail_ready_state;
6936
6937 if (megasas_set_dma_mask(instance))
bo yang31ea7082007-11-07 12:09:50 -05006938 goto fail_set_dma_mask;
6939
6940 /*
6941 * Initialize MFI Firmware
6942 */
6943
bo yang31ea7082007-11-07 12:09:50 -05006944 atomic_set(&instance->fw_outstanding, 0);
Shivasharan S41fae9a2018-01-05 05:27:39 -08006945 atomic_set(&instance->ldio_outstanding, 0);
bo yang31ea7082007-11-07 12:09:50 -05006946
adam radford3f1abce2011-05-11 18:33:47 -07006947 /* Now re-enable MSI-X */
Hannes Reineckefad119b2016-12-02 12:52:23 +01006948 if (instance->msix_vectors) {
6949 irq_flags = PCI_IRQ_MSIX;
6950 if (smp_affinity_enable)
6951 irq_flags |= PCI_IRQ_AFFINITY;
6952 }
6953 rval = pci_alloc_irq_vectors(instance->pdev, 1,
6954 instance->msix_vectors ?
6955 instance->msix_vectors : 1, irq_flags);
6956 if (rval < 0)
Alexander Gordeevdd088122014-08-18 08:01:43 +02006957 goto fail_reenable_msix;
adam radford3f1abce2011-05-11 18:33:47 -07006958
Ming Leiadbe5522018-03-13 17:42:40 +08006959 megasas_setup_reply_map(instance);
6960
Shivasharan Se7d36b82017-10-19 02:48:50 -07006961 if (instance->adapter_type != MFI_SERIES) {
adam radford9c915a82010-12-21 13:34:31 -08006962 megasas_reset_reply_desc(instance);
6963 if (megasas_ioc_init_fusion(instance)) {
6964 megasas_free_cmds(instance);
6965 megasas_free_cmds_fusion(instance);
6966 goto fail_init_mfi;
6967 }
6968 if (!megasas_get_map_info(instance))
6969 megasas_sync_map_info(instance);
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05306970 } else {
adam radford9c915a82010-12-21 13:34:31 -08006971 *instance->producer = 0;
6972 *instance->consumer = 0;
6973 if (megasas_issue_init_mfi(instance))
6974 goto fail_init_mfi;
adam radford9c915a82010-12-21 13:34:31 -08006975 }
bo yang31ea7082007-11-07 12:09:50 -05006976
Shivasharan Sc3b10a52018-06-04 03:45:10 -07006977 if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS)
6978 goto fail_init_mfi;
6979
adam radford9c915a82010-12-21 13:34:31 -08006980 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
6981 (unsigned long)instance);
bo yang31ea7082007-11-07 12:09:50 -05006982
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05306983 if (instance->msix_vectors ?
6984 megasas_setup_irqs_msix(instance, 0) :
6985 megasas_setup_irqs_ioapic(instance))
6986 goto fail_init_mfi;
bo yang31ea7082007-11-07 12:09:50 -05006987
adam radford229fe472014-03-10 02:51:56 -07006988 /* Re-launch SR-IOV heartbeat timer */
6989 if (instance->requestorId) {
6990 if (!megasas_sriov_start_heartbeat(instance, 0))
Kees Cookc251a7b2017-10-22 15:30:04 -07006991 megasas_start_timer(instance);
Sumit.Saxena@avagotech.com5765c5b2015-04-23 16:32:09 +05306992 else {
adam radford229fe472014-03-10 02:51:56 -07006993 instance->skip_heartbeat_timer_del = 1;
Sumit.Saxena@avagotech.com5765c5b2015-04-23 16:32:09 +05306994 goto fail_init_mfi;
6995 }
adam radford229fe472014-03-10 02:51:56 -07006996 }
6997
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05306998 instance->instancet->enable_intr(instance);
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05306999 megasas_setup_jbod_map(instance);
Yang, Bo0c79e682009-10-06 14:47:35 -06007000 instance->unload = 0;
7001
adam radford541f90b2011-05-11 18:34:29 -07007002 /*
7003 * Initiate AEN (Asynchronous Event Notification)
7004 */
7005 if (megasas_start_aen(instance))
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007006 dev_err(&instance->pdev->dev, "Start AEN failed\n");
adam radford541f90b2011-05-11 18:34:29 -07007007
Shivasharan S3f6194a2018-10-16 23:37:39 -07007008 /* Re-launch FW fault watchdog */
7009 if (instance->adapter_type != MFI_SERIES)
7010 if (megasas_fusion_start_watchdog(instance) != SUCCESS)
7011 goto fail_start_watchdog;
7012
bo yang31ea7082007-11-07 12:09:50 -05007013 return 0;
7014
Shivasharan S3f6194a2018-10-16 23:37:39 -07007015fail_start_watchdog:
7016 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
7017 del_timer_sync(&instance->sriov_heartbeat_timer);
bo yang31ea7082007-11-07 12:09:50 -05007018fail_init_mfi:
Shivasharan S1b4bed22017-10-19 02:48:55 -07007019 megasas_free_ctrl_dma_buffers(instance);
Shivasharan S49a7a4a2017-10-19 02:48:54 -07007020 megasas_free_ctrl_mem(instance);
bo yang31ea7082007-11-07 12:09:50 -05007021 scsi_host_put(host);
7022
Shivasharan S107a60d2017-10-19 02:49:05 -07007023fail_reenable_msix:
bo yang31ea7082007-11-07 12:09:50 -05007024fail_set_dma_mask:
7025fail_ready_state:
7026
7027 pci_disable_device(pdev);
7028
7029 return -ENODEV;
7030}
Jiri Slaby33139b22008-05-01 17:56:02 +02007031#else
7032#define megasas_suspend NULL
7033#define megasas_resume NULL
7034#endif
bo yang31ea7082007-11-07 12:09:50 -05007035
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007036static inline int
7037megasas_wait_for_adapter_operational(struct megasas_instance *instance)
7038{
7039 int wait_time = MEGASAS_RESET_WAIT_TIME * 2;
7040 int i;
Shivasharan S9c9db8b2018-06-04 03:45:11 -07007041 u8 adp_state;
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007042
7043 for (i = 0; i < wait_time; i++) {
Shivasharan S9c9db8b2018-06-04 03:45:11 -07007044 adp_state = atomic_read(&instance->adprecovery);
7045 if ((adp_state == MEGASAS_HBA_OPERATIONAL) ||
7046 (adp_state == MEGASAS_HW_CRITICAL_ERROR))
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007047 break;
7048
7049 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL))
7050 dev_notice(&instance->pdev->dev, "waiting for controller reset to finish\n");
7051
7052 msleep(1000);
7053 }
7054
Shivasharan S9c9db8b2018-06-04 03:45:11 -07007055 if (adp_state != MEGASAS_HBA_OPERATIONAL) {
7056 dev_info(&instance->pdev->dev,
7057 "%s HBA failed to become operational, adp_state %d\n",
7058 __func__, adp_state);
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007059 return 1;
7060 }
7061
7062 return 0;
7063}
7064
bo yang31ea7082007-11-07 12:09:50 -05007065/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007066 * megasas_detach_one - PCI hot"un"plug entry point
7067 * @pdev: PCI device structure
7068 */
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08007069static void megasas_detach_one(struct pci_dev *pdev)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007070{
7071 int i;
7072 struct Scsi_Host *host;
7073 struct megasas_instance *instance;
adam radford9c915a82010-12-21 13:34:31 -08007074 struct fusion_context *fusion;
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05307075 u32 pd_seq_map_sz;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007076
7077 instance = pci_get_drvdata(pdev);
7078 host = instance->host;
adam radford9c915a82010-12-21 13:34:31 -08007079 fusion = instance->ctrl_context;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007080
adam radford229fe472014-03-10 02:51:56 -07007081 /* Shutdown SR-IOV heartbeat timer */
7082 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
7083 del_timer_sync(&instance->sriov_heartbeat_timer);
7084
Shivasharan S3f6194a2018-10-16 23:37:39 -07007085 /* Stop the FW fault detection watchdog */
7086 if (instance->adapter_type != MFI_SERIES)
7087 megasas_fusion_stop_watchdog(instance);
7088
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307089 if (instance->fw_crash_state != UNAVAILABLE)
7090 megasas_free_host_crash_buffer(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007091 scsi_remove_host(instance->host);
Shivasharan Sf3f79202018-01-05 05:27:41 -08007092 instance->unload = 1;
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007093
7094 if (megasas_wait_for_adapter_operational(instance))
7095 goto skip_firing_dcmds;
7096
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007097 megasas_flush_cache(instance);
bo yang31ea7082007-11-07 12:09:50 -05007098 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007099
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007100skip_firing_dcmds:
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007101 /* cancel the delayed work if this work still in queue*/
7102 if (instance->ev != NULL) {
7103 struct megasas_aen_event *ev = instance->ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08007104 cancel_delayed_work_sync(&ev->hotplug_work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007105 instance->ev = NULL;
7106 }
7107
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05307108 /* cancel all wait events */
7109 wake_up_all(&instance->int_cmd_wait_q);
7110
Sumant Patro5d018ad2006-10-03 13:13:18 -07007111 tasklet_kill(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007112
7113 /*
7114 * Take the instance off the instance array. Note that we will not
7115 * decrement the max_index. We let this array be sparse array
7116 */
7117 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
7118 if (megasas_mgmt_info.instance[i] == instance) {
7119 megasas_mgmt_info.count--;
7120 megasas_mgmt_info.instance[i] = NULL;
7121
7122 break;
7123 }
7124 }
7125
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05307126 instance->instancet->disable_intr(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007127
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05307128 megasas_destroy_irqs(instance);
7129
adam radfordc8e858f2011-10-08 18:15:13 -07007130 if (instance->msix_vectors)
Hannes Reineckefad119b2016-12-02 12:52:23 +01007131 pci_free_irq_vectors(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007132
Shivasharan S630d42b2018-12-17 00:47:37 -08007133 if (instance->adapter_type >= VENTURA_SERIES) {
Sasikumar Chandrasekaranfdd84e22017-01-10 18:20:46 -05007134 for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i)
7135 kfree(fusion->stream_detect_by_ld[i]);
7136 kfree(fusion->stream_detect_by_ld);
7137 fusion->stream_detect_by_ld = NULL;
7138 }
7139
7140
Shivasharan Se7d36b82017-10-19 02:48:50 -07007141 if (instance->adapter_type != MFI_SERIES) {
adam radford9c915a82010-12-21 13:34:31 -08007142 megasas_release_fusion(instance);
sumit.saxena@avagotech.com3761cb42015-08-31 17:23:11 +05307143 pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
7144 (sizeof(struct MR_PD_CFG_SEQ) *
7145 (MAX_PHYSICAL_DEVICES - 1));
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05307146 for (i = 0; i < 2 ; i++) {
adam radford9c915a82010-12-21 13:34:31 -08007147 if (fusion->ld_map[i])
7148 dma_free_coherent(&instance->pdev->dev,
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05307149 fusion->max_map_sz,
adam radford9c915a82010-12-21 13:34:31 -08007150 fusion->ld_map[i],
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05307151 fusion->ld_map_phys[i]);
Shivasharan Sdef3e8d2017-08-23 04:47:03 -07007152 if (fusion->ld_drv_map[i]) {
7153 if (is_vmalloc_addr(fusion->ld_drv_map[i]))
7154 vfree(fusion->ld_drv_map[i]);
7155 else
7156 free_pages((ulong)fusion->ld_drv_map[i],
7157 fusion->drv_map_pages);
7158 }
7159
Maurizio Lombardi546e5592016-01-22 13:41:42 +01007160 if (fusion->pd_seq_sync[i])
7161 dma_free_coherent(&instance->pdev->dev,
7162 pd_seq_map_sz,
7163 fusion->pd_seq_sync[i],
7164 fusion->pd_seq_phys[i]);
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05307165 }
sumit.saxena@avagotech.com5a8cb852015-10-15 13:39:34 +05307166 } else {
adam radford9c915a82010-12-21 13:34:31 -08007167 megasas_release_mfi(instance);
adam radford9c915a82010-12-21 13:34:31 -08007168 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007169
adam radford229fe472014-03-10 02:51:56 -07007170 if (instance->vf_affiliation)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007171 dma_free_coherent(&pdev->dev, (MAX_LOGICAL_DRIVES + 1) *
adam radford229fe472014-03-10 02:51:56 -07007172 sizeof(struct MR_LD_VF_AFFILIATION),
7173 instance->vf_affiliation,
7174 instance->vf_affiliation_h);
7175
7176 if (instance->vf_affiliation_111)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007177 dma_free_coherent(&pdev->dev,
adam radford229fe472014-03-10 02:51:56 -07007178 sizeof(struct MR_LD_VF_AFFILIATION_111),
7179 instance->vf_affiliation_111,
7180 instance->vf_affiliation_111_h);
7181
7182 if (instance->hb_host_mem)
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007183 dma_free_coherent(&pdev->dev, sizeof(struct MR_CTRL_HB_HOST_MEM),
adam radford229fe472014-03-10 02:51:56 -07007184 instance->hb_host_mem,
7185 instance->hb_host_mem_h);
7186
Shivasharan S1b4bed22017-10-19 02:48:55 -07007187 megasas_free_ctrl_dma_buffers(instance);
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307188
Shivasharan S49a7a4a2017-10-19 02:48:54 -07007189 megasas_free_ctrl_mem(instance);
Sumit.Saxena@avagotech.com5765c5b2015-04-23 16:32:09 +05307190
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007191 scsi_host_put(host);
7192
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007193 pci_disable_device(pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007194}
7195
7196/**
7197 * megasas_shutdown - Shutdown entry point
7198 * @device: Generic device structure
7199 */
7200static void megasas_shutdown(struct pci_dev *pdev)
7201{
7202 struct megasas_instance *instance = pci_get_drvdata(pdev);
adam radfordc8e858f2011-10-08 18:15:13 -07007203
Yang, Bo0c79e682009-10-06 14:47:35 -06007204 instance->unload = 1;
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007205
7206 if (megasas_wait_for_adapter_operational(instance))
7207 goto skip_firing_dcmds;
7208
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007209 megasas_flush_cache(instance);
Yang, Bo530e6fc2008-08-10 12:42:37 -07007210 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Kashyap Desaia1dfd622016-10-21 06:33:31 -07007211
7212skip_firing_dcmds:
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05307213 instance->instancet->disable_intr(instance);
Sumit.Saxena@avagotech.comd3557fc2015-04-23 16:30:09 +05307214 megasas_destroy_irqs(instance);
7215
adam radfordc8e858f2011-10-08 18:15:13 -07007216 if (instance->msix_vectors)
Hannes Reineckefad119b2016-12-02 12:52:23 +01007217 pci_free_irq_vectors(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007218}
7219
7220/**
7221 * megasas_mgmt_open - char node "open" entry point
7222 */
7223static int megasas_mgmt_open(struct inode *inode, struct file *filep)
7224{
7225 /*
7226 * Allow only those users with admin rights
7227 */
7228 if (!capable(CAP_SYS_ADMIN))
7229 return -EACCES;
7230
7231 return 0;
7232}
7233
7234/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007235 * megasas_mgmt_fasync - Async notifier registration from applications
7236 *
7237 * This function adds the calling process to a driver global queue. When an
7238 * event occurs, SIGIO will be sent to all processes in this queue.
7239 */
7240static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
7241{
7242 int rc;
7243
Arjan van de Ven0b950672006-01-11 13:16:10 +01007244 mutex_lock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007245
7246 rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
7247
Arjan van de Ven0b950672006-01-11 13:16:10 +01007248 mutex_unlock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007249
7250 if (rc >= 0) {
7251 /* For sanity check when we get ioctl */
7252 filep->private_data = filep;
7253 return 0;
7254 }
7255
7256 printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc);
7257
7258 return rc;
7259}
7260
7261/**
Yang, Boc3518832009-10-06 14:18:02 -06007262 * megasas_mgmt_poll - char node "poll" entry point
7263 * */
Al Viroafc9a422017-07-03 06:39:46 -04007264static __poll_t megasas_mgmt_poll(struct file *file, poll_table *wait)
Yang, Boc3518832009-10-06 14:18:02 -06007265{
Al Viroafc9a422017-07-03 06:39:46 -04007266 __poll_t mask;
Yang, Boc3518832009-10-06 14:18:02 -06007267 unsigned long flags;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007268
Yang, Boc3518832009-10-06 14:18:02 -06007269 poll_wait(file, &megasas_poll_wait, wait);
7270 spin_lock_irqsave(&poll_aen_lock, flags);
7271 if (megasas_poll_wait_aen)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08007272 mask = (EPOLLIN | EPOLLRDNORM);
Yang, Boc3518832009-10-06 14:18:02 -06007273 else
7274 mask = 0;
Sumit.Saxena@avagotech.com51087a82014-09-12 18:57:33 +05307275 megasas_poll_wait_aen = 0;
Yang, Boc3518832009-10-06 14:18:02 -06007276 spin_unlock_irqrestore(&poll_aen_lock, flags);
7277 return mask;
7278}
7279
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307280/*
7281 * megasas_set_crash_dump_params_ioctl:
7282 * Send CRASH_DUMP_MODE DCMD to all controllers
7283 * @cmd: MFI command frame
7284 */
7285
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007286static int megasas_set_crash_dump_params_ioctl(struct megasas_cmd *cmd)
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307287{
7288 struct megasas_instance *local_instance;
7289 int i, error = 0;
7290 int crash_support;
7291
7292 crash_support = cmd->frame->dcmd.mbox.w[0];
7293
7294 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
7295 local_instance = megasas_mgmt_info.instance[i];
7296 if (local_instance && local_instance->crash_dump_drv_support) {
Sumit Saxena8a01a412016-01-28 21:04:32 +05307297 if ((atomic_read(&local_instance->adprecovery) ==
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307298 MEGASAS_HBA_OPERATIONAL) &&
7299 !megasas_set_crash_dump_params(local_instance,
7300 crash_support)) {
7301 local_instance->crash_dump_app_support =
7302 crash_support;
7303 dev_info(&local_instance->pdev->dev,
7304 "Application firmware crash "
7305 "dump mode set success\n");
7306 error = 0;
7307 } else {
7308 dev_info(&local_instance->pdev->dev,
7309 "Application firmware crash "
7310 "dump mode set failed\n");
7311 error = -1;
7312 }
7313 }
7314 }
7315 return error;
7316}
7317
Yang, Boc3518832009-10-06 14:18:02 -06007318/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007319 * megasas_mgmt_fw_ioctl - Issues management ioctls to FW
7320 * @instance: Adapter soft state
7321 * @argp: User's ioctl packet
7322 */
7323static int
7324megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
7325 struct megasas_iocpacket __user * user_ioc,
7326 struct megasas_iocpacket *ioc)
7327{
Shivasharan S107a60d2017-10-19 02:49:05 -07007328 struct megasas_sge64 *kern_sge64 = NULL;
7329 struct megasas_sge32 *kern_sge32 = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007330 struct megasas_cmd *cmd;
7331 void *kbuff_arr[MAX_IOCTL_SGE];
7332 dma_addr_t buf_handle = 0;
7333 int error = 0, i;
7334 void *sense = NULL;
7335 dma_addr_t sense_handle;
Yang, Bo7b2519a2009-10-06 14:52:20 -06007336 unsigned long *sense_ptr;
Shivasharan S82add4e2017-10-19 02:49:02 -07007337 u32 opcode = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007338
7339 memset(kbuff_arr, 0, sizeof(kbuff_arr));
7340
7341 if (ioc->sge_count > MAX_IOCTL_SGE) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007342 dev_printk(KERN_DEBUG, &instance->pdev->dev, "SGE count [%d] > max limit [%d]\n",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007343 ioc->sge_count, MAX_IOCTL_SGE);
7344 return -EINVAL;
7345 }
7346
Shivasharan Sf870bcb2018-01-05 05:33:04 -08007347 if ((ioc->frame.hdr.cmd >= MFI_CMD_OP_COUNT) ||
7348 ((ioc->frame.hdr.cmd == MFI_CMD_NVME) &&
7349 !instance->support_nvme_passthru)) {
Shivasharan S82add4e2017-10-19 02:49:02 -07007350 dev_err(&instance->pdev->dev,
7351 "Received invalid ioctl command 0x%x\n",
7352 ioc->frame.hdr.cmd);
7353 return -ENOTSUPP;
7354 }
7355
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007356 cmd = megasas_get_cmd(instance);
7357 if (!cmd) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007358 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a cmd packet\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007359 return -ENOMEM;
7360 }
7361
7362 /*
7363 * User's IOCTL packet has 2 frames (maximum). Copy those two
7364 * frames into our cmd's frames. cmd->frame's context will get
7365 * overwritten when we copy from user's frames. So set that value
7366 * alone separately
7367 */
7368 memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05307369 cmd->frame->hdr.context = cpu_to_le32(cmd->index);
Yang, Boc3518832009-10-06 14:18:02 -06007370 cmd->frame->hdr.pad_0 = 0;
Shivasharan S107a60d2017-10-19 02:49:05 -07007371
7372 cmd->frame->hdr.flags &= (~MFI_FRAME_IEEE);
7373
7374 if (instance->consistent_mask_64bit)
7375 cmd->frame->hdr.flags |= cpu_to_le16((MFI_FRAME_SGL64 |
7376 MFI_FRAME_SENSE64));
7377 else
7378 cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_SGL64 |
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05307379 MFI_FRAME_SENSE64));
Shivasharan S82add4e2017-10-19 02:49:02 -07007380
7381 if (cmd->frame->hdr.cmd == MFI_CMD_DCMD)
7382 opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007383
Shivasharan S8823abe2017-08-23 04:47:00 -07007384 if (opcode == MR_DCMD_CTRL_SHUTDOWN) {
Shivasharan S95c06082017-02-10 00:59:23 -08007385 if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) {
7386 megasas_return_cmd(instance, cmd);
7387 return -1;
7388 }
7389 }
7390
Shivasharan S8823abe2017-08-23 04:47:00 -07007391 if (opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) {
Sumit.Saxena@avagotech.comfc62b3f2014-09-12 18:57:28 +05307392 error = megasas_set_crash_dump_params_ioctl(cmd);
7393 megasas_return_cmd(instance, cmd);
7394 return error;
7395 }
7396
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007397 /*
7398 * The management interface between applications and the fw uses
7399 * MFI frames. E.g, RAID configuration changes, LD property changes
7400 * etc are accomplishes through different kinds of MFI frames. The
7401 * driver needs to care only about substituting user buffers with
7402 * kernel buffers in SGLs. The location of SGL is embedded in the
7403 * struct iocpacket itself.
7404 */
Shivasharan S107a60d2017-10-19 02:49:05 -07007405 if (instance->consistent_mask_64bit)
7406 kern_sge64 = (struct megasas_sge64 *)
7407 ((unsigned long)cmd->frame + ioc->sgl_off);
7408 else
7409 kern_sge32 = (struct megasas_sge32 *)
7410 ((unsigned long)cmd->frame + ioc->sgl_off);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007411
7412 /*
7413 * For each user buffer, create a mirror buffer and copy in
7414 */
7415 for (i = 0; i < ioc->sge_count; i++) {
Bjørn Mork98cb7e42011-01-19 10:01:14 +01007416 if (!ioc->sgl[i].iov_len)
7417 continue;
7418
Sumant Patro9f35fa82007-02-14 12:55:45 -08007419 kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007420 ioc->sgl[i].iov_len,
Sumant Patro9f35fa82007-02-14 12:55:45 -08007421 &buf_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007422 if (!kbuff_arr[i]) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007423 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc "
7424 "kernel SGL buffer for IOCTL\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007425 error = -ENOMEM;
7426 goto out;
7427 }
7428
7429 /*
7430 * We don't change the dma_coherent_mask, so
Christoph Hellwig60ee6522018-10-10 19:31:25 +02007431 * dma_alloc_coherent only returns 32bit addresses
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007432 */
Shivasharan S107a60d2017-10-19 02:49:05 -07007433 if (instance->consistent_mask_64bit) {
7434 kern_sge64[i].phys_addr = cpu_to_le64(buf_handle);
7435 kern_sge64[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
7436 } else {
7437 kern_sge32[i].phys_addr = cpu_to_le32(buf_handle);
7438 kern_sge32[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
7439 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007440
7441 /*
7442 * We created a kernel buffer corresponding to the
7443 * user buffer. Now copy in from the user buffer
7444 */
7445 if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base,
7446 (u32) (ioc->sgl[i].iov_len))) {
7447 error = -EFAULT;
7448 goto out;
7449 }
7450 }
7451
7452 if (ioc->sense_len) {
Sumant Patro9f35fa82007-02-14 12:55:45 -08007453 sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,
7454 &sense_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007455 if (!sense) {
7456 error = -ENOMEM;
7457 goto out;
7458 }
7459
7460 sense_ptr =
Yang, Bo7b2519a2009-10-06 14:52:20 -06007461 (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
Shivasharan S107a60d2017-10-19 02:49:05 -07007462 if (instance->consistent_mask_64bit)
7463 *sense_ptr = cpu_to_le64(sense_handle);
7464 else
7465 *sense_ptr = cpu_to_le32(sense_handle);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007466 }
7467
7468 /*
7469 * Set the sync_cmd flag so that the ISR knows not to complete this
7470 * cmd to the SCSI mid-layer
7471 */
7472 cmd->sync_cmd = 1;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307473 if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) {
7474 cmd->sync_cmd = 0;
7475 dev_err(&instance->pdev->dev,
Shivasharan S82add4e2017-10-19 02:49:02 -07007476 "return -EBUSY from %s %d cmd 0x%x opcode 0x%x cmd->cmd_status_drv 0x%x\n",
7477 __func__, __LINE__, cmd->frame->hdr.cmd, opcode,
7478 cmd->cmd_status_drv);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307479 return -EBUSY;
7480 }
7481
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007482 cmd->sync_cmd = 0;
7483
Sumit.Saxena@avagotech.comaa008322014-11-17 15:24:08 +05307484 if (instance->unload == 1) {
7485 dev_info(&instance->pdev->dev, "Driver unload is in progress "
7486 "don't submit data to application\n");
7487 goto out;
7488 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007489 /*
7490 * copy out the kernel buffers to user buffers
7491 */
7492 for (i = 0; i < ioc->sge_count; i++) {
7493 if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i],
7494 ioc->sgl[i].iov_len)) {
7495 error = -EFAULT;
7496 goto out;
7497 }
7498 }
7499
7500 /*
7501 * copy out the sense
7502 */
7503 if (ioc->sense_len) {
7504 /*
bo yangb70a41e2008-03-18 03:13:06 -04007505 * sense_ptr points to the location that has the user
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007506 * sense buffer address
7507 */
Yang, Bo7b2519a2009-10-06 14:52:20 -06007508 sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
7509 ioc->sense_off);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007510
Shivasharan S318aaef2017-02-10 00:59:22 -08007511 if (copy_to_user((void __user *)((unsigned long)
7512 get_unaligned((unsigned long *)sense_ptr)),
bo yangb70a41e2008-03-18 03:13:06 -04007513 sense, ioc->sense_len)) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007514 dev_err(&instance->pdev->dev, "Failed to copy out to user "
bo yangb10c36a2007-11-09 04:28:47 -05007515 "sense data\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007516 error = -EFAULT;
7517 goto out;
7518 }
7519 }
7520
7521 /*
7522 * copy the status codes returned by the fw
7523 */
7524 if (copy_to_user(&user_ioc->frame.hdr.cmd_status,
7525 &cmd->frame->hdr.cmd_status, sizeof(u8))) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007526 dev_printk(KERN_DEBUG, &instance->pdev->dev, "Error copying out cmd_status\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007527 error = -EFAULT;
7528 }
7529
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007530out:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007531 if (sense) {
Sumant Patro9f35fa82007-02-14 12:55:45 -08007532 dma_free_coherent(&instance->pdev->dev, ioc->sense_len,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007533 sense, sense_handle);
7534 }
7535
Bjørn Mork7a6a7312012-11-21 09:54:48 +01007536 for (i = 0; i < ioc->sge_count; i++) {
Arnd Bergmann3deb9432016-03-14 15:29:45 +01007537 if (kbuff_arr[i]) {
Shivasharan S107a60d2017-10-19 02:49:05 -07007538 if (instance->consistent_mask_64bit)
7539 dma_free_coherent(&instance->pdev->dev,
7540 le32_to_cpu(kern_sge64[i].length),
7541 kbuff_arr[i],
7542 le64_to_cpu(kern_sge64[i].phys_addr));
7543 else
7544 dma_free_coherent(&instance->pdev->dev,
7545 le32_to_cpu(kern_sge32[i].length),
7546 kbuff_arr[i],
7547 le32_to_cpu(kern_sge32[i].phys_addr));
Sumit.Saxena@avagotech.com90dc9d92014-09-12 18:57:58 +05307548 kbuff_arr[i] = NULL;
Arnd Bergmann3deb9432016-03-14 15:29:45 +01007549 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007550 }
7551
Sumit.Saxena@avagotech.com4026e9a2015-04-23 16:31:24 +05307552 megasas_return_cmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007553 return error;
7554}
7555
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007556static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
7557{
7558 struct megasas_iocpacket __user *user_ioc =
7559 (struct megasas_iocpacket __user *)arg;
7560 struct megasas_iocpacket *ioc;
7561 struct megasas_instance *instance;
7562 int error;
7563
Markus Elfring709ab232016-08-21 10:39:04 +02007564 ioc = memdup_user(user_ioc, sizeof(*ioc));
7565 if (IS_ERR(ioc))
7566 return PTR_ERR(ioc);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007567
7568 instance = megasas_lookup_instance(ioc->host_no);
7569 if (!instance) {
7570 error = -ENODEV;
7571 goto out_kfree_ioc;
7572 }
7573
adam radford229fe472014-03-10 02:51:56 -07007574 /* Block ioctls in VF mode */
7575 if (instance->requestorId && !allow_vf_ioctls) {
7576 error = -ENODEV;
7577 goto out_kfree_ioc;
7578 }
7579
Sumit Saxena8a01a412016-01-28 21:04:32 +05307580 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
Bjorn Helgaas1be18252015-07-07 15:52:34 -05007581 dev_err(&instance->pdev->dev, "Controller in crit error\n");
Yang, Bo0c79e682009-10-06 14:47:35 -06007582 error = -ENODEV;
7583 goto out_kfree_ioc;
7584 }
7585
7586 if (instance->unload == 1) {
7587 error = -ENODEV;
7588 goto out_kfree_ioc;
7589 }
7590
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007591 if (down_interruptible(&instance->ioctl_sem)) {
7592 error = -ERESTARTSYS;
7593 goto out_kfree_ioc;
7594 }
bo yang39a98552010-09-22 22:36:29 -04007595
Shivasharan S619831f2018-01-05 05:27:43 -08007596 if (megasas_wait_for_adapter_operational(instance)) {
bo yang39a98552010-09-22 22:36:29 -04007597 error = -ENODEV;
Dan Carpenterc64e4832013-04-16 10:44:19 +03007598 goto out_up;
bo yang39a98552010-09-22 22:36:29 -04007599 }
bo yang39a98552010-09-22 22:36:29 -04007600
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007601 error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007602out_up:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007603 up(&instance->ioctl_sem);
7604
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007605out_kfree_ioc:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007606 kfree(ioc);
7607 return error;
7608}
7609
7610static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
7611{
7612 struct megasas_instance *instance;
7613 struct megasas_aen aen;
7614 int error;
7615
7616 if (file->private_data != file) {
7617 printk(KERN_DEBUG "megasas: fasync_helper was not "
7618 "called first\n");
7619 return -EINVAL;
7620 }
7621
7622 if (copy_from_user(&aen, (void __user *)arg, sizeof(aen)))
7623 return -EFAULT;
7624
7625 instance = megasas_lookup_instance(aen.host_no);
7626
7627 if (!instance)
7628 return -ENODEV;
7629
Sumit Saxena8a01a412016-01-28 21:04:32 +05307630 if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
bo yang39a98552010-09-22 22:36:29 -04007631 return -ENODEV;
Yang, Bo0c79e682009-10-06 14:47:35 -06007632 }
7633
7634 if (instance->unload == 1) {
7635 return -ENODEV;
7636 }
7637
Shivasharan S619831f2018-01-05 05:27:43 -08007638 if (megasas_wait_for_adapter_operational(instance))
bo yang39a98552010-09-22 22:36:29 -04007639 return -ENODEV;
bo yang39a98552010-09-22 22:36:29 -04007640
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307641 mutex_lock(&instance->reset_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007642 error = megasas_register_aen(instance, aen.seq_num,
7643 aen.class_locale_word);
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307644 mutex_unlock(&instance->reset_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007645 return error;
7646}
7647
7648/**
7649 * megasas_mgmt_ioctl - char node ioctl entry point
7650 */
7651static long
7652megasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
7653{
7654 switch (cmd) {
7655 case MEGASAS_IOC_FIRMWARE:
7656 return megasas_mgmt_ioctl_fw(file, arg);
7657
7658 case MEGASAS_IOC_GET_AEN:
7659 return megasas_mgmt_ioctl_aen(file, arg);
7660 }
7661
7662 return -ENOTTY;
7663}
7664
7665#ifdef CONFIG_COMPAT
7666static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
7667{
7668 struct compat_megasas_iocpacket __user *cioc =
7669 (struct compat_megasas_iocpacket __user *)arg;
7670 struct megasas_iocpacket __user *ioc =
7671 compat_alloc_user_space(sizeof(struct megasas_iocpacket));
7672 int i;
7673 int error = 0;
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01007674 compat_uptr_t ptr;
sumit.saxena@avagotech.com323c4a02015-10-15 13:40:54 +05307675 u32 local_sense_off;
7676 u32 local_sense_len;
Sumit Saxenaea1c9282016-01-28 21:14:26 +05307677 u32 user_sense_off;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007678
Jeff Garzik83aabc12006-10-04 06:34:03 -04007679 if (clear_user(ioc, sizeof(*ioc)))
7680 return -EFAULT;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007681
7682 if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) ||
7683 copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) ||
7684 copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) ||
7685 copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) ||
7686 copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) ||
7687 copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
7688 return -EFAULT;
7689
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01007690 /*
7691 * The sense_ptr is used in megasas_mgmt_fw_ioctl only when
7692 * sense_len is not null, so prepare the 64bit value under
7693 * the same condition.
7694 */
Sumit Saxenaea1c9282016-01-28 21:14:26 +05307695 if (get_user(local_sense_off, &ioc->sense_off) ||
7696 get_user(local_sense_len, &ioc->sense_len) ||
7697 get_user(user_sense_off, &cioc->sense_off))
sumit.saxena@avagotech.com323c4a02015-10-15 13:40:54 +05307698 return -EFAULT;
7699
Wenwen Wang47db7872018-10-06 13:34:21 -05007700 if (local_sense_off != user_sense_off)
7701 return -EINVAL;
7702
sumit.saxena@avagotech.com323c4a02015-10-15 13:40:54 +05307703 if (local_sense_len) {
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01007704 void __user **sense_ioc_ptr =
Sumit Saxenaea1c9282016-01-28 21:14:26 +05307705 (void __user **)((u8 *)((unsigned long)&ioc->frame.raw) + local_sense_off);
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01007706 compat_uptr_t *sense_cioc_ptr =
Sumit Saxenaea1c9282016-01-28 21:14:26 +05307707 (compat_uptr_t *)(((unsigned long)&cioc->frame.raw) + user_sense_off);
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01007708 if (get_user(ptr, sense_cioc_ptr) ||
7709 put_user(compat_ptr(ptr), sense_ioc_ptr))
7710 return -EFAULT;
7711 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007712
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01007713 for (i = 0; i < MAX_IOCTL_SGE; i++) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007714 if (get_user(ptr, &cioc->sgl[i].iov_base) ||
7715 put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
7716 copy_in_user(&ioc->sgl[i].iov_len,
7717 &cioc->sgl[i].iov_len, sizeof(compat_size_t)))
7718 return -EFAULT;
7719 }
7720
7721 error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc);
7722
7723 if (copy_in_user(&cioc->frame.hdr.cmd_status,
7724 &ioc->frame.hdr.cmd_status, sizeof(u8))) {
7725 printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n");
7726 return -EFAULT;
7727 }
7728 return error;
7729}
7730
7731static long
7732megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd,
7733 unsigned long arg)
7734{
7735 switch (cmd) {
Sumant Patrocb59aa62006-01-25 11:53:25 -08007736 case MEGASAS_IOC_FIRMWARE32:
7737 return megasas_mgmt_compat_ioctl_fw(file, arg);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007738 case MEGASAS_IOC_GET_AEN:
7739 return megasas_mgmt_ioctl_aen(file, arg);
7740 }
7741
7742 return -ENOTTY;
7743}
7744#endif
7745
7746/*
7747 * File operations structure for management interface
7748 */
Arjan van de Ven00977a52007-02-12 00:55:34 -08007749static const struct file_operations megasas_mgmt_fops = {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007750 .owner = THIS_MODULE,
7751 .open = megasas_mgmt_open,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007752 .fasync = megasas_mgmt_fasync,
7753 .unlocked_ioctl = megasas_mgmt_ioctl,
Yang, Boc3518832009-10-06 14:18:02 -06007754 .poll = megasas_mgmt_poll,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007755#ifdef CONFIG_COMPAT
7756 .compat_ioctl = megasas_mgmt_compat_ioctl,
7757#endif
Arnd Bergmann6038f372010-08-15 18:52:59 +02007758 .llseek = noop_llseek,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007759};
7760
7761/*
7762 * PCI hotplug support registration structure
7763 */
7764static struct pci_driver megasas_pci_driver = {
7765
7766 .name = "megaraid_sas",
7767 .id_table = megasas_pci_table,
7768 .probe = megasas_probe_one,
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08007769 .remove = megasas_detach_one,
bo yang31ea7082007-11-07 12:09:50 -05007770 .suspend = megasas_suspend,
7771 .resume = megasas_resume,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007772 .shutdown = megasas_shutdown,
7773};
7774
7775/*
7776 * Sysfs driver attributes
7777 */
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007778static ssize_t version_show(struct device_driver *dd, char *buf)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007779{
7780 return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n",
7781 MEGASAS_VERSION);
7782}
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007783static DRIVER_ATTR_RO(version);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007784
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007785static ssize_t release_date_show(struct device_driver *dd, char *buf)
Sumit.Saxena@avagotech.com09fced12015-04-23 16:31:54 +05307786{
7787 return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n",
7788 MEGASAS_RELDATE);
7789}
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007790static DRIVER_ATTR_RO(release_date);
Sumit.Saxena@avagotech.com09fced12015-04-23 16:31:54 +05307791
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007792static ssize_t support_poll_for_event_show(struct device_driver *dd, char *buf)
Yang, Bo72c4fd32009-10-06 14:20:59 -06007793{
7794 return sprintf(buf, "%u\n", support_poll_for_event);
7795}
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007796static DRIVER_ATTR_RO(support_poll_for_event);
Yang, Bo72c4fd32009-10-06 14:20:59 -06007797
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007798static ssize_t support_device_change_show(struct device_driver *dd, char *buf)
Yang, Bo837f5fe2010-10-11 06:59:20 -06007799{
7800 return sprintf(buf, "%u\n", support_device_change);
7801}
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007802static DRIVER_ATTR_RO(support_device_change);
Yang, Bo837f5fe2010-10-11 06:59:20 -06007803
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007804static ssize_t dbg_lvl_show(struct device_driver *dd, char *buf)
Sumant Patro658dced2006-10-03 13:09:14 -07007805{
bo yangad84db22007-11-09 04:40:16 -05007806 return sprintf(buf, "%u\n", megasas_dbg_lvl);
Sumant Patro658dced2006-10-03 13:09:14 -07007807}
7808
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007809static ssize_t dbg_lvl_store(struct device_driver *dd, const char *buf,
7810 size_t count)
Sumant Patro658dced2006-10-03 13:09:14 -07007811{
7812 int retval = count;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007813
7814 if (sscanf(buf, "%u", &megasas_dbg_lvl) < 1) {
Sumant Patro658dced2006-10-03 13:09:14 -07007815 printk(KERN_ERR "megasas: could not set dbg_lvl\n");
7816 retval = -EINVAL;
7817 }
7818 return retval;
7819}
Greg Kroah-Hartmane14a3962017-07-19 14:50:06 +02007820static DRIVER_ATTR_RW(dbg_lvl);
bo yangad84db22007-11-09 04:40:16 -05007821
Shivasharan Sf870bcb2018-01-05 05:33:04 -08007822static ssize_t
7823support_nvme_encapsulation_show(struct device_driver *dd, char *buf)
7824{
7825 return sprintf(buf, "%u\n", support_nvme_encapsulation);
7826}
7827
7828static DRIVER_ATTR_RO(support_nvme_encapsulation);
7829
Shivasharan Sb4a42212017-02-10 00:59:16 -08007830static inline void megasas_remove_scsi_device(struct scsi_device *sdev)
7831{
7832 sdev_printk(KERN_INFO, sdev, "SCSI device is removed\n");
7833 scsi_remove_device(sdev);
7834 scsi_device_put(sdev);
7835}
7836
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007837static void
7838megasas_aen_polling(struct work_struct *work)
7839{
7840 struct megasas_aen_event *ev =
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08007841 container_of(work, struct megasas_aen_event, hotplug_work.work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007842 struct megasas_instance *instance = ev->instance;
7843 union megasas_evt_class_locale class_locale;
7844 struct Scsi_Host *host;
7845 struct scsi_device *sdev1;
7846 u16 pd_index = 0;
Yang, Boc9786842009-12-06 08:39:25 -07007847 u16 ld_index = 0;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007848 int i, j, doscan = 0;
adam radford229fe472014-03-10 02:51:56 -07007849 u32 seq_num, wait_time = MEGASAS_RESET_WAIT_TIME;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007850 int error;
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307851 u8 dcmd_ret = DCMD_SUCCESS;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007852
7853 if (!instance) {
7854 printk(KERN_ERR "invalid instance!\n");
7855 kfree(ev);
7856 return;
7857 }
adam radford229fe472014-03-10 02:51:56 -07007858
7859 /* Adjust event workqueue thread wait time for VF mode */
7860 if (instance->requestorId)
7861 wait_time = MEGASAS_ROUTINE_WAIT_TIME_VF;
7862
7863 /* Don't run the event workqueue thread if OCR is running */
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307864 mutex_lock(&instance->reset_mutex);
adam radford229fe472014-03-10 02:51:56 -07007865
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007866 instance->ev = NULL;
7867 host = instance->host;
7868 if (instance->evt_detail) {
sumit.saxena@avagotech.com714f5172015-08-31 17:23:51 +05307869 megasas_decode_evt(instance);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007870
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05307871 switch (le32_to_cpu(instance->evt_detail->code)) {
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307872
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007873 case MR_EVT_PD_INSERTED:
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307874 case MR_EVT_PD_REMOVED:
7875 dcmd_ret = megasas_get_pd_list(instance);
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307876 if (dcmd_ret == DCMD_SUCCESS)
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307877 doscan = SCAN_PD_CHANNEL;
Yang, Boc9786842009-12-06 08:39:25 -07007878 break;
7879
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307880 case MR_EVT_LD_OFFLINE:
7881 case MR_EVT_CFG_CLEARED:
7882 case MR_EVT_LD_DELETED:
7883 case MR_EVT_LD_CREATED:
7884 if (!instance->requestorId ||
7885 (instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0)))
7886 dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST);
Yang, Boc9786842009-12-06 08:39:25 -07007887
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307888 if (dcmd_ret == DCMD_SUCCESS)
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307889 doscan = SCAN_VD_CHANNEL;
Yang, Boc9786842009-12-06 08:39:25 -07007890
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307891 break;
7892
7893 case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
7894 case MR_EVT_FOREIGN_CFG_IMPORTED:
7895 case MR_EVT_LD_STATE_CHANGE:
7896 dcmd_ret = megasas_get_pd_list(instance);
7897
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307898 if (dcmd_ret != DCMD_SUCCESS)
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307899 break;
7900
7901 if (!instance->requestorId ||
7902 (instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0)))
7903 dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST);
7904
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307905 if (dcmd_ret != DCMD_SUCCESS)
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307906 break;
7907
7908 doscan = SCAN_VD_CHANNEL | SCAN_PD_CHANNEL;
7909 dev_info(&instance->pdev->dev, "scanning for scsi%d...\n",
7910 instance->host->host_no);
7911 break;
7912
7913 case MR_EVT_CTRL_PROP_CHANGED:
Shivasharan Sf0c21df2018-10-16 23:37:40 -07007914 dcmd_ret = megasas_get_ctrl_info(instance);
7915 if (dcmd_ret == DCMD_SUCCESS &&
7916 instance->snapdump_wait_time) {
7917 megasas_get_snapdump_properties(instance);
7918 dev_info(&instance->pdev->dev,
7919 "Snap dump wait time\t: %d\n",
7920 instance->snapdump_wait_time);
7921 }
7922 break;
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307923 default:
7924 doscan = 0;
7925 break;
7926 }
7927 } else {
7928 dev_err(&instance->pdev->dev, "invalid evt_detail!\n");
7929 mutex_unlock(&instance->reset_mutex);
7930 kfree(ev);
7931 return;
7932 }
7933
7934 mutex_unlock(&instance->reset_mutex);
7935
7936 if (doscan & SCAN_PD_CHANNEL) {
7937 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
7938 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
7939 pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
Bjorn Helgaasda0dc9f2015-07-07 15:52:45 -05007940 sdev1 = scsi_device_lookup(host, i, j, 0);
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307941 if (instance->pd_list[pd_index].driveState ==
7942 MR_PD_STATE_SYSTEM) {
7943 if (!sdev1)
7944 scsi_add_device(host, i, j, 0);
7945 else
Yang, Boc9786842009-12-06 08:39:25 -07007946 scsi_device_put(sdev1);
Yang, Boc9786842009-12-06 08:39:25 -07007947 } else {
Shivasharan Sb4a42212017-02-10 00:59:16 -08007948 if (sdev1)
7949 megasas_remove_scsi_device(sdev1);
Yang, Boc9786842009-12-06 08:39:25 -07007950 }
Yang, Boc9786842009-12-06 08:39:25 -07007951 }
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007952 }
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007953 }
7954
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307955 if (doscan & SCAN_VD_CHANNEL) {
7956 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
7957 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
7958 ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
7959 sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
7960 if (instance->ld_ids[ld_index] != 0xff) {
7961 if (!sdev1)
7962 scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
7963 else
7964 scsi_device_put(sdev1);
7965 } else {
Shivasharan Sb4a42212017-02-10 00:59:16 -08007966 if (sdev1)
7967 megasas_remove_scsi_device(sdev1);
Yang, Boc9786842009-12-06 08:39:25 -07007968 }
7969 }
7970 }
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007971 }
7972
Sumit Saxena6d40afb2016-01-28 21:04:23 +05307973 if (dcmd_ret == DCMD_SUCCESS)
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307974 seq_num = le32_to_cpu(instance->evt_detail->seq_num) + 1;
7975 else
7976 seq_num = instance->last_seq_num;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007977
7978 /* Register AEN with FW for latest sequence number plus 1 */
7979 class_locale.members.reserved = 0;
7980 class_locale.members.locale = MR_EVT_LOCALE_ALL;
7981 class_locale.members.class = MR_EVT_CLASS_DEBUG;
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307982
7983 if (instance->aen_cmd != NULL) {
7984 kfree(ev);
7985 return;
7986 }
7987
7988 mutex_lock(&instance->reset_mutex);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007989 error = megasas_register_aen(instance, seq_num,
7990 class_locale.word);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007991 if (error)
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307992 dev_err(&instance->pdev->dev,
7993 "register aen failed error %x\n", error);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007994
Sumit Saxena11c71cb2016-01-28 21:04:22 +05307995 mutex_unlock(&instance->reset_mutex);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06007996 kfree(ev);
7997}
7998
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04007999/**
8000 * megasas_init - Driver load entry point
8001 */
8002static int __init megasas_init(void)
8003{
8004 int rval;
8005
8006 /*
Sumit Saxenac3e385a2016-04-15 00:23:30 -07008007 * Booted in kdump kernel, minimize memory footprints by
8008 * disabling few features
8009 */
8010 if (reset_devices) {
8011 msix_vectors = 1;
8012 rdpq_enable = 0;
8013 dual_qdepth_disable = 1;
8014 }
8015
8016 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008017 * Announce driver version and other information
8018 */
Sumit.Saxena@avagotech.comd98a6de2014-11-17 15:23:58 +05308019 pr_info("megasas: %s\n", MEGASAS_VERSION);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008020
Kashyap Desaibd8d6dd2012-07-17 18:20:44 -07008021 spin_lock_init(&poll_aen_lock);
8022
Yang, Bo72c4fd32009-10-06 14:20:59 -06008023 support_poll_for_event = 2;
Yang, Bo837f5fe2010-10-11 06:59:20 -06008024 support_device_change = 1;
Shivasharan Sf870bcb2018-01-05 05:33:04 -08008025 support_nvme_encapsulation = true;
Yang, Bo72c4fd32009-10-06 14:20:59 -06008026
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008027 memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
8028
8029 /*
8030 * Register character device node
8031 */
8032 rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops);
8033
8034 if (rval < 0) {
8035 printk(KERN_DEBUG "megasas: failed to open device node\n");
8036 return rval;
8037 }
8038
8039 megasas_mgmt_majorno = rval;
8040
8041 /*
8042 * Register ourselves as PCI hotplug module
8043 */
Michal Piotrowski4041b9c2006-08-17 13:28:22 +00008044 rval = pci_register_driver(&megasas_pci_driver);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008045
8046 if (rval) {
Masanari Iida6774def2014-11-05 22:26:48 +09008047 printk(KERN_DEBUG "megasas: PCI hotplug registration failed \n");
Jeff Garzik83aabc12006-10-04 06:34:03 -04008048 goto err_pcidrv;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008049 }
8050
Jeff Garzik83aabc12006-10-04 06:34:03 -04008051 rval = driver_create_file(&megasas_pci_driver.driver,
8052 &driver_attr_version);
8053 if (rval)
8054 goto err_dcf_attr_ver;
Yang, Bo72c4fd32009-10-06 14:20:59 -06008055
8056 rval = driver_create_file(&megasas_pci_driver.driver,
Sumit.Saxena@avagotech.com09fced12015-04-23 16:31:54 +05308057 &driver_attr_release_date);
8058 if (rval)
8059 goto err_dcf_rel_date;
8060
8061 rval = driver_create_file(&megasas_pci_driver.driver,
Yang, Bo72c4fd32009-10-06 14:20:59 -06008062 &driver_attr_support_poll_for_event);
8063 if (rval)
8064 goto err_dcf_support_poll_for_event;
8065
Jeff Garzik83aabc12006-10-04 06:34:03 -04008066 rval = driver_create_file(&megasas_pci_driver.driver,
8067 &driver_attr_dbg_lvl);
8068 if (rval)
8069 goto err_dcf_dbg_lvl;
bo yangad84db22007-11-09 04:40:16 -05008070 rval = driver_create_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06008071 &driver_attr_support_device_change);
8072 if (rval)
8073 goto err_dcf_support_device_change;
8074
Shivasharan Sf870bcb2018-01-05 05:33:04 -08008075 rval = driver_create_file(&megasas_pci_driver.driver,
8076 &driver_attr_support_nvme_encapsulation);
8077 if (rval)
8078 goto err_dcf_support_nvme_encapsulation;
8079
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008080 return rval;
bo yangad84db22007-11-09 04:40:16 -05008081
Shivasharan Sf870bcb2018-01-05 05:33:04 -08008082err_dcf_support_nvme_encapsulation:
8083 driver_remove_file(&megasas_pci_driver.driver,
8084 &driver_attr_support_device_change);
8085
Yang, Bo837f5fe2010-10-11 06:59:20 -06008086err_dcf_support_device_change:
8087 driver_remove_file(&megasas_pci_driver.driver,
bo yangad84db22007-11-09 04:40:16 -05008088 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04008089err_dcf_dbg_lvl:
8090 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo72c4fd32009-10-06 14:20:59 -06008091 &driver_attr_support_poll_for_event);
Yang, Bo72c4fd32009-10-06 14:20:59 -06008092err_dcf_support_poll_for_event:
Sumit.Saxena@avagotech.com09fced12015-04-23 16:31:54 +05308093 driver_remove_file(&megasas_pci_driver.driver,
8094 &driver_attr_release_date);
8095err_dcf_rel_date:
Jeff Garzik83aabc12006-10-04 06:34:03 -04008096 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
8097err_dcf_attr_ver:
8098 pci_unregister_driver(&megasas_pci_driver);
8099err_pcidrv:
8100 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
adam radford0d490162010-12-14 19:17:17 -08008101 return rval;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008102}
8103
8104/**
8105 * megasas_exit - Driver unload entry point
8106 */
8107static void __exit megasas_exit(void)
8108{
Sumant Patro658dced2006-10-03 13:09:14 -07008109 driver_remove_file(&megasas_pci_driver.driver,
8110 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04008111 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06008112 &driver_attr_support_poll_for_event);
8113 driver_remove_file(&megasas_pci_driver.driver,
8114 &driver_attr_support_device_change);
Sumit.Saxena@avagotech.com09fced12015-04-23 16:31:54 +05308115 driver_remove_file(&megasas_pci_driver.driver,
8116 &driver_attr_release_date);
Jeff Garzik83aabc12006-10-04 06:34:03 -04008117 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
Shivasharan Sf870bcb2018-01-05 05:33:04 -08008118 driver_remove_file(&megasas_pci_driver.driver,
8119 &driver_attr_support_nvme_encapsulation);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04008120
8121 pci_unregister_driver(&megasas_pci_driver);
8122 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
8123}
8124
8125module_init(megasas_init);
8126module_exit(megasas_exit);