blob: 24e4116d2f4b0358649b12d3db2706109d7531b7 [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 Radford4cbfea82014-07-09 15:17:56 -07001828static int megasas_get_ld_vf_affiliation_111(struct megasas_instance *instance,
1829 int initial)
adam radford229fe472014-03-10 02:51:56 -07001830{
1831 struct megasas_cmd *cmd;
1832 struct megasas_dcmd_frame *dcmd;
adam radford229fe472014-03-10 02:51:56 -07001833 struct MR_LD_VF_AFFILIATION_111 *new_affiliation_111 = NULL;
adam radford229fe472014-03-10 02:51:56 -07001834 dma_addr_t new_affiliation_111_h;
1835 int ld, retval = 0;
1836 u8 thisVf;
1837
1838 cmd = megasas_get_cmd(instance);
1839
1840 if (!cmd) {
Adam Radford4cbfea82014-07-09 15:17:56 -07001841 printk(KERN_DEBUG "megasas: megasas_get_ld_vf_affiliation_111:"
1842 "Failed to get cmd for scsi%d.\n",
adam radford229fe472014-03-10 02:51:56 -07001843 instance->host->host_no);
1844 return -ENOMEM;
1845 }
1846
1847 dcmd = &cmd->frame->dcmd;
1848
Adam Radford4cbfea82014-07-09 15:17:56 -07001849 if (!instance->vf_affiliation_111) {
adam radford229fe472014-03-10 02:51:56 -07001850 printk(KERN_WARNING "megasas: SR-IOV: Couldn't get LD/VF "
1851 "affiliation for scsi%d.\n", instance->host->host_no);
1852 megasas_return_cmd(instance, cmd);
1853 return -ENOMEM;
1854 }
1855
1856 if (initial)
adam radford229fe472014-03-10 02:51:56 -07001857 memset(instance->vf_affiliation_111, 0,
1858 sizeof(struct MR_LD_VF_AFFILIATION_111));
adam radford229fe472014-03-10 02:51:56 -07001859 else {
Adam Radford4cbfea82014-07-09 15:17:56 -07001860 new_affiliation_111 =
1861 pci_alloc_consistent(instance->pdev,
1862 sizeof(struct MR_LD_VF_AFFILIATION_111),
1863 &new_affiliation_111_h);
1864 if (!new_affiliation_111) {
adam radford229fe472014-03-10 02:51:56 -07001865 printk(KERN_DEBUG "megasas: SR-IOV: Couldn't allocate "
1866 "memory for new affiliation for scsi%d.\n",
Adam Radford4cbfea82014-07-09 15:17:56 -07001867 instance->host->host_no);
adam radford229fe472014-03-10 02:51:56 -07001868 megasas_return_cmd(instance, cmd);
1869 return -ENOMEM;
1870 }
Adam Radford4cbfea82014-07-09 15:17:56 -07001871 memset(new_affiliation_111, 0,
1872 sizeof(struct MR_LD_VF_AFFILIATION_111));
adam radford229fe472014-03-10 02:51:56 -07001873 }
1874
1875 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
1876
1877 dcmd->cmd = MFI_CMD_DCMD;
1878 dcmd->cmd_status = 0xFF;
1879 dcmd->sge_count = 1;
1880 dcmd->flags = MFI_FRAME_DIR_BOTH;
1881 dcmd->timeout = 0;
1882 dcmd->pad_0 = 0;
Adam Radford4cbfea82014-07-09 15:17:56 -07001883 dcmd->data_xfer_len = sizeof(struct MR_LD_VF_AFFILIATION_111);
1884 dcmd->opcode = MR_DCMD_LD_VF_MAP_GET_ALL_LDS_111;
adam radford229fe472014-03-10 02:51:56 -07001885
Adam Radford4cbfea82014-07-09 15:17:56 -07001886 if (initial)
1887 dcmd->sgl.sge32[0].phys_addr =
1888 instance->vf_affiliation_111_h;
adam radford229fe472014-03-10 02:51:56 -07001889 else
Adam Radford4cbfea82014-07-09 15:17:56 -07001890 dcmd->sgl.sge32[0].phys_addr = new_affiliation_111_h;
1891
1892 dcmd->sgl.sge32[0].length =
1893 sizeof(struct MR_LD_VF_AFFILIATION_111);
adam radford229fe472014-03-10 02:51:56 -07001894
1895 printk(KERN_WARNING "megasas: SR-IOV: Getting LD/VF affiliation for "
1896 "scsi%d\n", instance->host->host_no);
1897
1898 megasas_issue_blocked_cmd(instance, cmd, 0);
1899
1900 if (dcmd->cmd_status) {
1901 printk(KERN_WARNING "megasas: SR-IOV: LD/VF affiliation DCMD"
1902 " failed with status 0x%x for scsi%d.\n",
1903 dcmd->cmd_status, instance->host->host_no);
1904 retval = 1; /* Do a scan if we couldn't get affiliation */
1905 goto out;
1906 }
1907
1908 if (!initial) {
Adam Radford4cbfea82014-07-09 15:17:56 -07001909 thisVf = new_affiliation_111->thisVf;
1910 for (ld = 0 ; ld < new_affiliation_111->vdCount; ld++)
1911 if (instance->vf_affiliation_111->map[ld].policy[thisVf] !=
1912 new_affiliation_111->map[ld].policy[thisVf]) {
1913 printk(KERN_WARNING "megasas: SR-IOV: "
1914 "Got new LD/VF affiliation "
adam radford229fe472014-03-10 02:51:56 -07001915 "for scsi%d.\n",
adam radford229fe472014-03-10 02:51:56 -07001916 instance->host->host_no);
Adam Radford4cbfea82014-07-09 15:17:56 -07001917 memcpy(instance->vf_affiliation_111,
1918 new_affiliation_111,
1919 sizeof(struct MR_LD_VF_AFFILIATION_111));
adam radford229fe472014-03-10 02:51:56 -07001920 retval = 1;
1921 goto out;
1922 }
Adam Radford4cbfea82014-07-09 15:17:56 -07001923 }
1924out:
1925 if (new_affiliation_111) {
1926 pci_free_consistent(instance->pdev,
1927 sizeof(struct MR_LD_VF_AFFILIATION_111),
1928 new_affiliation_111,
1929 new_affiliation_111_h);
1930 }
1931 megasas_return_cmd(instance, cmd);
1932
1933 return retval;
1934}
1935
1936static int megasas_get_ld_vf_affiliation_12(struct megasas_instance *instance,
1937 int initial)
1938{
1939 struct megasas_cmd *cmd;
1940 struct megasas_dcmd_frame *dcmd;
1941 struct MR_LD_VF_AFFILIATION *new_affiliation = NULL;
1942 struct MR_LD_VF_MAP *newmap = NULL, *savedmap = NULL;
1943 dma_addr_t new_affiliation_h;
1944 int i, j, retval = 0, found = 0, doscan = 0;
1945 u8 thisVf;
1946
1947 cmd = megasas_get_cmd(instance);
1948
1949 if (!cmd) {
1950 printk(KERN_DEBUG "megasas: megasas_get_ld_vf_affiliation12: "
1951 "Failed to get cmd for scsi%d.\n",
1952 instance->host->host_no);
1953 return -ENOMEM;
1954 }
1955
1956 dcmd = &cmd->frame->dcmd;
1957
1958 if (!instance->vf_affiliation) {
1959 printk(KERN_WARNING "megasas: SR-IOV: Couldn't get LD/VF "
1960 "affiliation for scsi%d.\n", instance->host->host_no);
1961 megasas_return_cmd(instance, cmd);
1962 return -ENOMEM;
1963 }
1964
1965 if (initial)
1966 memset(instance->vf_affiliation, 0, (MAX_LOGICAL_DRIVES + 1) *
1967 sizeof(struct MR_LD_VF_AFFILIATION));
1968 else {
1969 new_affiliation =
1970 pci_alloc_consistent(instance->pdev,
1971 (MAX_LOGICAL_DRIVES + 1) *
1972 sizeof(struct MR_LD_VF_AFFILIATION),
1973 &new_affiliation_h);
1974 if (!new_affiliation) {
1975 printk(KERN_DEBUG "megasas: SR-IOV: Couldn't allocate "
1976 "memory for new affiliation for scsi%d.\n",
1977 instance->host->host_no);
1978 megasas_return_cmd(instance, cmd);
1979 return -ENOMEM;
1980 }
1981 memset(new_affiliation, 0, (MAX_LOGICAL_DRIVES + 1) *
1982 sizeof(struct MR_LD_VF_AFFILIATION));
1983 }
1984
1985 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
1986
1987 dcmd->cmd = MFI_CMD_DCMD;
1988 dcmd->cmd_status = 0xFF;
1989 dcmd->sge_count = 1;
1990 dcmd->flags = MFI_FRAME_DIR_BOTH;
1991 dcmd->timeout = 0;
1992 dcmd->pad_0 = 0;
1993 dcmd->data_xfer_len = (MAX_LOGICAL_DRIVES + 1) *
1994 sizeof(struct MR_LD_VF_AFFILIATION);
1995 dcmd->opcode = MR_DCMD_LD_VF_MAP_GET_ALL_LDS;
1996
1997 if (initial)
1998 dcmd->sgl.sge32[0].phys_addr = instance->vf_affiliation_h;
1999 else
2000 dcmd->sgl.sge32[0].phys_addr = new_affiliation_h;
2001
2002 dcmd->sgl.sge32[0].length = (MAX_LOGICAL_DRIVES + 1) *
2003 sizeof(struct MR_LD_VF_AFFILIATION);
2004
2005 printk(KERN_WARNING "megasas: SR-IOV: Getting LD/VF affiliation for "
2006 "scsi%d\n", instance->host->host_no);
2007
2008 megasas_issue_blocked_cmd(instance, cmd, 0);
2009
2010 if (dcmd->cmd_status) {
2011 printk(KERN_WARNING "megasas: SR-IOV: LD/VF affiliation DCMD"
2012 " failed with status 0x%x for scsi%d.\n",
2013 dcmd->cmd_status, instance->host->host_no);
2014 retval = 1; /* Do a scan if we couldn't get affiliation */
2015 goto out;
2016 }
2017
2018 if (!initial) {
2019 if (!new_affiliation->ldCount) {
2020 printk(KERN_WARNING "megasas: SR-IOV: Got new LD/VF "
2021 "affiliation for passive path for scsi%d.\n",
2022 instance->host->host_no);
2023 retval = 1;
2024 goto out;
2025 }
2026 newmap = new_affiliation->map;
2027 savedmap = instance->vf_affiliation->map;
2028 thisVf = new_affiliation->thisVf;
2029 for (i = 0 ; i < new_affiliation->ldCount; i++) {
2030 found = 0;
2031 for (j = 0; j < instance->vf_affiliation->ldCount;
2032 j++) {
2033 if (newmap->ref.targetId ==
2034 savedmap->ref.targetId) {
2035 found = 1;
2036 if (newmap->policy[thisVf] !=
2037 savedmap->policy[thisVf]) {
2038 doscan = 1;
2039 goto out;
2040 }
adam radford229fe472014-03-10 02:51:56 -07002041 }
2042 savedmap = (struct MR_LD_VF_MAP *)
2043 ((unsigned char *)savedmap +
2044 savedmap->size);
Adam Radford4cbfea82014-07-09 15:17:56 -07002045 }
2046 if (!found && newmap->policy[thisVf] !=
2047 MR_LD_ACCESS_HIDDEN) {
2048 doscan = 1;
2049 goto out;
2050 }
2051 newmap = (struct MR_LD_VF_MAP *)
2052 ((unsigned char *)newmap + newmap->size);
2053 }
2054
2055 newmap = new_affiliation->map;
2056 savedmap = instance->vf_affiliation->map;
2057
2058 for (i = 0 ; i < instance->vf_affiliation->ldCount; i++) {
2059 found = 0;
2060 for (j = 0 ; j < new_affiliation->ldCount; j++) {
2061 if (savedmap->ref.targetId ==
2062 newmap->ref.targetId) {
2063 found = 1;
2064 if (savedmap->policy[thisVf] !=
2065 newmap->policy[thisVf]) {
2066 doscan = 1;
2067 goto out;
2068 }
2069 }
adam radford229fe472014-03-10 02:51:56 -07002070 newmap = (struct MR_LD_VF_MAP *)
2071 ((unsigned char *)newmap +
2072 newmap->size);
2073 }
Adam Radford4cbfea82014-07-09 15:17:56 -07002074 if (!found && savedmap->policy[thisVf] !=
2075 MR_LD_ACCESS_HIDDEN) {
2076 doscan = 1;
2077 goto out;
2078 }
2079 savedmap = (struct MR_LD_VF_MAP *)
2080 ((unsigned char *)savedmap +
2081 savedmap->size);
adam radford229fe472014-03-10 02:51:56 -07002082 }
2083 }
2084out:
Adam Radford4cbfea82014-07-09 15:17:56 -07002085 if (doscan) {
2086 printk(KERN_WARNING "megasas: SR-IOV: Got new LD/VF "
2087 "affiliation for scsi%d.\n", instance->host->host_no);
2088 memcpy(instance->vf_affiliation, new_affiliation,
2089 new_affiliation->size);
2090 retval = 1;
adam radford229fe472014-03-10 02:51:56 -07002091 }
Adam Radford4cbfea82014-07-09 15:17:56 -07002092
2093 if (new_affiliation)
2094 pci_free_consistent(instance->pdev,
2095 (MAX_LOGICAL_DRIVES + 1) *
2096 sizeof(struct MR_LD_VF_AFFILIATION),
2097 new_affiliation, new_affiliation_h);
adam radford229fe472014-03-10 02:51:56 -07002098 megasas_return_cmd(instance, cmd);
2099
2100 return retval;
2101}
2102
Adam Radford4cbfea82014-07-09 15:17:56 -07002103/* This function will get the current SR-IOV LD/VF affiliation */
2104static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
2105 int initial)
2106{
2107 int retval;
2108
2109 if (instance->PlasmaFW111)
2110 retval = megasas_get_ld_vf_affiliation_111(instance, initial);
2111 else
2112 retval = megasas_get_ld_vf_affiliation_12(instance, initial);
2113 return retval;
2114}
2115
adam radford229fe472014-03-10 02:51:56 -07002116/* This function will tell FW to start the SR-IOV heartbeat */
2117int megasas_sriov_start_heartbeat(struct megasas_instance *instance,
2118 int initial)
2119{
2120 struct megasas_cmd *cmd;
2121 struct megasas_dcmd_frame *dcmd;
2122 int retval = 0;
2123
2124 cmd = megasas_get_cmd(instance);
2125
2126 if (!cmd) {
2127 printk(KERN_DEBUG "megasas: megasas_sriov_start_heartbeat: "
2128 "Failed to get cmd for scsi%d.\n",
2129 instance->host->host_no);
2130 return -ENOMEM;
2131 }
2132
2133 dcmd = &cmd->frame->dcmd;
2134
2135 if (initial) {
2136 instance->hb_host_mem =
Joe Perches7c845eb2014-08-08 14:24:46 -07002137 pci_zalloc_consistent(instance->pdev,
2138 sizeof(struct MR_CTRL_HB_HOST_MEM),
2139 &instance->hb_host_mem_h);
adam radford229fe472014-03-10 02:51:56 -07002140 if (!instance->hb_host_mem) {
2141 printk(KERN_DEBUG "megasas: SR-IOV: Couldn't allocate"
2142 " memory for heartbeat host memory for "
2143 "scsi%d.\n", instance->host->host_no);
2144 retval = -ENOMEM;
2145 goto out;
2146 }
adam radford229fe472014-03-10 02:51:56 -07002147 }
2148
2149 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2150
2151 dcmd->mbox.s[0] = sizeof(struct MR_CTRL_HB_HOST_MEM);
2152 dcmd->cmd = MFI_CMD_DCMD;
2153 dcmd->cmd_status = 0xFF;
2154 dcmd->sge_count = 1;
2155 dcmd->flags = MFI_FRAME_DIR_BOTH;
2156 dcmd->timeout = 0;
2157 dcmd->pad_0 = 0;
2158 dcmd->data_xfer_len = sizeof(struct MR_CTRL_HB_HOST_MEM);
2159 dcmd->opcode = MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC;
2160 dcmd->sgl.sge32[0].phys_addr = instance->hb_host_mem_h;
2161 dcmd->sgl.sge32[0].length = sizeof(struct MR_CTRL_HB_HOST_MEM);
2162
2163 printk(KERN_WARNING "megasas: SR-IOV: Starting heartbeat for scsi%d\n",
2164 instance->host->host_no);
2165
2166 if (!megasas_issue_polled(instance, cmd)) {
2167 retval = 0;
2168 } else {
2169 printk(KERN_WARNING "megasas: SR-IOV: MR_DCMD_CTRL_SHARED_HOST"
2170 "_MEM_ALLOC DCMD timed out for scsi%d\n",
2171 instance->host->host_no);
2172 retval = 1;
2173 goto out;
2174 }
2175
2176
2177 if (dcmd->cmd_status) {
2178 printk(KERN_WARNING "megasas: SR-IOV: MR_DCMD_CTRL_SHARED_HOST"
2179 "_MEM_ALLOC DCMD failed with status 0x%x for scsi%d\n",
2180 dcmd->cmd_status,
2181 instance->host->host_no);
2182 retval = 1;
2183 goto out;
2184 }
2185
2186out:
2187 megasas_return_cmd(instance, cmd);
2188
2189 return retval;
2190}
2191
2192/* Handler for SR-IOV heartbeat */
2193void megasas_sriov_heartbeat_handler(unsigned long instance_addr)
2194{
2195 struct megasas_instance *instance =
2196 (struct megasas_instance *)instance_addr;
2197
2198 if (instance->hb_host_mem->HB.fwCounter !=
2199 instance->hb_host_mem->HB.driverCounter) {
2200 instance->hb_host_mem->HB.driverCounter =
2201 instance->hb_host_mem->HB.fwCounter;
2202 mod_timer(&instance->sriov_heartbeat_timer,
2203 jiffies + MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
2204 } else {
2205 printk(KERN_WARNING "megasas: SR-IOV: Heartbeat never "
2206 "completed for scsi%d\n", instance->host->host_no);
2207 schedule_work(&instance->work_init);
2208 }
2209}
2210
bo yang7343eb62007-11-09 04:35:44 -05002211/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002212 * megasas_wait_for_outstanding - Wait for all outstanding cmds
2213 * @instance: Adapter soft state
2214 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002215 * This function waits for up to MEGASAS_RESET_WAIT_TIME seconds for FW to
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002216 * complete all its outstanding commands. Returns error if one or more IOs
2217 * are pending after this time period. It also marks the controller dead.
2218 */
2219static int megasas_wait_for_outstanding(struct megasas_instance *instance)
2220{
2221 int i;
bo yang39a98552010-09-22 22:36:29 -04002222 u32 reset_index;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002223 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
bo yang39a98552010-09-22 22:36:29 -04002224 u8 adprecovery;
2225 unsigned long flags;
2226 struct list_head clist_local;
2227 struct megasas_cmd *reset_cmd;
Yang, Bo707e09b2010-10-12 07:20:27 -06002228 u32 fw_state;
2229 u8 kill_adapter_flag;
bo yang39a98552010-09-22 22:36:29 -04002230
2231 spin_lock_irqsave(&instance->hba_lock, flags);
2232 adprecovery = instance->adprecovery;
2233 spin_unlock_irqrestore(&instance->hba_lock, flags);
2234
2235 if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
2236
2237 INIT_LIST_HEAD(&clist_local);
2238 spin_lock_irqsave(&instance->hba_lock, flags);
2239 list_splice_init(&instance->internal_reset_pending_q,
2240 &clist_local);
2241 spin_unlock_irqrestore(&instance->hba_lock, flags);
2242
2243 printk(KERN_NOTICE "megasas: HBA reset wait ...\n");
2244 for (i = 0; i < wait_time; i++) {
2245 msleep(1000);
2246 spin_lock_irqsave(&instance->hba_lock, flags);
2247 adprecovery = instance->adprecovery;
2248 spin_unlock_irqrestore(&instance->hba_lock, flags);
2249 if (adprecovery == MEGASAS_HBA_OPERATIONAL)
2250 break;
2251 }
2252
2253 if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
2254 printk(KERN_NOTICE "megasas: reset: Stopping HBA.\n");
2255 spin_lock_irqsave(&instance->hba_lock, flags);
2256 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2257 spin_unlock_irqrestore(&instance->hba_lock, flags);
2258 return FAILED;
2259 }
2260
2261 reset_index = 0;
2262 while (!list_empty(&clist_local)) {
2263 reset_cmd = list_entry((&clist_local)->next,
2264 struct megasas_cmd, list);
2265 list_del_init(&reset_cmd->list);
2266 if (reset_cmd->scmd) {
2267 reset_cmd->scmd->result = DID_RESET << 16;
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002268 printk(KERN_NOTICE "%d:%p reset [%02x]\n",
bo yang39a98552010-09-22 22:36:29 -04002269 reset_index, reset_cmd,
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002270 reset_cmd->scmd->cmnd[0]);
bo yang39a98552010-09-22 22:36:29 -04002271
2272 reset_cmd->scmd->scsi_done(reset_cmd->scmd);
2273 megasas_return_cmd(instance, reset_cmd);
2274 } else if (reset_cmd->sync_cmd) {
2275 printk(KERN_NOTICE "megasas:%p synch cmds"
2276 "reset queue\n",
2277 reset_cmd);
2278
2279 reset_cmd->cmd_status = ENODATA;
2280 instance->instancet->fire_cmd(instance,
2281 reset_cmd->frame_phys_addr,
2282 0, instance->reg_set);
2283 } else {
2284 printk(KERN_NOTICE "megasas: %p unexpected"
2285 "cmds lst\n",
2286 reset_cmd);
2287 }
2288 reset_index++;
2289 }
2290
2291 return SUCCESS;
2292 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002293
adam radfordc007b8b2012-07-17 18:20:24 -07002294 for (i = 0; i < resetwaittime; i++) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002295
Sumant Patroe4a082c2006-05-30 12:03:37 -07002296 int outstanding = atomic_read(&instance->fw_outstanding);
2297
2298 if (!outstanding)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002299 break;
2300
2301 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
2302 printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
Sumant Patroe4a082c2006-05-30 12:03:37 -07002303 "commands to complete\n",i,outstanding);
bo yang7343eb62007-11-09 04:35:44 -05002304 /*
2305 * Call cmd completion routine. Cmd to be
2306 * be completed directly without depending on isr.
2307 */
2308 megasas_complete_cmd_dpc((unsigned long)instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002309 }
2310
2311 msleep(1000);
2312 }
2313
Yang, Bo707e09b2010-10-12 07:20:27 -06002314 i = 0;
2315 kill_adapter_flag = 0;
2316 do {
2317 fw_state = instance->instancet->read_fw_status_reg(
2318 instance->reg_set) & MFI_STATE_MASK;
2319 if ((fw_state == MFI_STATE_FAULT) &&
2320 (instance->disableOnlineCtrlReset == 0)) {
2321 if (i == 3) {
2322 kill_adapter_flag = 2;
2323 break;
2324 }
2325 megasas_do_ocr(instance);
2326 kill_adapter_flag = 1;
2327
2328 /* wait for 1 secs to let FW finish the pending cmds */
2329 msleep(1000);
2330 }
2331 i++;
2332 } while (i <= 3);
2333
2334 if (atomic_read(&instance->fw_outstanding) &&
2335 !kill_adapter_flag) {
2336 if (instance->disableOnlineCtrlReset == 0) {
2337
2338 megasas_do_ocr(instance);
2339
2340 /* wait for 5 secs to let FW finish the pending cmds */
2341 for (i = 0; i < wait_time; i++) {
2342 int outstanding =
2343 atomic_read(&instance->fw_outstanding);
2344 if (!outstanding)
2345 return SUCCESS;
2346 msleep(1000);
2347 }
2348 }
2349 }
2350
2351 if (atomic_read(&instance->fw_outstanding) ||
2352 (kill_adapter_flag == 2)) {
bo yang39a98552010-09-22 22:36:29 -04002353 printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n");
Sumant Patroe3bbff92006-10-03 12:28:49 -07002354 /*
2355 * Send signal to FW to stop processing any pending cmds.
2356 * The controller will be taken offline by the OS now.
2357 */
Yang, Bo0c79e682009-10-06 14:47:35 -06002358 if ((instance->pdev->device ==
2359 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2360 (instance->pdev->device ==
2361 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
2362 writel(MFI_STOP_ADP,
adam radford9c915a82010-12-21 13:34:31 -08002363 &instance->reg_set->doorbell);
Yang, Bo0c79e682009-10-06 14:47:35 -06002364 } else {
2365 writel(MFI_STOP_ADP,
Sumant Patroe3bbff92006-10-03 12:28:49 -07002366 &instance->reg_set->inbound_doorbell);
Yang, Bo0c79e682009-10-06 14:47:35 -06002367 }
Sumant Patro658dced2006-10-03 13:09:14 -07002368 megasas_dump_pending_frames(instance);
bo yang39a98552010-09-22 22:36:29 -04002369 spin_lock_irqsave(&instance->hba_lock, flags);
2370 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2371 spin_unlock_irqrestore(&instance->hba_lock, flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002372 return FAILED;
2373 }
2374
bo yang39a98552010-09-22 22:36:29 -04002375 printk(KERN_NOTICE "megaraid_sas: no pending cmds after reset\n");
2376
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002377 return SUCCESS;
2378}
2379
2380/**
2381 * megasas_generic_reset - Generic reset routine
2382 * @scmd: Mid-layer SCSI command
2383 *
2384 * This routine implements a generic reset handler for device, bus and host
2385 * reset requests. Device, bus and host specific reset handlers can use this
2386 * function after they do their specific tasks.
2387 */
2388static int megasas_generic_reset(struct scsi_cmnd *scmd)
2389{
2390 int ret_val;
2391 struct megasas_instance *instance;
2392
2393 instance = (struct megasas_instance *)scmd->device->host->hostdata;
2394
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002395 scmd_printk(KERN_NOTICE, scmd, "megasas: RESET cmd=%x retries=%x\n",
2396 scmd->cmnd[0], scmd->retries);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002397
bo yang39a98552010-09-22 22:36:29 -04002398 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002399 printk(KERN_ERR "megasas: cannot recover from previous reset "
2400 "failures\n");
2401 return FAILED;
2402 }
2403
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002404 ret_val = megasas_wait_for_outstanding(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002405 if (ret_val == SUCCESS)
2406 printk(KERN_NOTICE "megasas: reset successful \n");
2407 else
2408 printk(KERN_ERR "megasas: failed to do reset\n");
2409
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002410 return ret_val;
2411}
2412
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002413/**
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002414 * megasas_reset_timer - quiesce the adapter if required
2415 * @scmd: scsi cmnd
2416 *
2417 * Sets the FW busy flag and reduces the host->can_queue if the
2418 * cmd has not been completed within the timeout period.
2419 */
2420static enum
Jens Axboe242f9dc2008-09-14 05:55:09 -07002421blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002422{
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002423 struct megasas_instance *instance;
2424 unsigned long flags;
2425
2426 if (time_after(jiffies, scmd->jiffies_at_alloc +
2427 (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
Jens Axboe242f9dc2008-09-14 05:55:09 -07002428 return BLK_EH_NOT_HANDLED;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002429 }
2430
adam radfordf575c5d2011-10-13 16:01:12 -07002431 instance = (struct megasas_instance *)scmd->device->host->hostdata;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002432 if (!(instance->flag & MEGASAS_FW_BUSY)) {
2433 /* FW is busy, throttle IO */
2434 spin_lock_irqsave(instance->host->host_lock, flags);
2435
adam radfordc5daa6a2012-07-17 18:20:03 -07002436 instance->host->can_queue = instance->throttlequeuedepth;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002437 instance->last_time = jiffies;
2438 instance->flag |= MEGASAS_FW_BUSY;
2439
2440 spin_unlock_irqrestore(instance->host->host_lock, flags);
2441 }
Jens Axboe242f9dc2008-09-14 05:55:09 -07002442 return BLK_EH_RESET_TIMER;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002443}
2444
2445/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002446 * megasas_reset_device - Device reset handler entry point
2447 */
2448static int megasas_reset_device(struct scsi_cmnd *scmd)
2449{
2450 int ret;
2451
2452 /*
2453 * First wait for all commands to complete
2454 */
2455 ret = megasas_generic_reset(scmd);
2456
2457 return ret;
2458}
2459
2460/**
2461 * megasas_reset_bus_host - Bus & host reset handler entry point
2462 */
2463static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
2464{
2465 int ret;
adam radford9c915a82010-12-21 13:34:31 -08002466 struct megasas_instance *instance;
2467 instance = (struct megasas_instance *)scmd->device->host->hostdata;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002468
2469 /*
Uwe Zeisberger80682fa2006-03-22 00:21:33 +01002470 * First wait for all commands to complete
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002471 */
adam radford36807e62011-10-08 18:15:06 -07002472 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
adam radford229fe472014-03-10 02:51:56 -07002473 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05302474 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
2475 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
adam radford229fe472014-03-10 02:51:56 -07002476 ret = megasas_reset_fusion(scmd->device->host, 1);
adam radford9c915a82010-12-21 13:34:31 -08002477 else
2478 ret = megasas_generic_reset(scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002479
2480 return ret;
2481}
2482
2483/**
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002484 * megasas_bios_param - Returns disk geometry for a disk
2485 * @sdev: device handle
2486 * @bdev: block device
2487 * @capacity: drive capacity
2488 * @geom: geometry parameters
2489 */
2490static int
2491megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
2492 sector_t capacity, int geom[])
2493{
2494 int heads;
2495 int sectors;
2496 sector_t cylinders;
2497 unsigned long tmp;
2498 /* Default heads (64) & sectors (32) */
2499 heads = 64;
2500 sectors = 32;
2501
2502 tmp = heads * sectors;
2503 cylinders = capacity;
2504
2505 sector_div(cylinders, tmp);
2506
2507 /*
2508 * Handle extended translation size for logical drives > 1Gb
2509 */
2510
2511 if (capacity >= 0x200000) {
2512 heads = 255;
2513 sectors = 63;
2514 tmp = heads*sectors;
2515 cylinders = capacity;
2516 sector_div(cylinders, tmp);
2517 }
2518
2519 geom[0] = heads;
2520 geom[1] = sectors;
2521 geom[2] = cylinders;
2522
2523 return 0;
2524}
2525
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002526static void megasas_aen_polling(struct work_struct *work);
2527
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002528/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002529 * megasas_service_aen - Processes an event notification
2530 * @instance: Adapter soft state
2531 * @cmd: AEN command completed by the ISR
2532 *
2533 * For AEN, driver sends a command down to FW that is held by the FW till an
2534 * event occurs. When an event of interest occurs, FW completes the command
2535 * that it was previously holding.
2536 *
2537 * This routines sends SIGIO signal to processes that have registered with the
2538 * driver for AEN.
2539 */
2540static void
2541megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
2542{
Yang, Boc3518832009-10-06 14:18:02 -06002543 unsigned long flags;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002544 /*
2545 * Don't signal app if it is just an aborted previously registered aen
2546 */
Yang, Boc3518832009-10-06 14:18:02 -06002547 if ((!cmd->abort_aen) && (instance->unload == 0)) {
2548 spin_lock_irqsave(&poll_aen_lock, flags);
2549 megasas_poll_wait_aen = 1;
2550 spin_unlock_irqrestore(&poll_aen_lock, flags);
2551 wake_up(&megasas_poll_wait);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002552 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
Yang, Boc3518832009-10-06 14:18:02 -06002553 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002554 else
2555 cmd->abort_aen = 0;
2556
2557 instance->aen_cmd = NULL;
2558 megasas_return_cmd(instance, cmd);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002559
bo yang39a98552010-09-22 22:36:29 -04002560 if ((instance->unload == 0) &&
2561 ((instance->issuepend_done == 1))) {
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002562 struct megasas_aen_event *ev;
2563 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2564 if (!ev) {
2565 printk(KERN_ERR "megasas_service_aen: out of memory\n");
2566 } else {
2567 ev->instance = instance;
2568 instance->ev = ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08002569 INIT_DELAYED_WORK(&ev->hotplug_work,
2570 megasas_aen_polling);
2571 schedule_delayed_work(&ev->hotplug_work, 0);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002572 }
2573 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002574}
2575
adam radford4bcde502011-07-26 15:42:52 -07002576static int megasas_change_queue_depth(struct scsi_device *sdev,
2577 int queue_depth, int reason)
2578{
2579 if (reason != SCSI_QDEPTH_DEFAULT)
2580 return -EOPNOTSUPP;
2581
2582 if (queue_depth > sdev->host->can_queue)
2583 queue_depth = sdev->host->can_queue;
2584 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
2585 queue_depth);
2586
2587 return queue_depth;
2588}
2589
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002590/*
2591 * Scsi host template for megaraid_sas driver
2592 */
2593static struct scsi_host_template megasas_template = {
2594
2595 .module = THIS_MODULE,
bo yangf28cd7c2007-11-09 04:44:56 -05002596 .name = "LSI SAS based MegaRAID driver",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002597 .proc_name = "megaraid_sas",
Christoph Hellwig147aab62006-02-17 12:13:48 +01002598 .slave_configure = megasas_slave_configure,
Yang, Bo044833b2009-10-06 14:33:06 -06002599 .slave_alloc = megasas_slave_alloc,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002600 .queuecommand = megasas_queue_command,
2601 .eh_device_reset_handler = megasas_reset_device,
2602 .eh_bus_reset_handler = megasas_reset_bus_host,
2603 .eh_host_reset_handler = megasas_reset_bus_host,
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002604 .eh_timed_out = megasas_reset_timer,
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002605 .bios_param = megasas_bios_param,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002606 .use_clustering = ENABLE_CLUSTERING,
adam radford4bcde502011-07-26 15:42:52 -07002607 .change_queue_depth = megasas_change_queue_depth,
Martin K. Petersen54b2b502013-10-23 06:25:40 -04002608 .no_write_same = 1,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002609};
2610
2611/**
2612 * megasas_complete_int_cmd - Completes an internal command
2613 * @instance: Adapter soft state
2614 * @cmd: Command to be completed
2615 *
2616 * The megasas_issue_blocked_cmd() function waits for a command to complete
2617 * after it issues a command. This function wakes up that waiting routine by
2618 * calling wake_up() on the wait queue.
2619 */
2620static void
2621megasas_complete_int_cmd(struct megasas_instance *instance,
2622 struct megasas_cmd *cmd)
2623{
2624 cmd->cmd_status = cmd->frame->io.cmd_status;
2625
2626 if (cmd->cmd_status == ENODATA) {
2627 cmd->cmd_status = 0;
2628 }
2629 wake_up(&instance->int_cmd_wait_q);
2630}
2631
2632/**
2633 * megasas_complete_abort - Completes aborting a command
2634 * @instance: Adapter soft state
2635 * @cmd: Cmd that was issued to abort another cmd
2636 *
adam radford0d490162010-12-14 19:17:17 -08002637 * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
2638 * after it issues an abort on a previously issued command. This function
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002639 * wakes up all functions waiting on the same wait queue.
2640 */
2641static void
2642megasas_complete_abort(struct megasas_instance *instance,
2643 struct megasas_cmd *cmd)
2644{
2645 if (cmd->sync_cmd) {
2646 cmd->sync_cmd = 0;
2647 cmd->cmd_status = 0;
2648 wake_up(&instance->abort_cmd_wait_q);
2649 }
2650
2651 return;
2652}
2653
2654/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002655 * megasas_complete_cmd - Completes a command
2656 * @instance: Adapter soft state
2657 * @cmd: Command to be completed
adam radford0d490162010-12-14 19:17:17 -08002658 * @alt_status: If non-zero, use this value as status to
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002659 * SCSI mid-layer instead of the value returned
2660 * by the FW. This should be used if caller wants
2661 * an alternate status (as in the case of aborted
2662 * commands)
2663 */
adam radford9c915a82010-12-21 13:34:31 -08002664void
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002665megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
2666 u8 alt_status)
2667{
2668 int exception = 0;
2669 struct megasas_header *hdr = &cmd->frame->hdr;
Yang, Boc3518832009-10-06 14:18:02 -06002670 unsigned long flags;
adam radford9c915a82010-12-21 13:34:31 -08002671 struct fusion_context *fusion = instance->ctrl_context;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302672 u32 opcode;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002673
bo yang39a98552010-09-22 22:36:29 -04002674 /* flag for the retry reset */
2675 cmd->retry_for_fw_reset = 0;
2676
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002677 if (cmd->scmd)
2678 cmd->scmd->SCp.ptr = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002679
2680 switch (hdr->cmd) {
adam radforde5f93a32011-10-08 18:15:19 -07002681 case MFI_CMD_INVALID:
2682 /* Some older 1068 controller FW may keep a pended
2683 MR_DCMD_CTRL_EVENT_GET_INFO left over from the main kernel
2684 when booting the kdump kernel. Ignore this command to
2685 prevent a kernel panic on shutdown of the kdump kernel. */
2686 printk(KERN_WARNING "megaraid_sas: MFI_CMD_INVALID command "
2687 "completed.\n");
2688 printk(KERN_WARNING "megaraid_sas: If you have a controller "
2689 "other than PERC5, please upgrade your firmware.\n");
2690 break;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002691 case MFI_CMD_PD_SCSI_IO:
2692 case MFI_CMD_LD_SCSI_IO:
2693
2694 /*
2695 * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been
2696 * issued either through an IO path or an IOCTL path. If it
2697 * was via IOCTL, we will send it to internal completion.
2698 */
2699 if (cmd->sync_cmd) {
2700 cmd->sync_cmd = 0;
2701 megasas_complete_int_cmd(instance, cmd);
2702 break;
2703 }
2704
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002705 case MFI_CMD_LD_READ:
2706 case MFI_CMD_LD_WRITE:
2707
2708 if (alt_status) {
2709 cmd->scmd->result = alt_status << 16;
2710 exception = 1;
2711 }
2712
2713 if (exception) {
2714
Sumant Patroe4a082c2006-05-30 12:03:37 -07002715 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002716
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09002717 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002718 cmd->scmd->scsi_done(cmd->scmd);
2719 megasas_return_cmd(instance, cmd);
2720
2721 break;
2722 }
2723
2724 switch (hdr->cmd_status) {
2725
2726 case MFI_STAT_OK:
2727 cmd->scmd->result = DID_OK << 16;
2728 break;
2729
2730 case MFI_STAT_SCSI_IO_FAILED:
2731 case MFI_STAT_LD_INIT_IN_PROGRESS:
2732 cmd->scmd->result =
2733 (DID_ERROR << 16) | hdr->scsi_status;
2734 break;
2735
2736 case MFI_STAT_SCSI_DONE_WITH_ERROR:
2737
2738 cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status;
2739
2740 if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) {
2741 memset(cmd->scmd->sense_buffer, 0,
2742 SCSI_SENSE_BUFFERSIZE);
2743 memcpy(cmd->scmd->sense_buffer, cmd->sense,
2744 hdr->sense_len);
2745
2746 cmd->scmd->result |= DRIVER_SENSE << 24;
2747 }
2748
2749 break;
2750
2751 case MFI_STAT_LD_OFFLINE:
2752 case MFI_STAT_DEVICE_NOT_FOUND:
2753 cmd->scmd->result = DID_BAD_TARGET << 16;
2754 break;
2755
2756 default:
2757 printk(KERN_DEBUG "megasas: MFI FW status %#x\n",
2758 hdr->cmd_status);
2759 cmd->scmd->result = DID_ERROR << 16;
2760 break;
2761 }
2762
Sumant Patroe4a082c2006-05-30 12:03:37 -07002763 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002764
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09002765 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002766 cmd->scmd->scsi_done(cmd->scmd);
2767 megasas_return_cmd(instance, cmd);
2768
2769 break;
2770
2771 case MFI_CMD_SMP:
2772 case MFI_CMD_STP:
2773 case MFI_CMD_DCMD:
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302774 opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
adam radford9c915a82010-12-21 13:34:31 -08002775 /* Check for LD map update */
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302776 if ((opcode == MR_DCMD_LD_MAP_GET_INFO)
2777 && (cmd->frame->dcmd.mbox.b[1] == 1)) {
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05302778 fusion->fast_path_io = 0;
adam radford9c915a82010-12-21 13:34:31 -08002779 spin_lock_irqsave(instance->host->host_lock, flags);
2780 if (cmd->frame->hdr.cmd_status != 0) {
2781 if (cmd->frame->hdr.cmd_status !=
2782 MFI_STAT_NOT_FOUND)
2783 printk(KERN_WARNING "megasas: map sync"
2784 "failed, status = 0x%x.\n",
2785 cmd->frame->hdr.cmd_status);
2786 else {
2787 megasas_return_cmd(instance, cmd);
2788 spin_unlock_irqrestore(
2789 instance->host->host_lock,
2790 flags);
2791 break;
2792 }
2793 } else
2794 instance->map_id++;
2795 megasas_return_cmd(instance, cmd);
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05302796
2797 /*
2798 * Set fast path IO to ZERO.
2799 * Validate Map will set proper value.
2800 * Meanwhile all IOs will go as LD IO.
2801 */
2802 if (MR_ValidateMapInfo(instance))
adam radford9c915a82010-12-21 13:34:31 -08002803 fusion->fast_path_io = 1;
2804 else
2805 fusion->fast_path_io = 0;
2806 megasas_sync_map_info(instance);
2807 spin_unlock_irqrestore(instance->host->host_lock,
2808 flags);
2809 break;
2810 }
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302811 if (opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
2812 opcode == MR_DCMD_CTRL_EVENT_GET) {
Yang, Boc3518832009-10-06 14:18:02 -06002813 spin_lock_irqsave(&poll_aen_lock, flags);
2814 megasas_poll_wait_aen = 0;
2815 spin_unlock_irqrestore(&poll_aen_lock, flags);
2816 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002817
2818 /*
2819 * See if got an event notification
2820 */
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05302821 if (opcode == MR_DCMD_CTRL_EVENT_WAIT)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002822 megasas_service_aen(instance, cmd);
2823 else
2824 megasas_complete_int_cmd(instance, cmd);
2825
2826 break;
2827
2828 case MFI_CMD_ABORT:
2829 /*
2830 * Cmd issued to abort another cmd returned
2831 */
2832 megasas_complete_abort(instance, cmd);
2833 break;
2834
2835 default:
2836 printk("megasas: Unknown command completed! [0x%X]\n",
2837 hdr->cmd);
2838 break;
2839 }
2840}
2841
2842/**
bo yang39a98552010-09-22 22:36:29 -04002843 * megasas_issue_pending_cmds_again - issue all pending cmds
2844 * in FW again because of the fw reset
2845 * @instance: Adapter soft state
2846 */
2847static inline void
2848megasas_issue_pending_cmds_again(struct megasas_instance *instance)
2849{
2850 struct megasas_cmd *cmd;
2851 struct list_head clist_local;
2852 union megasas_evt_class_locale class_locale;
2853 unsigned long flags;
2854 u32 seq_num;
2855
2856 INIT_LIST_HEAD(&clist_local);
2857 spin_lock_irqsave(&instance->hba_lock, flags);
2858 list_splice_init(&instance->internal_reset_pending_q, &clist_local);
2859 spin_unlock_irqrestore(&instance->hba_lock, flags);
2860
2861 while (!list_empty(&clist_local)) {
2862 cmd = list_entry((&clist_local)->next,
2863 struct megasas_cmd, list);
2864 list_del_init(&cmd->list);
2865
2866 if (cmd->sync_cmd || cmd->scmd) {
2867 printk(KERN_NOTICE "megaraid_sas: command %p, %p:%d"
2868 "detected to be pending while HBA reset.\n",
2869 cmd, cmd->scmd, cmd->sync_cmd);
2870
2871 cmd->retry_for_fw_reset++;
2872
2873 if (cmd->retry_for_fw_reset == 3) {
2874 printk(KERN_NOTICE "megaraid_sas: cmd %p, %p:%d"
2875 "was tried multiple times during reset."
2876 "Shutting down the HBA\n",
2877 cmd, cmd->scmd, cmd->sync_cmd);
2878 megaraid_sas_kill_hba(instance);
2879
2880 instance->adprecovery =
2881 MEGASAS_HW_CRITICAL_ERROR;
2882 return;
2883 }
2884 }
2885
2886 if (cmd->sync_cmd == 1) {
2887 if (cmd->scmd) {
2888 printk(KERN_NOTICE "megaraid_sas: unexpected"
2889 "cmd attached to internal command!\n");
2890 }
2891 printk(KERN_NOTICE "megasas: %p synchronous cmd"
2892 "on the internal reset queue,"
2893 "issue it again.\n", cmd);
2894 cmd->cmd_status = ENODATA;
2895 instance->instancet->fire_cmd(instance,
2896 cmd->frame_phys_addr ,
2897 0, instance->reg_set);
2898 } else if (cmd->scmd) {
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002899 printk(KERN_NOTICE "megasas: %p scsi cmd [%02x]"
bo yang39a98552010-09-22 22:36:29 -04002900 "detected on the internal queue, issue again.\n",
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002901 cmd, cmd->scmd->cmnd[0]);
bo yang39a98552010-09-22 22:36:29 -04002902
2903 atomic_inc(&instance->fw_outstanding);
2904 instance->instancet->fire_cmd(instance,
2905 cmd->frame_phys_addr,
2906 cmd->frame_count-1, instance->reg_set);
2907 } else {
2908 printk(KERN_NOTICE "megasas: %p unexpected cmd on the"
2909 "internal reset defer list while re-issue!!\n",
2910 cmd);
2911 }
2912 }
2913
2914 if (instance->aen_cmd) {
2915 printk(KERN_NOTICE "megaraid_sas: aen_cmd in def process\n");
2916 megasas_return_cmd(instance, instance->aen_cmd);
2917
2918 instance->aen_cmd = NULL;
2919 }
2920
2921 /*
2922 * Initiate AEN (Asynchronous Event Notification)
2923 */
2924 seq_num = instance->last_seq_num;
2925 class_locale.members.reserved = 0;
2926 class_locale.members.locale = MR_EVT_LOCALE_ALL;
2927 class_locale.members.class = MR_EVT_CLASS_DEBUG;
2928
2929 megasas_register_aen(instance, seq_num, class_locale.word);
2930}
2931
2932/**
2933 * Move the internal reset pending commands to a deferred queue.
2934 *
2935 * We move the commands pending at internal reset time to a
2936 * pending queue. This queue would be flushed after successful
2937 * completion of the internal reset sequence. if the internal reset
2938 * did not complete in time, the kernel reset handler would flush
2939 * these commands.
2940 **/
2941static void
2942megasas_internal_reset_defer_cmds(struct megasas_instance *instance)
2943{
2944 struct megasas_cmd *cmd;
2945 int i;
2946 u32 max_cmd = instance->max_fw_cmds;
2947 u32 defer_index;
2948 unsigned long flags;
2949
2950 defer_index = 0;
2951 spin_lock_irqsave(&instance->cmd_pool_lock, flags);
2952 for (i = 0; i < max_cmd; i++) {
2953 cmd = instance->cmd_list[i];
2954 if (cmd->sync_cmd == 1 || cmd->scmd) {
2955 printk(KERN_NOTICE "megasas: moving cmd[%d]:%p:%d:%p"
2956 "on the defer queue as internal\n",
2957 defer_index, cmd, cmd->sync_cmd, cmd->scmd);
2958
2959 if (!list_empty(&cmd->list)) {
2960 printk(KERN_NOTICE "megaraid_sas: ERROR while"
2961 " moving this cmd:%p, %d %p, it was"
2962 "discovered on some list?\n",
2963 cmd, cmd->sync_cmd, cmd->scmd);
2964
2965 list_del_init(&cmd->list);
2966 }
2967 defer_index++;
2968 list_add_tail(&cmd->list,
2969 &instance->internal_reset_pending_q);
2970 }
2971 }
2972 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
2973}
2974
2975
2976static void
2977process_fw_state_change_wq(struct work_struct *work)
2978{
2979 struct megasas_instance *instance =
2980 container_of(work, struct megasas_instance, work_init);
2981 u32 wait;
2982 unsigned long flags;
2983
2984 if (instance->adprecovery != MEGASAS_ADPRESET_SM_INFAULT) {
2985 printk(KERN_NOTICE "megaraid_sas: error, recovery st %x \n",
2986 instance->adprecovery);
2987 return ;
2988 }
2989
2990 if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) {
2991 printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault"
2992 "state, restarting it...\n");
2993
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05302994 instance->instancet->disable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04002995 atomic_set(&instance->fw_outstanding, 0);
2996
2997 atomic_set(&instance->fw_reset_no_pci_access, 1);
2998 instance->instancet->adp_reset(instance, instance->reg_set);
2999 atomic_set(&instance->fw_reset_no_pci_access, 0 );
3000
3001 printk(KERN_NOTICE "megaraid_sas: FW restarted successfully,"
3002 "initiating next stage...\n");
3003
3004 printk(KERN_NOTICE "megaraid_sas: HBA recovery state machine,"
3005 "state 2 starting...\n");
3006
3007 /*waitting for about 20 second before start the second init*/
3008 for (wait = 0; wait < 30; wait++) {
3009 msleep(1000);
3010 }
3011
adam radford058a8fa2011-10-08 18:14:27 -07003012 if (megasas_transition_to_ready(instance, 1)) {
bo yang39a98552010-09-22 22:36:29 -04003013 printk(KERN_NOTICE "megaraid_sas:adapter not ready\n");
3014
3015 megaraid_sas_kill_hba(instance);
3016 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
3017 return ;
3018 }
3019
3020 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
3021 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
3022 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)
3023 ) {
3024 *instance->consumer = *instance->producer;
3025 } else {
3026 *instance->consumer = 0;
3027 *instance->producer = 0;
3028 }
3029
3030 megasas_issue_init_mfi(instance);
3031
3032 spin_lock_irqsave(&instance->hba_lock, flags);
3033 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
3034 spin_unlock_irqrestore(&instance->hba_lock, flags);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303035 instance->instancet->enable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04003036
3037 megasas_issue_pending_cmds_again(instance);
3038 instance->issuepend_done = 1;
3039 }
3040 return ;
3041}
3042
3043/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003044 * megasas_deplete_reply_queue - Processes all completed commands
3045 * @instance: Adapter soft state
3046 * @alt_status: Alternate status to be returned to
3047 * SCSI mid-layer instead of the status
3048 * returned by the FW
bo yang39a98552010-09-22 22:36:29 -04003049 * Note: this must be called with hba lock held
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003050 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08003051static int
bo yang39a98552010-09-22 22:36:29 -04003052megasas_deplete_reply_queue(struct megasas_instance *instance,
3053 u8 alt_status)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003054{
bo yang39a98552010-09-22 22:36:29 -04003055 u32 mfiStatus;
3056 u32 fw_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003057
bo yang39a98552010-09-22 22:36:29 -04003058 if ((mfiStatus = instance->instancet->check_reset(instance,
3059 instance->reg_set)) == 1) {
3060 return IRQ_HANDLED;
3061 }
3062
3063 if ((mfiStatus = instance->instancet->clear_intr(
3064 instance->reg_set)
3065 ) == 0) {
adam radforde1419192011-02-24 20:56:21 -08003066 /* Hardware may not set outbound_intr_status in MSI-X mode */
adam radfordc8e858f2011-10-08 18:15:13 -07003067 if (!instance->msix_vectors)
adam radforde1419192011-02-24 20:56:21 -08003068 return IRQ_NONE;
bo yang39a98552010-09-22 22:36:29 -04003069 }
3070
3071 instance->mfiStatus = mfiStatus;
3072
3073 if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) {
3074 fw_state = instance->instancet->read_fw_status_reg(
3075 instance->reg_set) & MFI_STATE_MASK;
3076
3077 if (fw_state != MFI_STATE_FAULT) {
3078 printk(KERN_NOTICE "megaraid_sas: fw state:%x\n",
3079 fw_state);
3080 }
3081
3082 if ((fw_state == MFI_STATE_FAULT) &&
3083 (instance->disableOnlineCtrlReset == 0)) {
3084 printk(KERN_NOTICE "megaraid_sas: wait adp restart\n");
3085
3086 if ((instance->pdev->device ==
3087 PCI_DEVICE_ID_LSI_SAS1064R) ||
3088 (instance->pdev->device ==
3089 PCI_DEVICE_ID_DELL_PERC5) ||
3090 (instance->pdev->device ==
3091 PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
3092
3093 *instance->consumer =
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303094 cpu_to_le32(MEGASAS_ADPRESET_INPROG_SIGN);
bo yang39a98552010-09-22 22:36:29 -04003095 }
3096
3097
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303098 instance->instancet->disable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04003099 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
3100 instance->issuepend_done = 0;
3101
3102 atomic_set(&instance->fw_outstanding, 0);
3103 megasas_internal_reset_defer_cmds(instance);
3104
3105 printk(KERN_NOTICE "megasas: fwState=%x, stage:%d\n",
3106 fw_state, instance->adprecovery);
3107
3108 schedule_work(&instance->work_init);
3109 return IRQ_HANDLED;
3110
3111 } else {
3112 printk(KERN_NOTICE "megasas: fwstate:%x, dis_OCR=%x\n",
3113 fw_state, instance->disableOnlineCtrlReset);
3114 }
3115 }
3116
Sumant Patro5d018ad2006-10-03 13:13:18 -07003117 tasklet_schedule(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003118 return IRQ_HANDLED;
3119}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003120/**
3121 * megasas_isr - isr entry point
3122 */
David Howells7d12e782006-10-05 14:55:46 +01003123static irqreturn_t megasas_isr(int irq, void *devp)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003124{
adam radfordc8e858f2011-10-08 18:15:13 -07003125 struct megasas_irq_context *irq_context = devp;
3126 struct megasas_instance *instance = irq_context->instance;
bo yang39a98552010-09-22 22:36:29 -04003127 unsigned long flags;
3128 irqreturn_t rc;
3129
adam radfordc8e858f2011-10-08 18:15:13 -07003130 if (atomic_read(&instance->fw_reset_no_pci_access))
bo yang39a98552010-09-22 22:36:29 -04003131 return IRQ_HANDLED;
3132
bo yang39a98552010-09-22 22:36:29 -04003133 spin_lock_irqsave(&instance->hba_lock, flags);
3134 rc = megasas_deplete_reply_queue(instance, DID_OK);
3135 spin_unlock_irqrestore(&instance->hba_lock, flags);
3136
3137 return rc;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003138}
3139
3140/**
3141 * megasas_transition_to_ready - Move the FW to READY state
Sumant Patro1341c932006-01-25 12:02:40 -08003142 * @instance: Adapter soft state
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003143 *
3144 * During the initialization, FW passes can potentially be in any one of
3145 * several possible states. If the FW in operational, waiting-for-handshake
3146 * states, driver must take steps to bring it to ready state. Otherwise, it
3147 * has to wait for the ready state.
3148 */
adam radford9c915a82010-12-21 13:34:31 -08003149int
adam radford058a8fa2011-10-08 18:14:27 -07003150megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003151{
3152 int i;
3153 u8 max_wait;
3154 u32 fw_state;
3155 u32 cur_state;
Yang, Bo7218df62009-10-06 14:52:20 -06003156 u32 abs_state, curr_abs_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003157
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02003158 abs_state = instance->instancet->read_fw_status_reg(instance->reg_set);
3159 fw_state = abs_state & MFI_STATE_MASK;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003160
Sumant Patroe3bbff92006-10-03 12:28:49 -07003161 if (fw_state != MFI_STATE_READY)
adam radford0d490162010-12-14 19:17:17 -08003162 printk(KERN_INFO "megasas: Waiting for FW to come to ready"
3163 " state\n");
Sumant Patroe3bbff92006-10-03 12:28:49 -07003164
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003165 while (fw_state != MFI_STATE_READY) {
3166
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003167 switch (fw_state) {
3168
3169 case MFI_STATE_FAULT:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003170 printk(KERN_DEBUG "megasas: FW in FAULT state!!\n");
adam radford058a8fa2011-10-08 18:14:27 -07003171 if (ocr) {
3172 max_wait = MEGASAS_RESET_WAIT_TIME;
3173 cur_state = MFI_STATE_FAULT;
3174 break;
3175 } else
3176 return -ENODEV;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003177
3178 case MFI_STATE_WAIT_HANDSHAKE:
3179 /*
3180 * Set the CLR bit in inbound doorbell
3181 */
Yang, Bo0c79e682009-10-06 14:47:35 -06003182 if ((instance->pdev->device ==
Yang, Bo87911122009-10-06 14:31:54 -06003183 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3184 (instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003185 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
3186 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303187 PCI_DEVICE_ID_LSI_FUSION) ||
adam radford36807e62011-10-08 18:15:06 -07003188 (instance->pdev->device ==
adam radford229fe472014-03-10 02:51:56 -07003189 PCI_DEVICE_ID_LSI_PLASMA) ||
3190 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303191 PCI_DEVICE_ID_LSI_INVADER) ||
3192 (instance->pdev->device ==
3193 PCI_DEVICE_ID_LSI_FURY)) {
Yang, Bo87911122009-10-06 14:31:54 -06003194 writel(
3195 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
adam radford9c915a82010-12-21 13:34:31 -08003196 &instance->reg_set->doorbell);
Yang, Bo87911122009-10-06 14:31:54 -06003197 } else {
3198 writel(
3199 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
3200 &instance->reg_set->inbound_doorbell);
3201 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003202
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_WAIT_HANDSHAKE;
3205 break;
3206
Sumant Patroe3bbff92006-10-03 12:28:49 -07003207 case MFI_STATE_BOOT_MESSAGE_PENDING:
Yang, Bo87911122009-10-06 14:31:54 -06003208 if ((instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003209 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3210 (instance->pdev->device ==
3211 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
3212 (instance->pdev->device ==
adam radford36807e62011-10-08 18:15:06 -07003213 PCI_DEVICE_ID_LSI_FUSION) ||
3214 (instance->pdev->device ==
adam radford229fe472014-03-10 02:51:56 -07003215 PCI_DEVICE_ID_LSI_PLASMA) ||
3216 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303217 PCI_DEVICE_ID_LSI_INVADER) ||
3218 (instance->pdev->device ==
3219 PCI_DEVICE_ID_LSI_FURY)) {
Yang, Bo87911122009-10-06 14:31:54 -06003220 writel(MFI_INIT_HOTPLUG,
adam radford9c915a82010-12-21 13:34:31 -08003221 &instance->reg_set->doorbell);
Yang, Bo87911122009-10-06 14:31:54 -06003222 } else
3223 writel(MFI_INIT_HOTPLUG,
3224 &instance->reg_set->inbound_doorbell);
Sumant Patroe3bbff92006-10-03 12:28:49 -07003225
Yang, Bo7218df62009-10-06 14:52:20 -06003226 max_wait = MEGASAS_RESET_WAIT_TIME;
Sumant Patroe3bbff92006-10-03 12:28:49 -07003227 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
3228 break;
3229
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003230 case MFI_STATE_OPERATIONAL:
3231 /*
Sumant Patroe3bbff92006-10-03 12:28:49 -07003232 * Bring it to READY state; assuming max wait 10 secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003233 */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303234 instance->instancet->disable_intr(instance);
Yang, Bo87911122009-10-06 14:31:54 -06003235 if ((instance->pdev->device ==
3236 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3237 (instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08003238 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
3239 (instance->pdev->device
adam radford36807e62011-10-08 18:15:06 -07003240 == PCI_DEVICE_ID_LSI_FUSION) ||
3241 (instance->pdev->device
adam radford229fe472014-03-10 02:51:56 -07003242 == PCI_DEVICE_ID_LSI_PLASMA) ||
3243 (instance->pdev->device
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303244 == PCI_DEVICE_ID_LSI_INVADER) ||
3245 (instance->pdev->device
3246 == PCI_DEVICE_ID_LSI_FURY)) {
Yang, Bo87911122009-10-06 14:31:54 -06003247 writel(MFI_RESET_FLAGS,
adam radford9c915a82010-12-21 13:34:31 -08003248 &instance->reg_set->doorbell);
adam radford36807e62011-10-08 18:15:06 -07003249 if ((instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303250 PCI_DEVICE_ID_LSI_FUSION) ||
3251 (instance->pdev->device ==
adam radford229fe472014-03-10 02:51:56 -07003252 PCI_DEVICE_ID_LSI_PLASMA) ||
3253 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303254 PCI_DEVICE_ID_LSI_INVADER) ||
3255 (instance->pdev->device ==
3256 PCI_DEVICE_ID_LSI_FURY)) {
adam radford9c915a82010-12-21 13:34:31 -08003257 for (i = 0; i < (10 * 1000); i += 20) {
3258 if (readl(
3259 &instance->
3260 reg_set->
3261 doorbell) & 1)
3262 msleep(20);
3263 else
3264 break;
3265 }
3266 }
Yang, Bo87911122009-10-06 14:31:54 -06003267 } else
3268 writel(MFI_RESET_FLAGS,
3269 &instance->reg_set->inbound_doorbell);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003270
Yang, Bo7218df62009-10-06 14:52:20 -06003271 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003272 cur_state = MFI_STATE_OPERATIONAL;
3273 break;
3274
3275 case MFI_STATE_UNDEFINED:
3276 /*
3277 * This state should not last for more than 2 seconds
3278 */
Yang, Bo7218df62009-10-06 14:52:20 -06003279 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003280 cur_state = MFI_STATE_UNDEFINED;
3281 break;
3282
3283 case MFI_STATE_BB_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06003284 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003285 cur_state = MFI_STATE_BB_INIT;
3286 break;
3287
3288 case MFI_STATE_FW_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06003289 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003290 cur_state = MFI_STATE_FW_INIT;
3291 break;
3292
3293 case MFI_STATE_FW_INIT_2:
Yang, Bo7218df62009-10-06 14:52:20 -06003294 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003295 cur_state = MFI_STATE_FW_INIT_2;
3296 break;
3297
3298 case MFI_STATE_DEVICE_SCAN:
Yang, Bo7218df62009-10-06 14:52:20 -06003299 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003300 cur_state = MFI_STATE_DEVICE_SCAN;
3301 break;
3302
3303 case MFI_STATE_FLUSH_CACHE:
Yang, Bo7218df62009-10-06 14:52:20 -06003304 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003305 cur_state = MFI_STATE_FLUSH_CACHE;
3306 break;
3307
3308 default:
3309 printk(KERN_DEBUG "megasas: Unknown state 0x%x\n",
3310 fw_state);
3311 return -ENODEV;
3312 }
3313
3314 /*
3315 * The cur_state should not last for more than max_wait secs
3316 */
3317 for (i = 0; i < (max_wait * 1000); i++) {
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02003318 curr_abs_state = instance->instancet->
3319 read_fw_status_reg(instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003320
Yang, Bo7218df62009-10-06 14:52:20 -06003321 if (abs_state == curr_abs_state) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003322 msleep(1);
3323 } else
3324 break;
3325 }
3326
3327 /*
3328 * Return error if fw_state hasn't changed after max_wait
3329 */
Yang, Bo7218df62009-10-06 14:52:20 -06003330 if (curr_abs_state == abs_state) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003331 printk(KERN_DEBUG "FW state [%d] hasn't changed "
3332 "in %d secs\n", fw_state, max_wait);
3333 return -ENODEV;
3334 }
Tomas Henzlbc6ac5e2014-04-01 13:59:50 +02003335
3336 abs_state = curr_abs_state;
3337 fw_state = curr_abs_state & MFI_STATE_MASK;
bo yang39a98552010-09-22 22:36:29 -04003338 }
adam radford0d490162010-12-14 19:17:17 -08003339 printk(KERN_INFO "megasas: FW now in Ready state\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003340
3341 return 0;
3342}
3343
3344/**
3345 * megasas_teardown_frame_pool - Destroy the cmd frame DMA pool
3346 * @instance: Adapter soft state
3347 */
3348static void megasas_teardown_frame_pool(struct megasas_instance *instance)
3349{
3350 int i;
adam radford9c915a82010-12-21 13:34:31 -08003351 u32 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003352 struct megasas_cmd *cmd;
3353
3354 if (!instance->frame_dma_pool)
3355 return;
3356
3357 /*
3358 * Return all frames to pool
3359 */
3360 for (i = 0; i < max_cmd; i++) {
3361
3362 cmd = instance->cmd_list[i];
3363
3364 if (cmd->frame)
3365 pci_pool_free(instance->frame_dma_pool, cmd->frame,
3366 cmd->frame_phys_addr);
3367
3368 if (cmd->sense)
Sumant Patroe3bbff92006-10-03 12:28:49 -07003369 pci_pool_free(instance->sense_dma_pool, cmd->sense,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003370 cmd->sense_phys_addr);
3371 }
3372
3373 /*
3374 * Now destroy the pool itself
3375 */
3376 pci_pool_destroy(instance->frame_dma_pool);
3377 pci_pool_destroy(instance->sense_dma_pool);
3378
3379 instance->frame_dma_pool = NULL;
3380 instance->sense_dma_pool = NULL;
3381}
3382
3383/**
3384 * megasas_create_frame_pool - Creates DMA pool for cmd frames
3385 * @instance: Adapter soft state
3386 *
3387 * Each command packet has an embedded DMA memory buffer that is used for
3388 * filling MFI frame and the SG list that immediately follows the frame. This
3389 * function creates those DMA memory buffers for each command packet by using
3390 * PCI pool facility.
3391 */
3392static int megasas_create_frame_pool(struct megasas_instance *instance)
3393{
3394 int i;
3395 u32 max_cmd;
3396 u32 sge_sz;
3397 u32 sgl_sz;
3398 u32 total_sz;
3399 u32 frame_count;
3400 struct megasas_cmd *cmd;
3401
adam radford9c915a82010-12-21 13:34:31 -08003402 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003403
3404 /*
3405 * Size of our frame is 64 bytes for MFI frame, followed by max SG
3406 * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer
3407 */
3408 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
3409 sizeof(struct megasas_sge32);
3410
Yang, Bof4c9a132009-10-06 14:43:28 -06003411 if (instance->flag_ieee) {
3412 sge_sz = sizeof(struct megasas_sge_skinny);
3413 }
3414
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003415 /*
3416 * Calculated the number of 64byte frames required for SGL
3417 */
3418 sgl_sz = sge_sz * instance->max_num_sge;
3419 frame_count = (sgl_sz + MEGAMFI_FRAME_SIZE - 1) / MEGAMFI_FRAME_SIZE;
bo yang39a98552010-09-22 22:36:29 -04003420 frame_count = 15;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003421
3422 /*
3423 * We need one extra frame for the MFI command
3424 */
3425 frame_count++;
3426
3427 total_sz = MEGAMFI_FRAME_SIZE * frame_count;
3428 /*
3429 * Use DMA pool facility provided by PCI layer
3430 */
3431 instance->frame_dma_pool = pci_pool_create("megasas frame pool",
3432 instance->pdev, total_sz, 64,
3433 0);
3434
3435 if (!instance->frame_dma_pool) {
3436 printk(KERN_DEBUG "megasas: failed to setup frame pool\n");
3437 return -ENOMEM;
3438 }
3439
3440 instance->sense_dma_pool = pci_pool_create("megasas sense pool",
3441 instance->pdev, 128, 4, 0);
3442
3443 if (!instance->sense_dma_pool) {
3444 printk(KERN_DEBUG "megasas: failed to setup sense pool\n");
3445
3446 pci_pool_destroy(instance->frame_dma_pool);
3447 instance->frame_dma_pool = NULL;
3448
3449 return -ENOMEM;
3450 }
3451
3452 /*
3453 * Allocate and attach a frame to each of the commands in cmd_list.
3454 * By making cmd->index as the context instead of the &cmd, we can
3455 * always use 32bit context regardless of the architecture
3456 */
3457 for (i = 0; i < max_cmd; i++) {
3458
3459 cmd = instance->cmd_list[i];
3460
3461 cmd->frame = pci_pool_alloc(instance->frame_dma_pool,
3462 GFP_KERNEL, &cmd->frame_phys_addr);
3463
3464 cmd->sense = pci_pool_alloc(instance->sense_dma_pool,
3465 GFP_KERNEL, &cmd->sense_phys_addr);
3466
3467 /*
3468 * megasas_teardown_frame_pool() takes care of freeing
3469 * whatever has been allocated
3470 */
3471 if (!cmd->frame || !cmd->sense) {
3472 printk(KERN_DEBUG "megasas: pci_pool_alloc failed \n");
3473 megasas_teardown_frame_pool(instance);
3474 return -ENOMEM;
3475 }
3476
Yang, Bo707e09b2010-10-12 07:20:27 -06003477 memset(cmd->frame, 0, total_sz);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303478 cmd->frame->io.context = cpu_to_le32(cmd->index);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06003479 cmd->frame->io.pad_0 = 0;
adam radforde5f93a32011-10-08 18:15:19 -07003480 if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
adam radford229fe472014-03-10 02:51:56 -07003481 (instance->pdev->device != PCI_DEVICE_ID_LSI_PLASMA) &&
adam radforde5f93a32011-10-08 18:15:19 -07003482 (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303483 (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
adam radforde5f93a32011-10-08 18:15:19 -07003484 (reset_devices))
3485 cmd->frame->hdr.cmd = MFI_CMD_INVALID;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003486 }
3487
3488 return 0;
3489}
3490
3491/**
3492 * megasas_free_cmds - Free all the cmds in the free cmd pool
3493 * @instance: Adapter soft state
3494 */
adam radford9c915a82010-12-21 13:34:31 -08003495void megasas_free_cmds(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003496{
3497 int i;
3498 /* First free the MFI frame pool */
3499 megasas_teardown_frame_pool(instance);
3500
3501 /* Free all the commands in the cmd_list */
adam radford9c915a82010-12-21 13:34:31 -08003502 for (i = 0; i < instance->max_mfi_cmds; i++)
3503
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003504 kfree(instance->cmd_list[i]);
3505
3506 /* Free the cmd_list buffer itself */
3507 kfree(instance->cmd_list);
3508 instance->cmd_list = NULL;
3509
3510 INIT_LIST_HEAD(&instance->cmd_pool);
3511}
3512
3513/**
3514 * megasas_alloc_cmds - Allocates the command packets
3515 * @instance: Adapter soft state
3516 *
3517 * Each command that is issued to the FW, whether IO commands from the OS or
3518 * internal commands like IOCTLs, are wrapped in local data structure called
3519 * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to
3520 * the FW.
3521 *
3522 * Each frame has a 32-bit field called context (tag). This context is used
3523 * to get back the megasas_cmd from the frame when a frame gets completed in
3524 * the ISR. Typically the address of the megasas_cmd itself would be used as
3525 * the context. But we wanted to keep the differences between 32 and 64 bit
3526 * systems to the mininum. We always use 32 bit integers for the context. In
3527 * this driver, the 32 bit values are the indices into an array cmd_list.
3528 * This array is used only to look up the megasas_cmd given the context. The
3529 * free commands themselves are maintained in a linked list called cmd_pool.
3530 */
adam radford9c915a82010-12-21 13:34:31 -08003531int megasas_alloc_cmds(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003532{
3533 int i;
3534 int j;
3535 u32 max_cmd;
3536 struct megasas_cmd *cmd;
3537
adam radford9c915a82010-12-21 13:34:31 -08003538 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003539
3540 /*
3541 * instance->cmd_list is an array of struct megasas_cmd pointers.
3542 * Allocate the dynamic array first and then allocate individual
3543 * commands.
3544 */
Yoann Padioleaudd00cc42007-07-19 01:49:03 -07003545 instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003546
3547 if (!instance->cmd_list) {
3548 printk(KERN_DEBUG "megasas: out of memory\n");
3549 return -ENOMEM;
3550 }
3551
adam radford9c915a82010-12-21 13:34:31 -08003552 memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) *max_cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003553
3554 for (i = 0; i < max_cmd; i++) {
3555 instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd),
3556 GFP_KERNEL);
3557
3558 if (!instance->cmd_list[i]) {
3559
3560 for (j = 0; j < i; j++)
3561 kfree(instance->cmd_list[j]);
3562
3563 kfree(instance->cmd_list);
3564 instance->cmd_list = NULL;
3565
3566 return -ENOMEM;
3567 }
3568 }
3569
3570 /*
3571 * Add all the commands to command pool (instance->cmd_pool)
3572 */
3573 for (i = 0; i < max_cmd; i++) {
3574 cmd = instance->cmd_list[i];
3575 memset(cmd, 0, sizeof(struct megasas_cmd));
3576 cmd->index = i;
bo yang39a98552010-09-22 22:36:29 -04003577 cmd->scmd = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003578 cmd->instance = instance;
3579
3580 list_add_tail(&cmd->list, &instance->cmd_pool);
3581 }
3582
3583 /*
3584 * Create a frame pool and assign one frame to each cmd
3585 */
3586 if (megasas_create_frame_pool(instance)) {
3587 printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n");
3588 megasas_free_cmds(instance);
3589 }
3590
3591 return 0;
3592}
3593
Yang, Bo81e403c2009-10-06 14:27:54 -06003594/*
3595 * megasas_get_pd_list_info - Returns FW's pd_list structure
3596 * @instance: Adapter soft state
3597 * @pd_list: pd_list structure
3598 *
3599 * Issues an internal command (DCMD) to get the FW's controller PD
3600 * list structure. This information is mainly used to find out SYSTEM
3601 * supported by the FW.
3602 */
3603static int
3604megasas_get_pd_list(struct megasas_instance *instance)
3605{
3606 int ret = 0, pd_index = 0;
3607 struct megasas_cmd *cmd;
3608 struct megasas_dcmd_frame *dcmd;
3609 struct MR_PD_LIST *ci;
3610 struct MR_PD_ADDRESS *pd_addr;
3611 dma_addr_t ci_h = 0;
3612
3613 cmd = megasas_get_cmd(instance);
3614
3615 if (!cmd) {
3616 printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
3617 return -ENOMEM;
3618 }
3619
3620 dcmd = &cmd->frame->dcmd;
3621
3622 ci = pci_alloc_consistent(instance->pdev,
3623 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
3624
3625 if (!ci) {
3626 printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
3627 megasas_return_cmd(instance, cmd);
3628 return -ENOMEM;
3629 }
3630
3631 memset(ci, 0, sizeof(*ci));
3632 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3633
3634 dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
3635 dcmd->mbox.b[1] = 0;
3636 dcmd->cmd = MFI_CMD_DCMD;
3637 dcmd->cmd_status = 0xFF;
3638 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303639 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
Yang, Bo81e403c2009-10-06 14:27:54 -06003640 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003641 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303642 dcmd->data_xfer_len = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST));
3643 dcmd->opcode = cpu_to_le32(MR_DCMD_PD_LIST_QUERY);
3644 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
3645 dcmd->sgl.sge32[0].length = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST));
Yang, Bo81e403c2009-10-06 14:27:54 -06003646
3647 if (!megasas_issue_polled(instance, cmd)) {
3648 ret = 0;
3649 } else {
3650 ret = -1;
3651 }
3652
3653 /*
3654 * the following function will get the instance PD LIST.
3655 */
3656
3657 pd_addr = ci->addr;
3658
3659 if ( ret == 0 &&
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303660 (le32_to_cpu(ci->count) <
Yang, Bo81e403c2009-10-06 14:27:54 -06003661 (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
3662
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05303663 memset(instance->local_pd_list, 0,
Yang, Bo81e403c2009-10-06 14:27:54 -06003664 MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
3665
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303666 for (pd_index = 0; pd_index < le32_to_cpu(ci->count); pd_index++) {
Yang, Bo81e403c2009-10-06 14:27:54 -06003667
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05303668 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].tid =
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303669 le16_to_cpu(pd_addr->deviceId);
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05303670 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveType =
Yang, Bo81e403c2009-10-06 14:27:54 -06003671 pd_addr->scsiDevType;
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05303672 instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveState =
Yang, Bo81e403c2009-10-06 14:27:54 -06003673 MR_PD_STATE_SYSTEM;
3674 pd_addr++;
3675 }
Sumit.Saxena@lsi.com999ece02013-10-18 12:50:37 +05303676 memcpy(instance->pd_list, instance->local_pd_list,
3677 sizeof(instance->pd_list));
Yang, Bo81e403c2009-10-06 14:27:54 -06003678 }
3679
3680 pci_free_consistent(instance->pdev,
3681 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
3682 ci, ci_h);
3683 megasas_return_cmd(instance, cmd);
3684
3685 return ret;
3686}
3687
Yang, Bobdc6fb82009-12-06 08:30:19 -07003688/*
3689 * megasas_get_ld_list_info - Returns FW's ld_list structure
3690 * @instance: Adapter soft state
3691 * @ld_list: ld_list structure
3692 *
3693 * Issues an internal command (DCMD) to get the FW's controller PD
3694 * list structure. This information is mainly used to find out SYSTEM
3695 * supported by the FW.
3696 */
3697static int
3698megasas_get_ld_list(struct megasas_instance *instance)
3699{
3700 int ret = 0, ld_index = 0, ids = 0;
3701 struct megasas_cmd *cmd;
3702 struct megasas_dcmd_frame *dcmd;
3703 struct MR_LD_LIST *ci;
3704 dma_addr_t ci_h = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303705 u32 ld_count;
Yang, Bobdc6fb82009-12-06 08:30:19 -07003706
3707 cmd = megasas_get_cmd(instance);
3708
3709 if (!cmd) {
3710 printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n");
3711 return -ENOMEM;
3712 }
3713
3714 dcmd = &cmd->frame->dcmd;
3715
3716 ci = pci_alloc_consistent(instance->pdev,
3717 sizeof(struct MR_LD_LIST),
3718 &ci_h);
3719
3720 if (!ci) {
3721 printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n");
3722 megasas_return_cmd(instance, cmd);
3723 return -ENOMEM;
3724 }
3725
3726 memset(ci, 0, sizeof(*ci));
3727 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3728
3729 dcmd->cmd = MFI_CMD_DCMD;
3730 dcmd->cmd_status = 0xFF;
3731 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303732 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
Yang, Bobdc6fb82009-12-06 08:30:19 -07003733 dcmd->timeout = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303734 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_LIST));
3735 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_GET_LIST);
3736 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
3737 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_LD_LIST));
Yang, Bobdc6fb82009-12-06 08:30:19 -07003738 dcmd->pad_0 = 0;
3739
3740 if (!megasas_issue_polled(instance, cmd)) {
3741 ret = 0;
3742 } else {
3743 ret = -1;
3744 }
3745
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303746 ld_count = le32_to_cpu(ci->ldCount);
3747
Yang, Bobdc6fb82009-12-06 08:30:19 -07003748 /* the following function will get the instance PD LIST */
3749
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303750 if ((ret == 0) && (ld_count <= MAX_LOGICAL_DRIVES)) {
Yang, Bobdc6fb82009-12-06 08:30:19 -07003751 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
3752
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303753 for (ld_index = 0; ld_index < ld_count; ld_index++) {
Yang, Bobdc6fb82009-12-06 08:30:19 -07003754 if (ci->ldList[ld_index].state != 0) {
3755 ids = ci->ldList[ld_index].ref.targetId;
3756 instance->ld_ids[ids] =
3757 ci->ldList[ld_index].ref.targetId;
3758 }
3759 }
3760 }
3761
3762 pci_free_consistent(instance->pdev,
3763 sizeof(struct MR_LD_LIST),
3764 ci,
3765 ci_h);
3766
3767 megasas_return_cmd(instance, cmd);
3768 return ret;
3769}
3770
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003771/**
adam radford21c9e162013-09-06 15:27:14 -07003772 * megasas_ld_list_query - Returns FW's ld_list structure
3773 * @instance: Adapter soft state
3774 * @ld_list: ld_list structure
3775 *
3776 * Issues an internal command (DCMD) to get the FW's controller PD
3777 * list structure. This information is mainly used to find out SYSTEM
3778 * supported by the FW.
3779 */
3780static int
3781megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
3782{
3783 int ret = 0, ld_index = 0, ids = 0;
3784 struct megasas_cmd *cmd;
3785 struct megasas_dcmd_frame *dcmd;
3786 struct MR_LD_TARGETID_LIST *ci;
3787 dma_addr_t ci_h = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303788 u32 tgtid_count;
adam radford21c9e162013-09-06 15:27:14 -07003789
3790 cmd = megasas_get_cmd(instance);
3791
3792 if (!cmd) {
3793 printk(KERN_WARNING
3794 "megasas:(megasas_ld_list_query): Failed to get cmd\n");
3795 return -ENOMEM;
3796 }
3797
3798 dcmd = &cmd->frame->dcmd;
3799
3800 ci = pci_alloc_consistent(instance->pdev,
3801 sizeof(struct MR_LD_TARGETID_LIST), &ci_h);
3802
3803 if (!ci) {
3804 printk(KERN_WARNING
3805 "megasas: Failed to alloc mem for ld_list_query\n");
3806 megasas_return_cmd(instance, cmd);
3807 return -ENOMEM;
3808 }
3809
3810 memset(ci, 0, sizeof(*ci));
3811 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3812
3813 dcmd->mbox.b[0] = query_type;
3814
3815 dcmd->cmd = MFI_CMD_DCMD;
3816 dcmd->cmd_status = 0xFF;
3817 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303818 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
adam radford21c9e162013-09-06 15:27:14 -07003819 dcmd->timeout = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303820 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST));
3821 dcmd->opcode = cpu_to_le32(MR_DCMD_LD_LIST_QUERY);
3822 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
3823 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST));
adam radford21c9e162013-09-06 15:27:14 -07003824 dcmd->pad_0 = 0;
3825
3826 if (!megasas_issue_polled(instance, cmd) && !dcmd->cmd_status) {
3827 ret = 0;
3828 } else {
3829 /* On failure, call older LD list DCMD */
3830 ret = 1;
3831 }
3832
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303833 tgtid_count = le32_to_cpu(ci->count);
3834
3835 if ((ret == 0) && (tgtid_count <= (MAX_LOGICAL_DRIVES))) {
adam radford21c9e162013-09-06 15:27:14 -07003836 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303837 for (ld_index = 0; ld_index < tgtid_count; ld_index++) {
adam radford21c9e162013-09-06 15:27:14 -07003838 ids = ci->targetId[ld_index];
3839 instance->ld_ids[ids] = ci->targetId[ld_index];
3840 }
3841
3842 }
3843
3844 pci_free_consistent(instance->pdev, sizeof(struct MR_LD_TARGETID_LIST),
3845 ci, ci_h);
3846
3847 megasas_return_cmd(instance, cmd);
3848
3849 return ret;
3850}
3851
3852/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003853 * megasas_get_controller_info - Returns FW's controller structure
3854 * @instance: Adapter soft state
3855 * @ctrl_info: Controller information structure
3856 *
3857 * Issues an internal command (DCMD) to get the FW's controller structure.
3858 * This information is mainly used to find out the maximum IO transfer per
3859 * command supported by the FW.
3860 */
3861static int
3862megasas_get_ctrl_info(struct megasas_instance *instance,
3863 struct megasas_ctrl_info *ctrl_info)
3864{
3865 int ret = 0;
3866 struct megasas_cmd *cmd;
3867 struct megasas_dcmd_frame *dcmd;
3868 struct megasas_ctrl_info *ci;
3869 dma_addr_t ci_h = 0;
3870
3871 cmd = megasas_get_cmd(instance);
3872
3873 if (!cmd) {
3874 printk(KERN_DEBUG "megasas: Failed to get a free cmd\n");
3875 return -ENOMEM;
3876 }
3877
3878 dcmd = &cmd->frame->dcmd;
3879
3880 ci = pci_alloc_consistent(instance->pdev,
3881 sizeof(struct megasas_ctrl_info), &ci_h);
3882
3883 if (!ci) {
3884 printk(KERN_DEBUG "Failed to alloc mem for ctrl info\n");
3885 megasas_return_cmd(instance, cmd);
3886 return -ENOMEM;
3887 }
3888
3889 memset(ci, 0, sizeof(*ci));
3890 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3891
3892 dcmd->cmd = MFI_CMD_DCMD;
3893 dcmd->cmd_status = 0xFF;
3894 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303895 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003896 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003897 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303898 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_ctrl_info));
3899 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_GET_INFO);
3900 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
3901 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_ctrl_info));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003902
3903 if (!megasas_issue_polled(instance, cmd)) {
3904 ret = 0;
3905 memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info));
3906 } else {
3907 ret = -1;
3908 }
3909
3910 pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
3911 ci, ci_h);
3912
3913 megasas_return_cmd(instance, cmd);
3914 return ret;
3915}
3916
3917/**
bo yang31ea7082007-11-07 12:09:50 -05003918 * megasas_issue_init_mfi - Initializes the FW
3919 * @instance: Adapter soft state
3920 *
3921 * Issues the INIT MFI cmd
3922 */
3923static int
3924megasas_issue_init_mfi(struct megasas_instance *instance)
3925{
3926 u32 context;
3927
3928 struct megasas_cmd *cmd;
3929
3930 struct megasas_init_frame *init_frame;
3931 struct megasas_init_queue_info *initq_info;
3932 dma_addr_t init_frame_h;
3933 dma_addr_t initq_info_h;
3934
3935 /*
3936 * Prepare a init frame. Note the init frame points to queue info
3937 * structure. Each frame has SGL allocated after first 64 bytes. For
3938 * this frame - since we don't need any SGL - we use SGL's space as
3939 * queue info structure
3940 *
3941 * We will not get a NULL command below. We just created the pool.
3942 */
3943 cmd = megasas_get_cmd(instance);
3944
3945 init_frame = (struct megasas_init_frame *)cmd->frame;
3946 initq_info = (struct megasas_init_queue_info *)
3947 ((unsigned long)init_frame + 64);
3948
3949 init_frame_h = cmd->frame_phys_addr;
3950 initq_info_h = init_frame_h + 64;
3951
3952 context = init_frame->context;
3953 memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
3954 memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
3955 init_frame->context = context;
3956
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303957 initq_info->reply_queue_entries = cpu_to_le32(instance->max_fw_cmds + 1);
3958 initq_info->reply_queue_start_phys_addr_lo = cpu_to_le32(instance->reply_queue_h);
bo yang31ea7082007-11-07 12:09:50 -05003959
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303960 initq_info->producer_index_phys_addr_lo = cpu_to_le32(instance->producer_h);
3961 initq_info->consumer_index_phys_addr_lo = cpu_to_le32(instance->consumer_h);
bo yang31ea7082007-11-07 12:09:50 -05003962
3963 init_frame->cmd = MFI_CMD_INIT;
3964 init_frame->cmd_status = 0xFF;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303965 init_frame->queue_info_new_phys_addr_lo =
3966 cpu_to_le32(lower_32_bits(initq_info_h));
3967 init_frame->queue_info_new_phys_addr_hi =
3968 cpu_to_le32(upper_32_bits(initq_info_h));
bo yang31ea7082007-11-07 12:09:50 -05003969
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05303970 init_frame->data_xfer_len = cpu_to_le32(sizeof(struct megasas_init_queue_info));
bo yang31ea7082007-11-07 12:09:50 -05003971
3972 /*
3973 * disable the intr before firing the init frame to FW
3974 */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303975 instance->instancet->disable_intr(instance);
bo yang31ea7082007-11-07 12:09:50 -05003976
3977 /*
3978 * Issue the init frame in polled mode
3979 */
3980
3981 if (megasas_issue_polled(instance, cmd)) {
3982 printk(KERN_ERR "megasas: Failed to init firmware\n");
3983 megasas_return_cmd(instance, cmd);
3984 goto fail_fw_init;
3985 }
3986
3987 megasas_return_cmd(instance, cmd);
3988
3989 return 0;
3990
3991fail_fw_init:
3992 return -EINVAL;
3993}
3994
adam radfordcd50ba82010-12-21 10:23:23 -08003995static u32
3996megasas_init_adapter_mfi(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003997{
adam radfordcd50ba82010-12-21 10:23:23 -08003998 struct megasas_register_set __iomem *reg_set;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003999 u32 context_sz;
4000 u32 reply_q_sz;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004001
4002 reg_set = instance->reg_set;
4003
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004004 /*
4005 * Get various operational parameters from status register
4006 */
Sumant Patro1341c932006-01-25 12:02:40 -08004007 instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
Sumant Patroe3bbff92006-10-03 12:28:49 -07004008 /*
4009 * Reduce the max supported cmds by 1. This is to ensure that the
4010 * reply_q_sz (1 more than the max cmd that driver may send)
4011 * does not exceed max cmds that the FW can support
4012 */
4013 instance->max_fw_cmds = instance->max_fw_cmds-1;
adam radford9c915a82010-12-21 13:34:31 -08004014 instance->max_mfi_cmds = instance->max_fw_cmds;
adam radford0d490162010-12-14 19:17:17 -08004015 instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
Sumant Patro1341c932006-01-25 12:02:40 -08004016 0x10;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004017 /*
4018 * Create a pool of commands
4019 */
4020 if (megasas_alloc_cmds(instance))
4021 goto fail_alloc_cmds;
4022
4023 /*
4024 * Allocate memory for reply queue. Length of reply queue should
4025 * be _one_ more than the maximum commands handled by the firmware.
4026 *
4027 * Note: When FW completes commands, it places corresponding contex
4028 * values in this circular reply queue. This circular queue is a fairly
4029 * typical producer-consumer queue. FW is the producer (of completed
4030 * commands) and the driver is the consumer.
4031 */
4032 context_sz = sizeof(u32);
4033 reply_q_sz = context_sz * (instance->max_fw_cmds + 1);
4034
4035 instance->reply_queue = pci_alloc_consistent(instance->pdev,
4036 reply_q_sz,
4037 &instance->reply_queue_h);
4038
4039 if (!instance->reply_queue) {
4040 printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n");
4041 goto fail_reply_queue;
4042 }
4043
bo yang31ea7082007-11-07 12:09:50 -05004044 if (megasas_issue_init_mfi(instance))
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004045 goto fail_fw_init;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004046
bo yang39a98552010-09-22 22:36:29 -04004047 instance->fw_support_ieee = 0;
4048 instance->fw_support_ieee =
4049 (instance->instancet->read_fw_status_reg(reg_set) &
4050 0x04000000);
4051
4052 printk(KERN_NOTICE "megasas_init_mfi: fw_support_ieee=%d",
4053 instance->fw_support_ieee);
4054
4055 if (instance->fw_support_ieee)
4056 instance->flag_ieee = 1;
4057
adam radfordcd50ba82010-12-21 10:23:23 -08004058 return 0;
4059
4060fail_fw_init:
4061
4062 pci_free_consistent(instance->pdev, reply_q_sz,
4063 instance->reply_queue, instance->reply_queue_h);
4064fail_reply_queue:
4065 megasas_free_cmds(instance);
4066
4067fail_alloc_cmds:
adam radfordcd50ba82010-12-21 10:23:23 -08004068 return 1;
4069}
4070
4071/**
4072 * megasas_init_fw - Initializes the FW
4073 * @instance: Adapter soft state
4074 *
4075 * This is the main function for initializing firmware
4076 */
4077
4078static int megasas_init_fw(struct megasas_instance *instance)
4079{
4080 u32 max_sectors_1;
4081 u32 max_sectors_2;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304082 u32 tmp_sectors, msix_enable, scratch_pad_2;
Ben Collins11f8a7b2013-09-13 12:46:44 -04004083 resource_size_t base_addr;
adam radfordcd50ba82010-12-21 10:23:23 -08004084 struct megasas_register_set __iomem *reg_set;
4085 struct megasas_ctrl_info *ctrl_info;
4086 unsigned long bar_list;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304087 int i, loop, fw_msix_count = 0;
adam radford229fe472014-03-10 02:51:56 -07004088 struct IOV_111 *iovPtr;
adam radfordcd50ba82010-12-21 10:23:23 -08004089
4090 /* Find first memory bar */
4091 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
4092 instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
adam radfordcd50ba82010-12-21 10:23:23 -08004093 if (pci_request_selected_regions(instance->pdev, instance->bar,
4094 "megasas: LSI")) {
4095 printk(KERN_DEBUG "megasas: IO memory region busy!\n");
4096 return -EBUSY;
4097 }
4098
Ben Collins11f8a7b2013-09-13 12:46:44 -04004099 base_addr = pci_resource_start(instance->pdev, instance->bar);
4100 instance->reg_set = ioremap_nocache(base_addr, 8192);
adam radfordcd50ba82010-12-21 10:23:23 -08004101
4102 if (!instance->reg_set) {
4103 printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
4104 goto fail_ioremap;
4105 }
4106
4107 reg_set = instance->reg_set;
4108
4109 switch (instance->pdev->device) {
adam radford9c915a82010-12-21 13:34:31 -08004110 case PCI_DEVICE_ID_LSI_FUSION:
adam radford229fe472014-03-10 02:51:56 -07004111 case PCI_DEVICE_ID_LSI_PLASMA:
adam radford36807e62011-10-08 18:15:06 -07004112 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304113 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08004114 instance->instancet = &megasas_instance_template_fusion;
4115 break;
adam radfordcd50ba82010-12-21 10:23:23 -08004116 case PCI_DEVICE_ID_LSI_SAS1078R:
4117 case PCI_DEVICE_ID_LSI_SAS1078DE:
4118 instance->instancet = &megasas_instance_template_ppc;
4119 break;
4120 case PCI_DEVICE_ID_LSI_SAS1078GEN2:
4121 case PCI_DEVICE_ID_LSI_SAS0079GEN2:
4122 instance->instancet = &megasas_instance_template_gen2;
4123 break;
4124 case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
4125 case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
4126 instance->instancet = &megasas_instance_template_skinny;
4127 break;
4128 case PCI_DEVICE_ID_LSI_SAS1064R:
4129 case PCI_DEVICE_ID_DELL_PERC5:
4130 default:
4131 instance->instancet = &megasas_instance_template_xscale;
4132 break;
4133 }
4134
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05304135 if (megasas_transition_to_ready(instance, 0)) {
4136 atomic_set(&instance->fw_reset_no_pci_access, 1);
4137 instance->instancet->adp_reset
4138 (instance, instance->reg_set);
4139 atomic_set(&instance->fw_reset_no_pci_access, 0);
4140 dev_info(&instance->pdev->dev,
4141 "megasas: FW restarted successfully from %s!\n",
4142 __func__);
4143
4144 /*waitting for about 30 second before retry*/
4145 ssleep(30);
4146
4147 if (megasas_transition_to_ready(instance, 0))
4148 goto fail_ready_state;
4149 }
adam radfordcd50ba82010-12-21 10:23:23 -08004150
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304151 /*
4152 * MSI-X host index 0 is common for all adapter.
4153 * It is used for all MPT based Adapters.
4154 */
4155 instance->reply_post_host_index_addr[0] =
4156 (u32 *)((u8 *)instance->reg_set +
4157 MPI2_REPLY_POST_HOST_INDEX_OFFSET);
4158
adam radford3f1abce2011-05-11 18:33:47 -07004159 /* Check if MSI-X is supported while in ready state */
4160 msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
4161 0x4000000) >> 0x1a;
adam radfordc8e858f2011-10-08 18:15:13 -07004162 if (msix_enable && !msix_disable) {
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304163 scratch_pad_2 = readl
4164 (&instance->reg_set->outbound_scratch_pad_2);
adam radfordc8e858f2011-10-08 18:15:13 -07004165 /* Check max MSI-X vectors */
adam radford229fe472014-03-10 02:51:56 -07004166 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
4167 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) {
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304168 instance->msix_vectors = (scratch_pad_2
4169 & MR_MAX_REPLY_QUEUES_OFFSET) + 1;
4170 fw_msix_count = instance->msix_vectors;
adam radford079eadd2012-10-01 19:26:59 -07004171 if (msix_vectors)
4172 instance->msix_vectors =
4173 min(msix_vectors,
4174 instance->msix_vectors);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304175 } else if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)
4176 || (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
4177 /* Invader/Fury supports more than 8 MSI-X */
4178 instance->msix_vectors = ((scratch_pad_2
4179 & MR_MAX_REPLY_QUEUES_EXT_OFFSET)
4180 >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
4181 fw_msix_count = instance->msix_vectors;
4182 /* Save 1-15 reply post index address to local memory
4183 * Index 0 is already saved from reg offset
4184 * MPI2_REPLY_POST_HOST_INDEX_OFFSET
4185 */
4186 for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
4187 instance->reply_post_host_index_addr[loop] =
4188 (u32 *)((u8 *)instance->reg_set +
4189 MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
4190 + (loop * 0x10));
4191 }
4192 if (msix_vectors)
4193 instance->msix_vectors = min(msix_vectors,
4194 instance->msix_vectors);
adam radfordc8e858f2011-10-08 18:15:13 -07004195 } else
4196 instance->msix_vectors = 1;
4197 /* Don't bother allocating more MSI-X vectors than cpus */
4198 instance->msix_vectors = min(instance->msix_vectors,
4199 (unsigned int)num_online_cpus());
4200 for (i = 0; i < instance->msix_vectors; i++)
4201 instance->msixentry[i].entry = i;
Alexander Gordeev8ae80ed2014-08-18 08:01:44 +02004202 i = pci_enable_msix_range(instance->pdev, instance->msixentry,
4203 1, instance->msix_vectors);
4204 if (i)
4205 instance->msix_vectors = i;
4206 else
adam radfordc8e858f2011-10-08 18:15:13 -07004207 instance->msix_vectors = 0;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304208
4209 dev_info(&instance->pdev->dev, "[scsi%d]: FW supports"
4210 "<%d> MSIX vector,Online CPUs: <%d>,"
4211 "Current MSIX <%d>\n", instance->host->host_no,
4212 fw_msix_count, (unsigned int)num_online_cpus(),
4213 instance->msix_vectors);
adam radfordc8e858f2011-10-08 18:15:13 -07004214 }
adam radford3f1abce2011-05-11 18:33:47 -07004215
adam radfordcd50ba82010-12-21 10:23:23 -08004216 /* Get operational params, sge flags, send init cmd to controller */
4217 if (instance->instancet->init_adapter(instance))
adam radfordeb1b1232011-02-24 20:55:56 -08004218 goto fail_init_adapter;
adam radfordcd50ba82010-12-21 10:23:23 -08004219
4220 printk(KERN_ERR "megasas: INIT adapter done\n");
4221
bo yang39a98552010-09-22 22:36:29 -04004222 /** for passthrough
4223 * the following function will get the PD LIST.
4224 */
4225
Yang, Bo81e403c2009-10-06 14:27:54 -06004226 memset(instance->pd_list, 0 ,
4227 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
Hannes Reinecke58968fc2014-01-16 11:25:36 +01004228 if (megasas_get_pd_list(instance) < 0) {
4229 printk(KERN_ERR "megasas: failed to get PD list\n");
4230 goto fail_init_adapter;
4231 }
Yang, Bo81e403c2009-10-06 14:27:54 -06004232
Yang, Bobdc6fb82009-12-06 08:30:19 -07004233 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
adam radford21c9e162013-09-06 15:27:14 -07004234 if (megasas_ld_list_query(instance,
4235 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
4236 megasas_get_ld_list(instance);
Yang, Bobdc6fb82009-12-06 08:30:19 -07004237
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004238 ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
4239
4240 /*
4241 * Compute the max allowed sectors per IO: The controller info has two
4242 * limits on max sectors. Driver should use the minimum of these two.
4243 *
4244 * 1 << stripe_sz_ops.min = max sectors per strip
4245 *
4246 * Note that older firmwares ( < FW ver 30) didn't report information
4247 * to calculate max_sectors_1. So the number ended up as zero always.
4248 */
bo yang14faea92007-11-09 04:14:00 -05004249 tmp_sectors = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004250 if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) {
4251
4252 max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304253 le16_to_cpu(ctrl_info->max_strips_per_io);
4254 max_sectors_2 = le32_to_cpu(ctrl_info->max_request_size);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004255
bo yang14faea92007-11-09 04:14:00 -05004256 tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2);
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304257
4258 /*Check whether controller is iMR or MR */
4259 if (ctrl_info->memory_size) {
4260 instance->is_imr = 0;
4261 dev_info(&instance->pdev->dev, "Controller type: MR,"
4262 "Memory size is: %dMB\n",
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304263 le16_to_cpu(ctrl_info->memory_size));
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304264 } else {
4265 instance->is_imr = 1;
4266 dev_info(&instance->pdev->dev,
4267 "Controller type: iMR\n");
4268 }
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304269 /* OnOffProperties are converted into CPU arch*/
4270 le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties);
bo yang39a98552010-09-22 22:36:29 -04004271 instance->disableOnlineCtrlReset =
4272 ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304273 /* adapterOperations2 are converted into CPU arch*/
4274 le32_to_cpus((u32 *)&ctrl_info->adapterOperations2);
adam radford229fe472014-03-10 02:51:56 -07004275 instance->mpio = ctrl_info->adapterOperations2.mpio;
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05304276 instance->UnevenSpanSupport =
4277 ctrl_info->adapterOperations2.supportUnevenSpans;
4278 if (instance->UnevenSpanSupport) {
4279 struct fusion_context *fusion = instance->ctrl_context;
4280 dev_info(&instance->pdev->dev, "FW supports: "
4281 "UnevenSpanSupport=%x\n", instance->UnevenSpanSupport);
4282 if (MR_ValidateMapInfo(instance))
4283 fusion->fast_path_io = 1;
4284 else
4285 fusion->fast_path_io = 0;
4286
4287 }
adam radford229fe472014-03-10 02:51:56 -07004288 if (ctrl_info->host_interface.SRIOV) {
4289 if (!ctrl_info->adapterOperations2.activePassive)
4290 instance->PlasmaFW111 = 1;
4291
4292 if (!instance->PlasmaFW111)
4293 instance->requestorId =
4294 ctrl_info->iov.requestorId;
4295 else {
4296 iovPtr = (struct IOV_111 *)((unsigned char *)ctrl_info + IOV_111_OFFSET);
4297 instance->requestorId = iovPtr->requestorId;
4298 }
4299 printk(KERN_WARNING "megaraid_sas: I am VF "
4300 "requestorId %d\n", instance->requestorId);
4301 }
bo yang14faea92007-11-09 04:14:00 -05004302 }
bo yang14faea92007-11-09 04:14:00 -05004303 instance->max_sectors_per_req = instance->max_num_sge *
4304 PAGE_SIZE / 512;
4305 if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
4306 instance->max_sectors_per_req = tmp_sectors;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004307
4308 kfree(ctrl_info);
4309
adam radfordc5daa6a2012-07-17 18:20:03 -07004310 /* Check for valid throttlequeuedepth module parameter */
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304311 if (instance->is_imr) {
adam radfordc5daa6a2012-07-17 18:20:03 -07004312 if (throttlequeuedepth > (instance->max_fw_cmds -
4313 MEGASAS_SKINNY_INT_CMDS))
4314 instance->throttlequeuedepth =
4315 MEGASAS_THROTTLE_QUEUE_DEPTH;
4316 else
4317 instance->throttlequeuedepth = throttlequeuedepth;
4318 } else {
4319 if (throttlequeuedepth > (instance->max_fw_cmds -
4320 MEGASAS_INT_CMDS))
4321 instance->throttlequeuedepth =
4322 MEGASAS_THROTTLE_QUEUE_DEPTH;
4323 else
4324 instance->throttlequeuedepth = throttlequeuedepth;
4325 }
4326
Sumant Patro5d018ad2006-10-03 13:13:18 -07004327 /*
4328 * Setup tasklet for cmd completion
4329 */
4330
adam radfordf86c54242011-02-24 20:57:00 -08004331 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
bo yangad84db22007-11-09 04:40:16 -05004332 (unsigned long)instance);
4333
adam radford229fe472014-03-10 02:51:56 -07004334 /* Launch SR-IOV heartbeat timer */
4335 if (instance->requestorId) {
4336 if (!megasas_sriov_start_heartbeat(instance, 1))
4337 megasas_start_timer(instance,
4338 &instance->sriov_heartbeat_timer,
4339 megasas_sriov_heartbeat_handler,
4340 MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
4341 else
4342 instance->skip_heartbeat_timer_del = 1;
4343 }
4344
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004345 return 0;
4346
adam radfordeb1b1232011-02-24 20:55:56 -08004347fail_init_adapter:
adam radfordcd50ba82010-12-21 10:23:23 -08004348fail_ready_state:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004349 iounmap(instance->reg_set);
4350
4351 fail_ioremap:
adam radfordb6d5d882010-12-14 18:56:07 -08004352 pci_release_selected_regions(instance->pdev, instance->bar);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004353
4354 return -EINVAL;
4355}
4356
4357/**
4358 * megasas_release_mfi - Reverses the FW initialization
4359 * @intance: Adapter soft state
4360 */
4361static void megasas_release_mfi(struct megasas_instance *instance)
4362{
adam radford9c915a82010-12-21 13:34:31 -08004363 u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004364
adam radford9c915a82010-12-21 13:34:31 -08004365 if (instance->reply_queue)
4366 pci_free_consistent(instance->pdev, reply_q_sz,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004367 instance->reply_queue, instance->reply_queue_h);
4368
4369 megasas_free_cmds(instance);
4370
4371 iounmap(instance->reg_set);
4372
adam radfordb6d5d882010-12-14 18:56:07 -08004373 pci_release_selected_regions(instance->pdev, instance->bar);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004374}
4375
4376/**
4377 * megasas_get_seq_num - Gets latest event sequence numbers
4378 * @instance: Adapter soft state
4379 * @eli: FW event log sequence numbers information
4380 *
4381 * FW maintains a log of all events in a non-volatile area. Upper layers would
4382 * usually find out the latest sequence number of the events, the seq number at
4383 * the boot etc. They would "read" all the events below the latest seq number
4384 * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq
4385 * number), they would subsribe to AEN (asynchronous event notification) and
4386 * wait for the events to happen.
4387 */
4388static int
4389megasas_get_seq_num(struct megasas_instance *instance,
4390 struct megasas_evt_log_info *eli)
4391{
4392 struct megasas_cmd *cmd;
4393 struct megasas_dcmd_frame *dcmd;
4394 struct megasas_evt_log_info *el_info;
4395 dma_addr_t el_info_h = 0;
4396
4397 cmd = megasas_get_cmd(instance);
4398
4399 if (!cmd) {
4400 return -ENOMEM;
4401 }
4402
4403 dcmd = &cmd->frame->dcmd;
4404 el_info = pci_alloc_consistent(instance->pdev,
4405 sizeof(struct megasas_evt_log_info),
4406 &el_info_h);
4407
4408 if (!el_info) {
4409 megasas_return_cmd(instance, cmd);
4410 return -ENOMEM;
4411 }
4412
4413 memset(el_info, 0, sizeof(*el_info));
4414 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4415
4416 dcmd->cmd = MFI_CMD_DCMD;
4417 dcmd->cmd_status = 0x0;
4418 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304419 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004420 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004421 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304422 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_log_info));
4423 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_EVENT_GET_INFO);
4424 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(el_info_h);
4425 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_log_info));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004426
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05304427 if (megasas_issue_blocked_cmd(instance, cmd, 30))
4428 dev_err(&instance->pdev->dev, "Command timedout"
4429 "from %s\n", __func__);
4430 else {
4431 /*
4432 * Copy the data back into callers buffer
4433 */
4434 eli->newest_seq_num = le32_to_cpu(el_info->newest_seq_num);
4435 eli->oldest_seq_num = le32_to_cpu(el_info->oldest_seq_num);
4436 eli->clear_seq_num = le32_to_cpu(el_info->clear_seq_num);
4437 eli->shutdown_seq_num = le32_to_cpu(el_info->shutdown_seq_num);
4438 eli->boot_seq_num = le32_to_cpu(el_info->boot_seq_num);
4439 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004440
4441 pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info),
4442 el_info, el_info_h);
4443
4444 megasas_return_cmd(instance, cmd);
4445
4446 return 0;
4447}
4448
4449/**
4450 * megasas_register_aen - Registers for asynchronous event notification
4451 * @instance: Adapter soft state
4452 * @seq_num: The starting sequence number
4453 * @class_locale: Class of the event
4454 *
4455 * This function subscribes for AEN for events beyond the @seq_num. It requests
4456 * to be notified if and only if the event is of type @class_locale
4457 */
4458static int
4459megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
4460 u32 class_locale_word)
4461{
4462 int ret_val;
4463 struct megasas_cmd *cmd;
4464 struct megasas_dcmd_frame *dcmd;
4465 union megasas_evt_class_locale curr_aen;
4466 union megasas_evt_class_locale prev_aen;
4467
4468 /*
4469 * If there an AEN pending already (aen_cmd), check if the
4470 * class_locale of that pending AEN is inclusive of the new
4471 * AEN request we currently have. If it is, then we don't have
4472 * to do anything. In other words, whichever events the current
4473 * AEN request is subscribing to, have already been subscribed
4474 * to.
4475 *
4476 * If the old_cmd is _not_ inclusive, then we have to abort
4477 * that command, form a class_locale that is superset of both
4478 * old and current and re-issue to the FW
4479 */
4480
4481 curr_aen.word = class_locale_word;
4482
4483 if (instance->aen_cmd) {
4484
4485 prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1];
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304486 prev_aen.members.locale = le16_to_cpu(prev_aen.members.locale);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004487
4488 /*
4489 * A class whose enum value is smaller is inclusive of all
4490 * higher values. If a PROGRESS (= -1) was previously
4491 * registered, then a new registration requests for higher
4492 * classes need not be sent to FW. They are automatically
4493 * included.
4494 *
4495 * Locale numbers don't have such hierarchy. They are bitmap
4496 * values
4497 */
4498 if ((prev_aen.members.class <= curr_aen.members.class) &&
Sumit.Saxena@lsi.com3993a862013-09-16 15:18:06 +05304499 !((prev_aen.members.locale & curr_aen.members.locale) ^
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004500 curr_aen.members.locale)) {
4501 /*
4502 * Previously issued event registration includes
4503 * current request. Nothing to do.
4504 */
4505 return 0;
4506 } else {
Sumit.Saxena@lsi.com3993a862013-09-16 15:18:06 +05304507 curr_aen.members.locale |= prev_aen.members.locale;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004508
4509 if (prev_aen.members.class < curr_aen.members.class)
4510 curr_aen.members.class = prev_aen.members.class;
4511
4512 instance->aen_cmd->abort_aen = 1;
4513 ret_val = megasas_issue_blocked_abort_cmd(instance,
4514 instance->
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05304515 aen_cmd, 30);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004516
4517 if (ret_val) {
4518 printk(KERN_DEBUG "megasas: Failed to abort "
4519 "previous AEN command\n");
4520 return ret_val;
4521 }
4522 }
4523 }
4524
4525 cmd = megasas_get_cmd(instance);
4526
4527 if (!cmd)
4528 return -ENOMEM;
4529
4530 dcmd = &cmd->frame->dcmd;
4531
4532 memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail));
4533
4534 /*
4535 * Prepare DCMD for aen registration
4536 */
4537 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4538
4539 dcmd->cmd = MFI_CMD_DCMD;
4540 dcmd->cmd_status = 0x0;
4541 dcmd->sge_count = 1;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304542 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004543 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004544 dcmd->pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304545 dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_detail));
4546 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_EVENT_WAIT);
4547 dcmd->mbox.w[0] = cpu_to_le32(seq_num);
bo yang39a98552010-09-22 22:36:29 -04004548 instance->last_seq_num = seq_num;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304549 dcmd->mbox.w[1] = cpu_to_le32(curr_aen.word);
4550 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->evt_detail_h);
4551 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_detail));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004552
Yang, Bof4c9a132009-10-06 14:43:28 -06004553 if (instance->aen_cmd != NULL) {
4554 megasas_return_cmd(instance, cmd);
4555 return 0;
4556 }
4557
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004558 /*
4559 * Store reference to the cmd used to register for AEN. When an
4560 * application wants us to register for AEN, we have to abort this
4561 * cmd and re-register with a new EVENT LOCALE supplied by that app
4562 */
4563 instance->aen_cmd = cmd;
4564
4565 /*
4566 * Issue the aen registration frame
4567 */
adam radford9c915a82010-12-21 13:34:31 -08004568 instance->instancet->issue_dcmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004569
4570 return 0;
4571}
4572
4573/**
4574 * megasas_start_aen - Subscribes to AEN during driver load time
4575 * @instance: Adapter soft state
4576 */
4577static int megasas_start_aen(struct megasas_instance *instance)
4578{
4579 struct megasas_evt_log_info eli;
4580 union megasas_evt_class_locale class_locale;
4581
4582 /*
4583 * Get the latest sequence number from FW
4584 */
4585 memset(&eli, 0, sizeof(eli));
4586
4587 if (megasas_get_seq_num(instance, &eli))
4588 return -1;
4589
4590 /*
4591 * Register AEN with FW for latest sequence number plus 1
4592 */
4593 class_locale.members.reserved = 0;
4594 class_locale.members.locale = MR_EVT_LOCALE_ALL;
4595 class_locale.members.class = MR_EVT_CLASS_DEBUG;
4596
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304597 return megasas_register_aen(instance,
Sumit.Saxena@lsi.com3993a862013-09-16 15:18:06 +05304598 eli.newest_seq_num + 1,
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304599 class_locale.word);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004600}
4601
4602/**
4603 * megasas_io_attach - Attaches this driver to SCSI mid-layer
4604 * @instance: Adapter soft state
4605 */
4606static int megasas_io_attach(struct megasas_instance *instance)
4607{
4608 struct Scsi_Host *host = instance->host;
4609
4610 /*
4611 * Export parameters required by SCSI mid-layer
4612 */
4613 host->irq = instance->pdev->irq;
4614 host->unique_id = instance->unique_id;
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304615 if (instance->is_imr) {
Yang, Bo7bebf5c2009-10-06 14:40:58 -06004616 host->can_queue =
4617 instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
4618 } else
4619 host->can_queue =
4620 instance->max_fw_cmds - MEGASAS_INT_CMDS;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004621 host->this_id = instance->init_id;
4622 host->sg_tablesize = instance->max_num_sge;
adam radford42a8d2b2011-02-24 20:57:09 -08004623
4624 if (instance->fw_support_ieee)
4625 instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE;
4626
Yang, Bo1fd10682010-10-12 07:18:50 -06004627 /*
4628 * Check if the module parameter value for max_sectors can be used
4629 */
4630 if (max_sectors && max_sectors < instance->max_sectors_per_req)
4631 instance->max_sectors_per_req = max_sectors;
4632 else {
4633 if (max_sectors) {
4634 if (((instance->pdev->device ==
4635 PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
4636 (instance->pdev->device ==
4637 PCI_DEVICE_ID_LSI_SAS0079GEN2)) &&
4638 (max_sectors <= MEGASAS_MAX_SECTORS)) {
4639 instance->max_sectors_per_req = max_sectors;
4640 } else {
4641 printk(KERN_INFO "megasas: max_sectors should be > 0"
4642 "and <= %d (or < 1MB for GEN2 controller)\n",
4643 instance->max_sectors_per_req);
4644 }
4645 }
4646 }
4647
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004648 host->max_sectors = instance->max_sectors_per_req;
adam radford9c915a82010-12-21 13:34:31 -08004649 host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004650 host->max_channel = MEGASAS_MAX_CHANNELS - 1;
4651 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
4652 host->max_lun = MEGASAS_MAX_LUN;
Joshua Giles122da302006-02-03 15:34:17 -08004653 host->max_cmd_len = 16;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004654
adam radford9c915a82010-12-21 13:34:31 -08004655 /* Fusion only supports host reset */
adam radford36807e62011-10-08 18:15:06 -07004656 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
adam radford229fe472014-03-10 02:51:56 -07004657 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304658 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
4659 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
adam radford9c915a82010-12-21 13:34:31 -08004660 host->hostt->eh_device_reset_handler = NULL;
4661 host->hostt->eh_bus_reset_handler = NULL;
4662 }
4663
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004664 /*
4665 * Notify the mid-layer about the new controller
4666 */
4667 if (scsi_add_host(host, &instance->pdev->dev)) {
4668 printk(KERN_DEBUG "megasas: scsi_add_host failed\n");
4669 return -ENODEV;
4670 }
4671
4672 /*
4673 * Trigger SCSI to scan our drives
4674 */
4675 scsi_scan_host(host);
4676 return 0;
4677}
4678
bo yang31ea7082007-11-07 12:09:50 -05004679static int
4680megasas_set_dma_mask(struct pci_dev *pdev)
4681{
4682 /*
4683 * All our contollers are capable of performing 64-bit DMA
4684 */
4685 if (IS_DMA64) {
Yang Hongyang6a355282009-04-06 19:01:13 -07004686 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
bo yang31ea7082007-11-07 12:09:50 -05004687
Yang Hongyang284901a2009-04-06 19:01:15 -07004688 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
bo yang31ea7082007-11-07 12:09:50 -05004689 goto fail_set_dma_mask;
4690 }
4691 } else {
Yang Hongyang284901a2009-04-06 19:01:15 -07004692 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
bo yang31ea7082007-11-07 12:09:50 -05004693 goto fail_set_dma_mask;
4694 }
Sumit.Saxena@lsi.com46de63e22014-02-12 23:38:44 +05304695 /*
4696 * Ensure that all data structures are allocated in 32-bit
4697 * memory.
4698 */
4699 if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
4700 /* Try 32bit DMA mask and 32 bit Consistent dma mask */
4701 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
4702 && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
4703 dev_info(&pdev->dev, "set 32bit DMA mask"
4704 "and 32 bit consistent mask\n");
4705 else
4706 goto fail_set_dma_mask;
4707 }
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05304708
bo yang31ea7082007-11-07 12:09:50 -05004709 return 0;
4710
4711fail_set_dma_mask:
4712 return 1;
4713}
4714
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004715/**
4716 * megasas_probe_one - PCI hotplug entry point
4717 * @pdev: PCI device structure
adam radford0d490162010-12-14 19:17:17 -08004718 * @id: PCI ids of supported hotplugged adapter
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004719 */
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08004720static int megasas_probe_one(struct pci_dev *pdev,
4721 const struct pci_device_id *id)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004722{
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304723 int rval, pos, i, j, cpu;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004724 struct Scsi_Host *host;
4725 struct megasas_instance *instance;
adam radford66192dfe2011-02-24 20:56:28 -08004726 u16 control = 0;
4727
4728 /* Reset MSI-X in the kdump kernel */
4729 if (reset_devices) {
4730 pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
4731 if (pos) {
Bjorn Helgaas99369062013-04-17 18:08:44 -06004732 pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS,
adam radford66192dfe2011-02-24 20:56:28 -08004733 &control);
4734 if (control & PCI_MSIX_FLAGS_ENABLE) {
4735 dev_info(&pdev->dev, "resetting MSI-X\n");
4736 pci_write_config_word(pdev,
Bjorn Helgaas99369062013-04-17 18:08:44 -06004737 pos + PCI_MSIX_FLAGS,
adam radford66192dfe2011-02-24 20:56:28 -08004738 control &
4739 ~PCI_MSIX_FLAGS_ENABLE);
4740 }
4741 }
4742 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004743
4744 /*
4745 * Announce PCI information
4746 */
4747 printk(KERN_INFO "megasas: %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
4748 pdev->vendor, pdev->device, pdev->subsystem_vendor,
4749 pdev->subsystem_device);
4750
4751 printk("bus %d:slot %d:func %d\n",
4752 pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
4753
4754 /*
4755 * PCI prepping: enable device set bus mastering and dma mask
4756 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09004757 rval = pci_enable_device_mem(pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004758
4759 if (rval) {
4760 return rval;
4761 }
4762
4763 pci_set_master(pdev);
4764
bo yang31ea7082007-11-07 12:09:50 -05004765 if (megasas_set_dma_mask(pdev))
4766 goto fail_set_dma_mask;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004767
4768 host = scsi_host_alloc(&megasas_template,
4769 sizeof(struct megasas_instance));
4770
4771 if (!host) {
4772 printk(KERN_DEBUG "megasas: scsi_host_alloc failed\n");
4773 goto fail_alloc_instance;
4774 }
4775
4776 instance = (struct megasas_instance *)host->hostdata;
4777 memset(instance, 0, sizeof(*instance));
bo yang39a98552010-09-22 22:36:29 -04004778 atomic_set( &instance->fw_reset_no_pci_access, 0 );
adam radford9c915a82010-12-21 13:34:31 -08004779 instance->pdev = pdev;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004780
adam radford9c915a82010-12-21 13:34:31 -08004781 switch (instance->pdev->device) {
4782 case PCI_DEVICE_ID_LSI_FUSION:
adam radford229fe472014-03-10 02:51:56 -07004783 case PCI_DEVICE_ID_LSI_PLASMA:
adam radford36807e62011-10-08 18:15:06 -07004784 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304785 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08004786 {
4787 struct fusion_context *fusion;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004788
adam radford9c915a82010-12-21 13:34:31 -08004789 instance->ctrl_context =
4790 kzalloc(sizeof(struct fusion_context), GFP_KERNEL);
4791 if (!instance->ctrl_context) {
4792 printk(KERN_DEBUG "megasas: Failed to allocate "
4793 "memory for Fusion context info\n");
4794 goto fail_alloc_dma_buf;
4795 }
4796 fusion = instance->ctrl_context;
4797 INIT_LIST_HEAD(&fusion->cmd_pool);
4798 spin_lock_init(&fusion->cmd_pool_lock);
4799 }
4800 break;
4801 default: /* For all other supported controllers */
4802
4803 instance->producer =
4804 pci_alloc_consistent(pdev, sizeof(u32),
4805 &instance->producer_h);
4806 instance->consumer =
4807 pci_alloc_consistent(pdev, sizeof(u32),
4808 &instance->consumer_h);
4809
4810 if (!instance->producer || !instance->consumer) {
4811 printk(KERN_DEBUG "megasas: Failed to allocate"
4812 "memory for producer, consumer\n");
4813 goto fail_alloc_dma_buf;
4814 }
4815
4816 *instance->producer = 0;
4817 *instance->consumer = 0;
4818 break;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004819 }
4820
Yang, Boc3518832009-10-06 14:18:02 -06004821 megasas_poll_wait_aen = 0;
Yang, Bof4c9a132009-10-06 14:43:28 -06004822 instance->flag_ieee = 0;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004823 instance->ev = NULL;
bo yang39a98552010-09-22 22:36:29 -04004824 instance->issuepend_done = 1;
4825 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304826 instance->is_imr = 0;
bo yang39a98552010-09-22 22:36:29 -04004827 megasas_poll_wait_aen = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004828
4829 instance->evt_detail = pci_alloc_consistent(pdev,
4830 sizeof(struct
4831 megasas_evt_detail),
4832 &instance->evt_detail_h);
4833
4834 if (!instance->evt_detail) {
4835 printk(KERN_DEBUG "megasas: Failed to allocate memory for "
4836 "event detail structure\n");
4837 goto fail_alloc_dma_buf;
4838 }
4839
4840 /*
4841 * Initialize locks and queues
4842 */
4843 INIT_LIST_HEAD(&instance->cmd_pool);
bo yang39a98552010-09-22 22:36:29 -04004844 INIT_LIST_HEAD(&instance->internal_reset_pending_q);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004845
Sumant Patroe4a082c2006-05-30 12:03:37 -07004846 atomic_set(&instance->fw_outstanding,0);
4847
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004848 init_waitqueue_head(&instance->int_cmd_wait_q);
4849 init_waitqueue_head(&instance->abort_cmd_wait_q);
4850
4851 spin_lock_init(&instance->cmd_pool_lock);
bo yang39a98552010-09-22 22:36:29 -04004852 spin_lock_init(&instance->hba_lock);
bo yang7343eb62007-11-09 04:35:44 -05004853 spin_lock_init(&instance->completion_lock);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004854
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02004855 mutex_init(&instance->aen_mutex);
adam radford9c915a82010-12-21 13:34:31 -08004856 mutex_init(&instance->reset_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004857
4858 /*
4859 * Initialize PCI related and misc parameters
4860 */
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004861 instance->host = host;
4862 instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
4863 instance->init_id = MEGASAS_DEFAULT_INIT_ID;
4864
Yang, Bo7bebf5c2009-10-06 14:40:58 -06004865 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
4866 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
Yang, Bof4c9a132009-10-06 14:43:28 -06004867 instance->flag_ieee = 1;
Yang, Bo7bebf5c2009-10-06 14:40:58 -06004868 sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
4869 } else
4870 sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
4871
Sumant Patro658dced2006-10-03 13:09:14 -07004872 megasas_dbg_lvl = 0;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07004873 instance->flag = 0;
Yang, Bo0c79e682009-10-06 14:47:35 -06004874 instance->unload = 1;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07004875 instance->last_time = 0;
bo yang39a98552010-09-22 22:36:29 -04004876 instance->disableOnlineCtrlReset = 1;
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05304877 instance->UnevenSpanSupport = 0;
bo yang39a98552010-09-22 22:36:29 -04004878
adam radford36807e62011-10-08 18:15:06 -07004879 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
adam radford229fe472014-03-10 02:51:56 -07004880 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304881 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
4882 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
adam radford9c915a82010-12-21 13:34:31 -08004883 INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
4884 else
4885 INIT_WORK(&instance->work_init, process_fw_state_change_wq);
Sumant Patro658dced2006-10-03 13:09:14 -07004886
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004887 /*
adam radford0a770662011-02-24 20:56:12 -08004888 * Initialize MFI Firmware
4889 */
4890 if (megasas_init_fw(instance))
4891 goto fail_init_mfi;
4892
adam radford229fe472014-03-10 02:51:56 -07004893 if (instance->requestorId) {
4894 if (instance->PlasmaFW111) {
4895 instance->vf_affiliation_111 =
4896 pci_alloc_consistent(pdev, sizeof(struct MR_LD_VF_AFFILIATION_111),
4897 &instance->vf_affiliation_111_h);
4898 if (!instance->vf_affiliation_111)
4899 printk(KERN_WARNING "megasas: Can't allocate "
4900 "memory for VF affiliation buffer\n");
4901 } else {
4902 instance->vf_affiliation =
4903 pci_alloc_consistent(pdev,
4904 (MAX_LOGICAL_DRIVES + 1) *
4905 sizeof(struct MR_LD_VF_AFFILIATION),
4906 &instance->vf_affiliation_h);
4907 if (!instance->vf_affiliation)
4908 printk(KERN_WARNING "megasas: Can't allocate "
4909 "memory for VF affiliation buffer\n");
4910 }
4911 }
4912
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304913retry_irq_register:
adam radford0a770662011-02-24 20:56:12 -08004914 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004915 * Register IRQ
4916 */
adam radfordc8e858f2011-10-08 18:15:13 -07004917 if (instance->msix_vectors) {
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304918 cpu = cpumask_first(cpu_online_mask);
4919 for (i = 0; i < instance->msix_vectors; i++) {
adam radfordc8e858f2011-10-08 18:15:13 -07004920 instance->irq_context[i].instance = instance;
4921 instance->irq_context[i].MSIxIndex = i;
4922 if (request_irq(instance->msixentry[i].vector,
4923 instance->instancet->service_isr, 0,
4924 "megasas",
4925 &instance->irq_context[i])) {
4926 printk(KERN_DEBUG "megasas: Failed to "
4927 "register IRQ for vector %d.\n", i);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304928 for (j = 0; j < i; j++) {
4929 irq_set_affinity_hint(
4930 instance->msixentry[j].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07004931 free_irq(
4932 instance->msixentry[j].vector,
4933 &instance->irq_context[j]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304934 }
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304935 /* Retry irq register for IO_APIC */
4936 instance->msix_vectors = 0;
4937 goto retry_irq_register;
adam radfordc8e858f2011-10-08 18:15:13 -07004938 }
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304939 if (irq_set_affinity_hint(instance->msixentry[i].vector,
4940 get_cpu_mask(cpu)))
4941 dev_err(&instance->pdev->dev, "Error setting"
4942 "affinity hint for cpu %d\n", cpu);
4943 cpu = cpumask_next(cpu, cpu_online_mask);
adam radfordc8e858f2011-10-08 18:15:13 -07004944 }
4945 } else {
4946 instance->irq_context[0].instance = instance;
4947 instance->irq_context[0].MSIxIndex = 0;
4948 if (request_irq(pdev->irq, instance->instancet->service_isr,
4949 IRQF_SHARED, "megasas",
4950 &instance->irq_context[0])) {
4951 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
4952 goto fail_irq;
4953 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004954 }
4955
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304956 instance->instancet->enable_intr(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004957
4958 /*
4959 * Store instance in PCI softstate
4960 */
4961 pci_set_drvdata(pdev, instance);
4962
4963 /*
4964 * Add this controller to megasas_mgmt_info structure so that it
4965 * can be exported to management applications
4966 */
4967 megasas_mgmt_info.count++;
4968 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance;
4969 megasas_mgmt_info.max_index++;
4970
4971 /*
adam radford541f90b2011-05-11 18:34:29 -07004972 * Register with SCSI mid-layer
4973 */
4974 if (megasas_io_attach(instance))
4975 goto fail_io_attach;
4976
4977 instance->unload = 0;
4978
4979 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004980 * Initiate AEN (Asynchronous Event Notification)
4981 */
4982 if (megasas_start_aen(instance)) {
4983 printk(KERN_DEBUG "megasas: start aen failed\n");
4984 goto fail_start_aen;
4985 }
4986
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004987 return 0;
4988
4989 fail_start_aen:
4990 fail_io_attach:
4991 megasas_mgmt_info.count--;
4992 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
4993 megasas_mgmt_info.max_index--;
4994
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304995 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07004996 if (instance->msix_vectors)
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05304997 for (i = 0; i < instance->msix_vectors; i++) {
4998 irq_set_affinity_hint(
4999 instance->msixentry[i].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07005000 free_irq(instance->msixentry[i].vector,
5001 &instance->irq_context[i]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305002 }
adam radfordc8e858f2011-10-08 18:15:13 -07005003 else
5004 free_irq(instance->pdev->irq, &instance->irq_context[0]);
adam radfordeb1b1232011-02-24 20:55:56 -08005005fail_irq:
adam radford36807e62011-10-08 18:15:06 -07005006 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
adam radford229fe472014-03-10 02:51:56 -07005007 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05305008 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
5009 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
adam radfordeb1b1232011-02-24 20:55:56 -08005010 megasas_release_fusion(instance);
5011 else
5012 megasas_release_mfi(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005013 fail_init_mfi:
adam radfordc8e858f2011-10-08 18:15:13 -07005014 if (instance->msix_vectors)
adam radford0a770662011-02-24 20:56:12 -08005015 pci_disable_msix(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005016 fail_alloc_dma_buf:
5017 if (instance->evt_detail)
5018 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
5019 instance->evt_detail,
5020 instance->evt_detail_h);
5021
adam radfordeb1b1232011-02-24 20:55:56 -08005022 if (instance->producer)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005023 pci_free_consistent(pdev, sizeof(u32), instance->producer,
5024 instance->producer_h);
5025 if (instance->consumer)
5026 pci_free_consistent(pdev, sizeof(u32), instance->consumer,
5027 instance->consumer_h);
5028 scsi_host_put(host);
5029
5030 fail_alloc_instance:
5031 fail_set_dma_mask:
5032 pci_disable_device(pdev);
5033
5034 return -ENODEV;
5035}
5036
5037/**
5038 * megasas_flush_cache - Requests FW to flush all its caches
5039 * @instance: Adapter soft state
5040 */
5041static void megasas_flush_cache(struct megasas_instance *instance)
5042{
5043 struct megasas_cmd *cmd;
5044 struct megasas_dcmd_frame *dcmd;
5045
bo yang39a98552010-09-22 22:36:29 -04005046 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
5047 return;
5048
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005049 cmd = megasas_get_cmd(instance);
5050
5051 if (!cmd)
5052 return;
5053
5054 dcmd = &cmd->frame->dcmd;
5055
5056 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
5057
5058 dcmd->cmd = MFI_CMD_DCMD;
5059 dcmd->cmd_status = 0x0;
5060 dcmd->sge_count = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305061 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005062 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07005063 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005064 dcmd->data_xfer_len = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305065 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_CACHE_FLUSH);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005066 dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
5067
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305068 if (megasas_issue_blocked_cmd(instance, cmd, 30))
5069 dev_err(&instance->pdev->dev, "Command timedout"
5070 " from %s\n", __func__);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005071
5072 megasas_return_cmd(instance, cmd);
5073
5074 return;
5075}
5076
5077/**
5078 * megasas_shutdown_controller - Instructs FW to shutdown the controller
5079 * @instance: Adapter soft state
bo yang31ea7082007-11-07 12:09:50 -05005080 * @opcode: Shutdown/Hibernate
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005081 */
bo yang31ea7082007-11-07 12:09:50 -05005082static void megasas_shutdown_controller(struct megasas_instance *instance,
5083 u32 opcode)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005084{
5085 struct megasas_cmd *cmd;
5086 struct megasas_dcmd_frame *dcmd;
5087
bo yang39a98552010-09-22 22:36:29 -04005088 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
5089 return;
5090
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005091 cmd = megasas_get_cmd(instance);
5092
5093 if (!cmd)
5094 return;
5095
5096 if (instance->aen_cmd)
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305097 megasas_issue_blocked_abort_cmd(instance,
5098 instance->aen_cmd, 30);
adam radford9c915a82010-12-21 13:34:31 -08005099 if (instance->map_update_cmd)
5100 megasas_issue_blocked_abort_cmd(instance,
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305101 instance->map_update_cmd, 30);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005102 dcmd = &cmd->frame->dcmd;
5103
5104 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
5105
5106 dcmd->cmd = MFI_CMD_DCMD;
5107 dcmd->cmd_status = 0x0;
5108 dcmd->sge_count = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305109 dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005110 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07005111 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005112 dcmd->data_xfer_len = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305113 dcmd->opcode = cpu_to_le32(opcode);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005114
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305115 if (megasas_issue_blocked_cmd(instance, cmd, 30))
5116 dev_err(&instance->pdev->dev, "Command timedout"
5117 "from %s\n", __func__);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005118
5119 megasas_return_cmd(instance, cmd);
5120
5121 return;
5122}
5123
Jiri Slaby33139b22008-05-01 17:56:02 +02005124#ifdef CONFIG_PM
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005125/**
bo yangad84db22007-11-09 04:40:16 -05005126 * megasas_suspend - driver suspend entry point
5127 * @pdev: PCI device structure
bo yang31ea7082007-11-07 12:09:50 -05005128 * @state: PCI power state to suspend routine
5129 */
Jiri Slaby33139b22008-05-01 17:56:02 +02005130static int
bo yang31ea7082007-11-07 12:09:50 -05005131megasas_suspend(struct pci_dev *pdev, pm_message_t state)
5132{
5133 struct Scsi_Host *host;
5134 struct megasas_instance *instance;
adam radfordc8e858f2011-10-08 18:15:13 -07005135 int i;
bo yang31ea7082007-11-07 12:09:50 -05005136
5137 instance = pci_get_drvdata(pdev);
5138 host = instance->host;
Yang, Bo0c79e682009-10-06 14:47:35 -06005139 instance->unload = 1;
bo yang31ea7082007-11-07 12:09:50 -05005140
adam radford229fe472014-03-10 02:51:56 -07005141 /* Shutdown SR-IOV heartbeat timer */
5142 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
5143 del_timer_sync(&instance->sriov_heartbeat_timer);
5144
bo yang31ea7082007-11-07 12:09:50 -05005145 megasas_flush_cache(instance);
5146 megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005147
5148 /* cancel the delayed work if this work still in queue */
5149 if (instance->ev != NULL) {
5150 struct megasas_aen_event *ev = instance->ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08005151 cancel_delayed_work_sync(&ev->hotplug_work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005152 instance->ev = NULL;
5153 }
5154
bo yang31ea7082007-11-07 12:09:50 -05005155 tasklet_kill(&instance->isr_tasklet);
5156
5157 pci_set_drvdata(instance->pdev, instance);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305158 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07005159
5160 if (instance->msix_vectors)
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305161 for (i = 0; i < instance->msix_vectors; i++) {
5162 irq_set_affinity_hint(
5163 instance->msixentry[i].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07005164 free_irq(instance->msixentry[i].vector,
5165 &instance->irq_context[i]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305166 }
adam radfordc8e858f2011-10-08 18:15:13 -07005167 else
5168 free_irq(instance->pdev->irq, &instance->irq_context[0]);
5169 if (instance->msix_vectors)
adam radford80d9da92010-12-21 10:17:40 -08005170 pci_disable_msix(instance->pdev);
bo yang31ea7082007-11-07 12:09:50 -05005171
5172 pci_save_state(pdev);
5173 pci_disable_device(pdev);
5174
5175 pci_set_power_state(pdev, pci_choose_state(pdev, state));
5176
5177 return 0;
5178}
5179
5180/**
5181 * megasas_resume- driver resume entry point
5182 * @pdev: PCI device structure
5183 */
Jiri Slaby33139b22008-05-01 17:56:02 +02005184static int
bo yang31ea7082007-11-07 12:09:50 -05005185megasas_resume(struct pci_dev *pdev)
5186{
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305187 int rval, i, j, cpu;
bo yang31ea7082007-11-07 12:09:50 -05005188 struct Scsi_Host *host;
5189 struct megasas_instance *instance;
5190
5191 instance = pci_get_drvdata(pdev);
5192 host = instance->host;
5193 pci_set_power_state(pdev, PCI_D0);
5194 pci_enable_wake(pdev, PCI_D0, 0);
5195 pci_restore_state(pdev);
5196
5197 /*
5198 * PCI prepping: enable device set bus mastering and dma mask
5199 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09005200 rval = pci_enable_device_mem(pdev);
bo yang31ea7082007-11-07 12:09:50 -05005201
5202 if (rval) {
5203 printk(KERN_ERR "megasas: Enable device failed\n");
5204 return rval;
5205 }
5206
5207 pci_set_master(pdev);
5208
5209 if (megasas_set_dma_mask(pdev))
5210 goto fail_set_dma_mask;
5211
5212 /*
5213 * Initialize MFI Firmware
5214 */
5215
bo yang31ea7082007-11-07 12:09:50 -05005216 atomic_set(&instance->fw_outstanding, 0);
5217
5218 /*
5219 * We expect the FW state to be READY
5220 */
adam radford058a8fa2011-10-08 18:14:27 -07005221 if (megasas_transition_to_ready(instance, 0))
bo yang31ea7082007-11-07 12:09:50 -05005222 goto fail_ready_state;
5223
adam radford3f1abce2011-05-11 18:33:47 -07005224 /* Now re-enable MSI-X */
Alexander Gordeevdd088122014-08-18 08:01:43 +02005225 if (instance->msix_vectors &&
Alexander Gordeev8ae80ed2014-08-18 08:01:44 +02005226 pci_enable_msix_exact(instance->pdev, instance->msixentry,
5227 instance->msix_vectors))
Alexander Gordeevdd088122014-08-18 08:01:43 +02005228 goto fail_reenable_msix;
adam radford3f1abce2011-05-11 18:33:47 -07005229
adam radford9c915a82010-12-21 13:34:31 -08005230 switch (instance->pdev->device) {
5231 case PCI_DEVICE_ID_LSI_FUSION:
adam radford229fe472014-03-10 02:51:56 -07005232 case PCI_DEVICE_ID_LSI_PLASMA:
adam radford36807e62011-10-08 18:15:06 -07005233 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05305234 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08005235 {
5236 megasas_reset_reply_desc(instance);
5237 if (megasas_ioc_init_fusion(instance)) {
5238 megasas_free_cmds(instance);
5239 megasas_free_cmds_fusion(instance);
5240 goto fail_init_mfi;
5241 }
5242 if (!megasas_get_map_info(instance))
5243 megasas_sync_map_info(instance);
5244 }
5245 break;
5246 default:
5247 *instance->producer = 0;
5248 *instance->consumer = 0;
5249 if (megasas_issue_init_mfi(instance))
5250 goto fail_init_mfi;
5251 break;
5252 }
bo yang31ea7082007-11-07 12:09:50 -05005253
adam radford9c915a82010-12-21 13:34:31 -08005254 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
5255 (unsigned long)instance);
bo yang31ea7082007-11-07 12:09:50 -05005256
5257 /*
5258 * Register IRQ
5259 */
adam radfordc8e858f2011-10-08 18:15:13 -07005260 if (instance->msix_vectors) {
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305261 cpu = cpumask_first(cpu_online_mask);
adam radfordc8e858f2011-10-08 18:15:13 -07005262 for (i = 0 ; i < instance->msix_vectors; i++) {
5263 instance->irq_context[i].instance = instance;
5264 instance->irq_context[i].MSIxIndex = i;
5265 if (request_irq(instance->msixentry[i].vector,
5266 instance->instancet->service_isr, 0,
5267 "megasas",
5268 &instance->irq_context[i])) {
5269 printk(KERN_DEBUG "megasas: Failed to "
5270 "register IRQ for vector %d.\n", i);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305271 for (j = 0; j < i; j++) {
5272 irq_set_affinity_hint(
5273 instance->msixentry[j].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07005274 free_irq(
5275 instance->msixentry[j].vector,
5276 &instance->irq_context[j]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305277 }
adam radfordc8e858f2011-10-08 18:15:13 -07005278 goto fail_irq;
5279 }
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305280
5281 if (irq_set_affinity_hint(instance->msixentry[i].vector,
5282 get_cpu_mask(cpu)))
5283 dev_err(&instance->pdev->dev, "Error setting"
5284 "affinity hint for cpu %d\n", cpu);
5285 cpu = cpumask_next(cpu, cpu_online_mask);
adam radfordc8e858f2011-10-08 18:15:13 -07005286 }
5287 } else {
5288 instance->irq_context[0].instance = instance;
5289 instance->irq_context[0].MSIxIndex = 0;
5290 if (request_irq(pdev->irq, instance->instancet->service_isr,
5291 IRQF_SHARED, "megasas",
5292 &instance->irq_context[0])) {
5293 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
5294 goto fail_irq;
5295 }
bo yang31ea7082007-11-07 12:09:50 -05005296 }
5297
adam radford229fe472014-03-10 02:51:56 -07005298 /* Re-launch SR-IOV heartbeat timer */
5299 if (instance->requestorId) {
5300 if (!megasas_sriov_start_heartbeat(instance, 0))
5301 megasas_start_timer(instance,
5302 &instance->sriov_heartbeat_timer,
5303 megasas_sriov_heartbeat_handler,
5304 MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
5305 else
5306 instance->skip_heartbeat_timer_del = 1;
5307 }
5308
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305309 instance->instancet->enable_intr(instance);
Yang, Bo0c79e682009-10-06 14:47:35 -06005310 instance->unload = 0;
5311
adam radford541f90b2011-05-11 18:34:29 -07005312 /*
5313 * Initiate AEN (Asynchronous Event Notification)
5314 */
5315 if (megasas_start_aen(instance))
5316 printk(KERN_ERR "megasas: Start AEN failed\n");
5317
bo yang31ea7082007-11-07 12:09:50 -05005318 return 0;
5319
5320fail_irq:
5321fail_init_mfi:
5322 if (instance->evt_detail)
5323 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
5324 instance->evt_detail,
5325 instance->evt_detail_h);
5326
5327 if (instance->producer)
5328 pci_free_consistent(pdev, sizeof(u32), instance->producer,
5329 instance->producer_h);
5330 if (instance->consumer)
5331 pci_free_consistent(pdev, sizeof(u32), instance->consumer,
5332 instance->consumer_h);
5333 scsi_host_put(host);
5334
5335fail_set_dma_mask:
5336fail_ready_state:
Alexander Gordeevdd088122014-08-18 08:01:43 +02005337fail_reenable_msix:
bo yang31ea7082007-11-07 12:09:50 -05005338
5339 pci_disable_device(pdev);
5340
5341 return -ENODEV;
5342}
Jiri Slaby33139b22008-05-01 17:56:02 +02005343#else
5344#define megasas_suspend NULL
5345#define megasas_resume NULL
5346#endif
bo yang31ea7082007-11-07 12:09:50 -05005347
5348/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005349 * megasas_detach_one - PCI hot"un"plug entry point
5350 * @pdev: PCI device structure
5351 */
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08005352static void megasas_detach_one(struct pci_dev *pdev)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005353{
5354 int i;
5355 struct Scsi_Host *host;
5356 struct megasas_instance *instance;
adam radford9c915a82010-12-21 13:34:31 -08005357 struct fusion_context *fusion;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005358
5359 instance = pci_get_drvdata(pdev);
Yang, Boc3518832009-10-06 14:18:02 -06005360 instance->unload = 1;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005361 host = instance->host;
adam radford9c915a82010-12-21 13:34:31 -08005362 fusion = instance->ctrl_context;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005363
adam radford229fe472014-03-10 02:51:56 -07005364 /* Shutdown SR-IOV heartbeat timer */
5365 if (instance->requestorId && !instance->skip_heartbeat_timer_del)
5366 del_timer_sync(&instance->sriov_heartbeat_timer);
5367
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005368 scsi_remove_host(instance->host);
5369 megasas_flush_cache(instance);
bo yang31ea7082007-11-07 12:09:50 -05005370 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005371
5372 /* cancel the delayed work if this work still in queue*/
5373 if (instance->ev != NULL) {
5374 struct megasas_aen_event *ev = instance->ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08005375 cancel_delayed_work_sync(&ev->hotplug_work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005376 instance->ev = NULL;
5377 }
5378
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305379 /* cancel all wait events */
5380 wake_up_all(&instance->int_cmd_wait_q);
5381
Sumant Patro5d018ad2006-10-03 13:13:18 -07005382 tasklet_kill(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005383
5384 /*
5385 * Take the instance off the instance array. Note that we will not
5386 * decrement the max_index. We let this array be sparse array
5387 */
5388 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
5389 if (megasas_mgmt_info.instance[i] == instance) {
5390 megasas_mgmt_info.count--;
5391 megasas_mgmt_info.instance[i] = NULL;
5392
5393 break;
5394 }
5395 }
5396
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305397 instance->instancet->disable_intr(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005398
adam radfordc8e858f2011-10-08 18:15:13 -07005399 if (instance->msix_vectors)
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305400 for (i = 0; i < instance->msix_vectors; i++) {
5401 irq_set_affinity_hint(
5402 instance->msixentry[i].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07005403 free_irq(instance->msixentry[i].vector,
5404 &instance->irq_context[i]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305405 }
adam radfordc8e858f2011-10-08 18:15:13 -07005406 else
5407 free_irq(instance->pdev->irq, &instance->irq_context[0]);
5408 if (instance->msix_vectors)
adam radford80d9da92010-12-21 10:17:40 -08005409 pci_disable_msix(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005410
adam radford9c915a82010-12-21 13:34:31 -08005411 switch (instance->pdev->device) {
5412 case PCI_DEVICE_ID_LSI_FUSION:
adam radford229fe472014-03-10 02:51:56 -07005413 case PCI_DEVICE_ID_LSI_PLASMA:
adam radford36807e62011-10-08 18:15:06 -07005414 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05305415 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08005416 megasas_release_fusion(instance);
5417 for (i = 0; i < 2 ; i++)
5418 if (fusion->ld_map[i])
5419 dma_free_coherent(&instance->pdev->dev,
5420 fusion->map_sz,
5421 fusion->ld_map[i],
5422 fusion->
5423 ld_map_phys[i]);
5424 kfree(instance->ctrl_context);
5425 break;
5426 default:
5427 megasas_release_mfi(instance);
adam radford9c915a82010-12-21 13:34:31 -08005428 pci_free_consistent(pdev, sizeof(u32),
5429 instance->producer,
5430 instance->producer_h);
5431 pci_free_consistent(pdev, sizeof(u32),
5432 instance->consumer,
5433 instance->consumer_h);
5434 break;
5435 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005436
Sumit.Saxena@lsi.com105900d2013-05-22 12:30:54 +05305437 if (instance->evt_detail)
5438 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
5439 instance->evt_detail, instance->evt_detail_h);
adam radford229fe472014-03-10 02:51:56 -07005440
5441 if (instance->vf_affiliation)
5442 pci_free_consistent(pdev, (MAX_LOGICAL_DRIVES + 1) *
5443 sizeof(struct MR_LD_VF_AFFILIATION),
5444 instance->vf_affiliation,
5445 instance->vf_affiliation_h);
5446
5447 if (instance->vf_affiliation_111)
5448 pci_free_consistent(pdev,
5449 sizeof(struct MR_LD_VF_AFFILIATION_111),
5450 instance->vf_affiliation_111,
5451 instance->vf_affiliation_111_h);
5452
5453 if (instance->hb_host_mem)
5454 pci_free_consistent(pdev, sizeof(struct MR_CTRL_HB_HOST_MEM),
5455 instance->hb_host_mem,
5456 instance->hb_host_mem_h);
5457
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005458 scsi_host_put(host);
5459
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005460 pci_disable_device(pdev);
5461
5462 return;
5463}
5464
5465/**
5466 * megasas_shutdown - Shutdown entry point
5467 * @device: Generic device structure
5468 */
5469static void megasas_shutdown(struct pci_dev *pdev)
5470{
adam radfordc8e858f2011-10-08 18:15:13 -07005471 int i;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005472 struct megasas_instance *instance = pci_get_drvdata(pdev);
adam radfordc8e858f2011-10-08 18:15:13 -07005473
Yang, Bo0c79e682009-10-06 14:47:35 -06005474 instance->unload = 1;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005475 megasas_flush_cache(instance);
Yang, Bo530e6fc2008-08-10 12:42:37 -07005476 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05305477 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07005478 if (instance->msix_vectors)
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305479 for (i = 0; i < instance->msix_vectors; i++) {
5480 irq_set_affinity_hint(
5481 instance->msixentry[i].vector, NULL);
adam radfordc8e858f2011-10-08 18:15:13 -07005482 free_irq(instance->msixentry[i].vector,
5483 &instance->irq_context[i]);
Sumit.Saxena@lsi.com8058a162014-03-02 05:28:11 +05305484 }
adam radfordc8e858f2011-10-08 18:15:13 -07005485 else
5486 free_irq(instance->pdev->irq, &instance->irq_context[0]);
5487 if (instance->msix_vectors)
adam radford46fd2562011-05-11 18:34:17 -07005488 pci_disable_msix(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005489}
5490
5491/**
5492 * megasas_mgmt_open - char node "open" entry point
5493 */
5494static int megasas_mgmt_open(struct inode *inode, struct file *filep)
5495{
5496 /*
5497 * Allow only those users with admin rights
5498 */
5499 if (!capable(CAP_SYS_ADMIN))
5500 return -EACCES;
5501
5502 return 0;
5503}
5504
5505/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005506 * megasas_mgmt_fasync - Async notifier registration from applications
5507 *
5508 * This function adds the calling process to a driver global queue. When an
5509 * event occurs, SIGIO will be sent to all processes in this queue.
5510 */
5511static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
5512{
5513 int rc;
5514
Arjan van de Ven0b950672006-01-11 13:16:10 +01005515 mutex_lock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005516
5517 rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
5518
Arjan van de Ven0b950672006-01-11 13:16:10 +01005519 mutex_unlock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005520
5521 if (rc >= 0) {
5522 /* For sanity check when we get ioctl */
5523 filep->private_data = filep;
5524 return 0;
5525 }
5526
5527 printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc);
5528
5529 return rc;
5530}
5531
5532/**
Yang, Boc3518832009-10-06 14:18:02 -06005533 * megasas_mgmt_poll - char node "poll" entry point
5534 * */
5535static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
5536{
5537 unsigned int mask;
5538 unsigned long flags;
5539 poll_wait(file, &megasas_poll_wait, wait);
5540 spin_lock_irqsave(&poll_aen_lock, flags);
5541 if (megasas_poll_wait_aen)
5542 mask = (POLLIN | POLLRDNORM);
5543 else
5544 mask = 0;
5545 spin_unlock_irqrestore(&poll_aen_lock, flags);
5546 return mask;
5547}
5548
5549/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005550 * megasas_mgmt_fw_ioctl - Issues management ioctls to FW
5551 * @instance: Adapter soft state
5552 * @argp: User's ioctl packet
5553 */
5554static int
5555megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
5556 struct megasas_iocpacket __user * user_ioc,
5557 struct megasas_iocpacket *ioc)
5558{
5559 struct megasas_sge32 *kern_sge32;
5560 struct megasas_cmd *cmd;
5561 void *kbuff_arr[MAX_IOCTL_SGE];
5562 dma_addr_t buf_handle = 0;
5563 int error = 0, i;
5564 void *sense = NULL;
5565 dma_addr_t sense_handle;
Yang, Bo7b2519a2009-10-06 14:52:20 -06005566 unsigned long *sense_ptr;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005567
5568 memset(kbuff_arr, 0, sizeof(kbuff_arr));
5569
5570 if (ioc->sge_count > MAX_IOCTL_SGE) {
5571 printk(KERN_DEBUG "megasas: SGE count [%d] > max limit [%d]\n",
5572 ioc->sge_count, MAX_IOCTL_SGE);
5573 return -EINVAL;
5574 }
5575
5576 cmd = megasas_get_cmd(instance);
5577 if (!cmd) {
5578 printk(KERN_DEBUG "megasas: Failed to get a cmd packet\n");
5579 return -ENOMEM;
5580 }
5581
5582 /*
5583 * User's IOCTL packet has 2 frames (maximum). Copy those two
5584 * frames into our cmd's frames. cmd->frame's context will get
5585 * overwritten when we copy from user's frames. So set that value
5586 * alone separately
5587 */
5588 memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305589 cmd->frame->hdr.context = cpu_to_le32(cmd->index);
Yang, Boc3518832009-10-06 14:18:02 -06005590 cmd->frame->hdr.pad_0 = 0;
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305591 cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_IEEE |
5592 MFI_FRAME_SGL64 |
5593 MFI_FRAME_SENSE64));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005594
5595 /*
5596 * The management interface between applications and the fw uses
5597 * MFI frames. E.g, RAID configuration changes, LD property changes
5598 * etc are accomplishes through different kinds of MFI frames. The
5599 * driver needs to care only about substituting user buffers with
5600 * kernel buffers in SGLs. The location of SGL is embedded in the
5601 * struct iocpacket itself.
5602 */
5603 kern_sge32 = (struct megasas_sge32 *)
5604 ((unsigned long)cmd->frame + ioc->sgl_off);
5605
5606 /*
5607 * For each user buffer, create a mirror buffer and copy in
5608 */
5609 for (i = 0; i < ioc->sge_count; i++) {
Bjørn Mork98cb7e42011-01-19 10:01:14 +01005610 if (!ioc->sgl[i].iov_len)
5611 continue;
5612
Sumant Patro9f35fa82007-02-14 12:55:45 -08005613 kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005614 ioc->sgl[i].iov_len,
Sumant Patro9f35fa82007-02-14 12:55:45 -08005615 &buf_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005616 if (!kbuff_arr[i]) {
5617 printk(KERN_DEBUG "megasas: Failed to alloc "
5618 "kernel SGL buffer for IOCTL \n");
5619 error = -ENOMEM;
5620 goto out;
5621 }
5622
5623 /*
5624 * We don't change the dma_coherent_mask, so
5625 * pci_alloc_consistent only returns 32bit addresses
5626 */
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305627 kern_sge32[i].phys_addr = cpu_to_le32(buf_handle);
5628 kern_sge32[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005629
5630 /*
5631 * We created a kernel buffer corresponding to the
5632 * user buffer. Now copy in from the user buffer
5633 */
5634 if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base,
5635 (u32) (ioc->sgl[i].iov_len))) {
5636 error = -EFAULT;
5637 goto out;
5638 }
5639 }
5640
5641 if (ioc->sense_len) {
Sumant Patro9f35fa82007-02-14 12:55:45 -08005642 sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,
5643 &sense_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005644 if (!sense) {
5645 error = -ENOMEM;
5646 goto out;
5647 }
5648
5649 sense_ptr =
Yang, Bo7b2519a2009-10-06 14:52:20 -06005650 (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305651 *sense_ptr = cpu_to_le32(sense_handle);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005652 }
5653
5654 /*
5655 * Set the sync_cmd flag so that the ISR knows not to complete this
5656 * cmd to the SCSI mid-layer
5657 */
5658 cmd->sync_cmd = 1;
Sumit.Saxena@lsi.comcfbe7552014-02-12 23:36:15 +05305659 megasas_issue_blocked_cmd(instance, cmd, 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005660 cmd->sync_cmd = 0;
5661
5662 /*
5663 * copy out the kernel buffers to user buffers
5664 */
5665 for (i = 0; i < ioc->sge_count; i++) {
5666 if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i],
5667 ioc->sgl[i].iov_len)) {
5668 error = -EFAULT;
5669 goto out;
5670 }
5671 }
5672
5673 /*
5674 * copy out the sense
5675 */
5676 if (ioc->sense_len) {
5677 /*
bo yangb70a41e2008-03-18 03:13:06 -04005678 * sense_ptr points to the location that has the user
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005679 * sense buffer address
5680 */
Yang, Bo7b2519a2009-10-06 14:52:20 -06005681 sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
5682 ioc->sense_off);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005683
bo yangb70a41e2008-03-18 03:13:06 -04005684 if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
5685 sense, ioc->sense_len)) {
bo yangb10c36a2007-11-09 04:28:47 -05005686 printk(KERN_ERR "megasas: Failed to copy out to user "
5687 "sense data\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005688 error = -EFAULT;
5689 goto out;
5690 }
5691 }
5692
5693 /*
5694 * copy the status codes returned by the fw
5695 */
5696 if (copy_to_user(&user_ioc->frame.hdr.cmd_status,
5697 &cmd->frame->hdr.cmd_status, sizeof(u8))) {
5698 printk(KERN_DEBUG "megasas: Error copying out cmd_status\n");
5699 error = -EFAULT;
5700 }
5701
5702 out:
5703 if (sense) {
Sumant Patro9f35fa82007-02-14 12:55:45 -08005704 dma_free_coherent(&instance->pdev->dev, ioc->sense_len,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005705 sense, sense_handle);
5706 }
5707
Bjørn Mork7a6a7312012-11-21 09:54:48 +01005708 for (i = 0; i < ioc->sge_count; i++) {
5709 if (kbuff_arr[i])
5710 dma_free_coherent(&instance->pdev->dev,
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305711 le32_to_cpu(kern_sge32[i].length),
Bjørn Mork7a6a7312012-11-21 09:54:48 +01005712 kbuff_arr[i],
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05305713 le32_to_cpu(kern_sge32[i].phys_addr));
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005714 }
5715
5716 megasas_return_cmd(instance, cmd);
5717 return error;
5718}
5719
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005720static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
5721{
5722 struct megasas_iocpacket __user *user_ioc =
5723 (struct megasas_iocpacket __user *)arg;
5724 struct megasas_iocpacket *ioc;
5725 struct megasas_instance *instance;
5726 int error;
bo yang39a98552010-09-22 22:36:29 -04005727 int i;
5728 unsigned long flags;
5729 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005730
5731 ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
5732 if (!ioc)
5733 return -ENOMEM;
5734
5735 if (copy_from_user(ioc, user_ioc, sizeof(*ioc))) {
5736 error = -EFAULT;
5737 goto out_kfree_ioc;
5738 }
5739
5740 instance = megasas_lookup_instance(ioc->host_no);
5741 if (!instance) {
5742 error = -ENODEV;
5743 goto out_kfree_ioc;
5744 }
5745
adam radford229fe472014-03-10 02:51:56 -07005746 /* Adjust ioctl wait time for VF mode */
5747 if (instance->requestorId)
5748 wait_time = MEGASAS_ROUTINE_WAIT_TIME_VF;
5749
5750 /* Block ioctls in VF mode */
5751 if (instance->requestorId && !allow_vf_ioctls) {
5752 error = -ENODEV;
5753 goto out_kfree_ioc;
5754 }
5755
bo yang39a98552010-09-22 22:36:29 -04005756 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
5757 printk(KERN_ERR "Controller in crit error\n");
Yang, Bo0c79e682009-10-06 14:47:35 -06005758 error = -ENODEV;
5759 goto out_kfree_ioc;
5760 }
5761
5762 if (instance->unload == 1) {
5763 error = -ENODEV;
5764 goto out_kfree_ioc;
5765 }
5766
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005767 /*
5768 * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
5769 */
5770 if (down_interruptible(&instance->ioctl_sem)) {
5771 error = -ERESTARTSYS;
5772 goto out_kfree_ioc;
5773 }
bo yang39a98552010-09-22 22:36:29 -04005774
5775 for (i = 0; i < wait_time; i++) {
5776
5777 spin_lock_irqsave(&instance->hba_lock, flags);
5778 if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
5779 spin_unlock_irqrestore(&instance->hba_lock, flags);
5780 break;
5781 }
5782 spin_unlock_irqrestore(&instance->hba_lock, flags);
5783
5784 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
5785 printk(KERN_NOTICE "megasas: waiting"
5786 "for controller reset to finish\n");
5787 }
5788
5789 msleep(1000);
5790 }
5791
5792 spin_lock_irqsave(&instance->hba_lock, flags);
5793 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
5794 spin_unlock_irqrestore(&instance->hba_lock, flags);
5795
5796 printk(KERN_ERR "megaraid_sas: timed out while"
5797 "waiting for HBA to recover\n");
5798 error = -ENODEV;
Dan Carpenterc64e4832013-04-16 10:44:19 +03005799 goto out_up;
bo yang39a98552010-09-22 22:36:29 -04005800 }
5801 spin_unlock_irqrestore(&instance->hba_lock, flags);
5802
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005803 error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
Dan Carpenterc64e4832013-04-16 10:44:19 +03005804 out_up:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005805 up(&instance->ioctl_sem);
5806
5807 out_kfree_ioc:
5808 kfree(ioc);
5809 return error;
5810}
5811
5812static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
5813{
5814 struct megasas_instance *instance;
5815 struct megasas_aen aen;
5816 int error;
bo yang39a98552010-09-22 22:36:29 -04005817 int i;
5818 unsigned long flags;
5819 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005820
5821 if (file->private_data != file) {
5822 printk(KERN_DEBUG "megasas: fasync_helper was not "
5823 "called first\n");
5824 return -EINVAL;
5825 }
5826
5827 if (copy_from_user(&aen, (void __user *)arg, sizeof(aen)))
5828 return -EFAULT;
5829
5830 instance = megasas_lookup_instance(aen.host_no);
5831
5832 if (!instance)
5833 return -ENODEV;
5834
bo yang39a98552010-09-22 22:36:29 -04005835 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
5836 return -ENODEV;
Yang, Bo0c79e682009-10-06 14:47:35 -06005837 }
5838
5839 if (instance->unload == 1) {
5840 return -ENODEV;
5841 }
5842
bo yang39a98552010-09-22 22:36:29 -04005843 for (i = 0; i < wait_time; i++) {
5844
5845 spin_lock_irqsave(&instance->hba_lock, flags);
5846 if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
5847 spin_unlock_irqrestore(&instance->hba_lock,
5848 flags);
5849 break;
5850 }
5851
5852 spin_unlock_irqrestore(&instance->hba_lock, flags);
5853
5854 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
5855 printk(KERN_NOTICE "megasas: waiting for"
5856 "controller reset to finish\n");
5857 }
5858
5859 msleep(1000);
5860 }
5861
5862 spin_lock_irqsave(&instance->hba_lock, flags);
5863 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
5864 spin_unlock_irqrestore(&instance->hba_lock, flags);
5865 printk(KERN_ERR "megaraid_sas: timed out while waiting"
5866 "for HBA to recover.\n");
5867 return -ENODEV;
5868 }
5869 spin_unlock_irqrestore(&instance->hba_lock, flags);
5870
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02005871 mutex_lock(&instance->aen_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005872 error = megasas_register_aen(instance, aen.seq_num,
5873 aen.class_locale_word);
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02005874 mutex_unlock(&instance->aen_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005875 return error;
5876}
5877
5878/**
5879 * megasas_mgmt_ioctl - char node ioctl entry point
5880 */
5881static long
5882megasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
5883{
5884 switch (cmd) {
5885 case MEGASAS_IOC_FIRMWARE:
5886 return megasas_mgmt_ioctl_fw(file, arg);
5887
5888 case MEGASAS_IOC_GET_AEN:
5889 return megasas_mgmt_ioctl_aen(file, arg);
5890 }
5891
5892 return -ENOTTY;
5893}
5894
5895#ifdef CONFIG_COMPAT
5896static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
5897{
5898 struct compat_megasas_iocpacket __user *cioc =
5899 (struct compat_megasas_iocpacket __user *)arg;
5900 struct megasas_iocpacket __user *ioc =
5901 compat_alloc_user_space(sizeof(struct megasas_iocpacket));
5902 int i;
5903 int error = 0;
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01005904 compat_uptr_t ptr;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005905
Jeff Garzik83aabc12006-10-04 06:34:03 -04005906 if (clear_user(ioc, sizeof(*ioc)))
5907 return -EFAULT;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005908
5909 if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) ||
5910 copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) ||
5911 copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) ||
5912 copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) ||
5913 copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) ||
5914 copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
5915 return -EFAULT;
5916
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01005917 /*
5918 * The sense_ptr is used in megasas_mgmt_fw_ioctl only when
5919 * sense_len is not null, so prepare the 64bit value under
5920 * the same condition.
5921 */
5922 if (ioc->sense_len) {
5923 void __user **sense_ioc_ptr =
5924 (void __user **)(ioc->frame.raw + ioc->sense_off);
5925 compat_uptr_t *sense_cioc_ptr =
5926 (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
5927 if (get_user(ptr, sense_cioc_ptr) ||
5928 put_user(compat_ptr(ptr), sense_ioc_ptr))
5929 return -EFAULT;
5930 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005931
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01005932 for (i = 0; i < MAX_IOCTL_SGE; i++) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005933 if (get_user(ptr, &cioc->sgl[i].iov_base) ||
5934 put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
5935 copy_in_user(&ioc->sgl[i].iov_len,
5936 &cioc->sgl[i].iov_len, sizeof(compat_size_t)))
5937 return -EFAULT;
5938 }
5939
5940 error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc);
5941
5942 if (copy_in_user(&cioc->frame.hdr.cmd_status,
5943 &ioc->frame.hdr.cmd_status, sizeof(u8))) {
5944 printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n");
5945 return -EFAULT;
5946 }
5947 return error;
5948}
5949
5950static long
5951megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd,
5952 unsigned long arg)
5953{
5954 switch (cmd) {
Sumant Patrocb59aa62006-01-25 11:53:25 -08005955 case MEGASAS_IOC_FIRMWARE32:
5956 return megasas_mgmt_compat_ioctl_fw(file, arg);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005957 case MEGASAS_IOC_GET_AEN:
5958 return megasas_mgmt_ioctl_aen(file, arg);
5959 }
5960
5961 return -ENOTTY;
5962}
5963#endif
5964
5965/*
5966 * File operations structure for management interface
5967 */
Arjan van de Ven00977a52007-02-12 00:55:34 -08005968static const struct file_operations megasas_mgmt_fops = {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005969 .owner = THIS_MODULE,
5970 .open = megasas_mgmt_open,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005971 .fasync = megasas_mgmt_fasync,
5972 .unlocked_ioctl = megasas_mgmt_ioctl,
Yang, Boc3518832009-10-06 14:18:02 -06005973 .poll = megasas_mgmt_poll,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005974#ifdef CONFIG_COMPAT
5975 .compat_ioctl = megasas_mgmt_compat_ioctl,
5976#endif
Arnd Bergmann6038f372010-08-15 18:52:59 +02005977 .llseek = noop_llseek,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005978};
5979
5980/*
5981 * PCI hotplug support registration structure
5982 */
5983static struct pci_driver megasas_pci_driver = {
5984
5985 .name = "megaraid_sas",
5986 .id_table = megasas_pci_table,
5987 .probe = megasas_probe_one,
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08005988 .remove = megasas_detach_one,
bo yang31ea7082007-11-07 12:09:50 -05005989 .suspend = megasas_suspend,
5990 .resume = megasas_resume,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005991 .shutdown = megasas_shutdown,
5992};
5993
5994/*
5995 * Sysfs driver attributes
5996 */
5997static ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf)
5998{
5999 return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n",
6000 MEGASAS_VERSION);
6001}
6002
6003static DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL);
6004
6005static ssize_t
6006megasas_sysfs_show_release_date(struct device_driver *dd, char *buf)
6007{
6008 return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n",
6009 MEGASAS_RELDATE);
6010}
6011
6012static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
6013 NULL);
6014
Sumant Patro658dced2006-10-03 13:09:14 -07006015static ssize_t
Yang, Bo72c4fd32009-10-06 14:20:59 -06006016megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
6017{
6018 return sprintf(buf, "%u\n", support_poll_for_event);
6019}
6020
6021static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
6022 megasas_sysfs_show_support_poll_for_event, NULL);
6023
Yang, Bo837f5fe2010-10-11 06:59:20 -06006024 static ssize_t
6025megasas_sysfs_show_support_device_change(struct device_driver *dd, char *buf)
6026{
6027 return sprintf(buf, "%u\n", support_device_change);
6028}
6029
6030static DRIVER_ATTR(support_device_change, S_IRUGO,
6031 megasas_sysfs_show_support_device_change, NULL);
6032
Yang, Bo72c4fd32009-10-06 14:20:59 -06006033static ssize_t
Sumant Patro658dced2006-10-03 13:09:14 -07006034megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
6035{
bo yangad84db22007-11-09 04:40:16 -05006036 return sprintf(buf, "%u\n", megasas_dbg_lvl);
Sumant Patro658dced2006-10-03 13:09:14 -07006037}
6038
6039static ssize_t
6040megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count)
6041{
6042 int retval = count;
6043 if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){
6044 printk(KERN_ERR "megasas: could not set dbg_lvl\n");
6045 retval = -EINVAL;
6046 }
6047 return retval;
6048}
6049
Joe Malicki66dca9b2008-08-14 17:14:48 -04006050static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl,
bo yangad84db22007-11-09 04:40:16 -05006051 megasas_sysfs_set_dbg_lvl);
6052
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006053static void
6054megasas_aen_polling(struct work_struct *work)
6055{
6056 struct megasas_aen_event *ev =
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08006057 container_of(work, struct megasas_aen_event, hotplug_work.work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006058 struct megasas_instance *instance = ev->instance;
6059 union megasas_evt_class_locale class_locale;
6060 struct Scsi_Host *host;
6061 struct scsi_device *sdev1;
6062 u16 pd_index = 0;
Yang, Boc9786842009-12-06 08:39:25 -07006063 u16 ld_index = 0;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006064 int i, j, doscan = 0;
adam radford229fe472014-03-10 02:51:56 -07006065 u32 seq_num, wait_time = MEGASAS_RESET_WAIT_TIME;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006066 int error;
6067
6068 if (!instance) {
6069 printk(KERN_ERR "invalid instance!\n");
6070 kfree(ev);
6071 return;
6072 }
adam radford229fe472014-03-10 02:51:56 -07006073
6074 /* Adjust event workqueue thread wait time for VF mode */
6075 if (instance->requestorId)
6076 wait_time = MEGASAS_ROUTINE_WAIT_TIME_VF;
6077
6078 /* Don't run the event workqueue thread if OCR is running */
6079 for (i = 0; i < wait_time; i++) {
6080 if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL)
6081 break;
6082 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
6083 printk(KERN_NOTICE "megasas: %s waiting for "
6084 "controller reset to finish for scsi%d\n",
6085 __func__, instance->host->host_no);
6086 }
6087 msleep(1000);
6088 }
6089
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006090 instance->ev = NULL;
6091 host = instance->host;
6092 if (instance->evt_detail) {
6093
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306094 switch (le32_to_cpu(instance->evt_detail->code)) {
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006095 case MR_EVT_PD_INSERTED:
Yang, Boc9786842009-12-06 08:39:25 -07006096 if (megasas_get_pd_list(instance) == 0) {
6097 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
6098 for (j = 0;
6099 j < MEGASAS_MAX_DEV_PER_CHANNEL;
6100 j++) {
6101
6102 pd_index =
6103 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
6104
6105 sdev1 =
6106 scsi_device_lookup(host, i, j, 0);
6107
6108 if (instance->pd_list[pd_index].driveState
6109 == MR_PD_STATE_SYSTEM) {
6110 if (!sdev1) {
6111 scsi_add_device(host, i, j, 0);
6112 }
6113
6114 if (sdev1)
6115 scsi_device_put(sdev1);
6116 }
6117 }
6118 }
6119 }
6120 doscan = 0;
6121 break;
6122
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006123 case MR_EVT_PD_REMOVED:
Yang, Boc9786842009-12-06 08:39:25 -07006124 if (megasas_get_pd_list(instance) == 0) {
Yang, Boc9786842009-12-06 08:39:25 -07006125 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
6126 for (j = 0;
6127 j < MEGASAS_MAX_DEV_PER_CHANNEL;
6128 j++) {
6129
6130 pd_index =
6131 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
6132
6133 sdev1 =
6134 scsi_device_lookup(host, i, j, 0);
6135
6136 if (instance->pd_list[pd_index].driveState
6137 == MR_PD_STATE_SYSTEM) {
6138 if (sdev1) {
6139 scsi_device_put(sdev1);
6140 }
6141 } else {
6142 if (sdev1) {
6143 scsi_remove_device(sdev1);
6144 scsi_device_put(sdev1);
6145 }
6146 }
6147 }
6148 }
6149 }
6150 doscan = 0;
6151 break;
6152
6153 case MR_EVT_LD_OFFLINE:
adam radford4c598b22011-02-24 20:56:53 -08006154 case MR_EVT_CFG_CLEARED:
Yang, Boc9786842009-12-06 08:39:25 -07006155 case MR_EVT_LD_DELETED:
adam radford229fe472014-03-10 02:51:56 -07006156 if (!instance->requestorId ||
6157 (instance->requestorId &&
6158 megasas_get_ld_vf_affiliation(instance, 0))) {
6159 if (megasas_ld_list_query(instance,
6160 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
6161 megasas_get_ld_list(instance);
6162 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
6163 for (j = 0;
6164 j < MEGASAS_MAX_DEV_PER_CHANNEL;
6165 j++) {
Yang, Boc9786842009-12-06 08:39:25 -07006166
adam radford229fe472014-03-10 02:51:56 -07006167 ld_index =
6168 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
Yang, Boc9786842009-12-06 08:39:25 -07006169
adam radford229fe472014-03-10 02:51:56 -07006170 sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
Yang, Boc9786842009-12-06 08:39:25 -07006171
adam radford229fe472014-03-10 02:51:56 -07006172 if (instance->ld_ids[ld_index]
6173 != 0xff) {
6174 if (sdev1)
6175 scsi_device_put(sdev1);
6176 } else {
6177 if (sdev1) {
6178 scsi_remove_device(sdev1);
6179 scsi_device_put(sdev1);
6180 }
Yang, Boc9786842009-12-06 08:39:25 -07006181 }
6182 }
adam radford229fe472014-03-10 02:51:56 -07006183 }
6184 doscan = 0;
6185 }
6186 break;
6187 case MR_EVT_LD_CREATED:
6188 if (!instance->requestorId ||
6189 (instance->requestorId &&
6190 megasas_get_ld_vf_affiliation(instance, 0))) {
6191 if (megasas_ld_list_query(instance,
6192 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
6193 megasas_get_ld_list(instance);
6194 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
6195 for (j = 0;
6196 j < MEGASAS_MAX_DEV_PER_CHANNEL;
6197 j++) {
6198 ld_index =
6199 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
6200
6201 sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
6202
6203 if (instance->ld_ids[ld_index]
6204 != 0xff) {
6205 if (!sdev1)
6206 scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
6207 }
6208 if (sdev1)
6209 scsi_device_put(sdev1);
Yang, Boc9786842009-12-06 08:39:25 -07006210 }
6211 }
adam radford229fe472014-03-10 02:51:56 -07006212 doscan = 0;
Yang, Boc9786842009-12-06 08:39:25 -07006213 }
Yang, Boc9786842009-12-06 08:39:25 -07006214 break;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006215 case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
Yang, Boc9786842009-12-06 08:39:25 -07006216 case MR_EVT_FOREIGN_CFG_IMPORTED:
adam radford9c915a82010-12-21 13:34:31 -08006217 case MR_EVT_LD_STATE_CHANGE:
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006218 doscan = 1;
6219 break;
6220 default:
6221 doscan = 0;
6222 break;
6223 }
6224 } else {
6225 printk(KERN_ERR "invalid evt_detail!\n");
6226 kfree(ev);
6227 return;
6228 }
6229
6230 if (doscan) {
adam radford229fe472014-03-10 02:51:56 -07006231 printk(KERN_INFO "megaraid_sas: scanning for scsi%d...\n",
6232 instance->host->host_no);
Hannes Reinecke58968fc2014-01-16 11:25:36 +01006233 if (megasas_get_pd_list(instance) == 0) {
6234 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
6235 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
6236 pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
6237 sdev1 = scsi_device_lookup(host, i, j, 0);
6238 if (instance->pd_list[pd_index].driveState ==
6239 MR_PD_STATE_SYSTEM) {
6240 if (!sdev1) {
6241 scsi_add_device(host, i, j, 0);
6242 }
6243 if (sdev1)
6244 scsi_device_put(sdev1);
6245 } else {
6246 if (sdev1) {
6247 scsi_remove_device(sdev1);
6248 scsi_device_put(sdev1);
6249 }
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006250 }
6251 }
6252 }
6253 }
Yang, Boc9786842009-12-06 08:39:25 -07006254
adam radford229fe472014-03-10 02:51:56 -07006255 if (!instance->requestorId ||
6256 (instance->requestorId &&
6257 megasas_get_ld_vf_affiliation(instance, 0))) {
6258 if (megasas_ld_list_query(instance,
6259 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
6260 megasas_get_ld_list(instance);
6261 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
6262 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL;
6263 j++) {
6264 ld_index =
6265 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
Yang, Boc9786842009-12-06 08:39:25 -07006266
adam radford229fe472014-03-10 02:51:56 -07006267 sdev1 = scsi_device_lookup(host,
6268 MEGASAS_MAX_PD_CHANNELS + i, j, 0);
6269 if (instance->ld_ids[ld_index]
6270 != 0xff) {
6271 if (!sdev1)
6272 scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
6273 else
6274 scsi_device_put(sdev1);
Yang, Boc9786842009-12-06 08:39:25 -07006275 } else {
adam radford229fe472014-03-10 02:51:56 -07006276 if (sdev1) {
6277 scsi_remove_device(sdev1);
6278 scsi_device_put(sdev1);
6279 }
Yang, Boc9786842009-12-06 08:39:25 -07006280 }
6281 }
6282 }
6283 }
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006284 }
6285
6286 if ( instance->aen_cmd != NULL ) {
6287 kfree(ev);
6288 return ;
6289 }
6290
Sumit.Saxena@lsi.com94cd65d2013-09-06 15:50:52 +05306291 seq_num = le32_to_cpu(instance->evt_detail->seq_num) + 1;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06006292
6293 /* Register AEN with FW for latest sequence number plus 1 */
6294 class_locale.members.reserved = 0;
6295 class_locale.members.locale = MR_EVT_LOCALE_ALL;
6296 class_locale.members.class = MR_EVT_CLASS_DEBUG;
6297 mutex_lock(&instance->aen_mutex);
6298 error = megasas_register_aen(instance, seq_num,
6299 class_locale.word);
6300 mutex_unlock(&instance->aen_mutex);
6301
6302 if (error)
6303 printk(KERN_ERR "register aen failed error %x\n", error);
6304
6305 kfree(ev);
6306}
6307
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006308/**
6309 * megasas_init - Driver load entry point
6310 */
6311static int __init megasas_init(void)
6312{
6313 int rval;
6314
6315 /*
6316 * Announce driver version and other information
6317 */
6318 printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
6319 MEGASAS_EXT_VERSION);
6320
Kashyap Desaibd8d6dd2012-07-17 18:20:44 -07006321 spin_lock_init(&poll_aen_lock);
6322
Yang, Bo72c4fd32009-10-06 14:20:59 -06006323 support_poll_for_event = 2;
Yang, Bo837f5fe2010-10-11 06:59:20 -06006324 support_device_change = 1;
Yang, Bo72c4fd32009-10-06 14:20:59 -06006325
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006326 memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
6327
6328 /*
6329 * Register character device node
6330 */
6331 rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops);
6332
6333 if (rval < 0) {
6334 printk(KERN_DEBUG "megasas: failed to open device node\n");
6335 return rval;
6336 }
6337
6338 megasas_mgmt_majorno = rval;
6339
6340 /*
6341 * Register ourselves as PCI hotplug module
6342 */
Michal Piotrowski4041b9c2006-08-17 13:28:22 +00006343 rval = pci_register_driver(&megasas_pci_driver);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006344
6345 if (rval) {
6346 printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n");
Jeff Garzik83aabc12006-10-04 06:34:03 -04006347 goto err_pcidrv;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006348 }
6349
Jeff Garzik83aabc12006-10-04 06:34:03 -04006350 rval = driver_create_file(&megasas_pci_driver.driver,
6351 &driver_attr_version);
6352 if (rval)
6353 goto err_dcf_attr_ver;
6354 rval = driver_create_file(&megasas_pci_driver.driver,
6355 &driver_attr_release_date);
6356 if (rval)
6357 goto err_dcf_rel_date;
Yang, Bo72c4fd32009-10-06 14:20:59 -06006358
6359 rval = driver_create_file(&megasas_pci_driver.driver,
6360 &driver_attr_support_poll_for_event);
6361 if (rval)
6362 goto err_dcf_support_poll_for_event;
6363
Jeff Garzik83aabc12006-10-04 06:34:03 -04006364 rval = driver_create_file(&megasas_pci_driver.driver,
6365 &driver_attr_dbg_lvl);
6366 if (rval)
6367 goto err_dcf_dbg_lvl;
bo yangad84db22007-11-09 04:40:16 -05006368 rval = driver_create_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06006369 &driver_attr_support_device_change);
6370 if (rval)
6371 goto err_dcf_support_device_change;
6372
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006373 return rval;
bo yangad84db22007-11-09 04:40:16 -05006374
Yang, Bo837f5fe2010-10-11 06:59:20 -06006375err_dcf_support_device_change:
6376 driver_remove_file(&megasas_pci_driver.driver,
bo yangad84db22007-11-09 04:40:16 -05006377 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04006378err_dcf_dbg_lvl:
6379 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo72c4fd32009-10-06 14:20:59 -06006380 &driver_attr_support_poll_for_event);
6381
6382err_dcf_support_poll_for_event:
6383 driver_remove_file(&megasas_pci_driver.driver,
Jeff Garzik83aabc12006-10-04 06:34:03 -04006384 &driver_attr_release_date);
Yang, Bo72c4fd32009-10-06 14:20:59 -06006385
Jeff Garzik83aabc12006-10-04 06:34:03 -04006386err_dcf_rel_date:
6387 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
6388err_dcf_attr_ver:
6389 pci_unregister_driver(&megasas_pci_driver);
6390err_pcidrv:
6391 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
adam radford0d490162010-12-14 19:17:17 -08006392 return rval;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006393}
6394
6395/**
6396 * megasas_exit - Driver unload entry point
6397 */
6398static void __exit megasas_exit(void)
6399{
Sumant Patro658dced2006-10-03 13:09:14 -07006400 driver_remove_file(&megasas_pci_driver.driver,
6401 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04006402 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06006403 &driver_attr_support_poll_for_event);
6404 driver_remove_file(&megasas_pci_driver.driver,
6405 &driver_attr_support_device_change);
6406 driver_remove_file(&megasas_pci_driver.driver,
Jeff Garzik83aabc12006-10-04 06:34:03 -04006407 &driver_attr_release_date);
6408 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04006409
6410 pci_unregister_driver(&megasas_pci_driver);
6411 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
6412}
6413
6414module_init(megasas_init);
6415module_exit(megasas_exit);