blob: 22a04e37b70acfa63b3f3cb7e61ddb31ef9ec209 [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 *
adam radfordae590572012-10-01 19:27:34 -07004 * Copyright (c) 2003-2012 LSI Corporation.
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005 *
adam radford3f1530c2010-12-14 18:51:48 -08006 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040010 *
adam radford3f1530c2010-12-14 18:51:48 -080011 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040015 *
adam radford3f1530c2010-12-14 18:51:48 -080016 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040019 *
adam radford3f1530c2010-12-14 18:51:48 -080020 * FILE: megaraid_sas_base.c
adam radford10b1db82014-03-10 02:52:03 -070021 * Version : 06.803.01.00-rc1
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040022 *
adam radford3f1530c2010-12-14 18:51:48 -080023 * Authors: LSI Corporation
24 * Sreenivas Bagalkote
25 * Sumant Patro
26 * Bo Yang
adam radford00fa2b12011-02-24 20:57:21 -080027 * Adam Radford <linuxraid@lsi.com>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040028 *
adam radford3f1530c2010-12-14 18:51:48 -080029 * Send feedback to: <megaraidlinux@lsi.com>
30 *
31 * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
32 * ATTN: Linuxraid
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040033 */
34
35#include <linux/kernel.h>
36#include <linux/types.h>
37#include <linux/pci.h>
38#include <linux/list.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040039#include <linux/moduleparam.h>
40#include <linux/module.h>
41#include <linux/spinlock.h>
42#include <linux/interrupt.h>
43#include <linux/delay.h>
44#include <linux/uio.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090045#include <linux/slab.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040046#include <asm/uaccess.h>
Al Viro43399232005-10-04 17:36:04 +010047#include <linux/fs.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040048#include <linux/compat.h>
Sumant Patrocf62a0a2007-02-14 12:41:55 -080049#include <linux/blkdev.h>
Arjan van de Ven0b950672006-01-11 13:16:10 +010050#include <linux/mutex.h>
Yang, Boc3518832009-10-06 14:18:02 -060051#include <linux/poll.h>
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040052
53#include <scsi/scsi.h>
54#include <scsi/scsi_cmnd.h>
55#include <scsi/scsi_device.h>
56#include <scsi/scsi_host.h>
adam radford4bcde502011-07-26 15:42:52 -070057#include <scsi/scsi_tcq.h>
adam radford9c915a82010-12-21 13:34:31 -080058#include "megaraid_sas_fusion.h"
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040059#include "megaraid_sas.h"
60
bo yangad84db22007-11-09 04:40:16 -050061/*
Yang, Bo1fd10682010-10-12 07:18:50 -060062 * Number of sectors per IO command
63 * Will be set in megasas_init_mfi if user does not provide
64 */
65static unsigned int max_sectors;
66module_param_named(max_sectors, max_sectors, int, 0);
67MODULE_PARM_DESC(max_sectors,
68 "Maximum number of sectors per IO command");
69
adam radford80d9da92010-12-21 10:17:40 -080070static int msix_disable;
71module_param(msix_disable, int, S_IRUGO);
72MODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0");
73
adam radford079eadd2012-10-01 19:26:59 -070074static unsigned int msix_vectors;
75module_param(msix_vectors, int, S_IRUGO);
76MODULE_PARM_DESC(msix_vectors, "MSI-X max vector count. Default: Set by FW");
77
adam radford229fe472014-03-10 02:51:56 -070078static int allow_vf_ioctls;
79module_param(allow_vf_ioctls, int, S_IRUGO);
80MODULE_PARM_DESC(allow_vf_ioctls, "Allow ioctls in SR-IOV VF mode. Default: 0");
81
adam radfordc5daa6a2012-07-17 18:20:03 -070082static int throttlequeuedepth = MEGASAS_THROTTLE_QUEUE_DEPTH;
83module_param(throttlequeuedepth, int, S_IRUGO);
84MODULE_PARM_DESC(throttlequeuedepth,
85 "Adapter queue depth when throttled due to I/O timeout. Default: 16");
86
adam radfordc007b8b2012-07-17 18:20:24 -070087int resetwaittime = MEGASAS_RESET_WAIT_TIME;
88module_param(resetwaittime, int, S_IRUGO);
89MODULE_PARM_DESC(resetwaittime, "Wait time in seconds after I/O timeout "
90 "before resetting adapter. Default: 180");
91
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040092MODULE_LICENSE("GPL");
93MODULE_VERSION(MEGASAS_VERSION);
Sumant Patro3d6d1742006-12-29 08:13:54 -080094MODULE_AUTHOR("megaraidlinux@lsi.com");
bo yangf28cd7c2007-11-09 04:44:56 -050095MODULE_DESCRIPTION("LSI MegaRAID SAS Driver");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040096
adam radford058a8fa2011-10-08 18:14:27 -070097int megasas_transition_to_ready(struct megasas_instance *instance, int ocr);
bo yang39a98552010-09-22 22:36:29 -040098static int megasas_get_pd_list(struct megasas_instance *instance);
adam radford21c9e162013-09-06 15:27:14 -070099static int megasas_ld_list_query(struct megasas_instance *instance,
100 u8 query_type);
bo yang39a98552010-09-22 22:36:29 -0400101static int megasas_issue_init_mfi(struct megasas_instance *instance);
102static int megasas_register_aen(struct megasas_instance *instance,
103 u32 seq_num, u32 class_locale_word);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400104/*
105 * PCI ID table for all supported controllers
106 */
107static struct pci_device_id megasas_pci_table[] = {
108
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200109 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064R)},
110 /* xscale IOP */
111 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
112 /* ppc IOP */
bo yangaf7a5642008-03-17 04:13:07 -0400113 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)},
114 /* ppc IOP */
Yang, Bo6610a6b2008-08-10 12:42:38 -0700115 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)},
116 /* gen2*/
117 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
118 /* gen2*/
Yang, Bo87911122009-10-06 14:31:54 -0600119 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
120 /* skinny*/
121 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
122 /* skinny*/
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200123 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
124 /* xscale IOP, vega */
125 {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
126 /* xscale IOP */
adam radford9c915a82010-12-21 13:34:31 -0800127 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FUSION)},
128 /* Fusion */
adam radford229fe472014-03-10 02:51:56 -0700129 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_PLASMA)},
130 /* Plasma */
adam radford36807e62011-10-08 18:15:06 -0700131 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INVADER)},
132 /* Invader */
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +0530133 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FURY)},
134 /* Fury */
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200135 {}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400136};
137
138MODULE_DEVICE_TABLE(pci, megasas_pci_table);
139
140static int megasas_mgmt_majorno;
adam radford229fe472014-03-10 02:51:56 -0700141struct megasas_mgmt_info megasas_mgmt_info;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400142static struct fasync_struct *megasas_async_queue;
Arjan van de Ven0b950672006-01-11 13:16:10 +0100143static DEFINE_MUTEX(megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400144
Yang, Boc3518832009-10-06 14:18:02 -0600145static int megasas_poll_wait_aen;
146static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
Yang, Bo72c4fd32009-10-06 14:20:59 -0600147static u32 support_poll_for_event;
adam radford9c915a82010-12-21 13:34:31 -0800148u32 megasas_dbg_lvl;
Yang, Bo837f5fe2010-10-11 06:59:20 -0600149static u32 support_device_change;
Sumant Patro658dced2006-10-03 13:09:14 -0700150
Yang, Boc3518832009-10-06 14:18:02 -0600151/* define lock for aen poll */
152spinlock_t poll_aen_lock;
153
adam radford9c915a82010-12-21 13:34:31 -0800154void
bo yang7343eb62007-11-09 04:35:44 -0500155megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
156 u8 alt_status);
adam radfordebf054b2011-02-24 20:57:15 -0800157static u32
158megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs);
159static int
160megasas_adp_reset_gen2(struct megasas_instance *instance,
161 struct megasas_register_set __iomem *reg_set);
adam radfordcd50ba82010-12-21 10:23:23 -0800162static irqreturn_t megasas_isr(int irq, void *devp);
163static u32
164megasas_init_adapter_mfi(struct megasas_instance *instance);
165u32
166megasas_build_and_issue_cmd(struct megasas_instance *instance,
167 struct scsi_cmnd *scmd);
168static void megasas_complete_cmd_dpc(unsigned long instance_addr);
adam radford9c915a82010-12-21 13:34:31 -0800169void
170megasas_release_fusion(struct megasas_instance *instance);
171int
172megasas_ioc_init_fusion(struct megasas_instance *instance);
173void
174megasas_free_cmds_fusion(struct megasas_instance *instance);
175u8
176megasas_get_map_info(struct megasas_instance *instance);
177int
178megasas_sync_map_info(struct megasas_instance *instance);
179int
adam radford229fe472014-03-10 02:51:56 -0700180wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
181 int seconds);
adam radford9c915a82010-12-21 13:34:31 -0800182void megasas_reset_reply_desc(struct megasas_instance *instance);
adam radford229fe472014-03-10 02:51:56 -0700183int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout);
adam radford9c915a82010-12-21 13:34:31 -0800184void megasas_fusion_ocr_wq(struct work_struct *work);
adam radford229fe472014-03-10 02:51:56 -0700185static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
186 int initial);
187int megasas_check_mpio_paths(struct megasas_instance *instance,
188 struct scsi_cmnd *scmd);
adam radfordcd50ba82010-12-21 10:23:23 -0800189
190void
191megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
192{
193 instance->instancet->fire_cmd(instance,
194 cmd->frame_phys_addr, 0, instance->reg_set);
195}
bo yang7343eb62007-11-09 04:35:44 -0500196
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400197/**
198 * megasas_get_cmd - Get a command from the free pool
199 * @instance: Adapter soft state
200 *
201 * Returns a free command from the pool
202 */
adam radford9c915a82010-12-21 13:34:31 -0800203struct megasas_cmd *megasas_get_cmd(struct megasas_instance
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400204 *instance)
205{
206 unsigned long flags;
207 struct megasas_cmd *cmd = NULL;
208
209 spin_lock_irqsave(&instance->cmd_pool_lock, flags);
210
211 if (!list_empty(&instance->cmd_pool)) {
212 cmd = list_entry((&instance->cmd_pool)->next,
213 struct megasas_cmd, list);
214 list_del_init(&cmd->list);
215 } else {
216 printk(KERN_ERR "megasas: Command pool empty!\n");
217 }
218
219 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
220 return cmd;
221}
222
223/**
224 * megasas_return_cmd - Return a cmd to free command pool
225 * @instance: Adapter soft state
226 * @cmd: Command packet to be returned to free command pool
227 */
adam radford9c915a82010-12-21 13:34:31 -0800228inline void
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400229megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
230{
231 unsigned long flags;
232
233 spin_lock_irqsave(&instance->cmd_pool_lock, flags);
234
235 cmd->scmd = NULL;
adam radford9c915a82010-12-21 13:34:31 -0800236 cmd->frame_count = 0;
adam radforde5f93a32011-10-08 18:15:19 -0700237 if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
adam radford229fe472014-03-10 02:51:56 -0700238 (instance->pdev->device != PCI_DEVICE_ID_LSI_PLASMA) &&
adam radforde5f93a32011-10-08 18:15:19 -0700239 (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +0530240 (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
adam radforde5f93a32011-10-08 18:15:19 -0700241 (reset_devices))
242 cmd->frame->hdr.cmd = MFI_CMD_INVALID;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400243 list_add_tail(&cmd->list, &instance->cmd_pool);
244
245 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
246}
247
Sumant Patro1341c932006-01-25 12:02:40 -0800248
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400249/**
adam radford0d490162010-12-14 19:17:17 -0800250* The following functions are defined for xscale
Sumant Patro1341c932006-01-25 12:02:40 -0800251* (deviceid : 1064R, PERC5) controllers
252*/
253
254/**
255 * megasas_enable_intr_xscale - Enables interrupts
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400256 * @regs: MFI register set
257 */
258static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530259megasas_enable_intr_xscale(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400260{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530261 struct megasas_register_set __iomem *regs;
262 regs = instance->reg_set;
bo yang39a98552010-09-22 22:36:29 -0400263 writel(0, &(regs)->outbound_intr_mask);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400264
265 /* Dummy readl to force pci flush */
266 readl(&regs->outbound_intr_mask);
267}
268
269/**
Sumant Patrob274cab2006-10-03 12:52:12 -0700270 * megasas_disable_intr_xscale -Disables interrupt
271 * @regs: MFI register set
272 */
273static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530274megasas_disable_intr_xscale(struct megasas_instance *instance)
Sumant Patrob274cab2006-10-03 12:52:12 -0700275{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530276 struct megasas_register_set __iomem *regs;
Sumant Patrob274cab2006-10-03 12:52:12 -0700277 u32 mask = 0x1f;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530278 regs = instance->reg_set;
Sumant Patrob274cab2006-10-03 12:52:12 -0700279 writel(mask, &regs->outbound_intr_mask);
280 /* Dummy readl to force pci flush */
281 readl(&regs->outbound_intr_mask);
282}
283
284/**
Sumant Patro1341c932006-01-25 12:02:40 -0800285 * megasas_read_fw_status_reg_xscale - returns the current FW status value
286 * @regs: MFI register set
287 */
288static u32
289megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs)
290{
291 return readl(&(regs)->outbound_msg_0);
292}
293/**
294 * megasas_clear_interrupt_xscale - Check & clear interrupt
295 * @regs: MFI register set
296 */
adam radford0d490162010-12-14 19:17:17 -0800297static int
Sumant Patro1341c932006-01-25 12:02:40 -0800298megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
299{
300 u32 status;
bo yang39a98552010-09-22 22:36:29 -0400301 u32 mfiStatus = 0;
Sumant Patro1341c932006-01-25 12:02:40 -0800302 /*
303 * Check if it is our interrupt
304 */
305 status = readl(&regs->outbound_intr_status);
306
bo yang39a98552010-09-22 22:36:29 -0400307 if (status & MFI_OB_INTR_STATUS_MASK)
308 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
309 if (status & MFI_XSCALE_OMR0_CHANGE_INTERRUPT)
310 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
Sumant Patro1341c932006-01-25 12:02:40 -0800311
312 /*
313 * Clear the interrupt by writing back the same value
314 */
bo yang39a98552010-09-22 22:36:29 -0400315 if (mfiStatus)
316 writel(status, &regs->outbound_intr_status);
Sumant Patro1341c932006-01-25 12:02:40 -0800317
Yang, Bo06f579d2008-08-10 12:42:37 -0700318 /* Dummy readl to force pci flush */
319 readl(&regs->outbound_intr_status);
320
bo yang39a98552010-09-22 22:36:29 -0400321 return mfiStatus;
Sumant Patro1341c932006-01-25 12:02:40 -0800322}
323
324/**
325 * megasas_fire_cmd_xscale - Sends command to the FW
326 * @frame_phys_addr : Physical address of cmd
327 * @frame_count : Number of frames for the command
328 * @regs : MFI register set
329 */
adam radford0d490162010-12-14 19:17:17 -0800330static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600331megasas_fire_cmd_xscale(struct megasas_instance *instance,
332 dma_addr_t frame_phys_addr,
333 u32 frame_count,
334 struct megasas_register_set __iomem *regs)
Sumant Patro1341c932006-01-25 12:02:40 -0800335{
bo yang39a98552010-09-22 22:36:29 -0400336 unsigned long flags;
337 spin_lock_irqsave(&instance->hba_lock, flags);
Sumant Patro1341c932006-01-25 12:02:40 -0800338 writel((frame_phys_addr >> 3)|(frame_count),
339 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400340 spin_unlock_irqrestore(&instance->hba_lock, flags);
341}
342
343/**
344 * megasas_adp_reset_xscale - For controller reset
345 * @regs: MFI register set
346 */
347static int
348megasas_adp_reset_xscale(struct megasas_instance *instance,
349 struct megasas_register_set __iomem *regs)
350{
351 u32 i;
352 u32 pcidata;
353 writel(MFI_ADP_RESET, &regs->inbound_doorbell);
354
355 for (i = 0; i < 3; i++)
356 msleep(1000); /* sleep for 3 secs */
357 pcidata = 0;
358 pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata);
359 printk(KERN_NOTICE "pcidata = %x\n", pcidata);
360 if (pcidata & 0x2) {
361 printk(KERN_NOTICE "mfi 1068 offset read=%x\n", pcidata);
362 pcidata &= ~0x2;
363 pci_write_config_dword(instance->pdev,
364 MFI_1068_PCSR_OFFSET, pcidata);
365
366 for (i = 0; i < 2; i++)
367 msleep(1000); /* need to wait 2 secs again */
368
369 pcidata = 0;
370 pci_read_config_dword(instance->pdev,
371 MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata);
372 printk(KERN_NOTICE "1068 offset handshake read=%x\n", pcidata);
373 if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) {
374 printk(KERN_NOTICE "1068 offset pcidt=%x\n", pcidata);
375 pcidata = 0;
376 pci_write_config_dword(instance->pdev,
377 MFI_1068_FW_HANDSHAKE_OFFSET, pcidata);
378 }
379 }
380 return 0;
381}
382
383/**
384 * megasas_check_reset_xscale - For controller reset check
385 * @regs: MFI register set
386 */
387static int
388megasas_check_reset_xscale(struct megasas_instance *instance,
389 struct megasas_register_set __iomem *regs)
390{
bo yang39a98552010-09-22 22:36:29 -0400391
392 if ((instance->adprecovery != MEGASAS_HBA_OPERATIONAL) &&
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +0530393 (le32_to_cpu(*instance->consumer) ==
394 MEGASAS_ADPRESET_INPROG_SIGN))
bo yang39a98552010-09-22 22:36:29 -0400395 return 1;
bo yang39a98552010-09-22 22:36:29 -0400396 return 0;
Sumant Patro1341c932006-01-25 12:02:40 -0800397}
398
399static struct megasas_instance_template megasas_instance_template_xscale = {
400
401 .fire_cmd = megasas_fire_cmd_xscale,
402 .enable_intr = megasas_enable_intr_xscale,
Sumant Patrob274cab2006-10-03 12:52:12 -0700403 .disable_intr = megasas_disable_intr_xscale,
Sumant Patro1341c932006-01-25 12:02:40 -0800404 .clear_intr = megasas_clear_intr_xscale,
405 .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
bo yang39a98552010-09-22 22:36:29 -0400406 .adp_reset = megasas_adp_reset_xscale,
407 .check_reset = megasas_check_reset_xscale,
adam radfordcd50ba82010-12-21 10:23:23 -0800408 .service_isr = megasas_isr,
409 .tasklet = megasas_complete_cmd_dpc,
410 .init_adapter = megasas_init_adapter_mfi,
411 .build_and_issue_cmd = megasas_build_and_issue_cmd,
412 .issue_dcmd = megasas_issue_dcmd,
Sumant Patro1341c932006-01-25 12:02:40 -0800413};
414
415/**
adam radford0d490162010-12-14 19:17:17 -0800416* This is the end of set of functions & definitions specific
Sumant Patro1341c932006-01-25 12:02:40 -0800417* to xscale (deviceid : 1064R, PERC5) controllers
418*/
419
420/**
adam radford0d490162010-12-14 19:17:17 -0800421* The following functions are defined for ppc (deviceid : 0x60)
Sumant Patrof9876f02006-02-03 15:34:35 -0800422* controllers
423*/
424
425/**
426 * megasas_enable_intr_ppc - Enables interrupts
427 * @regs: MFI register set
428 */
429static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530430megasas_enable_intr_ppc(struct megasas_instance *instance)
Sumant Patrof9876f02006-02-03 15:34:35 -0800431{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530432 struct megasas_register_set __iomem *regs;
433 regs = instance->reg_set;
Sumant Patrof9876f02006-02-03 15:34:35 -0800434 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
adam radford0d490162010-12-14 19:17:17 -0800435
bo yang39a98552010-09-22 22:36:29 -0400436 writel(~0x80000000, &(regs)->outbound_intr_mask);
Sumant Patrof9876f02006-02-03 15:34:35 -0800437
438 /* Dummy readl to force pci flush */
439 readl(&regs->outbound_intr_mask);
440}
441
442/**
Sumant Patrob274cab2006-10-03 12:52:12 -0700443 * megasas_disable_intr_ppc - Disable interrupt
444 * @regs: MFI register set
445 */
446static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530447megasas_disable_intr_ppc(struct megasas_instance *instance)
Sumant Patrob274cab2006-10-03 12:52:12 -0700448{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530449 struct megasas_register_set __iomem *regs;
Sumant Patrob274cab2006-10-03 12:52:12 -0700450 u32 mask = 0xFFFFFFFF;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530451 regs = instance->reg_set;
Sumant Patrob274cab2006-10-03 12:52:12 -0700452 writel(mask, &regs->outbound_intr_mask);
453 /* Dummy readl to force pci flush */
454 readl(&regs->outbound_intr_mask);
455}
456
457/**
Sumant Patrof9876f02006-02-03 15:34:35 -0800458 * megasas_read_fw_status_reg_ppc - returns the current FW status value
459 * @regs: MFI register set
460 */
461static u32
462megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)
463{
464 return readl(&(regs)->outbound_scratch_pad);
465}
466
467/**
468 * megasas_clear_interrupt_ppc - Check & clear interrupt
469 * @regs: MFI register set
470 */
adam radford0d490162010-12-14 19:17:17 -0800471static int
Sumant Patrof9876f02006-02-03 15:34:35 -0800472megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
473{
adam radford3cc6851f92011-05-11 18:34:52 -0700474 u32 status, mfiStatus = 0;
475
Sumant Patrof9876f02006-02-03 15:34:35 -0800476 /*
477 * Check if it is our interrupt
478 */
479 status = readl(&regs->outbound_intr_status);
480
adam radford3cc6851f92011-05-11 18:34:52 -0700481 if (status & MFI_REPLY_1078_MESSAGE_INTERRUPT)
482 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
483
484 if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT)
485 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
Sumant Patrof9876f02006-02-03 15:34:35 -0800486
487 /*
488 * Clear the interrupt by writing back the same value
489 */
490 writel(status, &regs->outbound_doorbell_clear);
491
Yang, Bo06f579d2008-08-10 12:42:37 -0700492 /* Dummy readl to force pci flush */
493 readl(&regs->outbound_doorbell_clear);
494
adam radford3cc6851f92011-05-11 18:34:52 -0700495 return mfiStatus;
Sumant Patrof9876f02006-02-03 15:34:35 -0800496}
adam radford3cc6851f92011-05-11 18:34:52 -0700497
Sumant Patrof9876f02006-02-03 15:34:35 -0800498/**
499 * megasas_fire_cmd_ppc - Sends command to the FW
500 * @frame_phys_addr : Physical address of cmd
501 * @frame_count : Number of frames for the command
502 * @regs : MFI register set
503 */
adam radford0d490162010-12-14 19:17:17 -0800504static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600505megasas_fire_cmd_ppc(struct megasas_instance *instance,
506 dma_addr_t frame_phys_addr,
507 u32 frame_count,
508 struct megasas_register_set __iomem *regs)
Sumant Patrof9876f02006-02-03 15:34:35 -0800509{
bo yang39a98552010-09-22 22:36:29 -0400510 unsigned long flags;
511 spin_lock_irqsave(&instance->hba_lock, flags);
adam radford0d490162010-12-14 19:17:17 -0800512 writel((frame_phys_addr | (frame_count<<1))|1,
Sumant Patrof9876f02006-02-03 15:34:35 -0800513 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400514 spin_unlock_irqrestore(&instance->hba_lock, flags);
Sumant Patrof9876f02006-02-03 15:34:35 -0800515}
516
bo yang39a98552010-09-22 22:36:29 -0400517/**
bo yang39a98552010-09-22 22:36:29 -0400518 * megasas_check_reset_ppc - For controller reset check
519 * @regs: MFI register set
520 */
521static int
522megasas_check_reset_ppc(struct megasas_instance *instance,
523 struct megasas_register_set __iomem *regs)
524{
adam radford3cc6851f92011-05-11 18:34:52 -0700525 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL)
526 return 1;
527
bo yang39a98552010-09-22 22:36:29 -0400528 return 0;
529}
adam radford3cc6851f92011-05-11 18:34:52 -0700530
Sumant Patrof9876f02006-02-03 15:34:35 -0800531static struct megasas_instance_template megasas_instance_template_ppc = {
adam radford0d490162010-12-14 19:17:17 -0800532
Sumant Patrof9876f02006-02-03 15:34:35 -0800533 .fire_cmd = megasas_fire_cmd_ppc,
534 .enable_intr = megasas_enable_intr_ppc,
Sumant Patrob274cab2006-10-03 12:52:12 -0700535 .disable_intr = megasas_disable_intr_ppc,
Sumant Patrof9876f02006-02-03 15:34:35 -0800536 .clear_intr = megasas_clear_intr_ppc,
537 .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
adam radford3cc6851f92011-05-11 18:34:52 -0700538 .adp_reset = megasas_adp_reset_xscale,
bo yang39a98552010-09-22 22:36:29 -0400539 .check_reset = megasas_check_reset_ppc,
adam radfordcd50ba82010-12-21 10:23:23 -0800540 .service_isr = megasas_isr,
541 .tasklet = megasas_complete_cmd_dpc,
542 .init_adapter = megasas_init_adapter_mfi,
543 .build_and_issue_cmd = megasas_build_and_issue_cmd,
544 .issue_dcmd = megasas_issue_dcmd,
Sumant Patrof9876f02006-02-03 15:34:35 -0800545};
546
547/**
Yang, Bo87911122009-10-06 14:31:54 -0600548 * megasas_enable_intr_skinny - Enables interrupts
549 * @regs: MFI register set
550 */
551static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530552megasas_enable_intr_skinny(struct megasas_instance *instance)
Yang, Bo87911122009-10-06 14:31:54 -0600553{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530554 struct megasas_register_set __iomem *regs;
555 regs = instance->reg_set;
Yang, Bo87911122009-10-06 14:31:54 -0600556 writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
557
558 writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
559
560 /* Dummy readl to force pci flush */
561 readl(&regs->outbound_intr_mask);
562}
563
564/**
565 * megasas_disable_intr_skinny - Disables interrupt
566 * @regs: MFI register set
567 */
568static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530569megasas_disable_intr_skinny(struct megasas_instance *instance)
Yang, Bo87911122009-10-06 14:31:54 -0600570{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530571 struct megasas_register_set __iomem *regs;
Yang, Bo87911122009-10-06 14:31:54 -0600572 u32 mask = 0xFFFFFFFF;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530573 regs = instance->reg_set;
Yang, Bo87911122009-10-06 14:31:54 -0600574 writel(mask, &regs->outbound_intr_mask);
575 /* Dummy readl to force pci flush */
576 readl(&regs->outbound_intr_mask);
577}
578
579/**
580 * megasas_read_fw_status_reg_skinny - returns the current FW status value
581 * @regs: MFI register set
582 */
583static u32
584megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
585{
586 return readl(&(regs)->outbound_scratch_pad);
587}
588
589/**
590 * megasas_clear_interrupt_skinny - Check & clear interrupt
591 * @regs: MFI register set
592 */
593static int
594megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
595{
596 u32 status;
adam radfordebf054b2011-02-24 20:57:15 -0800597 u32 mfiStatus = 0;
598
Yang, Bo87911122009-10-06 14:31:54 -0600599 /*
600 * Check if it is our interrupt
601 */
602 status = readl(&regs->outbound_intr_status);
603
604 if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
bo yang39a98552010-09-22 22:36:29 -0400605 return 0;
Yang, Bo87911122009-10-06 14:31:54 -0600606 }
607
608 /*
adam radfordebf054b2011-02-24 20:57:15 -0800609 * Check if it is our interrupt
610 */
James Georgasa3fda7d2013-06-26 12:03:19 -0600611 if ((megasas_read_fw_status_reg_skinny(regs) & MFI_STATE_MASK) ==
adam radfordebf054b2011-02-24 20:57:15 -0800612 MFI_STATE_FAULT) {
613 mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
614 } else
615 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
616
617 /*
Yang, Bo87911122009-10-06 14:31:54 -0600618 * Clear the interrupt by writing back the same value
619 */
620 writel(status, &regs->outbound_intr_status);
621
622 /*
623 * dummy read to flush PCI
624 */
625 readl(&regs->outbound_intr_status);
626
adam radfordebf054b2011-02-24 20:57:15 -0800627 return mfiStatus;
Yang, Bo87911122009-10-06 14:31:54 -0600628}
629
630/**
631 * megasas_fire_cmd_skinny - Sends command to the FW
632 * @frame_phys_addr : Physical address of cmd
633 * @frame_count : Number of frames for the command
634 * @regs : MFI register set
635 */
636static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600637megasas_fire_cmd_skinny(struct megasas_instance *instance,
638 dma_addr_t frame_phys_addr,
639 u32 frame_count,
Yang, Bo87911122009-10-06 14:31:54 -0600640 struct megasas_register_set __iomem *regs)
641{
Yang, Bo0c79e682009-10-06 14:47:35 -0600642 unsigned long flags;
bo yang39a98552010-09-22 22:36:29 -0400643 spin_lock_irqsave(&instance->hba_lock, flags);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +0530644 writel(upper_32_bits(frame_phys_addr),
645 &(regs)->inbound_high_queue_port);
646 writel((lower_32_bits(frame_phys_addr) | (frame_count<<1))|1,
647 &(regs)->inbound_low_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400648 spin_unlock_irqrestore(&instance->hba_lock, flags);
649}
650
651/**
bo yang39a98552010-09-22 22:36:29 -0400652 * megasas_check_reset_skinny - For controller reset check
653 * @regs: MFI register set
654 */
655static int
656megasas_check_reset_skinny(struct megasas_instance *instance,
657 struct megasas_register_set __iomem *regs)
658{
adam radford3cc6851f92011-05-11 18:34:52 -0700659 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL)
660 return 1;
661
bo yang39a98552010-09-22 22:36:29 -0400662 return 0;
Yang, Bo87911122009-10-06 14:31:54 -0600663}
664
665static struct megasas_instance_template megasas_instance_template_skinny = {
666
667 .fire_cmd = megasas_fire_cmd_skinny,
668 .enable_intr = megasas_enable_intr_skinny,
669 .disable_intr = megasas_disable_intr_skinny,
670 .clear_intr = megasas_clear_intr_skinny,
671 .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
adam radfordebf054b2011-02-24 20:57:15 -0800672 .adp_reset = megasas_adp_reset_gen2,
bo yang39a98552010-09-22 22:36:29 -0400673 .check_reset = megasas_check_reset_skinny,
adam radfordcd50ba82010-12-21 10:23:23 -0800674 .service_isr = megasas_isr,
675 .tasklet = megasas_complete_cmd_dpc,
676 .init_adapter = megasas_init_adapter_mfi,
677 .build_and_issue_cmd = megasas_build_and_issue_cmd,
678 .issue_dcmd = megasas_issue_dcmd,
Yang, Bo87911122009-10-06 14:31:54 -0600679};
680
681
682/**
Yang, Bo6610a6b2008-08-10 12:42:38 -0700683* The following functions are defined for gen2 (deviceid : 0x78 0x79)
684* controllers
685*/
686
687/**
688 * megasas_enable_intr_gen2 - Enables interrupts
689 * @regs: MFI register set
690 */
691static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530692megasas_enable_intr_gen2(struct megasas_instance *instance)
Yang, Bo6610a6b2008-08-10 12:42:38 -0700693{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530694 struct megasas_register_set __iomem *regs;
695 regs = instance->reg_set;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700696 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
697
698 /* write ~0x00000005 (4 & 1) to the intr mask*/
699 writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
700
701 /* Dummy readl to force pci flush */
702 readl(&regs->outbound_intr_mask);
703}
704
705/**
706 * megasas_disable_intr_gen2 - Disables interrupt
707 * @regs: MFI register set
708 */
709static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530710megasas_disable_intr_gen2(struct megasas_instance *instance)
Yang, Bo6610a6b2008-08-10 12:42:38 -0700711{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530712 struct megasas_register_set __iomem *regs;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700713 u32 mask = 0xFFFFFFFF;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530714 regs = instance->reg_set;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700715 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_gen2 - returns the current FW status value
722 * @regs: MFI register set
723 */
724static u32
725megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs)
726{
727 return readl(&(regs)->outbound_scratch_pad);
728}
729
730/**
731 * megasas_clear_interrupt_gen2 - Check & clear interrupt
732 * @regs: MFI register set
733 */
734static int
735megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
736{
737 u32 status;
bo yang39a98552010-09-22 22:36:29 -0400738 u32 mfiStatus = 0;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700739 /*
740 * Check if it is our interrupt
741 */
742 status = readl(&regs->outbound_intr_status);
743
Sumit.Saxena@lsi.comb5bccad2013-05-22 12:29:54 +0530744 if (status & MFI_INTR_FLAG_REPLY_MESSAGE) {
bo yang39a98552010-09-22 22:36:29 -0400745 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
746 }
747 if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) {
748 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
749 }
Yang, Bo6610a6b2008-08-10 12:42:38 -0700750
751 /*
752 * Clear the interrupt by writing back the same value
753 */
bo yang39a98552010-09-22 22:36:29 -0400754 if (mfiStatus)
755 writel(status, &regs->outbound_doorbell_clear);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700756
757 /* Dummy readl to force pci flush */
758 readl(&regs->outbound_intr_status);
759
bo yang39a98552010-09-22 22:36:29 -0400760 return mfiStatus;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700761}
762/**
763 * megasas_fire_cmd_gen2 - Sends command to the FW
764 * @frame_phys_addr : Physical address of cmd
765 * @frame_count : Number of frames for the command
766 * @regs : MFI register set
767 */
768static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600769megasas_fire_cmd_gen2(struct megasas_instance *instance,
770 dma_addr_t frame_phys_addr,
771 u32 frame_count,
Yang, Bo6610a6b2008-08-10 12:42:38 -0700772 struct megasas_register_set __iomem *regs)
773{
bo yang39a98552010-09-22 22:36:29 -0400774 unsigned long flags;
775 spin_lock_irqsave(&instance->hba_lock, flags);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700776 writel((frame_phys_addr | (frame_count<<1))|1,
777 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400778 spin_unlock_irqrestore(&instance->hba_lock, flags);
779}
780
781/**
782 * megasas_adp_reset_gen2 - For controller reset
783 * @regs: MFI register set
784 */
785static int
786megasas_adp_reset_gen2(struct megasas_instance *instance,
787 struct megasas_register_set __iomem *reg_set)
788{
789 u32 retry = 0 ;
790 u32 HostDiag;
adam radfordebf054b2011-02-24 20:57:15 -0800791 u32 *seq_offset = &reg_set->seq_offset;
792 u32 *hostdiag_offset = &reg_set->host_diag;
bo yang39a98552010-09-22 22:36:29 -0400793
adam radfordebf054b2011-02-24 20:57:15 -0800794 if (instance->instancet == &megasas_instance_template_skinny) {
795 seq_offset = &reg_set->fusion_seq_offset;
796 hostdiag_offset = &reg_set->fusion_host_diag;
797 }
798
799 writel(0, seq_offset);
800 writel(4, seq_offset);
801 writel(0xb, seq_offset);
802 writel(2, seq_offset);
803 writel(7, seq_offset);
804 writel(0xd, seq_offset);
805
bo yang39a98552010-09-22 22:36:29 -0400806 msleep(1000);
807
adam radfordebf054b2011-02-24 20:57:15 -0800808 HostDiag = (u32)readl(hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400809
810 while ( !( HostDiag & DIAG_WRITE_ENABLE) ) {
811 msleep(100);
adam radfordebf054b2011-02-24 20:57:15 -0800812 HostDiag = (u32)readl(hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400813 printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n",
814 retry, HostDiag);
815
816 if (retry++ >= 100)
817 return 1;
818
819 }
820
821 printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag);
822
adam radfordebf054b2011-02-24 20:57:15 -0800823 writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400824
825 ssleep(10);
826
adam radfordebf054b2011-02-24 20:57:15 -0800827 HostDiag = (u32)readl(hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400828 while ( ( HostDiag & DIAG_RESET_ADAPTER) ) {
829 msleep(100);
adam radfordebf054b2011-02-24 20:57:15 -0800830 HostDiag = (u32)readl(hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400831 printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n",
832 retry, HostDiag);
833
834 if (retry++ >= 1000)
835 return 1;
836
837 }
838 return 0;
839}
840
841/**
842 * megasas_check_reset_gen2 - For controller reset check
843 * @regs: MFI register set
844 */
845static int
846megasas_check_reset_gen2(struct megasas_instance *instance,
847 struct megasas_register_set __iomem *regs)
848{
Yang, Bo707e09b2010-10-12 07:20:27 -0600849 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
850 return 1;
851 }
852
bo yang39a98552010-09-22 22:36:29 -0400853 return 0;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700854}
855
856static struct megasas_instance_template megasas_instance_template_gen2 = {
857
858 .fire_cmd = megasas_fire_cmd_gen2,
859 .enable_intr = megasas_enable_intr_gen2,
860 .disable_intr = megasas_disable_intr_gen2,
861 .clear_intr = megasas_clear_intr_gen2,
862 .read_fw_status_reg = megasas_read_fw_status_reg_gen2,
bo yang39a98552010-09-22 22:36:29 -0400863 .adp_reset = megasas_adp_reset_gen2,
864 .check_reset = megasas_check_reset_gen2,
adam radfordcd50ba82010-12-21 10:23:23 -0800865 .service_isr = megasas_isr,
866 .tasklet = megasas_complete_cmd_dpc,
867 .init_adapter = megasas_init_adapter_mfi,
868 .build_and_issue_cmd = megasas_build_and_issue_cmd,
869 .issue_dcmd = megasas_issue_dcmd,
Yang, Bo6610a6b2008-08-10 12:42:38 -0700870};
871
872/**
Sumant Patrof9876f02006-02-03 15:34:35 -0800873* This is the end of set of functions & definitions
bo yang39a98552010-09-22 22:36:29 -0400874* specific to gen2 (deviceid : 0x78, 0x79) controllers
Sumant Patrof9876f02006-02-03 15:34:35 -0800875*/
876
adam radford9c915a82010-12-21 13:34:31 -0800877/*
878 * Template added for TB (Fusion)
879 */
880extern struct megasas_instance_template megasas_instance_template_fusion;
881
Sumant Patrof9876f02006-02-03 15:34:35 -0800882/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400883 * megasas_issue_polled - Issues a polling command
884 * @instance: Adapter soft state
adam radford0d490162010-12-14 19:17:17 -0800885 * @cmd: Command packet to be issued
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400886 *
887 * For polling, MFI requires the cmd_status to be set to 0xFF before posting.
888 */
adam radford9c915a82010-12-21 13:34:31 -0800889int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400890megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
891{
adam radford229fe472014-03-10 02:51:56 -0700892 int seconds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400893
894 struct megasas_header *frame_hdr = &cmd->frame->hdr;
895
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +0530896 frame_hdr->cmd_status = MFI_CMD_STATUS_POLL_MODE;
897 frame_hdr->flags |= cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400898
899 /*
900 * Issue the frame using inbound queue port
901 */
adam radford9c915a82010-12-21 13:34:31 -0800902 instance->instancet->issue_dcmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400903
904 /*
905 * Wait for cmd_status to change
906 */
adam radford229fe472014-03-10 02:51:56 -0700907 if (instance->requestorId)
908 seconds = MEGASAS_ROUTINE_WAIT_TIME_VF;
909 else
910 seconds = MFI_POLL_TIMEOUT_SECS;
911 return wait_and_poll(instance, cmd, seconds);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400912}
913
914/**
915 * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds
916 * @instance: Adapter soft state
917 * @cmd: Command to be issued
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +0530918 * @timeout: Timeout in seconds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400919 *
920 * This function waits on an event for the command to be returned from ISR.
Sumant Patro2a3681e2006-10-03 13:19:21 -0700921 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400922 * Used to issue ioctl commands.
923 */
924static int
925megasas_issue_blocked_cmd(struct megasas_instance *instance,
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +0530926 struct megasas_cmd *cmd, int timeout)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400927{
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +0530928 int ret = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400929 cmd->cmd_status = ENODATA;
930
adam radford9c915a82010-12-21 13:34:31 -0800931 instance->instancet->issue_dcmd(instance, cmd);
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +0530932 if (timeout) {
933 ret = wait_event_timeout(instance->int_cmd_wait_q,
934 cmd->cmd_status != ENODATA, timeout * HZ);
935 if (!ret)
936 return 1;
937 } else
938 wait_event(instance->int_cmd_wait_q,
939 cmd->cmd_status != ENODATA);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400940
941 return 0;
942}
943
944/**
945 * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd
946 * @instance: Adapter soft state
947 * @cmd_to_abort: Previously issued cmd to be aborted
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +0530948 * @timeout: Timeout in seconds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400949 *
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +0530950 * MFI firmware can abort previously issued AEN comamnd (automatic event
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400951 * notification). The megasas_issue_blocked_abort_cmd() issues such abort
Sumant Patro2a3681e2006-10-03 13:19:21 -0700952 * cmd and waits for return status.
953 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400954 */
955static int
956megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +0530957 struct megasas_cmd *cmd_to_abort, int timeout)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400958{
959 struct megasas_cmd *cmd;
960 struct megasas_abort_frame *abort_fr;
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +0530961 int ret = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400962
963 cmd = megasas_get_cmd(instance);
964
965 if (!cmd)
966 return -1;
967
968 abort_fr = &cmd->frame->abort;
969
970 /*
971 * Prepare and issue the abort frame
972 */
973 abort_fr->cmd = MFI_CMD_ABORT;
974 abort_fr->cmd_status = 0xFF;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +0530975 abort_fr->flags = cpu_to_le16(0);
976 abort_fr->abort_context = cpu_to_le32(cmd_to_abort->index);
977 abort_fr->abort_mfi_phys_addr_lo =
978 cpu_to_le32(lower_32_bits(cmd_to_abort->frame_phys_addr));
979 abort_fr->abort_mfi_phys_addr_hi =
980 cpu_to_le32(upper_32_bits(cmd_to_abort->frame_phys_addr));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400981
982 cmd->sync_cmd = 1;
983 cmd->cmd_status = 0xFF;
984
adam radford9c915a82010-12-21 13:34:31 -0800985 instance->instancet->issue_dcmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400986
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +0530987 if (timeout) {
988 ret = wait_event_timeout(instance->abort_cmd_wait_q,
989 cmd->cmd_status != ENODATA, timeout * HZ);
990 if (!ret) {
991 dev_err(&instance->pdev->dev, "Command timedout"
992 "from %s\n", __func__);
993 return 1;
994 }
995 } else
996 wait_event(instance->abort_cmd_wait_q,
997 cmd->cmd_status != ENODATA);
998
bo yang39a98552010-09-22 22:36:29 -0400999 cmd->sync_cmd = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001000
1001 megasas_return_cmd(instance, cmd);
1002 return 0;
1003}
1004
1005/**
1006 * megasas_make_sgl32 - Prepares 32-bit SGL
1007 * @instance: Adapter soft state
1008 * @scp: SCSI command from the mid-layer
1009 * @mfi_sgl: SGL to be filled in
1010 *
1011 * If successful, this function returns the number of SG elements. Otherwise,
1012 * it returnes -1.
1013 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001014static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001015megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp,
1016 union megasas_sgl *mfi_sgl)
1017{
1018 int i;
1019 int sge_count;
1020 struct scatterlist *os_sgl;
1021
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001022 sge_count = scsi_dma_map(scp);
1023 BUG_ON(sge_count < 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001024
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001025 if (sge_count) {
1026 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301027 mfi_sgl->sge32[i].length = cpu_to_le32(sg_dma_len(os_sgl));
1028 mfi_sgl->sge32[i].phys_addr = cpu_to_le32(sg_dma_address(os_sgl));
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001029 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001030 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001031 return sge_count;
1032}
1033
1034/**
1035 * megasas_make_sgl64 - Prepares 64-bit SGL
1036 * @instance: Adapter soft state
1037 * @scp: SCSI command from the mid-layer
1038 * @mfi_sgl: SGL to be filled in
1039 *
1040 * If successful, this function returns the number of SG elements. Otherwise,
1041 * it returnes -1.
1042 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001043static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001044megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
1045 union megasas_sgl *mfi_sgl)
1046{
1047 int i;
1048 int sge_count;
1049 struct scatterlist *os_sgl;
1050
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001051 sge_count = scsi_dma_map(scp);
1052 BUG_ON(sge_count < 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001053
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001054 if (sge_count) {
1055 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301056 mfi_sgl->sge64[i].length = cpu_to_le32(sg_dma_len(os_sgl));
1057 mfi_sgl->sge64[i].phys_addr = cpu_to_le64(sg_dma_address(os_sgl));
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001058 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001059 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001060 return sge_count;
1061}
1062
Yang, Bof4c9a132009-10-06 14:43:28 -06001063/**
1064 * megasas_make_sgl_skinny - Prepares IEEE SGL
1065 * @instance: Adapter soft state
1066 * @scp: SCSI command from the mid-layer
1067 * @mfi_sgl: SGL to be filled in
1068 *
1069 * If successful, this function returns the number of SG elements. Otherwise,
1070 * it returnes -1.
1071 */
1072static int
1073megasas_make_sgl_skinny(struct megasas_instance *instance,
1074 struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
1075{
1076 int i;
1077 int sge_count;
1078 struct scatterlist *os_sgl;
1079
1080 sge_count = scsi_dma_map(scp);
1081
1082 if (sge_count) {
1083 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301084 mfi_sgl->sge_skinny[i].length =
1085 cpu_to_le32(sg_dma_len(os_sgl));
Yang, Bof4c9a132009-10-06 14:43:28 -06001086 mfi_sgl->sge_skinny[i].phys_addr =
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301087 cpu_to_le64(sg_dma_address(os_sgl));
1088 mfi_sgl->sge_skinny[i].flag = cpu_to_le32(0);
Yang, Bof4c9a132009-10-06 14:43:28 -06001089 }
1090 }
1091 return sge_count;
1092}
1093
Sumant Patrob1df99d2006-10-03 12:40:47 -07001094 /**
1095 * megasas_get_frame_count - Computes the number of frames
bo yangd532dbe2008-03-17 03:36:43 -04001096 * @frame_type : type of frame- io or pthru frame
Sumant Patrob1df99d2006-10-03 12:40:47 -07001097 * @sge_count : number of sg elements
1098 *
1099 * Returns the number of frames required for numnber of sge's (sge_count)
1100 */
1101
Yang, Bof4c9a132009-10-06 14:43:28 -06001102static u32 megasas_get_frame_count(struct megasas_instance *instance,
1103 u8 sge_count, u8 frame_type)
Sumant Patrob1df99d2006-10-03 12:40:47 -07001104{
1105 int num_cnt;
1106 int sge_bytes;
1107 u32 sge_sz;
1108 u32 frame_count=0;
1109
1110 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
1111 sizeof(struct megasas_sge32);
1112
Yang, Bof4c9a132009-10-06 14:43:28 -06001113 if (instance->flag_ieee) {
1114 sge_sz = sizeof(struct megasas_sge_skinny);
1115 }
1116
Sumant Patrob1df99d2006-10-03 12:40:47 -07001117 /*
bo yangd532dbe2008-03-17 03:36:43 -04001118 * Main frame can contain 2 SGEs for 64-bit SGLs and
1119 * 3 SGEs for 32-bit SGLs for ldio &
1120 * 1 SGEs for 64-bit SGLs and
1121 * 2 SGEs for 32-bit SGLs for pthru frame
1122 */
1123 if (unlikely(frame_type == PTHRU_FRAME)) {
Yang, Bof4c9a132009-10-06 14:43:28 -06001124 if (instance->flag_ieee == 1) {
1125 num_cnt = sge_count - 1;
1126 } else if (IS_DMA64)
bo yangd532dbe2008-03-17 03:36:43 -04001127 num_cnt = sge_count - 1;
1128 else
1129 num_cnt = sge_count - 2;
1130 } else {
Yang, Bof4c9a132009-10-06 14:43:28 -06001131 if (instance->flag_ieee == 1) {
1132 num_cnt = sge_count - 1;
1133 } else if (IS_DMA64)
bo yangd532dbe2008-03-17 03:36:43 -04001134 num_cnt = sge_count - 2;
1135 else
1136 num_cnt = sge_count - 3;
1137 }
Sumant Patrob1df99d2006-10-03 12:40:47 -07001138
1139 if(num_cnt>0){
1140 sge_bytes = sge_sz * num_cnt;
1141
1142 frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
1143 ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ;
1144 }
1145 /* Main frame */
1146 frame_count +=1;
1147
1148 if (frame_count > 7)
1149 frame_count = 8;
1150 return frame_count;
1151}
1152
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001153/**
1154 * megasas_build_dcdb - Prepares a direct cdb (DCDB) command
1155 * @instance: Adapter soft state
1156 * @scp: SCSI command
1157 * @cmd: Command to be prepared in
1158 *
1159 * This function prepares CDB commands. These are typcially pass-through
1160 * commands to the devices.
1161 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001162static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001163megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
1164 struct megasas_cmd *cmd)
1165{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001166 u32 is_logical;
1167 u32 device_id;
1168 u16 flags = 0;
1169 struct megasas_pthru_frame *pthru;
1170
1171 is_logical = MEGASAS_IS_LOGICAL(scp);
1172 device_id = MEGASAS_DEV_INDEX(instance, scp);
1173 pthru = (struct megasas_pthru_frame *)cmd->frame;
1174
1175 if (scp->sc_data_direction == PCI_DMA_TODEVICE)
1176 flags = MFI_FRAME_DIR_WRITE;
1177 else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
1178 flags = MFI_FRAME_DIR_READ;
1179 else if (scp->sc_data_direction == PCI_DMA_NONE)
1180 flags = MFI_FRAME_DIR_NONE;
1181
Yang, Bof4c9a132009-10-06 14:43:28 -06001182 if (instance->flag_ieee == 1) {
1183 flags |= MFI_FRAME_IEEE;
1184 }
1185
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001186 /*
1187 * Prepare the DCDB frame
1188 */
1189 pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO;
1190 pthru->cmd_status = 0x0;
1191 pthru->scsi_status = 0x0;
1192 pthru->target_id = device_id;
1193 pthru->lun = scp->device->lun;
1194 pthru->cdb_len = scp->cmd_len;
1195 pthru->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07001196 pthru->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301197 pthru->flags = cpu_to_le16(flags);
1198 pthru->data_xfer_len = cpu_to_le32(scsi_bufflen(scp));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001199
1200 memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
1201
1202 /*
Yang, Bo8d568252009-10-06 14:12:21 -06001203 * If the command is for the tape device, set the
1204 * pthru timeout to the os layer timeout value.
1205 */
1206 if (scp->device->type == TYPE_TAPE) {
1207 if ((scp->request->timeout / HZ) > 0xFFFF)
1208 pthru->timeout = 0xFFFF;
1209 else
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301210 pthru->timeout = cpu_to_le16(scp->request->timeout / HZ);
Yang, Bo8d568252009-10-06 14:12:21 -06001211 }
1212
1213 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001214 * Construct SGL
1215 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001216 if (instance->flag_ieee == 1) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301217 pthru->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Yang, Bof4c9a132009-10-06 14:43:28 -06001218 pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
1219 &pthru->sgl);
1220 } else if (IS_DMA64) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301221 pthru->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001222 pthru->sge_count = megasas_make_sgl64(instance, scp,
1223 &pthru->sgl);
1224 } else
1225 pthru->sge_count = megasas_make_sgl32(instance, scp,
1226 &pthru->sgl);
1227
Yang, Bobdc6fb82009-12-06 08:30:19 -07001228 if (pthru->sge_count > instance->max_num_sge) {
1229 printk(KERN_ERR "megasas: DCDB two many SGE NUM=%x\n",
1230 pthru->sge_count);
1231 return 0;
1232 }
1233
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001234 /*
1235 * Sense info specific
1236 */
1237 pthru->sense_len = SCSI_SENSE_BUFFERSIZE;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301238 pthru->sense_buf_phys_addr_hi =
1239 cpu_to_le32(upper_32_bits(cmd->sense_phys_addr));
1240 pthru->sense_buf_phys_addr_lo =
1241 cpu_to_le32(lower_32_bits(cmd->sense_phys_addr));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001242
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001243 /*
1244 * Compute the total number of frames this command consumes. FW uses
1245 * this number to pull sufficient number of frames from host memory.
1246 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001247 cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
bo yangd532dbe2008-03-17 03:36:43 -04001248 PTHRU_FRAME);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001249
1250 return cmd->frame_count;
1251}
1252
1253/**
1254 * megasas_build_ldio - Prepares IOs to logical devices
1255 * @instance: Adapter soft state
1256 * @scp: SCSI command
Anand Gadiyarfd589a82009-07-16 17:13:03 +02001257 * @cmd: Command to be prepared
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001258 *
1259 * Frames (and accompanying SGLs) for regular SCSI IOs use this function.
1260 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001261static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001262megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
1263 struct megasas_cmd *cmd)
1264{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001265 u32 device_id;
1266 u8 sc = scp->cmnd[0];
1267 u16 flags = 0;
1268 struct megasas_io_frame *ldio;
1269
1270 device_id = MEGASAS_DEV_INDEX(instance, scp);
1271 ldio = (struct megasas_io_frame *)cmd->frame;
1272
1273 if (scp->sc_data_direction == PCI_DMA_TODEVICE)
1274 flags = MFI_FRAME_DIR_WRITE;
1275 else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
1276 flags = MFI_FRAME_DIR_READ;
1277
Yang, Bof4c9a132009-10-06 14:43:28 -06001278 if (instance->flag_ieee == 1) {
1279 flags |= MFI_FRAME_IEEE;
1280 }
1281
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001282 /*
Sumant Patrob1df99d2006-10-03 12:40:47 -07001283 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001284 */
1285 ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ;
1286 ldio->cmd_status = 0x0;
1287 ldio->scsi_status = 0x0;
1288 ldio->target_id = device_id;
1289 ldio->timeout = 0;
1290 ldio->reserved_0 = 0;
1291 ldio->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301292 ldio->flags = cpu_to_le16(flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001293 ldio->start_lba_hi = 0;
1294 ldio->access_byte = (scp->cmd_len != 6) ? scp->cmnd[1] : 0;
1295
1296 /*
1297 * 6-byte READ(0x08) or WRITE(0x0A) cdb
1298 */
1299 if (scp->cmd_len == 6) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301300 ldio->lba_count = cpu_to_le32((u32) scp->cmnd[4]);
1301 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[1] << 16) |
1302 ((u32) scp->cmnd[2] << 8) |
1303 (u32) scp->cmnd[3]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001304
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301305 ldio->start_lba_lo &= cpu_to_le32(0x1FFFFF);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001306 }
1307
1308 /*
1309 * 10-byte READ(0x28) or WRITE(0x2A) cdb
1310 */
1311 else if (scp->cmd_len == 10) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301312 ldio->lba_count = cpu_to_le32((u32) scp->cmnd[8] |
1313 ((u32) scp->cmnd[7] << 8));
1314 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[2] << 24) |
1315 ((u32) scp->cmnd[3] << 16) |
1316 ((u32) scp->cmnd[4] << 8) |
1317 (u32) scp->cmnd[5]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001318 }
1319
1320 /*
1321 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
1322 */
1323 else if (scp->cmd_len == 12) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301324 ldio->lba_count = cpu_to_le32(((u32) scp->cmnd[6] << 24) |
1325 ((u32) scp->cmnd[7] << 16) |
1326 ((u32) scp->cmnd[8] << 8) |
1327 (u32) scp->cmnd[9]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001328
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301329 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[2] << 24) |
1330 ((u32) scp->cmnd[3] << 16) |
1331 ((u32) scp->cmnd[4] << 8) |
1332 (u32) scp->cmnd[5]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001333 }
1334
1335 /*
1336 * 16-byte READ(0x88) or WRITE(0x8A) cdb
1337 */
1338 else if (scp->cmd_len == 16) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301339 ldio->lba_count = cpu_to_le32(((u32) scp->cmnd[10] << 24) |
1340 ((u32) scp->cmnd[11] << 16) |
1341 ((u32) scp->cmnd[12] << 8) |
1342 (u32) scp->cmnd[13]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001343
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301344 ldio->start_lba_lo = cpu_to_le32(((u32) scp->cmnd[6] << 24) |
1345 ((u32) scp->cmnd[7] << 16) |
1346 ((u32) scp->cmnd[8] << 8) |
1347 (u32) scp->cmnd[9]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001348
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301349 ldio->start_lba_hi = cpu_to_le32(((u32) scp->cmnd[2] << 24) |
1350 ((u32) scp->cmnd[3] << 16) |
1351 ((u32) scp->cmnd[4] << 8) |
1352 (u32) scp->cmnd[5]);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001353
1354 }
1355
1356 /*
1357 * Construct SGL
1358 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001359 if (instance->flag_ieee) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301360 ldio->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Yang, Bof4c9a132009-10-06 14:43:28 -06001361 ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
1362 &ldio->sgl);
1363 } else if (IS_DMA64) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301364 ldio->flags |= cpu_to_le16(MFI_FRAME_SGL64);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001365 ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
1366 } else
1367 ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
1368
Yang, Bobdc6fb82009-12-06 08:30:19 -07001369 if (ldio->sge_count > instance->max_num_sge) {
1370 printk(KERN_ERR "megasas: build_ld_io: sge_count = %x\n",
1371 ldio->sge_count);
1372 return 0;
1373 }
1374
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001375 /*
1376 * Sense info specific
1377 */
1378 ldio->sense_len = SCSI_SENSE_BUFFERSIZE;
1379 ldio->sense_buf_phys_addr_hi = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301380 ldio->sense_buf_phys_addr_lo = cpu_to_le32(cmd->sense_phys_addr);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001381
Sumant Patrob1df99d2006-10-03 12:40:47 -07001382 /*
1383 * Compute the total number of frames this command consumes. FW uses
1384 * this number to pull sufficient number of frames from host memory.
1385 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001386 cmd->frame_count = megasas_get_frame_count(instance,
1387 ldio->sge_count, IO_FRAME);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001388
1389 return cmd->frame_count;
1390}
1391
1392/**
Sumant Patrocb59aa62006-01-25 11:53:25 -08001393 * megasas_is_ldio - Checks if the cmd is for logical drive
1394 * @scmd: SCSI command
adam radford0d490162010-12-14 19:17:17 -08001395 *
Sumant Patrocb59aa62006-01-25 11:53:25 -08001396 * Called by megasas_queue_command to find out if the command to be queued
adam radford0d490162010-12-14 19:17:17 -08001397 * is a logical drive command
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001398 */
adam radford9c915a82010-12-21 13:34:31 -08001399inline int megasas_is_ldio(struct scsi_cmnd *cmd)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001400{
Sumant Patrocb59aa62006-01-25 11:53:25 -08001401 if (!MEGASAS_IS_LOGICAL(cmd))
1402 return 0;
1403 switch (cmd->cmnd[0]) {
1404 case READ_10:
1405 case WRITE_10:
1406 case READ_12:
1407 case WRITE_12:
1408 case READ_6:
1409 case WRITE_6:
1410 case READ_16:
1411 case WRITE_16:
1412 return 1;
1413 default:
1414 return 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001415 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001416}
1417
Sumant Patro658dced2006-10-03 13:09:14 -07001418 /**
1419 * megasas_dump_pending_frames - Dumps the frame address of all pending cmds
1420 * in FW
1421 * @instance: Adapter soft state
1422 */
1423static inline void
1424megasas_dump_pending_frames(struct megasas_instance *instance)
1425{
1426 struct megasas_cmd *cmd;
1427 int i,n;
1428 union megasas_sgl *mfi_sgl;
1429 struct megasas_io_frame *ldio;
1430 struct megasas_pthru_frame *pthru;
1431 u32 sgcount;
1432 u32 max_cmd = instance->max_fw_cmds;
1433
1434 printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
1435 printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding));
1436 if (IS_DMA64)
1437 printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no);
1438 else
1439 printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);
1440
1441 printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
1442 for (i = 0; i < max_cmd; i++) {
1443 cmd = instance->cmd_list[i];
1444 if(!cmd->scmd)
1445 continue;
1446 printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
1447 if (megasas_is_ldio(cmd->scmd)){
1448 ldio = (struct megasas_io_frame *)cmd->frame;
1449 mfi_sgl = &ldio->sgl;
1450 sgcount = ldio->sge_count;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301451 printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x,"
1452 " lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",
1453 instance->host->host_no, cmd->frame_count, ldio->cmd, ldio->target_id,
1454 le32_to_cpu(ldio->start_lba_lo), le32_to_cpu(ldio->start_lba_hi),
1455 le32_to_cpu(ldio->sense_buf_phys_addr_lo), sgcount);
Sumant Patro658dced2006-10-03 13:09:14 -07001456 }
1457 else {
1458 pthru = (struct megasas_pthru_frame *) cmd->frame;
1459 mfi_sgl = &pthru->sgl;
1460 sgcount = pthru->sge_count;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301461 printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, "
1462 "lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",
1463 instance->host->host_no, cmd->frame_count, pthru->cmd, pthru->target_id,
1464 pthru->lun, pthru->cdb_len, le32_to_cpu(pthru->data_xfer_len),
1465 le32_to_cpu(pthru->sense_buf_phys_addr_lo), sgcount);
Sumant Patro658dced2006-10-03 13:09:14 -07001466 }
1467 if(megasas_dbg_lvl & MEGASAS_DBG_LVL){
1468 for (n = 0; n < sgcount; n++){
1469 if (IS_DMA64)
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301470 printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%llx ",
1471 le32_to_cpu(mfi_sgl->sge64[n].length),
1472 le64_to_cpu(mfi_sgl->sge64[n].phys_addr));
Sumant Patro658dced2006-10-03 13:09:14 -07001473 else
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301474 printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",
1475 le32_to_cpu(mfi_sgl->sge32[n].length),
1476 le32_to_cpu(mfi_sgl->sge32[n].phys_addr));
Sumant Patro658dced2006-10-03 13:09:14 -07001477 }
1478 }
1479 printk(KERN_ERR "\n");
1480 } /*for max_cmd*/
1481 printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
1482 for (i = 0; i < max_cmd; i++) {
1483
1484 cmd = instance->cmd_list[i];
1485
1486 if(cmd->sync_cmd == 1){
1487 printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
1488 }
1489 }
1490 printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
1491}
1492
adam radfordcd50ba82010-12-21 10:23:23 -08001493u32
1494megasas_build_and_issue_cmd(struct megasas_instance *instance,
1495 struct scsi_cmnd *scmd)
1496{
1497 struct megasas_cmd *cmd;
1498 u32 frame_count;
1499
1500 cmd = megasas_get_cmd(instance);
1501 if (!cmd)
1502 return SCSI_MLQUEUE_HOST_BUSY;
1503
1504 /*
1505 * Logical drive command
1506 */
1507 if (megasas_is_ldio(scmd))
1508 frame_count = megasas_build_ldio(instance, scmd, cmd);
1509 else
1510 frame_count = megasas_build_dcdb(instance, scmd, cmd);
1511
1512 if (!frame_count)
1513 goto out_return_cmd;
1514
1515 cmd->scmd = scmd;
1516 scmd->SCp.ptr = (char *)cmd;
1517
1518 /*
1519 * Issue the command to the FW
1520 */
1521 atomic_inc(&instance->fw_outstanding);
1522
1523 instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
1524 cmd->frame_count-1, instance->reg_set);
adam radfordcd50ba82010-12-21 10:23:23 -08001525
1526 return 0;
1527out_return_cmd:
1528 megasas_return_cmd(instance, cmd);
1529 return 1;
1530}
1531
1532
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001533/**
1534 * megasas_queue_command - Queue entry point
1535 * @scmd: SCSI command to be queued
1536 * @done: Callback entry point
1537 */
1538static int
Jeff Garzikf2812332010-11-16 02:10:29 -05001539megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001540{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001541 struct megasas_instance *instance;
bo yang39a98552010-09-22 22:36:29 -04001542 unsigned long flags;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001543
1544 instance = (struct megasas_instance *)
1545 scmd->device->host->hostdata;
Sumant Patroaf37acf2007-02-14 12:34:46 -08001546
bo yang39a98552010-09-22 22:36:29 -04001547 if (instance->issuepend_done == 0)
Sumant Patroaf37acf2007-02-14 12:34:46 -08001548 return SCSI_MLQUEUE_HOST_BUSY;
1549
bo yang39a98552010-09-22 22:36:29 -04001550 spin_lock_irqsave(&instance->hba_lock, flags);
Sumit.Saxena@lsi.comb09e66d2013-05-22 12:29:28 +05301551
adam radford229fe472014-03-10 02:51:56 -07001552 /* Check for an mpio path and adjust behavior */
1553 if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) {
1554 if (megasas_check_mpio_paths(instance, scmd) ==
1555 (DID_RESET << 16)) {
1556 spin_unlock_irqrestore(&instance->hba_lock, flags);
1557 return SCSI_MLQUEUE_HOST_BUSY;
1558 } else {
1559 spin_unlock_irqrestore(&instance->hba_lock, flags);
1560 scmd->result = DID_NO_CONNECT << 16;
1561 done(scmd);
1562 return 0;
1563 }
1564 }
1565
Sumit.Saxena@lsi.comb09e66d2013-05-22 12:29:28 +05301566 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
1567 spin_unlock_irqrestore(&instance->hba_lock, flags);
adam radford229fe472014-03-10 02:51:56 -07001568 scmd->result = DID_NO_CONNECT << 16;
Sumit.Saxena@lsi.comb09e66d2013-05-22 12:29:28 +05301569 done(scmd);
1570 return 0;
1571 }
1572
bo yang39a98552010-09-22 22:36:29 -04001573 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
1574 spin_unlock_irqrestore(&instance->hba_lock, flags);
1575 return SCSI_MLQUEUE_HOST_BUSY;
1576 }
1577
1578 spin_unlock_irqrestore(&instance->hba_lock, flags);
1579
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001580 scmd->scsi_done = done;
1581 scmd->result = 0;
1582
Sumant Patrocb59aa62006-01-25 11:53:25 -08001583 if (MEGASAS_IS_LOGICAL(scmd) &&
1584 (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) {
1585 scmd->result = DID_BAD_TARGET << 16;
1586 goto out_done;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001587 }
1588
Sumant Patro02b01e02007-02-14 13:00:55 -08001589 switch (scmd->cmnd[0]) {
1590 case SYNCHRONIZE_CACHE:
1591 /*
1592 * FW takes care of flush cache on its own
1593 * No need to send it down
1594 */
1595 scmd->result = DID_OK << 16;
1596 goto out_done;
1597 default:
1598 break;
1599 }
1600
adam radfordcd50ba82010-12-21 10:23:23 -08001601 if (instance->instancet->build_and_issue_cmd(instance, scmd)) {
1602 printk(KERN_ERR "megasas: Err returned from build_and_issue_cmd\n");
Sumant Patrocb59aa62006-01-25 11:53:25 -08001603 return SCSI_MLQUEUE_HOST_BUSY;
adam radfordcd50ba82010-12-21 10:23:23 -08001604 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001605
1606 return 0;
Sumant Patrocb59aa62006-01-25 11:53:25 -08001607
Sumant Patrocb59aa62006-01-25 11:53:25 -08001608 out_done:
1609 done(scmd);
1610 return 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001611}
1612
Jeff Garzikf2812332010-11-16 02:10:29 -05001613static DEF_SCSI_QCMD(megasas_queue_command)
1614
Yang, Bo044833b2009-10-06 14:33:06 -06001615static struct megasas_instance *megasas_lookup_instance(u16 host_no)
1616{
1617 int i;
1618
1619 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
1620
1621 if ((megasas_mgmt_info.instance[i]) &&
1622 (megasas_mgmt_info.instance[i]->host->host_no == host_no))
1623 return megasas_mgmt_info.instance[i];
1624 }
1625
1626 return NULL;
1627}
1628
Christoph Hellwig147aab62006-02-17 12:13:48 +01001629static int megasas_slave_configure(struct scsi_device *sdev)
1630{
Yang, Bo044833b2009-10-06 14:33:06 -06001631 u16 pd_index = 0;
1632 struct megasas_instance *instance ;
1633
1634 instance = megasas_lookup_instance(sdev->host->host_no);
Christoph Hellwige5b3a652006-03-10 17:08:57 +01001635
1636 /*
Yang, Bo044833b2009-10-06 14:33:06 -06001637 * Don't export physical disk devices to the disk driver.
1638 *
1639 * FIXME: Currently we don't export them to the midlayer at all.
1640 * That will be fixed once LSI engineers have audited the
1641 * firmware for possible issues.
1642 */
1643 if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
1644 sdev->type == TYPE_DISK) {
1645 pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
1646 sdev->id;
1647 if (instance->pd_list[pd_index].driveState ==
1648 MR_PD_STATE_SYSTEM) {
1649 blk_queue_rq_timeout(sdev->request_queue,
1650 MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1651 return 0;
1652 }
1653 return -ENXIO;
1654 }
1655
1656 /*
1657 * The RAID firmware may require extended timeouts.
1658 */
1659 blk_queue_rq_timeout(sdev->request_queue,
1660 MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1661 return 0;
1662}
1663
1664static int megasas_slave_alloc(struct scsi_device *sdev)
1665{
1666 u16 pd_index = 0;
1667 struct megasas_instance *instance ;
1668 instance = megasas_lookup_instance(sdev->host->host_no);
1669 if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
1670 (sdev->type == TYPE_DISK)) {
1671 /*
1672 * Open the OS scan to the SYSTEM PD
1673 */
1674 pd_index =
1675 (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
1676 sdev->id;
1677 if ((instance->pd_list[pd_index].driveState ==
1678 MR_PD_STATE_SYSTEM) &&
1679 (instance->pd_list[pd_index].driveType ==
1680 TYPE_DISK)) {
1681 return 0;
1682 }
1683 return -ENXIO;
1684 }
Christoph Hellwig147aab62006-02-17 12:13:48 +01001685 return 0;
1686}
1687
adam radford9c915a82010-12-21 13:34:31 -08001688void megaraid_sas_kill_hba(struct megasas_instance *instance)
bo yang39a98552010-09-22 22:36:29 -04001689{
1690 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
adam radford9c915a82010-12-21 13:34:31 -08001691 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
adam radford36807e62011-10-08 18:15:06 -07001692 (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
adam radford229fe472014-03-10 02:51:56 -07001693 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05301694 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
1695 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
adam radford9c915a82010-12-21 13:34:31 -08001696 writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
adam radford229fe472014-03-10 02:51:56 -07001697 /* Flush */
1698 readl(&instance->reg_set->doorbell);
1699 if (instance->mpio && instance->requestorId)
1700 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
bo yang39a98552010-09-22 22:36:29 -04001701 } else {
adam radford9c915a82010-12-21 13:34:31 -08001702 writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell);
1703 }
1704}
1705
1706 /**
1707 * megasas_check_and_restore_queue_depth - Check if queue depth needs to be
1708 * restored to max value
1709 * @instance: Adapter soft state
1710 *
1711 */
1712void
1713megasas_check_and_restore_queue_depth(struct megasas_instance *instance)
1714{
1715 unsigned long flags;
1716 if (instance->flag & MEGASAS_FW_BUSY
adam radfordc5daa6a2012-07-17 18:20:03 -07001717 && time_after(jiffies, instance->last_time + 5 * HZ)
1718 && atomic_read(&instance->fw_outstanding) <
1719 instance->throttlequeuedepth + 1) {
adam radford9c915a82010-12-21 13:34:31 -08001720
1721 spin_lock_irqsave(instance->host->host_lock, flags);
1722 instance->flag &= ~MEGASAS_FW_BUSY;
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05301723 if (instance->is_imr) {
adam radford9c915a82010-12-21 13:34:31 -08001724 instance->host->can_queue =
1725 instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
1726 } else
1727 instance->host->can_queue =
1728 instance->max_fw_cmds - MEGASAS_INT_CMDS;
1729
1730 spin_unlock_irqrestore(instance->host->host_lock, flags);
bo yang39a98552010-09-22 22:36:29 -04001731 }
1732}
1733
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001734/**
bo yang7343eb62007-11-09 04:35:44 -05001735 * megasas_complete_cmd_dpc - Returns FW's controller structure
1736 * @instance_addr: Address of adapter soft state
1737 *
1738 * Tasklet to complete cmds
1739 */
1740static void megasas_complete_cmd_dpc(unsigned long instance_addr)
1741{
1742 u32 producer;
1743 u32 consumer;
1744 u32 context;
1745 struct megasas_cmd *cmd;
1746 struct megasas_instance *instance =
1747 (struct megasas_instance *)instance_addr;
1748 unsigned long flags;
1749
1750 /* If we have already declared adapter dead, donot complete cmds */
bo yang39a98552010-09-22 22:36:29 -04001751 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR )
bo yang7343eb62007-11-09 04:35:44 -05001752 return;
1753
1754 spin_lock_irqsave(&instance->completion_lock, flags);
1755
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301756 producer = le32_to_cpu(*instance->producer);
1757 consumer = le32_to_cpu(*instance->consumer);
bo yang7343eb62007-11-09 04:35:44 -05001758
1759 while (consumer != producer) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301760 context = le32_to_cpu(instance->reply_queue[consumer]);
bo yang39a98552010-09-22 22:36:29 -04001761 if (context >= instance->max_fw_cmds) {
1762 printk(KERN_ERR "Unexpected context value %x\n",
1763 context);
1764 BUG();
1765 }
bo yang7343eb62007-11-09 04:35:44 -05001766
1767 cmd = instance->cmd_list[context];
1768
1769 megasas_complete_cmd(instance, cmd, DID_OK);
1770
1771 consumer++;
1772 if (consumer == (instance->max_fw_cmds + 1)) {
1773 consumer = 0;
1774 }
1775 }
1776
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301777 *instance->consumer = cpu_to_le32(producer);
bo yang7343eb62007-11-09 04:35:44 -05001778
1779 spin_unlock_irqrestore(&instance->completion_lock, flags);
1780
1781 /*
1782 * Check if we can restore can_queue
1783 */
adam radford9c915a82010-12-21 13:34:31 -08001784 megasas_check_and_restore_queue_depth(instance);
bo yang7343eb62007-11-09 04:35:44 -05001785}
1786
adam radford229fe472014-03-10 02:51:56 -07001787/**
1788 * megasas_start_timer - Initializes a timer object
1789 * @instance: Adapter soft state
1790 * @timer: timer object to be initialized
1791 * @fn: timer function
1792 * @interval: time interval between timer function call
1793 *
1794 */
1795void megasas_start_timer(struct megasas_instance *instance,
1796 struct timer_list *timer,
1797 void *fn, unsigned long interval)
1798{
1799 init_timer(timer);
1800 timer->expires = jiffies + interval;
1801 timer->data = (unsigned long)instance;
1802 timer->function = fn;
1803 add_timer(timer);
1804}
1805
Yang, Bo707e09b2010-10-12 07:20:27 -06001806static void
1807megasas_internal_reset_defer_cmds(struct megasas_instance *instance);
1808
1809static void
1810process_fw_state_change_wq(struct work_struct *work);
1811
1812void megasas_do_ocr(struct megasas_instance *instance)
1813{
1814 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
1815 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
1816 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05301817 *instance->consumer = cpu_to_le32(MEGASAS_ADPRESET_INPROG_SIGN);
Yang, Bo707e09b2010-10-12 07:20:27 -06001818 }
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05301819 instance->instancet->disable_intr(instance);
Yang, Bo707e09b2010-10-12 07:20:27 -06001820 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
1821 instance->issuepend_done = 0;
1822
1823 atomic_set(&instance->fw_outstanding, 0);
1824 megasas_internal_reset_defer_cmds(instance);
1825 process_fw_state_change_wq(&instance->work_init);
1826}
1827
adam radford229fe472014-03-10 02:51:56 -07001828/* This function will get the current SR-IOV LD/VF affiliation */
1829static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
1830 int initial)
1831{
1832 struct megasas_cmd *cmd;
1833 struct megasas_dcmd_frame *dcmd;
1834 struct MR_LD_VF_AFFILIATION *new_affiliation = NULL;
1835 struct MR_LD_VF_AFFILIATION_111 *new_affiliation_111 = NULL;
1836 struct MR_LD_VF_MAP *newmap = NULL, *savedmap = NULL;
1837 dma_addr_t new_affiliation_h;
1838 dma_addr_t new_affiliation_111_h;
1839 int ld, retval = 0;
1840 u8 thisVf;
1841
1842 cmd = megasas_get_cmd(instance);
1843
1844 if (!cmd) {
1845 printk(KERN_DEBUG "megasas: megasas_get_ld_vf_"
1846 "affiliation: Failed to get cmd for scsi%d.\n",
1847 instance->host->host_no);
1848 return -ENOMEM;
1849 }
1850
1851 dcmd = &cmd->frame->dcmd;
1852
1853 if (!instance->vf_affiliation && !instance->vf_affiliation_111) {
1854 printk(KERN_WARNING "megasas: SR-IOV: Couldn't get LD/VF "
1855 "affiliation for scsi%d.\n", instance->host->host_no);
1856 megasas_return_cmd(instance, cmd);
1857 return -ENOMEM;
1858 }
1859
1860 if (initial)
1861 if (instance->PlasmaFW111)
1862 memset(instance->vf_affiliation_111, 0,
1863 sizeof(struct MR_LD_VF_AFFILIATION_111));
1864 else
1865 memset(instance->vf_affiliation, 0,
1866 (MAX_LOGICAL_DRIVES + 1) *
1867 sizeof(struct MR_LD_VF_AFFILIATION));
1868 else {
1869 if (instance->PlasmaFW111)
1870 new_affiliation_111 =
1871 pci_alloc_consistent(instance->pdev,
1872 sizeof(struct MR_LD_VF_AFFILIATION_111),
1873 &new_affiliation_111_h);
1874 else
1875 new_affiliation =
1876 pci_alloc_consistent(instance->pdev,
1877 (MAX_LOGICAL_DRIVES + 1) *
1878 sizeof(struct MR_LD_VF_AFFILIATION),
1879 &new_affiliation_h);
1880 if (!new_affiliation && !new_affiliation_111) {
1881 printk(KERN_DEBUG "megasas: SR-IOV: Couldn't allocate "
1882 "memory for new affiliation for scsi%d.\n",
1883 instance->host->host_no);
1884 megasas_return_cmd(instance, cmd);
1885 return -ENOMEM;
1886 }
1887 if (instance->PlasmaFW111)
1888 memset(new_affiliation_111, 0,
1889 sizeof(struct MR_LD_VF_AFFILIATION_111));
1890 else
1891 memset(new_affiliation, 0, (MAX_LOGICAL_DRIVES + 1) *
1892 sizeof(struct MR_LD_VF_AFFILIATION));
1893 }
1894
1895 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
1896
1897 dcmd->cmd = MFI_CMD_DCMD;
1898 dcmd->cmd_status = 0xFF;
1899 dcmd->sge_count = 1;
1900 dcmd->flags = MFI_FRAME_DIR_BOTH;
1901 dcmd->timeout = 0;
1902 dcmd->pad_0 = 0;
1903 if (instance->PlasmaFW111) {
1904 dcmd->data_xfer_len = sizeof(struct MR_LD_VF_AFFILIATION_111);
1905 dcmd->opcode = MR_DCMD_LD_VF_MAP_GET_ALL_LDS_111;
1906 } else {
1907 dcmd->data_xfer_len = (MAX_LOGICAL_DRIVES + 1) *
1908 sizeof(struct MR_LD_VF_AFFILIATION);
1909 dcmd->opcode = MR_DCMD_LD_VF_MAP_GET_ALL_LDS;
1910 }
1911
1912 if (initial) {
1913 if (instance->PlasmaFW111)
1914 dcmd->sgl.sge32[0].phys_addr =
1915 instance->vf_affiliation_111_h;
1916 else
1917 dcmd->sgl.sge32[0].phys_addr =
1918 instance->vf_affiliation_h;
1919 } else {
1920 if (instance->PlasmaFW111)
1921 dcmd->sgl.sge32[0].phys_addr = new_affiliation_111_h;
1922 else
1923 dcmd->sgl.sge32[0].phys_addr = new_affiliation_h;
1924 }
1925 if (instance->PlasmaFW111)
1926 dcmd->sgl.sge32[0].length =
1927 sizeof(struct MR_LD_VF_AFFILIATION_111);
1928 else
1929 dcmd->sgl.sge32[0].length = (MAX_LOGICAL_DRIVES + 1) *
1930 sizeof(struct MR_LD_VF_AFFILIATION);
1931
1932 printk(KERN_WARNING "megasas: SR-IOV: Getting LD/VF affiliation for "
1933 "scsi%d\n", instance->host->host_no);
1934
1935 megasas_issue_blocked_cmd(instance, cmd, 0);
1936
1937 if (dcmd->cmd_status) {
1938 printk(KERN_WARNING "megasas: SR-IOV: LD/VF affiliation DCMD"
1939 " failed with status 0x%x for scsi%d.\n",
1940 dcmd->cmd_status, instance->host->host_no);
1941 retval = 1; /* Do a scan if we couldn't get affiliation */
1942 goto out;
1943 }
1944
1945 if (!initial) {
1946 if (instance->PlasmaFW111) {
1947 if (!new_affiliation_111->vdCount) {
1948 printk(KERN_WARNING "megasas: SR-IOV: Got new "
1949 "LD/VF affiliation for passive path "
1950 "for scsi%d.\n",
1951 instance->host->host_no);
1952 retval = 1;
1953 goto out;
1954 }
1955 thisVf = new_affiliation_111->thisVf;
1956 for (ld = 0 ; ld < new_affiliation_111->vdCount; ld++)
1957 if (instance->vf_affiliation_111->map[ld].policy[thisVf] != new_affiliation_111->map[ld].policy[thisVf]) {
1958 printk(KERN_WARNING "megasas: SR-IOV: "
1959 "Got new LD/VF affiliation "
1960 "for scsi%d.\n",
1961 instance->host->host_no);
1962 memcpy(instance->vf_affiliation_111,
1963 new_affiliation_111,
1964 sizeof(struct MR_LD_VF_AFFILIATION_111));
1965 retval = 1;
1966 goto out;
1967 }
1968 } else {
1969 if (!new_affiliation->ldCount) {
1970 printk(KERN_WARNING "megasas: SR-IOV: Got new "
1971 "LD/VF affiliation for passive "
1972 "path for scsi%d.\n",
1973 instance->host->host_no);
1974 retval = 1;
1975 goto out;
1976 }
1977 newmap = new_affiliation->map;
1978 savedmap = instance->vf_affiliation->map;
1979 thisVf = new_affiliation->thisVf;
1980 for (ld = 0 ; ld < new_affiliation->ldCount; ld++) {
1981 if (savedmap->policy[thisVf] !=
1982 newmap->policy[thisVf]) {
1983 printk(KERN_WARNING "megasas: SR-IOV: "
1984 "Got new LD/VF affiliation "
1985 "for scsi%d.\n",
1986 instance->host->host_no);
1987 memcpy(instance->vf_affiliation,
1988 new_affiliation,
1989 new_affiliation->size);
1990 retval = 1;
1991 goto out;
1992 }
1993 savedmap = (struct MR_LD_VF_MAP *)
1994 ((unsigned char *)savedmap +
1995 savedmap->size);
1996 newmap = (struct MR_LD_VF_MAP *)
1997 ((unsigned char *)newmap +
1998 newmap->size);
1999 }
2000 }
2001 }
2002out:
2003 if (new_affiliation) {
2004 if (instance->PlasmaFW111)
2005 pci_free_consistent(instance->pdev,
2006 sizeof(struct MR_LD_VF_AFFILIATION_111),
2007 new_affiliation_111,
2008 new_affiliation_111_h);
2009 else
2010 pci_free_consistent(instance->pdev,
2011 (MAX_LOGICAL_DRIVES + 1) *
2012 sizeof(struct MR_LD_VF_AFFILIATION),
2013 new_affiliation, new_affiliation_h);
2014 }
2015 megasas_return_cmd(instance, cmd);
2016
2017 return retval;
2018}
2019
2020/* This function will tell FW to start the SR-IOV heartbeat */
2021int megasas_sriov_start_heartbeat(struct megasas_instance *instance,
2022 int initial)
2023{
2024 struct megasas_cmd *cmd;
2025 struct megasas_dcmd_frame *dcmd;
2026 int retval = 0;
2027
2028 cmd = megasas_get_cmd(instance);
2029
2030 if (!cmd) {
2031 printk(KERN_DEBUG "megasas: megasas_sriov_start_heartbeat: "
2032 "Failed to get cmd for scsi%d.\n",
2033 instance->host->host_no);
2034 return -ENOMEM;
2035 }
2036
2037 dcmd = &cmd->frame->dcmd;
2038
2039 if (initial) {
2040 instance->hb_host_mem =
Joe Perches7c845eb2014-08-08 14:24:46 -07002041 pci_zalloc_consistent(instance->pdev,
2042 sizeof(struct MR_CTRL_HB_HOST_MEM),
2043 &instance->hb_host_mem_h);
adam radford229fe472014-03-10 02:51:56 -07002044 if (!instance->hb_host_mem) {
2045 printk(KERN_DEBUG "megasas: SR-IOV: Couldn't allocate"
2046 " memory for heartbeat host memory for "
2047 "scsi%d.\n", instance->host->host_no);
2048 retval = -ENOMEM;
2049 goto out;
2050 }
adam radford229fe472014-03-10 02:51:56 -07002051 }
2052
2053 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2054
2055 dcmd->mbox.s[0] = sizeof(struct MR_CTRL_HB_HOST_MEM);
2056 dcmd->cmd = MFI_CMD_DCMD;
2057 dcmd->cmd_status = 0xFF;
2058 dcmd->sge_count = 1;
2059 dcmd->flags = MFI_FRAME_DIR_BOTH;
2060 dcmd->timeout = 0;
2061 dcmd->pad_0 = 0;
2062 dcmd->data_xfer_len = sizeof(struct MR_CTRL_HB_HOST_MEM);
2063 dcmd->opcode = MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC;
2064 dcmd->sgl.sge32[0].phys_addr = instance->hb_host_mem_h;
2065 dcmd->sgl.sge32[0].length = sizeof(struct MR_CTRL_HB_HOST_MEM);
2066
2067 printk(KERN_WARNING "megasas: SR-IOV: Starting heartbeat for scsi%d\n",
2068 instance->host->host_no);
2069
2070 if (!megasas_issue_polled(instance, cmd)) {
2071 retval = 0;
2072 } else {
2073 printk(KERN_WARNING "megasas: SR-IOV: MR_DCMD_CTRL_SHARED_HOST"
2074 "_MEM_ALLOC DCMD timed out for scsi%d\n",
2075 instance->host->host_no);
2076 retval = 1;
2077 goto out;
2078 }
2079
2080
2081 if (dcmd->cmd_status) {
2082 printk(KERN_WARNING "megasas: SR-IOV: MR_DCMD_CTRL_SHARED_HOST"
2083 "_MEM_ALLOC DCMD failed with status 0x%x for scsi%d\n",
2084 dcmd->cmd_status,
2085 instance->host->host_no);
2086 retval = 1;
2087 goto out;
2088 }
2089
2090out:
2091 megasas_return_cmd(instance, cmd);
2092
2093 return retval;
2094}
2095
2096/* Handler for SR-IOV heartbeat */
2097void megasas_sriov_heartbeat_handler(unsigned long instance_addr)
2098{
2099 struct megasas_instance *instance =
2100 (struct megasas_instance *)instance_addr;
2101
2102 if (instance->hb_host_mem->HB.fwCounter !=
2103 instance->hb_host_mem->HB.driverCounter) {
2104 instance->hb_host_mem->HB.driverCounter =
2105 instance->hb_host_mem->HB.fwCounter;
2106 mod_timer(&instance->sriov_heartbeat_timer,
2107 jiffies + MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
2108 } else {
2109 printk(KERN_WARNING "megasas: SR-IOV: Heartbeat never "
2110 "completed for scsi%d\n", instance->host->host_no);
2111 schedule_work(&instance->work_init);
2112 }
2113}
2114
bo yang7343eb62007-11-09 04:35:44 -05002115/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002116 * megasas_wait_for_outstanding - Wait for all outstanding cmds
2117 * @instance: Adapter soft state
2118 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002119 * This function waits for up to MEGASAS_RESET_WAIT_TIME seconds for FW to
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002120 * complete all its outstanding commands. Returns error if one or more IOs
2121 * are pending after this time period. It also marks the controller dead.
2122 */
2123static int megasas_wait_for_outstanding(struct megasas_instance *instance)
2124{
2125 int i;
bo yang39a98552010-09-22 22:36:29 -04002126 u32 reset_index;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002127 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
bo yang39a98552010-09-22 22:36:29 -04002128 u8 adprecovery;
2129 unsigned long flags;
2130 struct list_head clist_local;
2131 struct megasas_cmd *reset_cmd;
Yang, Bo707e09b2010-10-12 07:20:27 -06002132 u32 fw_state;
2133 u8 kill_adapter_flag;
bo yang39a98552010-09-22 22:36:29 -04002134
2135 spin_lock_irqsave(&instance->hba_lock, flags);
2136 adprecovery = instance->adprecovery;
2137 spin_unlock_irqrestore(&instance->hba_lock, flags);
2138
2139 if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
2140
2141 INIT_LIST_HEAD(&clist_local);
2142 spin_lock_irqsave(&instance->hba_lock, flags);
2143 list_splice_init(&instance->internal_reset_pending_q,
2144 &clist_local);
2145 spin_unlock_irqrestore(&instance->hba_lock, flags);
2146
2147 printk(KERN_NOTICE "megasas: HBA reset wait ...\n");
2148 for (i = 0; i < wait_time; i++) {
2149 msleep(1000);
2150 spin_lock_irqsave(&instance->hba_lock, flags);
2151 adprecovery = instance->adprecovery;
2152 spin_unlock_irqrestore(&instance->hba_lock, flags);
2153 if (adprecovery == MEGASAS_HBA_OPERATIONAL)
2154 break;
2155 }
2156
2157 if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
2158 printk(KERN_NOTICE "megasas: reset: Stopping HBA.\n");
2159 spin_lock_irqsave(&instance->hba_lock, flags);
2160 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2161 spin_unlock_irqrestore(&instance->hba_lock, flags);
2162 return FAILED;
2163 }
2164
2165 reset_index = 0;
2166 while (!list_empty(&clist_local)) {
2167 reset_cmd = list_entry((&clist_local)->next,
2168 struct megasas_cmd, list);
2169 list_del_init(&reset_cmd->list);
2170 if (reset_cmd->scmd) {
2171 reset_cmd->scmd->result = DID_RESET << 16;
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002172 printk(KERN_NOTICE "%d:%p reset [%02x]\n",
bo yang39a98552010-09-22 22:36:29 -04002173 reset_index, reset_cmd,
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002174 reset_cmd->scmd->cmnd[0]);
bo yang39a98552010-09-22 22:36:29 -04002175
2176 reset_cmd->scmd->scsi_done(reset_cmd->scmd);
2177 megasas_return_cmd(instance, reset_cmd);
2178 } else if (reset_cmd->sync_cmd) {
2179 printk(KERN_NOTICE "megasas:%p synch cmds"
2180 "reset queue\n",
2181 reset_cmd);
2182
2183 reset_cmd->cmd_status = ENODATA;
2184 instance->instancet->fire_cmd(instance,
2185 reset_cmd->frame_phys_addr,
2186 0, instance->reg_set);
2187 } else {
2188 printk(KERN_NOTICE "megasas: %p unexpected"
2189 "cmds lst\n",
2190 reset_cmd);
2191 }
2192 reset_index++;
2193 }
2194
2195 return SUCCESS;
2196 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002197
adam radfordc007b8b2012-07-17 18:20:24 -07002198 for (i = 0; i < resetwaittime; i++) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002199
Sumant Patroe4a082c2006-05-30 12:03:37 -07002200 int outstanding = atomic_read(&instance->fw_outstanding);
2201
2202 if (!outstanding)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002203 break;
2204
2205 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
2206 printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
Sumant Patroe4a082c2006-05-30 12:03:37 -07002207 "commands to complete\n",i,outstanding);
bo yang7343eb62007-11-09 04:35:44 -05002208 /*
2209 * Call cmd completion routine. Cmd to be
2210 * be completed directly without depending on isr.
2211 */
2212 megasas_complete_cmd_dpc((unsigned long)instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002213 }
2214
2215 msleep(1000);
2216 }
2217
Yang, Bo707e09b2010-10-12 07:20:27 -06002218 i = 0;
2219 kill_adapter_flag = 0;
2220 do {
2221 fw_state = instance->instancet->read_fw_status_reg(
2222 instance->reg_set) & MFI_STATE_MASK;
2223 if ((fw_state == MFI_STATE_FAULT) &&
2224 (instance->disableOnlineCtrlReset == 0)) {
2225 if (i == 3) {
2226 kill_adapter_flag = 2;
2227 break;
2228 }
2229 megasas_do_ocr(instance);
2230 kill_adapter_flag = 1;
2231
2232 /* wait for 1 secs to let FW finish the pending cmds */
2233 msleep(1000);
2234 }
2235 i++;
2236 } while (i <= 3);
2237
2238 if (atomic_read(&instance->fw_outstanding) &&
2239 !kill_adapter_flag) {
2240 if (instance->disableOnlineCtrlReset == 0) {
2241
2242 megasas_do_ocr(instance);
2243
2244 /* wait for 5 secs to let FW finish the pending cmds */
2245 for (i = 0; i < wait_time; i++) {
2246 int outstanding =
2247 atomic_read(&instance->fw_outstanding);
2248 if (!outstanding)
2249 return SUCCESS;
2250 msleep(1000);
2251 }
2252 }
2253 }
2254
2255 if (atomic_read(&instance->fw_outstanding) ||
2256 (kill_adapter_flag == 2)) {
bo yang39a98552010-09-22 22:36:29 -04002257 printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n");
Sumant Patroe3bbff92006-10-03 12:28:49 -07002258 /*
2259 * Send signal to FW to stop processing any pending cmds.
2260 * The controller will be taken offline by the OS now.
2261 */
Yang, Bo0c79e682009-10-06 14:47:35 -06002262 if ((instance->pdev->device ==
2263 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2264 (instance->pdev->device ==
2265 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
2266 writel(MFI_STOP_ADP,
adam radford9c915a82010-12-21 13:34:31 -08002267 &instance->reg_set->doorbell);
Yang, Bo0c79e682009-10-06 14:47:35 -06002268 } else {
2269 writel(MFI_STOP_ADP,
Sumant Patroe3bbff92006-10-03 12:28:49 -07002270 &instance->reg_set->inbound_doorbell);
Yang, Bo0c79e682009-10-06 14:47:35 -06002271 }
Sumant Patro658dced2006-10-03 13:09:14 -07002272 megasas_dump_pending_frames(instance);
bo yang39a98552010-09-22 22:36:29 -04002273 spin_lock_irqsave(&instance->hba_lock, flags);
2274 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2275 spin_unlock_irqrestore(&instance->hba_lock, flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002276 return FAILED;
2277 }
2278
bo yang39a98552010-09-22 22:36:29 -04002279 printk(KERN_NOTICE "megaraid_sas: no pending cmds after reset\n");
2280
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002281 return SUCCESS;
2282}
2283
2284/**
2285 * megasas_generic_reset - Generic reset routine
2286 * @scmd: Mid-layer SCSI command
2287 *
2288 * This routine implements a generic reset handler for device, bus and host
2289 * reset requests. Device, bus and host specific reset handlers can use this
2290 * function after they do their specific tasks.
2291 */
2292static int megasas_generic_reset(struct scsi_cmnd *scmd)
2293{
2294 int ret_val;
2295 struct megasas_instance *instance;
2296
2297 instance = (struct megasas_instance *)scmd->device->host->hostdata;
2298
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002299 scmd_printk(KERN_NOTICE, scmd, "megasas: RESET cmd=%x retries=%x\n",
2300 scmd->cmnd[0], scmd->retries);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002301
bo yang39a98552010-09-22 22:36:29 -04002302 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002303 printk(KERN_ERR "megasas: cannot recover from previous reset "
2304 "failures\n");
2305 return FAILED;
2306 }
2307
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002308 ret_val = megasas_wait_for_outstanding(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002309 if (ret_val == SUCCESS)
2310 printk(KERN_NOTICE "megasas: reset successful \n");
2311 else
2312 printk(KERN_ERR "megasas: failed to do reset\n");
2313
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002314 return ret_val;
2315}
2316
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002317/**
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002318 * megasas_reset_timer - quiesce the adapter if required
2319 * @scmd: scsi cmnd
2320 *
2321 * Sets the FW busy flag and reduces the host->can_queue if the
2322 * cmd has not been completed within the timeout period.
2323 */
2324static enum
Jens Axboe242f9dc2008-09-14 05:55:09 -07002325blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002326{
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002327 struct megasas_instance *instance;
2328 unsigned long flags;
2329
2330 if (time_after(jiffies, scmd->jiffies_at_alloc +
2331 (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
Jens Axboe242f9dc2008-09-14 05:55:09 -07002332 return BLK_EH_NOT_HANDLED;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002333 }
2334
adam radfordf575c5d2011-10-13 16:01:12 -07002335 instance = (struct megasas_instance *)scmd->device->host->hostdata;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002336 if (!(instance->flag & MEGASAS_FW_BUSY)) {
2337 /* FW is busy, throttle IO */
2338 spin_lock_irqsave(instance->host->host_lock, flags);
2339
adam radfordc5daa6a2012-07-17 18:20:03 -07002340 instance->host->can_queue = instance->throttlequeuedepth;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002341 instance->last_time = jiffies;
2342 instance->flag |= MEGASAS_FW_BUSY;
2343
2344 spin_unlock_irqrestore(instance->host->host_lock, flags);
2345 }
Jens Axboe242f9dc2008-09-14 05:55:09 -07002346 return BLK_EH_RESET_TIMER;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002347}
2348
2349/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002350 * megasas_reset_device - Device reset handler entry point
2351 */
2352static int megasas_reset_device(struct scsi_cmnd *scmd)
2353{
2354 int ret;
2355
2356 /*
2357 * First wait for all commands to complete
2358 */
2359 ret = megasas_generic_reset(scmd);
2360
2361 return ret;
2362}
2363
2364/**
2365 * megasas_reset_bus_host - Bus & host reset handler entry point
2366 */
2367static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
2368{
2369 int ret;
adam radford9c915a82010-12-21 13:34:31 -08002370 struct megasas_instance *instance;
2371 instance = (struct megasas_instance *)scmd->device->host->hostdata;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002372
2373 /*
Uwe Zeisberger80682fa2006-03-22 00:21:33 +01002374 * First wait for all commands to complete
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002375 */
adam radford36807e62011-10-08 18:15:06 -07002376 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
adam radford229fe472014-03-10 02:51:56 -07002377 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05302378 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
2379 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
adam radford229fe472014-03-10 02:51:56 -07002380 ret = megasas_reset_fusion(scmd->device->host, 1);
adam radford9c915a82010-12-21 13:34:31 -08002381 else
2382 ret = megasas_generic_reset(scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002383
2384 return ret;
2385}
2386
2387/**
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002388 * megasas_bios_param - Returns disk geometry for a disk
2389 * @sdev: device handle
2390 * @bdev: block device
2391 * @capacity: drive capacity
2392 * @geom: geometry parameters
2393 */
2394static int
2395megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
2396 sector_t capacity, int geom[])
2397{
2398 int heads;
2399 int sectors;
2400 sector_t cylinders;
2401 unsigned long tmp;
2402 /* Default heads (64) & sectors (32) */
2403 heads = 64;
2404 sectors = 32;
2405
2406 tmp = heads * sectors;
2407 cylinders = capacity;
2408
2409 sector_div(cylinders, tmp);
2410
2411 /*
2412 * Handle extended translation size for logical drives > 1Gb
2413 */
2414
2415 if (capacity >= 0x200000) {
2416 heads = 255;
2417 sectors = 63;
2418 tmp = heads*sectors;
2419 cylinders = capacity;
2420 sector_div(cylinders, tmp);
2421 }
2422
2423 geom[0] = heads;
2424 geom[1] = sectors;
2425 geom[2] = cylinders;
2426
2427 return 0;
2428}
2429
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002430static void megasas_aen_polling(struct work_struct *work);
2431
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002432/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002433 * megasas_service_aen - Processes an event notification
2434 * @instance: Adapter soft state
2435 * @cmd: AEN command completed by the ISR
2436 *
2437 * For AEN, driver sends a command down to FW that is held by the FW till an
2438 * event occurs. When an event of interest occurs, FW completes the command
2439 * that it was previously holding.
2440 *
2441 * This routines sends SIGIO signal to processes that have registered with the
2442 * driver for AEN.
2443 */
2444static void
2445megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
2446{
Yang, Boc3518832009-10-06 14:18:02 -06002447 unsigned long flags;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002448 /*
2449 * Don't signal app if it is just an aborted previously registered aen
2450 */
Yang, Boc3518832009-10-06 14:18:02 -06002451 if ((!cmd->abort_aen) && (instance->unload == 0)) {
2452 spin_lock_irqsave(&poll_aen_lock, flags);
2453 megasas_poll_wait_aen = 1;
2454 spin_unlock_irqrestore(&poll_aen_lock, flags);
2455 wake_up(&megasas_poll_wait);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002456 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
Yang, Boc3518832009-10-06 14:18:02 -06002457 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002458 else
2459 cmd->abort_aen = 0;
2460
2461 instance->aen_cmd = NULL;
2462 megasas_return_cmd(instance, cmd);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002463
bo yang39a98552010-09-22 22:36:29 -04002464 if ((instance->unload == 0) &&
2465 ((instance->issuepend_done == 1))) {
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002466 struct megasas_aen_event *ev;
2467 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2468 if (!ev) {
2469 printk(KERN_ERR "megasas_service_aen: out of memory\n");
2470 } else {
2471 ev->instance = instance;
2472 instance->ev = ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08002473 INIT_DELAYED_WORK(&ev->hotplug_work,
2474 megasas_aen_polling);
2475 schedule_delayed_work(&ev->hotplug_work, 0);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002476 }
2477 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002478}
2479
adam radford4bcde502011-07-26 15:42:52 -07002480static int megasas_change_queue_depth(struct scsi_device *sdev,
2481 int queue_depth, int reason)
2482{
2483 if (reason != SCSI_QDEPTH_DEFAULT)
2484 return -EOPNOTSUPP;
2485
2486 if (queue_depth > sdev->host->can_queue)
2487 queue_depth = sdev->host->can_queue;
2488 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
2489 queue_depth);
2490
2491 return queue_depth;
2492}
2493
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002494/*
2495 * Scsi host template for megaraid_sas driver
2496 */
2497static struct scsi_host_template megasas_template = {
2498
2499 .module = THIS_MODULE,
bo yangf28cd7c2007-11-09 04:44:56 -05002500 .name = "LSI SAS based MegaRAID driver",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002501 .proc_name = "megaraid_sas",
Christoph Hellwig147aab62006-02-17 12:13:48 +01002502 .slave_configure = megasas_slave_configure,
Yang, Bo044833b2009-10-06 14:33:06 -06002503 .slave_alloc = megasas_slave_alloc,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002504 .queuecommand = megasas_queue_command,
2505 .eh_device_reset_handler = megasas_reset_device,
2506 .eh_bus_reset_handler = megasas_reset_bus_host,
2507 .eh_host_reset_handler = megasas_reset_bus_host,
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002508 .eh_timed_out = megasas_reset_timer,
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002509 .bios_param = megasas_bios_param,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002510 .use_clustering = ENABLE_CLUSTERING,
adam radford4bcde502011-07-26 15:42:52 -07002511 .change_queue_depth = megasas_change_queue_depth,
Martin K. Petersen54b2b502013-10-23 06:25:40 -04002512 .no_write_same = 1,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002513};
2514
2515/**
2516 * megasas_complete_int_cmd - Completes an internal command
2517 * @instance: Adapter soft state
2518 * @cmd: Command to be completed
2519 *
2520 * The megasas_issue_blocked_cmd() function waits for a command to complete
2521 * after it issues a command. This function wakes up that waiting routine by
2522 * calling wake_up() on the wait queue.
2523 */
2524static void
2525megasas_complete_int_cmd(struct megasas_instance *instance,
2526 struct megasas_cmd *cmd)
2527{
2528 cmd->cmd_status = cmd->frame->io.cmd_status;
2529
2530 if (cmd->cmd_status == ENODATA) {
2531 cmd->cmd_status = 0;
2532 }
2533 wake_up(&instance->int_cmd_wait_q);
2534}
2535
2536/**
2537 * megasas_complete_abort - Completes aborting a command
2538 * @instance: Adapter soft state
2539 * @cmd: Cmd that was issued to abort another cmd
2540 *
adam radford0d490162010-12-14 19:17:17 -08002541 * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
2542 * after it issues an abort on a previously issued command. This function
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002543 * wakes up all functions waiting on the same wait queue.
2544 */
2545static void
2546megasas_complete_abort(struct megasas_instance *instance,
2547 struct megasas_cmd *cmd)
2548{
2549 if (cmd->sync_cmd) {
2550 cmd->sync_cmd = 0;
2551 cmd->cmd_status = 0;
2552 wake_up(&instance->abort_cmd_wait_q);
2553 }
2554
2555 return;
2556}
2557
2558/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002559 * megasas_complete_cmd - Completes a command
2560 * @instance: Adapter soft state
2561 * @cmd: Command to be completed
adam radford0d490162010-12-14 19:17:17 -08002562 * @alt_status: If non-zero, use this value as status to
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002563 * SCSI mid-layer instead of the value returned
2564 * by the FW. This should be used if caller wants
2565 * an alternate status (as in the case of aborted
2566 * commands)
2567 */
adam radford9c915a82010-12-21 13:34:31 -08002568void
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002569megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
2570 u8 alt_status)
2571{
2572 int exception = 0;
2573 struct megasas_header *hdr = &cmd->frame->hdr;
Yang, Boc3518832009-10-06 14:18:02 -06002574 unsigned long flags;
adam radford9c915a82010-12-21 13:34:31 -08002575 struct fusion_context *fusion = instance->ctrl_context;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302576 u32 opcode;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002577
bo yang39a98552010-09-22 22:36:29 -04002578 /* flag for the retry reset */
2579 cmd->retry_for_fw_reset = 0;
2580
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002581 if (cmd->scmd)
2582 cmd->scmd->SCp.ptr = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002583
2584 switch (hdr->cmd) {
adam radforde5f93a32011-10-08 18:15:19 -07002585 case MFI_CMD_INVALID:
2586 /* Some older 1068 controller FW may keep a pended
2587 MR_DCMD_CTRL_EVENT_GET_INFO left over from the main kernel
2588 when booting the kdump kernel. Ignore this command to
2589 prevent a kernel panic on shutdown of the kdump kernel. */
2590 printk(KERN_WARNING "megaraid_sas: MFI_CMD_INVALID command "
2591 "completed.\n");
2592 printk(KERN_WARNING "megaraid_sas: If you have a controller "
2593 "other than PERC5, please upgrade your firmware.\n");
2594 break;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002595 case MFI_CMD_PD_SCSI_IO:
2596 case MFI_CMD_LD_SCSI_IO:
2597
2598 /*
2599 * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been
2600 * issued either through an IO path or an IOCTL path. If it
2601 * was via IOCTL, we will send it to internal completion.
2602 */
2603 if (cmd->sync_cmd) {
2604 cmd->sync_cmd = 0;
2605 megasas_complete_int_cmd(instance, cmd);
2606 break;
2607 }
2608
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002609 case MFI_CMD_LD_READ:
2610 case MFI_CMD_LD_WRITE:
2611
2612 if (alt_status) {
2613 cmd->scmd->result = alt_status << 16;
2614 exception = 1;
2615 }
2616
2617 if (exception) {
2618
Sumant Patroe4a082c2006-05-30 12:03:37 -07002619 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002620
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09002621 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002622 cmd->scmd->scsi_done(cmd->scmd);
2623 megasas_return_cmd(instance, cmd);
2624
2625 break;
2626 }
2627
2628 switch (hdr->cmd_status) {
2629
2630 case MFI_STAT_OK:
2631 cmd->scmd->result = DID_OK << 16;
2632 break;
2633
2634 case MFI_STAT_SCSI_IO_FAILED:
2635 case MFI_STAT_LD_INIT_IN_PROGRESS:
2636 cmd->scmd->result =
2637 (DID_ERROR << 16) | hdr->scsi_status;
2638 break;
2639
2640 case MFI_STAT_SCSI_DONE_WITH_ERROR:
2641
2642 cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status;
2643
2644 if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) {
2645 memset(cmd->scmd->sense_buffer, 0,
2646 SCSI_SENSE_BUFFERSIZE);
2647 memcpy(cmd->scmd->sense_buffer, cmd->sense,
2648 hdr->sense_len);
2649
2650 cmd->scmd->result |= DRIVER_SENSE << 24;
2651 }
2652
2653 break;
2654
2655 case MFI_STAT_LD_OFFLINE:
2656 case MFI_STAT_DEVICE_NOT_FOUND:
2657 cmd->scmd->result = DID_BAD_TARGET << 16;
2658 break;
2659
2660 default:
2661 printk(KERN_DEBUG "megasas: MFI FW status %#x\n",
2662 hdr->cmd_status);
2663 cmd->scmd->result = DID_ERROR << 16;
2664 break;
2665 }
2666
Sumant Patroe4a082c2006-05-30 12:03:37 -07002667 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002668
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09002669 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002670 cmd->scmd->scsi_done(cmd->scmd);
2671 megasas_return_cmd(instance, cmd);
2672
2673 break;
2674
2675 case MFI_CMD_SMP:
2676 case MFI_CMD_STP:
2677 case MFI_CMD_DCMD:
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302678 opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
adam radford9c915a82010-12-21 13:34:31 -08002679 /* Check for LD map update */
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302680 if ((opcode == MR_DCMD_LD_MAP_GET_INFO)
2681 && (cmd->frame->dcmd.mbox.b[1] == 1)) {
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05302682 fusion->fast_path_io = 0;
adam radford9c915a82010-12-21 13:34:31 -08002683 spin_lock_irqsave(instance->host->host_lock, flags);
2684 if (cmd->frame->hdr.cmd_status != 0) {
2685 if (cmd->frame->hdr.cmd_status !=
2686 MFI_STAT_NOT_FOUND)
2687 printk(KERN_WARNING "megasas: map sync"
2688 "failed, status = 0x%x.\n",
2689 cmd->frame->hdr.cmd_status);
2690 else {
2691 megasas_return_cmd(instance, cmd);
2692 spin_unlock_irqrestore(
2693 instance->host->host_lock,
2694 flags);
2695 break;
2696 }
2697 } else
2698 instance->map_id++;
2699 megasas_return_cmd(instance, cmd);
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05302700
2701 /*
2702 * Set fast path IO to ZERO.
2703 * Validate Map will set proper value.
2704 * Meanwhile all IOs will go as LD IO.
2705 */
2706 if (MR_ValidateMapInfo(instance))
adam radford9c915a82010-12-21 13:34:31 -08002707 fusion->fast_path_io = 1;
2708 else
2709 fusion->fast_path_io = 0;
2710 megasas_sync_map_info(instance);
2711 spin_unlock_irqrestore(instance->host->host_lock,
2712 flags);
2713 break;
2714 }
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302715 if (opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
2716 opcode == MR_DCMD_CTRL_EVENT_GET) {
Yang, Boc3518832009-10-06 14:18:02 -06002717 spin_lock_irqsave(&poll_aen_lock, flags);
2718 megasas_poll_wait_aen = 0;
2719 spin_unlock_irqrestore(&poll_aen_lock, flags);
2720 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002721
2722 /*
2723 * See if got an event notification
2724 */
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302725 if (opcode == MR_DCMD_CTRL_EVENT_WAIT)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002726 megasas_service_aen(instance, cmd);
2727 else
2728 megasas_complete_int_cmd(instance, cmd);
2729
2730 break;
2731
2732 case MFI_CMD_ABORT:
2733 /*
2734 * Cmd issued to abort another cmd returned
2735 */
2736 megasas_complete_abort(instance, cmd);
2737 break;
2738
2739 default:
2740 printk("megasas: Unknown command completed! [0x%X]\n",
2741 hdr->cmd);
2742 break;
2743 }
2744}
2745
2746/**
bo yang39a98552010-09-22 22:36:29 -04002747 * megasas_issue_pending_cmds_again - issue all pending cmds
2748 * in FW again because of the fw reset
2749 * @instance: Adapter soft state
2750 */
2751static inline void
2752megasas_issue_pending_cmds_again(struct megasas_instance *instance)
2753{
2754 struct megasas_cmd *cmd;
2755 struct list_head clist_local;
2756 union megasas_evt_class_locale class_locale;
2757 unsigned long flags;
2758 u32 seq_num;
2759
2760 INIT_LIST_HEAD(&clist_local);
2761 spin_lock_irqsave(&instance->hba_lock, flags);
2762 list_splice_init(&instance->internal_reset_pending_q, &clist_local);
2763 spin_unlock_irqrestore(&instance->hba_lock, flags);
2764
2765 while (!list_empty(&clist_local)) {
2766 cmd = list_entry((&clist_local)->next,
2767 struct megasas_cmd, list);
2768 list_del_init(&cmd->list);
2769
2770 if (cmd->sync_cmd || cmd->scmd) {
2771 printk(KERN_NOTICE "megaraid_sas: command %p, %p:%d"
2772 "detected to be pending while HBA reset.\n",
2773 cmd, cmd->scmd, cmd->sync_cmd);
2774
2775 cmd->retry_for_fw_reset++;
2776
2777 if (cmd->retry_for_fw_reset == 3) {
2778 printk(KERN_NOTICE "megaraid_sas: cmd %p, %p:%d"
2779 "was tried multiple times during reset."
2780 "Shutting down the HBA\n",
2781 cmd, cmd->scmd, cmd->sync_cmd);
2782 megaraid_sas_kill_hba(instance);
2783
2784 instance->adprecovery =
2785 MEGASAS_HW_CRITICAL_ERROR;
2786 return;
2787 }
2788 }
2789
2790 if (cmd->sync_cmd == 1) {
2791 if (cmd->scmd) {
2792 printk(KERN_NOTICE "megaraid_sas: unexpected"
2793 "cmd attached to internal command!\n");
2794 }
2795 printk(KERN_NOTICE "megasas: %p synchronous cmd"
2796 "on the internal reset queue,"
2797 "issue it again.\n", cmd);
2798 cmd->cmd_status = ENODATA;
2799 instance->instancet->fire_cmd(instance,
2800 cmd->frame_phys_addr ,
2801 0, instance->reg_set);
2802 } else if (cmd->scmd) {
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002803 printk(KERN_NOTICE "megasas: %p scsi cmd [%02x]"
bo yang39a98552010-09-22 22:36:29 -04002804 "detected on the internal queue, issue again.\n",
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002805 cmd, cmd->scmd->cmnd[0]);
bo yang39a98552010-09-22 22:36:29 -04002806
2807 atomic_inc(&instance->fw_outstanding);
2808 instance->instancet->fire_cmd(instance,
2809 cmd->frame_phys_addr,
2810 cmd->frame_count-1, instance->reg_set);
2811 } else {
2812 printk(KERN_NOTICE "megasas: %p unexpected cmd on the"
2813 "internal reset defer list while re-issue!!\n",
2814 cmd);
2815 }
2816 }
2817
2818 if (instance->aen_cmd) {
2819 printk(KERN_NOTICE "megaraid_sas: aen_cmd in def process\n");
2820 megasas_return_cmd(instance, instance->aen_cmd);
2821
2822 instance->aen_cmd = NULL;
2823 }
2824
2825 /*
2826 * Initiate AEN (Asynchronous Event Notification)
2827 */
2828 seq_num = instance->last_seq_num;
2829 class_locale.members.reserved = 0;
2830 class_locale.members.locale = MR_EVT_LOCALE_ALL;
2831 class_locale.members.class = MR_EVT_CLASS_DEBUG;
2832
2833 megasas_register_aen(instance, seq_num, class_locale.word);
2834}
2835
2836/**
2837 * Move the internal reset pending commands to a deferred queue.
2838 *
2839 * We move the commands pending at internal reset time to a
2840 * pending queue. This queue would be flushed after successful
2841 * completion of the internal reset sequence. if the internal reset
2842 * did not complete in time, the kernel reset handler would flush
2843 * these commands.
2844 **/
2845static void
2846megasas_internal_reset_defer_cmds(struct megasas_instance *instance)
2847{
2848 struct megasas_cmd *cmd;
2849 int i;
2850 u32 max_cmd = instance->max_fw_cmds;
2851 u32 defer_index;
2852 unsigned long flags;
2853
2854 defer_index = 0;
2855 spin_lock_irqsave(&instance->cmd_pool_lock, flags);
2856 for (i = 0; i < max_cmd; i++) {
2857 cmd = instance->cmd_list[i];
2858 if (cmd->sync_cmd == 1 || cmd->scmd) {
2859 printk(KERN_NOTICE "megasas: moving cmd[%d]:%p:%d:%p"
2860 "on the defer queue as internal\n",
2861 defer_index, cmd, cmd->sync_cmd, cmd->scmd);
2862
2863 if (!list_empty(&cmd->list)) {
2864 printk(KERN_NOTICE "megaraid_sas: ERROR while"
2865 " moving this cmd:%p, %d %p, it was"
2866 "discovered on some list?\n",
2867 cmd, cmd->sync_cmd, cmd->scmd);
2868
2869 list_del_init(&cmd->list);
2870 }
2871 defer_index++;
2872 list_add_tail(&cmd->list,
2873 &instance->internal_reset_pending_q);
2874 }
2875 }
2876 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
2877}
2878
2879
2880static void
2881process_fw_state_change_wq(struct work_struct *work)
2882{
2883 struct megasas_instance *instance =
2884 container_of(work, struct megasas_instance, work_init);
2885 u32 wait;
2886 unsigned long flags;
2887
2888 if (instance->adprecovery != MEGASAS_ADPRESET_SM_INFAULT) {
2889 printk(KERN_NOTICE "megaraid_sas: error, recovery st %x \n",
2890 instance->adprecovery);
2891 return ;
2892 }
2893
2894 if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) {
2895 printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault"
2896 "state, restarting it...\n");
2897
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05302898 instance->instancet->disable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04002899 atomic_set(&instance->fw_outstanding, 0);
2900
2901 atomic_set(&instance->fw_reset_no_pci_access, 1);
2902 instance->instancet->adp_reset(instance, instance->reg_set);
2903 atomic_set(&instance->fw_reset_no_pci_access, 0 );
2904
2905 printk(KERN_NOTICE "megaraid_sas: FW restarted successfully,"
2906 "initiating next stage...\n");
2907
2908 printk(KERN_NOTICE "megaraid_sas: HBA recovery state machine,"
2909 "state 2 starting...\n");
2910
2911 /*waitting for about 20 second before start the second init*/
2912 for (wait = 0; wait < 30; wait++) {
2913 msleep(1000);
2914 }
2915
adam radford058a8fa2011-10-08 18:14:27 -07002916 if (megasas_transition_to_ready(instance, 1)) {
bo yang39a98552010-09-22 22:36:29 -04002917 printk(KERN_NOTICE "megaraid_sas:adapter not ready\n");
2918
2919 megaraid_sas_kill_hba(instance);
2920 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2921 return ;
2922 }
2923
2924 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
2925 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
2926 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)
2927 ) {
2928 *instance->consumer = *instance->producer;
2929 } else {
2930 *instance->consumer = 0;
2931 *instance->producer = 0;
2932 }
2933
2934 megasas_issue_init_mfi(instance);
2935
2936 spin_lock_irqsave(&instance->hba_lock, flags);
2937 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
2938 spin_unlock_irqrestore(&instance->hba_lock, flags);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05302939 instance->instancet->enable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04002940
2941 megasas_issue_pending_cmds_again(instance);
2942 instance->issuepend_done = 1;
2943 }
2944 return ;
2945}
2946
2947/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002948 * megasas_deplete_reply_queue - Processes all completed commands
2949 * @instance: Adapter soft state
2950 * @alt_status: Alternate status to be returned to
2951 * SCSI mid-layer instead of the status
2952 * returned by the FW
bo yang39a98552010-09-22 22:36:29 -04002953 * Note: this must be called with hba lock held
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002954 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08002955static int
bo yang39a98552010-09-22 22:36:29 -04002956megasas_deplete_reply_queue(struct megasas_instance *instance,
2957 u8 alt_status)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002958{
bo yang39a98552010-09-22 22:36:29 -04002959 u32 mfiStatus;
2960 u32 fw_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002961
bo yang39a98552010-09-22 22:36:29 -04002962 if ((mfiStatus = instance->instancet->check_reset(instance,
2963 instance->reg_set)) == 1) {
2964 return IRQ_HANDLED;
2965 }
2966
2967 if ((mfiStatus = instance->instancet->clear_intr(
2968 instance->reg_set)
2969 ) == 0) {
adam radforde1419192011-02-24 20:56:21 -08002970 /* Hardware may not set outbound_intr_status in MSI-X mode */
adam radfordc8e858f2011-10-08 18:15:13 -07002971 if (!instance->msix_vectors)
adam radforde1419192011-02-24 20:56:21 -08002972 return IRQ_NONE;
bo yang39a98552010-09-22 22:36:29 -04002973 }
2974
2975 instance->mfiStatus = mfiStatus;
2976
2977 if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) {
2978 fw_state = instance->instancet->read_fw_status_reg(
2979 instance->reg_set) & MFI_STATE_MASK;
2980
2981 if (fw_state != MFI_STATE_FAULT) {
2982 printk(KERN_NOTICE "megaraid_sas: fw state:%x\n",
2983 fw_state);
2984 }
2985
2986 if ((fw_state == MFI_STATE_FAULT) &&
2987 (instance->disableOnlineCtrlReset == 0)) {
2988 printk(KERN_NOTICE "megaraid_sas: wait adp restart\n");
2989
2990 if ((instance->pdev->device ==
2991 PCI_DEVICE_ID_LSI_SAS1064R) ||
2992 (instance->pdev->device ==
2993 PCI_DEVICE_ID_DELL_PERC5) ||
2994 (instance->pdev->device ==
2995 PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
2996
2997 *instance->consumer =
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302998 cpu_to_le32(MEGASAS_ADPRESET_INPROG_SIGN);
bo yang39a98552010-09-22 22:36:29 -04002999 }
3000
3001
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303002 instance->instancet->disable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04003003 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
3004 instance->issuepend_done = 0;
3005
3006 atomic_set(&instance->fw_outstanding, 0);
3007 megasas_internal_reset_defer_cmds(instance);
3008
3009 printk(KERN_NOTICE "megasas: fwState=%x, stage:%d\n",
3010 fw_state, instance->adprecovery);
3011
3012 schedule_work(&instance->work_init);
3013 return IRQ_HANDLED;
3014
3015 } else {
3016 printk(KERN_NOTICE "megasas: fwstate:%x, dis_OCR=%x\n",
3017 fw_state, instance->disableOnlineCtrlReset);
3018 }
3019 }
3020
Sumant Patro5d018ad2006-10-03 13:13:18 -07003021 tasklet_schedule(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003022 return IRQ_HANDLED;
3023}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003024/**
3025 * megasas_isr - isr entry point
3026 */
David Howells7d12e782006-10-05 14:55:46 +01003027static irqreturn_t megasas_isr(int irq, void *devp)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003028{
adam radfordc8e858f2011-10-08 18:15:13 -07003029 struct megasas_irq_context *irq_context = devp;
3030 struct megasas_instance *instance = irq_context->instance;
bo yang39a98552010-09-22 22:36:29 -04003031 unsigned long flags;
3032 irqreturn_t rc;
3033
adam radfordc8e858f2011-10-08 18:15:13 -07003034 if (atomic_read(&instance->fw_reset_no_pci_access))
bo yang39a98552010-09-22 22:36:29 -04003035 return IRQ_HANDLED;
3036
bo yang39a98552010-09-22 22:36:29 -04003037 spin_lock_irqsave(&instance->hba_lock, flags);
3038 rc = megasas_deplete_reply_queue(instance, DID_OK);
3039 spin_unlock_irqrestore(&instance->hba_lock, flags);
3040
3041 return rc;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003042}
3043
3044/**
3045 * megasas_transition_to_ready - Move the FW to READY state
Sumant Patro1341c932006-01-25 12:02:40 -08003046 * @instance: Adapter soft state
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003047 *
3048 * During the initialization, FW passes can potentially be in any one of
3049 * several possible states. If the FW in operational, waiting-for-handshake
3050 * states, driver must take steps to bring it to ready state. Otherwise, it
3051 * has to wait for the ready state.
3052 */
adam radford9c915a82010-12-21 13:34:31 -08003053int
adam radford058a8fa2011-10-08 18:14:27 -07003054megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003055{
3056 int i;
3057 u8 max_wait;
3058 u32 fw_state;
3059 u32 cur_state;
Yang, Bo7218df62009-10-06 14:52:20 -06003060 u32 abs_state, curr_abs_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003061
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02003062 abs_state = instance->instancet->read_fw_status_reg(instance->reg_set);
3063 fw_state = abs_state & MFI_STATE_MASK;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003064
Sumant Patroe3bbff92006-10-03 12:28:49 -07003065 if (fw_state != MFI_STATE_READY)
adam radford0d490162010-12-14 19:17:17 -08003066 printk(KERN_INFO "megasas: Waiting for FW to come to ready"
3067 " state\n");
Sumant Patroe3bbff92006-10-03 12:28:49 -07003068
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003069 while (fw_state != MFI_STATE_READY) {
3070
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003071 switch (fw_state) {
3072
3073 case MFI_STATE_FAULT:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003074 printk(KERN_DEBUG "megasas: FW in FAULT state!!\n");
adam radford058a8fa2011-10-08 18:14:27 -07003075 if (ocr) {
3076 max_wait = MEGASAS_RESET_WAIT_TIME;
3077 cur_state = MFI_STATE_FAULT;
3078 break;
3079 } else
3080 return -ENODEV;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003081
3082 case MFI_STATE_WAIT_HANDSHAKE:
3083 /*
3084 * Set the CLR bit in inbound doorbell
3085 */
Yang, Bo0c79e682009-10-06 14:47:35 -06003086 if ((instance->pdev->device ==
Yang, Bo87911122009-10-06 14:31:54 -06003087 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3088 (instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003089 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
3090 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303091 PCI_DEVICE_ID_LSI_FUSION) ||
adam radford36807e62011-10-08 18:15:06 -07003092 (instance->pdev->device ==
adam radford229fe472014-03-10 02:51:56 -07003093 PCI_DEVICE_ID_LSI_PLASMA) ||
3094 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303095 PCI_DEVICE_ID_LSI_INVADER) ||
3096 (instance->pdev->device ==
3097 PCI_DEVICE_ID_LSI_FURY)) {
Yang, Bo87911122009-10-06 14:31:54 -06003098 writel(
3099 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
adam radford9c915a82010-12-21 13:34:31 -08003100 &instance->reg_set->doorbell);
Yang, Bo87911122009-10-06 14:31:54 -06003101 } else {
3102 writel(
3103 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
3104 &instance->reg_set->inbound_doorbell);
3105 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003106
Yang, Bo7218df62009-10-06 14:52:20 -06003107 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003108 cur_state = MFI_STATE_WAIT_HANDSHAKE;
3109 break;
3110
Sumant Patroe3bbff92006-10-03 12:28:49 -07003111 case MFI_STATE_BOOT_MESSAGE_PENDING:
Yang, Bo87911122009-10-06 14:31:54 -06003112 if ((instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003113 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3114 (instance->pdev->device ==
3115 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
3116 (instance->pdev->device ==
adam radford36807e62011-10-08 18:15:06 -07003117 PCI_DEVICE_ID_LSI_FUSION) ||
3118 (instance->pdev->device ==
adam radford229fe472014-03-10 02:51:56 -07003119 PCI_DEVICE_ID_LSI_PLASMA) ||
3120 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303121 PCI_DEVICE_ID_LSI_INVADER) ||
3122 (instance->pdev->device ==
3123 PCI_DEVICE_ID_LSI_FURY)) {
Yang, Bo87911122009-10-06 14:31:54 -06003124 writel(MFI_INIT_HOTPLUG,
adam radford9c915a82010-12-21 13:34:31 -08003125 &instance->reg_set->doorbell);
Yang, Bo87911122009-10-06 14:31:54 -06003126 } else
3127 writel(MFI_INIT_HOTPLUG,
3128 &instance->reg_set->inbound_doorbell);
Sumant Patroe3bbff92006-10-03 12:28:49 -07003129
Yang, Bo7218df62009-10-06 14:52:20 -06003130 max_wait = MEGASAS_RESET_WAIT_TIME;
Sumant Patroe3bbff92006-10-03 12:28:49 -07003131 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
3132 break;
3133
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003134 case MFI_STATE_OPERATIONAL:
3135 /*
Sumant Patroe3bbff92006-10-03 12:28:49 -07003136 * Bring it to READY state; assuming max wait 10 secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003137 */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303138 instance->instancet->disable_intr(instance);
Yang, Bo87911122009-10-06 14:31:54 -06003139 if ((instance->pdev->device ==
3140 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3141 (instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003142 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
3143 (instance->pdev->device
adam radford36807e62011-10-08 18:15:06 -07003144 == PCI_DEVICE_ID_LSI_FUSION) ||
3145 (instance->pdev->device
adam radford229fe472014-03-10 02:51:56 -07003146 == PCI_DEVICE_ID_LSI_PLASMA) ||
3147 (instance->pdev->device
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303148 == PCI_DEVICE_ID_LSI_INVADER) ||
3149 (instance->pdev->device
3150 == PCI_DEVICE_ID_LSI_FURY)) {
Yang, Bo87911122009-10-06 14:31:54 -06003151 writel(MFI_RESET_FLAGS,
adam radford9c915a82010-12-21 13:34:31 -08003152 &instance->reg_set->doorbell);
adam radford36807e62011-10-08 18:15:06 -07003153 if ((instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303154 PCI_DEVICE_ID_LSI_FUSION) ||
3155 (instance->pdev->device ==
adam radford229fe472014-03-10 02:51:56 -07003156 PCI_DEVICE_ID_LSI_PLASMA) ||
3157 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303158 PCI_DEVICE_ID_LSI_INVADER) ||
3159 (instance->pdev->device ==
3160 PCI_DEVICE_ID_LSI_FURY)) {
adam radford9c915a82010-12-21 13:34:31 -08003161 for (i = 0; i < (10 * 1000); i += 20) {
3162 if (readl(
3163 &instance->
3164 reg_set->
3165 doorbell) & 1)
3166 msleep(20);
3167 else
3168 break;
3169 }
3170 }
Yang, Bo87911122009-10-06 14:31:54 -06003171 } else
3172 writel(MFI_RESET_FLAGS,
3173 &instance->reg_set->inbound_doorbell);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003174
Yang, Bo7218df62009-10-06 14:52:20 -06003175 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003176 cur_state = MFI_STATE_OPERATIONAL;
3177 break;
3178
3179 case MFI_STATE_UNDEFINED:
3180 /*
3181 * This state should not last for more than 2 seconds
3182 */
Yang, Bo7218df62009-10-06 14:52:20 -06003183 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003184 cur_state = MFI_STATE_UNDEFINED;
3185 break;
3186
3187 case MFI_STATE_BB_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06003188 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003189 cur_state = MFI_STATE_BB_INIT;
3190 break;
3191
3192 case MFI_STATE_FW_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06003193 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003194 cur_state = MFI_STATE_FW_INIT;
3195 break;
3196
3197 case MFI_STATE_FW_INIT_2:
Yang, Bo7218df62009-10-06 14:52:20 -06003198 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003199 cur_state = MFI_STATE_FW_INIT_2;
3200 break;
3201
3202 case MFI_STATE_DEVICE_SCAN:
Yang, Bo7218df62009-10-06 14:52:20 -06003203 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003204 cur_state = MFI_STATE_DEVICE_SCAN;
3205 break;
3206
3207 case MFI_STATE_FLUSH_CACHE:
Yang, Bo7218df62009-10-06 14:52:20 -06003208 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003209 cur_state = MFI_STATE_FLUSH_CACHE;
3210 break;
3211
3212 default:
3213 printk(KERN_DEBUG "megasas: Unknown state 0x%x\n",
3214 fw_state);
3215 return -ENODEV;
3216 }
3217
3218 /*
3219 * The cur_state should not last for more than max_wait secs
3220 */
3221 for (i = 0; i < (max_wait * 1000); i++) {
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02003222 curr_abs_state = instance->instancet->
3223 read_fw_status_reg(instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003224
Yang, Bo7218df62009-10-06 14:52:20 -06003225 if (abs_state == curr_abs_state) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003226 msleep(1);
3227 } else
3228 break;
3229 }
3230
3231 /*
3232 * Return error if fw_state hasn't changed after max_wait
3233 */
Yang, Bo7218df62009-10-06 14:52:20 -06003234 if (curr_abs_state == abs_state) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003235 printk(KERN_DEBUG "FW state [%d] hasn't changed "
3236 "in %d secs\n", fw_state, max_wait);
3237 return -ENODEV;
3238 }
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02003239
3240 abs_state = curr_abs_state;
3241 fw_state = curr_abs_state & MFI_STATE_MASK;
bo yang39a98552010-09-22 22:36:29 -04003242 }
adam radford0d490162010-12-14 19:17:17 -08003243 printk(KERN_INFO "megasas: FW now in Ready state\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003244
3245 return 0;
3246}
3247
3248/**
3249 * megasas_teardown_frame_pool - Destroy the cmd frame DMA pool
3250 * @instance: Adapter soft state
3251 */
3252static void megasas_teardown_frame_pool(struct megasas_instance *instance)
3253{
3254 int i;
adam radford9c915a82010-12-21 13:34:31 -08003255 u32 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003256 struct megasas_cmd *cmd;
3257
3258 if (!instance->frame_dma_pool)
3259 return;
3260
3261 /*
3262 * Return all frames to pool
3263 */
3264 for (i = 0; i < max_cmd; i++) {
3265
3266 cmd = instance->cmd_list[i];
3267
3268 if (cmd->frame)
3269 pci_pool_free(instance->frame_dma_pool, cmd->frame,
3270 cmd->frame_phys_addr);
3271
3272 if (cmd->sense)
Sumant Patroe3bbff92006-10-03 12:28:49 -07003273 pci_pool_free(instance->sense_dma_pool, cmd->sense,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003274 cmd->sense_phys_addr);
3275 }
3276
3277 /*
3278 * Now destroy the pool itself
3279 */
3280 pci_pool_destroy(instance->frame_dma_pool);
3281 pci_pool_destroy(instance->sense_dma_pool);
3282
3283 instance->frame_dma_pool = NULL;
3284 instance->sense_dma_pool = NULL;
3285}
3286
3287/**
3288 * megasas_create_frame_pool - Creates DMA pool for cmd frames
3289 * @instance: Adapter soft state
3290 *
3291 * Each command packet has an embedded DMA memory buffer that is used for
3292 * filling MFI frame and the SG list that immediately follows the frame. This
3293 * function creates those DMA memory buffers for each command packet by using
3294 * PCI pool facility.
3295 */
3296static int megasas_create_frame_pool(struct megasas_instance *instance)
3297{
3298 int i;
3299 u32 max_cmd;
3300 u32 sge_sz;
3301 u32 sgl_sz;
3302 u32 total_sz;
3303 u32 frame_count;
3304 struct megasas_cmd *cmd;
3305
adam radford9c915a82010-12-21 13:34:31 -08003306 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003307
3308 /*
3309 * Size of our frame is 64 bytes for MFI frame, followed by max SG
3310 * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer
3311 */
3312 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
3313 sizeof(struct megasas_sge32);
3314
Yang, Bof4c9a132009-10-06 14:43:28 -06003315 if (instance->flag_ieee) {
3316 sge_sz = sizeof(struct megasas_sge_skinny);
3317 }
3318
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003319 /*
3320 * Calculated the number of 64byte frames required for SGL
3321 */
3322 sgl_sz = sge_sz * instance->max_num_sge;
3323 frame_count = (sgl_sz + MEGAMFI_FRAME_SIZE - 1) / MEGAMFI_FRAME_SIZE;
bo yang39a98552010-09-22 22:36:29 -04003324 frame_count = 15;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003325
3326 /*
3327 * We need one extra frame for the MFI command
3328 */
3329 frame_count++;
3330
3331 total_sz = MEGAMFI_FRAME_SIZE * frame_count;
3332 /*
3333 * Use DMA pool facility provided by PCI layer
3334 */
3335 instance->frame_dma_pool = pci_pool_create("megasas frame pool",
3336 instance->pdev, total_sz, 64,
3337 0);
3338
3339 if (!instance->frame_dma_pool) {
3340 printk(KERN_DEBUG "megasas: failed to setup frame pool\n");
3341 return -ENOMEM;
3342 }
3343
3344 instance->sense_dma_pool = pci_pool_create("megasas sense pool",
3345 instance->pdev, 128, 4, 0);
3346
3347 if (!instance->sense_dma_pool) {
3348 printk(KERN_DEBUG "megasas: failed to setup sense pool\n");
3349
3350 pci_pool_destroy(instance->frame_dma_pool);
3351 instance->frame_dma_pool = NULL;
3352
3353 return -ENOMEM;
3354 }
3355
3356 /*
3357 * Allocate and attach a frame to each of the commands in cmd_list.
3358 * By making cmd->index as the context instead of the &cmd, we can
3359 * always use 32bit context regardless of the architecture
3360 */
3361 for (i = 0; i < max_cmd; i++) {
3362
3363 cmd = instance->cmd_list[i];
3364
3365 cmd->frame = pci_pool_alloc(instance->frame_dma_pool,
3366 GFP_KERNEL, &cmd->frame_phys_addr);
3367
3368 cmd->sense = pci_pool_alloc(instance->sense_dma_pool,
3369 GFP_KERNEL, &cmd->sense_phys_addr);
3370
3371 /*
3372 * megasas_teardown_frame_pool() takes care of freeing
3373 * whatever has been allocated
3374 */
3375 if (!cmd->frame || !cmd->sense) {
3376 printk(KERN_DEBUG "megasas: pci_pool_alloc failed \n");
3377 megasas_teardown_frame_pool(instance);
3378 return -ENOMEM;
3379 }
3380
Yang, Bo707e09b2010-10-12 07:20:27 -06003381 memset(cmd->frame, 0, total_sz);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303382 cmd->frame->io.context = cpu_to_le32(cmd->index);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06003383 cmd->frame->io.pad_0 = 0;
adam radforde5f93a32011-10-08 18:15:19 -07003384 if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
adam radford229fe472014-03-10 02:51:56 -07003385 (instance->pdev->device != PCI_DEVICE_ID_LSI_PLASMA) &&
adam radforde5f93a32011-10-08 18:15:19 -07003386 (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303387 (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
adam radforde5f93a32011-10-08 18:15:19 -07003388 (reset_devices))
3389 cmd->frame->hdr.cmd = MFI_CMD_INVALID;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003390 }
3391
3392 return 0;
3393}
3394
3395/**
3396 * megasas_free_cmds - Free all the cmds in the free cmd pool
3397 * @instance: Adapter soft state
3398 */
adam radford9c915a82010-12-21 13:34:31 -08003399void megasas_free_cmds(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003400{
3401 int i;
3402 /* First free the MFI frame pool */
3403 megasas_teardown_frame_pool(instance);
3404
3405 /* Free all the commands in the cmd_list */
adam radford9c915a82010-12-21 13:34:31 -08003406 for (i = 0; i < instance->max_mfi_cmds; i++)
3407
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003408 kfree(instance->cmd_list[i]);
3409
3410 /* Free the cmd_list buffer itself */
3411 kfree(instance->cmd_list);
3412 instance->cmd_list = NULL;
3413
3414 INIT_LIST_HEAD(&instance->cmd_pool);
3415}
3416
3417/**
3418 * megasas_alloc_cmds - Allocates the command packets
3419 * @instance: Adapter soft state
3420 *
3421 * Each command that is issued to the FW, whether IO commands from the OS or
3422 * internal commands like IOCTLs, are wrapped in local data structure called
3423 * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to
3424 * the FW.
3425 *
3426 * Each frame has a 32-bit field called context (tag). This context is used
3427 * to get back the megasas_cmd from the frame when a frame gets completed in
3428 * the ISR. Typically the address of the megasas_cmd itself would be used as
3429 * the context. But we wanted to keep the differences between 32 and 64 bit
3430 * systems to the mininum. We always use 32 bit integers for the context. In
3431 * this driver, the 32 bit values are the indices into an array cmd_list.
3432 * This array is used only to look up the megasas_cmd given the context. The
3433 * free commands themselves are maintained in a linked list called cmd_pool.
3434 */
adam radford9c915a82010-12-21 13:34:31 -08003435int megasas_alloc_cmds(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003436{
3437 int i;
3438 int j;
3439 u32 max_cmd;
3440 struct megasas_cmd *cmd;
3441
adam radford9c915a82010-12-21 13:34:31 -08003442 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003443
3444 /*
3445 * instance->cmd_list is an array of struct megasas_cmd pointers.
3446 * Allocate the dynamic array first and then allocate individual
3447 * commands.
3448 */
Yoann Padioleaudd00cc42007-07-19 01:49:03 -07003449 instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003450
3451 if (!instance->cmd_list) {
3452 printk(KERN_DEBUG "megasas: out of memory\n");
3453 return -ENOMEM;
3454 }
3455
adam radford9c915a82010-12-21 13:34:31 -08003456 memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) *max_cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003457
3458 for (i = 0; i < max_cmd; i++) {
3459 instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd),
3460 GFP_KERNEL);
3461
3462 if (!instance->cmd_list[i]) {
3463
3464 for (j = 0; j < i; j++)
3465 kfree(instance->cmd_list[j]);
3466
3467 kfree(instance->cmd_list);
3468 instance->cmd_list = NULL;
3469
3470 return -ENOMEM;
3471 }
3472 }
3473
3474 /*
3475 * Add all the commands to command pool (instance->cmd_pool)
3476 */
3477 for (i = 0; i < max_cmd; i++) {
3478 cmd = instance->cmd_list[i];
3479 memset(cmd, 0, sizeof(struct megasas_cmd));
3480 cmd->index = i;
bo yang39a98552010-09-22 22:36:29 -04003481 cmd->scmd = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003482 cmd->instance = instance;
3483
3484 list_add_tail(&cmd->list, &instance->cmd_pool);
3485 }
3486
3487 /*
3488 * Create a frame pool and assign one frame to each cmd
3489 */
3490 if (megasas_create_frame_pool(instance)) {
3491 printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n");
3492 megasas_free_cmds(instance);
3493 }
3494
3495 return 0;
3496}
3497
Yang, Bo81e403c2009-10-06 14:27:54 -06003498/*
3499 * megasas_get_pd_list_info - Returns FW's pd_list structure
3500 * @instance: Adapter soft state
3501 * @pd_list: pd_list structure
3502 *
3503 * Issues an internal command (DCMD) to get the FW's controller PD
3504 * list structure. This information is mainly used to find out SYSTEM
3505 * supported by the FW.
3506 */
3507static int
3508megasas_get_pd_list(struct megasas_instance *instance)
3509{
3510 int ret = 0, pd_index = 0;
3511 struct megasas_cmd *cmd;
3512 struct megasas_dcmd_frame *dcmd;
3513 struct MR_PD_LIST *ci;
3514 struct MR_PD_ADDRESS *pd_addr;
3515 dma_addr_t ci_h = 0;
3516
3517 cmd = megasas_get_cmd(instance);
3518
3519 if (!cmd) {
3520 printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
3521 return -ENOMEM;
3522 }
3523
3524 dcmd = &cmd->frame->dcmd;
3525
3526 ci = pci_alloc_consistent(instance->pdev,
3527 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
3528
3529 if (!ci) {
3530 printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
3531 megasas_return_cmd(instance, cmd);
3532 return -ENOMEM;
3533 }
3534
3535 memset(ci, 0, sizeof(*ci));
3536 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3537
3538 dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
3539 dcmd->mbox.b[1] = 0;
3540 dcmd->cmd = MFI_CMD_DCMD;
3541 dcmd->cmd_status = 0xFF;
3542 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303543 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
Yang, Bo81e403c2009-10-06 14:27:54 -06003544 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003545 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303546 dcmd->data_xfer_len = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST));
3547 dcmd->opcode = cpu_to_le32(MR_DCMD_PD_LIST_QUERY);
3548 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
3549 dcmd->sgl.sge32[0].length = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST));
Yang, Bo81e403c2009-10-06 14:27:54 -06003550
3551 if (!megasas_issue_polled(instance, cmd)) {
3552 ret = 0;
3553 } else {
3554 ret = -1;
3555 }
3556
3557 /*
3558 * the following function will get the instance PD LIST.
3559 */
3560
3561 pd_addr = ci->addr;
3562
3563 if ( ret == 0 &&
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303564 (le32_to_cpu(ci->count) <
Yang, Bo81e403c2009-10-06 14:27:54 -06003565 (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
3566
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05303567 memset(instance->local_pd_list, 0,
Yang, Bo81e403c2009-10-06 14:27:54 -06003568 MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
3569
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303570 for (pd_index = 0; pd_index < le32_to_cpu(ci->count); pd_index++) {
Yang, Bo81e403c2009-10-06 14:27:54 -06003571
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05303572 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].tid =
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303573 le16_to_cpu(pd_addr->deviceId);
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05303574 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveType =
Yang, Bo81e403c2009-10-06 14:27:54 -06003575 pd_addr->scsiDevType;
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05303576 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveState =
Yang, Bo81e403c2009-10-06 14:27:54 -06003577 MR_PD_STATE_SYSTEM;
3578 pd_addr++;
3579 }
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05303580 memcpy(instance->pd_list, instance->local_pd_list,
3581 sizeof(instance->pd_list));
Yang, Bo81e403c2009-10-06 14:27:54 -06003582 }
3583
3584 pci_free_consistent(instance->pdev,
3585 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
3586 ci, ci_h);
3587 megasas_return_cmd(instance, cmd);
3588
3589 return ret;
3590}
3591
Yang, Bobdc6fb82009-12-06 08:30:19 -07003592/*
3593 * megasas_get_ld_list_info - Returns FW's ld_list structure
3594 * @instance: Adapter soft state
3595 * @ld_list: ld_list structure
3596 *
3597 * Issues an internal command (DCMD) to get the FW's controller PD
3598 * list structure. This information is mainly used to find out SYSTEM
3599 * supported by the FW.
3600 */
3601static int
3602megasas_get_ld_list(struct megasas_instance *instance)
3603{
3604 int ret = 0, ld_index = 0, ids = 0;
3605 struct megasas_cmd *cmd;
3606 struct megasas_dcmd_frame *dcmd;
3607 struct MR_LD_LIST *ci;
3608 dma_addr_t ci_h = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303609 u32 ld_count;
Yang, Bobdc6fb82009-12-06 08:30:19 -07003610
3611 cmd = megasas_get_cmd(instance);
3612
3613 if (!cmd) {
3614 printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n");
3615 return -ENOMEM;
3616 }
3617
3618 dcmd = &cmd->frame->dcmd;
3619
3620 ci = pci_alloc_consistent(instance->pdev,
3621 sizeof(struct MR_LD_LIST),
3622 &ci_h);
3623
3624 if (!ci) {
3625 printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n");
3626 megasas_return_cmd(instance, cmd);
3627 return -ENOMEM;
3628 }
3629
3630 memset(ci, 0, sizeof(*ci));
3631 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3632
3633 dcmd->cmd = MFI_CMD_DCMD;
3634 dcmd->cmd_status = 0xFF;
3635 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303636 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
Yang, Bobdc6fb82009-12-06 08:30:19 -07003637 dcmd->timeout = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303638 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_LIST));
3639 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_GET_LIST);
3640 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
3641 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_LD_LIST));
Yang, Bobdc6fb82009-12-06 08:30:19 -07003642 dcmd->pad_0 = 0;
3643
3644 if (!megasas_issue_polled(instance, cmd)) {
3645 ret = 0;
3646 } else {
3647 ret = -1;
3648 }
3649
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303650 ld_count = le32_to_cpu(ci->ldCount);
3651
Yang, Bobdc6fb82009-12-06 08:30:19 -07003652 /* the following function will get the instance PD LIST */
3653
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303654 if ((ret == 0) && (ld_count <= MAX_LOGICAL_DRIVES)) {
Yang, Bobdc6fb82009-12-06 08:30:19 -07003655 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
3656
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303657 for (ld_index = 0; ld_index < ld_count; ld_index++) {
Yang, Bobdc6fb82009-12-06 08:30:19 -07003658 if (ci->ldList[ld_index].state != 0) {
3659 ids = ci->ldList[ld_index].ref.targetId;
3660 instance->ld_ids[ids] =
3661 ci->ldList[ld_index].ref.targetId;
3662 }
3663 }
3664 }
3665
3666 pci_free_consistent(instance->pdev,
3667 sizeof(struct MR_LD_LIST),
3668 ci,
3669 ci_h);
3670
3671 megasas_return_cmd(instance, cmd);
3672 return ret;
3673}
3674
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003675/**
adam radford21c9e162013-09-06 15:27:14 -07003676 * megasas_ld_list_query - Returns FW's ld_list structure
3677 * @instance: Adapter soft state
3678 * @ld_list: ld_list structure
3679 *
3680 * Issues an internal command (DCMD) to get the FW's controller PD
3681 * list structure. This information is mainly used to find out SYSTEM
3682 * supported by the FW.
3683 */
3684static int
3685megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
3686{
3687 int ret = 0, ld_index = 0, ids = 0;
3688 struct megasas_cmd *cmd;
3689 struct megasas_dcmd_frame *dcmd;
3690 struct MR_LD_TARGETID_LIST *ci;
3691 dma_addr_t ci_h = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303692 u32 tgtid_count;
adam radford21c9e162013-09-06 15:27:14 -07003693
3694 cmd = megasas_get_cmd(instance);
3695
3696 if (!cmd) {
3697 printk(KERN_WARNING
3698 "megasas:(megasas_ld_list_query): Failed to get cmd\n");
3699 return -ENOMEM;
3700 }
3701
3702 dcmd = &cmd->frame->dcmd;
3703
3704 ci = pci_alloc_consistent(instance->pdev,
3705 sizeof(struct MR_LD_TARGETID_LIST), &ci_h);
3706
3707 if (!ci) {
3708 printk(KERN_WARNING
3709 "megasas: Failed to alloc mem for ld_list_query\n");
3710 megasas_return_cmd(instance, cmd);
3711 return -ENOMEM;
3712 }
3713
3714 memset(ci, 0, sizeof(*ci));
3715 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3716
3717 dcmd->mbox.b[0] = query_type;
3718
3719 dcmd->cmd = MFI_CMD_DCMD;
3720 dcmd->cmd_status = 0xFF;
3721 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303722 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
adam radford21c9e162013-09-06 15:27:14 -07003723 dcmd->timeout = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303724 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST));
3725 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_LIST_QUERY);
3726 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
3727 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST));
adam radford21c9e162013-09-06 15:27:14 -07003728 dcmd->pad_0 = 0;
3729
3730 if (!megasas_issue_polled(instance, cmd) && !dcmd->cmd_status) {
3731 ret = 0;
3732 } else {
3733 /* On failure, call older LD list DCMD */
3734 ret = 1;
3735 }
3736
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303737 tgtid_count = le32_to_cpu(ci->count);
3738
3739 if ((ret == 0) && (tgtid_count <= (MAX_LOGICAL_DRIVES))) {
adam radford21c9e162013-09-06 15:27:14 -07003740 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303741 for (ld_index = 0; ld_index < tgtid_count; ld_index++) {
adam radford21c9e162013-09-06 15:27:14 -07003742 ids = ci->targetId[ld_index];
3743 instance->ld_ids[ids] = ci->targetId[ld_index];
3744 }
3745
3746 }
3747
3748 pci_free_consistent(instance->pdev, sizeof(struct MR_LD_TARGETID_LIST),
3749 ci, ci_h);
3750
3751 megasas_return_cmd(instance, cmd);
3752
3753 return ret;
3754}
3755
3756/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003757 * megasas_get_controller_info - Returns FW's controller structure
3758 * @instance: Adapter soft state
3759 * @ctrl_info: Controller information structure
3760 *
3761 * Issues an internal command (DCMD) to get the FW's controller structure.
3762 * This information is mainly used to find out the maximum IO transfer per
3763 * command supported by the FW.
3764 */
3765static int
3766megasas_get_ctrl_info(struct megasas_instance *instance,
3767 struct megasas_ctrl_info *ctrl_info)
3768{
3769 int ret = 0;
3770 struct megasas_cmd *cmd;
3771 struct megasas_dcmd_frame *dcmd;
3772 struct megasas_ctrl_info *ci;
3773 dma_addr_t ci_h = 0;
3774
3775 cmd = megasas_get_cmd(instance);
3776
3777 if (!cmd) {
3778 printk(KERN_DEBUG "megasas: Failed to get a free cmd\n");
3779 return -ENOMEM;
3780 }
3781
3782 dcmd = &cmd->frame->dcmd;
3783
3784 ci = pci_alloc_consistent(instance->pdev,
3785 sizeof(struct megasas_ctrl_info), &ci_h);
3786
3787 if (!ci) {
3788 printk(KERN_DEBUG "Failed to alloc mem for ctrl info\n");
3789 megasas_return_cmd(instance, cmd);
3790 return -ENOMEM;
3791 }
3792
3793 memset(ci, 0, sizeof(*ci));
3794 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3795
3796 dcmd->cmd = MFI_CMD_DCMD;
3797 dcmd->cmd_status = 0xFF;
3798 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303799 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003800 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003801 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303802 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_ctrl_info));
3803 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_GET_INFO);
3804 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
3805 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_ctrl_info));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003806
3807 if (!megasas_issue_polled(instance, cmd)) {
3808 ret = 0;
3809 memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info));
3810 } else {
3811 ret = -1;
3812 }
3813
3814 pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
3815 ci, ci_h);
3816
3817 megasas_return_cmd(instance, cmd);
3818 return ret;
3819}
3820
3821/**
bo yang31ea7082007-11-07 12:09:50 -05003822 * megasas_issue_init_mfi - Initializes the FW
3823 * @instance: Adapter soft state
3824 *
3825 * Issues the INIT MFI cmd
3826 */
3827static int
3828megasas_issue_init_mfi(struct megasas_instance *instance)
3829{
3830 u32 context;
3831
3832 struct megasas_cmd *cmd;
3833
3834 struct megasas_init_frame *init_frame;
3835 struct megasas_init_queue_info *initq_info;
3836 dma_addr_t init_frame_h;
3837 dma_addr_t initq_info_h;
3838
3839 /*
3840 * Prepare a init frame. Note the init frame points to queue info
3841 * structure. Each frame has SGL allocated after first 64 bytes. For
3842 * this frame - since we don't need any SGL - we use SGL's space as
3843 * queue info structure
3844 *
3845 * We will not get a NULL command below. We just created the pool.
3846 */
3847 cmd = megasas_get_cmd(instance);
3848
3849 init_frame = (struct megasas_init_frame *)cmd->frame;
3850 initq_info = (struct megasas_init_queue_info *)
3851 ((unsigned long)init_frame + 64);
3852
3853 init_frame_h = cmd->frame_phys_addr;
3854 initq_info_h = init_frame_h + 64;
3855
3856 context = init_frame->context;
3857 memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
3858 memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
3859 init_frame->context = context;
3860
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303861 initq_info->reply_queue_entries = cpu_to_le32(instance->max_fw_cmds + 1);
3862 initq_info->reply_queue_start_phys_addr_lo = cpu_to_le32(instance->reply_queue_h);
bo yang31ea7082007-11-07 12:09:50 -05003863
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303864 initq_info->producer_index_phys_addr_lo = cpu_to_le32(instance->producer_h);
3865 initq_info->consumer_index_phys_addr_lo = cpu_to_le32(instance->consumer_h);
bo yang31ea7082007-11-07 12:09:50 -05003866
3867 init_frame->cmd = MFI_CMD_INIT;
3868 init_frame->cmd_status = 0xFF;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303869 init_frame->queue_info_new_phys_addr_lo =
3870 cpu_to_le32(lower_32_bits(initq_info_h));
3871 init_frame->queue_info_new_phys_addr_hi =
3872 cpu_to_le32(upper_32_bits(initq_info_h));
bo yang31ea7082007-11-07 12:09:50 -05003873
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303874 init_frame->data_xfer_len = cpu_to_le32(sizeof(struct megasas_init_queue_info));
bo yang31ea7082007-11-07 12:09:50 -05003875
3876 /*
3877 * disable the intr before firing the init frame to FW
3878 */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303879 instance->instancet->disable_intr(instance);
bo yang31ea7082007-11-07 12:09:50 -05003880
3881 /*
3882 * Issue the init frame in polled mode
3883 */
3884
3885 if (megasas_issue_polled(instance, cmd)) {
3886 printk(KERN_ERR "megasas: Failed to init firmware\n");
3887 megasas_return_cmd(instance, cmd);
3888 goto fail_fw_init;
3889 }
3890
3891 megasas_return_cmd(instance, cmd);
3892
3893 return 0;
3894
3895fail_fw_init:
3896 return -EINVAL;
3897}
3898
adam radfordcd50ba82010-12-21 10:23:23 -08003899static u32
3900megasas_init_adapter_mfi(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003901{
adam radfordcd50ba82010-12-21 10:23:23 -08003902 struct megasas_register_set __iomem *reg_set;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003903 u32 context_sz;
3904 u32 reply_q_sz;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003905
3906 reg_set = instance->reg_set;
3907
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003908 /*
3909 * Get various operational parameters from status register
3910 */
Sumant Patro1341c932006-01-25 12:02:40 -08003911 instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
Sumant Patroe3bbff92006-10-03 12:28:49 -07003912 /*
3913 * Reduce the max supported cmds by 1. This is to ensure that the
3914 * reply_q_sz (1 more than the max cmd that driver may send)
3915 * does not exceed max cmds that the FW can support
3916 */
3917 instance->max_fw_cmds = instance->max_fw_cmds-1;
adam radford9c915a82010-12-21 13:34:31 -08003918 instance->max_mfi_cmds = instance->max_fw_cmds;
adam radford0d490162010-12-14 19:17:17 -08003919 instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
Sumant Patro1341c932006-01-25 12:02:40 -08003920 0x10;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003921 /*
3922 * Create a pool of commands
3923 */
3924 if (megasas_alloc_cmds(instance))
3925 goto fail_alloc_cmds;
3926
3927 /*
3928 * Allocate memory for reply queue. Length of reply queue should
3929 * be _one_ more than the maximum commands handled by the firmware.
3930 *
3931 * Note: When FW completes commands, it places corresponding contex
3932 * values in this circular reply queue. This circular queue is a fairly
3933 * typical producer-consumer queue. FW is the producer (of completed
3934 * commands) and the driver is the consumer.
3935 */
3936 context_sz = sizeof(u32);
3937 reply_q_sz = context_sz * (instance->max_fw_cmds + 1);
3938
3939 instance->reply_queue = pci_alloc_consistent(instance->pdev,
3940 reply_q_sz,
3941 &instance->reply_queue_h);
3942
3943 if (!instance->reply_queue) {
3944 printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n");
3945 goto fail_reply_queue;
3946 }
3947
bo yang31ea7082007-11-07 12:09:50 -05003948 if (megasas_issue_init_mfi(instance))
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003949 goto fail_fw_init;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003950
bo yang39a98552010-09-22 22:36:29 -04003951 instance->fw_support_ieee = 0;
3952 instance->fw_support_ieee =
3953 (instance->instancet->read_fw_status_reg(reg_set) &
3954 0x04000000);
3955
3956 printk(KERN_NOTICE "megasas_init_mfi: fw_support_ieee=%d",
3957 instance->fw_support_ieee);
3958
3959 if (instance->fw_support_ieee)
3960 instance->flag_ieee = 1;
3961
adam radfordcd50ba82010-12-21 10:23:23 -08003962 return 0;
3963
3964fail_fw_init:
3965
3966 pci_free_consistent(instance->pdev, reply_q_sz,
3967 instance->reply_queue, instance->reply_queue_h);
3968fail_reply_queue:
3969 megasas_free_cmds(instance);
3970
3971fail_alloc_cmds:
adam radfordcd50ba82010-12-21 10:23:23 -08003972 return 1;
3973}
3974
3975/**
3976 * megasas_init_fw - Initializes the FW
3977 * @instance: Adapter soft state
3978 *
3979 * This is the main function for initializing firmware
3980 */
3981
3982static int megasas_init_fw(struct megasas_instance *instance)
3983{
3984 u32 max_sectors_1;
3985 u32 max_sectors_2;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303986 u32 tmp_sectors, msix_enable, scratch_pad_2;
Ben Collins11f8a7b2013-09-13 12:46:44 -04003987 resource_size_t base_addr;
adam radfordcd50ba82010-12-21 10:23:23 -08003988 struct megasas_register_set __iomem *reg_set;
3989 struct megasas_ctrl_info *ctrl_info;
3990 unsigned long bar_list;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303991 int i, loop, fw_msix_count = 0;
adam radford229fe472014-03-10 02:51:56 -07003992 struct IOV_111 *iovPtr;
adam radfordcd50ba82010-12-21 10:23:23 -08003993
3994 /* Find first memory bar */
3995 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
3996 instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
adam radfordcd50ba82010-12-21 10:23:23 -08003997 if (pci_request_selected_regions(instance->pdev, instance->bar,
3998 "megasas: LSI")) {
3999 printk(KERN_DEBUG "megasas: IO memory region busy!\n");
4000 return -EBUSY;
4001 }
4002
Ben Collins11f8a7b2013-09-13 12:46:44 -04004003 base_addr = pci_resource_start(instance->pdev, instance->bar);
4004 instance->reg_set = ioremap_nocache(base_addr, 8192);
adam radfordcd50ba82010-12-21 10:23:23 -08004005
4006 if (!instance->reg_set) {
4007 printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
4008 goto fail_ioremap;
4009 }
4010
4011 reg_set = instance->reg_set;
4012
4013 switch (instance->pdev->device) {
adam radford9c915a82010-12-21 13:34:31 -08004014 case PCI_DEVICE_ID_LSI_FUSION:
adam radford229fe472014-03-10 02:51:56 -07004015 case PCI_DEVICE_ID_LSI_PLASMA:
adam radford36807e62011-10-08 18:15:06 -07004016 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304017 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08004018 instance->instancet = &megasas_instance_template_fusion;
4019 break;
adam radfordcd50ba82010-12-21 10:23:23 -08004020 case PCI_DEVICE_ID_LSI_SAS1078R:
4021 case PCI_DEVICE_ID_LSI_SAS1078DE:
4022 instance->instancet = &megasas_instance_template_ppc;
4023 break;
4024 case PCI_DEVICE_ID_LSI_SAS1078GEN2:
4025 case PCI_DEVICE_ID_LSI_SAS0079GEN2:
4026 instance->instancet = &megasas_instance_template_gen2;
4027 break;
4028 case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
4029 case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
4030 instance->instancet = &megasas_instance_template_skinny;
4031 break;
4032 case PCI_DEVICE_ID_LSI_SAS1064R:
4033 case PCI_DEVICE_ID_DELL_PERC5:
4034 default:
4035 instance->instancet = &megasas_instance_template_xscale;
4036 break;
4037 }
4038
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05304039 if (megasas_transition_to_ready(instance, 0)) {
4040 atomic_set(&instance->fw_reset_no_pci_access, 1);
4041 instance->instancet->adp_reset
4042 (instance, instance->reg_set);
4043 atomic_set(&instance->fw_reset_no_pci_access, 0);
4044 dev_info(&instance->pdev->dev,
4045 "megasas: FW restarted successfully from %s!\n",
4046 __func__);
4047
4048 /*waitting for about 30 second before retry*/
4049 ssleep(30);
4050
4051 if (megasas_transition_to_ready(instance, 0))
4052 goto fail_ready_state;
4053 }
adam radfordcd50ba82010-12-21 10:23:23 -08004054
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304055 /*
4056 * MSI-X host index 0 is common for all adapter.
4057 * It is used for all MPT based Adapters.
4058 */
4059 instance->reply_post_host_index_addr[0] =
4060 (u32 *)((u8 *)instance->reg_set +
4061 MPI2_REPLY_POST_HOST_INDEX_OFFSET);
4062
adam radford3f1abce2011-05-11 18:33:47 -07004063 /* Check if MSI-X is supported while in ready state */
4064 msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
4065 0x4000000) >> 0x1a;
adam radfordc8e858f2011-10-08 18:15:13 -07004066 if (msix_enable && !msix_disable) {
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304067 scratch_pad_2 = readl
4068 (&instance->reg_set->outbound_scratch_pad_2);
adam radfordc8e858f2011-10-08 18:15:13 -07004069 /* Check max MSI-X vectors */
adam radford229fe472014-03-10 02:51:56 -07004070 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
4071 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) {
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304072 instance->msix_vectors = (scratch_pad_2
4073 & MR_MAX_REPLY_QUEUES_OFFSET) + 1;
4074 fw_msix_count = instance->msix_vectors;
adam radford079eadd2012-10-01 19:26:59 -07004075 if (msix_vectors)
4076 instance->msix_vectors =
4077 min(msix_vectors,
4078 instance->msix_vectors);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304079 } else if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)
4080 || (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
4081 /* Invader/Fury supports more than 8 MSI-X */
4082 instance->msix_vectors = ((scratch_pad_2
4083 & MR_MAX_REPLY_QUEUES_EXT_OFFSET)
4084 >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
4085 fw_msix_count = instance->msix_vectors;
4086 /* Save 1-15 reply post index address to local memory
4087 * Index 0 is already saved from reg offset
4088 * MPI2_REPLY_POST_HOST_INDEX_OFFSET
4089 */
4090 for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
4091 instance->reply_post_host_index_addr[loop] =
4092 (u32 *)((u8 *)instance->reg_set +
4093 MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
4094 + (loop * 0x10));
4095 }
4096 if (msix_vectors)
4097 instance->msix_vectors = min(msix_vectors,
4098 instance->msix_vectors);
adam radfordc8e858f2011-10-08 18:15:13 -07004099 } else
4100 instance->msix_vectors = 1;
4101 /* Don't bother allocating more MSI-X vectors than cpus */
4102 instance->msix_vectors = min(instance->msix_vectors,
4103 (unsigned int)num_online_cpus());
4104 for (i = 0; i < instance->msix_vectors; i++)
4105 instance->msixentry[i].entry = i;
4106 i = pci_enable_msix(instance->pdev, instance->msixentry,
4107 instance->msix_vectors);
4108 if (i >= 0) {
4109 if (i) {
4110 if (!pci_enable_msix(instance->pdev,
4111 instance->msixentry, i))
4112 instance->msix_vectors = i;
4113 else
4114 instance->msix_vectors = 0;
4115 }
4116 } else
4117 instance->msix_vectors = 0;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304118
4119 dev_info(&instance->pdev->dev, "[scsi%d]: FW supports"
4120 "<%d> MSIX vector,Online CPUs: <%d>,"
4121 "Current MSIX <%d>\n", instance->host->host_no,
4122 fw_msix_count, (unsigned int)num_online_cpus(),
4123 instance->msix_vectors);
adam radfordc8e858f2011-10-08 18:15:13 -07004124 }
adam radford3f1abce2011-05-11 18:33:47 -07004125
adam radfordcd50ba82010-12-21 10:23:23 -08004126 /* Get operational params, sge flags, send init cmd to controller */
4127 if (instance->instancet->init_adapter(instance))
adam radfordeb1b1232011-02-24 20:55:56 -08004128 goto fail_init_adapter;
adam radfordcd50ba82010-12-21 10:23:23 -08004129
4130 printk(KERN_ERR "megasas: INIT adapter done\n");
4131
bo yang39a98552010-09-22 22:36:29 -04004132 /** for passthrough
4133 * the following function will get the PD LIST.
4134 */
4135
Yang, Bo81e403c2009-10-06 14:27:54 -06004136 memset(instance->pd_list, 0 ,
4137 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
Hannes Reinecke58968fc2014-01-16 11:25:36 +01004138 if (megasas_get_pd_list(instance) < 0) {
4139 printk(KERN_ERR "megasas: failed to get PD list\n");
4140 goto fail_init_adapter;
4141 }
Yang, Bo81e403c2009-10-06 14:27:54 -06004142
Yang, Bobdc6fb82009-12-06 08:30:19 -07004143 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
adam radford21c9e162013-09-06 15:27:14 -07004144 if (megasas_ld_list_query(instance,
4145 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
4146 megasas_get_ld_list(instance);
Yang, Bobdc6fb82009-12-06 08:30:19 -07004147
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004148 ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
4149
4150 /*
4151 * Compute the max allowed sectors per IO: The controller info has two
4152 * limits on max sectors. Driver should use the minimum of these two.
4153 *
4154 * 1 << stripe_sz_ops.min = max sectors per strip
4155 *
4156 * Note that older firmwares ( < FW ver 30) didn't report information
4157 * to calculate max_sectors_1. So the number ended up as zero always.
4158 */
bo yang14faea92007-11-09 04:14:00 -05004159 tmp_sectors = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004160 if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) {
4161
4162 max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304163 le16_to_cpu(ctrl_info->max_strips_per_io);
4164 max_sectors_2 = le32_to_cpu(ctrl_info->max_request_size);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004165
bo yang14faea92007-11-09 04:14:00 -05004166 tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2);
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304167
4168 /*Check whether controller is iMR or MR */
4169 if (ctrl_info->memory_size) {
4170 instance->is_imr = 0;
4171 dev_info(&instance->pdev->dev, "Controller type: MR,"
4172 "Memory size is: %dMB\n",
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304173 le16_to_cpu(ctrl_info->memory_size));
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304174 } else {
4175 instance->is_imr = 1;
4176 dev_info(&instance->pdev->dev,
4177 "Controller type: iMR\n");
4178 }
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304179 /* OnOffProperties are converted into CPU arch*/
4180 le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties);
bo yang39a98552010-09-22 22:36:29 -04004181 instance->disableOnlineCtrlReset =
4182 ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304183 /* adapterOperations2 are converted into CPU arch*/
4184 le32_to_cpus((u32 *)&ctrl_info->adapterOperations2);
adam radford229fe472014-03-10 02:51:56 -07004185 instance->mpio = ctrl_info->adapterOperations2.mpio;
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05304186 instance->UnevenSpanSupport =
4187 ctrl_info->adapterOperations2.supportUnevenSpans;
4188 if (instance->UnevenSpanSupport) {
4189 struct fusion_context *fusion = instance->ctrl_context;
4190 dev_info(&instance->pdev->dev, "FW supports: "
4191 "UnevenSpanSupport=%x\n", instance->UnevenSpanSupport);
4192 if (MR_ValidateMapInfo(instance))
4193 fusion->fast_path_io = 1;
4194 else
4195 fusion->fast_path_io = 0;
4196
4197 }
adam radford229fe472014-03-10 02:51:56 -07004198 if (ctrl_info->host_interface.SRIOV) {
4199 if (!ctrl_info->adapterOperations2.activePassive)
4200 instance->PlasmaFW111 = 1;
4201
4202 if (!instance->PlasmaFW111)
4203 instance->requestorId =
4204 ctrl_info->iov.requestorId;
4205 else {
4206 iovPtr = (struct IOV_111 *)((unsigned char *)ctrl_info + IOV_111_OFFSET);
4207 instance->requestorId = iovPtr->requestorId;
4208 }
4209 printk(KERN_WARNING "megaraid_sas: I am VF "
4210 "requestorId %d\n", instance->requestorId);
4211 }
bo yang14faea92007-11-09 04:14:00 -05004212 }
bo yang14faea92007-11-09 04:14:00 -05004213 instance->max_sectors_per_req = instance->max_num_sge *
4214 PAGE_SIZE / 512;
4215 if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
4216 instance->max_sectors_per_req = tmp_sectors;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004217
4218 kfree(ctrl_info);
4219
adam radfordc5daa6a2012-07-17 18:20:03 -07004220 /* Check for valid throttlequeuedepth module parameter */
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304221 if (instance->is_imr) {
adam radfordc5daa6a2012-07-17 18:20:03 -07004222 if (throttlequeuedepth > (instance->max_fw_cmds -
4223 MEGASAS_SKINNY_INT_CMDS))
4224 instance->throttlequeuedepth =
4225 MEGASAS_THROTTLE_QUEUE_DEPTH;
4226 else
4227 instance->throttlequeuedepth = throttlequeuedepth;
4228 } else {
4229 if (throttlequeuedepth > (instance->max_fw_cmds -
4230 MEGASAS_INT_CMDS))
4231 instance->throttlequeuedepth =
4232 MEGASAS_THROTTLE_QUEUE_DEPTH;
4233 else
4234 instance->throttlequeuedepth = throttlequeuedepth;
4235 }
4236
Sumant Patro5d018ad2006-10-03 13:13:18 -07004237 /*
4238 * Setup tasklet for cmd completion
4239 */
4240
adam radfordf86c5422011-02-24 20:57:00 -08004241 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
bo yangad84db22007-11-09 04:40:16 -05004242 (unsigned long)instance);
4243
adam radford229fe472014-03-10 02:51:56 -07004244 /* Launch SR-IOV heartbeat timer */
4245 if (instance->requestorId) {
4246 if (!megasas_sriov_start_heartbeat(instance, 1))
4247 megasas_start_timer(instance,
4248 &instance->sriov_heartbeat_timer,
4249 megasas_sriov_heartbeat_handler,
4250 MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
4251 else
4252 instance->skip_heartbeat_timer_del = 1;
4253 }
4254
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004255 return 0;
4256
adam radfordeb1b1232011-02-24 20:55:56 -08004257fail_init_adapter:
adam radfordcd50ba82010-12-21 10:23:23 -08004258fail_ready_state:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004259 iounmap(instance->reg_set);
4260
4261 fail_ioremap:
adam radfordb6d5d882010-12-14 18:56:07 -08004262 pci_release_selected_regions(instance->pdev, instance->bar);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004263
4264 return -EINVAL;
4265}
4266
4267/**
4268 * megasas_release_mfi - Reverses the FW initialization
4269 * @intance: Adapter soft state
4270 */
4271static void megasas_release_mfi(struct megasas_instance *instance)
4272{
adam radford9c915a82010-12-21 13:34:31 -08004273 u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004274
adam radford9c915a82010-12-21 13:34:31 -08004275 if (instance->reply_queue)
4276 pci_free_consistent(instance->pdev, reply_q_sz,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004277 instance->reply_queue, instance->reply_queue_h);
4278
4279 megasas_free_cmds(instance);
4280
4281 iounmap(instance->reg_set);
4282
adam radfordb6d5d882010-12-14 18:56:07 -08004283 pci_release_selected_regions(instance->pdev, instance->bar);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004284}
4285
4286/**
4287 * megasas_get_seq_num - Gets latest event sequence numbers
4288 * @instance: Adapter soft state
4289 * @eli: FW event log sequence numbers information
4290 *
4291 * FW maintains a log of all events in a non-volatile area. Upper layers would
4292 * usually find out the latest sequence number of the events, the seq number at
4293 * the boot etc. They would "read" all the events below the latest seq number
4294 * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq
4295 * number), they would subsribe to AEN (asynchronous event notification) and
4296 * wait for the events to happen.
4297 */
4298static int
4299megasas_get_seq_num(struct megasas_instance *instance,
4300 struct megasas_evt_log_info *eli)
4301{
4302 struct megasas_cmd *cmd;
4303 struct megasas_dcmd_frame *dcmd;
4304 struct megasas_evt_log_info *el_info;
4305 dma_addr_t el_info_h = 0;
4306
4307 cmd = megasas_get_cmd(instance);
4308
4309 if (!cmd) {
4310 return -ENOMEM;
4311 }
4312
4313 dcmd = &cmd->frame->dcmd;
4314 el_info = pci_alloc_consistent(instance->pdev,
4315 sizeof(struct megasas_evt_log_info),
4316 &el_info_h);
4317
4318 if (!el_info) {
4319 megasas_return_cmd(instance, cmd);
4320 return -ENOMEM;
4321 }
4322
4323 memset(el_info, 0, sizeof(*el_info));
4324 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4325
4326 dcmd->cmd = MFI_CMD_DCMD;
4327 dcmd->cmd_status = 0x0;
4328 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304329 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004330 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004331 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304332 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_log_info));
4333 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_EVENT_GET_INFO);
4334 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(el_info_h);
4335 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_log_info));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004336
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05304337 if (megasas_issue_blocked_cmd(instance, cmd, 30))
4338 dev_err(&instance->pdev->dev, "Command timedout"
4339 "from %s\n", __func__);
4340 else {
4341 /*
4342 * Copy the data back into callers buffer
4343 */
4344 eli->newest_seq_num = le32_to_cpu(el_info->newest_seq_num);
4345 eli->oldest_seq_num = le32_to_cpu(el_info->oldest_seq_num);
4346 eli->clear_seq_num = le32_to_cpu(el_info->clear_seq_num);
4347 eli->shutdown_seq_num = le32_to_cpu(el_info->shutdown_seq_num);
4348 eli->boot_seq_num = le32_to_cpu(el_info->boot_seq_num);
4349 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004350
4351 pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info),
4352 el_info, el_info_h);
4353
4354 megasas_return_cmd(instance, cmd);
4355
4356 return 0;
4357}
4358
4359/**
4360 * megasas_register_aen - Registers for asynchronous event notification
4361 * @instance: Adapter soft state
4362 * @seq_num: The starting sequence number
4363 * @class_locale: Class of the event
4364 *
4365 * This function subscribes for AEN for events beyond the @seq_num. It requests
4366 * to be notified if and only if the event is of type @class_locale
4367 */
4368static int
4369megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
4370 u32 class_locale_word)
4371{
4372 int ret_val;
4373 struct megasas_cmd *cmd;
4374 struct megasas_dcmd_frame *dcmd;
4375 union megasas_evt_class_locale curr_aen;
4376 union megasas_evt_class_locale prev_aen;
4377
4378 /*
4379 * If there an AEN pending already (aen_cmd), check if the
4380 * class_locale of that pending AEN is inclusive of the new
4381 * AEN request we currently have. If it is, then we don't have
4382 * to do anything. In other words, whichever events the current
4383 * AEN request is subscribing to, have already been subscribed
4384 * to.
4385 *
4386 * If the old_cmd is _not_ inclusive, then we have to abort
4387 * that command, form a class_locale that is superset of both
4388 * old and current and re-issue to the FW
4389 */
4390
4391 curr_aen.word = class_locale_word;
4392
4393 if (instance->aen_cmd) {
4394
4395 prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1];
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304396 prev_aen.members.locale = le16_to_cpu(prev_aen.members.locale);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004397
4398 /*
4399 * A class whose enum value is smaller is inclusive of all
4400 * higher values. If a PROGRESS (= -1) was previously
4401 * registered, then a new registration requests for higher
4402 * classes need not be sent to FW. They are automatically
4403 * included.
4404 *
4405 * Locale numbers don't have such hierarchy. They are bitmap
4406 * values
4407 */
4408 if ((prev_aen.members.class <= curr_aen.members.class) &&
Sumit.Saxena@lsi.com3993a862013-09-16 15:18:06 +05304409 !((prev_aen.members.locale & curr_aen.members.locale) ^
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004410 curr_aen.members.locale)) {
4411 /*
4412 * Previously issued event registration includes
4413 * current request. Nothing to do.
4414 */
4415 return 0;
4416 } else {
Sumit.Saxena@lsi.com3993a862013-09-16 15:18:06 +05304417 curr_aen.members.locale |= prev_aen.members.locale;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004418
4419 if (prev_aen.members.class < curr_aen.members.class)
4420 curr_aen.members.class = prev_aen.members.class;
4421
4422 instance->aen_cmd->abort_aen = 1;
4423 ret_val = megasas_issue_blocked_abort_cmd(instance,
4424 instance->
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05304425 aen_cmd, 30);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004426
4427 if (ret_val) {
4428 printk(KERN_DEBUG "megasas: Failed to abort "
4429 "previous AEN command\n");
4430 return ret_val;
4431 }
4432 }
4433 }
4434
4435 cmd = megasas_get_cmd(instance);
4436
4437 if (!cmd)
4438 return -ENOMEM;
4439
4440 dcmd = &cmd->frame->dcmd;
4441
4442 memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail));
4443
4444 /*
4445 * Prepare DCMD for aen registration
4446 */
4447 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4448
4449 dcmd->cmd = MFI_CMD_DCMD;
4450 dcmd->cmd_status = 0x0;
4451 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304452 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004453 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004454 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304455 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_detail));
4456 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_EVENT_WAIT);
4457 dcmd->mbox.w[0] = cpu_to_le32(seq_num);
bo yang39a98552010-09-22 22:36:29 -04004458 instance->last_seq_num = seq_num;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304459 dcmd->mbox.w[1] = cpu_to_le32(curr_aen.word);
4460 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->evt_detail_h);
4461 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_detail));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004462
Yang, Bof4c9a132009-10-06 14:43:28 -06004463 if (instance->aen_cmd != NULL) {
4464 megasas_return_cmd(instance, cmd);
4465 return 0;
4466 }
4467
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004468 /*
4469 * Store reference to the cmd used to register for AEN. When an
4470 * application wants us to register for AEN, we have to abort this
4471 * cmd and re-register with a new EVENT LOCALE supplied by that app
4472 */
4473 instance->aen_cmd = cmd;
4474
4475 /*
4476 * Issue the aen registration frame
4477 */
adam radford9c915a82010-12-21 13:34:31 -08004478 instance->instancet->issue_dcmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004479
4480 return 0;
4481}
4482
4483/**
4484 * megasas_start_aen - Subscribes to AEN during driver load time
4485 * @instance: Adapter soft state
4486 */
4487static int megasas_start_aen(struct megasas_instance *instance)
4488{
4489 struct megasas_evt_log_info eli;
4490 union megasas_evt_class_locale class_locale;
4491
4492 /*
4493 * Get the latest sequence number from FW
4494 */
4495 memset(&eli, 0, sizeof(eli));
4496
4497 if (megasas_get_seq_num(instance, &eli))
4498 return -1;
4499
4500 /*
4501 * Register AEN with FW for latest sequence number plus 1
4502 */
4503 class_locale.members.reserved = 0;
4504 class_locale.members.locale = MR_EVT_LOCALE_ALL;
4505 class_locale.members.class = MR_EVT_CLASS_DEBUG;
4506
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304507 return megasas_register_aen(instance,
Sumit.Saxena@lsi.com3993a862013-09-16 15:18:06 +05304508 eli.newest_seq_num + 1,
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304509 class_locale.word);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004510}
4511
4512/**
4513 * megasas_io_attach - Attaches this driver to SCSI mid-layer
4514 * @instance: Adapter soft state
4515 */
4516static int megasas_io_attach(struct megasas_instance *instance)
4517{
4518 struct Scsi_Host *host = instance->host;
4519
4520 /*
4521 * Export parameters required by SCSI mid-layer
4522 */
4523 host->irq = instance->pdev->irq;
4524 host->unique_id = instance->unique_id;
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304525 if (instance->is_imr) {
Yang, Bo7bebf5c2009-10-06 14:40:58 -06004526 host->can_queue =
4527 instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
4528 } else
4529 host->can_queue =
4530 instance->max_fw_cmds - MEGASAS_INT_CMDS;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004531 host->this_id = instance->init_id;
4532 host->sg_tablesize = instance->max_num_sge;
adam radford42a8d2b2011-02-24 20:57:09 -08004533
4534 if (instance->fw_support_ieee)
4535 instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE;
4536
Yang, Bo1fd10682010-10-12 07:18:50 -06004537 /*
4538 * Check if the module parameter value for max_sectors can be used
4539 */
4540 if (max_sectors && max_sectors < instance->max_sectors_per_req)
4541 instance->max_sectors_per_req = max_sectors;
4542 else {
4543 if (max_sectors) {
4544 if (((instance->pdev->device ==
4545 PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
4546 (instance->pdev->device ==
4547 PCI_DEVICE_ID_LSI_SAS0079GEN2)) &&
4548 (max_sectors <= MEGASAS_MAX_SECTORS)) {
4549 instance->max_sectors_per_req = max_sectors;
4550 } else {
4551 printk(KERN_INFO "megasas: max_sectors should be > 0"
4552 "and <= %d (or < 1MB for GEN2 controller)\n",
4553 instance->max_sectors_per_req);
4554 }
4555 }
4556 }
4557
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004558 host->max_sectors = instance->max_sectors_per_req;
adam radford9c915a82010-12-21 13:34:31 -08004559 host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004560 host->max_channel = MEGASAS_MAX_CHANNELS - 1;
4561 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
4562 host->max_lun = MEGASAS_MAX_LUN;
Joshua Giles122da302006-02-03 15:34:17 -08004563 host->max_cmd_len = 16;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004564
adam radford9c915a82010-12-21 13:34:31 -08004565 /* Fusion only supports host reset */
adam radford36807e62011-10-08 18:15:06 -07004566 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
adam radford229fe472014-03-10 02:51:56 -07004567 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304568 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
4569 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
adam radford9c915a82010-12-21 13:34:31 -08004570 host->hostt->eh_device_reset_handler = NULL;
4571 host->hostt->eh_bus_reset_handler = NULL;
4572 }
4573
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004574 /*
4575 * Notify the mid-layer about the new controller
4576 */
4577 if (scsi_add_host(host, &instance->pdev->dev)) {
4578 printk(KERN_DEBUG "megasas: scsi_add_host failed\n");
4579 return -ENODEV;
4580 }
4581
4582 /*
4583 * Trigger SCSI to scan our drives
4584 */
4585 scsi_scan_host(host);
4586 return 0;
4587}
4588
bo yang31ea7082007-11-07 12:09:50 -05004589static int
4590megasas_set_dma_mask(struct pci_dev *pdev)
4591{
4592 /*
4593 * All our contollers are capable of performing 64-bit DMA
4594 */
4595 if (IS_DMA64) {
Yang Hongyang6a355282009-04-06 19:01:13 -07004596 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
bo yang31ea7082007-11-07 12:09:50 -05004597
Yang Hongyang284901a2009-04-06 19:01:15 -07004598 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
bo yang31ea7082007-11-07 12:09:50 -05004599 goto fail_set_dma_mask;
4600 }
4601 } else {
Yang Hongyang284901a2009-04-06 19:01:15 -07004602 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
bo yang31ea7082007-11-07 12:09:50 -05004603 goto fail_set_dma_mask;
4604 }
Sumit.Saxena@lsi.com46de63e22014-02-12 23:38:44 +05304605 /*
4606 * Ensure that all data structures are allocated in 32-bit
4607 * memory.
4608 */
4609 if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
4610 /* Try 32bit DMA mask and 32 bit Consistent dma mask */
4611 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
4612 && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
4613 dev_info(&pdev->dev, "set 32bit DMA mask"
4614 "and 32 bit consistent mask\n");
4615 else
4616 goto fail_set_dma_mask;
4617 }
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304618
bo yang31ea7082007-11-07 12:09:50 -05004619 return 0;
4620
4621fail_set_dma_mask:
4622 return 1;
4623}
4624
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004625/**
4626 * megasas_probe_one - PCI hotplug entry point
4627 * @pdev: PCI device structure
adam radford0d490162010-12-14 19:17:17 -08004628 * @id: PCI ids of supported hotplugged adapter
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004629 */
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08004630static int megasas_probe_one(struct pci_dev *pdev,
4631 const struct pci_device_id *id)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004632{
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304633 int rval, pos, i, j, cpu;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004634 struct Scsi_Host *host;
4635 struct megasas_instance *instance;
adam radford66192dfe2011-02-24 20:56:28 -08004636 u16 control = 0;
4637
4638 /* Reset MSI-X in the kdump kernel */
4639 if (reset_devices) {
4640 pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
4641 if (pos) {
Bjorn Helgaas99369062013-04-17 18:08:44 -06004642 pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS,
adam radford66192dfe2011-02-24 20:56:28 -08004643 &control);
4644 if (control & PCI_MSIX_FLAGS_ENABLE) {
4645 dev_info(&pdev->dev, "resetting MSI-X\n");
4646 pci_write_config_word(pdev,
Bjorn Helgaas99369062013-04-17 18:08:44 -06004647 pos + PCI_MSIX_FLAGS,
adam radford66192dfe2011-02-24 20:56:28 -08004648 control &
4649 ~PCI_MSIX_FLAGS_ENABLE);
4650 }
4651 }
4652 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004653
4654 /*
4655 * Announce PCI information
4656 */
4657 printk(KERN_INFO "megasas: %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
4658 pdev->vendor, pdev->device, pdev->subsystem_vendor,
4659 pdev->subsystem_device);
4660
4661 printk("bus %d:slot %d:func %d\n",
4662 pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
4663
4664 /*
4665 * PCI prepping: enable device set bus mastering and dma mask
4666 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09004667 rval = pci_enable_device_mem(pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004668
4669 if (rval) {
4670 return rval;
4671 }
4672
4673 pci_set_master(pdev);
4674
bo yang31ea7082007-11-07 12:09:50 -05004675 if (megasas_set_dma_mask(pdev))
4676 goto fail_set_dma_mask;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004677
4678 host = scsi_host_alloc(&megasas_template,
4679 sizeof(struct megasas_instance));
4680
4681 if (!host) {
4682 printk(KERN_DEBUG "megasas: scsi_host_alloc failed\n");
4683 goto fail_alloc_instance;
4684 }
4685
4686 instance = (struct megasas_instance *)host->hostdata;
4687 memset(instance, 0, sizeof(*instance));
bo yang39a98552010-09-22 22:36:29 -04004688 atomic_set( &instance->fw_reset_no_pci_access, 0 );
adam radford9c915a82010-12-21 13:34:31 -08004689 instance->pdev = pdev;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004690
adam radford9c915a82010-12-21 13:34:31 -08004691 switch (instance->pdev->device) {
4692 case PCI_DEVICE_ID_LSI_FUSION:
adam radford229fe472014-03-10 02:51:56 -07004693 case PCI_DEVICE_ID_LSI_PLASMA:
adam radford36807e62011-10-08 18:15:06 -07004694 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304695 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08004696 {
4697 struct fusion_context *fusion;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004698
adam radford9c915a82010-12-21 13:34:31 -08004699 instance->ctrl_context =
4700 kzalloc(sizeof(struct fusion_context), GFP_KERNEL);
4701 if (!instance->ctrl_context) {
4702 printk(KERN_DEBUG "megasas: Failed to allocate "
4703 "memory for Fusion context info\n");
4704 goto fail_alloc_dma_buf;
4705 }
4706 fusion = instance->ctrl_context;
4707 INIT_LIST_HEAD(&fusion->cmd_pool);
4708 spin_lock_init(&fusion->cmd_pool_lock);
4709 }
4710 break;
4711 default: /* For all other supported controllers */
4712
4713 instance->producer =
4714 pci_alloc_consistent(pdev, sizeof(u32),
4715 &instance->producer_h);
4716 instance->consumer =
4717 pci_alloc_consistent(pdev, sizeof(u32),
4718 &instance->consumer_h);
4719
4720 if (!instance->producer || !instance->consumer) {
4721 printk(KERN_DEBUG "megasas: Failed to allocate"
4722 "memory for producer, consumer\n");
4723 goto fail_alloc_dma_buf;
4724 }
4725
4726 *instance->producer = 0;
4727 *instance->consumer = 0;
4728 break;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004729 }
4730
Yang, Boc3518832009-10-06 14:18:02 -06004731 megasas_poll_wait_aen = 0;
Yang, Bof4c9a132009-10-06 14:43:28 -06004732 instance->flag_ieee = 0;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004733 instance->ev = NULL;
bo yang39a98552010-09-22 22:36:29 -04004734 instance->issuepend_done = 1;
4735 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304736 instance->is_imr = 0;
bo yang39a98552010-09-22 22:36:29 -04004737 megasas_poll_wait_aen = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004738
4739 instance->evt_detail = pci_alloc_consistent(pdev,
4740 sizeof(struct
4741 megasas_evt_detail),
4742 &instance->evt_detail_h);
4743
4744 if (!instance->evt_detail) {
4745 printk(KERN_DEBUG "megasas: Failed to allocate memory for "
4746 "event detail structure\n");
4747 goto fail_alloc_dma_buf;
4748 }
4749
4750 /*
4751 * Initialize locks and queues
4752 */
4753 INIT_LIST_HEAD(&instance->cmd_pool);
bo yang39a98552010-09-22 22:36:29 -04004754 INIT_LIST_HEAD(&instance->internal_reset_pending_q);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004755
Sumant Patroe4a082c2006-05-30 12:03:37 -07004756 atomic_set(&instance->fw_outstanding,0);
4757
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004758 init_waitqueue_head(&instance->int_cmd_wait_q);
4759 init_waitqueue_head(&instance->abort_cmd_wait_q);
4760
4761 spin_lock_init(&instance->cmd_pool_lock);
bo yang39a98552010-09-22 22:36:29 -04004762 spin_lock_init(&instance->hba_lock);
bo yang7343eb62007-11-09 04:35:44 -05004763 spin_lock_init(&instance->completion_lock);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004764
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02004765 mutex_init(&instance->aen_mutex);
adam radford9c915a82010-12-21 13:34:31 -08004766 mutex_init(&instance->reset_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004767
4768 /*
4769 * Initialize PCI related and misc parameters
4770 */
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004771 instance->host = host;
4772 instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
4773 instance->init_id = MEGASAS_DEFAULT_INIT_ID;
4774
Yang, Bo7bebf5c2009-10-06 14:40:58 -06004775 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
4776 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
Yang, Bof4c9a132009-10-06 14:43:28 -06004777 instance->flag_ieee = 1;
Yang, Bo7bebf5c2009-10-06 14:40:58 -06004778 sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
4779 } else
4780 sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
4781
Sumant Patro658dced2006-10-03 13:09:14 -07004782 megasas_dbg_lvl = 0;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07004783 instance->flag = 0;
Yang, Bo0c79e682009-10-06 14:47:35 -06004784 instance->unload = 1;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07004785 instance->last_time = 0;
bo yang39a98552010-09-22 22:36:29 -04004786 instance->disableOnlineCtrlReset = 1;
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05304787 instance->UnevenSpanSupport = 0;
bo yang39a98552010-09-22 22:36:29 -04004788
adam radford36807e62011-10-08 18:15:06 -07004789 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
adam radford229fe472014-03-10 02:51:56 -07004790 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304791 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
4792 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
adam radford9c915a82010-12-21 13:34:31 -08004793 INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
4794 else
4795 INIT_WORK(&instance->work_init, process_fw_state_change_wq);
Sumant Patro658dced2006-10-03 13:09:14 -07004796
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004797 /*
adam radford0a770662011-02-24 20:56:12 -08004798 * Initialize MFI Firmware
4799 */
4800 if (megasas_init_fw(instance))
4801 goto fail_init_mfi;
4802
adam radford229fe472014-03-10 02:51:56 -07004803 if (instance->requestorId) {
4804 if (instance->PlasmaFW111) {
4805 instance->vf_affiliation_111 =
4806 pci_alloc_consistent(pdev, sizeof(struct MR_LD_VF_AFFILIATION_111),
4807 &instance->vf_affiliation_111_h);
4808 if (!instance->vf_affiliation_111)
4809 printk(KERN_WARNING "megasas: Can't allocate "
4810 "memory for VF affiliation buffer\n");
4811 } else {
4812 instance->vf_affiliation =
4813 pci_alloc_consistent(pdev,
4814 (MAX_LOGICAL_DRIVES + 1) *
4815 sizeof(struct MR_LD_VF_AFFILIATION),
4816 &instance->vf_affiliation_h);
4817 if (!instance->vf_affiliation)
4818 printk(KERN_WARNING "megasas: Can't allocate "
4819 "memory for VF affiliation buffer\n");
4820 }
4821 }
4822
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304823retry_irq_register:
adam radford0a770662011-02-24 20:56:12 -08004824 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004825 * Register IRQ
4826 */
adam radfordc8e858f2011-10-08 18:15:13 -07004827 if (instance->msix_vectors) {
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304828 cpu = cpumask_first(cpu_online_mask);
4829 for (i = 0; i < instance->msix_vectors; i++) {
adam radfordc8e858f2011-10-08 18:15:13 -07004830 instance->irq_context[i].instance = instance;
4831 instance->irq_context[i].MSIxIndex = i;
4832 if (request_irq(instance->msixentry[i].vector,
4833 instance->instancet->service_isr, 0,
4834 "megasas",
4835 &instance->irq_context[i])) {
4836 printk(KERN_DEBUG "megasas: Failed to "
4837 "register IRQ for vector %d.\n", i);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304838 for (j = 0; j < i; j++) {
4839 irq_set_affinity_hint(
4840 instance->msixentry[j].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07004841 free_irq(
4842 instance->msixentry[j].vector,
4843 &instance->irq_context[j]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304844 }
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304845 /* Retry irq register for IO_APIC */
4846 instance->msix_vectors = 0;
4847 goto retry_irq_register;
adam radfordc8e858f2011-10-08 18:15:13 -07004848 }
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304849 if (irq_set_affinity_hint(instance->msixentry[i].vector,
4850 get_cpu_mask(cpu)))
4851 dev_err(&instance->pdev->dev, "Error setting"
4852 "affinity hint for cpu %d\n", cpu);
4853 cpu = cpumask_next(cpu, cpu_online_mask);
adam radfordc8e858f2011-10-08 18:15:13 -07004854 }
4855 } else {
4856 instance->irq_context[0].instance = instance;
4857 instance->irq_context[0].MSIxIndex = 0;
4858 if (request_irq(pdev->irq, instance->instancet->service_isr,
4859 IRQF_SHARED, "megasas",
4860 &instance->irq_context[0])) {
4861 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
4862 goto fail_irq;
4863 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004864 }
4865
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304866 instance->instancet->enable_intr(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004867
4868 /*
4869 * Store instance in PCI softstate
4870 */
4871 pci_set_drvdata(pdev, instance);
4872
4873 /*
4874 * Add this controller to megasas_mgmt_info structure so that it
4875 * can be exported to management applications
4876 */
4877 megasas_mgmt_info.count++;
4878 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance;
4879 megasas_mgmt_info.max_index++;
4880
4881 /*
adam radford541f90b2011-05-11 18:34:29 -07004882 * Register with SCSI mid-layer
4883 */
4884 if (megasas_io_attach(instance))
4885 goto fail_io_attach;
4886
4887 instance->unload = 0;
4888
4889 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004890 * Initiate AEN (Asynchronous Event Notification)
4891 */
4892 if (megasas_start_aen(instance)) {
4893 printk(KERN_DEBUG "megasas: start aen failed\n");
4894 goto fail_start_aen;
4895 }
4896
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004897 return 0;
4898
4899 fail_start_aen:
4900 fail_io_attach:
4901 megasas_mgmt_info.count--;
4902 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
4903 megasas_mgmt_info.max_index--;
4904
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304905 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07004906 if (instance->msix_vectors)
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304907 for (i = 0; i < instance->msix_vectors; i++) {
4908 irq_set_affinity_hint(
4909 instance->msixentry[i].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07004910 free_irq(instance->msixentry[i].vector,
4911 &instance->irq_context[i]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304912 }
adam radfordc8e858f2011-10-08 18:15:13 -07004913 else
4914 free_irq(instance->pdev->irq, &instance->irq_context[0]);
adam radfordeb1b1232011-02-24 20:55:56 -08004915fail_irq:
adam radford36807e62011-10-08 18:15:06 -07004916 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
adam radford229fe472014-03-10 02:51:56 -07004917 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304918 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
4919 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
adam radfordeb1b1232011-02-24 20:55:56 -08004920 megasas_release_fusion(instance);
4921 else
4922 megasas_release_mfi(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004923 fail_init_mfi:
adam radfordc8e858f2011-10-08 18:15:13 -07004924 if (instance->msix_vectors)
adam radford0a770662011-02-24 20:56:12 -08004925 pci_disable_msix(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004926 fail_alloc_dma_buf:
4927 if (instance->evt_detail)
4928 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
4929 instance->evt_detail,
4930 instance->evt_detail_h);
4931
adam radfordeb1b1232011-02-24 20:55:56 -08004932 if (instance->producer)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004933 pci_free_consistent(pdev, sizeof(u32), instance->producer,
4934 instance->producer_h);
4935 if (instance->consumer)
4936 pci_free_consistent(pdev, sizeof(u32), instance->consumer,
4937 instance->consumer_h);
4938 scsi_host_put(host);
4939
4940 fail_alloc_instance:
4941 fail_set_dma_mask:
4942 pci_disable_device(pdev);
4943
4944 return -ENODEV;
4945}
4946
4947/**
4948 * megasas_flush_cache - Requests FW to flush all its caches
4949 * @instance: Adapter soft state
4950 */
4951static void megasas_flush_cache(struct megasas_instance *instance)
4952{
4953 struct megasas_cmd *cmd;
4954 struct megasas_dcmd_frame *dcmd;
4955
bo yang39a98552010-09-22 22:36:29 -04004956 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
4957 return;
4958
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004959 cmd = megasas_get_cmd(instance);
4960
4961 if (!cmd)
4962 return;
4963
4964 dcmd = &cmd->frame->dcmd;
4965
4966 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4967
4968 dcmd->cmd = MFI_CMD_DCMD;
4969 dcmd->cmd_status = 0x0;
4970 dcmd->sge_count = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304971 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004972 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004973 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004974 dcmd->data_xfer_len = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304975 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_CACHE_FLUSH);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004976 dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
4977
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05304978 if (megasas_issue_blocked_cmd(instance, cmd, 30))
4979 dev_err(&instance->pdev->dev, "Command timedout"
4980 " from %s\n", __func__);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004981
4982 megasas_return_cmd(instance, cmd);
4983
4984 return;
4985}
4986
4987/**
4988 * megasas_shutdown_controller - Instructs FW to shutdown the controller
4989 * @instance: Adapter soft state
bo yang31ea7082007-11-07 12:09:50 -05004990 * @opcode: Shutdown/Hibernate
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004991 */
bo yang31ea7082007-11-07 12:09:50 -05004992static void megasas_shutdown_controller(struct megasas_instance *instance,
4993 u32 opcode)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004994{
4995 struct megasas_cmd *cmd;
4996 struct megasas_dcmd_frame *dcmd;
4997
bo yang39a98552010-09-22 22:36:29 -04004998 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
4999 return;
5000
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005001 cmd = megasas_get_cmd(instance);
5002
5003 if (!cmd)
5004 return;
5005
5006 if (instance->aen_cmd)
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305007 megasas_issue_blocked_abort_cmd(instance,
5008 instance->aen_cmd, 30);
adam radford9c915a82010-12-21 13:34:31 -08005009 if (instance->map_update_cmd)
5010 megasas_issue_blocked_abort_cmd(instance,
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305011 instance->map_update_cmd, 30);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005012 dcmd = &cmd->frame->dcmd;
5013
5014 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
5015
5016 dcmd->cmd = MFI_CMD_DCMD;
5017 dcmd->cmd_status = 0x0;
5018 dcmd->sge_count = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305019 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005020 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07005021 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005022 dcmd->data_xfer_len = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305023 dcmd->opcode = cpu_to_le32(opcode);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005024
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305025 if (megasas_issue_blocked_cmd(instance, cmd, 30))
5026 dev_err(&instance->pdev->dev, "Command timedout"
5027 "from %s\n", __func__);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005028
5029 megasas_return_cmd(instance, cmd);
5030
5031 return;
5032}
5033
Jiri Slaby33139b22008-05-01 17:56:02 +02005034#ifdef CONFIG_PM
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005035/**
bo yangad84db22007-11-09 04:40:16 -05005036 * megasas_suspend - driver suspend entry point
5037 * @pdev: PCI device structure
bo yang31ea7082007-11-07 12:09:50 -05005038 * @state: PCI power state to suspend routine
5039 */
Jiri Slaby33139b22008-05-01 17:56:02 +02005040static int
bo yang31ea7082007-11-07 12:09:50 -05005041megasas_suspend(struct pci_dev *pdev, pm_message_t state)
5042{
5043 struct Scsi_Host *host;
5044 struct megasas_instance *instance;
adam radfordc8e858f2011-10-08 18:15:13 -07005045 int i;
bo yang31ea7082007-11-07 12:09:50 -05005046
5047 instance = pci_get_drvdata(pdev);
5048 host = instance->host;
Yang, Bo0c79e682009-10-06 14:47:35 -06005049 instance->unload = 1;
bo yang31ea7082007-11-07 12:09:50 -05005050
adam radford229fe472014-03-10 02:51:56 -07005051 /* Shutdown SR-IOV heartbeat timer */
5052 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
5053 del_timer_sync(&instance->sriov_heartbeat_timer);
5054
bo yang31ea7082007-11-07 12:09:50 -05005055 megasas_flush_cache(instance);
5056 megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005057
5058 /* cancel the delayed work if this work still in queue */
5059 if (instance->ev != NULL) {
5060 struct megasas_aen_event *ev = instance->ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08005061 cancel_delayed_work_sync(&ev->hotplug_work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005062 instance->ev = NULL;
5063 }
5064
bo yang31ea7082007-11-07 12:09:50 -05005065 tasklet_kill(&instance->isr_tasklet);
5066
5067 pci_set_drvdata(instance->pdev, instance);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305068 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07005069
5070 if (instance->msix_vectors)
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305071 for (i = 0; i < instance->msix_vectors; i++) {
5072 irq_set_affinity_hint(
5073 instance->msixentry[i].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07005074 free_irq(instance->msixentry[i].vector,
5075 &instance->irq_context[i]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305076 }
adam radfordc8e858f2011-10-08 18:15:13 -07005077 else
5078 free_irq(instance->pdev->irq, &instance->irq_context[0]);
5079 if (instance->msix_vectors)
adam radford80d9da92010-12-21 10:17:40 -08005080 pci_disable_msix(instance->pdev);
bo yang31ea7082007-11-07 12:09:50 -05005081
5082 pci_save_state(pdev);
5083 pci_disable_device(pdev);
5084
5085 pci_set_power_state(pdev, pci_choose_state(pdev, state));
5086
5087 return 0;
5088}
5089
5090/**
5091 * megasas_resume- driver resume entry point
5092 * @pdev: PCI device structure
5093 */
Jiri Slaby33139b22008-05-01 17:56:02 +02005094static int
bo yang31ea7082007-11-07 12:09:50 -05005095megasas_resume(struct pci_dev *pdev)
5096{
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305097 int rval, i, j, cpu;
bo yang31ea7082007-11-07 12:09:50 -05005098 struct Scsi_Host *host;
5099 struct megasas_instance *instance;
5100
5101 instance = pci_get_drvdata(pdev);
5102 host = instance->host;
5103 pci_set_power_state(pdev, PCI_D0);
5104 pci_enable_wake(pdev, PCI_D0, 0);
5105 pci_restore_state(pdev);
5106
5107 /*
5108 * PCI prepping: enable device set bus mastering and dma mask
5109 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09005110 rval = pci_enable_device_mem(pdev);
bo yang31ea7082007-11-07 12:09:50 -05005111
5112 if (rval) {
5113 printk(KERN_ERR "megasas: Enable device failed\n");
5114 return rval;
5115 }
5116
5117 pci_set_master(pdev);
5118
5119 if (megasas_set_dma_mask(pdev))
5120 goto fail_set_dma_mask;
5121
5122 /*
5123 * Initialize MFI Firmware
5124 */
5125
bo yang31ea7082007-11-07 12:09:50 -05005126 atomic_set(&instance->fw_outstanding, 0);
5127
5128 /*
5129 * We expect the FW state to be READY
5130 */
adam radford058a8fa2011-10-08 18:14:27 -07005131 if (megasas_transition_to_ready(instance, 0))
bo yang31ea7082007-11-07 12:09:50 -05005132 goto fail_ready_state;
5133
adam radford3f1abce2011-05-11 18:33:47 -07005134 /* Now re-enable MSI-X */
adam radfordc8e858f2011-10-08 18:15:13 -07005135 if (instance->msix_vectors)
5136 pci_enable_msix(instance->pdev, instance->msixentry,
5137 instance->msix_vectors);
adam radford3f1abce2011-05-11 18:33:47 -07005138
adam radford9c915a82010-12-21 13:34:31 -08005139 switch (instance->pdev->device) {
5140 case PCI_DEVICE_ID_LSI_FUSION:
adam radford229fe472014-03-10 02:51:56 -07005141 case PCI_DEVICE_ID_LSI_PLASMA:
adam radford36807e62011-10-08 18:15:06 -07005142 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05305143 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08005144 {
5145 megasas_reset_reply_desc(instance);
5146 if (megasas_ioc_init_fusion(instance)) {
5147 megasas_free_cmds(instance);
5148 megasas_free_cmds_fusion(instance);
5149 goto fail_init_mfi;
5150 }
5151 if (!megasas_get_map_info(instance))
5152 megasas_sync_map_info(instance);
5153 }
5154 break;
5155 default:
5156 *instance->producer = 0;
5157 *instance->consumer = 0;
5158 if (megasas_issue_init_mfi(instance))
5159 goto fail_init_mfi;
5160 break;
5161 }
bo yang31ea7082007-11-07 12:09:50 -05005162
adam radford9c915a82010-12-21 13:34:31 -08005163 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
5164 (unsigned long)instance);
bo yang31ea7082007-11-07 12:09:50 -05005165
5166 /*
5167 * Register IRQ
5168 */
adam radfordc8e858f2011-10-08 18:15:13 -07005169 if (instance->msix_vectors) {
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305170 cpu = cpumask_first(cpu_online_mask);
adam radfordc8e858f2011-10-08 18:15:13 -07005171 for (i = 0 ; i < instance->msix_vectors; i++) {
5172 instance->irq_context[i].instance = instance;
5173 instance->irq_context[i].MSIxIndex = i;
5174 if (request_irq(instance->msixentry[i].vector,
5175 instance->instancet->service_isr, 0,
5176 "megasas",
5177 &instance->irq_context[i])) {
5178 printk(KERN_DEBUG "megasas: Failed to "
5179 "register IRQ for vector %d.\n", i);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305180 for (j = 0; j < i; j++) {
5181 irq_set_affinity_hint(
5182 instance->msixentry[j].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07005183 free_irq(
5184 instance->msixentry[j].vector,
5185 &instance->irq_context[j]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305186 }
adam radfordc8e858f2011-10-08 18:15:13 -07005187 goto fail_irq;
5188 }
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305189
5190 if (irq_set_affinity_hint(instance->msixentry[i].vector,
5191 get_cpu_mask(cpu)))
5192 dev_err(&instance->pdev->dev, "Error setting"
5193 "affinity hint for cpu %d\n", cpu);
5194 cpu = cpumask_next(cpu, cpu_online_mask);
adam radfordc8e858f2011-10-08 18:15:13 -07005195 }
5196 } else {
5197 instance->irq_context[0].instance = instance;
5198 instance->irq_context[0].MSIxIndex = 0;
5199 if (request_irq(pdev->irq, instance->instancet->service_isr,
5200 IRQF_SHARED, "megasas",
5201 &instance->irq_context[0])) {
5202 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
5203 goto fail_irq;
5204 }
bo yang31ea7082007-11-07 12:09:50 -05005205 }
5206
adam radford229fe472014-03-10 02:51:56 -07005207 /* Re-launch SR-IOV heartbeat timer */
5208 if (instance->requestorId) {
5209 if (!megasas_sriov_start_heartbeat(instance, 0))
5210 megasas_start_timer(instance,
5211 &instance->sriov_heartbeat_timer,
5212 megasas_sriov_heartbeat_handler,
5213 MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
5214 else
5215 instance->skip_heartbeat_timer_del = 1;
5216 }
5217
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305218 instance->instancet->enable_intr(instance);
Yang, Bo0c79e682009-10-06 14:47:35 -06005219 instance->unload = 0;
5220
adam radford541f90b2011-05-11 18:34:29 -07005221 /*
5222 * Initiate AEN (Asynchronous Event Notification)
5223 */
5224 if (megasas_start_aen(instance))
5225 printk(KERN_ERR "megasas: Start AEN failed\n");
5226
bo yang31ea7082007-11-07 12:09:50 -05005227 return 0;
5228
5229fail_irq:
5230fail_init_mfi:
5231 if (instance->evt_detail)
5232 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
5233 instance->evt_detail,
5234 instance->evt_detail_h);
5235
5236 if (instance->producer)
5237 pci_free_consistent(pdev, sizeof(u32), instance->producer,
5238 instance->producer_h);
5239 if (instance->consumer)
5240 pci_free_consistent(pdev, sizeof(u32), instance->consumer,
5241 instance->consumer_h);
5242 scsi_host_put(host);
5243
5244fail_set_dma_mask:
5245fail_ready_state:
5246
5247 pci_disable_device(pdev);
5248
5249 return -ENODEV;
5250}
Jiri Slaby33139b22008-05-01 17:56:02 +02005251#else
5252#define megasas_suspend NULL
5253#define megasas_resume NULL
5254#endif
bo yang31ea7082007-11-07 12:09:50 -05005255
5256/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005257 * megasas_detach_one - PCI hot"un"plug entry point
5258 * @pdev: PCI device structure
5259 */
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08005260static void megasas_detach_one(struct pci_dev *pdev)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005261{
5262 int i;
5263 struct Scsi_Host *host;
5264 struct megasas_instance *instance;
adam radford9c915a82010-12-21 13:34:31 -08005265 struct fusion_context *fusion;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005266
5267 instance = pci_get_drvdata(pdev);
Yang, Boc3518832009-10-06 14:18:02 -06005268 instance->unload = 1;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005269 host = instance->host;
adam radford9c915a82010-12-21 13:34:31 -08005270 fusion = instance->ctrl_context;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005271
adam radford229fe472014-03-10 02:51:56 -07005272 /* Shutdown SR-IOV heartbeat timer */
5273 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
5274 del_timer_sync(&instance->sriov_heartbeat_timer);
5275
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005276 scsi_remove_host(instance->host);
5277 megasas_flush_cache(instance);
bo yang31ea7082007-11-07 12:09:50 -05005278 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005279
5280 /* cancel the delayed work if this work still in queue*/
5281 if (instance->ev != NULL) {
5282 struct megasas_aen_event *ev = instance->ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08005283 cancel_delayed_work_sync(&ev->hotplug_work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005284 instance->ev = NULL;
5285 }
5286
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305287 /* cancel all wait events */
5288 wake_up_all(&instance->int_cmd_wait_q);
5289
Sumant Patro5d018ad2006-10-03 13:13:18 -07005290 tasklet_kill(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005291
5292 /*
5293 * Take the instance off the instance array. Note that we will not
5294 * decrement the max_index. We let this array be sparse array
5295 */
5296 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
5297 if (megasas_mgmt_info.instance[i] == instance) {
5298 megasas_mgmt_info.count--;
5299 megasas_mgmt_info.instance[i] = NULL;
5300
5301 break;
5302 }
5303 }
5304
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305305 instance->instancet->disable_intr(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005306
adam radfordc8e858f2011-10-08 18:15:13 -07005307 if (instance->msix_vectors)
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305308 for (i = 0; i < instance->msix_vectors; i++) {
5309 irq_set_affinity_hint(
5310 instance->msixentry[i].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07005311 free_irq(instance->msixentry[i].vector,
5312 &instance->irq_context[i]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305313 }
adam radfordc8e858f2011-10-08 18:15:13 -07005314 else
5315 free_irq(instance->pdev->irq, &instance->irq_context[0]);
5316 if (instance->msix_vectors)
adam radford80d9da92010-12-21 10:17:40 -08005317 pci_disable_msix(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005318
adam radford9c915a82010-12-21 13:34:31 -08005319 switch (instance->pdev->device) {
5320 case PCI_DEVICE_ID_LSI_FUSION:
adam radford229fe472014-03-10 02:51:56 -07005321 case PCI_DEVICE_ID_LSI_PLASMA:
adam radford36807e62011-10-08 18:15:06 -07005322 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05305323 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08005324 megasas_release_fusion(instance);
5325 for (i = 0; i < 2 ; i++)
5326 if (fusion->ld_map[i])
5327 dma_free_coherent(&instance->pdev->dev,
5328 fusion->map_sz,
5329 fusion->ld_map[i],
5330 fusion->
5331 ld_map_phys[i]);
5332 kfree(instance->ctrl_context);
5333 break;
5334 default:
5335 megasas_release_mfi(instance);
adam radford9c915a82010-12-21 13:34:31 -08005336 pci_free_consistent(pdev, sizeof(u32),
5337 instance->producer,
5338 instance->producer_h);
5339 pci_free_consistent(pdev, sizeof(u32),
5340 instance->consumer,
5341 instance->consumer_h);
5342 break;
5343 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005344
Sumit.Saxena@lsi.com105900d2013-05-22 12:30:54 +05305345 if (instance->evt_detail)
5346 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
5347 instance->evt_detail, instance->evt_detail_h);
adam radford229fe472014-03-10 02:51:56 -07005348
5349 if (instance->vf_affiliation)
5350 pci_free_consistent(pdev, (MAX_LOGICAL_DRIVES + 1) *
5351 sizeof(struct MR_LD_VF_AFFILIATION),
5352 instance->vf_affiliation,
5353 instance->vf_affiliation_h);
5354
5355 if (instance->vf_affiliation_111)
5356 pci_free_consistent(pdev,
5357 sizeof(struct MR_LD_VF_AFFILIATION_111),
5358 instance->vf_affiliation_111,
5359 instance->vf_affiliation_111_h);
5360
5361 if (instance->hb_host_mem)
5362 pci_free_consistent(pdev, sizeof(struct MR_CTRL_HB_HOST_MEM),
5363 instance->hb_host_mem,
5364 instance->hb_host_mem_h);
5365
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005366 scsi_host_put(host);
5367
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005368 pci_disable_device(pdev);
5369
5370 return;
5371}
5372
5373/**
5374 * megasas_shutdown - Shutdown entry point
5375 * @device: Generic device structure
5376 */
5377static void megasas_shutdown(struct pci_dev *pdev)
5378{
adam radfordc8e858f2011-10-08 18:15:13 -07005379 int i;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005380 struct megasas_instance *instance = pci_get_drvdata(pdev);
adam radfordc8e858f2011-10-08 18:15:13 -07005381
Yang, Bo0c79e682009-10-06 14:47:35 -06005382 instance->unload = 1;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005383 megasas_flush_cache(instance);
Yang, Bo530e6fc2008-08-10 12:42:37 -07005384 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305385 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07005386 if (instance->msix_vectors)
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305387 for (i = 0; i < instance->msix_vectors; i++) {
5388 irq_set_affinity_hint(
5389 instance->msixentry[i].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07005390 free_irq(instance->msixentry[i].vector,
5391 &instance->irq_context[i]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305392 }
adam radfordc8e858f2011-10-08 18:15:13 -07005393 else
5394 free_irq(instance->pdev->irq, &instance->irq_context[0]);
5395 if (instance->msix_vectors)
adam radford46fd2562011-05-11 18:34:17 -07005396 pci_disable_msix(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005397}
5398
5399/**
5400 * megasas_mgmt_open - char node "open" entry point
5401 */
5402static int megasas_mgmt_open(struct inode *inode, struct file *filep)
5403{
5404 /*
5405 * Allow only those users with admin rights
5406 */
5407 if (!capable(CAP_SYS_ADMIN))
5408 return -EACCES;
5409
5410 return 0;
5411}
5412
5413/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005414 * megasas_mgmt_fasync - Async notifier registration from applications
5415 *
5416 * This function adds the calling process to a driver global queue. When an
5417 * event occurs, SIGIO will be sent to all processes in this queue.
5418 */
5419static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
5420{
5421 int rc;
5422
Arjan van de Ven0b950672006-01-11 13:16:10 +01005423 mutex_lock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005424
5425 rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
5426
Arjan van de Ven0b950672006-01-11 13:16:10 +01005427 mutex_unlock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005428
5429 if (rc >= 0) {
5430 /* For sanity check when we get ioctl */
5431 filep->private_data = filep;
5432 return 0;
5433 }
5434
5435 printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc);
5436
5437 return rc;
5438}
5439
5440/**
Yang, Boc3518832009-10-06 14:18:02 -06005441 * megasas_mgmt_poll - char node "poll" entry point
5442 * */
5443static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
5444{
5445 unsigned int mask;
5446 unsigned long flags;
5447 poll_wait(file, &megasas_poll_wait, wait);
5448 spin_lock_irqsave(&poll_aen_lock, flags);
5449 if (megasas_poll_wait_aen)
5450 mask = (POLLIN | POLLRDNORM);
5451 else
5452 mask = 0;
5453 spin_unlock_irqrestore(&poll_aen_lock, flags);
5454 return mask;
5455}
5456
5457/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005458 * megasas_mgmt_fw_ioctl - Issues management ioctls to FW
5459 * @instance: Adapter soft state
5460 * @argp: User's ioctl packet
5461 */
5462static int
5463megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
5464 struct megasas_iocpacket __user * user_ioc,
5465 struct megasas_iocpacket *ioc)
5466{
5467 struct megasas_sge32 *kern_sge32;
5468 struct megasas_cmd *cmd;
5469 void *kbuff_arr[MAX_IOCTL_SGE];
5470 dma_addr_t buf_handle = 0;
5471 int error = 0, i;
5472 void *sense = NULL;
5473 dma_addr_t sense_handle;
Yang, Bo7b2519a2009-10-06 14:52:20 -06005474 unsigned long *sense_ptr;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005475
5476 memset(kbuff_arr, 0, sizeof(kbuff_arr));
5477
5478 if (ioc->sge_count > MAX_IOCTL_SGE) {
5479 printk(KERN_DEBUG "megasas: SGE count [%d] > max limit [%d]\n",
5480 ioc->sge_count, MAX_IOCTL_SGE);
5481 return -EINVAL;
5482 }
5483
5484 cmd = megasas_get_cmd(instance);
5485 if (!cmd) {
5486 printk(KERN_DEBUG "megasas: Failed to get a cmd packet\n");
5487 return -ENOMEM;
5488 }
5489
5490 /*
5491 * User's IOCTL packet has 2 frames (maximum). Copy those two
5492 * frames into our cmd's frames. cmd->frame's context will get
5493 * overwritten when we copy from user's frames. So set that value
5494 * alone separately
5495 */
5496 memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305497 cmd->frame->hdr.context = cpu_to_le32(cmd->index);
Yang, Boc3518832009-10-06 14:18:02 -06005498 cmd->frame->hdr.pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305499 cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_IEEE |
5500 MFI_FRAME_SGL64 |
5501 MFI_FRAME_SENSE64));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005502
5503 /*
5504 * The management interface between applications and the fw uses
5505 * MFI frames. E.g, RAID configuration changes, LD property changes
5506 * etc are accomplishes through different kinds of MFI frames. The
5507 * driver needs to care only about substituting user buffers with
5508 * kernel buffers in SGLs. The location of SGL is embedded in the
5509 * struct iocpacket itself.
5510 */
5511 kern_sge32 = (struct megasas_sge32 *)
5512 ((unsigned long)cmd->frame + ioc->sgl_off);
5513
5514 /*
5515 * For each user buffer, create a mirror buffer and copy in
5516 */
5517 for (i = 0; i < ioc->sge_count; i++) {
Bjørn Mork98cb7e42011-01-19 10:01:14 +01005518 if (!ioc->sgl[i].iov_len)
5519 continue;
5520
Sumant Patro9f35fa82007-02-14 12:55:45 -08005521 kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005522 ioc->sgl[i].iov_len,
Sumant Patro9f35fa82007-02-14 12:55:45 -08005523 &buf_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005524 if (!kbuff_arr[i]) {
5525 printk(KERN_DEBUG "megasas: Failed to alloc "
5526 "kernel SGL buffer for IOCTL \n");
5527 error = -ENOMEM;
5528 goto out;
5529 }
5530
5531 /*
5532 * We don't change the dma_coherent_mask, so
5533 * pci_alloc_consistent only returns 32bit addresses
5534 */
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305535 kern_sge32[i].phys_addr = cpu_to_le32(buf_handle);
5536 kern_sge32[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005537
5538 /*
5539 * We created a kernel buffer corresponding to the
5540 * user buffer. Now copy in from the user buffer
5541 */
5542 if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base,
5543 (u32) (ioc->sgl[i].iov_len))) {
5544 error = -EFAULT;
5545 goto out;
5546 }
5547 }
5548
5549 if (ioc->sense_len) {
Sumant Patro9f35fa82007-02-14 12:55:45 -08005550 sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,
5551 &sense_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005552 if (!sense) {
5553 error = -ENOMEM;
5554 goto out;
5555 }
5556
5557 sense_ptr =
Yang, Bo7b2519a2009-10-06 14:52:20 -06005558 (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305559 *sense_ptr = cpu_to_le32(sense_handle);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005560 }
5561
5562 /*
5563 * Set the sync_cmd flag so that the ISR knows not to complete this
5564 * cmd to the SCSI mid-layer
5565 */
5566 cmd->sync_cmd = 1;
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305567 megasas_issue_blocked_cmd(instance, cmd, 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005568 cmd->sync_cmd = 0;
5569
5570 /*
5571 * copy out the kernel buffers to user buffers
5572 */
5573 for (i = 0; i < ioc->sge_count; i++) {
5574 if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i],
5575 ioc->sgl[i].iov_len)) {
5576 error = -EFAULT;
5577 goto out;
5578 }
5579 }
5580
5581 /*
5582 * copy out the sense
5583 */
5584 if (ioc->sense_len) {
5585 /*
bo yangb70a41e2008-03-18 03:13:06 -04005586 * sense_ptr points to the location that has the user
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005587 * sense buffer address
5588 */
Yang, Bo7b2519a2009-10-06 14:52:20 -06005589 sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
5590 ioc->sense_off);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005591
bo yangb70a41e2008-03-18 03:13:06 -04005592 if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
5593 sense, ioc->sense_len)) {
bo yangb10c36a2007-11-09 04:28:47 -05005594 printk(KERN_ERR "megasas: Failed to copy out to user "
5595 "sense data\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005596 error = -EFAULT;
5597 goto out;
5598 }
5599 }
5600
5601 /*
5602 * copy the status codes returned by the fw
5603 */
5604 if (copy_to_user(&user_ioc->frame.hdr.cmd_status,
5605 &cmd->frame->hdr.cmd_status, sizeof(u8))) {
5606 printk(KERN_DEBUG "megasas: Error copying out cmd_status\n");
5607 error = -EFAULT;
5608 }
5609
5610 out:
5611 if (sense) {
Sumant Patro9f35fa82007-02-14 12:55:45 -08005612 dma_free_coherent(&instance->pdev->dev, ioc->sense_len,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005613 sense, sense_handle);
5614 }
5615
Bjørn Mork7a6a7312012-11-21 09:54:48 +01005616 for (i = 0; i < ioc->sge_count; i++) {
5617 if (kbuff_arr[i])
5618 dma_free_coherent(&instance->pdev->dev,
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305619 le32_to_cpu(kern_sge32[i].length),
Bjørn Mork7a6a7312012-11-21 09:54:48 +01005620 kbuff_arr[i],
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305621 le32_to_cpu(kern_sge32[i].phys_addr));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005622 }
5623
5624 megasas_return_cmd(instance, cmd);
5625 return error;
5626}
5627
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005628static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
5629{
5630 struct megasas_iocpacket __user *user_ioc =
5631 (struct megasas_iocpacket __user *)arg;
5632 struct megasas_iocpacket *ioc;
5633 struct megasas_instance *instance;
5634 int error;
bo yang39a98552010-09-22 22:36:29 -04005635 int i;
5636 unsigned long flags;
5637 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005638
5639 ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
5640 if (!ioc)
5641 return -ENOMEM;
5642
5643 if (copy_from_user(ioc, user_ioc, sizeof(*ioc))) {
5644 error = -EFAULT;
5645 goto out_kfree_ioc;
5646 }
5647
5648 instance = megasas_lookup_instance(ioc->host_no);
5649 if (!instance) {
5650 error = -ENODEV;
5651 goto out_kfree_ioc;
5652 }
5653
adam radford229fe472014-03-10 02:51:56 -07005654 /* Adjust ioctl wait time for VF mode */
5655 if (instance->requestorId)
5656 wait_time = MEGASAS_ROUTINE_WAIT_TIME_VF;
5657
5658 /* Block ioctls in VF mode */
5659 if (instance->requestorId && !allow_vf_ioctls) {
5660 error = -ENODEV;
5661 goto out_kfree_ioc;
5662 }
5663
bo yang39a98552010-09-22 22:36:29 -04005664 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
5665 printk(KERN_ERR "Controller in crit error\n");
Yang, Bo0c79e682009-10-06 14:47:35 -06005666 error = -ENODEV;
5667 goto out_kfree_ioc;
5668 }
5669
5670 if (instance->unload == 1) {
5671 error = -ENODEV;
5672 goto out_kfree_ioc;
5673 }
5674
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005675 /*
5676 * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
5677 */
5678 if (down_interruptible(&instance->ioctl_sem)) {
5679 error = -ERESTARTSYS;
5680 goto out_kfree_ioc;
5681 }
bo yang39a98552010-09-22 22:36:29 -04005682
5683 for (i = 0; i < wait_time; i++) {
5684
5685 spin_lock_irqsave(&instance->hba_lock, flags);
5686 if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
5687 spin_unlock_irqrestore(&instance->hba_lock, flags);
5688 break;
5689 }
5690 spin_unlock_irqrestore(&instance->hba_lock, flags);
5691
5692 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
5693 printk(KERN_NOTICE "megasas: waiting"
5694 "for controller reset to finish\n");
5695 }
5696
5697 msleep(1000);
5698 }
5699
5700 spin_lock_irqsave(&instance->hba_lock, flags);
5701 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
5702 spin_unlock_irqrestore(&instance->hba_lock, flags);
5703
5704 printk(KERN_ERR "megaraid_sas: timed out while"
5705 "waiting for HBA to recover\n");
5706 error = -ENODEV;
Dan Carpenterc64e4832013-04-16 10:44:19 +03005707 goto out_up;
bo yang39a98552010-09-22 22:36:29 -04005708 }
5709 spin_unlock_irqrestore(&instance->hba_lock, flags);
5710
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005711 error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
Dan Carpenterc64e4832013-04-16 10:44:19 +03005712 out_up:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005713 up(&instance->ioctl_sem);
5714
5715 out_kfree_ioc:
5716 kfree(ioc);
5717 return error;
5718}
5719
5720static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
5721{
5722 struct megasas_instance *instance;
5723 struct megasas_aen aen;
5724 int error;
bo yang39a98552010-09-22 22:36:29 -04005725 int i;
5726 unsigned long flags;
5727 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005728
5729 if (file->private_data != file) {
5730 printk(KERN_DEBUG "megasas: fasync_helper was not "
5731 "called first\n");
5732 return -EINVAL;
5733 }
5734
5735 if (copy_from_user(&aen, (void __user *)arg, sizeof(aen)))
5736 return -EFAULT;
5737
5738 instance = megasas_lookup_instance(aen.host_no);
5739
5740 if (!instance)
5741 return -ENODEV;
5742
bo yang39a98552010-09-22 22:36:29 -04005743 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
5744 return -ENODEV;
Yang, Bo0c79e682009-10-06 14:47:35 -06005745 }
5746
5747 if (instance->unload == 1) {
5748 return -ENODEV;
5749 }
5750
bo yang39a98552010-09-22 22:36:29 -04005751 for (i = 0; i < wait_time; i++) {
5752
5753 spin_lock_irqsave(&instance->hba_lock, flags);
5754 if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
5755 spin_unlock_irqrestore(&instance->hba_lock,
5756 flags);
5757 break;
5758 }
5759
5760 spin_unlock_irqrestore(&instance->hba_lock, flags);
5761
5762 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
5763 printk(KERN_NOTICE "megasas: waiting for"
5764 "controller reset to finish\n");
5765 }
5766
5767 msleep(1000);
5768 }
5769
5770 spin_lock_irqsave(&instance->hba_lock, flags);
5771 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
5772 spin_unlock_irqrestore(&instance->hba_lock, flags);
5773 printk(KERN_ERR "megaraid_sas: timed out while waiting"
5774 "for HBA to recover.\n");
5775 return -ENODEV;
5776 }
5777 spin_unlock_irqrestore(&instance->hba_lock, flags);
5778
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02005779 mutex_lock(&instance->aen_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005780 error = megasas_register_aen(instance, aen.seq_num,
5781 aen.class_locale_word);
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02005782 mutex_unlock(&instance->aen_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005783 return error;
5784}
5785
5786/**
5787 * megasas_mgmt_ioctl - char node ioctl entry point
5788 */
5789static long
5790megasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
5791{
5792 switch (cmd) {
5793 case MEGASAS_IOC_FIRMWARE:
5794 return megasas_mgmt_ioctl_fw(file, arg);
5795
5796 case MEGASAS_IOC_GET_AEN:
5797 return megasas_mgmt_ioctl_aen(file, arg);
5798 }
5799
5800 return -ENOTTY;
5801}
5802
5803#ifdef CONFIG_COMPAT
5804static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
5805{
5806 struct compat_megasas_iocpacket __user *cioc =
5807 (struct compat_megasas_iocpacket __user *)arg;
5808 struct megasas_iocpacket __user *ioc =
5809 compat_alloc_user_space(sizeof(struct megasas_iocpacket));
5810 int i;
5811 int error = 0;
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01005812 compat_uptr_t ptr;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005813
Jeff Garzik83aabc12006-10-04 06:34:03 -04005814 if (clear_user(ioc, sizeof(*ioc)))
5815 return -EFAULT;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005816
5817 if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) ||
5818 copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) ||
5819 copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) ||
5820 copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) ||
5821 copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) ||
5822 copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
5823 return -EFAULT;
5824
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01005825 /*
5826 * The sense_ptr is used in megasas_mgmt_fw_ioctl only when
5827 * sense_len is not null, so prepare the 64bit value under
5828 * the same condition.
5829 */
5830 if (ioc->sense_len) {
5831 void __user **sense_ioc_ptr =
5832 (void __user **)(ioc->frame.raw + ioc->sense_off);
5833 compat_uptr_t *sense_cioc_ptr =
5834 (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
5835 if (get_user(ptr, sense_cioc_ptr) ||
5836 put_user(compat_ptr(ptr), sense_ioc_ptr))
5837 return -EFAULT;
5838 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005839
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01005840 for (i = 0; i < MAX_IOCTL_SGE; i++) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005841 if (get_user(ptr, &cioc->sgl[i].iov_base) ||
5842 put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
5843 copy_in_user(&ioc->sgl[i].iov_len,
5844 &cioc->sgl[i].iov_len, sizeof(compat_size_t)))
5845 return -EFAULT;
5846 }
5847
5848 error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc);
5849
5850 if (copy_in_user(&cioc->frame.hdr.cmd_status,
5851 &ioc->frame.hdr.cmd_status, sizeof(u8))) {
5852 printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n");
5853 return -EFAULT;
5854 }
5855 return error;
5856}
5857
5858static long
5859megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd,
5860 unsigned long arg)
5861{
5862 switch (cmd) {
Sumant Patrocb59aa62006-01-25 11:53:25 -08005863 case MEGASAS_IOC_FIRMWARE32:
5864 return megasas_mgmt_compat_ioctl_fw(file, arg);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005865 case MEGASAS_IOC_GET_AEN:
5866 return megasas_mgmt_ioctl_aen(file, arg);
5867 }
5868
5869 return -ENOTTY;
5870}
5871#endif
5872
5873/*
5874 * File operations structure for management interface
5875 */
Arjan van de Ven00977a52007-02-12 00:55:34 -08005876static const struct file_operations megasas_mgmt_fops = {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005877 .owner = THIS_MODULE,
5878 .open = megasas_mgmt_open,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005879 .fasync = megasas_mgmt_fasync,
5880 .unlocked_ioctl = megasas_mgmt_ioctl,
Yang, Boc3518832009-10-06 14:18:02 -06005881 .poll = megasas_mgmt_poll,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005882#ifdef CONFIG_COMPAT
5883 .compat_ioctl = megasas_mgmt_compat_ioctl,
5884#endif
Arnd Bergmann6038f372010-08-15 18:52:59 +02005885 .llseek = noop_llseek,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005886};
5887
5888/*
5889 * PCI hotplug support registration structure
5890 */
5891static struct pci_driver megasas_pci_driver = {
5892
5893 .name = "megaraid_sas",
5894 .id_table = megasas_pci_table,
5895 .probe = megasas_probe_one,
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08005896 .remove = megasas_detach_one,
bo yang31ea7082007-11-07 12:09:50 -05005897 .suspend = megasas_suspend,
5898 .resume = megasas_resume,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005899 .shutdown = megasas_shutdown,
5900};
5901
5902/*
5903 * Sysfs driver attributes
5904 */
5905static ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf)
5906{
5907 return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n",
5908 MEGASAS_VERSION);
5909}
5910
5911static DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL);
5912
5913static ssize_t
5914megasas_sysfs_show_release_date(struct device_driver *dd, char *buf)
5915{
5916 return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n",
5917 MEGASAS_RELDATE);
5918}
5919
5920static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
5921 NULL);
5922
Sumant Patro658dced2006-10-03 13:09:14 -07005923static ssize_t
Yang, Bo72c4fd32009-10-06 14:20:59 -06005924megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
5925{
5926 return sprintf(buf, "%u\n", support_poll_for_event);
5927}
5928
5929static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
5930 megasas_sysfs_show_support_poll_for_event, NULL);
5931
Yang, Bo837f5fe2010-10-11 06:59:20 -06005932 static ssize_t
5933megasas_sysfs_show_support_device_change(struct device_driver *dd, char *buf)
5934{
5935 return sprintf(buf, "%u\n", support_device_change);
5936}
5937
5938static DRIVER_ATTR(support_device_change, S_IRUGO,
5939 megasas_sysfs_show_support_device_change, NULL);
5940
Yang, Bo72c4fd32009-10-06 14:20:59 -06005941static ssize_t
Sumant Patro658dced2006-10-03 13:09:14 -07005942megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
5943{
bo yangad84db22007-11-09 04:40:16 -05005944 return sprintf(buf, "%u\n", megasas_dbg_lvl);
Sumant Patro658dced2006-10-03 13:09:14 -07005945}
5946
5947static ssize_t
5948megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count)
5949{
5950 int retval = count;
5951 if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){
5952 printk(KERN_ERR "megasas: could not set dbg_lvl\n");
5953 retval = -EINVAL;
5954 }
5955 return retval;
5956}
5957
Joe Malicki66dca9b2008-08-14 17:14:48 -04005958static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl,
bo yangad84db22007-11-09 04:40:16 -05005959 megasas_sysfs_set_dbg_lvl);
5960
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005961static void
5962megasas_aen_polling(struct work_struct *work)
5963{
5964 struct megasas_aen_event *ev =
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08005965 container_of(work, struct megasas_aen_event, hotplug_work.work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005966 struct megasas_instance *instance = ev->instance;
5967 union megasas_evt_class_locale class_locale;
5968 struct Scsi_Host *host;
5969 struct scsi_device *sdev1;
5970 u16 pd_index = 0;
Yang, Boc9786842009-12-06 08:39:25 -07005971 u16 ld_index = 0;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005972 int i, j, doscan = 0;
adam radford229fe472014-03-10 02:51:56 -07005973 u32 seq_num, wait_time = MEGASAS_RESET_WAIT_TIME;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005974 int error;
5975
5976 if (!instance) {
5977 printk(KERN_ERR "invalid instance!\n");
5978 kfree(ev);
5979 return;
5980 }
adam radford229fe472014-03-10 02:51:56 -07005981
5982 /* Adjust event workqueue thread wait time for VF mode */
5983 if (instance->requestorId)
5984 wait_time = MEGASAS_ROUTINE_WAIT_TIME_VF;
5985
5986 /* Don't run the event workqueue thread if OCR is running */
5987 for (i = 0; i < wait_time; i++) {
5988 if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL)
5989 break;
5990 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
5991 printk(KERN_NOTICE "megasas: %s waiting for "
5992 "controller reset to finish for scsi%d\n",
5993 __func__, instance->host->host_no);
5994 }
5995 msleep(1000);
5996 }
5997
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005998 instance->ev = NULL;
5999 host = instance->host;
6000 if (instance->evt_detail) {
6001
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306002 switch (le32_to_cpu(instance->evt_detail->code)) {
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006003 case MR_EVT_PD_INSERTED:
Yang, Boc9786842009-12-06 08:39:25 -07006004 if (megasas_get_pd_list(instance) == 0) {
6005 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
6006 for (j = 0;
6007 j < MEGASAS_MAX_DEV_PER_CHANNEL;
6008 j++) {
6009
6010 pd_index =
6011 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
6012
6013 sdev1 =
6014 scsi_device_lookup(host, i, j, 0);
6015
6016 if (instance->pd_list[pd_index].driveState
6017 == MR_PD_STATE_SYSTEM) {
6018 if (!sdev1) {
6019 scsi_add_device(host, i, j, 0);
6020 }
6021
6022 if (sdev1)
6023 scsi_device_put(sdev1);
6024 }
6025 }
6026 }
6027 }
6028 doscan = 0;
6029 break;
6030
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006031 case MR_EVT_PD_REMOVED:
Yang, Boc9786842009-12-06 08:39:25 -07006032 if (megasas_get_pd_list(instance) == 0) {
Yang, Boc9786842009-12-06 08:39:25 -07006033 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
6034 for (j = 0;
6035 j < MEGASAS_MAX_DEV_PER_CHANNEL;
6036 j++) {
6037
6038 pd_index =
6039 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
6040
6041 sdev1 =
6042 scsi_device_lookup(host, i, j, 0);
6043
6044 if (instance->pd_list[pd_index].driveState
6045 == MR_PD_STATE_SYSTEM) {
6046 if (sdev1) {
6047 scsi_device_put(sdev1);
6048 }
6049 } else {
6050 if (sdev1) {
6051 scsi_remove_device(sdev1);
6052 scsi_device_put(sdev1);
6053 }
6054 }
6055 }
6056 }
6057 }
6058 doscan = 0;
6059 break;
6060
6061 case MR_EVT_LD_OFFLINE:
adam radford4c598b22011-02-24 20:56:53 -08006062 case MR_EVT_CFG_CLEARED:
Yang, Boc9786842009-12-06 08:39:25 -07006063 case MR_EVT_LD_DELETED:
adam radford229fe472014-03-10 02:51:56 -07006064 if (!instance->requestorId ||
6065 (instance->requestorId &&
6066 megasas_get_ld_vf_affiliation(instance, 0))) {
6067 if (megasas_ld_list_query(instance,
6068 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
6069 megasas_get_ld_list(instance);
6070 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
6071 for (j = 0;
6072 j < MEGASAS_MAX_DEV_PER_CHANNEL;
6073 j++) {
Yang, Boc9786842009-12-06 08:39:25 -07006074
adam radford229fe472014-03-10 02:51:56 -07006075 ld_index =
6076 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
Yang, Boc9786842009-12-06 08:39:25 -07006077
adam radford229fe472014-03-10 02:51:56 -07006078 sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
Yang, Boc9786842009-12-06 08:39:25 -07006079
adam radford229fe472014-03-10 02:51:56 -07006080 if (instance->ld_ids[ld_index]
6081 != 0xff) {
6082 if (sdev1)
6083 scsi_device_put(sdev1);
6084 } else {
6085 if (sdev1) {
6086 scsi_remove_device(sdev1);
6087 scsi_device_put(sdev1);
6088 }
Yang, Boc9786842009-12-06 08:39:25 -07006089 }
6090 }
adam radford229fe472014-03-10 02:51:56 -07006091 }
6092 doscan = 0;
6093 }
6094 break;
6095 case MR_EVT_LD_CREATED:
6096 if (!instance->requestorId ||
6097 (instance->requestorId &&
6098 megasas_get_ld_vf_affiliation(instance, 0))) {
6099 if (megasas_ld_list_query(instance,
6100 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
6101 megasas_get_ld_list(instance);
6102 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
6103 for (j = 0;
6104 j < MEGASAS_MAX_DEV_PER_CHANNEL;
6105 j++) {
6106 ld_index =
6107 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
6108
6109 sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
6110
6111 if (instance->ld_ids[ld_index]
6112 != 0xff) {
6113 if (!sdev1)
6114 scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
6115 }
6116 if (sdev1)
6117 scsi_device_put(sdev1);
Yang, Boc9786842009-12-06 08:39:25 -07006118 }
6119 }
adam radford229fe472014-03-10 02:51:56 -07006120 doscan = 0;
Yang, Boc9786842009-12-06 08:39:25 -07006121 }
Yang, Boc9786842009-12-06 08:39:25 -07006122 break;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006123 case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
Yang, Boc9786842009-12-06 08:39:25 -07006124 case MR_EVT_FOREIGN_CFG_IMPORTED:
adam radford9c915a82010-12-21 13:34:31 -08006125 case MR_EVT_LD_STATE_CHANGE:
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006126 doscan = 1;
6127 break;
6128 default:
6129 doscan = 0;
6130 break;
6131 }
6132 } else {
6133 printk(KERN_ERR "invalid evt_detail!\n");
6134 kfree(ev);
6135 return;
6136 }
6137
6138 if (doscan) {
adam radford229fe472014-03-10 02:51:56 -07006139 printk(KERN_INFO "megaraid_sas: scanning for scsi%d...\n",
6140 instance->host->host_no);
Hannes Reinecke58968fc2014-01-16 11:25:36 +01006141 if (megasas_get_pd_list(instance) == 0) {
6142 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
6143 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
6144 pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
6145 sdev1 = scsi_device_lookup(host, i, j, 0);
6146 if (instance->pd_list[pd_index].driveState ==
6147 MR_PD_STATE_SYSTEM) {
6148 if (!sdev1) {
6149 scsi_add_device(host, i, j, 0);
6150 }
6151 if (sdev1)
6152 scsi_device_put(sdev1);
6153 } else {
6154 if (sdev1) {
6155 scsi_remove_device(sdev1);
6156 scsi_device_put(sdev1);
6157 }
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006158 }
6159 }
6160 }
6161 }
Yang, Boc9786842009-12-06 08:39:25 -07006162
adam radford229fe472014-03-10 02:51:56 -07006163 if (!instance->requestorId ||
6164 (instance->requestorId &&
6165 megasas_get_ld_vf_affiliation(instance, 0))) {
6166 if (megasas_ld_list_query(instance,
6167 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
6168 megasas_get_ld_list(instance);
6169 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
6170 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL;
6171 j++) {
6172 ld_index =
6173 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
Yang, Boc9786842009-12-06 08:39:25 -07006174
adam radford229fe472014-03-10 02:51:56 -07006175 sdev1 = scsi_device_lookup(host,
6176 MEGASAS_MAX_PD_CHANNELS + i, j, 0);
6177 if (instance->ld_ids[ld_index]
6178 != 0xff) {
6179 if (!sdev1)
6180 scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
6181 else
6182 scsi_device_put(sdev1);
Yang, Boc9786842009-12-06 08:39:25 -07006183 } else {
adam radford229fe472014-03-10 02:51:56 -07006184 if (sdev1) {
6185 scsi_remove_device(sdev1);
6186 scsi_device_put(sdev1);
6187 }
Yang, Boc9786842009-12-06 08:39:25 -07006188 }
6189 }
6190 }
6191 }
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006192 }
6193
6194 if ( instance->aen_cmd != NULL ) {
6195 kfree(ev);
6196 return ;
6197 }
6198
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306199 seq_num = le32_to_cpu(instance->evt_detail->seq_num) + 1;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006200
6201 /* Register AEN with FW for latest sequence number plus 1 */
6202 class_locale.members.reserved = 0;
6203 class_locale.members.locale = MR_EVT_LOCALE_ALL;
6204 class_locale.members.class = MR_EVT_CLASS_DEBUG;
6205 mutex_lock(&instance->aen_mutex);
6206 error = megasas_register_aen(instance, seq_num,
6207 class_locale.word);
6208 mutex_unlock(&instance->aen_mutex);
6209
6210 if (error)
6211 printk(KERN_ERR "register aen failed error %x\n", error);
6212
6213 kfree(ev);
6214}
6215
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006216/**
6217 * megasas_init - Driver load entry point
6218 */
6219static int __init megasas_init(void)
6220{
6221 int rval;
6222
6223 /*
6224 * Announce driver version and other information
6225 */
6226 printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
6227 MEGASAS_EXT_VERSION);
6228
Kashyap Desaibd8d6dd2012-07-17 18:20:44 -07006229 spin_lock_init(&poll_aen_lock);
6230
Yang, Bo72c4fd32009-10-06 14:20:59 -06006231 support_poll_for_event = 2;
Yang, Bo837f5fe2010-10-11 06:59:20 -06006232 support_device_change = 1;
Yang, Bo72c4fd32009-10-06 14:20:59 -06006233
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006234 memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
6235
6236 /*
6237 * Register character device node
6238 */
6239 rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops);
6240
6241 if (rval < 0) {
6242 printk(KERN_DEBUG "megasas: failed to open device node\n");
6243 return rval;
6244 }
6245
6246 megasas_mgmt_majorno = rval;
6247
6248 /*
6249 * Register ourselves as PCI hotplug module
6250 */
Michal Piotrowski4041b9c2006-08-17 13:28:22 +00006251 rval = pci_register_driver(&megasas_pci_driver);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006252
6253 if (rval) {
6254 printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n");
Jeff Garzik83aabc12006-10-04 06:34:03 -04006255 goto err_pcidrv;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006256 }
6257
Jeff Garzik83aabc12006-10-04 06:34:03 -04006258 rval = driver_create_file(&megasas_pci_driver.driver,
6259 &driver_attr_version);
6260 if (rval)
6261 goto err_dcf_attr_ver;
6262 rval = driver_create_file(&megasas_pci_driver.driver,
6263 &driver_attr_release_date);
6264 if (rval)
6265 goto err_dcf_rel_date;
Yang, Bo72c4fd32009-10-06 14:20:59 -06006266
6267 rval = driver_create_file(&megasas_pci_driver.driver,
6268 &driver_attr_support_poll_for_event);
6269 if (rval)
6270 goto err_dcf_support_poll_for_event;
6271
Jeff Garzik83aabc12006-10-04 06:34:03 -04006272 rval = driver_create_file(&megasas_pci_driver.driver,
6273 &driver_attr_dbg_lvl);
6274 if (rval)
6275 goto err_dcf_dbg_lvl;
bo yangad84db22007-11-09 04:40:16 -05006276 rval = driver_create_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06006277 &driver_attr_support_device_change);
6278 if (rval)
6279 goto err_dcf_support_device_change;
6280
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006281 return rval;
bo yangad84db22007-11-09 04:40:16 -05006282
Yang, Bo837f5fe2010-10-11 06:59:20 -06006283err_dcf_support_device_change:
6284 driver_remove_file(&megasas_pci_driver.driver,
bo yangad84db22007-11-09 04:40:16 -05006285 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04006286err_dcf_dbg_lvl:
6287 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo72c4fd32009-10-06 14:20:59 -06006288 &driver_attr_support_poll_for_event);
6289
6290err_dcf_support_poll_for_event:
6291 driver_remove_file(&megasas_pci_driver.driver,
Jeff Garzik83aabc12006-10-04 06:34:03 -04006292 &driver_attr_release_date);
Yang, Bo72c4fd32009-10-06 14:20:59 -06006293
Jeff Garzik83aabc12006-10-04 06:34:03 -04006294err_dcf_rel_date:
6295 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
6296err_dcf_attr_ver:
6297 pci_unregister_driver(&megasas_pci_driver);
6298err_pcidrv:
6299 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
adam radford0d490162010-12-14 19:17:17 -08006300 return rval;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006301}
6302
6303/**
6304 * megasas_exit - Driver unload entry point
6305 */
6306static void __exit megasas_exit(void)
6307{
Sumant Patro658dced2006-10-03 13:09:14 -07006308 driver_remove_file(&megasas_pci_driver.driver,
6309 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04006310 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06006311 &driver_attr_support_poll_for_event);
6312 driver_remove_file(&megasas_pci_driver.driver,
6313 &driver_attr_support_device_change);
6314 driver_remove_file(&megasas_pci_driver.driver,
Jeff Garzik83aabc12006-10-04 06:34:03 -04006315 &driver_attr_release_date);
6316 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006317
6318 pci_unregister_driver(&megasas_pci_driver);
6319 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
6320}
6321
6322module_init(megasas_init);
6323module_exit(megasas_exit);