blob: 3eaec7ca84525ebb09f02953a012deab3e70123d [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 radford2b4857c2013-08-31 16:54:28 -070021 * Version : 06.700.06.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 radfordc5daa6a2012-07-17 18:20:03 -070078static int throttlequeuedepth = MEGASAS_THROTTLE_QUEUE_DEPTH;
79module_param(throttlequeuedepth, int, S_IRUGO);
80MODULE_PARM_DESC(throttlequeuedepth,
81 "Adapter queue depth when throttled due to I/O timeout. Default: 16");
82
adam radfordc007b8b2012-07-17 18:20:24 -070083int resetwaittime = MEGASAS_RESET_WAIT_TIME;
84module_param(resetwaittime, int, S_IRUGO);
85MODULE_PARM_DESC(resetwaittime, "Wait time in seconds after I/O timeout "
86 "before resetting adapter. Default: 180");
87
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040088MODULE_LICENSE("GPL");
89MODULE_VERSION(MEGASAS_VERSION);
Sumant Patro3d6d1742006-12-29 08:13:54 -080090MODULE_AUTHOR("megaraidlinux@lsi.com");
bo yangf28cd7c2007-11-09 04:44:56 -050091MODULE_DESCRIPTION("LSI MegaRAID SAS Driver");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -040092
adam radford058a8fa2011-10-08 18:14:27 -070093int megasas_transition_to_ready(struct megasas_instance *instance, int ocr);
bo yang39a98552010-09-22 22:36:29 -040094static int megasas_get_pd_list(struct megasas_instance *instance);
adam radford21c9e162013-09-06 15:27:14 -070095static int megasas_ld_list_query(struct megasas_instance *instance,
96 u8 query_type);
bo yang39a98552010-09-22 22:36:29 -040097static int megasas_issue_init_mfi(struct megasas_instance *instance);
98static int megasas_register_aen(struct megasas_instance *instance,
99 u32 seq_num, u32 class_locale_word);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400100/*
101 * PCI ID table for all supported controllers
102 */
103static struct pci_device_id megasas_pci_table[] = {
104
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200105 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064R)},
106 /* xscale IOP */
107 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
108 /* ppc IOP */
bo yangaf7a5642008-03-17 04:13:07 -0400109 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)},
110 /* ppc IOP */
Yang, Bo6610a6b2008-08-10 12:42:38 -0700111 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)},
112 /* gen2*/
113 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
114 /* gen2*/
Yang, Bo87911122009-10-06 14:31:54 -0600115 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
116 /* skinny*/
117 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
118 /* skinny*/
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200119 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
120 /* xscale IOP, vega */
121 {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
122 /* xscale IOP */
adam radford9c915a82010-12-21 13:34:31 -0800123 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FUSION)},
124 /* Fusion */
adam radford36807e62011-10-08 18:15:06 -0700125 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INVADER)},
126 /* Invader */
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +0530127 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FURY)},
128 /* Fury */
Henrik Kretzschmarf3d72712006-08-15 11:17:21 +0200129 {}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400130};
131
132MODULE_DEVICE_TABLE(pci, megasas_pci_table);
133
134static int megasas_mgmt_majorno;
135static struct megasas_mgmt_info megasas_mgmt_info;
136static struct fasync_struct *megasas_async_queue;
Arjan van de Ven0b950672006-01-11 13:16:10 +0100137static DEFINE_MUTEX(megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400138
Yang, Boc3518832009-10-06 14:18:02 -0600139static int megasas_poll_wait_aen;
140static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
Yang, Bo72c4fd32009-10-06 14:20:59 -0600141static u32 support_poll_for_event;
adam radford9c915a82010-12-21 13:34:31 -0800142u32 megasas_dbg_lvl;
Yang, Bo837f5fe2010-10-11 06:59:20 -0600143static u32 support_device_change;
Sumant Patro658dced2006-10-03 13:09:14 -0700144
Yang, Boc3518832009-10-06 14:18:02 -0600145/* define lock for aen poll */
146spinlock_t poll_aen_lock;
147
adam radford9c915a82010-12-21 13:34:31 -0800148void
bo yang7343eb62007-11-09 04:35:44 -0500149megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
150 u8 alt_status);
adam radfordebf054b2011-02-24 20:57:15 -0800151static u32
152megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs);
153static int
154megasas_adp_reset_gen2(struct megasas_instance *instance,
155 struct megasas_register_set __iomem *reg_set);
adam radfordcd50ba82010-12-21 10:23:23 -0800156static irqreturn_t megasas_isr(int irq, void *devp);
157static u32
158megasas_init_adapter_mfi(struct megasas_instance *instance);
159u32
160megasas_build_and_issue_cmd(struct megasas_instance *instance,
161 struct scsi_cmnd *scmd);
162static void megasas_complete_cmd_dpc(unsigned long instance_addr);
adam radford9c915a82010-12-21 13:34:31 -0800163void
164megasas_release_fusion(struct megasas_instance *instance);
165int
166megasas_ioc_init_fusion(struct megasas_instance *instance);
167void
168megasas_free_cmds_fusion(struct megasas_instance *instance);
169u8
170megasas_get_map_info(struct megasas_instance *instance);
171int
172megasas_sync_map_info(struct megasas_instance *instance);
173int
174wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd);
175void megasas_reset_reply_desc(struct megasas_instance *instance);
adam radford9c915a82010-12-21 13:34:31 -0800176int megasas_reset_fusion(struct Scsi_Host *shost);
177void megasas_fusion_ocr_wq(struct work_struct *work);
adam radfordcd50ba82010-12-21 10:23:23 -0800178
179void
180megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
181{
182 instance->instancet->fire_cmd(instance,
183 cmd->frame_phys_addr, 0, instance->reg_set);
184}
bo yang7343eb62007-11-09 04:35:44 -0500185
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400186/**
187 * megasas_get_cmd - Get a command from the free pool
188 * @instance: Adapter soft state
189 *
190 * Returns a free command from the pool
191 */
adam radford9c915a82010-12-21 13:34:31 -0800192struct megasas_cmd *megasas_get_cmd(struct megasas_instance
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400193 *instance)
194{
195 unsigned long flags;
196 struct megasas_cmd *cmd = NULL;
197
198 spin_lock_irqsave(&instance->cmd_pool_lock, flags);
199
200 if (!list_empty(&instance->cmd_pool)) {
201 cmd = list_entry((&instance->cmd_pool)->next,
202 struct megasas_cmd, list);
203 list_del_init(&cmd->list);
204 } else {
205 printk(KERN_ERR "megasas: Command pool empty!\n");
206 }
207
208 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
209 return cmd;
210}
211
212/**
213 * megasas_return_cmd - Return a cmd to free command pool
214 * @instance: Adapter soft state
215 * @cmd: Command packet to be returned to free command pool
216 */
adam radford9c915a82010-12-21 13:34:31 -0800217inline void
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400218megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
219{
220 unsigned long flags;
221
222 spin_lock_irqsave(&instance->cmd_pool_lock, flags);
223
224 cmd->scmd = NULL;
adam radford9c915a82010-12-21 13:34:31 -0800225 cmd->frame_count = 0;
adam radforde5f93a32011-10-08 18:15:19 -0700226 if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
227 (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +0530228 (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
adam radforde5f93a32011-10-08 18:15:19 -0700229 (reset_devices))
230 cmd->frame->hdr.cmd = MFI_CMD_INVALID;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400231 list_add_tail(&cmd->list, &instance->cmd_pool);
232
233 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
234}
235
Sumant Patro1341c932006-01-25 12:02:40 -0800236
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400237/**
adam radford0d490162010-12-14 19:17:17 -0800238* The following functions are defined for xscale
Sumant Patro1341c932006-01-25 12:02:40 -0800239* (deviceid : 1064R, PERC5) controllers
240*/
241
242/**
243 * megasas_enable_intr_xscale - Enables interrupts
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400244 * @regs: MFI register set
245 */
246static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530247megasas_enable_intr_xscale(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400248{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530249 struct megasas_register_set __iomem *regs;
250 regs = instance->reg_set;
bo yang39a98552010-09-22 22:36:29 -0400251 writel(0, &(regs)->outbound_intr_mask);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400252
253 /* Dummy readl to force pci flush */
254 readl(&regs->outbound_intr_mask);
255}
256
257/**
Sumant Patrob274cab2006-10-03 12:52:12 -0700258 * megasas_disable_intr_xscale -Disables interrupt
259 * @regs: MFI register set
260 */
261static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530262megasas_disable_intr_xscale(struct megasas_instance *instance)
Sumant Patrob274cab2006-10-03 12:52:12 -0700263{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530264 struct megasas_register_set __iomem *regs;
Sumant Patrob274cab2006-10-03 12:52:12 -0700265 u32 mask = 0x1f;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530266 regs = instance->reg_set;
Sumant Patrob274cab2006-10-03 12:52:12 -0700267 writel(mask, &regs->outbound_intr_mask);
268 /* Dummy readl to force pci flush */
269 readl(&regs->outbound_intr_mask);
270}
271
272/**
Sumant Patro1341c932006-01-25 12:02:40 -0800273 * megasas_read_fw_status_reg_xscale - returns the current FW status value
274 * @regs: MFI register set
275 */
276static u32
277megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs)
278{
279 return readl(&(regs)->outbound_msg_0);
280}
281/**
282 * megasas_clear_interrupt_xscale - Check & clear interrupt
283 * @regs: MFI register set
284 */
adam radford0d490162010-12-14 19:17:17 -0800285static int
Sumant Patro1341c932006-01-25 12:02:40 -0800286megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
287{
288 u32 status;
bo yang39a98552010-09-22 22:36:29 -0400289 u32 mfiStatus = 0;
Sumant Patro1341c932006-01-25 12:02:40 -0800290 /*
291 * Check if it is our interrupt
292 */
293 status = readl(&regs->outbound_intr_status);
294
bo yang39a98552010-09-22 22:36:29 -0400295 if (status & MFI_OB_INTR_STATUS_MASK)
296 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
297 if (status & MFI_XSCALE_OMR0_CHANGE_INTERRUPT)
298 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
Sumant Patro1341c932006-01-25 12:02:40 -0800299
300 /*
301 * Clear the interrupt by writing back the same value
302 */
bo yang39a98552010-09-22 22:36:29 -0400303 if (mfiStatus)
304 writel(status, &regs->outbound_intr_status);
Sumant Patro1341c932006-01-25 12:02:40 -0800305
Yang, Bo06f579d2008-08-10 12:42:37 -0700306 /* Dummy readl to force pci flush */
307 readl(&regs->outbound_intr_status);
308
bo yang39a98552010-09-22 22:36:29 -0400309 return mfiStatus;
Sumant Patro1341c932006-01-25 12:02:40 -0800310}
311
312/**
313 * megasas_fire_cmd_xscale - Sends command to the FW
314 * @frame_phys_addr : Physical address of cmd
315 * @frame_count : Number of frames for the command
316 * @regs : MFI register set
317 */
adam radford0d490162010-12-14 19:17:17 -0800318static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600319megasas_fire_cmd_xscale(struct megasas_instance *instance,
320 dma_addr_t frame_phys_addr,
321 u32 frame_count,
322 struct megasas_register_set __iomem *regs)
Sumant Patro1341c932006-01-25 12:02:40 -0800323{
bo yang39a98552010-09-22 22:36:29 -0400324 unsigned long flags;
325 spin_lock_irqsave(&instance->hba_lock, flags);
Sumant Patro1341c932006-01-25 12:02:40 -0800326 writel((frame_phys_addr >> 3)|(frame_count),
327 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400328 spin_unlock_irqrestore(&instance->hba_lock, flags);
329}
330
331/**
332 * megasas_adp_reset_xscale - For controller reset
333 * @regs: MFI register set
334 */
335static int
336megasas_adp_reset_xscale(struct megasas_instance *instance,
337 struct megasas_register_set __iomem *regs)
338{
339 u32 i;
340 u32 pcidata;
341 writel(MFI_ADP_RESET, &regs->inbound_doorbell);
342
343 for (i = 0; i < 3; i++)
344 msleep(1000); /* sleep for 3 secs */
345 pcidata = 0;
346 pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata);
347 printk(KERN_NOTICE "pcidata = %x\n", pcidata);
348 if (pcidata & 0x2) {
349 printk(KERN_NOTICE "mfi 1068 offset read=%x\n", pcidata);
350 pcidata &= ~0x2;
351 pci_write_config_dword(instance->pdev,
352 MFI_1068_PCSR_OFFSET, pcidata);
353
354 for (i = 0; i < 2; i++)
355 msleep(1000); /* need to wait 2 secs again */
356
357 pcidata = 0;
358 pci_read_config_dword(instance->pdev,
359 MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata);
360 printk(KERN_NOTICE "1068 offset handshake read=%x\n", pcidata);
361 if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) {
362 printk(KERN_NOTICE "1068 offset pcidt=%x\n", pcidata);
363 pcidata = 0;
364 pci_write_config_dword(instance->pdev,
365 MFI_1068_FW_HANDSHAKE_OFFSET, pcidata);
366 }
367 }
368 return 0;
369}
370
371/**
372 * megasas_check_reset_xscale - For controller reset check
373 * @regs: MFI register set
374 */
375static int
376megasas_check_reset_xscale(struct megasas_instance *instance,
377 struct megasas_register_set __iomem *regs)
378{
379 u32 consumer;
380 consumer = *instance->consumer;
381
382 if ((instance->adprecovery != MEGASAS_HBA_OPERATIONAL) &&
383 (*instance->consumer == MEGASAS_ADPRESET_INPROG_SIGN)) {
384 return 1;
385 }
386 return 0;
Sumant Patro1341c932006-01-25 12:02:40 -0800387}
388
389static struct megasas_instance_template megasas_instance_template_xscale = {
390
391 .fire_cmd = megasas_fire_cmd_xscale,
392 .enable_intr = megasas_enable_intr_xscale,
Sumant Patrob274cab2006-10-03 12:52:12 -0700393 .disable_intr = megasas_disable_intr_xscale,
Sumant Patro1341c932006-01-25 12:02:40 -0800394 .clear_intr = megasas_clear_intr_xscale,
395 .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
bo yang39a98552010-09-22 22:36:29 -0400396 .adp_reset = megasas_adp_reset_xscale,
397 .check_reset = megasas_check_reset_xscale,
adam radfordcd50ba82010-12-21 10:23:23 -0800398 .service_isr = megasas_isr,
399 .tasklet = megasas_complete_cmd_dpc,
400 .init_adapter = megasas_init_adapter_mfi,
401 .build_and_issue_cmd = megasas_build_and_issue_cmd,
402 .issue_dcmd = megasas_issue_dcmd,
Sumant Patro1341c932006-01-25 12:02:40 -0800403};
404
405/**
adam radford0d490162010-12-14 19:17:17 -0800406* This is the end of set of functions & definitions specific
Sumant Patro1341c932006-01-25 12:02:40 -0800407* to xscale (deviceid : 1064R, PERC5) controllers
408*/
409
410/**
adam radford0d490162010-12-14 19:17:17 -0800411* The following functions are defined for ppc (deviceid : 0x60)
Sumant Patrof9876f02006-02-03 15:34:35 -0800412* controllers
413*/
414
415/**
416 * megasas_enable_intr_ppc - Enables interrupts
417 * @regs: MFI register set
418 */
419static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530420megasas_enable_intr_ppc(struct megasas_instance *instance)
Sumant Patrof9876f02006-02-03 15:34:35 -0800421{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530422 struct megasas_register_set __iomem *regs;
423 regs = instance->reg_set;
Sumant Patrof9876f02006-02-03 15:34:35 -0800424 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
adam radford0d490162010-12-14 19:17:17 -0800425
bo yang39a98552010-09-22 22:36:29 -0400426 writel(~0x80000000, &(regs)->outbound_intr_mask);
Sumant Patrof9876f02006-02-03 15:34:35 -0800427
428 /* Dummy readl to force pci flush */
429 readl(&regs->outbound_intr_mask);
430}
431
432/**
Sumant Patrob274cab2006-10-03 12:52:12 -0700433 * megasas_disable_intr_ppc - Disable interrupt
434 * @regs: MFI register set
435 */
436static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530437megasas_disable_intr_ppc(struct megasas_instance *instance)
Sumant Patrob274cab2006-10-03 12:52:12 -0700438{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530439 struct megasas_register_set __iomem *regs;
Sumant Patrob274cab2006-10-03 12:52:12 -0700440 u32 mask = 0xFFFFFFFF;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530441 regs = instance->reg_set;
Sumant Patrob274cab2006-10-03 12:52:12 -0700442 writel(mask, &regs->outbound_intr_mask);
443 /* Dummy readl to force pci flush */
444 readl(&regs->outbound_intr_mask);
445}
446
447/**
Sumant Patrof9876f02006-02-03 15:34:35 -0800448 * megasas_read_fw_status_reg_ppc - returns the current FW status value
449 * @regs: MFI register set
450 */
451static u32
452megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)
453{
454 return readl(&(regs)->outbound_scratch_pad);
455}
456
457/**
458 * megasas_clear_interrupt_ppc - Check & clear interrupt
459 * @regs: MFI register set
460 */
adam radford0d490162010-12-14 19:17:17 -0800461static int
Sumant Patrof9876f02006-02-03 15:34:35 -0800462megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
463{
adam radford3cc6851f92011-05-11 18:34:52 -0700464 u32 status, mfiStatus = 0;
465
Sumant Patrof9876f02006-02-03 15:34:35 -0800466 /*
467 * Check if it is our interrupt
468 */
469 status = readl(&regs->outbound_intr_status);
470
adam radford3cc6851f92011-05-11 18:34:52 -0700471 if (status & MFI_REPLY_1078_MESSAGE_INTERRUPT)
472 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
473
474 if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT)
475 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
Sumant Patrof9876f02006-02-03 15:34:35 -0800476
477 /*
478 * Clear the interrupt by writing back the same value
479 */
480 writel(status, &regs->outbound_doorbell_clear);
481
Yang, Bo06f579d2008-08-10 12:42:37 -0700482 /* Dummy readl to force pci flush */
483 readl(&regs->outbound_doorbell_clear);
484
adam radford3cc6851f92011-05-11 18:34:52 -0700485 return mfiStatus;
Sumant Patrof9876f02006-02-03 15:34:35 -0800486}
adam radford3cc6851f92011-05-11 18:34:52 -0700487
Sumant Patrof9876f02006-02-03 15:34:35 -0800488/**
489 * megasas_fire_cmd_ppc - Sends command to the FW
490 * @frame_phys_addr : Physical address of cmd
491 * @frame_count : Number of frames for the command
492 * @regs : MFI register set
493 */
adam radford0d490162010-12-14 19:17:17 -0800494static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600495megasas_fire_cmd_ppc(struct megasas_instance *instance,
496 dma_addr_t frame_phys_addr,
497 u32 frame_count,
498 struct megasas_register_set __iomem *regs)
Sumant Patrof9876f02006-02-03 15:34:35 -0800499{
bo yang39a98552010-09-22 22:36:29 -0400500 unsigned long flags;
501 spin_lock_irqsave(&instance->hba_lock, flags);
adam radford0d490162010-12-14 19:17:17 -0800502 writel((frame_phys_addr | (frame_count<<1))|1,
Sumant Patrof9876f02006-02-03 15:34:35 -0800503 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400504 spin_unlock_irqrestore(&instance->hba_lock, flags);
Sumant Patrof9876f02006-02-03 15:34:35 -0800505}
506
bo yang39a98552010-09-22 22:36:29 -0400507/**
bo yang39a98552010-09-22 22:36:29 -0400508 * megasas_check_reset_ppc - For controller reset check
509 * @regs: MFI register set
510 */
511static int
512megasas_check_reset_ppc(struct megasas_instance *instance,
513 struct megasas_register_set __iomem *regs)
514{
adam radford3cc6851f92011-05-11 18:34:52 -0700515 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL)
516 return 1;
517
bo yang39a98552010-09-22 22:36:29 -0400518 return 0;
519}
adam radford3cc6851f92011-05-11 18:34:52 -0700520
Sumant Patrof9876f02006-02-03 15:34:35 -0800521static struct megasas_instance_template megasas_instance_template_ppc = {
adam radford0d490162010-12-14 19:17:17 -0800522
Sumant Patrof9876f02006-02-03 15:34:35 -0800523 .fire_cmd = megasas_fire_cmd_ppc,
524 .enable_intr = megasas_enable_intr_ppc,
Sumant Patrob274cab2006-10-03 12:52:12 -0700525 .disable_intr = megasas_disable_intr_ppc,
Sumant Patrof9876f02006-02-03 15:34:35 -0800526 .clear_intr = megasas_clear_intr_ppc,
527 .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
adam radford3cc6851f92011-05-11 18:34:52 -0700528 .adp_reset = megasas_adp_reset_xscale,
bo yang39a98552010-09-22 22:36:29 -0400529 .check_reset = megasas_check_reset_ppc,
adam radfordcd50ba82010-12-21 10:23:23 -0800530 .service_isr = megasas_isr,
531 .tasklet = megasas_complete_cmd_dpc,
532 .init_adapter = megasas_init_adapter_mfi,
533 .build_and_issue_cmd = megasas_build_and_issue_cmd,
534 .issue_dcmd = megasas_issue_dcmd,
Sumant Patrof9876f02006-02-03 15:34:35 -0800535};
536
537/**
Yang, Bo87911122009-10-06 14:31:54 -0600538 * megasas_enable_intr_skinny - Enables interrupts
539 * @regs: MFI register set
540 */
541static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530542megasas_enable_intr_skinny(struct megasas_instance *instance)
Yang, Bo87911122009-10-06 14:31:54 -0600543{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530544 struct megasas_register_set __iomem *regs;
545 regs = instance->reg_set;
Yang, Bo87911122009-10-06 14:31:54 -0600546 writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
547
548 writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
549
550 /* Dummy readl to force pci flush */
551 readl(&regs->outbound_intr_mask);
552}
553
554/**
555 * megasas_disable_intr_skinny - Disables interrupt
556 * @regs: MFI register set
557 */
558static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530559megasas_disable_intr_skinny(struct megasas_instance *instance)
Yang, Bo87911122009-10-06 14:31:54 -0600560{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530561 struct megasas_register_set __iomem *regs;
Yang, Bo87911122009-10-06 14:31:54 -0600562 u32 mask = 0xFFFFFFFF;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530563 regs = instance->reg_set;
Yang, Bo87911122009-10-06 14:31:54 -0600564 writel(mask, &regs->outbound_intr_mask);
565 /* Dummy readl to force pci flush */
566 readl(&regs->outbound_intr_mask);
567}
568
569/**
570 * megasas_read_fw_status_reg_skinny - returns the current FW status value
571 * @regs: MFI register set
572 */
573static u32
574megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
575{
576 return readl(&(regs)->outbound_scratch_pad);
577}
578
579/**
580 * megasas_clear_interrupt_skinny - Check & clear interrupt
581 * @regs: MFI register set
582 */
583static int
584megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
585{
586 u32 status;
adam radfordebf054b2011-02-24 20:57:15 -0800587 u32 mfiStatus = 0;
588
Yang, Bo87911122009-10-06 14:31:54 -0600589 /*
590 * Check if it is our interrupt
591 */
592 status = readl(&regs->outbound_intr_status);
593
594 if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
bo yang39a98552010-09-22 22:36:29 -0400595 return 0;
Yang, Bo87911122009-10-06 14:31:54 -0600596 }
597
598 /*
adam radfordebf054b2011-02-24 20:57:15 -0800599 * Check if it is our interrupt
600 */
James Georgasa3fda7d2013-06-26 12:03:19 -0600601 if ((megasas_read_fw_status_reg_skinny(regs) & MFI_STATE_MASK) ==
adam radfordebf054b2011-02-24 20:57:15 -0800602 MFI_STATE_FAULT) {
603 mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
604 } else
605 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
606
607 /*
Yang, Bo87911122009-10-06 14:31:54 -0600608 * Clear the interrupt by writing back the same value
609 */
610 writel(status, &regs->outbound_intr_status);
611
612 /*
613 * dummy read to flush PCI
614 */
615 readl(&regs->outbound_intr_status);
616
adam radfordebf054b2011-02-24 20:57:15 -0800617 return mfiStatus;
Yang, Bo87911122009-10-06 14:31:54 -0600618}
619
620/**
621 * megasas_fire_cmd_skinny - Sends command to the FW
622 * @frame_phys_addr : Physical address of cmd
623 * @frame_count : Number of frames for the command
624 * @regs : MFI register set
625 */
626static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600627megasas_fire_cmd_skinny(struct megasas_instance *instance,
628 dma_addr_t frame_phys_addr,
629 u32 frame_count,
Yang, Bo87911122009-10-06 14:31:54 -0600630 struct megasas_register_set __iomem *regs)
631{
Yang, Bo0c79e682009-10-06 14:47:35 -0600632 unsigned long flags;
bo yang39a98552010-09-22 22:36:29 -0400633 spin_lock_irqsave(&instance->hba_lock, flags);
Yang, Bo87911122009-10-06 14:31:54 -0600634 writel(0, &(regs)->inbound_high_queue_port);
635 writel((frame_phys_addr | (frame_count<<1))|1,
636 &(regs)->inbound_low_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400637 spin_unlock_irqrestore(&instance->hba_lock, flags);
638}
639
640/**
bo yang39a98552010-09-22 22:36:29 -0400641 * megasas_check_reset_skinny - For controller reset check
642 * @regs: MFI register set
643 */
644static int
645megasas_check_reset_skinny(struct megasas_instance *instance,
646 struct megasas_register_set __iomem *regs)
647{
adam radford3cc6851f92011-05-11 18:34:52 -0700648 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL)
649 return 1;
650
bo yang39a98552010-09-22 22:36:29 -0400651 return 0;
Yang, Bo87911122009-10-06 14:31:54 -0600652}
653
654static struct megasas_instance_template megasas_instance_template_skinny = {
655
656 .fire_cmd = megasas_fire_cmd_skinny,
657 .enable_intr = megasas_enable_intr_skinny,
658 .disable_intr = megasas_disable_intr_skinny,
659 .clear_intr = megasas_clear_intr_skinny,
660 .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
adam radfordebf054b2011-02-24 20:57:15 -0800661 .adp_reset = megasas_adp_reset_gen2,
bo yang39a98552010-09-22 22:36:29 -0400662 .check_reset = megasas_check_reset_skinny,
adam radfordcd50ba82010-12-21 10:23:23 -0800663 .service_isr = megasas_isr,
664 .tasklet = megasas_complete_cmd_dpc,
665 .init_adapter = megasas_init_adapter_mfi,
666 .build_and_issue_cmd = megasas_build_and_issue_cmd,
667 .issue_dcmd = megasas_issue_dcmd,
Yang, Bo87911122009-10-06 14:31:54 -0600668};
669
670
671/**
Yang, Bo6610a6b2008-08-10 12:42:38 -0700672* The following functions are defined for gen2 (deviceid : 0x78 0x79)
673* controllers
674*/
675
676/**
677 * megasas_enable_intr_gen2 - Enables interrupts
678 * @regs: MFI register set
679 */
680static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530681megasas_enable_intr_gen2(struct megasas_instance *instance)
Yang, Bo6610a6b2008-08-10 12:42:38 -0700682{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530683 struct megasas_register_set __iomem *regs;
684 regs = instance->reg_set;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700685 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
686
687 /* write ~0x00000005 (4 & 1) to the intr mask*/
688 writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
689
690 /* Dummy readl to force pci flush */
691 readl(&regs->outbound_intr_mask);
692}
693
694/**
695 * megasas_disable_intr_gen2 - Disables interrupt
696 * @regs: MFI register set
697 */
698static inline void
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530699megasas_disable_intr_gen2(struct megasas_instance *instance)
Yang, Bo6610a6b2008-08-10 12:42:38 -0700700{
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530701 struct megasas_register_set __iomem *regs;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700702 u32 mask = 0xFFFFFFFF;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +0530703 regs = instance->reg_set;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700704 writel(mask, &regs->outbound_intr_mask);
705 /* Dummy readl to force pci flush */
706 readl(&regs->outbound_intr_mask);
707}
708
709/**
710 * megasas_read_fw_status_reg_gen2 - returns the current FW status value
711 * @regs: MFI register set
712 */
713static u32
714megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs)
715{
716 return readl(&(regs)->outbound_scratch_pad);
717}
718
719/**
720 * megasas_clear_interrupt_gen2 - Check & clear interrupt
721 * @regs: MFI register set
722 */
723static int
724megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
725{
726 u32 status;
bo yang39a98552010-09-22 22:36:29 -0400727 u32 mfiStatus = 0;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700728 /*
729 * Check if it is our interrupt
730 */
731 status = readl(&regs->outbound_intr_status);
732
Sumit.Saxena@lsi.comb5bccad2013-05-22 12:29:54 +0530733 if (status & MFI_INTR_FLAG_REPLY_MESSAGE) {
bo yang39a98552010-09-22 22:36:29 -0400734 mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
735 }
736 if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) {
737 mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
738 }
Yang, Bo6610a6b2008-08-10 12:42:38 -0700739
740 /*
741 * Clear the interrupt by writing back the same value
742 */
bo yang39a98552010-09-22 22:36:29 -0400743 if (mfiStatus)
744 writel(status, &regs->outbound_doorbell_clear);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700745
746 /* Dummy readl to force pci flush */
747 readl(&regs->outbound_intr_status);
748
bo yang39a98552010-09-22 22:36:29 -0400749 return mfiStatus;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700750}
751/**
752 * megasas_fire_cmd_gen2 - Sends command to the FW
753 * @frame_phys_addr : Physical address of cmd
754 * @frame_count : Number of frames for the command
755 * @regs : MFI register set
756 */
757static inline void
Yang, Bo0c79e682009-10-06 14:47:35 -0600758megasas_fire_cmd_gen2(struct megasas_instance *instance,
759 dma_addr_t frame_phys_addr,
760 u32 frame_count,
Yang, Bo6610a6b2008-08-10 12:42:38 -0700761 struct megasas_register_set __iomem *regs)
762{
bo yang39a98552010-09-22 22:36:29 -0400763 unsigned long flags;
764 spin_lock_irqsave(&instance->hba_lock, flags);
Yang, Bo6610a6b2008-08-10 12:42:38 -0700765 writel((frame_phys_addr | (frame_count<<1))|1,
766 &(regs)->inbound_queue_port);
bo yang39a98552010-09-22 22:36:29 -0400767 spin_unlock_irqrestore(&instance->hba_lock, flags);
768}
769
770/**
771 * megasas_adp_reset_gen2 - For controller reset
772 * @regs: MFI register set
773 */
774static int
775megasas_adp_reset_gen2(struct megasas_instance *instance,
776 struct megasas_register_set __iomem *reg_set)
777{
778 u32 retry = 0 ;
779 u32 HostDiag;
adam radfordebf054b2011-02-24 20:57:15 -0800780 u32 *seq_offset = &reg_set->seq_offset;
781 u32 *hostdiag_offset = &reg_set->host_diag;
bo yang39a98552010-09-22 22:36:29 -0400782
adam radfordebf054b2011-02-24 20:57:15 -0800783 if (instance->instancet == &megasas_instance_template_skinny) {
784 seq_offset = &reg_set->fusion_seq_offset;
785 hostdiag_offset = &reg_set->fusion_host_diag;
786 }
787
788 writel(0, seq_offset);
789 writel(4, seq_offset);
790 writel(0xb, seq_offset);
791 writel(2, seq_offset);
792 writel(7, seq_offset);
793 writel(0xd, seq_offset);
794
bo yang39a98552010-09-22 22:36:29 -0400795 msleep(1000);
796
adam radfordebf054b2011-02-24 20:57:15 -0800797 HostDiag = (u32)readl(hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400798
799 while ( !( HostDiag & DIAG_WRITE_ENABLE) ) {
800 msleep(100);
adam radfordebf054b2011-02-24 20:57:15 -0800801 HostDiag = (u32)readl(hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400802 printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n",
803 retry, HostDiag);
804
805 if (retry++ >= 100)
806 return 1;
807
808 }
809
810 printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag);
811
adam radfordebf054b2011-02-24 20:57:15 -0800812 writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400813
814 ssleep(10);
815
adam radfordebf054b2011-02-24 20:57:15 -0800816 HostDiag = (u32)readl(hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400817 while ( ( HostDiag & DIAG_RESET_ADAPTER) ) {
818 msleep(100);
adam radfordebf054b2011-02-24 20:57:15 -0800819 HostDiag = (u32)readl(hostdiag_offset);
bo yang39a98552010-09-22 22:36:29 -0400820 printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n",
821 retry, HostDiag);
822
823 if (retry++ >= 1000)
824 return 1;
825
826 }
827 return 0;
828}
829
830/**
831 * megasas_check_reset_gen2 - For controller reset check
832 * @regs: MFI register set
833 */
834static int
835megasas_check_reset_gen2(struct megasas_instance *instance,
836 struct megasas_register_set __iomem *regs)
837{
Yang, Bo707e09b2010-10-12 07:20:27 -0600838 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
839 return 1;
840 }
841
bo yang39a98552010-09-22 22:36:29 -0400842 return 0;
Yang, Bo6610a6b2008-08-10 12:42:38 -0700843}
844
845static struct megasas_instance_template megasas_instance_template_gen2 = {
846
847 .fire_cmd = megasas_fire_cmd_gen2,
848 .enable_intr = megasas_enable_intr_gen2,
849 .disable_intr = megasas_disable_intr_gen2,
850 .clear_intr = megasas_clear_intr_gen2,
851 .read_fw_status_reg = megasas_read_fw_status_reg_gen2,
bo yang39a98552010-09-22 22:36:29 -0400852 .adp_reset = megasas_adp_reset_gen2,
853 .check_reset = megasas_check_reset_gen2,
adam radfordcd50ba82010-12-21 10:23:23 -0800854 .service_isr = megasas_isr,
855 .tasklet = megasas_complete_cmd_dpc,
856 .init_adapter = megasas_init_adapter_mfi,
857 .build_and_issue_cmd = megasas_build_and_issue_cmd,
858 .issue_dcmd = megasas_issue_dcmd,
Yang, Bo6610a6b2008-08-10 12:42:38 -0700859};
860
861/**
Sumant Patrof9876f02006-02-03 15:34:35 -0800862* This is the end of set of functions & definitions
bo yang39a98552010-09-22 22:36:29 -0400863* specific to gen2 (deviceid : 0x78, 0x79) controllers
Sumant Patrof9876f02006-02-03 15:34:35 -0800864*/
865
adam radford9c915a82010-12-21 13:34:31 -0800866/*
867 * Template added for TB (Fusion)
868 */
869extern struct megasas_instance_template megasas_instance_template_fusion;
870
Sumant Patrof9876f02006-02-03 15:34:35 -0800871/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400872 * megasas_issue_polled - Issues a polling command
873 * @instance: Adapter soft state
adam radford0d490162010-12-14 19:17:17 -0800874 * @cmd: Command packet to be issued
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400875 *
876 * For polling, MFI requires the cmd_status to be set to 0xFF before posting.
877 */
adam radford9c915a82010-12-21 13:34:31 -0800878int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400879megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
880{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400881
882 struct megasas_header *frame_hdr = &cmd->frame->hdr;
883
884 frame_hdr->cmd_status = 0xFF;
885 frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
886
887 /*
888 * Issue the frame using inbound queue port
889 */
adam radford9c915a82010-12-21 13:34:31 -0800890 instance->instancet->issue_dcmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400891
892 /*
893 * Wait for cmd_status to change
894 */
adam radford9c915a82010-12-21 13:34:31 -0800895 return wait_and_poll(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400896}
897
898/**
899 * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds
900 * @instance: Adapter soft state
901 * @cmd: Command to be issued
902 *
903 * This function waits on an event for the command to be returned from ISR.
Sumant Patro2a3681e2006-10-03 13:19:21 -0700904 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400905 * Used to issue ioctl commands.
906 */
907static int
908megasas_issue_blocked_cmd(struct megasas_instance *instance,
909 struct megasas_cmd *cmd)
910{
911 cmd->cmd_status = ENODATA;
912
adam radford9c915a82010-12-21 13:34:31 -0800913 instance->instancet->issue_dcmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400914
bo yang39a98552010-09-22 22:36:29 -0400915 wait_event(instance->int_cmd_wait_q, cmd->cmd_status != ENODATA);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400916
917 return 0;
918}
919
920/**
921 * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd
922 * @instance: Adapter soft state
923 * @cmd_to_abort: Previously issued cmd to be aborted
924 *
Justin P. Mattock8e572ba2011-02-02 11:31:21 +0100925 * MFI firmware can abort previously issued AEN command (automatic event
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400926 * notification). The megasas_issue_blocked_abort_cmd() issues such abort
Sumant Patro2a3681e2006-10-03 13:19:21 -0700927 * cmd and waits for return status.
928 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400929 */
930static int
931megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
932 struct megasas_cmd *cmd_to_abort)
933{
934 struct megasas_cmd *cmd;
935 struct megasas_abort_frame *abort_fr;
936
937 cmd = megasas_get_cmd(instance);
938
939 if (!cmd)
940 return -1;
941
942 abort_fr = &cmd->frame->abort;
943
944 /*
945 * Prepare and issue the abort frame
946 */
947 abort_fr->cmd = MFI_CMD_ABORT;
948 abort_fr->cmd_status = 0xFF;
949 abort_fr->flags = 0;
950 abort_fr->abort_context = cmd_to_abort->index;
951 abort_fr->abort_mfi_phys_addr_lo = cmd_to_abort->frame_phys_addr;
952 abort_fr->abort_mfi_phys_addr_hi = 0;
953
954 cmd->sync_cmd = 1;
955 cmd->cmd_status = 0xFF;
956
adam radford9c915a82010-12-21 13:34:31 -0800957 instance->instancet->issue_dcmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400958
959 /*
960 * Wait for this cmd to complete
961 */
bo yang39a98552010-09-22 22:36:29 -0400962 wait_event(instance->abort_cmd_wait_q, cmd->cmd_status != 0xFF);
963 cmd->sync_cmd = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400964
965 megasas_return_cmd(instance, cmd);
966 return 0;
967}
968
969/**
970 * megasas_make_sgl32 - Prepares 32-bit SGL
971 * @instance: Adapter soft state
972 * @scp: SCSI command from the mid-layer
973 * @mfi_sgl: SGL to be filled in
974 *
975 * If successful, this function returns the number of SG elements. Otherwise,
976 * it returnes -1.
977 */
Arjan van de Ven858119e2006-01-14 13:20:43 -0800978static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400979megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp,
980 union megasas_sgl *mfi_sgl)
981{
982 int i;
983 int sge_count;
984 struct scatterlist *os_sgl;
985
FUJITA Tomonori155d98f2007-05-26 05:04:08 +0900986 sge_count = scsi_dma_map(scp);
987 BUG_ON(sge_count < 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400988
FUJITA Tomonori155d98f2007-05-26 05:04:08 +0900989 if (sge_count) {
990 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
991 mfi_sgl->sge32[i].length = sg_dma_len(os_sgl);
992 mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl);
993 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400994 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -0400995 return sge_count;
996}
997
998/**
999 * megasas_make_sgl64 - Prepares 64-bit SGL
1000 * @instance: Adapter soft state
1001 * @scp: SCSI command from the mid-layer
1002 * @mfi_sgl: SGL to be filled in
1003 *
1004 * If successful, this function returns the number of SG elements. Otherwise,
1005 * it returnes -1.
1006 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001007static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001008megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
1009 union megasas_sgl *mfi_sgl)
1010{
1011 int i;
1012 int sge_count;
1013 struct scatterlist *os_sgl;
1014
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001015 sge_count = scsi_dma_map(scp);
1016 BUG_ON(sge_count < 0);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001017
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001018 if (sge_count) {
1019 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
1020 mfi_sgl->sge64[i].length = sg_dma_len(os_sgl);
1021 mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl);
1022 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001023 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001024 return sge_count;
1025}
1026
Yang, Bof4c9a132009-10-06 14:43:28 -06001027/**
1028 * megasas_make_sgl_skinny - Prepares IEEE SGL
1029 * @instance: Adapter soft state
1030 * @scp: SCSI command from the mid-layer
1031 * @mfi_sgl: SGL to be filled in
1032 *
1033 * If successful, this function returns the number of SG elements. Otherwise,
1034 * it returnes -1.
1035 */
1036static int
1037megasas_make_sgl_skinny(struct megasas_instance *instance,
1038 struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
1039{
1040 int i;
1041 int sge_count;
1042 struct scatterlist *os_sgl;
1043
1044 sge_count = scsi_dma_map(scp);
1045
1046 if (sge_count) {
1047 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
1048 mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
1049 mfi_sgl->sge_skinny[i].phys_addr =
1050 sg_dma_address(os_sgl);
Yang, Bo707e09b2010-10-12 07:20:27 -06001051 mfi_sgl->sge_skinny[i].flag = 0;
Yang, Bof4c9a132009-10-06 14:43:28 -06001052 }
1053 }
1054 return sge_count;
1055}
1056
Sumant Patrob1df99d2006-10-03 12:40:47 -07001057 /**
1058 * megasas_get_frame_count - Computes the number of frames
bo yangd532dbe2008-03-17 03:36:43 -04001059 * @frame_type : type of frame- io or pthru frame
Sumant Patrob1df99d2006-10-03 12:40:47 -07001060 * @sge_count : number of sg elements
1061 *
1062 * Returns the number of frames required for numnber of sge's (sge_count)
1063 */
1064
Yang, Bof4c9a132009-10-06 14:43:28 -06001065static u32 megasas_get_frame_count(struct megasas_instance *instance,
1066 u8 sge_count, u8 frame_type)
Sumant Patrob1df99d2006-10-03 12:40:47 -07001067{
1068 int num_cnt;
1069 int sge_bytes;
1070 u32 sge_sz;
1071 u32 frame_count=0;
1072
1073 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
1074 sizeof(struct megasas_sge32);
1075
Yang, Bof4c9a132009-10-06 14:43:28 -06001076 if (instance->flag_ieee) {
1077 sge_sz = sizeof(struct megasas_sge_skinny);
1078 }
1079
Sumant Patrob1df99d2006-10-03 12:40:47 -07001080 /*
bo yangd532dbe2008-03-17 03:36:43 -04001081 * Main frame can contain 2 SGEs for 64-bit SGLs and
1082 * 3 SGEs for 32-bit SGLs for ldio &
1083 * 1 SGEs for 64-bit SGLs and
1084 * 2 SGEs for 32-bit SGLs for pthru frame
1085 */
1086 if (unlikely(frame_type == PTHRU_FRAME)) {
Yang, Bof4c9a132009-10-06 14:43:28 -06001087 if (instance->flag_ieee == 1) {
1088 num_cnt = sge_count - 1;
1089 } else if (IS_DMA64)
bo yangd532dbe2008-03-17 03:36:43 -04001090 num_cnt = sge_count - 1;
1091 else
1092 num_cnt = sge_count - 2;
1093 } else {
Yang, Bof4c9a132009-10-06 14:43:28 -06001094 if (instance->flag_ieee == 1) {
1095 num_cnt = sge_count - 1;
1096 } else if (IS_DMA64)
bo yangd532dbe2008-03-17 03:36:43 -04001097 num_cnt = sge_count - 2;
1098 else
1099 num_cnt = sge_count - 3;
1100 }
Sumant Patrob1df99d2006-10-03 12:40:47 -07001101
1102 if(num_cnt>0){
1103 sge_bytes = sge_sz * num_cnt;
1104
1105 frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
1106 ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ;
1107 }
1108 /* Main frame */
1109 frame_count +=1;
1110
1111 if (frame_count > 7)
1112 frame_count = 8;
1113 return frame_count;
1114}
1115
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001116/**
1117 * megasas_build_dcdb - Prepares a direct cdb (DCDB) command
1118 * @instance: Adapter soft state
1119 * @scp: SCSI command
1120 * @cmd: Command to be prepared in
1121 *
1122 * This function prepares CDB commands. These are typcially pass-through
1123 * commands to the devices.
1124 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001125static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001126megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
1127 struct megasas_cmd *cmd)
1128{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001129 u32 is_logical;
1130 u32 device_id;
1131 u16 flags = 0;
1132 struct megasas_pthru_frame *pthru;
1133
1134 is_logical = MEGASAS_IS_LOGICAL(scp);
1135 device_id = MEGASAS_DEV_INDEX(instance, scp);
1136 pthru = (struct megasas_pthru_frame *)cmd->frame;
1137
1138 if (scp->sc_data_direction == PCI_DMA_TODEVICE)
1139 flags = MFI_FRAME_DIR_WRITE;
1140 else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
1141 flags = MFI_FRAME_DIR_READ;
1142 else if (scp->sc_data_direction == PCI_DMA_NONE)
1143 flags = MFI_FRAME_DIR_NONE;
1144
Yang, Bof4c9a132009-10-06 14:43:28 -06001145 if (instance->flag_ieee == 1) {
1146 flags |= MFI_FRAME_IEEE;
1147 }
1148
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001149 /*
1150 * Prepare the DCDB frame
1151 */
1152 pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO;
1153 pthru->cmd_status = 0x0;
1154 pthru->scsi_status = 0x0;
1155 pthru->target_id = device_id;
1156 pthru->lun = scp->device->lun;
1157 pthru->cdb_len = scp->cmd_len;
1158 pthru->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07001159 pthru->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001160 pthru->flags = flags;
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09001161 pthru->data_xfer_len = scsi_bufflen(scp);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001162
1163 memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
1164
1165 /*
Yang, Bo8d568252009-10-06 14:12:21 -06001166 * If the command is for the tape device, set the
1167 * pthru timeout to the os layer timeout value.
1168 */
1169 if (scp->device->type == TYPE_TAPE) {
1170 if ((scp->request->timeout / HZ) > 0xFFFF)
1171 pthru->timeout = 0xFFFF;
1172 else
1173 pthru->timeout = scp->request->timeout / HZ;
1174 }
1175
1176 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001177 * Construct SGL
1178 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001179 if (instance->flag_ieee == 1) {
1180 pthru->flags |= MFI_FRAME_SGL64;
1181 pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
1182 &pthru->sgl);
1183 } else if (IS_DMA64) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001184 pthru->flags |= MFI_FRAME_SGL64;
1185 pthru->sge_count = megasas_make_sgl64(instance, scp,
1186 &pthru->sgl);
1187 } else
1188 pthru->sge_count = megasas_make_sgl32(instance, scp,
1189 &pthru->sgl);
1190
Yang, Bobdc6fb82009-12-06 08:30:19 -07001191 if (pthru->sge_count > instance->max_num_sge) {
1192 printk(KERN_ERR "megasas: DCDB two many SGE NUM=%x\n",
1193 pthru->sge_count);
1194 return 0;
1195 }
1196
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001197 /*
1198 * Sense info specific
1199 */
1200 pthru->sense_len = SCSI_SENSE_BUFFERSIZE;
1201 pthru->sense_buf_phys_addr_hi = 0;
1202 pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
1203
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001204 /*
1205 * Compute the total number of frames this command consumes. FW uses
1206 * this number to pull sufficient number of frames from host memory.
1207 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001208 cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
bo yangd532dbe2008-03-17 03:36:43 -04001209 PTHRU_FRAME);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001210
1211 return cmd->frame_count;
1212}
1213
1214/**
1215 * megasas_build_ldio - Prepares IOs to logical devices
1216 * @instance: Adapter soft state
1217 * @scp: SCSI command
Anand Gadiyarfd589a82009-07-16 17:13:03 +02001218 * @cmd: Command to be prepared
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001219 *
1220 * Frames (and accompanying SGLs) for regular SCSI IOs use this function.
1221 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001222static int
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001223megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
1224 struct megasas_cmd *cmd)
1225{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001226 u32 device_id;
1227 u8 sc = scp->cmnd[0];
1228 u16 flags = 0;
1229 struct megasas_io_frame *ldio;
1230
1231 device_id = MEGASAS_DEV_INDEX(instance, scp);
1232 ldio = (struct megasas_io_frame *)cmd->frame;
1233
1234 if (scp->sc_data_direction == PCI_DMA_TODEVICE)
1235 flags = MFI_FRAME_DIR_WRITE;
1236 else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
1237 flags = MFI_FRAME_DIR_READ;
1238
Yang, Bof4c9a132009-10-06 14:43:28 -06001239 if (instance->flag_ieee == 1) {
1240 flags |= MFI_FRAME_IEEE;
1241 }
1242
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001243 /*
Sumant Patrob1df99d2006-10-03 12:40:47 -07001244 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001245 */
1246 ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ;
1247 ldio->cmd_status = 0x0;
1248 ldio->scsi_status = 0x0;
1249 ldio->target_id = device_id;
1250 ldio->timeout = 0;
1251 ldio->reserved_0 = 0;
1252 ldio->pad_0 = 0;
1253 ldio->flags = flags;
1254 ldio->start_lba_hi = 0;
1255 ldio->access_byte = (scp->cmd_len != 6) ? scp->cmnd[1] : 0;
1256
1257 /*
1258 * 6-byte READ(0x08) or WRITE(0x0A) cdb
1259 */
1260 if (scp->cmd_len == 6) {
1261 ldio->lba_count = (u32) scp->cmnd[4];
1262 ldio->start_lba_lo = ((u32) scp->cmnd[1] << 16) |
1263 ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3];
1264
1265 ldio->start_lba_lo &= 0x1FFFFF;
1266 }
1267
1268 /*
1269 * 10-byte READ(0x28) or WRITE(0x2A) cdb
1270 */
1271 else if (scp->cmd_len == 10) {
1272 ldio->lba_count = (u32) scp->cmnd[8] |
1273 ((u32) scp->cmnd[7] << 8);
1274 ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) |
1275 ((u32) scp->cmnd[3] << 16) |
1276 ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
1277 }
1278
1279 /*
1280 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
1281 */
1282 else if (scp->cmd_len == 12) {
1283 ldio->lba_count = ((u32) scp->cmnd[6] << 24) |
1284 ((u32) scp->cmnd[7] << 16) |
1285 ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
1286
1287 ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) |
1288 ((u32) scp->cmnd[3] << 16) |
1289 ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
1290 }
1291
1292 /*
1293 * 16-byte READ(0x88) or WRITE(0x8A) cdb
1294 */
1295 else if (scp->cmd_len == 16) {
1296 ldio->lba_count = ((u32) scp->cmnd[10] << 24) |
1297 ((u32) scp->cmnd[11] << 16) |
1298 ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13];
1299
1300 ldio->start_lba_lo = ((u32) scp->cmnd[6] << 24) |
1301 ((u32) scp->cmnd[7] << 16) |
1302 ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
1303
1304 ldio->start_lba_hi = ((u32) scp->cmnd[2] << 24) |
1305 ((u32) scp->cmnd[3] << 16) |
1306 ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
1307
1308 }
1309
1310 /*
1311 * Construct SGL
1312 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001313 if (instance->flag_ieee) {
1314 ldio->flags |= MFI_FRAME_SGL64;
1315 ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
1316 &ldio->sgl);
1317 } else if (IS_DMA64) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001318 ldio->flags |= MFI_FRAME_SGL64;
1319 ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
1320 } else
1321 ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
1322
Yang, Bobdc6fb82009-12-06 08:30:19 -07001323 if (ldio->sge_count > instance->max_num_sge) {
1324 printk(KERN_ERR "megasas: build_ld_io: sge_count = %x\n",
1325 ldio->sge_count);
1326 return 0;
1327 }
1328
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001329 /*
1330 * Sense info specific
1331 */
1332 ldio->sense_len = SCSI_SENSE_BUFFERSIZE;
1333 ldio->sense_buf_phys_addr_hi = 0;
1334 ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
1335
Sumant Patrob1df99d2006-10-03 12:40:47 -07001336 /*
1337 * Compute the total number of frames this command consumes. FW uses
1338 * this number to pull sufficient number of frames from host memory.
1339 */
Yang, Bof4c9a132009-10-06 14:43:28 -06001340 cmd->frame_count = megasas_get_frame_count(instance,
1341 ldio->sge_count, IO_FRAME);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001342
1343 return cmd->frame_count;
1344}
1345
1346/**
Sumant Patrocb59aa62006-01-25 11:53:25 -08001347 * megasas_is_ldio - Checks if the cmd is for logical drive
1348 * @scmd: SCSI command
adam radford0d490162010-12-14 19:17:17 -08001349 *
Sumant Patrocb59aa62006-01-25 11:53:25 -08001350 * Called by megasas_queue_command to find out if the command to be queued
adam radford0d490162010-12-14 19:17:17 -08001351 * is a logical drive command
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001352 */
adam radford9c915a82010-12-21 13:34:31 -08001353inline int megasas_is_ldio(struct scsi_cmnd *cmd)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001354{
Sumant Patrocb59aa62006-01-25 11:53:25 -08001355 if (!MEGASAS_IS_LOGICAL(cmd))
1356 return 0;
1357 switch (cmd->cmnd[0]) {
1358 case READ_10:
1359 case WRITE_10:
1360 case READ_12:
1361 case WRITE_12:
1362 case READ_6:
1363 case WRITE_6:
1364 case READ_16:
1365 case WRITE_16:
1366 return 1;
1367 default:
1368 return 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001369 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001370}
1371
Sumant Patro658dced2006-10-03 13:09:14 -07001372 /**
1373 * megasas_dump_pending_frames - Dumps the frame address of all pending cmds
1374 * in FW
1375 * @instance: Adapter soft state
1376 */
1377static inline void
1378megasas_dump_pending_frames(struct megasas_instance *instance)
1379{
1380 struct megasas_cmd *cmd;
1381 int i,n;
1382 union megasas_sgl *mfi_sgl;
1383 struct megasas_io_frame *ldio;
1384 struct megasas_pthru_frame *pthru;
1385 u32 sgcount;
1386 u32 max_cmd = instance->max_fw_cmds;
1387
1388 printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
1389 printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding));
1390 if (IS_DMA64)
1391 printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no);
1392 else
1393 printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);
1394
1395 printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
1396 for (i = 0; i < max_cmd; i++) {
1397 cmd = instance->cmd_list[i];
1398 if(!cmd->scmd)
1399 continue;
1400 printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
1401 if (megasas_is_ldio(cmd->scmd)){
1402 ldio = (struct megasas_io_frame *)cmd->frame;
1403 mfi_sgl = &ldio->sgl;
1404 sgcount = ldio->sge_count;
1405 printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no, cmd->frame_count,ldio->cmd,ldio->target_id, ldio->start_lba_lo,ldio->start_lba_hi,ldio->sense_buf_phys_addr_lo,sgcount);
1406 }
1407 else {
1408 pthru = (struct megasas_pthru_frame *) cmd->frame;
1409 mfi_sgl = &pthru->sgl;
1410 sgcount = pthru->sge_count;
1411 printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no,cmd->frame_count,pthru->cmd,pthru->target_id,pthru->lun,pthru->cdb_len , pthru->data_xfer_len,pthru->sense_buf_phys_addr_lo,sgcount);
1412 }
1413 if(megasas_dbg_lvl & MEGASAS_DBG_LVL){
1414 for (n = 0; n < sgcount; n++){
1415 if (IS_DMA64)
1416 printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%08lx ",mfi_sgl->sge64[n].length , (unsigned long)mfi_sgl->sge64[n].phys_addr) ;
1417 else
1418 printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",mfi_sgl->sge32[n].length , mfi_sgl->sge32[n].phys_addr) ;
1419 }
1420 }
1421 printk(KERN_ERR "\n");
1422 } /*for max_cmd*/
1423 printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
1424 for (i = 0; i < max_cmd; i++) {
1425
1426 cmd = instance->cmd_list[i];
1427
1428 if(cmd->sync_cmd == 1){
1429 printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
1430 }
1431 }
1432 printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
1433}
1434
adam radfordcd50ba82010-12-21 10:23:23 -08001435u32
1436megasas_build_and_issue_cmd(struct megasas_instance *instance,
1437 struct scsi_cmnd *scmd)
1438{
1439 struct megasas_cmd *cmd;
1440 u32 frame_count;
1441
1442 cmd = megasas_get_cmd(instance);
1443 if (!cmd)
1444 return SCSI_MLQUEUE_HOST_BUSY;
1445
1446 /*
1447 * Logical drive command
1448 */
1449 if (megasas_is_ldio(scmd))
1450 frame_count = megasas_build_ldio(instance, scmd, cmd);
1451 else
1452 frame_count = megasas_build_dcdb(instance, scmd, cmd);
1453
1454 if (!frame_count)
1455 goto out_return_cmd;
1456
1457 cmd->scmd = scmd;
1458 scmd->SCp.ptr = (char *)cmd;
1459
1460 /*
1461 * Issue the command to the FW
1462 */
1463 atomic_inc(&instance->fw_outstanding);
1464
1465 instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
1466 cmd->frame_count-1, instance->reg_set);
adam radfordcd50ba82010-12-21 10:23:23 -08001467
1468 return 0;
1469out_return_cmd:
1470 megasas_return_cmd(instance, cmd);
1471 return 1;
1472}
1473
1474
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001475/**
1476 * megasas_queue_command - Queue entry point
1477 * @scmd: SCSI command to be queued
1478 * @done: Callback entry point
1479 */
1480static int
Jeff Garzikf2812332010-11-16 02:10:29 -05001481megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001482{
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001483 struct megasas_instance *instance;
bo yang39a98552010-09-22 22:36:29 -04001484 unsigned long flags;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001485
1486 instance = (struct megasas_instance *)
1487 scmd->device->host->hostdata;
Sumant Patroaf37acf2007-02-14 12:34:46 -08001488
bo yang39a98552010-09-22 22:36:29 -04001489 if (instance->issuepend_done == 0)
Sumant Patroaf37acf2007-02-14 12:34:46 -08001490 return SCSI_MLQUEUE_HOST_BUSY;
1491
bo yang39a98552010-09-22 22:36:29 -04001492 spin_lock_irqsave(&instance->hba_lock, flags);
Sumit.Saxena@lsi.comb09e66d2013-05-22 12:29:28 +05301493
1494 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
1495 spin_unlock_irqrestore(&instance->hba_lock, flags);
1496 scmd->result = DID_ERROR << 16;
1497 done(scmd);
1498 return 0;
1499 }
1500
bo yang39a98552010-09-22 22:36:29 -04001501 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
1502 spin_unlock_irqrestore(&instance->hba_lock, flags);
1503 return SCSI_MLQUEUE_HOST_BUSY;
1504 }
1505
1506 spin_unlock_irqrestore(&instance->hba_lock, flags);
1507
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001508 scmd->scsi_done = done;
1509 scmd->result = 0;
1510
Sumant Patrocb59aa62006-01-25 11:53:25 -08001511 if (MEGASAS_IS_LOGICAL(scmd) &&
1512 (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) {
1513 scmd->result = DID_BAD_TARGET << 16;
1514 goto out_done;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001515 }
1516
Sumant Patro02b01e02007-02-14 13:00:55 -08001517 switch (scmd->cmnd[0]) {
1518 case SYNCHRONIZE_CACHE:
1519 /*
1520 * FW takes care of flush cache on its own
1521 * No need to send it down
1522 */
1523 scmd->result = DID_OK << 16;
1524 goto out_done;
1525 default:
1526 break;
1527 }
1528
adam radfordcd50ba82010-12-21 10:23:23 -08001529 if (instance->instancet->build_and_issue_cmd(instance, scmd)) {
1530 printk(KERN_ERR "megasas: Err returned from build_and_issue_cmd\n");
Sumant Patrocb59aa62006-01-25 11:53:25 -08001531 return SCSI_MLQUEUE_HOST_BUSY;
adam radfordcd50ba82010-12-21 10:23:23 -08001532 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001533
1534 return 0;
Sumant Patrocb59aa62006-01-25 11:53:25 -08001535
Sumant Patrocb59aa62006-01-25 11:53:25 -08001536 out_done:
1537 done(scmd);
1538 return 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001539}
1540
Jeff Garzikf2812332010-11-16 02:10:29 -05001541static DEF_SCSI_QCMD(megasas_queue_command)
1542
Yang, Bo044833b2009-10-06 14:33:06 -06001543static struct megasas_instance *megasas_lookup_instance(u16 host_no)
1544{
1545 int i;
1546
1547 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
1548
1549 if ((megasas_mgmt_info.instance[i]) &&
1550 (megasas_mgmt_info.instance[i]->host->host_no == host_no))
1551 return megasas_mgmt_info.instance[i];
1552 }
1553
1554 return NULL;
1555}
1556
Christoph Hellwig147aab62006-02-17 12:13:48 +01001557static int megasas_slave_configure(struct scsi_device *sdev)
1558{
Yang, Bo044833b2009-10-06 14:33:06 -06001559 u16 pd_index = 0;
1560 struct megasas_instance *instance ;
1561
1562 instance = megasas_lookup_instance(sdev->host->host_no);
Christoph Hellwige5b3a652006-03-10 17:08:57 +01001563
1564 /*
Yang, Bo044833b2009-10-06 14:33:06 -06001565 * Don't export physical disk devices to the disk driver.
1566 *
1567 * FIXME: Currently we don't export them to the midlayer at all.
1568 * That will be fixed once LSI engineers have audited the
1569 * firmware for possible issues.
1570 */
1571 if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
1572 sdev->type == TYPE_DISK) {
1573 pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
1574 sdev->id;
1575 if (instance->pd_list[pd_index].driveState ==
1576 MR_PD_STATE_SYSTEM) {
1577 blk_queue_rq_timeout(sdev->request_queue,
1578 MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1579 return 0;
1580 }
1581 return -ENXIO;
1582 }
1583
1584 /*
1585 * The RAID firmware may require extended timeouts.
1586 */
1587 blk_queue_rq_timeout(sdev->request_queue,
1588 MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1589 return 0;
1590}
1591
1592static int megasas_slave_alloc(struct scsi_device *sdev)
1593{
1594 u16 pd_index = 0;
1595 struct megasas_instance *instance ;
1596 instance = megasas_lookup_instance(sdev->host->host_no);
1597 if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
1598 (sdev->type == TYPE_DISK)) {
1599 /*
1600 * Open the OS scan to the SYSTEM PD
1601 */
1602 pd_index =
1603 (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
1604 sdev->id;
1605 if ((instance->pd_list[pd_index].driveState ==
1606 MR_PD_STATE_SYSTEM) &&
1607 (instance->pd_list[pd_index].driveType ==
1608 TYPE_DISK)) {
1609 return 0;
1610 }
1611 return -ENXIO;
1612 }
Christoph Hellwig147aab62006-02-17 12:13:48 +01001613 return 0;
1614}
1615
adam radford9c915a82010-12-21 13:34:31 -08001616void megaraid_sas_kill_hba(struct megasas_instance *instance)
bo yang39a98552010-09-22 22:36:29 -04001617{
1618 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
adam radford9c915a82010-12-21 13:34:31 -08001619 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
adam radford36807e62011-10-08 18:15:06 -07001620 (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05301621 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
1622 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
adam radford9c915a82010-12-21 13:34:31 -08001623 writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
bo yang39a98552010-09-22 22:36:29 -04001624 } else {
adam radford9c915a82010-12-21 13:34:31 -08001625 writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell);
1626 }
1627}
1628
1629 /**
1630 * megasas_check_and_restore_queue_depth - Check if queue depth needs to be
1631 * restored to max value
1632 * @instance: Adapter soft state
1633 *
1634 */
1635void
1636megasas_check_and_restore_queue_depth(struct megasas_instance *instance)
1637{
1638 unsigned long flags;
1639 if (instance->flag & MEGASAS_FW_BUSY
adam radfordc5daa6a2012-07-17 18:20:03 -07001640 && time_after(jiffies, instance->last_time + 5 * HZ)
1641 && atomic_read(&instance->fw_outstanding) <
1642 instance->throttlequeuedepth + 1) {
adam radford9c915a82010-12-21 13:34:31 -08001643
1644 spin_lock_irqsave(instance->host->host_lock, flags);
1645 instance->flag &= ~MEGASAS_FW_BUSY;
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05301646 if (instance->is_imr) {
adam radford9c915a82010-12-21 13:34:31 -08001647 instance->host->can_queue =
1648 instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
1649 } else
1650 instance->host->can_queue =
1651 instance->max_fw_cmds - MEGASAS_INT_CMDS;
1652
1653 spin_unlock_irqrestore(instance->host->host_lock, flags);
bo yang39a98552010-09-22 22:36:29 -04001654 }
1655}
1656
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001657/**
bo yang7343eb62007-11-09 04:35:44 -05001658 * megasas_complete_cmd_dpc - Returns FW's controller structure
1659 * @instance_addr: Address of adapter soft state
1660 *
1661 * Tasklet to complete cmds
1662 */
1663static void megasas_complete_cmd_dpc(unsigned long instance_addr)
1664{
1665 u32 producer;
1666 u32 consumer;
1667 u32 context;
1668 struct megasas_cmd *cmd;
1669 struct megasas_instance *instance =
1670 (struct megasas_instance *)instance_addr;
1671 unsigned long flags;
1672
1673 /* If we have already declared adapter dead, donot complete cmds */
bo yang39a98552010-09-22 22:36:29 -04001674 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR )
bo yang7343eb62007-11-09 04:35:44 -05001675 return;
1676
1677 spin_lock_irqsave(&instance->completion_lock, flags);
1678
1679 producer = *instance->producer;
1680 consumer = *instance->consumer;
1681
1682 while (consumer != producer) {
1683 context = instance->reply_queue[consumer];
bo yang39a98552010-09-22 22:36:29 -04001684 if (context >= instance->max_fw_cmds) {
1685 printk(KERN_ERR "Unexpected context value %x\n",
1686 context);
1687 BUG();
1688 }
bo yang7343eb62007-11-09 04:35:44 -05001689
1690 cmd = instance->cmd_list[context];
1691
1692 megasas_complete_cmd(instance, cmd, DID_OK);
1693
1694 consumer++;
1695 if (consumer == (instance->max_fw_cmds + 1)) {
1696 consumer = 0;
1697 }
1698 }
1699
1700 *instance->consumer = producer;
1701
1702 spin_unlock_irqrestore(&instance->completion_lock, flags);
1703
1704 /*
1705 * Check if we can restore can_queue
1706 */
adam radford9c915a82010-12-21 13:34:31 -08001707 megasas_check_and_restore_queue_depth(instance);
bo yang7343eb62007-11-09 04:35:44 -05001708}
1709
Yang, Bo707e09b2010-10-12 07:20:27 -06001710static void
1711megasas_internal_reset_defer_cmds(struct megasas_instance *instance);
1712
1713static void
1714process_fw_state_change_wq(struct work_struct *work);
1715
1716void megasas_do_ocr(struct megasas_instance *instance)
1717{
1718 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
1719 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
1720 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
1721 *instance->consumer = MEGASAS_ADPRESET_INPROG_SIGN;
1722 }
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05301723 instance->instancet->disable_intr(instance);
Yang, Bo707e09b2010-10-12 07:20:27 -06001724 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
1725 instance->issuepend_done = 0;
1726
1727 atomic_set(&instance->fw_outstanding, 0);
1728 megasas_internal_reset_defer_cmds(instance);
1729 process_fw_state_change_wq(&instance->work_init);
1730}
1731
bo yang7343eb62007-11-09 04:35:44 -05001732/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001733 * megasas_wait_for_outstanding - Wait for all outstanding cmds
1734 * @instance: Adapter soft state
1735 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001736 * This function waits for up to MEGASAS_RESET_WAIT_TIME seconds for FW to
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001737 * complete all its outstanding commands. Returns error if one or more IOs
1738 * are pending after this time period. It also marks the controller dead.
1739 */
1740static int megasas_wait_for_outstanding(struct megasas_instance *instance)
1741{
1742 int i;
bo yang39a98552010-09-22 22:36:29 -04001743 u32 reset_index;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001744 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
bo yang39a98552010-09-22 22:36:29 -04001745 u8 adprecovery;
1746 unsigned long flags;
1747 struct list_head clist_local;
1748 struct megasas_cmd *reset_cmd;
Yang, Bo707e09b2010-10-12 07:20:27 -06001749 u32 fw_state;
1750 u8 kill_adapter_flag;
bo yang39a98552010-09-22 22:36:29 -04001751
1752 spin_lock_irqsave(&instance->hba_lock, flags);
1753 adprecovery = instance->adprecovery;
1754 spin_unlock_irqrestore(&instance->hba_lock, flags);
1755
1756 if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
1757
1758 INIT_LIST_HEAD(&clist_local);
1759 spin_lock_irqsave(&instance->hba_lock, flags);
1760 list_splice_init(&instance->internal_reset_pending_q,
1761 &clist_local);
1762 spin_unlock_irqrestore(&instance->hba_lock, flags);
1763
1764 printk(KERN_NOTICE "megasas: HBA reset wait ...\n");
1765 for (i = 0; i < wait_time; i++) {
1766 msleep(1000);
1767 spin_lock_irqsave(&instance->hba_lock, flags);
1768 adprecovery = instance->adprecovery;
1769 spin_unlock_irqrestore(&instance->hba_lock, flags);
1770 if (adprecovery == MEGASAS_HBA_OPERATIONAL)
1771 break;
1772 }
1773
1774 if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
1775 printk(KERN_NOTICE "megasas: reset: Stopping HBA.\n");
1776 spin_lock_irqsave(&instance->hba_lock, flags);
1777 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
1778 spin_unlock_irqrestore(&instance->hba_lock, flags);
1779 return FAILED;
1780 }
1781
1782 reset_index = 0;
1783 while (!list_empty(&clist_local)) {
1784 reset_cmd = list_entry((&clist_local)->next,
1785 struct megasas_cmd, list);
1786 list_del_init(&reset_cmd->list);
1787 if (reset_cmd->scmd) {
1788 reset_cmd->scmd->result = DID_RESET << 16;
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04001789 printk(KERN_NOTICE "%d:%p reset [%02x]\n",
bo yang39a98552010-09-22 22:36:29 -04001790 reset_index, reset_cmd,
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04001791 reset_cmd->scmd->cmnd[0]);
bo yang39a98552010-09-22 22:36:29 -04001792
1793 reset_cmd->scmd->scsi_done(reset_cmd->scmd);
1794 megasas_return_cmd(instance, reset_cmd);
1795 } else if (reset_cmd->sync_cmd) {
1796 printk(KERN_NOTICE "megasas:%p synch cmds"
1797 "reset queue\n",
1798 reset_cmd);
1799
1800 reset_cmd->cmd_status = ENODATA;
1801 instance->instancet->fire_cmd(instance,
1802 reset_cmd->frame_phys_addr,
1803 0, instance->reg_set);
1804 } else {
1805 printk(KERN_NOTICE "megasas: %p unexpected"
1806 "cmds lst\n",
1807 reset_cmd);
1808 }
1809 reset_index++;
1810 }
1811
1812 return SUCCESS;
1813 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001814
adam radfordc007b8b2012-07-17 18:20:24 -07001815 for (i = 0; i < resetwaittime; i++) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001816
Sumant Patroe4a082c2006-05-30 12:03:37 -07001817 int outstanding = atomic_read(&instance->fw_outstanding);
1818
1819 if (!outstanding)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001820 break;
1821
1822 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
1823 printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
Sumant Patroe4a082c2006-05-30 12:03:37 -07001824 "commands to complete\n",i,outstanding);
bo yang7343eb62007-11-09 04:35:44 -05001825 /*
1826 * Call cmd completion routine. Cmd to be
1827 * be completed directly without depending on isr.
1828 */
1829 megasas_complete_cmd_dpc((unsigned long)instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001830 }
1831
1832 msleep(1000);
1833 }
1834
Yang, Bo707e09b2010-10-12 07:20:27 -06001835 i = 0;
1836 kill_adapter_flag = 0;
1837 do {
1838 fw_state = instance->instancet->read_fw_status_reg(
1839 instance->reg_set) & MFI_STATE_MASK;
1840 if ((fw_state == MFI_STATE_FAULT) &&
1841 (instance->disableOnlineCtrlReset == 0)) {
1842 if (i == 3) {
1843 kill_adapter_flag = 2;
1844 break;
1845 }
1846 megasas_do_ocr(instance);
1847 kill_adapter_flag = 1;
1848
1849 /* wait for 1 secs to let FW finish the pending cmds */
1850 msleep(1000);
1851 }
1852 i++;
1853 } while (i <= 3);
1854
1855 if (atomic_read(&instance->fw_outstanding) &&
1856 !kill_adapter_flag) {
1857 if (instance->disableOnlineCtrlReset == 0) {
1858
1859 megasas_do_ocr(instance);
1860
1861 /* wait for 5 secs to let FW finish the pending cmds */
1862 for (i = 0; i < wait_time; i++) {
1863 int outstanding =
1864 atomic_read(&instance->fw_outstanding);
1865 if (!outstanding)
1866 return SUCCESS;
1867 msleep(1000);
1868 }
1869 }
1870 }
1871
1872 if (atomic_read(&instance->fw_outstanding) ||
1873 (kill_adapter_flag == 2)) {
bo yang39a98552010-09-22 22:36:29 -04001874 printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n");
Sumant Patroe3bbff92006-10-03 12:28:49 -07001875 /*
1876 * Send signal to FW to stop processing any pending cmds.
1877 * The controller will be taken offline by the OS now.
1878 */
Yang, Bo0c79e682009-10-06 14:47:35 -06001879 if ((instance->pdev->device ==
1880 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
1881 (instance->pdev->device ==
1882 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
1883 writel(MFI_STOP_ADP,
adam radford9c915a82010-12-21 13:34:31 -08001884 &instance->reg_set->doorbell);
Yang, Bo0c79e682009-10-06 14:47:35 -06001885 } else {
1886 writel(MFI_STOP_ADP,
Sumant Patroe3bbff92006-10-03 12:28:49 -07001887 &instance->reg_set->inbound_doorbell);
Yang, Bo0c79e682009-10-06 14:47:35 -06001888 }
Sumant Patro658dced2006-10-03 13:09:14 -07001889 megasas_dump_pending_frames(instance);
bo yang39a98552010-09-22 22:36:29 -04001890 spin_lock_irqsave(&instance->hba_lock, flags);
1891 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
1892 spin_unlock_irqrestore(&instance->hba_lock, flags);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001893 return FAILED;
1894 }
1895
bo yang39a98552010-09-22 22:36:29 -04001896 printk(KERN_NOTICE "megaraid_sas: no pending cmds after reset\n");
1897
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001898 return SUCCESS;
1899}
1900
1901/**
1902 * megasas_generic_reset - Generic reset routine
1903 * @scmd: Mid-layer SCSI command
1904 *
1905 * This routine implements a generic reset handler for device, bus and host
1906 * reset requests. Device, bus and host specific reset handlers can use this
1907 * function after they do their specific tasks.
1908 */
1909static int megasas_generic_reset(struct scsi_cmnd *scmd)
1910{
1911 int ret_val;
1912 struct megasas_instance *instance;
1913
1914 instance = (struct megasas_instance *)scmd->device->host->hostdata;
1915
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04001916 scmd_printk(KERN_NOTICE, scmd, "megasas: RESET cmd=%x retries=%x\n",
1917 scmd->cmnd[0], scmd->retries);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001918
bo yang39a98552010-09-22 22:36:29 -04001919 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001920 printk(KERN_ERR "megasas: cannot recover from previous reset "
1921 "failures\n");
1922 return FAILED;
1923 }
1924
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001925 ret_val = megasas_wait_for_outstanding(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001926 if (ret_val == SUCCESS)
1927 printk(KERN_NOTICE "megasas: reset successful \n");
1928 else
1929 printk(KERN_ERR "megasas: failed to do reset\n");
1930
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001931 return ret_val;
1932}
1933
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001934/**
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001935 * megasas_reset_timer - quiesce the adapter if required
1936 * @scmd: scsi cmnd
1937 *
1938 * Sets the FW busy flag and reduces the host->can_queue if the
1939 * cmd has not been completed within the timeout period.
1940 */
1941static enum
Jens Axboe242f9dc2008-09-14 05:55:09 -07001942blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001943{
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001944 struct megasas_instance *instance;
1945 unsigned long flags;
1946
1947 if (time_after(jiffies, scmd->jiffies_at_alloc +
1948 (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
Jens Axboe242f9dc2008-09-14 05:55:09 -07001949 return BLK_EH_NOT_HANDLED;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001950 }
1951
adam radfordf575c5d2011-10-13 16:01:12 -07001952 instance = (struct megasas_instance *)scmd->device->host->hostdata;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001953 if (!(instance->flag & MEGASAS_FW_BUSY)) {
1954 /* FW is busy, throttle IO */
1955 spin_lock_irqsave(instance->host->host_lock, flags);
1956
adam radfordc5daa6a2012-07-17 18:20:03 -07001957 instance->host->can_queue = instance->throttlequeuedepth;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001958 instance->last_time = jiffies;
1959 instance->flag |= MEGASAS_FW_BUSY;
1960
1961 spin_unlock_irqrestore(instance->host->host_lock, flags);
1962 }
Jens Axboe242f9dc2008-09-14 05:55:09 -07001963 return BLK_EH_RESET_TIMER;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07001964}
1965
1966/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001967 * megasas_reset_device - Device reset handler entry point
1968 */
1969static int megasas_reset_device(struct scsi_cmnd *scmd)
1970{
1971 int ret;
1972
1973 /*
1974 * First wait for all commands to complete
1975 */
1976 ret = megasas_generic_reset(scmd);
1977
1978 return ret;
1979}
1980
1981/**
1982 * megasas_reset_bus_host - Bus & host reset handler entry point
1983 */
1984static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
1985{
1986 int ret;
adam radford9c915a82010-12-21 13:34:31 -08001987 struct megasas_instance *instance;
1988 instance = (struct megasas_instance *)scmd->device->host->hostdata;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001989
1990 /*
Uwe Zeisberger80682fa2006-03-22 00:21:33 +01001991 * First wait for all commands to complete
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001992 */
adam radford36807e62011-10-08 18:15:06 -07001993 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05301994 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
1995 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
adam radford9c915a82010-12-21 13:34:31 -08001996 ret = megasas_reset_fusion(scmd->device->host);
1997 else
1998 ret = megasas_generic_reset(scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04001999
2000 return ret;
2001}
2002
2003/**
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002004 * megasas_bios_param - Returns disk geometry for a disk
2005 * @sdev: device handle
2006 * @bdev: block device
2007 * @capacity: drive capacity
2008 * @geom: geometry parameters
2009 */
2010static int
2011megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
2012 sector_t capacity, int geom[])
2013{
2014 int heads;
2015 int sectors;
2016 sector_t cylinders;
2017 unsigned long tmp;
2018 /* Default heads (64) & sectors (32) */
2019 heads = 64;
2020 sectors = 32;
2021
2022 tmp = heads * sectors;
2023 cylinders = capacity;
2024
2025 sector_div(cylinders, tmp);
2026
2027 /*
2028 * Handle extended translation size for logical drives > 1Gb
2029 */
2030
2031 if (capacity >= 0x200000) {
2032 heads = 255;
2033 sectors = 63;
2034 tmp = heads*sectors;
2035 cylinders = capacity;
2036 sector_div(cylinders, tmp);
2037 }
2038
2039 geom[0] = heads;
2040 geom[1] = sectors;
2041 geom[2] = cylinders;
2042
2043 return 0;
2044}
2045
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002046static void megasas_aen_polling(struct work_struct *work);
2047
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002048/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002049 * megasas_service_aen - Processes an event notification
2050 * @instance: Adapter soft state
2051 * @cmd: AEN command completed by the ISR
2052 *
2053 * For AEN, driver sends a command down to FW that is held by the FW till an
2054 * event occurs. When an event of interest occurs, FW completes the command
2055 * that it was previously holding.
2056 *
2057 * This routines sends SIGIO signal to processes that have registered with the
2058 * driver for AEN.
2059 */
2060static void
2061megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
2062{
Yang, Boc3518832009-10-06 14:18:02 -06002063 unsigned long flags;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002064 /*
2065 * Don't signal app if it is just an aborted previously registered aen
2066 */
Yang, Boc3518832009-10-06 14:18:02 -06002067 if ((!cmd->abort_aen) && (instance->unload == 0)) {
2068 spin_lock_irqsave(&poll_aen_lock, flags);
2069 megasas_poll_wait_aen = 1;
2070 spin_unlock_irqrestore(&poll_aen_lock, flags);
2071 wake_up(&megasas_poll_wait);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002072 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
Yang, Boc3518832009-10-06 14:18:02 -06002073 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002074 else
2075 cmd->abort_aen = 0;
2076
2077 instance->aen_cmd = NULL;
2078 megasas_return_cmd(instance, cmd);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002079
bo yang39a98552010-09-22 22:36:29 -04002080 if ((instance->unload == 0) &&
2081 ((instance->issuepend_done == 1))) {
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002082 struct megasas_aen_event *ev;
2083 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2084 if (!ev) {
2085 printk(KERN_ERR "megasas_service_aen: out of memory\n");
2086 } else {
2087 ev->instance = instance;
2088 instance->ev = ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08002089 INIT_DELAYED_WORK(&ev->hotplug_work,
2090 megasas_aen_polling);
2091 schedule_delayed_work(&ev->hotplug_work, 0);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002092 }
2093 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002094}
2095
adam radford4bcde502011-07-26 15:42:52 -07002096static int megasas_change_queue_depth(struct scsi_device *sdev,
2097 int queue_depth, int reason)
2098{
2099 if (reason != SCSI_QDEPTH_DEFAULT)
2100 return -EOPNOTSUPP;
2101
2102 if (queue_depth > sdev->host->can_queue)
2103 queue_depth = sdev->host->can_queue;
2104 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
2105 queue_depth);
2106
2107 return queue_depth;
2108}
2109
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002110/*
2111 * Scsi host template for megaraid_sas driver
2112 */
2113static struct scsi_host_template megasas_template = {
2114
2115 .module = THIS_MODULE,
bo yangf28cd7c2007-11-09 04:44:56 -05002116 .name = "LSI SAS based MegaRAID driver",
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002117 .proc_name = "megaraid_sas",
Christoph Hellwig147aab62006-02-17 12:13:48 +01002118 .slave_configure = megasas_slave_configure,
Yang, Bo044833b2009-10-06 14:33:06 -06002119 .slave_alloc = megasas_slave_alloc,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002120 .queuecommand = megasas_queue_command,
2121 .eh_device_reset_handler = megasas_reset_device,
2122 .eh_bus_reset_handler = megasas_reset_bus_host,
2123 .eh_host_reset_handler = megasas_reset_bus_host,
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002124 .eh_timed_out = megasas_reset_timer,
Sumant Patrocf62a0a2007-02-14 12:41:55 -08002125 .bios_param = megasas_bios_param,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002126 .use_clustering = ENABLE_CLUSTERING,
adam radford4bcde502011-07-26 15:42:52 -07002127 .change_queue_depth = megasas_change_queue_depth,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002128};
2129
2130/**
2131 * megasas_complete_int_cmd - Completes an internal command
2132 * @instance: Adapter soft state
2133 * @cmd: Command to be completed
2134 *
2135 * The megasas_issue_blocked_cmd() function waits for a command to complete
2136 * after it issues a command. This function wakes up that waiting routine by
2137 * calling wake_up() on the wait queue.
2138 */
2139static void
2140megasas_complete_int_cmd(struct megasas_instance *instance,
2141 struct megasas_cmd *cmd)
2142{
2143 cmd->cmd_status = cmd->frame->io.cmd_status;
2144
2145 if (cmd->cmd_status == ENODATA) {
2146 cmd->cmd_status = 0;
2147 }
2148 wake_up(&instance->int_cmd_wait_q);
2149}
2150
2151/**
2152 * megasas_complete_abort - Completes aborting a command
2153 * @instance: Adapter soft state
2154 * @cmd: Cmd that was issued to abort another cmd
2155 *
adam radford0d490162010-12-14 19:17:17 -08002156 * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
2157 * after it issues an abort on a previously issued command. This function
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002158 * wakes up all functions waiting on the same wait queue.
2159 */
2160static void
2161megasas_complete_abort(struct megasas_instance *instance,
2162 struct megasas_cmd *cmd)
2163{
2164 if (cmd->sync_cmd) {
2165 cmd->sync_cmd = 0;
2166 cmd->cmd_status = 0;
2167 wake_up(&instance->abort_cmd_wait_q);
2168 }
2169
2170 return;
2171}
2172
2173/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002174 * megasas_complete_cmd - Completes a command
2175 * @instance: Adapter soft state
2176 * @cmd: Command to be completed
adam radford0d490162010-12-14 19:17:17 -08002177 * @alt_status: If non-zero, use this value as status to
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002178 * SCSI mid-layer instead of the value returned
2179 * by the FW. This should be used if caller wants
2180 * an alternate status (as in the case of aborted
2181 * commands)
2182 */
adam radford9c915a82010-12-21 13:34:31 -08002183void
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002184megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
2185 u8 alt_status)
2186{
2187 int exception = 0;
2188 struct megasas_header *hdr = &cmd->frame->hdr;
Yang, Boc3518832009-10-06 14:18:02 -06002189 unsigned long flags;
adam radford9c915a82010-12-21 13:34:31 -08002190 struct fusion_context *fusion = instance->ctrl_context;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002191
bo yang39a98552010-09-22 22:36:29 -04002192 /* flag for the retry reset */
2193 cmd->retry_for_fw_reset = 0;
2194
Sumant Patro05e9ebb2007-05-17 05:47:51 -07002195 if (cmd->scmd)
2196 cmd->scmd->SCp.ptr = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002197
2198 switch (hdr->cmd) {
adam radforde5f93a32011-10-08 18:15:19 -07002199 case MFI_CMD_INVALID:
2200 /* Some older 1068 controller FW may keep a pended
2201 MR_DCMD_CTRL_EVENT_GET_INFO left over from the main kernel
2202 when booting the kdump kernel. Ignore this command to
2203 prevent a kernel panic on shutdown of the kdump kernel. */
2204 printk(KERN_WARNING "megaraid_sas: MFI_CMD_INVALID command "
2205 "completed.\n");
2206 printk(KERN_WARNING "megaraid_sas: If you have a controller "
2207 "other than PERC5, please upgrade your firmware.\n");
2208 break;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002209 case MFI_CMD_PD_SCSI_IO:
2210 case MFI_CMD_LD_SCSI_IO:
2211
2212 /*
2213 * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been
2214 * issued either through an IO path or an IOCTL path. If it
2215 * was via IOCTL, we will send it to internal completion.
2216 */
2217 if (cmd->sync_cmd) {
2218 cmd->sync_cmd = 0;
2219 megasas_complete_int_cmd(instance, cmd);
2220 break;
2221 }
2222
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002223 case MFI_CMD_LD_READ:
2224 case MFI_CMD_LD_WRITE:
2225
2226 if (alt_status) {
2227 cmd->scmd->result = alt_status << 16;
2228 exception = 1;
2229 }
2230
2231 if (exception) {
2232
Sumant Patroe4a082c2006-05-30 12:03:37 -07002233 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002234
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09002235 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002236 cmd->scmd->scsi_done(cmd->scmd);
2237 megasas_return_cmd(instance, cmd);
2238
2239 break;
2240 }
2241
2242 switch (hdr->cmd_status) {
2243
2244 case MFI_STAT_OK:
2245 cmd->scmd->result = DID_OK << 16;
2246 break;
2247
2248 case MFI_STAT_SCSI_IO_FAILED:
2249 case MFI_STAT_LD_INIT_IN_PROGRESS:
2250 cmd->scmd->result =
2251 (DID_ERROR << 16) | hdr->scsi_status;
2252 break;
2253
2254 case MFI_STAT_SCSI_DONE_WITH_ERROR:
2255
2256 cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status;
2257
2258 if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) {
2259 memset(cmd->scmd->sense_buffer, 0,
2260 SCSI_SENSE_BUFFERSIZE);
2261 memcpy(cmd->scmd->sense_buffer, cmd->sense,
2262 hdr->sense_len);
2263
2264 cmd->scmd->result |= DRIVER_SENSE << 24;
2265 }
2266
2267 break;
2268
2269 case MFI_STAT_LD_OFFLINE:
2270 case MFI_STAT_DEVICE_NOT_FOUND:
2271 cmd->scmd->result = DID_BAD_TARGET << 16;
2272 break;
2273
2274 default:
2275 printk(KERN_DEBUG "megasas: MFI FW status %#x\n",
2276 hdr->cmd_status);
2277 cmd->scmd->result = DID_ERROR << 16;
2278 break;
2279 }
2280
Sumant Patroe4a082c2006-05-30 12:03:37 -07002281 atomic_dec(&instance->fw_outstanding);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002282
FUJITA Tomonori155d98f2007-05-26 05:04:08 +09002283 scsi_dma_unmap(cmd->scmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002284 cmd->scmd->scsi_done(cmd->scmd);
2285 megasas_return_cmd(instance, cmd);
2286
2287 break;
2288
2289 case MFI_CMD_SMP:
2290 case MFI_CMD_STP:
2291 case MFI_CMD_DCMD:
adam radford9c915a82010-12-21 13:34:31 -08002292 /* Check for LD map update */
2293 if ((cmd->frame->dcmd.opcode == MR_DCMD_LD_MAP_GET_INFO) &&
2294 (cmd->frame->dcmd.mbox.b[1] == 1)) {
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05302295 fusion->fast_path_io = 0;
adam radford9c915a82010-12-21 13:34:31 -08002296 spin_lock_irqsave(instance->host->host_lock, flags);
2297 if (cmd->frame->hdr.cmd_status != 0) {
2298 if (cmd->frame->hdr.cmd_status !=
2299 MFI_STAT_NOT_FOUND)
2300 printk(KERN_WARNING "megasas: map sync"
2301 "failed, status = 0x%x.\n",
2302 cmd->frame->hdr.cmd_status);
2303 else {
2304 megasas_return_cmd(instance, cmd);
2305 spin_unlock_irqrestore(
2306 instance->host->host_lock,
2307 flags);
2308 break;
2309 }
2310 } else
2311 instance->map_id++;
2312 megasas_return_cmd(instance, cmd);
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05302313
2314 /*
2315 * Set fast path IO to ZERO.
2316 * Validate Map will set proper value.
2317 * Meanwhile all IOs will go as LD IO.
2318 */
2319 if (MR_ValidateMapInfo(instance))
adam radford9c915a82010-12-21 13:34:31 -08002320 fusion->fast_path_io = 1;
2321 else
2322 fusion->fast_path_io = 0;
2323 megasas_sync_map_info(instance);
2324 spin_unlock_irqrestore(instance->host->host_lock,
2325 flags);
2326 break;
2327 }
Yang, Boc3518832009-10-06 14:18:02 -06002328 if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
2329 cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
2330 spin_lock_irqsave(&poll_aen_lock, flags);
2331 megasas_poll_wait_aen = 0;
2332 spin_unlock_irqrestore(&poll_aen_lock, flags);
2333 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002334
2335 /*
2336 * See if got an event notification
2337 */
2338 if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_WAIT)
2339 megasas_service_aen(instance, cmd);
2340 else
2341 megasas_complete_int_cmd(instance, cmd);
2342
2343 break;
2344
2345 case MFI_CMD_ABORT:
2346 /*
2347 * Cmd issued to abort another cmd returned
2348 */
2349 megasas_complete_abort(instance, cmd);
2350 break;
2351
2352 default:
2353 printk("megasas: Unknown command completed! [0x%X]\n",
2354 hdr->cmd);
2355 break;
2356 }
2357}
2358
2359/**
bo yang39a98552010-09-22 22:36:29 -04002360 * megasas_issue_pending_cmds_again - issue all pending cmds
2361 * in FW again because of the fw reset
2362 * @instance: Adapter soft state
2363 */
2364static inline void
2365megasas_issue_pending_cmds_again(struct megasas_instance *instance)
2366{
2367 struct megasas_cmd *cmd;
2368 struct list_head clist_local;
2369 union megasas_evt_class_locale class_locale;
2370 unsigned long flags;
2371 u32 seq_num;
2372
2373 INIT_LIST_HEAD(&clist_local);
2374 spin_lock_irqsave(&instance->hba_lock, flags);
2375 list_splice_init(&instance->internal_reset_pending_q, &clist_local);
2376 spin_unlock_irqrestore(&instance->hba_lock, flags);
2377
2378 while (!list_empty(&clist_local)) {
2379 cmd = list_entry((&clist_local)->next,
2380 struct megasas_cmd, list);
2381 list_del_init(&cmd->list);
2382
2383 if (cmd->sync_cmd || cmd->scmd) {
2384 printk(KERN_NOTICE "megaraid_sas: command %p, %p:%d"
2385 "detected to be pending while HBA reset.\n",
2386 cmd, cmd->scmd, cmd->sync_cmd);
2387
2388 cmd->retry_for_fw_reset++;
2389
2390 if (cmd->retry_for_fw_reset == 3) {
2391 printk(KERN_NOTICE "megaraid_sas: cmd %p, %p:%d"
2392 "was tried multiple times during reset."
2393 "Shutting down the HBA\n",
2394 cmd, cmd->scmd, cmd->sync_cmd);
2395 megaraid_sas_kill_hba(instance);
2396
2397 instance->adprecovery =
2398 MEGASAS_HW_CRITICAL_ERROR;
2399 return;
2400 }
2401 }
2402
2403 if (cmd->sync_cmd == 1) {
2404 if (cmd->scmd) {
2405 printk(KERN_NOTICE "megaraid_sas: unexpected"
2406 "cmd attached to internal command!\n");
2407 }
2408 printk(KERN_NOTICE "megasas: %p synchronous cmd"
2409 "on the internal reset queue,"
2410 "issue it again.\n", cmd);
2411 cmd->cmd_status = ENODATA;
2412 instance->instancet->fire_cmd(instance,
2413 cmd->frame_phys_addr ,
2414 0, instance->reg_set);
2415 } else if (cmd->scmd) {
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002416 printk(KERN_NOTICE "megasas: %p scsi cmd [%02x]"
bo yang39a98552010-09-22 22:36:29 -04002417 "detected on the internal queue, issue again.\n",
Christoph Hellwig5cd049a2011-04-04 09:42:14 -04002418 cmd, cmd->scmd->cmnd[0]);
bo yang39a98552010-09-22 22:36:29 -04002419
2420 atomic_inc(&instance->fw_outstanding);
2421 instance->instancet->fire_cmd(instance,
2422 cmd->frame_phys_addr,
2423 cmd->frame_count-1, instance->reg_set);
2424 } else {
2425 printk(KERN_NOTICE "megasas: %p unexpected cmd on the"
2426 "internal reset defer list while re-issue!!\n",
2427 cmd);
2428 }
2429 }
2430
2431 if (instance->aen_cmd) {
2432 printk(KERN_NOTICE "megaraid_sas: aen_cmd in def process\n");
2433 megasas_return_cmd(instance, instance->aen_cmd);
2434
2435 instance->aen_cmd = NULL;
2436 }
2437
2438 /*
2439 * Initiate AEN (Asynchronous Event Notification)
2440 */
2441 seq_num = instance->last_seq_num;
2442 class_locale.members.reserved = 0;
2443 class_locale.members.locale = MR_EVT_LOCALE_ALL;
2444 class_locale.members.class = MR_EVT_CLASS_DEBUG;
2445
2446 megasas_register_aen(instance, seq_num, class_locale.word);
2447}
2448
2449/**
2450 * Move the internal reset pending commands to a deferred queue.
2451 *
2452 * We move the commands pending at internal reset time to a
2453 * pending queue. This queue would be flushed after successful
2454 * completion of the internal reset sequence. if the internal reset
2455 * did not complete in time, the kernel reset handler would flush
2456 * these commands.
2457 **/
2458static void
2459megasas_internal_reset_defer_cmds(struct megasas_instance *instance)
2460{
2461 struct megasas_cmd *cmd;
2462 int i;
2463 u32 max_cmd = instance->max_fw_cmds;
2464 u32 defer_index;
2465 unsigned long flags;
2466
2467 defer_index = 0;
2468 spin_lock_irqsave(&instance->cmd_pool_lock, flags);
2469 for (i = 0; i < max_cmd; i++) {
2470 cmd = instance->cmd_list[i];
2471 if (cmd->sync_cmd == 1 || cmd->scmd) {
2472 printk(KERN_NOTICE "megasas: moving cmd[%d]:%p:%d:%p"
2473 "on the defer queue as internal\n",
2474 defer_index, cmd, cmd->sync_cmd, cmd->scmd);
2475
2476 if (!list_empty(&cmd->list)) {
2477 printk(KERN_NOTICE "megaraid_sas: ERROR while"
2478 " moving this cmd:%p, %d %p, it was"
2479 "discovered on some list?\n",
2480 cmd, cmd->sync_cmd, cmd->scmd);
2481
2482 list_del_init(&cmd->list);
2483 }
2484 defer_index++;
2485 list_add_tail(&cmd->list,
2486 &instance->internal_reset_pending_q);
2487 }
2488 }
2489 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
2490}
2491
2492
2493static void
2494process_fw_state_change_wq(struct work_struct *work)
2495{
2496 struct megasas_instance *instance =
2497 container_of(work, struct megasas_instance, work_init);
2498 u32 wait;
2499 unsigned long flags;
2500
2501 if (instance->adprecovery != MEGASAS_ADPRESET_SM_INFAULT) {
2502 printk(KERN_NOTICE "megaraid_sas: error, recovery st %x \n",
2503 instance->adprecovery);
2504 return ;
2505 }
2506
2507 if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) {
2508 printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault"
2509 "state, restarting it...\n");
2510
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05302511 instance->instancet->disable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04002512 atomic_set(&instance->fw_outstanding, 0);
2513
2514 atomic_set(&instance->fw_reset_no_pci_access, 1);
2515 instance->instancet->adp_reset(instance, instance->reg_set);
2516 atomic_set(&instance->fw_reset_no_pci_access, 0 );
2517
2518 printk(KERN_NOTICE "megaraid_sas: FW restarted successfully,"
2519 "initiating next stage...\n");
2520
2521 printk(KERN_NOTICE "megaraid_sas: HBA recovery state machine,"
2522 "state 2 starting...\n");
2523
2524 /*waitting for about 20 second before start the second init*/
2525 for (wait = 0; wait < 30; wait++) {
2526 msleep(1000);
2527 }
2528
adam radford058a8fa2011-10-08 18:14:27 -07002529 if (megasas_transition_to_ready(instance, 1)) {
bo yang39a98552010-09-22 22:36:29 -04002530 printk(KERN_NOTICE "megaraid_sas:adapter not ready\n");
2531
2532 megaraid_sas_kill_hba(instance);
2533 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2534 return ;
2535 }
2536
2537 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
2538 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
2539 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)
2540 ) {
2541 *instance->consumer = *instance->producer;
2542 } else {
2543 *instance->consumer = 0;
2544 *instance->producer = 0;
2545 }
2546
2547 megasas_issue_init_mfi(instance);
2548
2549 spin_lock_irqsave(&instance->hba_lock, flags);
2550 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
2551 spin_unlock_irqrestore(&instance->hba_lock, flags);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05302552 instance->instancet->enable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04002553
2554 megasas_issue_pending_cmds_again(instance);
2555 instance->issuepend_done = 1;
2556 }
2557 return ;
2558}
2559
2560/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002561 * megasas_deplete_reply_queue - Processes all completed commands
2562 * @instance: Adapter soft state
2563 * @alt_status: Alternate status to be returned to
2564 * SCSI mid-layer instead of the status
2565 * returned by the FW
bo yang39a98552010-09-22 22:36:29 -04002566 * Note: this must be called with hba lock held
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002567 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08002568static int
bo yang39a98552010-09-22 22:36:29 -04002569megasas_deplete_reply_queue(struct megasas_instance *instance,
2570 u8 alt_status)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002571{
bo yang39a98552010-09-22 22:36:29 -04002572 u32 mfiStatus;
2573 u32 fw_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002574
bo yang39a98552010-09-22 22:36:29 -04002575 if ((mfiStatus = instance->instancet->check_reset(instance,
2576 instance->reg_set)) == 1) {
2577 return IRQ_HANDLED;
2578 }
2579
2580 if ((mfiStatus = instance->instancet->clear_intr(
2581 instance->reg_set)
2582 ) == 0) {
adam radforde1419192011-02-24 20:56:21 -08002583 /* Hardware may not set outbound_intr_status in MSI-X mode */
adam radfordc8e858f2011-10-08 18:15:13 -07002584 if (!instance->msix_vectors)
adam radforde1419192011-02-24 20:56:21 -08002585 return IRQ_NONE;
bo yang39a98552010-09-22 22:36:29 -04002586 }
2587
2588 instance->mfiStatus = mfiStatus;
2589
2590 if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) {
2591 fw_state = instance->instancet->read_fw_status_reg(
2592 instance->reg_set) & MFI_STATE_MASK;
2593
2594 if (fw_state != MFI_STATE_FAULT) {
2595 printk(KERN_NOTICE "megaraid_sas: fw state:%x\n",
2596 fw_state);
2597 }
2598
2599 if ((fw_state == MFI_STATE_FAULT) &&
2600 (instance->disableOnlineCtrlReset == 0)) {
2601 printk(KERN_NOTICE "megaraid_sas: wait adp restart\n");
2602
2603 if ((instance->pdev->device ==
2604 PCI_DEVICE_ID_LSI_SAS1064R) ||
2605 (instance->pdev->device ==
2606 PCI_DEVICE_ID_DELL_PERC5) ||
2607 (instance->pdev->device ==
2608 PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
2609
2610 *instance->consumer =
2611 MEGASAS_ADPRESET_INPROG_SIGN;
2612 }
2613
2614
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05302615 instance->instancet->disable_intr(instance);
bo yang39a98552010-09-22 22:36:29 -04002616 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
2617 instance->issuepend_done = 0;
2618
2619 atomic_set(&instance->fw_outstanding, 0);
2620 megasas_internal_reset_defer_cmds(instance);
2621
2622 printk(KERN_NOTICE "megasas: fwState=%x, stage:%d\n",
2623 fw_state, instance->adprecovery);
2624
2625 schedule_work(&instance->work_init);
2626 return IRQ_HANDLED;
2627
2628 } else {
2629 printk(KERN_NOTICE "megasas: fwstate:%x, dis_OCR=%x\n",
2630 fw_state, instance->disableOnlineCtrlReset);
2631 }
2632 }
2633
Sumant Patro5d018ad2006-10-03 13:13:18 -07002634 tasklet_schedule(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002635 return IRQ_HANDLED;
2636}
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002637/**
2638 * megasas_isr - isr entry point
2639 */
David Howells7d12e782006-10-05 14:55:46 +01002640static irqreturn_t megasas_isr(int irq, void *devp)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002641{
adam radfordc8e858f2011-10-08 18:15:13 -07002642 struct megasas_irq_context *irq_context = devp;
2643 struct megasas_instance *instance = irq_context->instance;
bo yang39a98552010-09-22 22:36:29 -04002644 unsigned long flags;
2645 irqreturn_t rc;
2646
adam radfordc8e858f2011-10-08 18:15:13 -07002647 if (atomic_read(&instance->fw_reset_no_pci_access))
bo yang39a98552010-09-22 22:36:29 -04002648 return IRQ_HANDLED;
2649
bo yang39a98552010-09-22 22:36:29 -04002650 spin_lock_irqsave(&instance->hba_lock, flags);
2651 rc = megasas_deplete_reply_queue(instance, DID_OK);
2652 spin_unlock_irqrestore(&instance->hba_lock, flags);
2653
2654 return rc;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002655}
2656
2657/**
2658 * megasas_transition_to_ready - Move the FW to READY state
Sumant Patro1341c932006-01-25 12:02:40 -08002659 * @instance: Adapter soft state
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002660 *
2661 * During the initialization, FW passes can potentially be in any one of
2662 * several possible states. If the FW in operational, waiting-for-handshake
2663 * states, driver must take steps to bring it to ready state. Otherwise, it
2664 * has to wait for the ready state.
2665 */
adam radford9c915a82010-12-21 13:34:31 -08002666int
adam radford058a8fa2011-10-08 18:14:27 -07002667megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002668{
2669 int i;
2670 u8 max_wait;
2671 u32 fw_state;
2672 u32 cur_state;
Yang, Bo7218df62009-10-06 14:52:20 -06002673 u32 abs_state, curr_abs_state;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002674
Sumant Patro1341c932006-01-25 12:02:40 -08002675 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002676
Sumant Patroe3bbff92006-10-03 12:28:49 -07002677 if (fw_state != MFI_STATE_READY)
adam radford0d490162010-12-14 19:17:17 -08002678 printk(KERN_INFO "megasas: Waiting for FW to come to ready"
2679 " state\n");
Sumant Patroe3bbff92006-10-03 12:28:49 -07002680
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002681 while (fw_state != MFI_STATE_READY) {
2682
Yang, Bo7218df62009-10-06 14:52:20 -06002683 abs_state =
2684 instance->instancet->read_fw_status_reg(instance->reg_set);
2685
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002686 switch (fw_state) {
2687
2688 case MFI_STATE_FAULT:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002689 printk(KERN_DEBUG "megasas: FW in FAULT state!!\n");
adam radford058a8fa2011-10-08 18:14:27 -07002690 if (ocr) {
2691 max_wait = MEGASAS_RESET_WAIT_TIME;
2692 cur_state = MFI_STATE_FAULT;
2693 break;
2694 } else
2695 return -ENODEV;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002696
2697 case MFI_STATE_WAIT_HANDSHAKE:
2698 /*
2699 * Set the CLR bit in inbound doorbell
2700 */
Yang, Bo0c79e682009-10-06 14:47:35 -06002701 if ((instance->pdev->device ==
Yang, Bo87911122009-10-06 14:31:54 -06002702 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2703 (instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08002704 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
2705 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05302706 PCI_DEVICE_ID_LSI_FUSION) ||
adam radford36807e62011-10-08 18:15:06 -07002707 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05302708 PCI_DEVICE_ID_LSI_INVADER) ||
2709 (instance->pdev->device ==
2710 PCI_DEVICE_ID_LSI_FURY)) {
Yang, Bo87911122009-10-06 14:31:54 -06002711 writel(
2712 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
adam radford9c915a82010-12-21 13:34:31 -08002713 &instance->reg_set->doorbell);
Yang, Bo87911122009-10-06 14:31:54 -06002714 } else {
2715 writel(
2716 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
2717 &instance->reg_set->inbound_doorbell);
2718 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002719
Yang, Bo7218df62009-10-06 14:52:20 -06002720 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002721 cur_state = MFI_STATE_WAIT_HANDSHAKE;
2722 break;
2723
Sumant Patroe3bbff92006-10-03 12:28:49 -07002724 case MFI_STATE_BOOT_MESSAGE_PENDING:
Yang, Bo87911122009-10-06 14:31:54 -06002725 if ((instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08002726 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2727 (instance->pdev->device ==
2728 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
2729 (instance->pdev->device ==
adam radford36807e62011-10-08 18:15:06 -07002730 PCI_DEVICE_ID_LSI_FUSION) ||
2731 (instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05302732 PCI_DEVICE_ID_LSI_INVADER) ||
2733 (instance->pdev->device ==
2734 PCI_DEVICE_ID_LSI_FURY)) {
Yang, Bo87911122009-10-06 14:31:54 -06002735 writel(MFI_INIT_HOTPLUG,
adam radford9c915a82010-12-21 13:34:31 -08002736 &instance->reg_set->doorbell);
Yang, Bo87911122009-10-06 14:31:54 -06002737 } else
2738 writel(MFI_INIT_HOTPLUG,
2739 &instance->reg_set->inbound_doorbell);
Sumant Patroe3bbff92006-10-03 12:28:49 -07002740
Yang, Bo7218df62009-10-06 14:52:20 -06002741 max_wait = MEGASAS_RESET_WAIT_TIME;
Sumant Patroe3bbff92006-10-03 12:28:49 -07002742 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
2743 break;
2744
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002745 case MFI_STATE_OPERATIONAL:
2746 /*
Sumant Patroe3bbff92006-10-03 12:28:49 -07002747 * Bring it to READY state; assuming max wait 10 secs
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002748 */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05302749 instance->instancet->disable_intr(instance);
Yang, Bo87911122009-10-06 14:31:54 -06002750 if ((instance->pdev->device ==
2751 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2752 (instance->pdev->device ==
adam radford9c915a82010-12-21 13:34:31 -08002753 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
2754 (instance->pdev->device
adam radford36807e62011-10-08 18:15:06 -07002755 == PCI_DEVICE_ID_LSI_FUSION) ||
2756 (instance->pdev->device
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05302757 == PCI_DEVICE_ID_LSI_INVADER) ||
2758 (instance->pdev->device
2759 == PCI_DEVICE_ID_LSI_FURY)) {
Yang, Bo87911122009-10-06 14:31:54 -06002760 writel(MFI_RESET_FLAGS,
adam radford9c915a82010-12-21 13:34:31 -08002761 &instance->reg_set->doorbell);
adam radford36807e62011-10-08 18:15:06 -07002762 if ((instance->pdev->device ==
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05302763 PCI_DEVICE_ID_LSI_FUSION) ||
2764 (instance->pdev->device ==
2765 PCI_DEVICE_ID_LSI_INVADER) ||
2766 (instance->pdev->device ==
2767 PCI_DEVICE_ID_LSI_FURY)) {
adam radford9c915a82010-12-21 13:34:31 -08002768 for (i = 0; i < (10 * 1000); i += 20) {
2769 if (readl(
2770 &instance->
2771 reg_set->
2772 doorbell) & 1)
2773 msleep(20);
2774 else
2775 break;
2776 }
2777 }
Yang, Bo87911122009-10-06 14:31:54 -06002778 } else
2779 writel(MFI_RESET_FLAGS,
2780 &instance->reg_set->inbound_doorbell);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002781
Yang, Bo7218df62009-10-06 14:52:20 -06002782 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002783 cur_state = MFI_STATE_OPERATIONAL;
2784 break;
2785
2786 case MFI_STATE_UNDEFINED:
2787 /*
2788 * This state should not last for more than 2 seconds
2789 */
Yang, Bo7218df62009-10-06 14:52:20 -06002790 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002791 cur_state = MFI_STATE_UNDEFINED;
2792 break;
2793
2794 case MFI_STATE_BB_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06002795 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002796 cur_state = MFI_STATE_BB_INIT;
2797 break;
2798
2799 case MFI_STATE_FW_INIT:
Yang, Bo7218df62009-10-06 14:52:20 -06002800 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002801 cur_state = MFI_STATE_FW_INIT;
2802 break;
2803
2804 case MFI_STATE_FW_INIT_2:
Yang, Bo7218df62009-10-06 14:52:20 -06002805 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002806 cur_state = MFI_STATE_FW_INIT_2;
2807 break;
2808
2809 case MFI_STATE_DEVICE_SCAN:
Yang, Bo7218df62009-10-06 14:52:20 -06002810 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002811 cur_state = MFI_STATE_DEVICE_SCAN;
2812 break;
2813
2814 case MFI_STATE_FLUSH_CACHE:
Yang, Bo7218df62009-10-06 14:52:20 -06002815 max_wait = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002816 cur_state = MFI_STATE_FLUSH_CACHE;
2817 break;
2818
2819 default:
2820 printk(KERN_DEBUG "megasas: Unknown state 0x%x\n",
2821 fw_state);
2822 return -ENODEV;
2823 }
2824
2825 /*
2826 * The cur_state should not last for more than max_wait secs
2827 */
2828 for (i = 0; i < (max_wait * 1000); i++) {
adam radford0d490162010-12-14 19:17:17 -08002829 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
Sumant Patro1341c932006-01-25 12:02:40 -08002830 MFI_STATE_MASK ;
Yang, Bo7218df62009-10-06 14:52:20 -06002831 curr_abs_state =
2832 instance->instancet->read_fw_status_reg(instance->reg_set);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002833
Yang, Bo7218df62009-10-06 14:52:20 -06002834 if (abs_state == curr_abs_state) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002835 msleep(1);
2836 } else
2837 break;
2838 }
2839
2840 /*
2841 * Return error if fw_state hasn't changed after max_wait
2842 */
Yang, Bo7218df62009-10-06 14:52:20 -06002843 if (curr_abs_state == abs_state) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002844 printk(KERN_DEBUG "FW state [%d] hasn't changed "
2845 "in %d secs\n", fw_state, max_wait);
2846 return -ENODEV;
2847 }
bo yang39a98552010-09-22 22:36:29 -04002848 }
adam radford0d490162010-12-14 19:17:17 -08002849 printk(KERN_INFO "megasas: FW now in Ready state\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002850
2851 return 0;
2852}
2853
2854/**
2855 * megasas_teardown_frame_pool - Destroy the cmd frame DMA pool
2856 * @instance: Adapter soft state
2857 */
2858static void megasas_teardown_frame_pool(struct megasas_instance *instance)
2859{
2860 int i;
adam radford9c915a82010-12-21 13:34:31 -08002861 u32 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002862 struct megasas_cmd *cmd;
2863
2864 if (!instance->frame_dma_pool)
2865 return;
2866
2867 /*
2868 * Return all frames to pool
2869 */
2870 for (i = 0; i < max_cmd; i++) {
2871
2872 cmd = instance->cmd_list[i];
2873
2874 if (cmd->frame)
2875 pci_pool_free(instance->frame_dma_pool, cmd->frame,
2876 cmd->frame_phys_addr);
2877
2878 if (cmd->sense)
Sumant Patroe3bbff92006-10-03 12:28:49 -07002879 pci_pool_free(instance->sense_dma_pool, cmd->sense,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002880 cmd->sense_phys_addr);
2881 }
2882
2883 /*
2884 * Now destroy the pool itself
2885 */
2886 pci_pool_destroy(instance->frame_dma_pool);
2887 pci_pool_destroy(instance->sense_dma_pool);
2888
2889 instance->frame_dma_pool = NULL;
2890 instance->sense_dma_pool = NULL;
2891}
2892
2893/**
2894 * megasas_create_frame_pool - Creates DMA pool for cmd frames
2895 * @instance: Adapter soft state
2896 *
2897 * Each command packet has an embedded DMA memory buffer that is used for
2898 * filling MFI frame and the SG list that immediately follows the frame. This
2899 * function creates those DMA memory buffers for each command packet by using
2900 * PCI pool facility.
2901 */
2902static int megasas_create_frame_pool(struct megasas_instance *instance)
2903{
2904 int i;
2905 u32 max_cmd;
2906 u32 sge_sz;
2907 u32 sgl_sz;
2908 u32 total_sz;
2909 u32 frame_count;
2910 struct megasas_cmd *cmd;
2911
adam radford9c915a82010-12-21 13:34:31 -08002912 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002913
2914 /*
2915 * Size of our frame is 64 bytes for MFI frame, followed by max SG
2916 * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer
2917 */
2918 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
2919 sizeof(struct megasas_sge32);
2920
Yang, Bof4c9a132009-10-06 14:43:28 -06002921 if (instance->flag_ieee) {
2922 sge_sz = sizeof(struct megasas_sge_skinny);
2923 }
2924
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002925 /*
2926 * Calculated the number of 64byte frames required for SGL
2927 */
2928 sgl_sz = sge_sz * instance->max_num_sge;
2929 frame_count = (sgl_sz + MEGAMFI_FRAME_SIZE - 1) / MEGAMFI_FRAME_SIZE;
bo yang39a98552010-09-22 22:36:29 -04002930 frame_count = 15;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002931
2932 /*
2933 * We need one extra frame for the MFI command
2934 */
2935 frame_count++;
2936
2937 total_sz = MEGAMFI_FRAME_SIZE * frame_count;
2938 /*
2939 * Use DMA pool facility provided by PCI layer
2940 */
2941 instance->frame_dma_pool = pci_pool_create("megasas frame pool",
2942 instance->pdev, total_sz, 64,
2943 0);
2944
2945 if (!instance->frame_dma_pool) {
2946 printk(KERN_DEBUG "megasas: failed to setup frame pool\n");
2947 return -ENOMEM;
2948 }
2949
2950 instance->sense_dma_pool = pci_pool_create("megasas sense pool",
2951 instance->pdev, 128, 4, 0);
2952
2953 if (!instance->sense_dma_pool) {
2954 printk(KERN_DEBUG "megasas: failed to setup sense pool\n");
2955
2956 pci_pool_destroy(instance->frame_dma_pool);
2957 instance->frame_dma_pool = NULL;
2958
2959 return -ENOMEM;
2960 }
2961
2962 /*
2963 * Allocate and attach a frame to each of the commands in cmd_list.
2964 * By making cmd->index as the context instead of the &cmd, we can
2965 * always use 32bit context regardless of the architecture
2966 */
2967 for (i = 0; i < max_cmd; i++) {
2968
2969 cmd = instance->cmd_list[i];
2970
2971 cmd->frame = pci_pool_alloc(instance->frame_dma_pool,
2972 GFP_KERNEL, &cmd->frame_phys_addr);
2973
2974 cmd->sense = pci_pool_alloc(instance->sense_dma_pool,
2975 GFP_KERNEL, &cmd->sense_phys_addr);
2976
2977 /*
2978 * megasas_teardown_frame_pool() takes care of freeing
2979 * whatever has been allocated
2980 */
2981 if (!cmd->frame || !cmd->sense) {
2982 printk(KERN_DEBUG "megasas: pci_pool_alloc failed \n");
2983 megasas_teardown_frame_pool(instance);
2984 return -ENOMEM;
2985 }
2986
Yang, Bo707e09b2010-10-12 07:20:27 -06002987 memset(cmd->frame, 0, total_sz);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002988 cmd->frame->io.context = cmd->index;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06002989 cmd->frame->io.pad_0 = 0;
adam radforde5f93a32011-10-08 18:15:19 -07002990 if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
2991 (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05302992 (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
adam radforde5f93a32011-10-08 18:15:19 -07002993 (reset_devices))
2994 cmd->frame->hdr.cmd = MFI_CMD_INVALID;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04002995 }
2996
2997 return 0;
2998}
2999
3000/**
3001 * megasas_free_cmds - Free all the cmds in the free cmd pool
3002 * @instance: Adapter soft state
3003 */
adam radford9c915a82010-12-21 13:34:31 -08003004void megasas_free_cmds(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003005{
3006 int i;
3007 /* First free the MFI frame pool */
3008 megasas_teardown_frame_pool(instance);
3009
3010 /* Free all the commands in the cmd_list */
adam radford9c915a82010-12-21 13:34:31 -08003011 for (i = 0; i < instance->max_mfi_cmds; i++)
3012
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003013 kfree(instance->cmd_list[i]);
3014
3015 /* Free the cmd_list buffer itself */
3016 kfree(instance->cmd_list);
3017 instance->cmd_list = NULL;
3018
3019 INIT_LIST_HEAD(&instance->cmd_pool);
3020}
3021
3022/**
3023 * megasas_alloc_cmds - Allocates the command packets
3024 * @instance: Adapter soft state
3025 *
3026 * Each command that is issued to the FW, whether IO commands from the OS or
3027 * internal commands like IOCTLs, are wrapped in local data structure called
3028 * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to
3029 * the FW.
3030 *
3031 * Each frame has a 32-bit field called context (tag). This context is used
3032 * to get back the megasas_cmd from the frame when a frame gets completed in
3033 * the ISR. Typically the address of the megasas_cmd itself would be used as
3034 * the context. But we wanted to keep the differences between 32 and 64 bit
3035 * systems to the mininum. We always use 32 bit integers for the context. In
3036 * this driver, the 32 bit values are the indices into an array cmd_list.
3037 * This array is used only to look up the megasas_cmd given the context. The
3038 * free commands themselves are maintained in a linked list called cmd_pool.
3039 */
adam radford9c915a82010-12-21 13:34:31 -08003040int megasas_alloc_cmds(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003041{
3042 int i;
3043 int j;
3044 u32 max_cmd;
3045 struct megasas_cmd *cmd;
3046
adam radford9c915a82010-12-21 13:34:31 -08003047 max_cmd = instance->max_mfi_cmds;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003048
3049 /*
3050 * instance->cmd_list is an array of struct megasas_cmd pointers.
3051 * Allocate the dynamic array first and then allocate individual
3052 * commands.
3053 */
Yoann Padioleaudd00cc42007-07-19 01:49:03 -07003054 instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003055
3056 if (!instance->cmd_list) {
3057 printk(KERN_DEBUG "megasas: out of memory\n");
3058 return -ENOMEM;
3059 }
3060
adam radford9c915a82010-12-21 13:34:31 -08003061 memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) *max_cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003062
3063 for (i = 0; i < max_cmd; i++) {
3064 instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd),
3065 GFP_KERNEL);
3066
3067 if (!instance->cmd_list[i]) {
3068
3069 for (j = 0; j < i; j++)
3070 kfree(instance->cmd_list[j]);
3071
3072 kfree(instance->cmd_list);
3073 instance->cmd_list = NULL;
3074
3075 return -ENOMEM;
3076 }
3077 }
3078
3079 /*
3080 * Add all the commands to command pool (instance->cmd_pool)
3081 */
3082 for (i = 0; i < max_cmd; i++) {
3083 cmd = instance->cmd_list[i];
3084 memset(cmd, 0, sizeof(struct megasas_cmd));
3085 cmd->index = i;
bo yang39a98552010-09-22 22:36:29 -04003086 cmd->scmd = NULL;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003087 cmd->instance = instance;
3088
3089 list_add_tail(&cmd->list, &instance->cmd_pool);
3090 }
3091
3092 /*
3093 * Create a frame pool and assign one frame to each cmd
3094 */
3095 if (megasas_create_frame_pool(instance)) {
3096 printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n");
3097 megasas_free_cmds(instance);
3098 }
3099
3100 return 0;
3101}
3102
Yang, Bo81e403c2009-10-06 14:27:54 -06003103/*
3104 * megasas_get_pd_list_info - Returns FW's pd_list structure
3105 * @instance: Adapter soft state
3106 * @pd_list: pd_list structure
3107 *
3108 * Issues an internal command (DCMD) to get the FW's controller PD
3109 * list structure. This information is mainly used to find out SYSTEM
3110 * supported by the FW.
3111 */
3112static int
3113megasas_get_pd_list(struct megasas_instance *instance)
3114{
3115 int ret = 0, pd_index = 0;
3116 struct megasas_cmd *cmd;
3117 struct megasas_dcmd_frame *dcmd;
3118 struct MR_PD_LIST *ci;
3119 struct MR_PD_ADDRESS *pd_addr;
3120 dma_addr_t ci_h = 0;
3121
3122 cmd = megasas_get_cmd(instance);
3123
3124 if (!cmd) {
3125 printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
3126 return -ENOMEM;
3127 }
3128
3129 dcmd = &cmd->frame->dcmd;
3130
3131 ci = pci_alloc_consistent(instance->pdev,
3132 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
3133
3134 if (!ci) {
3135 printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
3136 megasas_return_cmd(instance, cmd);
3137 return -ENOMEM;
3138 }
3139
3140 memset(ci, 0, sizeof(*ci));
3141 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3142
3143 dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
3144 dcmd->mbox.b[1] = 0;
3145 dcmd->cmd = MFI_CMD_DCMD;
3146 dcmd->cmd_status = 0xFF;
3147 dcmd->sge_count = 1;
3148 dcmd->flags = MFI_FRAME_DIR_READ;
3149 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003150 dcmd->pad_0 = 0;
Yang, Bo81e403c2009-10-06 14:27:54 -06003151 dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
3152 dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
3153 dcmd->sgl.sge32[0].phys_addr = ci_h;
3154 dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
3155
3156 if (!megasas_issue_polled(instance, cmd)) {
3157 ret = 0;
3158 } else {
3159 ret = -1;
3160 }
3161
3162 /*
3163 * the following function will get the instance PD LIST.
3164 */
3165
3166 pd_addr = ci->addr;
3167
3168 if ( ret == 0 &&
3169 (ci->count <
3170 (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
3171
3172 memset(instance->pd_list, 0,
3173 MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
3174
3175 for (pd_index = 0; pd_index < ci->count; pd_index++) {
3176
3177 instance->pd_list[pd_addr->deviceId].tid =
3178 pd_addr->deviceId;
3179 instance->pd_list[pd_addr->deviceId].driveType =
3180 pd_addr->scsiDevType;
3181 instance->pd_list[pd_addr->deviceId].driveState =
3182 MR_PD_STATE_SYSTEM;
3183 pd_addr++;
3184 }
3185 }
3186
3187 pci_free_consistent(instance->pdev,
3188 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
3189 ci, ci_h);
3190 megasas_return_cmd(instance, cmd);
3191
3192 return ret;
3193}
3194
Yang, Bobdc6fb82009-12-06 08:30:19 -07003195/*
3196 * megasas_get_ld_list_info - Returns FW's ld_list structure
3197 * @instance: Adapter soft state
3198 * @ld_list: ld_list structure
3199 *
3200 * Issues an internal command (DCMD) to get the FW's controller PD
3201 * list structure. This information is mainly used to find out SYSTEM
3202 * supported by the FW.
3203 */
3204static int
3205megasas_get_ld_list(struct megasas_instance *instance)
3206{
3207 int ret = 0, ld_index = 0, ids = 0;
3208 struct megasas_cmd *cmd;
3209 struct megasas_dcmd_frame *dcmd;
3210 struct MR_LD_LIST *ci;
3211 dma_addr_t ci_h = 0;
3212
3213 cmd = megasas_get_cmd(instance);
3214
3215 if (!cmd) {
3216 printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n");
3217 return -ENOMEM;
3218 }
3219
3220 dcmd = &cmd->frame->dcmd;
3221
3222 ci = pci_alloc_consistent(instance->pdev,
3223 sizeof(struct MR_LD_LIST),
3224 &ci_h);
3225
3226 if (!ci) {
3227 printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n");
3228 megasas_return_cmd(instance, cmd);
3229 return -ENOMEM;
3230 }
3231
3232 memset(ci, 0, sizeof(*ci));
3233 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3234
3235 dcmd->cmd = MFI_CMD_DCMD;
3236 dcmd->cmd_status = 0xFF;
3237 dcmd->sge_count = 1;
3238 dcmd->flags = MFI_FRAME_DIR_READ;
3239 dcmd->timeout = 0;
3240 dcmd->data_xfer_len = sizeof(struct MR_LD_LIST);
3241 dcmd->opcode = MR_DCMD_LD_GET_LIST;
3242 dcmd->sgl.sge32[0].phys_addr = ci_h;
3243 dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_LIST);
3244 dcmd->pad_0 = 0;
3245
3246 if (!megasas_issue_polled(instance, cmd)) {
3247 ret = 0;
3248 } else {
3249 ret = -1;
3250 }
3251
3252 /* the following function will get the instance PD LIST */
3253
bo yang39a98552010-09-22 22:36:29 -04003254 if ((ret == 0) && (ci->ldCount <= MAX_LOGICAL_DRIVES)) {
Yang, Bobdc6fb82009-12-06 08:30:19 -07003255 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
3256
3257 for (ld_index = 0; ld_index < ci->ldCount; ld_index++) {
3258 if (ci->ldList[ld_index].state != 0) {
3259 ids = ci->ldList[ld_index].ref.targetId;
3260 instance->ld_ids[ids] =
3261 ci->ldList[ld_index].ref.targetId;
3262 }
3263 }
3264 }
3265
3266 pci_free_consistent(instance->pdev,
3267 sizeof(struct MR_LD_LIST),
3268 ci,
3269 ci_h);
3270
3271 megasas_return_cmd(instance, cmd);
3272 return ret;
3273}
3274
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003275/**
adam radford21c9e162013-09-06 15:27:14 -07003276 * megasas_ld_list_query - Returns FW's ld_list structure
3277 * @instance: Adapter soft state
3278 * @ld_list: ld_list structure
3279 *
3280 * Issues an internal command (DCMD) to get the FW's controller PD
3281 * list structure. This information is mainly used to find out SYSTEM
3282 * supported by the FW.
3283 */
3284static int
3285megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
3286{
3287 int ret = 0, ld_index = 0, ids = 0;
3288 struct megasas_cmd *cmd;
3289 struct megasas_dcmd_frame *dcmd;
3290 struct MR_LD_TARGETID_LIST *ci;
3291 dma_addr_t ci_h = 0;
3292
3293 cmd = megasas_get_cmd(instance);
3294
3295 if (!cmd) {
3296 printk(KERN_WARNING
3297 "megasas:(megasas_ld_list_query): Failed to get cmd\n");
3298 return -ENOMEM;
3299 }
3300
3301 dcmd = &cmd->frame->dcmd;
3302
3303 ci = pci_alloc_consistent(instance->pdev,
3304 sizeof(struct MR_LD_TARGETID_LIST), &ci_h);
3305
3306 if (!ci) {
3307 printk(KERN_WARNING
3308 "megasas: Failed to alloc mem for ld_list_query\n");
3309 megasas_return_cmd(instance, cmd);
3310 return -ENOMEM;
3311 }
3312
3313 memset(ci, 0, sizeof(*ci));
3314 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3315
3316 dcmd->mbox.b[0] = query_type;
3317
3318 dcmd->cmd = MFI_CMD_DCMD;
3319 dcmd->cmd_status = 0xFF;
3320 dcmd->sge_count = 1;
3321 dcmd->flags = MFI_FRAME_DIR_READ;
3322 dcmd->timeout = 0;
3323 dcmd->data_xfer_len = sizeof(struct MR_LD_TARGETID_LIST);
3324 dcmd->opcode = MR_DCMD_LD_LIST_QUERY;
3325 dcmd->sgl.sge32[0].phys_addr = ci_h;
3326 dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_TARGETID_LIST);
3327 dcmd->pad_0 = 0;
3328
3329 if (!megasas_issue_polled(instance, cmd) && !dcmd->cmd_status) {
3330 ret = 0;
3331 } else {
3332 /* On failure, call older LD list DCMD */
3333 ret = 1;
3334 }
3335
3336 if ((ret == 0) && (ci->count <= (MAX_LOGICAL_DRIVES))) {
3337 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
3338 for (ld_index = 0; ld_index < ci->count; ld_index++) {
3339 ids = ci->targetId[ld_index];
3340 instance->ld_ids[ids] = ci->targetId[ld_index];
3341 }
3342
3343 }
3344
3345 pci_free_consistent(instance->pdev, sizeof(struct MR_LD_TARGETID_LIST),
3346 ci, ci_h);
3347
3348 megasas_return_cmd(instance, cmd);
3349
3350 return ret;
3351}
3352
3353/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003354 * megasas_get_controller_info - Returns FW's controller structure
3355 * @instance: Adapter soft state
3356 * @ctrl_info: Controller information structure
3357 *
3358 * Issues an internal command (DCMD) to get the FW's controller structure.
3359 * This information is mainly used to find out the maximum IO transfer per
3360 * command supported by the FW.
3361 */
3362static int
3363megasas_get_ctrl_info(struct megasas_instance *instance,
3364 struct megasas_ctrl_info *ctrl_info)
3365{
3366 int ret = 0;
3367 struct megasas_cmd *cmd;
3368 struct megasas_dcmd_frame *dcmd;
3369 struct megasas_ctrl_info *ci;
3370 dma_addr_t ci_h = 0;
3371
3372 cmd = megasas_get_cmd(instance);
3373
3374 if (!cmd) {
3375 printk(KERN_DEBUG "megasas: Failed to get a free cmd\n");
3376 return -ENOMEM;
3377 }
3378
3379 dcmd = &cmd->frame->dcmd;
3380
3381 ci = pci_alloc_consistent(instance->pdev,
3382 sizeof(struct megasas_ctrl_info), &ci_h);
3383
3384 if (!ci) {
3385 printk(KERN_DEBUG "Failed to alloc mem for ctrl info\n");
3386 megasas_return_cmd(instance, cmd);
3387 return -ENOMEM;
3388 }
3389
3390 memset(ci, 0, sizeof(*ci));
3391 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3392
3393 dcmd->cmd = MFI_CMD_DCMD;
3394 dcmd->cmd_status = 0xFF;
3395 dcmd->sge_count = 1;
3396 dcmd->flags = MFI_FRAME_DIR_READ;
3397 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003398 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003399 dcmd->data_xfer_len = sizeof(struct megasas_ctrl_info);
3400 dcmd->opcode = MR_DCMD_CTRL_GET_INFO;
3401 dcmd->sgl.sge32[0].phys_addr = ci_h;
3402 dcmd->sgl.sge32[0].length = sizeof(struct megasas_ctrl_info);
3403
3404 if (!megasas_issue_polled(instance, cmd)) {
3405 ret = 0;
3406 memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info));
3407 } else {
3408 ret = -1;
3409 }
3410
3411 pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
3412 ci, ci_h);
3413
3414 megasas_return_cmd(instance, cmd);
3415 return ret;
3416}
3417
3418/**
bo yang31ea7082007-11-07 12:09:50 -05003419 * megasas_issue_init_mfi - Initializes the FW
3420 * @instance: Adapter soft state
3421 *
3422 * Issues the INIT MFI cmd
3423 */
3424static int
3425megasas_issue_init_mfi(struct megasas_instance *instance)
3426{
3427 u32 context;
3428
3429 struct megasas_cmd *cmd;
3430
3431 struct megasas_init_frame *init_frame;
3432 struct megasas_init_queue_info *initq_info;
3433 dma_addr_t init_frame_h;
3434 dma_addr_t initq_info_h;
3435
3436 /*
3437 * Prepare a init frame. Note the init frame points to queue info
3438 * structure. Each frame has SGL allocated after first 64 bytes. For
3439 * this frame - since we don't need any SGL - we use SGL's space as
3440 * queue info structure
3441 *
3442 * We will not get a NULL command below. We just created the pool.
3443 */
3444 cmd = megasas_get_cmd(instance);
3445
3446 init_frame = (struct megasas_init_frame *)cmd->frame;
3447 initq_info = (struct megasas_init_queue_info *)
3448 ((unsigned long)init_frame + 64);
3449
3450 init_frame_h = cmd->frame_phys_addr;
3451 initq_info_h = init_frame_h + 64;
3452
3453 context = init_frame->context;
3454 memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
3455 memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
3456 init_frame->context = context;
3457
3458 initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
3459 initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h;
3460
3461 initq_info->producer_index_phys_addr_lo = instance->producer_h;
3462 initq_info->consumer_index_phys_addr_lo = instance->consumer_h;
3463
3464 init_frame->cmd = MFI_CMD_INIT;
3465 init_frame->cmd_status = 0xFF;
3466 init_frame->queue_info_new_phys_addr_lo = initq_info_h;
3467
3468 init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);
3469
3470 /*
3471 * disable the intr before firing the init frame to FW
3472 */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303473 instance->instancet->disable_intr(instance);
bo yang31ea7082007-11-07 12:09:50 -05003474
3475 /*
3476 * Issue the init frame in polled mode
3477 */
3478
3479 if (megasas_issue_polled(instance, cmd)) {
3480 printk(KERN_ERR "megasas: Failed to init firmware\n");
3481 megasas_return_cmd(instance, cmd);
3482 goto fail_fw_init;
3483 }
3484
3485 megasas_return_cmd(instance, cmd);
3486
3487 return 0;
3488
3489fail_fw_init:
3490 return -EINVAL;
3491}
3492
adam radfordcd50ba82010-12-21 10:23:23 -08003493static u32
3494megasas_init_adapter_mfi(struct megasas_instance *instance)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003495{
adam radfordcd50ba82010-12-21 10:23:23 -08003496 struct megasas_register_set __iomem *reg_set;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003497 u32 context_sz;
3498 u32 reply_q_sz;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003499
3500 reg_set = instance->reg_set;
3501
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003502 /*
3503 * Get various operational parameters from status register
3504 */
Sumant Patro1341c932006-01-25 12:02:40 -08003505 instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
Sumant Patroe3bbff92006-10-03 12:28:49 -07003506 /*
3507 * Reduce the max supported cmds by 1. This is to ensure that the
3508 * reply_q_sz (1 more than the max cmd that driver may send)
3509 * does not exceed max cmds that the FW can support
3510 */
3511 instance->max_fw_cmds = instance->max_fw_cmds-1;
adam radford9c915a82010-12-21 13:34:31 -08003512 instance->max_mfi_cmds = instance->max_fw_cmds;
adam radford0d490162010-12-14 19:17:17 -08003513 instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
Sumant Patro1341c932006-01-25 12:02:40 -08003514 0x10;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003515 /*
3516 * Create a pool of commands
3517 */
3518 if (megasas_alloc_cmds(instance))
3519 goto fail_alloc_cmds;
3520
3521 /*
3522 * Allocate memory for reply queue. Length of reply queue should
3523 * be _one_ more than the maximum commands handled by the firmware.
3524 *
3525 * Note: When FW completes commands, it places corresponding contex
3526 * values in this circular reply queue. This circular queue is a fairly
3527 * typical producer-consumer queue. FW is the producer (of completed
3528 * commands) and the driver is the consumer.
3529 */
3530 context_sz = sizeof(u32);
3531 reply_q_sz = context_sz * (instance->max_fw_cmds + 1);
3532
3533 instance->reply_queue = pci_alloc_consistent(instance->pdev,
3534 reply_q_sz,
3535 &instance->reply_queue_h);
3536
3537 if (!instance->reply_queue) {
3538 printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n");
3539 goto fail_reply_queue;
3540 }
3541
bo yang31ea7082007-11-07 12:09:50 -05003542 if (megasas_issue_init_mfi(instance))
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003543 goto fail_fw_init;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003544
bo yang39a98552010-09-22 22:36:29 -04003545 instance->fw_support_ieee = 0;
3546 instance->fw_support_ieee =
3547 (instance->instancet->read_fw_status_reg(reg_set) &
3548 0x04000000);
3549
3550 printk(KERN_NOTICE "megasas_init_mfi: fw_support_ieee=%d",
3551 instance->fw_support_ieee);
3552
3553 if (instance->fw_support_ieee)
3554 instance->flag_ieee = 1;
3555
adam radfordcd50ba82010-12-21 10:23:23 -08003556 return 0;
3557
3558fail_fw_init:
3559
3560 pci_free_consistent(instance->pdev, reply_q_sz,
3561 instance->reply_queue, instance->reply_queue_h);
3562fail_reply_queue:
3563 megasas_free_cmds(instance);
3564
3565fail_alloc_cmds:
adam radfordcd50ba82010-12-21 10:23:23 -08003566 return 1;
3567}
3568
3569/**
3570 * megasas_init_fw - Initializes the FW
3571 * @instance: Adapter soft state
3572 *
3573 * This is the main function for initializing firmware
3574 */
3575
3576static int megasas_init_fw(struct megasas_instance *instance)
3577{
3578 u32 max_sectors_1;
3579 u32 max_sectors_2;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303580 u32 tmp_sectors, msix_enable, scratch_pad_2;
adam radfordcd50ba82010-12-21 10:23:23 -08003581 struct megasas_register_set __iomem *reg_set;
3582 struct megasas_ctrl_info *ctrl_info;
3583 unsigned long bar_list;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303584 int i, loop, fw_msix_count = 0;
adam radfordcd50ba82010-12-21 10:23:23 -08003585
3586 /* Find first memory bar */
3587 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
3588 instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
3589 instance->base_addr = pci_resource_start(instance->pdev, instance->bar);
3590 if (pci_request_selected_regions(instance->pdev, instance->bar,
3591 "megasas: LSI")) {
3592 printk(KERN_DEBUG "megasas: IO memory region busy!\n");
3593 return -EBUSY;
3594 }
3595
3596 instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
3597
3598 if (!instance->reg_set) {
3599 printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
3600 goto fail_ioremap;
3601 }
3602
3603 reg_set = instance->reg_set;
3604
3605 switch (instance->pdev->device) {
adam radford9c915a82010-12-21 13:34:31 -08003606 case PCI_DEVICE_ID_LSI_FUSION:
adam radford36807e62011-10-08 18:15:06 -07003607 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05303608 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08003609 instance->instancet = &megasas_instance_template_fusion;
3610 break;
adam radfordcd50ba82010-12-21 10:23:23 -08003611 case PCI_DEVICE_ID_LSI_SAS1078R:
3612 case PCI_DEVICE_ID_LSI_SAS1078DE:
3613 instance->instancet = &megasas_instance_template_ppc;
3614 break;
3615 case PCI_DEVICE_ID_LSI_SAS1078GEN2:
3616 case PCI_DEVICE_ID_LSI_SAS0079GEN2:
3617 instance->instancet = &megasas_instance_template_gen2;
3618 break;
3619 case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
3620 case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
3621 instance->instancet = &megasas_instance_template_skinny;
3622 break;
3623 case PCI_DEVICE_ID_LSI_SAS1064R:
3624 case PCI_DEVICE_ID_DELL_PERC5:
3625 default:
3626 instance->instancet = &megasas_instance_template_xscale;
3627 break;
3628 }
3629
Sumit.Saxena@lsi.com6431f5d2013-07-16 02:26:05 +05303630 if (megasas_transition_to_ready(instance, 0)) {
3631 atomic_set(&instance->fw_reset_no_pci_access, 1);
3632 instance->instancet->adp_reset
3633 (instance, instance->reg_set);
3634 atomic_set(&instance->fw_reset_no_pci_access, 0);
3635 dev_info(&instance->pdev->dev,
3636 "megasas: FW restarted successfully from %s!\n",
3637 __func__);
3638
3639 /*waitting for about 30 second before retry*/
3640 ssleep(30);
3641
3642 if (megasas_transition_to_ready(instance, 0))
3643 goto fail_ready_state;
3644 }
adam radfordcd50ba82010-12-21 10:23:23 -08003645
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303646 /*
3647 * MSI-X host index 0 is common for all adapter.
3648 * It is used for all MPT based Adapters.
3649 */
3650 instance->reply_post_host_index_addr[0] =
3651 (u32 *)((u8 *)instance->reg_set +
3652 MPI2_REPLY_POST_HOST_INDEX_OFFSET);
3653
adam radford3f1abce2011-05-11 18:33:47 -07003654 /* Check if MSI-X is supported while in ready state */
3655 msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
3656 0x4000000) >> 0x1a;
adam radfordc8e858f2011-10-08 18:15:13 -07003657 if (msix_enable && !msix_disable) {
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303658 scratch_pad_2 = readl
3659 (&instance->reg_set->outbound_scratch_pad_2);
adam radfordc8e858f2011-10-08 18:15:13 -07003660 /* Check max MSI-X vectors */
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303661 if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) {
3662 instance->msix_vectors = (scratch_pad_2
3663 & MR_MAX_REPLY_QUEUES_OFFSET) + 1;
3664 fw_msix_count = instance->msix_vectors;
adam radford079eadd2012-10-01 19:26:59 -07003665 if (msix_vectors)
3666 instance->msix_vectors =
3667 min(msix_vectors,
3668 instance->msix_vectors);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303669 } else if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)
3670 || (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
3671 /* Invader/Fury supports more than 8 MSI-X */
3672 instance->msix_vectors = ((scratch_pad_2
3673 & MR_MAX_REPLY_QUEUES_EXT_OFFSET)
3674 >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
3675 fw_msix_count = instance->msix_vectors;
3676 /* Save 1-15 reply post index address to local memory
3677 * Index 0 is already saved from reg offset
3678 * MPI2_REPLY_POST_HOST_INDEX_OFFSET
3679 */
3680 for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
3681 instance->reply_post_host_index_addr[loop] =
3682 (u32 *)((u8 *)instance->reg_set +
3683 MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
3684 + (loop * 0x10));
3685 }
3686 if (msix_vectors)
3687 instance->msix_vectors = min(msix_vectors,
3688 instance->msix_vectors);
adam radfordc8e858f2011-10-08 18:15:13 -07003689 } else
3690 instance->msix_vectors = 1;
3691 /* Don't bother allocating more MSI-X vectors than cpus */
3692 instance->msix_vectors = min(instance->msix_vectors,
3693 (unsigned int)num_online_cpus());
3694 for (i = 0; i < instance->msix_vectors; i++)
3695 instance->msixentry[i].entry = i;
3696 i = pci_enable_msix(instance->pdev, instance->msixentry,
3697 instance->msix_vectors);
3698 if (i >= 0) {
3699 if (i) {
3700 if (!pci_enable_msix(instance->pdev,
3701 instance->msixentry, i))
3702 instance->msix_vectors = i;
3703 else
3704 instance->msix_vectors = 0;
3705 }
3706 } else
3707 instance->msix_vectors = 0;
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05303708
3709 dev_info(&instance->pdev->dev, "[scsi%d]: FW supports"
3710 "<%d> MSIX vector,Online CPUs: <%d>,"
3711 "Current MSIX <%d>\n", instance->host->host_no,
3712 fw_msix_count, (unsigned int)num_online_cpus(),
3713 instance->msix_vectors);
adam radfordc8e858f2011-10-08 18:15:13 -07003714 }
adam radford3f1abce2011-05-11 18:33:47 -07003715
adam radfordcd50ba82010-12-21 10:23:23 -08003716 /* Get operational params, sge flags, send init cmd to controller */
3717 if (instance->instancet->init_adapter(instance))
adam radfordeb1b1232011-02-24 20:55:56 -08003718 goto fail_init_adapter;
adam radfordcd50ba82010-12-21 10:23:23 -08003719
3720 printk(KERN_ERR "megasas: INIT adapter done\n");
3721
bo yang39a98552010-09-22 22:36:29 -04003722 /** for passthrough
3723 * the following function will get the PD LIST.
3724 */
3725
Yang, Bo81e403c2009-10-06 14:27:54 -06003726 memset(instance->pd_list, 0 ,
3727 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
3728 megasas_get_pd_list(instance);
3729
Yang, Bobdc6fb82009-12-06 08:30:19 -07003730 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
adam radford21c9e162013-09-06 15:27:14 -07003731 if (megasas_ld_list_query(instance,
3732 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
3733 megasas_get_ld_list(instance);
Yang, Bobdc6fb82009-12-06 08:30:19 -07003734
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003735 ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
3736
3737 /*
3738 * Compute the max allowed sectors per IO: The controller info has two
3739 * limits on max sectors. Driver should use the minimum of these two.
3740 *
3741 * 1 << stripe_sz_ops.min = max sectors per strip
3742 *
3743 * Note that older firmwares ( < FW ver 30) didn't report information
3744 * to calculate max_sectors_1. So the number ended up as zero always.
3745 */
bo yang14faea92007-11-09 04:14:00 -05003746 tmp_sectors = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003747 if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) {
3748
3749 max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
3750 ctrl_info->max_strips_per_io;
3751 max_sectors_2 = ctrl_info->max_request_size;
3752
bo yang14faea92007-11-09 04:14:00 -05003753 tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2);
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05303754
3755 /*Check whether controller is iMR or MR */
3756 if (ctrl_info->memory_size) {
3757 instance->is_imr = 0;
3758 dev_info(&instance->pdev->dev, "Controller type: MR,"
3759 "Memory size is: %dMB\n",
3760 ctrl_info->memory_size);
3761 } else {
3762 instance->is_imr = 1;
3763 dev_info(&instance->pdev->dev,
3764 "Controller type: iMR\n");
3765 }
bo yang39a98552010-09-22 22:36:29 -04003766 instance->disableOnlineCtrlReset =
3767 ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05303768 instance->UnevenSpanSupport =
3769 ctrl_info->adapterOperations2.supportUnevenSpans;
3770 if (instance->UnevenSpanSupport) {
3771 struct fusion_context *fusion = instance->ctrl_context;
3772 dev_info(&instance->pdev->dev, "FW supports: "
3773 "UnevenSpanSupport=%x\n", instance->UnevenSpanSupport);
3774 if (MR_ValidateMapInfo(instance))
3775 fusion->fast_path_io = 1;
3776 else
3777 fusion->fast_path_io = 0;
3778
3779 }
bo yang14faea92007-11-09 04:14:00 -05003780 }
3781
3782 instance->max_sectors_per_req = instance->max_num_sge *
3783 PAGE_SIZE / 512;
3784 if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
3785 instance->max_sectors_per_req = tmp_sectors;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003786
3787 kfree(ctrl_info);
3788
adam radfordc5daa6a2012-07-17 18:20:03 -07003789 /* Check for valid throttlequeuedepth module parameter */
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05303790 if (instance->is_imr) {
adam radfordc5daa6a2012-07-17 18:20:03 -07003791 if (throttlequeuedepth > (instance->max_fw_cmds -
3792 MEGASAS_SKINNY_INT_CMDS))
3793 instance->throttlequeuedepth =
3794 MEGASAS_THROTTLE_QUEUE_DEPTH;
3795 else
3796 instance->throttlequeuedepth = throttlequeuedepth;
3797 } else {
3798 if (throttlequeuedepth > (instance->max_fw_cmds -
3799 MEGASAS_INT_CMDS))
3800 instance->throttlequeuedepth =
3801 MEGASAS_THROTTLE_QUEUE_DEPTH;
3802 else
3803 instance->throttlequeuedepth = throttlequeuedepth;
3804 }
3805
Sumant Patro5d018ad2006-10-03 13:13:18 -07003806 /*
3807 * Setup tasklet for cmd completion
3808 */
3809
adam radfordf86c5422011-02-24 20:57:00 -08003810 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
bo yangad84db22007-11-09 04:40:16 -05003811 (unsigned long)instance);
3812
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003813 return 0;
3814
adam radfordeb1b1232011-02-24 20:55:56 -08003815fail_init_adapter:
adam radfordcd50ba82010-12-21 10:23:23 -08003816fail_ready_state:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003817 iounmap(instance->reg_set);
3818
3819 fail_ioremap:
adam radfordb6d5d882010-12-14 18:56:07 -08003820 pci_release_selected_regions(instance->pdev, instance->bar);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003821
3822 return -EINVAL;
3823}
3824
3825/**
3826 * megasas_release_mfi - Reverses the FW initialization
3827 * @intance: Adapter soft state
3828 */
3829static void megasas_release_mfi(struct megasas_instance *instance)
3830{
adam radford9c915a82010-12-21 13:34:31 -08003831 u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003832
adam radford9c915a82010-12-21 13:34:31 -08003833 if (instance->reply_queue)
3834 pci_free_consistent(instance->pdev, reply_q_sz,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003835 instance->reply_queue, instance->reply_queue_h);
3836
3837 megasas_free_cmds(instance);
3838
3839 iounmap(instance->reg_set);
3840
adam radfordb6d5d882010-12-14 18:56:07 -08003841 pci_release_selected_regions(instance->pdev, instance->bar);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003842}
3843
3844/**
3845 * megasas_get_seq_num - Gets latest event sequence numbers
3846 * @instance: Adapter soft state
3847 * @eli: FW event log sequence numbers information
3848 *
3849 * FW maintains a log of all events in a non-volatile area. Upper layers would
3850 * usually find out the latest sequence number of the events, the seq number at
3851 * the boot etc. They would "read" all the events below the latest seq number
3852 * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq
3853 * number), they would subsribe to AEN (asynchronous event notification) and
3854 * wait for the events to happen.
3855 */
3856static int
3857megasas_get_seq_num(struct megasas_instance *instance,
3858 struct megasas_evt_log_info *eli)
3859{
3860 struct megasas_cmd *cmd;
3861 struct megasas_dcmd_frame *dcmd;
3862 struct megasas_evt_log_info *el_info;
3863 dma_addr_t el_info_h = 0;
3864
3865 cmd = megasas_get_cmd(instance);
3866
3867 if (!cmd) {
3868 return -ENOMEM;
3869 }
3870
3871 dcmd = &cmd->frame->dcmd;
3872 el_info = pci_alloc_consistent(instance->pdev,
3873 sizeof(struct megasas_evt_log_info),
3874 &el_info_h);
3875
3876 if (!el_info) {
3877 megasas_return_cmd(instance, cmd);
3878 return -ENOMEM;
3879 }
3880
3881 memset(el_info, 0, sizeof(*el_info));
3882 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3883
3884 dcmd->cmd = MFI_CMD_DCMD;
3885 dcmd->cmd_status = 0x0;
3886 dcmd->sge_count = 1;
3887 dcmd->flags = MFI_FRAME_DIR_READ;
3888 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07003889 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04003890 dcmd->data_xfer_len = sizeof(struct megasas_evt_log_info);
3891 dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO;
3892 dcmd->sgl.sge32[0].phys_addr = el_info_h;
3893 dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_log_info);
3894
3895 megasas_issue_blocked_cmd(instance, cmd);
3896
3897 /*
3898 * Copy the data back into callers buffer
3899 */
3900 memcpy(eli, el_info, sizeof(struct megasas_evt_log_info));
3901
3902 pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info),
3903 el_info, el_info_h);
3904
3905 megasas_return_cmd(instance, cmd);
3906
3907 return 0;
3908}
3909
3910/**
3911 * megasas_register_aen - Registers for asynchronous event notification
3912 * @instance: Adapter soft state
3913 * @seq_num: The starting sequence number
3914 * @class_locale: Class of the event
3915 *
3916 * This function subscribes for AEN for events beyond the @seq_num. It requests
3917 * to be notified if and only if the event is of type @class_locale
3918 */
3919static int
3920megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
3921 u32 class_locale_word)
3922{
3923 int ret_val;
3924 struct megasas_cmd *cmd;
3925 struct megasas_dcmd_frame *dcmd;
3926 union megasas_evt_class_locale curr_aen;
3927 union megasas_evt_class_locale prev_aen;
3928
3929 /*
3930 * If there an AEN pending already (aen_cmd), check if the
3931 * class_locale of that pending AEN is inclusive of the new
3932 * AEN request we currently have. If it is, then we don't have
3933 * to do anything. In other words, whichever events the current
3934 * AEN request is subscribing to, have already been subscribed
3935 * to.
3936 *
3937 * If the old_cmd is _not_ inclusive, then we have to abort
3938 * that command, form a class_locale that is superset of both
3939 * old and current and re-issue to the FW
3940 */
3941
3942 curr_aen.word = class_locale_word;
3943
3944 if (instance->aen_cmd) {
3945
3946 prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1];
3947
3948 /*
3949 * A class whose enum value is smaller is inclusive of all
3950 * higher values. If a PROGRESS (= -1) was previously
3951 * registered, then a new registration requests for higher
3952 * classes need not be sent to FW. They are automatically
3953 * included.
3954 *
3955 * Locale numbers don't have such hierarchy. They are bitmap
3956 * values
3957 */
3958 if ((prev_aen.members.class <= curr_aen.members.class) &&
3959 !((prev_aen.members.locale & curr_aen.members.locale) ^
3960 curr_aen.members.locale)) {
3961 /*
3962 * Previously issued event registration includes
3963 * current request. Nothing to do.
3964 */
3965 return 0;
3966 } else {
3967 curr_aen.members.locale |= prev_aen.members.locale;
3968
3969 if (prev_aen.members.class < curr_aen.members.class)
3970 curr_aen.members.class = prev_aen.members.class;
3971
3972 instance->aen_cmd->abort_aen = 1;
3973 ret_val = megasas_issue_blocked_abort_cmd(instance,
3974 instance->
3975 aen_cmd);
3976
3977 if (ret_val) {
3978 printk(KERN_DEBUG "megasas: Failed to abort "
3979 "previous AEN command\n");
3980 return ret_val;
3981 }
3982 }
3983 }
3984
3985 cmd = megasas_get_cmd(instance);
3986
3987 if (!cmd)
3988 return -ENOMEM;
3989
3990 dcmd = &cmd->frame->dcmd;
3991
3992 memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail));
3993
3994 /*
3995 * Prepare DCMD for aen registration
3996 */
3997 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3998
3999 dcmd->cmd = MFI_CMD_DCMD;
4000 dcmd->cmd_status = 0x0;
4001 dcmd->sge_count = 1;
4002 dcmd->flags = MFI_FRAME_DIR_READ;
4003 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004004 dcmd->pad_0 = 0;
bo yang39a98552010-09-22 22:36:29 -04004005 instance->last_seq_num = seq_num;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004006 dcmd->data_xfer_len = sizeof(struct megasas_evt_detail);
4007 dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT;
4008 dcmd->mbox.w[0] = seq_num;
4009 dcmd->mbox.w[1] = curr_aen.word;
4010 dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
4011 dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
4012
Yang, Bof4c9a132009-10-06 14:43:28 -06004013 if (instance->aen_cmd != NULL) {
4014 megasas_return_cmd(instance, cmd);
4015 return 0;
4016 }
4017
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004018 /*
4019 * Store reference to the cmd used to register for AEN. When an
4020 * application wants us to register for AEN, we have to abort this
4021 * cmd and re-register with a new EVENT LOCALE supplied by that app
4022 */
4023 instance->aen_cmd = cmd;
4024
4025 /*
4026 * Issue the aen registration frame
4027 */
adam radford9c915a82010-12-21 13:34:31 -08004028 instance->instancet->issue_dcmd(instance, cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004029
4030 return 0;
4031}
4032
4033/**
4034 * megasas_start_aen - Subscribes to AEN during driver load time
4035 * @instance: Adapter soft state
4036 */
4037static int megasas_start_aen(struct megasas_instance *instance)
4038{
4039 struct megasas_evt_log_info eli;
4040 union megasas_evt_class_locale class_locale;
4041
4042 /*
4043 * Get the latest sequence number from FW
4044 */
4045 memset(&eli, 0, sizeof(eli));
4046
4047 if (megasas_get_seq_num(instance, &eli))
4048 return -1;
4049
4050 /*
4051 * Register AEN with FW for latest sequence number plus 1
4052 */
4053 class_locale.members.reserved = 0;
4054 class_locale.members.locale = MR_EVT_LOCALE_ALL;
4055 class_locale.members.class = MR_EVT_CLASS_DEBUG;
4056
4057 return megasas_register_aen(instance, eli.newest_seq_num + 1,
4058 class_locale.word);
4059}
4060
4061/**
4062 * megasas_io_attach - Attaches this driver to SCSI mid-layer
4063 * @instance: Adapter soft state
4064 */
4065static int megasas_io_attach(struct megasas_instance *instance)
4066{
4067 struct Scsi_Host *host = instance->host;
4068
4069 /*
4070 * Export parameters required by SCSI mid-layer
4071 */
4072 host->irq = instance->pdev->irq;
4073 host->unique_id = instance->unique_id;
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304074 if (instance->is_imr) {
Yang, Bo7bebf5c2009-10-06 14:40:58 -06004075 host->can_queue =
4076 instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
4077 } else
4078 host->can_queue =
4079 instance->max_fw_cmds - MEGASAS_INT_CMDS;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004080 host->this_id = instance->init_id;
4081 host->sg_tablesize = instance->max_num_sge;
adam radford42a8d2b2011-02-24 20:57:09 -08004082
4083 if (instance->fw_support_ieee)
4084 instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE;
4085
Yang, Bo1fd10682010-10-12 07:18:50 -06004086 /*
4087 * Check if the module parameter value for max_sectors can be used
4088 */
4089 if (max_sectors && max_sectors < instance->max_sectors_per_req)
4090 instance->max_sectors_per_req = max_sectors;
4091 else {
4092 if (max_sectors) {
4093 if (((instance->pdev->device ==
4094 PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
4095 (instance->pdev->device ==
4096 PCI_DEVICE_ID_LSI_SAS0079GEN2)) &&
4097 (max_sectors <= MEGASAS_MAX_SECTORS)) {
4098 instance->max_sectors_per_req = max_sectors;
4099 } else {
4100 printk(KERN_INFO "megasas: max_sectors should be > 0"
4101 "and <= %d (or < 1MB for GEN2 controller)\n",
4102 instance->max_sectors_per_req);
4103 }
4104 }
4105 }
4106
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004107 host->max_sectors = instance->max_sectors_per_req;
adam radford9c915a82010-12-21 13:34:31 -08004108 host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004109 host->max_channel = MEGASAS_MAX_CHANNELS - 1;
4110 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
4111 host->max_lun = MEGASAS_MAX_LUN;
Joshua Giles122da302006-02-03 15:34:17 -08004112 host->max_cmd_len = 16;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004113
adam radford9c915a82010-12-21 13:34:31 -08004114 /* Fusion only supports host reset */
adam radford36807e62011-10-08 18:15:06 -07004115 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304116 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
4117 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
adam radford9c915a82010-12-21 13:34:31 -08004118 host->hostt->eh_device_reset_handler = NULL;
4119 host->hostt->eh_bus_reset_handler = NULL;
4120 }
4121
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004122 /*
4123 * Notify the mid-layer about the new controller
4124 */
4125 if (scsi_add_host(host, &instance->pdev->dev)) {
4126 printk(KERN_DEBUG "megasas: scsi_add_host failed\n");
4127 return -ENODEV;
4128 }
4129
4130 /*
4131 * Trigger SCSI to scan our drives
4132 */
4133 scsi_scan_host(host);
4134 return 0;
4135}
4136
bo yang31ea7082007-11-07 12:09:50 -05004137static int
4138megasas_set_dma_mask(struct pci_dev *pdev)
4139{
4140 /*
4141 * All our contollers are capable of performing 64-bit DMA
4142 */
4143 if (IS_DMA64) {
Yang Hongyang6a355282009-04-06 19:01:13 -07004144 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
bo yang31ea7082007-11-07 12:09:50 -05004145
Yang Hongyang284901a2009-04-06 19:01:15 -07004146 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
bo yang31ea7082007-11-07 12:09:50 -05004147 goto fail_set_dma_mask;
4148 }
4149 } else {
Yang Hongyang284901a2009-04-06 19:01:15 -07004150 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
bo yang31ea7082007-11-07 12:09:50 -05004151 goto fail_set_dma_mask;
4152 }
4153 return 0;
4154
4155fail_set_dma_mask:
4156 return 1;
4157}
4158
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004159/**
4160 * megasas_probe_one - PCI hotplug entry point
4161 * @pdev: PCI device structure
adam radford0d490162010-12-14 19:17:17 -08004162 * @id: PCI ids of supported hotplugged adapter
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004163 */
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08004164static int megasas_probe_one(struct pci_dev *pdev,
4165 const struct pci_device_id *id)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004166{
adam radfordc8e858f2011-10-08 18:15:13 -07004167 int rval, pos, i, j;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004168 struct Scsi_Host *host;
4169 struct megasas_instance *instance;
adam radford66192dfe2011-02-24 20:56:28 -08004170 u16 control = 0;
4171
4172 /* Reset MSI-X in the kdump kernel */
4173 if (reset_devices) {
4174 pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
4175 if (pos) {
Bjorn Helgaas99369062013-04-17 18:08:44 -06004176 pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS,
adam radford66192dfe2011-02-24 20:56:28 -08004177 &control);
4178 if (control & PCI_MSIX_FLAGS_ENABLE) {
4179 dev_info(&pdev->dev, "resetting MSI-X\n");
4180 pci_write_config_word(pdev,
Bjorn Helgaas99369062013-04-17 18:08:44 -06004181 pos + PCI_MSIX_FLAGS,
adam radford66192dfe2011-02-24 20:56:28 -08004182 control &
4183 ~PCI_MSIX_FLAGS_ENABLE);
4184 }
4185 }
4186 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004187
4188 /*
4189 * Announce PCI information
4190 */
4191 printk(KERN_INFO "megasas: %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
4192 pdev->vendor, pdev->device, pdev->subsystem_vendor,
4193 pdev->subsystem_device);
4194
4195 printk("bus %d:slot %d:func %d\n",
4196 pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
4197
4198 /*
4199 * PCI prepping: enable device set bus mastering and dma mask
4200 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09004201 rval = pci_enable_device_mem(pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004202
4203 if (rval) {
4204 return rval;
4205 }
4206
4207 pci_set_master(pdev);
4208
bo yang31ea7082007-11-07 12:09:50 -05004209 if (megasas_set_dma_mask(pdev))
4210 goto fail_set_dma_mask;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004211
4212 host = scsi_host_alloc(&megasas_template,
4213 sizeof(struct megasas_instance));
4214
4215 if (!host) {
4216 printk(KERN_DEBUG "megasas: scsi_host_alloc failed\n");
4217 goto fail_alloc_instance;
4218 }
4219
4220 instance = (struct megasas_instance *)host->hostdata;
4221 memset(instance, 0, sizeof(*instance));
bo yang39a98552010-09-22 22:36:29 -04004222 atomic_set( &instance->fw_reset_no_pci_access, 0 );
adam radford9c915a82010-12-21 13:34:31 -08004223 instance->pdev = pdev;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004224
adam radford9c915a82010-12-21 13:34:31 -08004225 switch (instance->pdev->device) {
4226 case PCI_DEVICE_ID_LSI_FUSION:
adam radford36807e62011-10-08 18:15:06 -07004227 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304228 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08004229 {
4230 struct fusion_context *fusion;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004231
adam radford9c915a82010-12-21 13:34:31 -08004232 instance->ctrl_context =
4233 kzalloc(sizeof(struct fusion_context), GFP_KERNEL);
4234 if (!instance->ctrl_context) {
4235 printk(KERN_DEBUG "megasas: Failed to allocate "
4236 "memory for Fusion context info\n");
4237 goto fail_alloc_dma_buf;
4238 }
4239 fusion = instance->ctrl_context;
4240 INIT_LIST_HEAD(&fusion->cmd_pool);
4241 spin_lock_init(&fusion->cmd_pool_lock);
4242 }
4243 break;
4244 default: /* For all other supported controllers */
4245
4246 instance->producer =
4247 pci_alloc_consistent(pdev, sizeof(u32),
4248 &instance->producer_h);
4249 instance->consumer =
4250 pci_alloc_consistent(pdev, sizeof(u32),
4251 &instance->consumer_h);
4252
4253 if (!instance->producer || !instance->consumer) {
4254 printk(KERN_DEBUG "megasas: Failed to allocate"
4255 "memory for producer, consumer\n");
4256 goto fail_alloc_dma_buf;
4257 }
4258
4259 *instance->producer = 0;
4260 *instance->consumer = 0;
4261 break;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004262 }
4263
Yang, Boc3518832009-10-06 14:18:02 -06004264 megasas_poll_wait_aen = 0;
Yang, Bof4c9a132009-10-06 14:43:28 -06004265 instance->flag_ieee = 0;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004266 instance->ev = NULL;
bo yang39a98552010-09-22 22:36:29 -04004267 instance->issuepend_done = 1;
4268 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
Sumit.Saxena@lsi.com404a8a12013-05-22 12:35:33 +05304269 instance->is_imr = 0;
bo yang39a98552010-09-22 22:36:29 -04004270 megasas_poll_wait_aen = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004271
4272 instance->evt_detail = pci_alloc_consistent(pdev,
4273 sizeof(struct
4274 megasas_evt_detail),
4275 &instance->evt_detail_h);
4276
4277 if (!instance->evt_detail) {
4278 printk(KERN_DEBUG "megasas: Failed to allocate memory for "
4279 "event detail structure\n");
4280 goto fail_alloc_dma_buf;
4281 }
4282
4283 /*
4284 * Initialize locks and queues
4285 */
4286 INIT_LIST_HEAD(&instance->cmd_pool);
bo yang39a98552010-09-22 22:36:29 -04004287 INIT_LIST_HEAD(&instance->internal_reset_pending_q);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004288
Sumant Patroe4a082c2006-05-30 12:03:37 -07004289 atomic_set(&instance->fw_outstanding,0);
4290
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004291 init_waitqueue_head(&instance->int_cmd_wait_q);
4292 init_waitqueue_head(&instance->abort_cmd_wait_q);
4293
4294 spin_lock_init(&instance->cmd_pool_lock);
bo yang39a98552010-09-22 22:36:29 -04004295 spin_lock_init(&instance->hba_lock);
bo yang7343eb62007-11-09 04:35:44 -05004296 spin_lock_init(&instance->completion_lock);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004297
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02004298 mutex_init(&instance->aen_mutex);
adam radford9c915a82010-12-21 13:34:31 -08004299 mutex_init(&instance->reset_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004300
4301 /*
4302 * Initialize PCI related and misc parameters
4303 */
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004304 instance->host = host;
4305 instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
4306 instance->init_id = MEGASAS_DEFAULT_INIT_ID;
4307
Yang, Bo7bebf5c2009-10-06 14:40:58 -06004308 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
4309 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
Yang, Bof4c9a132009-10-06 14:43:28 -06004310 instance->flag_ieee = 1;
Yang, Bo7bebf5c2009-10-06 14:40:58 -06004311 sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
4312 } else
4313 sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
4314
Sumant Patro658dced2006-10-03 13:09:14 -07004315 megasas_dbg_lvl = 0;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07004316 instance->flag = 0;
Yang, Bo0c79e682009-10-06 14:47:35 -06004317 instance->unload = 1;
Sumant Patro05e9ebb2007-05-17 05:47:51 -07004318 instance->last_time = 0;
bo yang39a98552010-09-22 22:36:29 -04004319 instance->disableOnlineCtrlReset = 1;
Sumit.Saxena@lsi.combc93d422013-05-22 12:35:04 +05304320 instance->UnevenSpanSupport = 0;
bo yang39a98552010-09-22 22:36:29 -04004321
adam radford36807e62011-10-08 18:15:06 -07004322 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304323 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
4324 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
adam radford9c915a82010-12-21 13:34:31 -08004325 INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
4326 else
4327 INIT_WORK(&instance->work_init, process_fw_state_change_wq);
Sumant Patro658dced2006-10-03 13:09:14 -07004328
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004329 /*
adam radford0a770662011-02-24 20:56:12 -08004330 * Initialize MFI Firmware
4331 */
4332 if (megasas_init_fw(instance))
4333 goto fail_init_mfi;
4334
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304335retry_irq_register:
adam radford0a770662011-02-24 20:56:12 -08004336 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004337 * Register IRQ
4338 */
adam radfordc8e858f2011-10-08 18:15:13 -07004339 if (instance->msix_vectors) {
4340 for (i = 0 ; i < instance->msix_vectors; i++) {
4341 instance->irq_context[i].instance = instance;
4342 instance->irq_context[i].MSIxIndex = i;
4343 if (request_irq(instance->msixentry[i].vector,
4344 instance->instancet->service_isr, 0,
4345 "megasas",
4346 &instance->irq_context[i])) {
4347 printk(KERN_DEBUG "megasas: Failed to "
4348 "register IRQ for vector %d.\n", i);
4349 for (j = 0 ; j < i ; j++)
4350 free_irq(
4351 instance->msixentry[j].vector,
4352 &instance->irq_context[j]);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304353 /* Retry irq register for IO_APIC */
4354 instance->msix_vectors = 0;
4355 goto retry_irq_register;
adam radfordc8e858f2011-10-08 18:15:13 -07004356 }
4357 }
4358 } else {
4359 instance->irq_context[0].instance = instance;
4360 instance->irq_context[0].MSIxIndex = 0;
4361 if (request_irq(pdev->irq, instance->instancet->service_isr,
4362 IRQF_SHARED, "megasas",
4363 &instance->irq_context[0])) {
4364 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
4365 goto fail_irq;
4366 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004367 }
4368
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304369 instance->instancet->enable_intr(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004370
4371 /*
4372 * Store instance in PCI softstate
4373 */
4374 pci_set_drvdata(pdev, instance);
4375
4376 /*
4377 * Add this controller to megasas_mgmt_info structure so that it
4378 * can be exported to management applications
4379 */
4380 megasas_mgmt_info.count++;
4381 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance;
4382 megasas_mgmt_info.max_index++;
4383
4384 /*
adam radford541f90b2011-05-11 18:34:29 -07004385 * Register with SCSI mid-layer
4386 */
4387 if (megasas_io_attach(instance))
4388 goto fail_io_attach;
4389
4390 instance->unload = 0;
4391
4392 /*
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004393 * Initiate AEN (Asynchronous Event Notification)
4394 */
4395 if (megasas_start_aen(instance)) {
4396 printk(KERN_DEBUG "megasas: start aen failed\n");
4397 goto fail_start_aen;
4398 }
4399
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004400 return 0;
4401
4402 fail_start_aen:
4403 fail_io_attach:
4404 megasas_mgmt_info.count--;
4405 megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
4406 megasas_mgmt_info.max_index--;
4407
4408 pci_set_drvdata(pdev, NULL);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304409 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07004410 if (instance->msix_vectors)
4411 for (i = 0 ; i < instance->msix_vectors; i++)
4412 free_irq(instance->msixentry[i].vector,
4413 &instance->irq_context[i]);
4414 else
4415 free_irq(instance->pdev->irq, &instance->irq_context[0]);
adam radfordeb1b1232011-02-24 20:55:56 -08004416fail_irq:
adam radford36807e62011-10-08 18:15:06 -07004417 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304418 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
4419 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
adam radfordeb1b1232011-02-24 20:55:56 -08004420 megasas_release_fusion(instance);
4421 else
4422 megasas_release_mfi(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004423 fail_init_mfi:
adam radfordc8e858f2011-10-08 18:15:13 -07004424 if (instance->msix_vectors)
adam radford0a770662011-02-24 20:56:12 -08004425 pci_disable_msix(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004426 fail_alloc_dma_buf:
4427 if (instance->evt_detail)
4428 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
4429 instance->evt_detail,
4430 instance->evt_detail_h);
4431
adam radfordeb1b1232011-02-24 20:55:56 -08004432 if (instance->producer)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004433 pci_free_consistent(pdev, sizeof(u32), instance->producer,
4434 instance->producer_h);
4435 if (instance->consumer)
4436 pci_free_consistent(pdev, sizeof(u32), instance->consumer,
4437 instance->consumer_h);
4438 scsi_host_put(host);
4439
4440 fail_alloc_instance:
4441 fail_set_dma_mask:
4442 pci_disable_device(pdev);
4443
4444 return -ENODEV;
4445}
4446
4447/**
4448 * megasas_flush_cache - Requests FW to flush all its caches
4449 * @instance: Adapter soft state
4450 */
4451static void megasas_flush_cache(struct megasas_instance *instance)
4452{
4453 struct megasas_cmd *cmd;
4454 struct megasas_dcmd_frame *dcmd;
4455
bo yang39a98552010-09-22 22:36:29 -04004456 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
4457 return;
4458
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004459 cmd = megasas_get_cmd(instance);
4460
4461 if (!cmd)
4462 return;
4463
4464 dcmd = &cmd->frame->dcmd;
4465
4466 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4467
4468 dcmd->cmd = MFI_CMD_DCMD;
4469 dcmd->cmd_status = 0x0;
4470 dcmd->sge_count = 0;
4471 dcmd->flags = MFI_FRAME_DIR_NONE;
4472 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004473 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004474 dcmd->data_xfer_len = 0;
4475 dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH;
4476 dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
4477
4478 megasas_issue_blocked_cmd(instance, cmd);
4479
4480 megasas_return_cmd(instance, cmd);
4481
4482 return;
4483}
4484
4485/**
4486 * megasas_shutdown_controller - Instructs FW to shutdown the controller
4487 * @instance: Adapter soft state
bo yang31ea7082007-11-07 12:09:50 -05004488 * @opcode: Shutdown/Hibernate
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004489 */
bo yang31ea7082007-11-07 12:09:50 -05004490static void megasas_shutdown_controller(struct megasas_instance *instance,
4491 u32 opcode)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004492{
4493 struct megasas_cmd *cmd;
4494 struct megasas_dcmd_frame *dcmd;
4495
bo yang39a98552010-09-22 22:36:29 -04004496 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
4497 return;
4498
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004499 cmd = megasas_get_cmd(instance);
4500
4501 if (!cmd)
4502 return;
4503
4504 if (instance->aen_cmd)
4505 megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd);
adam radford9c915a82010-12-21 13:34:31 -08004506 if (instance->map_update_cmd)
4507 megasas_issue_blocked_abort_cmd(instance,
4508 instance->map_update_cmd);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004509 dcmd = &cmd->frame->dcmd;
4510
4511 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4512
4513 dcmd->cmd = MFI_CMD_DCMD;
4514 dcmd->cmd_status = 0x0;
4515 dcmd->sge_count = 0;
4516 dcmd->flags = MFI_FRAME_DIR_NONE;
4517 dcmd->timeout = 0;
Yang, Bo780a3762009-12-06 08:24:21 -07004518 dcmd->pad_0 = 0;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004519 dcmd->data_xfer_len = 0;
bo yang31ea7082007-11-07 12:09:50 -05004520 dcmd->opcode = opcode;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004521
4522 megasas_issue_blocked_cmd(instance, cmd);
4523
4524 megasas_return_cmd(instance, cmd);
4525
4526 return;
4527}
4528
Jiri Slaby33139b22008-05-01 17:56:02 +02004529#ifdef CONFIG_PM
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004530/**
bo yangad84db22007-11-09 04:40:16 -05004531 * megasas_suspend - driver suspend entry point
4532 * @pdev: PCI device structure
bo yang31ea7082007-11-07 12:09:50 -05004533 * @state: PCI power state to suspend routine
4534 */
Jiri Slaby33139b22008-05-01 17:56:02 +02004535static int
bo yang31ea7082007-11-07 12:09:50 -05004536megasas_suspend(struct pci_dev *pdev, pm_message_t state)
4537{
4538 struct Scsi_Host *host;
4539 struct megasas_instance *instance;
adam radfordc8e858f2011-10-08 18:15:13 -07004540 int i;
bo yang31ea7082007-11-07 12:09:50 -05004541
4542 instance = pci_get_drvdata(pdev);
4543 host = instance->host;
Yang, Bo0c79e682009-10-06 14:47:35 -06004544 instance->unload = 1;
bo yang31ea7082007-11-07 12:09:50 -05004545
4546 megasas_flush_cache(instance);
4547 megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004548
4549 /* cancel the delayed work if this work still in queue */
4550 if (instance->ev != NULL) {
4551 struct megasas_aen_event *ev = instance->ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08004552 cancel_delayed_work_sync(&ev->hotplug_work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004553 instance->ev = NULL;
4554 }
4555
bo yang31ea7082007-11-07 12:09:50 -05004556 tasklet_kill(&instance->isr_tasklet);
4557
4558 pci_set_drvdata(instance->pdev, instance);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304559 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07004560
4561 if (instance->msix_vectors)
4562 for (i = 0 ; i < instance->msix_vectors; i++)
4563 free_irq(instance->msixentry[i].vector,
4564 &instance->irq_context[i]);
4565 else
4566 free_irq(instance->pdev->irq, &instance->irq_context[0]);
4567 if (instance->msix_vectors)
adam radford80d9da92010-12-21 10:17:40 -08004568 pci_disable_msix(instance->pdev);
bo yang31ea7082007-11-07 12:09:50 -05004569
4570 pci_save_state(pdev);
4571 pci_disable_device(pdev);
4572
4573 pci_set_power_state(pdev, pci_choose_state(pdev, state));
4574
4575 return 0;
4576}
4577
4578/**
4579 * megasas_resume- driver resume entry point
4580 * @pdev: PCI device structure
4581 */
Jiri Slaby33139b22008-05-01 17:56:02 +02004582static int
bo yang31ea7082007-11-07 12:09:50 -05004583megasas_resume(struct pci_dev *pdev)
4584{
adam radfordc8e858f2011-10-08 18:15:13 -07004585 int rval, i, j;
bo yang31ea7082007-11-07 12:09:50 -05004586 struct Scsi_Host *host;
4587 struct megasas_instance *instance;
4588
4589 instance = pci_get_drvdata(pdev);
4590 host = instance->host;
4591 pci_set_power_state(pdev, PCI_D0);
4592 pci_enable_wake(pdev, PCI_D0, 0);
4593 pci_restore_state(pdev);
4594
4595 /*
4596 * PCI prepping: enable device set bus mastering and dma mask
4597 */
Noriyuki Fujiiaeab3fd2009-11-20 16:27:20 +09004598 rval = pci_enable_device_mem(pdev);
bo yang31ea7082007-11-07 12:09:50 -05004599
4600 if (rval) {
4601 printk(KERN_ERR "megasas: Enable device failed\n");
4602 return rval;
4603 }
4604
4605 pci_set_master(pdev);
4606
4607 if (megasas_set_dma_mask(pdev))
4608 goto fail_set_dma_mask;
4609
4610 /*
4611 * Initialize MFI Firmware
4612 */
4613
bo yang31ea7082007-11-07 12:09:50 -05004614 atomic_set(&instance->fw_outstanding, 0);
4615
4616 /*
4617 * We expect the FW state to be READY
4618 */
adam radford058a8fa2011-10-08 18:14:27 -07004619 if (megasas_transition_to_ready(instance, 0))
bo yang31ea7082007-11-07 12:09:50 -05004620 goto fail_ready_state;
4621
adam radford3f1abce2011-05-11 18:33:47 -07004622 /* Now re-enable MSI-X */
adam radfordc8e858f2011-10-08 18:15:13 -07004623 if (instance->msix_vectors)
4624 pci_enable_msix(instance->pdev, instance->msixentry,
4625 instance->msix_vectors);
adam radford3f1abce2011-05-11 18:33:47 -07004626
adam radford9c915a82010-12-21 13:34:31 -08004627 switch (instance->pdev->device) {
4628 case PCI_DEVICE_ID_LSI_FUSION:
adam radford36807e62011-10-08 18:15:06 -07004629 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304630 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08004631 {
4632 megasas_reset_reply_desc(instance);
4633 if (megasas_ioc_init_fusion(instance)) {
4634 megasas_free_cmds(instance);
4635 megasas_free_cmds_fusion(instance);
4636 goto fail_init_mfi;
4637 }
4638 if (!megasas_get_map_info(instance))
4639 megasas_sync_map_info(instance);
4640 }
4641 break;
4642 default:
4643 *instance->producer = 0;
4644 *instance->consumer = 0;
4645 if (megasas_issue_init_mfi(instance))
4646 goto fail_init_mfi;
4647 break;
4648 }
bo yang31ea7082007-11-07 12:09:50 -05004649
adam radford9c915a82010-12-21 13:34:31 -08004650 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
4651 (unsigned long)instance);
bo yang31ea7082007-11-07 12:09:50 -05004652
4653 /*
4654 * Register IRQ
4655 */
adam radfordc8e858f2011-10-08 18:15:13 -07004656 if (instance->msix_vectors) {
4657 for (i = 0 ; i < instance->msix_vectors; i++) {
4658 instance->irq_context[i].instance = instance;
4659 instance->irq_context[i].MSIxIndex = i;
4660 if (request_irq(instance->msixentry[i].vector,
4661 instance->instancet->service_isr, 0,
4662 "megasas",
4663 &instance->irq_context[i])) {
4664 printk(KERN_DEBUG "megasas: Failed to "
4665 "register IRQ for vector %d.\n", i);
4666 for (j = 0 ; j < i ; j++)
4667 free_irq(
4668 instance->msixentry[j].vector,
4669 &instance->irq_context[j]);
4670 goto fail_irq;
4671 }
4672 }
4673 } else {
4674 instance->irq_context[0].instance = instance;
4675 instance->irq_context[0].MSIxIndex = 0;
4676 if (request_irq(pdev->irq, instance->instancet->service_isr,
4677 IRQF_SHARED, "megasas",
4678 &instance->irq_context[0])) {
4679 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
4680 goto fail_irq;
4681 }
bo yang31ea7082007-11-07 12:09:50 -05004682 }
4683
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304684 instance->instancet->enable_intr(instance);
Yang, Bo0c79e682009-10-06 14:47:35 -06004685 instance->unload = 0;
4686
adam radford541f90b2011-05-11 18:34:29 -07004687 /*
4688 * Initiate AEN (Asynchronous Event Notification)
4689 */
4690 if (megasas_start_aen(instance))
4691 printk(KERN_ERR "megasas: Start AEN failed\n");
4692
bo yang31ea7082007-11-07 12:09:50 -05004693 return 0;
4694
4695fail_irq:
4696fail_init_mfi:
4697 if (instance->evt_detail)
4698 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
4699 instance->evt_detail,
4700 instance->evt_detail_h);
4701
4702 if (instance->producer)
4703 pci_free_consistent(pdev, sizeof(u32), instance->producer,
4704 instance->producer_h);
4705 if (instance->consumer)
4706 pci_free_consistent(pdev, sizeof(u32), instance->consumer,
4707 instance->consumer_h);
4708 scsi_host_put(host);
4709
4710fail_set_dma_mask:
4711fail_ready_state:
4712
4713 pci_disable_device(pdev);
4714
4715 return -ENODEV;
4716}
Jiri Slaby33139b22008-05-01 17:56:02 +02004717#else
4718#define megasas_suspend NULL
4719#define megasas_resume NULL
4720#endif
bo yang31ea7082007-11-07 12:09:50 -05004721
4722/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004723 * megasas_detach_one - PCI hot"un"plug entry point
4724 * @pdev: PCI device structure
4725 */
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08004726static void megasas_detach_one(struct pci_dev *pdev)
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004727{
4728 int i;
4729 struct Scsi_Host *host;
4730 struct megasas_instance *instance;
adam radford9c915a82010-12-21 13:34:31 -08004731 struct fusion_context *fusion;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004732
4733 instance = pci_get_drvdata(pdev);
Yang, Boc3518832009-10-06 14:18:02 -06004734 instance->unload = 1;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004735 host = instance->host;
adam radford9c915a82010-12-21 13:34:31 -08004736 fusion = instance->ctrl_context;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004737
4738 scsi_remove_host(instance->host);
4739 megasas_flush_cache(instance);
bo yang31ea7082007-11-07 12:09:50 -05004740 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004741
4742 /* cancel the delayed work if this work still in queue*/
4743 if (instance->ev != NULL) {
4744 struct megasas_aen_event *ev = instance->ev;
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08004745 cancel_delayed_work_sync(&ev->hotplug_work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06004746 instance->ev = NULL;
4747 }
4748
Sumant Patro5d018ad2006-10-03 13:13:18 -07004749 tasklet_kill(&instance->isr_tasklet);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004750
4751 /*
4752 * Take the instance off the instance array. Note that we will not
4753 * decrement the max_index. We let this array be sparse array
4754 */
4755 for (i = 0; i < megasas_mgmt_info.max_index; i++) {
4756 if (megasas_mgmt_info.instance[i] == instance) {
4757 megasas_mgmt_info.count--;
4758 megasas_mgmt_info.instance[i] = NULL;
4759
4760 break;
4761 }
4762 }
4763
4764 pci_set_drvdata(instance->pdev, NULL);
4765
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304766 instance->instancet->disable_intr(instance);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004767
adam radfordc8e858f2011-10-08 18:15:13 -07004768 if (instance->msix_vectors)
4769 for (i = 0 ; i < instance->msix_vectors; i++)
4770 free_irq(instance->msixentry[i].vector,
4771 &instance->irq_context[i]);
4772 else
4773 free_irq(instance->pdev->irq, &instance->irq_context[0]);
4774 if (instance->msix_vectors)
adam radford80d9da92010-12-21 10:17:40 -08004775 pci_disable_msix(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004776
adam radford9c915a82010-12-21 13:34:31 -08004777 switch (instance->pdev->device) {
4778 case PCI_DEVICE_ID_LSI_FUSION:
adam radford36807e62011-10-08 18:15:06 -07004779 case PCI_DEVICE_ID_LSI_INVADER:
Sumit.Saxena@lsi.com21d3c712013-05-22 12:31:43 +05304780 case PCI_DEVICE_ID_LSI_FURY:
adam radford9c915a82010-12-21 13:34:31 -08004781 megasas_release_fusion(instance);
4782 for (i = 0; i < 2 ; i++)
4783 if (fusion->ld_map[i])
4784 dma_free_coherent(&instance->pdev->dev,
4785 fusion->map_sz,
4786 fusion->ld_map[i],
4787 fusion->
4788 ld_map_phys[i]);
4789 kfree(instance->ctrl_context);
4790 break;
4791 default:
4792 megasas_release_mfi(instance);
adam radford9c915a82010-12-21 13:34:31 -08004793 pci_free_consistent(pdev, sizeof(u32),
4794 instance->producer,
4795 instance->producer_h);
4796 pci_free_consistent(pdev, sizeof(u32),
4797 instance->consumer,
4798 instance->consumer_h);
4799 break;
4800 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004801
Sumit.Saxena@lsi.com105900d2013-05-22 12:30:54 +05304802 if (instance->evt_detail)
4803 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
4804 instance->evt_detail, instance->evt_detail_h);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004805 scsi_host_put(host);
4806
4807 pci_set_drvdata(pdev, NULL);
4808
4809 pci_disable_device(pdev);
4810
4811 return;
4812}
4813
4814/**
4815 * megasas_shutdown - Shutdown entry point
4816 * @device: Generic device structure
4817 */
4818static void megasas_shutdown(struct pci_dev *pdev)
4819{
adam radfordc8e858f2011-10-08 18:15:13 -07004820 int i;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004821 struct megasas_instance *instance = pci_get_drvdata(pdev);
adam radfordc8e858f2011-10-08 18:15:13 -07004822
Yang, Bo0c79e682009-10-06 14:47:35 -06004823 instance->unload = 1;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004824 megasas_flush_cache(instance);
Yang, Bo530e6fc2008-08-10 12:42:37 -07004825 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Sumit.Saxena@lsi.comd46a3ad2013-05-22 12:34:14 +05304826 instance->instancet->disable_intr(instance);
adam radfordc8e858f2011-10-08 18:15:13 -07004827 if (instance->msix_vectors)
4828 for (i = 0 ; i < instance->msix_vectors; i++)
4829 free_irq(instance->msixentry[i].vector,
4830 &instance->irq_context[i]);
4831 else
4832 free_irq(instance->pdev->irq, &instance->irq_context[0]);
4833 if (instance->msix_vectors)
adam radford46fd2562011-05-11 18:34:17 -07004834 pci_disable_msix(instance->pdev);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004835}
4836
4837/**
4838 * megasas_mgmt_open - char node "open" entry point
4839 */
4840static int megasas_mgmt_open(struct inode *inode, struct file *filep)
4841{
4842 /*
4843 * Allow only those users with admin rights
4844 */
4845 if (!capable(CAP_SYS_ADMIN))
4846 return -EACCES;
4847
4848 return 0;
4849}
4850
4851/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004852 * megasas_mgmt_fasync - Async notifier registration from applications
4853 *
4854 * This function adds the calling process to a driver global queue. When an
4855 * event occurs, SIGIO will be sent to all processes in this queue.
4856 */
4857static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
4858{
4859 int rc;
4860
Arjan van de Ven0b950672006-01-11 13:16:10 +01004861 mutex_lock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004862
4863 rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
4864
Arjan van de Ven0b950672006-01-11 13:16:10 +01004865 mutex_unlock(&megasas_async_queue_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004866
4867 if (rc >= 0) {
4868 /* For sanity check when we get ioctl */
4869 filep->private_data = filep;
4870 return 0;
4871 }
4872
4873 printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc);
4874
4875 return rc;
4876}
4877
4878/**
Yang, Boc3518832009-10-06 14:18:02 -06004879 * megasas_mgmt_poll - char node "poll" entry point
4880 * */
4881static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
4882{
4883 unsigned int mask;
4884 unsigned long flags;
4885 poll_wait(file, &megasas_poll_wait, wait);
4886 spin_lock_irqsave(&poll_aen_lock, flags);
4887 if (megasas_poll_wait_aen)
4888 mask = (POLLIN | POLLRDNORM);
4889 else
4890 mask = 0;
4891 spin_unlock_irqrestore(&poll_aen_lock, flags);
4892 return mask;
4893}
4894
4895/**
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004896 * megasas_mgmt_fw_ioctl - Issues management ioctls to FW
4897 * @instance: Adapter soft state
4898 * @argp: User's ioctl packet
4899 */
4900static int
4901megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
4902 struct megasas_iocpacket __user * user_ioc,
4903 struct megasas_iocpacket *ioc)
4904{
4905 struct megasas_sge32 *kern_sge32;
4906 struct megasas_cmd *cmd;
4907 void *kbuff_arr[MAX_IOCTL_SGE];
4908 dma_addr_t buf_handle = 0;
4909 int error = 0, i;
4910 void *sense = NULL;
4911 dma_addr_t sense_handle;
Yang, Bo7b2519a2009-10-06 14:52:20 -06004912 unsigned long *sense_ptr;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004913
4914 memset(kbuff_arr, 0, sizeof(kbuff_arr));
4915
4916 if (ioc->sge_count > MAX_IOCTL_SGE) {
4917 printk(KERN_DEBUG "megasas: SGE count [%d] > max limit [%d]\n",
4918 ioc->sge_count, MAX_IOCTL_SGE);
4919 return -EINVAL;
4920 }
4921
4922 cmd = megasas_get_cmd(instance);
4923 if (!cmd) {
4924 printk(KERN_DEBUG "megasas: Failed to get a cmd packet\n");
4925 return -ENOMEM;
4926 }
4927
4928 /*
4929 * User's IOCTL packet has 2 frames (maximum). Copy those two
4930 * frames into our cmd's frames. cmd->frame's context will get
4931 * overwritten when we copy from user's frames. So set that value
4932 * alone separately
4933 */
4934 memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
4935 cmd->frame->hdr.context = cmd->index;
Yang, Boc3518832009-10-06 14:18:02 -06004936 cmd->frame->hdr.pad_0 = 0;
adam radford882be7c32012-01-06 17:02:34 -08004937 cmd->frame->hdr.flags &= ~(MFI_FRAME_IEEE | MFI_FRAME_SGL64 |
4938 MFI_FRAME_SENSE64);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004939
4940 /*
4941 * The management interface between applications and the fw uses
4942 * MFI frames. E.g, RAID configuration changes, LD property changes
4943 * etc are accomplishes through different kinds of MFI frames. The
4944 * driver needs to care only about substituting user buffers with
4945 * kernel buffers in SGLs. The location of SGL is embedded in the
4946 * struct iocpacket itself.
4947 */
4948 kern_sge32 = (struct megasas_sge32 *)
4949 ((unsigned long)cmd->frame + ioc->sgl_off);
4950
4951 /*
4952 * For each user buffer, create a mirror buffer and copy in
4953 */
4954 for (i = 0; i < ioc->sge_count; i++) {
Bjørn Mork98cb7e42011-01-19 10:01:14 +01004955 if (!ioc->sgl[i].iov_len)
4956 continue;
4957
Sumant Patro9f35fa82007-02-14 12:55:45 -08004958 kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004959 ioc->sgl[i].iov_len,
Sumant Patro9f35fa82007-02-14 12:55:45 -08004960 &buf_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004961 if (!kbuff_arr[i]) {
4962 printk(KERN_DEBUG "megasas: Failed to alloc "
4963 "kernel SGL buffer for IOCTL \n");
4964 error = -ENOMEM;
4965 goto out;
4966 }
4967
4968 /*
4969 * We don't change the dma_coherent_mask, so
4970 * pci_alloc_consistent only returns 32bit addresses
4971 */
4972 kern_sge32[i].phys_addr = (u32) buf_handle;
4973 kern_sge32[i].length = ioc->sgl[i].iov_len;
4974
4975 /*
4976 * We created a kernel buffer corresponding to the
4977 * user buffer. Now copy in from the user buffer
4978 */
4979 if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base,
4980 (u32) (ioc->sgl[i].iov_len))) {
4981 error = -EFAULT;
4982 goto out;
4983 }
4984 }
4985
4986 if (ioc->sense_len) {
Sumant Patro9f35fa82007-02-14 12:55:45 -08004987 sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,
4988 &sense_handle, GFP_KERNEL);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004989 if (!sense) {
4990 error = -ENOMEM;
4991 goto out;
4992 }
4993
4994 sense_ptr =
Yang, Bo7b2519a2009-10-06 14:52:20 -06004995 (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04004996 *sense_ptr = sense_handle;
4997 }
4998
4999 /*
5000 * Set the sync_cmd flag so that the ISR knows not to complete this
5001 * cmd to the SCSI mid-layer
5002 */
5003 cmd->sync_cmd = 1;
5004 megasas_issue_blocked_cmd(instance, cmd);
5005 cmd->sync_cmd = 0;
5006
5007 /*
5008 * copy out the kernel buffers to user buffers
5009 */
5010 for (i = 0; i < ioc->sge_count; i++) {
5011 if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i],
5012 ioc->sgl[i].iov_len)) {
5013 error = -EFAULT;
5014 goto out;
5015 }
5016 }
5017
5018 /*
5019 * copy out the sense
5020 */
5021 if (ioc->sense_len) {
5022 /*
bo yangb70a41e2008-03-18 03:13:06 -04005023 * sense_ptr points to the location that has the user
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005024 * sense buffer address
5025 */
Yang, Bo7b2519a2009-10-06 14:52:20 -06005026 sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
5027 ioc->sense_off);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005028
bo yangb70a41e2008-03-18 03:13:06 -04005029 if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
5030 sense, ioc->sense_len)) {
bo yangb10c36a2007-11-09 04:28:47 -05005031 printk(KERN_ERR "megasas: Failed to copy out to user "
5032 "sense data\n");
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005033 error = -EFAULT;
5034 goto out;
5035 }
5036 }
5037
5038 /*
5039 * copy the status codes returned by the fw
5040 */
5041 if (copy_to_user(&user_ioc->frame.hdr.cmd_status,
5042 &cmd->frame->hdr.cmd_status, sizeof(u8))) {
5043 printk(KERN_DEBUG "megasas: Error copying out cmd_status\n");
5044 error = -EFAULT;
5045 }
5046
5047 out:
5048 if (sense) {
Sumant Patro9f35fa82007-02-14 12:55:45 -08005049 dma_free_coherent(&instance->pdev->dev, ioc->sense_len,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005050 sense, sense_handle);
5051 }
5052
Bjørn Mork7a6a7312012-11-21 09:54:48 +01005053 for (i = 0; i < ioc->sge_count; i++) {
5054 if (kbuff_arr[i])
5055 dma_free_coherent(&instance->pdev->dev,
5056 kern_sge32[i].length,
5057 kbuff_arr[i],
5058 kern_sge32[i].phys_addr);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005059 }
5060
5061 megasas_return_cmd(instance, cmd);
5062 return error;
5063}
5064
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005065static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
5066{
5067 struct megasas_iocpacket __user *user_ioc =
5068 (struct megasas_iocpacket __user *)arg;
5069 struct megasas_iocpacket *ioc;
5070 struct megasas_instance *instance;
5071 int error;
bo yang39a98552010-09-22 22:36:29 -04005072 int i;
5073 unsigned long flags;
5074 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005075
5076 ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
5077 if (!ioc)
5078 return -ENOMEM;
5079
5080 if (copy_from_user(ioc, user_ioc, sizeof(*ioc))) {
5081 error = -EFAULT;
5082 goto out_kfree_ioc;
5083 }
5084
5085 instance = megasas_lookup_instance(ioc->host_no);
5086 if (!instance) {
5087 error = -ENODEV;
5088 goto out_kfree_ioc;
5089 }
5090
bo yang39a98552010-09-22 22:36:29 -04005091 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
5092 printk(KERN_ERR "Controller in crit error\n");
Yang, Bo0c79e682009-10-06 14:47:35 -06005093 error = -ENODEV;
5094 goto out_kfree_ioc;
5095 }
5096
5097 if (instance->unload == 1) {
5098 error = -ENODEV;
5099 goto out_kfree_ioc;
5100 }
5101
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005102 /*
5103 * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
5104 */
5105 if (down_interruptible(&instance->ioctl_sem)) {
5106 error = -ERESTARTSYS;
5107 goto out_kfree_ioc;
5108 }
bo yang39a98552010-09-22 22:36:29 -04005109
5110 for (i = 0; i < wait_time; i++) {
5111
5112 spin_lock_irqsave(&instance->hba_lock, flags);
5113 if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
5114 spin_unlock_irqrestore(&instance->hba_lock, flags);
5115 break;
5116 }
5117 spin_unlock_irqrestore(&instance->hba_lock, flags);
5118
5119 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
5120 printk(KERN_NOTICE "megasas: waiting"
5121 "for controller reset to finish\n");
5122 }
5123
5124 msleep(1000);
5125 }
5126
5127 spin_lock_irqsave(&instance->hba_lock, flags);
5128 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
5129 spin_unlock_irqrestore(&instance->hba_lock, flags);
5130
5131 printk(KERN_ERR "megaraid_sas: timed out while"
5132 "waiting for HBA to recover\n");
5133 error = -ENODEV;
Dan Carpenterc64e4832013-04-16 10:44:19 +03005134 goto out_up;
bo yang39a98552010-09-22 22:36:29 -04005135 }
5136 spin_unlock_irqrestore(&instance->hba_lock, flags);
5137
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005138 error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
Dan Carpenterc64e4832013-04-16 10:44:19 +03005139 out_up:
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005140 up(&instance->ioctl_sem);
5141
5142 out_kfree_ioc:
5143 kfree(ioc);
5144 return error;
5145}
5146
5147static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
5148{
5149 struct megasas_instance *instance;
5150 struct megasas_aen aen;
5151 int error;
bo yang39a98552010-09-22 22:36:29 -04005152 int i;
5153 unsigned long flags;
5154 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005155
5156 if (file->private_data != file) {
5157 printk(KERN_DEBUG "megasas: fasync_helper was not "
5158 "called first\n");
5159 return -EINVAL;
5160 }
5161
5162 if (copy_from_user(&aen, (void __user *)arg, sizeof(aen)))
5163 return -EFAULT;
5164
5165 instance = megasas_lookup_instance(aen.host_no);
5166
5167 if (!instance)
5168 return -ENODEV;
5169
bo yang39a98552010-09-22 22:36:29 -04005170 if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
5171 return -ENODEV;
Yang, Bo0c79e682009-10-06 14:47:35 -06005172 }
5173
5174 if (instance->unload == 1) {
5175 return -ENODEV;
5176 }
5177
bo yang39a98552010-09-22 22:36:29 -04005178 for (i = 0; i < wait_time; i++) {
5179
5180 spin_lock_irqsave(&instance->hba_lock, flags);
5181 if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
5182 spin_unlock_irqrestore(&instance->hba_lock,
5183 flags);
5184 break;
5185 }
5186
5187 spin_unlock_irqrestore(&instance->hba_lock, flags);
5188
5189 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
5190 printk(KERN_NOTICE "megasas: waiting for"
5191 "controller reset to finish\n");
5192 }
5193
5194 msleep(1000);
5195 }
5196
5197 spin_lock_irqsave(&instance->hba_lock, flags);
5198 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
5199 spin_unlock_irqrestore(&instance->hba_lock, flags);
5200 printk(KERN_ERR "megaraid_sas: timed out while waiting"
5201 "for HBA to recover.\n");
5202 return -ENODEV;
5203 }
5204 spin_unlock_irqrestore(&instance->hba_lock, flags);
5205
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02005206 mutex_lock(&instance->aen_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005207 error = megasas_register_aen(instance, aen.seq_num,
5208 aen.class_locale_word);
Matthias Kaehlckee5a69e22007-10-27 09:48:46 +02005209 mutex_unlock(&instance->aen_mutex);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005210 return error;
5211}
5212
5213/**
5214 * megasas_mgmt_ioctl - char node ioctl entry point
5215 */
5216static long
5217megasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
5218{
5219 switch (cmd) {
5220 case MEGASAS_IOC_FIRMWARE:
5221 return megasas_mgmt_ioctl_fw(file, arg);
5222
5223 case MEGASAS_IOC_GET_AEN:
5224 return megasas_mgmt_ioctl_aen(file, arg);
5225 }
5226
5227 return -ENOTTY;
5228}
5229
5230#ifdef CONFIG_COMPAT
5231static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
5232{
5233 struct compat_megasas_iocpacket __user *cioc =
5234 (struct compat_megasas_iocpacket __user *)arg;
5235 struct megasas_iocpacket __user *ioc =
5236 compat_alloc_user_space(sizeof(struct megasas_iocpacket));
5237 int i;
5238 int error = 0;
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01005239 compat_uptr_t ptr;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005240
Jeff Garzik83aabc12006-10-04 06:34:03 -04005241 if (clear_user(ioc, sizeof(*ioc)))
5242 return -EFAULT;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005243
5244 if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) ||
5245 copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) ||
5246 copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) ||
5247 copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) ||
5248 copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) ||
5249 copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
5250 return -EFAULT;
5251
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01005252 /*
5253 * The sense_ptr is used in megasas_mgmt_fw_ioctl only when
5254 * sense_len is not null, so prepare the 64bit value under
5255 * the same condition.
5256 */
5257 if (ioc->sense_len) {
5258 void __user **sense_ioc_ptr =
5259 (void __user **)(ioc->frame.raw + ioc->sense_off);
5260 compat_uptr_t *sense_cioc_ptr =
5261 (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
5262 if (get_user(ptr, sense_cioc_ptr) ||
5263 put_user(compat_ptr(ptr), sense_ioc_ptr))
5264 return -EFAULT;
5265 }
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005266
Tomas Henzlb3dc1a22010-02-11 18:01:50 +01005267 for (i = 0; i < MAX_IOCTL_SGE; i++) {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005268 if (get_user(ptr, &cioc->sgl[i].iov_base) ||
5269 put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
5270 copy_in_user(&ioc->sgl[i].iov_len,
5271 &cioc->sgl[i].iov_len, sizeof(compat_size_t)))
5272 return -EFAULT;
5273 }
5274
5275 error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc);
5276
5277 if (copy_in_user(&cioc->frame.hdr.cmd_status,
5278 &ioc->frame.hdr.cmd_status, sizeof(u8))) {
5279 printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n");
5280 return -EFAULT;
5281 }
5282 return error;
5283}
5284
5285static long
5286megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd,
5287 unsigned long arg)
5288{
5289 switch (cmd) {
Sumant Patrocb59aa62006-01-25 11:53:25 -08005290 case MEGASAS_IOC_FIRMWARE32:
5291 return megasas_mgmt_compat_ioctl_fw(file, arg);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005292 case MEGASAS_IOC_GET_AEN:
5293 return megasas_mgmt_ioctl_aen(file, arg);
5294 }
5295
5296 return -ENOTTY;
5297}
5298#endif
5299
5300/*
5301 * File operations structure for management interface
5302 */
Arjan van de Ven00977a52007-02-12 00:55:34 -08005303static const struct file_operations megasas_mgmt_fops = {
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005304 .owner = THIS_MODULE,
5305 .open = megasas_mgmt_open,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005306 .fasync = megasas_mgmt_fasync,
5307 .unlocked_ioctl = megasas_mgmt_ioctl,
Yang, Boc3518832009-10-06 14:18:02 -06005308 .poll = megasas_mgmt_poll,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005309#ifdef CONFIG_COMPAT
5310 .compat_ioctl = megasas_mgmt_compat_ioctl,
5311#endif
Arnd Bergmann6038f372010-08-15 18:52:59 +02005312 .llseek = noop_llseek,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005313};
5314
5315/*
5316 * PCI hotplug support registration structure
5317 */
5318static struct pci_driver megasas_pci_driver = {
5319
5320 .name = "megaraid_sas",
5321 .id_table = megasas_pci_table,
5322 .probe = megasas_probe_one,
Greg Kroah-Hartman6f039792012-12-21 13:08:55 -08005323 .remove = megasas_detach_one,
bo yang31ea7082007-11-07 12:09:50 -05005324 .suspend = megasas_suspend,
5325 .resume = megasas_resume,
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005326 .shutdown = megasas_shutdown,
5327};
5328
5329/*
5330 * Sysfs driver attributes
5331 */
5332static ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf)
5333{
5334 return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n",
5335 MEGASAS_VERSION);
5336}
5337
5338static DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL);
5339
5340static ssize_t
5341megasas_sysfs_show_release_date(struct device_driver *dd, char *buf)
5342{
5343 return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n",
5344 MEGASAS_RELDATE);
5345}
5346
5347static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
5348 NULL);
5349
Sumant Patro658dced2006-10-03 13:09:14 -07005350static ssize_t
Yang, Bo72c4fd32009-10-06 14:20:59 -06005351megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
5352{
5353 return sprintf(buf, "%u\n", support_poll_for_event);
5354}
5355
5356static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
5357 megasas_sysfs_show_support_poll_for_event, NULL);
5358
Yang, Bo837f5fe2010-10-11 06:59:20 -06005359 static ssize_t
5360megasas_sysfs_show_support_device_change(struct device_driver *dd, char *buf)
5361{
5362 return sprintf(buf, "%u\n", support_device_change);
5363}
5364
5365static DRIVER_ATTR(support_device_change, S_IRUGO,
5366 megasas_sysfs_show_support_device_change, NULL);
5367
Yang, Bo72c4fd32009-10-06 14:20:59 -06005368static ssize_t
Sumant Patro658dced2006-10-03 13:09:14 -07005369megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
5370{
bo yangad84db22007-11-09 04:40:16 -05005371 return sprintf(buf, "%u\n", megasas_dbg_lvl);
Sumant Patro658dced2006-10-03 13:09:14 -07005372}
5373
5374static ssize_t
5375megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count)
5376{
5377 int retval = count;
5378 if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){
5379 printk(KERN_ERR "megasas: could not set dbg_lvl\n");
5380 retval = -EINVAL;
5381 }
5382 return retval;
5383}
5384
Joe Malicki66dca9b2008-08-14 17:14:48 -04005385static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl,
bo yangad84db22007-11-09 04:40:16 -05005386 megasas_sysfs_set_dbg_lvl);
5387
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005388static void
5389megasas_aen_polling(struct work_struct *work)
5390{
5391 struct megasas_aen_event *ev =
Xiaotian Fengc1d390d82012-12-04 19:33:54 +08005392 container_of(work, struct megasas_aen_event, hotplug_work.work);
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005393 struct megasas_instance *instance = ev->instance;
5394 union megasas_evt_class_locale class_locale;
5395 struct Scsi_Host *host;
5396 struct scsi_device *sdev1;
5397 u16 pd_index = 0;
Yang, Boc9786842009-12-06 08:39:25 -07005398 u16 ld_index = 0;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005399 int i, j, doscan = 0;
5400 u32 seq_num;
5401 int error;
5402
5403 if (!instance) {
5404 printk(KERN_ERR "invalid instance!\n");
5405 kfree(ev);
5406 return;
5407 }
5408 instance->ev = NULL;
5409 host = instance->host;
5410 if (instance->evt_detail) {
5411
5412 switch (instance->evt_detail->code) {
5413 case MR_EVT_PD_INSERTED:
Yang, Boc9786842009-12-06 08:39:25 -07005414 if (megasas_get_pd_list(instance) == 0) {
5415 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
5416 for (j = 0;
5417 j < MEGASAS_MAX_DEV_PER_CHANNEL;
5418 j++) {
5419
5420 pd_index =
5421 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
5422
5423 sdev1 =
5424 scsi_device_lookup(host, i, j, 0);
5425
5426 if (instance->pd_list[pd_index].driveState
5427 == MR_PD_STATE_SYSTEM) {
5428 if (!sdev1) {
5429 scsi_add_device(host, i, j, 0);
5430 }
5431
5432 if (sdev1)
5433 scsi_device_put(sdev1);
5434 }
5435 }
5436 }
5437 }
5438 doscan = 0;
5439 break;
5440
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005441 case MR_EVT_PD_REMOVED:
Yang, Boc9786842009-12-06 08:39:25 -07005442 if (megasas_get_pd_list(instance) == 0) {
Yang, Boc9786842009-12-06 08:39:25 -07005443 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
5444 for (j = 0;
5445 j < MEGASAS_MAX_DEV_PER_CHANNEL;
5446 j++) {
5447
5448 pd_index =
5449 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
5450
5451 sdev1 =
5452 scsi_device_lookup(host, i, j, 0);
5453
5454 if (instance->pd_list[pd_index].driveState
5455 == MR_PD_STATE_SYSTEM) {
5456 if (sdev1) {
5457 scsi_device_put(sdev1);
5458 }
5459 } else {
5460 if (sdev1) {
5461 scsi_remove_device(sdev1);
5462 scsi_device_put(sdev1);
5463 }
5464 }
5465 }
5466 }
5467 }
5468 doscan = 0;
5469 break;
5470
5471 case MR_EVT_LD_OFFLINE:
adam radford4c598b22011-02-24 20:56:53 -08005472 case MR_EVT_CFG_CLEARED:
Yang, Boc9786842009-12-06 08:39:25 -07005473 case MR_EVT_LD_DELETED:
adam radford21c9e162013-09-06 15:27:14 -07005474 if (megasas_ld_list_query(instance,
5475 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
5476 megasas_get_ld_list(instance);
Yang, Boc9786842009-12-06 08:39:25 -07005477 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
5478 for (j = 0;
5479 j < MEGASAS_MAX_DEV_PER_CHANNEL;
5480 j++) {
5481
5482 ld_index =
5483 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
5484
5485 sdev1 = scsi_device_lookup(host,
adam radford21c9e162013-09-06 15:27:14 -07005486 MEGASAS_MAX_PD_CHANNELS + i,
Yang, Boc9786842009-12-06 08:39:25 -07005487 j,
5488 0);
5489
5490 if (instance->ld_ids[ld_index] != 0xff) {
5491 if (sdev1) {
5492 scsi_device_put(sdev1);
5493 }
5494 } else {
5495 if (sdev1) {
5496 scsi_remove_device(sdev1);
5497 scsi_device_put(sdev1);
5498 }
5499 }
5500 }
5501 }
5502 doscan = 0;
5503 break;
5504 case MR_EVT_LD_CREATED:
adam radford21c9e162013-09-06 15:27:14 -07005505 if (megasas_ld_list_query(instance,
5506 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
5507 megasas_get_ld_list(instance);
Yang, Boc9786842009-12-06 08:39:25 -07005508 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
5509 for (j = 0;
5510 j < MEGASAS_MAX_DEV_PER_CHANNEL;
5511 j++) {
5512 ld_index =
5513 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
5514
5515 sdev1 = scsi_device_lookup(host,
adam radford21c9e162013-09-06 15:27:14 -07005516 MEGASAS_MAX_PD_CHANNELS + i,
Yang, Boc9786842009-12-06 08:39:25 -07005517 j, 0);
5518
5519 if (instance->ld_ids[ld_index] !=
5520 0xff) {
5521 if (!sdev1) {
5522 scsi_add_device(host,
adam radford21c9e162013-09-06 15:27:14 -07005523 MEGASAS_MAX_PD_CHANNELS + i,
Yang, Boc9786842009-12-06 08:39:25 -07005524 j, 0);
5525 }
5526 }
5527 if (sdev1) {
5528 scsi_device_put(sdev1);
5529 }
5530 }
5531 }
5532 doscan = 0;
5533 break;
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005534 case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
Yang, Boc9786842009-12-06 08:39:25 -07005535 case MR_EVT_FOREIGN_CFG_IMPORTED:
adam radford9c915a82010-12-21 13:34:31 -08005536 case MR_EVT_LD_STATE_CHANGE:
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005537 doscan = 1;
5538 break;
5539 default:
5540 doscan = 0;
5541 break;
5542 }
5543 } else {
5544 printk(KERN_ERR "invalid evt_detail!\n");
5545 kfree(ev);
5546 return;
5547 }
5548
5549 if (doscan) {
5550 printk(KERN_INFO "scanning ...\n");
5551 megasas_get_pd_list(instance);
5552 for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
5553 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
5554 pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
5555 sdev1 = scsi_device_lookup(host, i, j, 0);
5556 if (instance->pd_list[pd_index].driveState ==
5557 MR_PD_STATE_SYSTEM) {
5558 if (!sdev1) {
5559 scsi_add_device(host, i, j, 0);
5560 }
5561 if (sdev1)
5562 scsi_device_put(sdev1);
5563 } else {
5564 if (sdev1) {
5565 scsi_remove_device(sdev1);
5566 scsi_device_put(sdev1);
5567 }
5568 }
5569 }
5570 }
Yang, Boc9786842009-12-06 08:39:25 -07005571
adam radford21c9e162013-09-06 15:27:14 -07005572 if (megasas_ld_list_query(instance,
5573 MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
5574 megasas_get_ld_list(instance);
Yang, Boc9786842009-12-06 08:39:25 -07005575 for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
5576 for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
5577 ld_index =
5578 (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
5579
5580 sdev1 = scsi_device_lookup(host,
adam radford21c9e162013-09-06 15:27:14 -07005581 MEGASAS_MAX_PD_CHANNELS + i, j, 0);
Yang, Boc9786842009-12-06 08:39:25 -07005582 if (instance->ld_ids[ld_index] != 0xff) {
5583 if (!sdev1) {
5584 scsi_add_device(host,
adam radford21c9e162013-09-06 15:27:14 -07005585 MEGASAS_MAX_PD_CHANNELS + i,
Yang, Boc9786842009-12-06 08:39:25 -07005586 j, 0);
5587 } else {
5588 scsi_device_put(sdev1);
5589 }
5590 } else {
5591 if (sdev1) {
5592 scsi_remove_device(sdev1);
5593 scsi_device_put(sdev1);
5594 }
5595 }
5596 }
5597 }
Yang, Bo7e8a75f2009-10-06 14:50:17 -06005598 }
5599
5600 if ( instance->aen_cmd != NULL ) {
5601 kfree(ev);
5602 return ;
5603 }
5604
5605 seq_num = instance->evt_detail->seq_num + 1;
5606
5607 /* Register AEN with FW for latest sequence number plus 1 */
5608 class_locale.members.reserved = 0;
5609 class_locale.members.locale = MR_EVT_LOCALE_ALL;
5610 class_locale.members.class = MR_EVT_CLASS_DEBUG;
5611 mutex_lock(&instance->aen_mutex);
5612 error = megasas_register_aen(instance, seq_num,
5613 class_locale.word);
5614 mutex_unlock(&instance->aen_mutex);
5615
5616 if (error)
5617 printk(KERN_ERR "register aen failed error %x\n", error);
5618
5619 kfree(ev);
5620}
5621
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005622/**
5623 * megasas_init - Driver load entry point
5624 */
5625static int __init megasas_init(void)
5626{
5627 int rval;
5628
5629 /*
5630 * Announce driver version and other information
5631 */
5632 printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
5633 MEGASAS_EXT_VERSION);
5634
Kashyap Desaibd8d6dd2012-07-17 18:20:44 -07005635 spin_lock_init(&poll_aen_lock);
5636
Yang, Bo72c4fd32009-10-06 14:20:59 -06005637 support_poll_for_event = 2;
Yang, Bo837f5fe2010-10-11 06:59:20 -06005638 support_device_change = 1;
Yang, Bo72c4fd32009-10-06 14:20:59 -06005639
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005640 memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
5641
5642 /*
5643 * Register character device node
5644 */
5645 rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops);
5646
5647 if (rval < 0) {
5648 printk(KERN_DEBUG "megasas: failed to open device node\n");
5649 return rval;
5650 }
5651
5652 megasas_mgmt_majorno = rval;
5653
5654 /*
5655 * Register ourselves as PCI hotplug module
5656 */
Michal Piotrowski4041b9c2006-08-17 13:28:22 +00005657 rval = pci_register_driver(&megasas_pci_driver);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005658
5659 if (rval) {
5660 printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n");
Jeff Garzik83aabc12006-10-04 06:34:03 -04005661 goto err_pcidrv;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005662 }
5663
Jeff Garzik83aabc12006-10-04 06:34:03 -04005664 rval = driver_create_file(&megasas_pci_driver.driver,
5665 &driver_attr_version);
5666 if (rval)
5667 goto err_dcf_attr_ver;
5668 rval = driver_create_file(&megasas_pci_driver.driver,
5669 &driver_attr_release_date);
5670 if (rval)
5671 goto err_dcf_rel_date;
Yang, Bo72c4fd32009-10-06 14:20:59 -06005672
5673 rval = driver_create_file(&megasas_pci_driver.driver,
5674 &driver_attr_support_poll_for_event);
5675 if (rval)
5676 goto err_dcf_support_poll_for_event;
5677
Jeff Garzik83aabc12006-10-04 06:34:03 -04005678 rval = driver_create_file(&megasas_pci_driver.driver,
5679 &driver_attr_dbg_lvl);
5680 if (rval)
5681 goto err_dcf_dbg_lvl;
bo yangad84db22007-11-09 04:40:16 -05005682 rval = driver_create_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06005683 &driver_attr_support_device_change);
5684 if (rval)
5685 goto err_dcf_support_device_change;
5686
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005687 return rval;
bo yangad84db22007-11-09 04:40:16 -05005688
Yang, Bo837f5fe2010-10-11 06:59:20 -06005689err_dcf_support_device_change:
5690 driver_remove_file(&megasas_pci_driver.driver,
bo yangad84db22007-11-09 04:40:16 -05005691 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04005692err_dcf_dbg_lvl:
5693 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo72c4fd32009-10-06 14:20:59 -06005694 &driver_attr_support_poll_for_event);
5695
5696err_dcf_support_poll_for_event:
5697 driver_remove_file(&megasas_pci_driver.driver,
Jeff Garzik83aabc12006-10-04 06:34:03 -04005698 &driver_attr_release_date);
Yang, Bo72c4fd32009-10-06 14:20:59 -06005699
Jeff Garzik83aabc12006-10-04 06:34:03 -04005700err_dcf_rel_date:
5701 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
5702err_dcf_attr_ver:
5703 pci_unregister_driver(&megasas_pci_driver);
5704err_pcidrv:
5705 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
adam radford0d490162010-12-14 19:17:17 -08005706 return rval;
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005707}
5708
5709/**
5710 * megasas_exit - Driver unload entry point
5711 */
5712static void __exit megasas_exit(void)
5713{
Sumant Patro658dced2006-10-03 13:09:14 -07005714 driver_remove_file(&megasas_pci_driver.driver,
5715 &driver_attr_dbg_lvl);
Jeff Garzik83aabc12006-10-04 06:34:03 -04005716 driver_remove_file(&megasas_pci_driver.driver,
Yang, Bo837f5fe2010-10-11 06:59:20 -06005717 &driver_attr_support_poll_for_event);
5718 driver_remove_file(&megasas_pci_driver.driver,
5719 &driver_attr_support_device_change);
5720 driver_remove_file(&megasas_pci_driver.driver,
Jeff Garzik83aabc12006-10-04 06:34:03 -04005721 &driver_attr_release_date);
5722 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
Bagalkote, Sreenivasc4a3e0a2005-09-20 17:46:58 -04005723
5724 pci_unregister_driver(&megasas_pci_driver);
5725 unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
5726}
5727
5728module_init(megasas_init);
5729module_exit(megasas_exit);