megaraid_sas_base.c revision 3f1530c1e1f7fc570672f4a54565949070fad05f
1c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/*
23f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  Linux MegaRAID driver for SAS based RAID controllers
3c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
43f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  Copyright (c) 2009-2011  LSI Corporation.
5c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
63f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  This program is free software; you can redistribute it and/or
73f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  modify it under the terms of the GNU General Public License
83f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  as published by the Free Software Foundation; either version 2
93f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  of the License, or (at your option) any later version.
10c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
113f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  This program is distributed in the hope that it will be useful,
123f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  but WITHOUT ANY WARRANTY; without even the implied warranty of
133f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
143f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  GNU General Public License for more details.
15c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
163f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  You should have received a copy of the GNU General Public License
173f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  along with this program; if not, write to the Free Software
183f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
203f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  FILE: megaraid_sas_base.c
213f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  Version : v00.00.05.29-rc1
22c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
233f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  Authors: LSI Corporation
243f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *           Sreenivas Bagalkote
253f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *           Sumant Patro
263f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *           Bo Yang
27c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
283f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  Send feedback to: <megaraidlinux@lsi.com>
293f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *
303f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *  Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
313f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford *     ATTN: Linuxraid
32c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
33c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
34c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/kernel.h>
35c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/types.h>
36c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/pci.h>
37c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/list.h>
38c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/moduleparam.h>
39c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/module.h>
40c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/spinlock.h>
41c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/interrupt.h>
42c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/delay.h>
43c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/uio.h>
445a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
45c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <asm/uaccess.h>
46433992361ce95a1da76b76c9c24d4c957b058affAl Viro#include <linux/fs.h>
47c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/compat.h>
48cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro#include <linux/blkdev.h>
490b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven#include <linux/mutex.h>
50c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo#include <linux/poll.h>
51c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
52c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <scsi/scsi.h>
53c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <scsi/scsi_cmnd.h>
54c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <scsi/scsi_device.h>
55c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <scsi/scsi_host.h>
56c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include "megaraid_sas.h"
57c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
58ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang/*
59ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * poll_mode_io:1- schedule complete completion from q cmd
60ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang */
61ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangstatic unsigned int poll_mode_io;
62ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangmodule_param_named(poll_mode_io, poll_mode_io, int, 0);
63ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangMODULE_PARM_DESC(poll_mode_io,
64ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	"Complete cmds from IO path, (default=0)");
65ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
661fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo/*
671fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo * Number of sectors per IO command
681fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo * Will be set in megasas_init_mfi if user does not provide
691fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo */
701fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bostatic unsigned int max_sectors;
711fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bomodule_param_named(max_sectors, max_sectors, int, 0);
721fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, BoMODULE_PARM_DESC(max_sectors,
731fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo	"Maximum number of sectors per IO command");
741fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo
75c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, SreenivasMODULE_LICENSE("GPL");
76c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, SreenivasMODULE_VERSION(MEGASAS_VERSION);
773d6d174a0888fe082e87ce1d4a0f1a85044a4515Sumant PatroMODULE_AUTHOR("megaraidlinux@lsi.com");
78f28cd7cf8f696eafe42d1632b5a306fbf784d3cdbo yangMODULE_DESCRIPTION("LSI MegaRAID SAS Driver");
79c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
8039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int megasas_transition_to_ready(struct megasas_instance *instance);
8139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int megasas_get_pd_list(struct megasas_instance *instance);
8239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int megasas_issue_init_mfi(struct megasas_instance *instance);
8339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int megasas_register_aen(struct megasas_instance *instance,
8439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				u32 seq_num, u32 class_locale_word);
85c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/*
86c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI ID table for all supported controllers
87c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
88c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct pci_device_id megasas_pci_table[] = {
89c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
90f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064R)},
91f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar	/* xscale IOP */
92f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
93f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar	/* ppc IOP */
94af7a5647c03c18f5ea58033710ccb23d71727e0cbo yang	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)},
95af7a5647c03c18f5ea58033710ccb23d71727e0cbo yang	/* ppc IOP */
966610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)},
976610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	/* gen2*/
986610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
996610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	/* gen2*/
100879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
101879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	/* skinny*/
102879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
103879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	/* skinny*/
104f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
105f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar	/* xscale IOP, vega */
106f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar	{PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
107f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar	/* xscale IOP */
108f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar	{}
109c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas};
110c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
111c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, SreenivasMODULE_DEVICE_TABLE(pci, megasas_pci_table);
112c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
113c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_majorno;
114c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct megasas_mgmt_info megasas_mgmt_info;
115c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct fasync_struct *megasas_async_queue;
1160b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Venstatic DEFINE_MUTEX(megasas_async_queue_mutex);
117c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
118c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bostatic int megasas_poll_wait_aen;
119c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bostatic DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
12072c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bostatic u32 support_poll_for_event;
121658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patrostatic u32 megasas_dbg_lvl;
122837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bostatic u32 support_device_change;
123658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro
124c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo/* define lock for aen poll */
125c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bospinlock_t poll_aen_lock;
126c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo
1277343eb6570ae3b299e7b5185b139d8335ef60e9bbo yangstatic void
1287343eb6570ae3b299e7b5185b139d8335ef60e9bbo yangmegasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
1297343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		     u8 alt_status);
1307343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
131c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
132c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_get_cmd -	Get a command from the free pool
133c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
134c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
135c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Returns a free command from the pool
136c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
137858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic struct megasas_cmd *megasas_get_cmd(struct megasas_instance
138c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						  *instance)
139c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
140c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	unsigned long flags;
141c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd = NULL;
142c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
143c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	spin_lock_irqsave(&instance->cmd_pool_lock, flags);
144c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
145c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!list_empty(&instance->cmd_pool)) {
146c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd = list_entry((&instance->cmd_pool)->next,
147c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				 struct megasas_cmd, list);
148c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		list_del_init(&cmd->list);
149c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	} else {
150c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_ERR "megasas: Command pool empty!\n");
151c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
152c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
153c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
154c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return cmd;
155c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
156c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
157c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
158c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_return_cmd -	Return a cmd to free command pool
159c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
160c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd:		Command packet to be returned to free command pool
161c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
162c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic inline void
163c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
164c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
165c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	unsigned long flags;
166c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
167c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	spin_lock_irqsave(&instance->cmd_pool_lock, flags);
168c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
169c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd->scmd = NULL;
170c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	list_add_tail(&cmd->list, &instance->cmd_pool);
171c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
172c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
173c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
174c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1751341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
1761341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/**
1770d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford*	The following functions are defined for xscale
1781341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro*	(deviceid : 1064R, PERC5) controllers
1791341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro*/
1801341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
181c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
1821341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_enable_intr_xscale -	Enables interrupts
183c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @regs:			MFI register set
184c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
185c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic inline void
1861341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_enable_intr_xscale(struct megasas_register_set __iomem * regs)
187c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
18839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	writel(0, &(regs)->outbound_intr_mask);
189c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/* Dummy readl to force pci flush */
191c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	readl(&regs->outbound_intr_mask);
192c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
195b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * megasas_disable_intr_xscale -Disables interrupt
196b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * @regs:			MFI register set
197b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro */
198b274cab779219325fd480cc696a456d1c3893bd8Sumant Patrostatic inline void
199b274cab779219325fd480cc696a456d1c3893bd8Sumant Patromegasas_disable_intr_xscale(struct megasas_register_set __iomem * regs)
200b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro{
201b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	u32 mask = 0x1f;
202b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	writel(mask, &regs->outbound_intr_mask);
203b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	/* Dummy readl to force pci flush */
204b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	readl(&regs->outbound_intr_mask);
205b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro}
206b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro
207b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro/**
2081341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_read_fw_status_reg_xscale - returns the current FW status value
2091341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @regs:			MFI register set
2101341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */
2111341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patrostatic u32
2121341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs)
2131341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro{
2141341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	return readl(&(regs)->outbound_msg_0);
2151341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro}
2161341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/**
2171341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_clear_interrupt_xscale -	Check & clear interrupt
2181341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @regs:				MFI register set
2191341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */
2200d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic int
2211341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
2221341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro{
2231341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	u32 status;
22439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 mfiStatus = 0;
2251341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	/*
2261341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	 * Check if it is our interrupt
2271341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	 */
2281341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	status = readl(&regs->outbound_intr_status);
2291341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
23039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (status & MFI_OB_INTR_STATUS_MASK)
23139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
23239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (status & MFI_XSCALE_OMR0_CHANGE_INTERRUPT)
23339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
2341341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
2351341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	/*
2361341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	 * Clear the interrupt by writing back the same value
2371341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	 */
23839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (mfiStatus)
23939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		writel(status, &regs->outbound_intr_status);
2401341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
24106f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo	/* Dummy readl to force pci flush */
24206f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo	readl(&regs->outbound_intr_status);
24306f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo
24439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return mfiStatus;
2451341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro}
2461341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
2471341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/**
2481341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_fire_cmd_xscale -	Sends command to the FW
2491341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @frame_phys_addr :		Physical address of cmd
2501341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @frame_count :		Number of frames for the command
2511341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @regs :			MFI register set
2521341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */
2530d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic inline void
2540c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_xscale(struct megasas_instance *instance,
2550c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		dma_addr_t frame_phys_addr,
2560c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		u32 frame_count,
2570c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		struct megasas_register_set __iomem *regs)
2581341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro{
25939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
26039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->hba_lock, flags);
2611341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	writel((frame_phys_addr >> 3)|(frame_count),
2621341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	       &(regs)->inbound_queue_port);
26339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->hba_lock, flags);
26439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
26539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
26639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/**
26739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_adp_reset_xscale -  For controller reset
26839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs:                              MFI register set
26939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */
27039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int
27139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_adp_reset_xscale(struct megasas_instance *instance,
27239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	struct megasas_register_set __iomem *regs)
27339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
27439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 i;
27539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 pcidata;
27639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	writel(MFI_ADP_RESET, &regs->inbound_doorbell);
27739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
27839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	for (i = 0; i < 3; i++)
27939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		msleep(1000); /* sleep for 3 secs */
28039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	pcidata  = 0;
28139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata);
28239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	printk(KERN_NOTICE "pcidata = %x\n", pcidata);
28339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (pcidata & 0x2) {
28439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "mfi 1068 offset read=%x\n", pcidata);
28539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		pcidata &= ~0x2;
28639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		pci_write_config_dword(instance->pdev,
28739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				MFI_1068_PCSR_OFFSET, pcidata);
28839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
28939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		for (i = 0; i < 2; i++)
29039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			msleep(1000); /* need to wait 2 secs again */
29139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
29239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		pcidata  = 0;
29339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		pci_read_config_dword(instance->pdev,
29439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata);
29539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "1068 offset handshake read=%x\n", pcidata);
29639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) {
29739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "1068 offset pcidt=%x\n", pcidata);
29839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			pcidata = 0;
29939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			pci_write_config_dword(instance->pdev,
30039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				MFI_1068_FW_HANDSHAKE_OFFSET, pcidata);
30139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
30239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
30339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return 0;
30439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
30539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
30639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/**
30739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_xscale -	For controller reset check
30839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs:				MFI register set
30939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */
31039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int
31139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_xscale(struct megasas_instance *instance,
31239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		struct megasas_register_set __iomem *regs)
31339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
31439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 consumer;
31539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	consumer = *instance->consumer;
31639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
31739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if ((instance->adprecovery != MEGASAS_HBA_OPERATIONAL) &&
31839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		(*instance->consumer == MEGASAS_ADPRESET_INPROG_SIGN)) {
31939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return 1;
32039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
32139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return 0;
3221341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro}
3231341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
3241341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patrostatic struct megasas_instance_template megasas_instance_template_xscale = {
3251341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
3261341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	.fire_cmd = megasas_fire_cmd_xscale,
3271341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	.enable_intr = megasas_enable_intr_xscale,
328b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	.disable_intr = megasas_disable_intr_xscale,
3291341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	.clear_intr = megasas_clear_intr_xscale,
3301341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	.read_fw_status_reg = megasas_read_fw_status_reg_xscale,
33139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	.adp_reset = megasas_adp_reset_xscale,
33239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	.check_reset = megasas_check_reset_xscale,
3331341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro};
3341341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
3351341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/**
3360d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford*	This is the end of set of functions & definitions specific
3371341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro*	to xscale (deviceid : 1064R, PERC5) controllers
3381341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro*/
3391341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
3401341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/**
3410d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford*	The following functions are defined for ppc (deviceid : 0x60)
342f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro* 	controllers
343f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro*/
344f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro
345f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/**
346f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_enable_intr_ppc -	Enables interrupts
347f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs:			MFI register set
348f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */
349f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patrostatic inline void
350f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patromegasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
351f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{
352f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
3530d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford
35439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	writel(~0x80000000, &(regs)->outbound_intr_mask);
355f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro
356f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	/* Dummy readl to force pci flush */
357f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	readl(&regs->outbound_intr_mask);
358f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro}
359f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro
360f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/**
361b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * megasas_disable_intr_ppc -	Disable interrupt
362b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * @regs:			MFI register set
363b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro */
364b274cab779219325fd480cc696a456d1c3893bd8Sumant Patrostatic inline void
365b274cab779219325fd480cc696a456d1c3893bd8Sumant Patromegasas_disable_intr_ppc(struct megasas_register_set __iomem * regs)
366b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro{
367b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	u32 mask = 0xFFFFFFFF;
368b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	writel(mask, &regs->outbound_intr_mask);
369b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	/* Dummy readl to force pci flush */
370b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	readl(&regs->outbound_intr_mask);
371b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro}
372b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro
373b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro/**
374f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_read_fw_status_reg_ppc - returns the current FW status value
375f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs:			MFI register set
376f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */
377f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patrostatic u32
378f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patromegasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)
379f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{
380f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	return readl(&(regs)->outbound_scratch_pad);
381f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro}
382f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro
383f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/**
384f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_clear_interrupt_ppc -	Check & clear interrupt
385f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs:				MFI register set
386f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */
3870d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic int
388f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patromegasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
389f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{
390f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	u32 status;
391f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	/*
392f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	 * Check if it is our interrupt
393f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	 */
394f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	status = readl(&regs->outbound_intr_status);
395f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro
396f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) {
39739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return 0;
398f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	}
399f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro
400f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	/*
401f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	 * Clear the interrupt by writing back the same value
402f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	 */
403f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	writel(status, &regs->outbound_doorbell_clear);
404f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro
40506f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo	/* Dummy readl to force pci flush */
40606f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo	readl(&regs->outbound_doorbell_clear);
40706f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo
40839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return 1;
409f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro}
410f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/**
411f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_fire_cmd_ppc -	Sends command to the FW
412f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @frame_phys_addr :		Physical address of cmd
413f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @frame_count :		Number of frames for the command
414f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs :			MFI register set
415f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */
4160d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic inline void
4170c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_ppc(struct megasas_instance *instance,
4180c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		dma_addr_t frame_phys_addr,
4190c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		u32 frame_count,
4200c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		struct megasas_register_set __iomem *regs)
421f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{
42239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
42339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->hba_lock, flags);
4240d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford	writel((frame_phys_addr | (frame_count<<1))|1,
425f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro			&(regs)->inbound_queue_port);
42639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->hba_lock, flags);
427f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro}
428f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro
42939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/**
43039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_adp_reset_ppc -	For controller reset
43139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs:				MFI register set
43239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */
43339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int
43439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_adp_reset_ppc(struct megasas_instance *instance,
43539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			struct megasas_register_set __iomem *regs)
43639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
43739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return 0;
43839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
43939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
44039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/**
44139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_ppc -	For controller reset check
44239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs:				MFI register set
44339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */
44439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int
44539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_ppc(struct megasas_instance *instance,
44639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			struct megasas_register_set __iomem *regs)
44739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
44839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return 0;
44939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
450f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patrostatic struct megasas_instance_template megasas_instance_template_ppc = {
4510d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford
452f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	.fire_cmd = megasas_fire_cmd_ppc,
453f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	.enable_intr = megasas_enable_intr_ppc,
454b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	.disable_intr = megasas_disable_intr_ppc,
455f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	.clear_intr = megasas_clear_intr_ppc,
456f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	.read_fw_status_reg = megasas_read_fw_status_reg_ppc,
45739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	.adp_reset = megasas_adp_reset_ppc,
45839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	.check_reset = megasas_check_reset_ppc,
459f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro};
460f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro
461f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/**
462879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_enable_intr_skinny -	Enables interrupts
463879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs:			MFI register set
464879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */
465879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic inline void
466879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
467879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{
468879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
469879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
470879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
471879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
472879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	/* Dummy readl to force pci flush */
473879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	readl(&regs->outbound_intr_mask);
474879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo}
475879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
476879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/**
477879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_disable_intr_skinny -	Disables interrupt
478879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs:			MFI register set
479879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */
480879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic inline void
481879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_disable_intr_skinny(struct megasas_register_set __iomem *regs)
482879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{
483879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	u32 mask = 0xFFFFFFFF;
484879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	writel(mask, &regs->outbound_intr_mask);
485879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	/* Dummy readl to force pci flush */
486879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	readl(&regs->outbound_intr_mask);
487879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo}
488879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
489879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/**
490879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_read_fw_status_reg_skinny - returns the current FW status value
491879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs:			MFI register set
492879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */
493879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic u32
494879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
495879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{
496879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	return readl(&(regs)->outbound_scratch_pad);
497879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo}
498879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
499879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/**
500879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_clear_interrupt_skinny -	Check & clear interrupt
501879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs:				MFI register set
502879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */
503879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic int
504879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
505879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{
506879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	u32 status;
507879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	/*
508879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	 * Check if it is our interrupt
509879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	 */
510879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	status = readl(&regs->outbound_intr_status);
511879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
512879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
51339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return 0;
514879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	}
515879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
516879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	/*
517879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	 * Clear the interrupt by writing back the same value
518879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	 */
519879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	writel(status, &regs->outbound_intr_status);
520879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
521879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	/*
522879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	* dummy read to flush PCI
523879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	*/
524879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	readl(&regs->outbound_intr_status);
525879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
52639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return 1;
527879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo}
528879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
529879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/**
530879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_fire_cmd_skinny -	Sends command to the FW
531879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @frame_phys_addr :		Physical address of cmd
532879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @frame_count :		Number of frames for the command
533879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs :			MFI register set
534879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */
535879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic inline void
5360c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_skinny(struct megasas_instance *instance,
5370c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			dma_addr_t frame_phys_addr,
5380c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			u32 frame_count,
539879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo			struct megasas_register_set __iomem *regs)
540879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{
5410c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	unsigned long flags;
54239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->hba_lock, flags);
543879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	writel(0, &(regs)->inbound_high_queue_port);
544879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	writel((frame_phys_addr | (frame_count<<1))|1,
545879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo		&(regs)->inbound_low_queue_port);
54639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->hba_lock, flags);
54739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
54839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
54939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/**
55039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_adp_reset_skinny -	For controller reset
55139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs:				MFI register set
55239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */
55339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int
55439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_adp_reset_skinny(struct megasas_instance *instance,
55539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			struct megasas_register_set __iomem *regs)
55639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
55739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return 0;
55839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
55939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
56039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/**
56139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_skinny -	For controller reset check
56239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs:				MFI register set
56339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */
56439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int
56539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_skinny(struct megasas_instance *instance,
56639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				struct megasas_register_set __iomem *regs)
56739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
56839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return 0;
569879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo}
570879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
571879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic struct megasas_instance_template megasas_instance_template_skinny = {
572879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
573879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	.fire_cmd = megasas_fire_cmd_skinny,
574879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	.enable_intr = megasas_enable_intr_skinny,
575879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	.disable_intr = megasas_disable_intr_skinny,
576879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	.clear_intr = megasas_clear_intr_skinny,
577879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo	.read_fw_status_reg = megasas_read_fw_status_reg_skinny,
57839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	.adp_reset = megasas_adp_reset_skinny,
57939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	.check_reset = megasas_check_reset_skinny,
580879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo};
581879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
582879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
583879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/**
5846610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo*	The following functions are defined for gen2 (deviceid : 0x78 0x79)
5856610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo*	controllers
5866610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo*/
5876610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
5886610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/**
5896610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_enable_intr_gen2 -  Enables interrupts
5906610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs:                      MFI register set
5916610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */
5926610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic inline void
5936610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_enable_intr_gen2(struct megasas_register_set __iomem *regs)
5946610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{
5956610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
5966610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
5976610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	/* write ~0x00000005 (4 & 1) to the intr mask*/
5986610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
5996610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
6006610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	/* Dummy readl to force pci flush */
6016610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	readl(&regs->outbound_intr_mask);
6026610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo}
6036610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
6046610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/**
6056610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_disable_intr_gen2 - Disables interrupt
6066610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs:                      MFI register set
6076610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */
6086610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic inline void
6096610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_disable_intr_gen2(struct megasas_register_set __iomem *regs)
6106610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{
6116610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	u32 mask = 0xFFFFFFFF;
6126610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	writel(mask, &regs->outbound_intr_mask);
6136610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	/* Dummy readl to force pci flush */
6146610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	readl(&regs->outbound_intr_mask);
6156610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo}
6166610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
6176610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/**
6186610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_read_fw_status_reg_gen2 - returns the current FW status value
6196610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs:                      MFI register set
6206610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */
6216610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic u32
6226610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs)
6236610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{
6246610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	return readl(&(regs)->outbound_scratch_pad);
6256610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo}
6266610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
6276610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/**
6286610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_clear_interrupt_gen2 -      Check & clear interrupt
6296610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs:                              MFI register set
6306610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */
6316610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic int
6326610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
6336610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{
6346610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	u32 status;
63539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 mfiStatus = 0;
6366610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	/*
6376610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	 * Check if it is our interrupt
6386610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	 */
6396610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	status = readl(&regs->outbound_intr_status);
6406610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
64139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (status & MFI_GEN2_ENABLE_INTERRUPT_MASK) {
64239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
64339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
64439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) {
64539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
64639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
6476610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
6486610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	/*
6496610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	 * Clear the interrupt by writing back the same value
6506610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	 */
65139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (mfiStatus)
65239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		writel(status, &regs->outbound_doorbell_clear);
6536610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
6546610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	/* Dummy readl to force pci flush */
6556610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	readl(&regs->outbound_intr_status);
6566610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
65739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return mfiStatus;
6586610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo}
6596610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/**
6606610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_fire_cmd_gen2 -     Sends command to the FW
6616610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @frame_phys_addr :          Physical address of cmd
6626610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @frame_count :              Number of frames for the command
6636610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs :                     MFI register set
6646610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */
6656610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic inline void
6660c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_gen2(struct megasas_instance *instance,
6670c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			dma_addr_t frame_phys_addr,
6680c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			u32 frame_count,
6696610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo			struct megasas_register_set __iomem *regs)
6706610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{
67139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
67239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->hba_lock, flags);
6736610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	writel((frame_phys_addr | (frame_count<<1))|1,
6746610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo			&(regs)->inbound_queue_port);
67539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->hba_lock, flags);
67639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
67739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
67839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/**
67939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_adp_reset_gen2 -	For controller reset
68039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs:				MFI register set
68139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */
68239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int
68339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_adp_reset_gen2(struct megasas_instance *instance,
68439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			struct megasas_register_set __iomem *reg_set)
68539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
68639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32			retry = 0 ;
68739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32			HostDiag;
68839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
68939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	writel(0, &reg_set->seq_offset);
69039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	writel(4, &reg_set->seq_offset);
69139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	writel(0xb, &reg_set->seq_offset);
69239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	writel(2, &reg_set->seq_offset);
69339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	writel(7, &reg_set->seq_offset);
69439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	writel(0xd, &reg_set->seq_offset);
69539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	msleep(1000);
69639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
69739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	HostDiag = (u32)readl(&reg_set->host_diag);
69839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
69939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	while ( !( HostDiag & DIAG_WRITE_ENABLE) ) {
70039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		msleep(100);
70139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		HostDiag = (u32)readl(&reg_set->host_diag);
70239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n",
70339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					retry, HostDiag);
70439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
70539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (retry++ >= 100)
70639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			return 1;
70739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
70839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
70939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
71039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag);
71139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
71239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	writel((HostDiag | DIAG_RESET_ADAPTER), &reg_set->host_diag);
71339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
71439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	ssleep(10);
71539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
71639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	HostDiag = (u32)readl(&reg_set->host_diag);
71739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	while ( ( HostDiag & DIAG_RESET_ADAPTER) ) {
71839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		msleep(100);
71939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		HostDiag = (u32)readl(&reg_set->host_diag);
72039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n",
72139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				retry, HostDiag);
72239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
72339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (retry++ >= 1000)
72439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			return 1;
72539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
72639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
72739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return 0;
72839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
72939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
73039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/**
73139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_gen2 -	For controller reset check
73239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs:				MFI register set
73339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */
73439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int
73539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_gen2(struct megasas_instance *instance,
73639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		struct megasas_register_set __iomem *regs)
73739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
738707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
739707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo		return 1;
740707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	}
741707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo
74239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return 0;
7436610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo}
7446610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
7456610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic struct megasas_instance_template megasas_instance_template_gen2 = {
7466610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
7476610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	.fire_cmd = megasas_fire_cmd_gen2,
7486610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	.enable_intr = megasas_enable_intr_gen2,
7496610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	.disable_intr = megasas_disable_intr_gen2,
7506610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	.clear_intr = megasas_clear_intr_gen2,
7516610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	.read_fw_status_reg = megasas_read_fw_status_reg_gen2,
75239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	.adp_reset = megasas_adp_reset_gen2,
75339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	.check_reset = megasas_check_reset_gen2,
7546610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo};
7556610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo
7566610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/**
757f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro*	This is the end of set of functions & definitions
75839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang*       specific to gen2 (deviceid : 0x78, 0x79) controllers
759f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro*/
760f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro
761f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/**
762c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_issue_polled -	Issues a polling command
763c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
7640d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * @cmd:			Command packet to be issued
765c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
766c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * For polling, MFI requires the cmd_status to be set to 0xFF before posting.
767c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
768c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int
769c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
770c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
771c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
772c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 msecs = MFI_POLL_TIMEOUT_SECS * 1000;
773c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
774c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_header *frame_hdr = &cmd->frame->hdr;
775c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
776c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	frame_hdr->cmd_status = 0xFF;
777c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
778c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
779c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Issue the frame using inbound queue port
781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
7820c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	instance->instancet->fire_cmd(instance,
7830c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			cmd->frame_phys_addr, 0, instance->reg_set);
784c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
785c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
786c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Wait for cmd_status to change
787c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
788c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; (i < msecs) && (frame_hdr->cmd_status == 0xff); i++) {
789c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		rmb();
790c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		msleep(1);
791c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
792c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
793c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (frame_hdr->cmd_status == 0xff)
794c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ETIME;
795c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
797c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
798c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
799c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
800c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_issue_blocked_cmd -	Synchronous wrapper around regular FW cmds
801c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
802c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd:			Command to be issued
803c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
804c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function waits on an event for the command to be returned from ISR.
8052a3681e56e825bce469d2ccf3c85741b5005e1f1Sumant Patro * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
806c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Used to issue ioctl commands.
807c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
808c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int
809c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_issue_blocked_cmd(struct megasas_instance *instance,
810c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			  struct megasas_cmd *cmd)
811c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
812c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd->cmd_status = ENODATA;
813c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
8140c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	instance->instancet->fire_cmd(instance,
8150c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			cmd->frame_phys_addr, 0, instance->reg_set);
816c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
81739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	wait_event(instance->int_cmd_wait_q, cmd->cmd_status != ENODATA);
818c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
819c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
820c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
821c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
822c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
823c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_issue_blocked_abort_cmd -	Aborts previously issued cmd
824c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:				Adapter soft state
825c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd_to_abort:			Previously issued cmd to be aborted
826c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
827c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * MFI firmware can abort previously issued AEN comamnd (automatic event
828c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * notification). The megasas_issue_blocked_abort_cmd() issues such abort
8292a3681e56e825bce469d2ccf3c85741b5005e1f1Sumant Patro * cmd and waits for return status.
8302a3681e56e825bce469d2ccf3c85741b5005e1f1Sumant Patro * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
831c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
832c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int
833c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
834c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				struct megasas_cmd *cmd_to_abort)
835c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
836c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
837c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_abort_frame *abort_fr;
838c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
839c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd = megasas_get_cmd(instance);
840c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
841c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!cmd)
842c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -1;
843c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
844c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	abort_fr = &cmd->frame->abort;
845c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
846c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
847c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Prepare and issue the abort frame
848c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
849c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	abort_fr->cmd = MFI_CMD_ABORT;
850c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	abort_fr->cmd_status = 0xFF;
851c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	abort_fr->flags = 0;
852c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	abort_fr->abort_context = cmd_to_abort->index;
853c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	abort_fr->abort_mfi_phys_addr_lo = cmd_to_abort->frame_phys_addr;
854c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	abort_fr->abort_mfi_phys_addr_hi = 0;
855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
856c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd->sync_cmd = 1;
857c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd->cmd_status = 0xFF;
858c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
8590c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	instance->instancet->fire_cmd(instance,
8600c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			cmd->frame_phys_addr, 0, instance->reg_set);
861c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
862c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
863c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Wait for this cmd to complete
864c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
86539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	wait_event(instance->abort_cmd_wait_q, cmd->cmd_status != 0xFF);
86639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	cmd->sync_cmd = 0;
867c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
868c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_return_cmd(instance, cmd);
869c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
870c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
871c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
872c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
873c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_make_sgl32 -	Prepares 32-bit SGL
874c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
875c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp:		SCSI command from the mid-layer
876c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @mfi_sgl:		SGL to be filled in
877c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
878c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * If successful, this function returns the number of SG elements. Otherwise,
879c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * it returnes -1.
880c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
881858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int
882c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp,
883c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		   union megasas_sgl *mfi_sgl)
884c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
885c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
886c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int sge_count;
887c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct scatterlist *os_sgl;
888c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
889155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori	sge_count = scsi_dma_map(scp);
890155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori	BUG_ON(sge_count < 0);
891c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
892155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori	if (sge_count) {
893155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori		scsi_for_each_sg(scp, os_sgl, sge_count, i) {
894155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori			mfi_sgl->sge32[i].length = sg_dma_len(os_sgl);
895155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori			mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl);
896155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori		}
897c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
898c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return sge_count;
899c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
900c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
901c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
902c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_make_sgl64 -	Prepares 64-bit SGL
903c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
904c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp:		SCSI command from the mid-layer
905c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @mfi_sgl:		SGL to be filled in
906c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
907c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * If successful, this function returns the number of SG elements. Otherwise,
908c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * it returnes -1.
909c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
910858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int
911c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
912c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		   union megasas_sgl *mfi_sgl)
913c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
914c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
915c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int sge_count;
916c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct scatterlist *os_sgl;
917c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
918155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori	sge_count = scsi_dma_map(scp);
919155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori	BUG_ON(sge_count < 0);
920c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
921155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori	if (sge_count) {
922155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori		scsi_for_each_sg(scp, os_sgl, sge_count, i) {
923155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori			mfi_sgl->sge64[i].length = sg_dma_len(os_sgl);
924155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori			mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl);
925155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori		}
926c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
927c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return sge_count;
928c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
929c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
930f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo/**
931f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * megasas_make_sgl_skinny - Prepares IEEE SGL
932f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * @instance:           Adapter soft state
933f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * @scp:                SCSI command from the mid-layer
934f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * @mfi_sgl:            SGL to be filled in
935f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo *
936f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * If successful, this function returns the number of SG elements. Otherwise,
937f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * it returnes -1.
938f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo */
939f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bostatic int
940f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bomegasas_make_sgl_skinny(struct megasas_instance *instance,
941f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
942f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo{
943f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	int i;
944f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	int sge_count;
945f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	struct scatterlist *os_sgl;
946f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo
947f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	sge_count = scsi_dma_map(scp);
948f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo
949f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	if (sge_count) {
950f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		scsi_for_each_sg(scp, os_sgl, sge_count, i) {
951f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo			mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
952f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo			mfi_sgl->sge_skinny[i].phys_addr =
953f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo						sg_dma_address(os_sgl);
954707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			mfi_sgl->sge_skinny[i].flag = 0;
955f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		}
956f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	}
957f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	return sge_count;
958f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo}
959f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo
960b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro /**
961b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * megasas_get_frame_count - Computes the number of frames
962d532dbe2cb71586ab520dbef732d1af54a689313bo yang * @frame_type		: type of frame- io or pthru frame
963b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * @sge_count		: number of sg elements
964b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro *
965b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * Returns the number of frames required for numnber of sge's (sge_count)
966b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro */
967b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro
968f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bostatic u32 megasas_get_frame_count(struct megasas_instance *instance,
969f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo			u8 sge_count, u8 frame_type)
970b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro{
971b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	int num_cnt;
972b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	int sge_bytes;
973b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	u32 sge_sz;
974b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	u32 frame_count=0;
975b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro
976b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
977b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	    sizeof(struct megasas_sge32);
978b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro
979f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	if (instance->flag_ieee) {
980f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		sge_sz = sizeof(struct megasas_sge_skinny);
981f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	}
982f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo
983b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	/*
984d532dbe2cb71586ab520dbef732d1af54a689313bo yang	 * Main frame can contain 2 SGEs for 64-bit SGLs and
985d532dbe2cb71586ab520dbef732d1af54a689313bo yang	 * 3 SGEs for 32-bit SGLs for ldio &
986d532dbe2cb71586ab520dbef732d1af54a689313bo yang	 * 1 SGEs for 64-bit SGLs and
987d532dbe2cb71586ab520dbef732d1af54a689313bo yang	 * 2 SGEs for 32-bit SGLs for pthru frame
988d532dbe2cb71586ab520dbef732d1af54a689313bo yang	 */
989d532dbe2cb71586ab520dbef732d1af54a689313bo yang	if (unlikely(frame_type == PTHRU_FRAME)) {
990f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		if (instance->flag_ieee == 1) {
991f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo			num_cnt = sge_count - 1;
992f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		} else if (IS_DMA64)
993d532dbe2cb71586ab520dbef732d1af54a689313bo yang			num_cnt = sge_count - 1;
994d532dbe2cb71586ab520dbef732d1af54a689313bo yang		else
995d532dbe2cb71586ab520dbef732d1af54a689313bo yang			num_cnt = sge_count - 2;
996d532dbe2cb71586ab520dbef732d1af54a689313bo yang	} else {
997f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		if (instance->flag_ieee == 1) {
998f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo			num_cnt = sge_count - 1;
999f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		} else if (IS_DMA64)
1000d532dbe2cb71586ab520dbef732d1af54a689313bo yang			num_cnt = sge_count - 2;
1001d532dbe2cb71586ab520dbef732d1af54a689313bo yang		else
1002d532dbe2cb71586ab520dbef732d1af54a689313bo yang			num_cnt = sge_count - 3;
1003d532dbe2cb71586ab520dbef732d1af54a689313bo yang	}
1004b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro
1005b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	if(num_cnt>0){
1006b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro		sge_bytes = sge_sz * num_cnt;
1007b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro
1008b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro		frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
1009b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro		    ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ;
1010b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	}
1011b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	/* Main frame */
1012b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	frame_count +=1;
1013b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro
1014b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	if (frame_count > 7)
1015b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro		frame_count = 8;
1016b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	return frame_count;
1017b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro}
1018b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro
1019c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
1020c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_build_dcdb -	Prepares a direct cdb (DCDB) command
1021c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
1022c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp:		SCSI command
1023c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd:		Command to be prepared in
1024c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
1025c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function prepares CDB commands. These are typcially pass-through
1026c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * commands to the devices.
1027c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1028858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int
1029c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
1030c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		   struct megasas_cmd *cmd)
1031c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
1032c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 is_logical;
1033c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 device_id;
1034c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u16 flags = 0;
1035c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_pthru_frame *pthru;
1036c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1037c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	is_logical = MEGASAS_IS_LOGICAL(scp);
1038c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	device_id = MEGASAS_DEV_INDEX(instance, scp);
1039c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru = (struct megasas_pthru_frame *)cmd->frame;
1040c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1041c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (scp->sc_data_direction == PCI_DMA_TODEVICE)
1042c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		flags = MFI_FRAME_DIR_WRITE;
1043c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
1044c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		flags = MFI_FRAME_DIR_READ;
1045c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	else if (scp->sc_data_direction == PCI_DMA_NONE)
1046c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		flags = MFI_FRAME_DIR_NONE;
1047c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1048f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	if (instance->flag_ieee == 1) {
1049f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		flags |= MFI_FRAME_IEEE;
1050f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	}
1051f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo
1052c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1053c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Prepare the DCDB frame
1054c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1055c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO;
1056c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->cmd_status = 0x0;
1057c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->scsi_status = 0x0;
1058c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->target_id = device_id;
1059c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->lun = scp->device->lun;
1060c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->cdb_len = scp->cmd_len;
1061c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->timeout = 0;
1062780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo	pthru->pad_0 = 0;
1063c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->flags = flags;
1064155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori	pthru->data_xfer_len = scsi_bufflen(scp);
1065c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1066c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
1067c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1068c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
10698d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo	* If the command is for the tape device, set the
10708d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo	* pthru timeout to the os layer timeout value.
10718d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo	*/
10728d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo	if (scp->device->type == TYPE_TAPE) {
10738d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo		if ((scp->request->timeout / HZ) > 0xFFFF)
10748d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo			pthru->timeout = 0xFFFF;
10758d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo		else
10768d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo			pthru->timeout = scp->request->timeout / HZ;
10778d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo	}
10788d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo
10798d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo	/*
1080c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Construct SGL
1081c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1082f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	if (instance->flag_ieee == 1) {
1083f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		pthru->flags |= MFI_FRAME_SGL64;
1084f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
1085f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo						      &pthru->sgl);
1086f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	} else if (IS_DMA64) {
1087c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		pthru->flags |= MFI_FRAME_SGL64;
1088c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		pthru->sge_count = megasas_make_sgl64(instance, scp,
1089c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						      &pthru->sgl);
1090c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	} else
1091c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		pthru->sge_count = megasas_make_sgl32(instance, scp,
1092c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						      &pthru->sgl);
1093c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1094bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	if (pthru->sge_count > instance->max_num_sge) {
1095bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		printk(KERN_ERR "megasas: DCDB two many SGE NUM=%x\n",
1096bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo			pthru->sge_count);
1097bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		return 0;
1098bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	}
1099bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
1100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1101c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Sense info specific
1102c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1103c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->sense_len = SCSI_SENSE_BUFFERSIZE;
1104c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->sense_buf_phys_addr_hi = 0;
1105c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
1106c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1107c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1108c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Compute the total number of frames this command consumes. FW uses
1109c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * this number to pull sufficient number of frames from host memory.
1110c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1111f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
1112d532dbe2cb71586ab520dbef732d1af54a689313bo yang							PTHRU_FRAME);
1113c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1114c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return cmd->frame_count;
1115c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
1116c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1117c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
1118c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_build_ldio -	Prepares IOs to logical devices
1119c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
1120c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp:		SCSI command
1121fd589a8f0a13f53a2dd580b1fe170633cf6b095fAnand Gadiyar * @cmd:		Command to be prepared
1122c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
1123c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Frames (and accompanying SGLs) for regular SCSI IOs use this function.
1124c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1125858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int
1126c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
1127c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		   struct megasas_cmd *cmd)
1128c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
1129c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 device_id;
1130c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u8 sc = scp->cmnd[0];
1131c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u16 flags = 0;
1132c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_io_frame *ldio;
1133c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1134c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	device_id = MEGASAS_DEV_INDEX(instance, scp);
1135c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio = (struct megasas_io_frame *)cmd->frame;
1136c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1137c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (scp->sc_data_direction == PCI_DMA_TODEVICE)
1138c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		flags = MFI_FRAME_DIR_WRITE;
1139c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
1140c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		flags = MFI_FRAME_DIR_READ;
1141c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1142f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	if (instance->flag_ieee == 1) {
1143f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		flags |= MFI_FRAME_IEEE;
1144f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	}
1145f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo
1146c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1147b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
1148c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1149c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ;
1150c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->cmd_status = 0x0;
1151c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->scsi_status = 0x0;
1152c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->target_id = device_id;
1153c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->timeout = 0;
1154c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->reserved_0 = 0;
1155c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->pad_0 = 0;
1156c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->flags = flags;
1157c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->start_lba_hi = 0;
1158c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->access_byte = (scp->cmd_len != 6) ? scp->cmnd[1] : 0;
1159c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1160c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1161c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * 6-byte READ(0x08) or WRITE(0x0A) cdb
1162c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1163c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (scp->cmd_len == 6) {
1164c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->lba_count = (u32) scp->cmnd[4];
1165c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->start_lba_lo = ((u32) scp->cmnd[1] << 16) |
1166c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3];
1167c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1168c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->start_lba_lo &= 0x1FFFFF;
1169c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
1170c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1171c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1172c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * 10-byte READ(0x28) or WRITE(0x2A) cdb
1173c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1174c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	else if (scp->cmd_len == 10) {
1175c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->lba_count = (u32) scp->cmnd[8] |
1176c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[7] << 8);
1177c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) |
1178c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[3] << 16) |
1179c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
1180c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
1181c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1182c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1183c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
1184c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1185c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	else if (scp->cmd_len == 12) {
1186c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->lba_count = ((u32) scp->cmnd[6] << 24) |
1187c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[7] << 16) |
1188c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
1189c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) |
1191c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[3] << 16) |
1192c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
1193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
1194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * 16-byte READ(0x88) or WRITE(0x8A) cdb
1197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	else if (scp->cmd_len == 16) {
1199c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->lba_count = ((u32) scp->cmnd[10] << 24) |
1200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[11] << 16) |
1201c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13];
1202c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->start_lba_lo = ((u32) scp->cmnd[6] << 24) |
1204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[7] << 16) |
1205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
1206c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1207c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->start_lba_hi = ((u32) scp->cmnd[2] << 24) |
1208c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[3] << 16) |
1209c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
1210c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1211c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
1212c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1213c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1214c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Construct SGL
1215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1216f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	if (instance->flag_ieee) {
1217f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		ldio->flags |= MFI_FRAME_SGL64;
1218f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
1219f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo					      &ldio->sgl);
1220f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	} else if (IS_DMA64) {
1221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->flags |= MFI_FRAME_SGL64;
1222c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
1223c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	} else
1224c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
1225c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1226bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	if (ldio->sge_count > instance->max_num_sge) {
1227bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		printk(KERN_ERR "megasas: build_ld_io: sge_count = %x\n",
1228bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo			ldio->sge_count);
1229bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		return 0;
1230bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	}
1231bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
1232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Sense info specific
1234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1235c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->sense_len = SCSI_SENSE_BUFFERSIZE;
1236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->sense_buf_phys_addr_hi = 0;
1237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
1238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1239b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	/*
1240b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	 * Compute the total number of frames this command consumes. FW uses
1241b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	 * this number to pull sufficient number of frames from host memory.
1242b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro	 */
1243f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	cmd->frame_count = megasas_get_frame_count(instance,
1244f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo			ldio->sge_count, IO_FRAME);
1245c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1246c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return cmd->frame_count;
1247c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
1248c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1249c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
1250cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro * megasas_is_ldio -		Checks if the cmd is for logical drive
1251cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro * @scmd:			SCSI command
12520d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford *
1253cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro * Called by megasas_queue_command to find out if the command to be queued
12540d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * is a logical drive command
1255c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1256cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patrostatic inline int megasas_is_ldio(struct scsi_cmnd *cmd)
1257c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
1258cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	if (!MEGASAS_IS_LOGICAL(cmd))
1259cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro		return 0;
1260cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	switch (cmd->cmnd[0]) {
1261cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	case READ_10:
1262cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	case WRITE_10:
1263cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	case READ_12:
1264cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	case WRITE_12:
1265cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	case READ_6:
1266cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	case WRITE_6:
1267cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	case READ_16:
1268cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	case WRITE_16:
1269cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro		return 1;
1270cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	default:
1271cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro		return 0;
1272c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
1273c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
1274c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1275658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro /**
1276658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro * megasas_dump_pending_frames -	Dumps the frame address of all pending cmds
1277658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro *                              	in FW
1278658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro * @instance:				Adapter soft state
1279658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro */
1280658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patrostatic inline void
1281658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patromegasas_dump_pending_frames(struct megasas_instance *instance)
1282658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro{
1283658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	struct megasas_cmd *cmd;
1284658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	int i,n;
1285658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	union megasas_sgl *mfi_sgl;
1286658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	struct megasas_io_frame *ldio;
1287658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	struct megasas_pthru_frame *pthru;
1288658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	u32 sgcount;
1289658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	u32 max_cmd = instance->max_fw_cmds;
1290658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro
1291658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
1292658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding));
1293658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	if (IS_DMA64)
1294658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no);
1295658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	else
1296658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);
1297658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro
1298658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
1299658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	for (i = 0; i < max_cmd; i++) {
1300658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		cmd = instance->cmd_list[i];
1301658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		if(!cmd->scmd)
1302658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			continue;
1303658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
1304658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		if (megasas_is_ldio(cmd->scmd)){
1305658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			ldio = (struct megasas_io_frame *)cmd->frame;
1306658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			mfi_sgl = &ldio->sgl;
1307658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			sgcount = ldio->sge_count;
1308658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			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);
1309658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		}
1310658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		else {
1311658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			pthru = (struct megasas_pthru_frame *) cmd->frame;
1312658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			mfi_sgl = &pthru->sgl;
1313658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			sgcount = pthru->sge_count;
1314658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			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);
1315658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		}
1316658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	if(megasas_dbg_lvl & MEGASAS_DBG_LVL){
1317658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		for (n = 0; n < sgcount; n++){
1318658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			if (IS_DMA64)
1319658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro				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) ;
1320658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			else
1321658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro				printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",mfi_sgl->sge32[n].length , mfi_sgl->sge32[n].phys_addr) ;
1322658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			}
1323658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		}
1324658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		printk(KERN_ERR "\n");
1325658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	} /*for max_cmd*/
1326658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
1327658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	for (i = 0; i < max_cmd; i++) {
1328658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro
1329658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		cmd = instance->cmd_list[i];
1330658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro
1331658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		if(cmd->sync_cmd == 1){
1332658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
1333658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		}
1334658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	}
1335658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
1336658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro}
1337658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro
1338c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
1339c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_queue_command -	Queue entry point
1340c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scmd:			SCSI command to be queued
1341c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @done:			Callback entry point
1342c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1343c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int
1344f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzikmegasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
1345c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
1346c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 frame_count;
1347c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
1348c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_instance *instance;
134939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
1350c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1351c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance = (struct megasas_instance *)
1352c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    scmd->device->host->hostdata;
1353af37acfb63d8e924550e67b884dbd1c478e26c96Sumant Patro
135439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->issuepend_done == 0)
1355af37acfb63d8e924550e67b884dbd1c478e26c96Sumant Patro		return SCSI_MLQUEUE_HOST_BUSY;
1356af37acfb63d8e924550e67b884dbd1c478e26c96Sumant Patro
135739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->hba_lock, flags);
135839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
135939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_unlock_irqrestore(&instance->hba_lock, flags);
136039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return SCSI_MLQUEUE_HOST_BUSY;
136139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
136239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
136339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->hba_lock, flags);
136439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
1365c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	scmd->scsi_done = done;
1366c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	scmd->result = 0;
1367c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1368cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	if (MEGASAS_IS_LOGICAL(scmd) &&
1369cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	    (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) {
1370cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro		scmd->result = DID_BAD_TARGET << 16;
1371cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro		goto out_done;
1372c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
1373c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
137402b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro	switch (scmd->cmnd[0]) {
137502b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro	case SYNCHRONIZE_CACHE:
137602b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro		/*
137702b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro		 * FW takes care of flush cache on its own
137802b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro		 * No need to send it down
137902b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro		 */
138002b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro		scmd->result = DID_OK << 16;
138102b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro		goto out_done;
138202b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro	default:
138302b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro		break;
138402b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro	}
138502b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro
1386cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	cmd = megasas_get_cmd(instance);
1387cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	if (!cmd)
1388cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro		return SCSI_MLQUEUE_HOST_BUSY;
1389cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro
1390cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	/*
1391cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	 * Logical drive command
1392cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	 */
1393cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	if (megasas_is_ldio(scmd))
1394cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro		frame_count = megasas_build_ldio(instance, scmd, cmd);
1395cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	else
1396cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro		frame_count = megasas_build_dcdb(instance, scmd, cmd);
1397cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro
1398cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	if (!frame_count)
1399cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro		goto out_return_cmd;
1400cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro
1401c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd->scmd = scmd;
140205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	scmd->SCp.ptr = (char *)cmd;
1403c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1404c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1405c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Issue the command to the FW
1406c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1407e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro	atomic_inc(&instance->fw_outstanding);
1408c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
14090c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
14100c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo				cmd->frame_count-1, instance->reg_set);
1411ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	/*
1412ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	 * Check if we have pend cmds to be completed
1413ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	 */
1414ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if (poll_mode_io && atomic_read(&instance->fw_outstanding))
1415ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		tasklet_schedule(&instance->isr_tasklet);
1416ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
1417c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1418c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
1419cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro
1420cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro out_return_cmd:
1421cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	megasas_return_cmd(instance, cmd);
1422cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro out_done:
1423cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	done(scmd);
1424cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	return 0;
1425c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
1426c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1427f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzikstatic DEF_SCSI_QCMD(megasas_queue_command)
1428f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzik
1429044833b572b96afe91506a0edec42efd84ba4939Yang, Bostatic struct megasas_instance *megasas_lookup_instance(u16 host_no)
1430044833b572b96afe91506a0edec42efd84ba4939Yang, Bo{
1431044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	int i;
1432044833b572b96afe91506a0edec42efd84ba4939Yang, Bo
1433044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	for (i = 0; i < megasas_mgmt_info.max_index; i++) {
1434044833b572b96afe91506a0edec42efd84ba4939Yang, Bo
1435044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		if ((megasas_mgmt_info.instance[i]) &&
1436044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		    (megasas_mgmt_info.instance[i]->host->host_no == host_no))
1437044833b572b96afe91506a0edec42efd84ba4939Yang, Bo			return megasas_mgmt_info.instance[i];
1438044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	}
1439044833b572b96afe91506a0edec42efd84ba4939Yang, Bo
1440044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	return NULL;
1441044833b572b96afe91506a0edec42efd84ba4939Yang, Bo}
1442044833b572b96afe91506a0edec42efd84ba4939Yang, Bo
1443147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwigstatic int megasas_slave_configure(struct scsi_device *sdev)
1444147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig{
1445044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	u16             pd_index = 0;
1446044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	struct  megasas_instance *instance ;
1447044833b572b96afe91506a0edec42efd84ba4939Yang, Bo
1448044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	instance = megasas_lookup_instance(sdev->host->host_no);
1449044833b572b96afe91506a0edec42efd84ba4939Yang, Bo
1450147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig	/*
1451044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	* Don't export physical disk devices to the disk driver.
1452044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	*
1453044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	* FIXME: Currently we don't export them to the midlayer at all.
1454044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	*        That will be fixed once LSI engineers have audited the
1455044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	*        firmware for possible issues.
1456044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	*/
1457044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
1458044833b572b96afe91506a0edec42efd84ba4939Yang, Bo				sdev->type == TYPE_DISK) {
1459044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
1460044833b572b96afe91506a0edec42efd84ba4939Yang, Bo								sdev->id;
1461044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		if (instance->pd_list[pd_index].driveState ==
1462044833b572b96afe91506a0edec42efd84ba4939Yang, Bo						MR_PD_STATE_SYSTEM) {
1463044833b572b96afe91506a0edec42efd84ba4939Yang, Bo			blk_queue_rq_timeout(sdev->request_queue,
1464044833b572b96afe91506a0edec42efd84ba4939Yang, Bo				MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1465044833b572b96afe91506a0edec42efd84ba4939Yang, Bo			return 0;
1466044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		}
1467147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig		return -ENXIO;
1468044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	}
1469e5b3a65fd7244e662691cf617145983ecde28cc9Christoph Hellwig
1470e5b3a65fd7244e662691cf617145983ecde28cc9Christoph Hellwig	/*
1471044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	* The RAID firmware may require extended timeouts.
1472044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	*/
1473044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	blk_queue_rq_timeout(sdev->request_queue,
1474044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1475044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	return 0;
1476044833b572b96afe91506a0edec42efd84ba4939Yang, Bo}
1477044833b572b96afe91506a0edec42efd84ba4939Yang, Bo
1478044833b572b96afe91506a0edec42efd84ba4939Yang, Bostatic int megasas_slave_alloc(struct scsi_device *sdev)
1479044833b572b96afe91506a0edec42efd84ba4939Yang, Bo{
1480044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	u16             pd_index = 0;
1481044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	struct megasas_instance *instance ;
1482044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	instance = megasas_lookup_instance(sdev->host->host_no);
1483044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
1484044833b572b96afe91506a0edec42efd84ba4939Yang, Bo				(sdev->type == TYPE_DISK)) {
1485044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		/*
1486044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		 * Open the OS scan to the SYSTEM PD
1487044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		 */
1488044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		pd_index =
1489044833b572b96afe91506a0edec42efd84ba4939Yang, Bo			(sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
1490044833b572b96afe91506a0edec42efd84ba4939Yang, Bo			sdev->id;
1491044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		if ((instance->pd_list[pd_index].driveState ==
1492044833b572b96afe91506a0edec42efd84ba4939Yang, Bo					MR_PD_STATE_SYSTEM) &&
1493044833b572b96afe91506a0edec42efd84ba4939Yang, Bo			(instance->pd_list[pd_index].driveType ==
1494044833b572b96afe91506a0edec42efd84ba4939Yang, Bo						TYPE_DISK)) {
1495044833b572b96afe91506a0edec42efd84ba4939Yang, Bo			return 0;
1496044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		}
1497044833b572b96afe91506a0edec42efd84ba4939Yang, Bo		return -ENXIO;
1498044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	}
1499147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig	return 0;
1500147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig}
1501147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig
150239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic void megaraid_sas_kill_hba(struct megasas_instance *instance)
150339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
150439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
150539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
150639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		writel(MFI_STOP_ADP,
150739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			&instance->reg_set->reserved_0[0]);
150839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	} else {
150939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		writel(MFI_STOP_ADP,
151039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			&instance->reg_set->inbound_doorbell);
151139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
151239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
151339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
1514c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
15157343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * megasas_complete_cmd_dpc	 -	Returns FW's controller structure
15167343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * @instance_addr:			Address of adapter soft state
15177343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang *
15187343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * Tasklet to complete cmds
15197343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang */
15207343eb6570ae3b299e7b5185b139d8335ef60e9bbo yangstatic void megasas_complete_cmd_dpc(unsigned long instance_addr)
15217343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang{
15227343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	u32 producer;
15237343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	u32 consumer;
15247343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	u32 context;
15257343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	struct megasas_cmd *cmd;
15267343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	struct megasas_instance *instance =
15277343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang				(struct megasas_instance *)instance_addr;
15287343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	unsigned long flags;
15297343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15307343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	/* If we have already declared adapter dead, donot complete cmds */
153139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR )
15327343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		return;
15337343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15347343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	spin_lock_irqsave(&instance->completion_lock, flags);
15357343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15367343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	producer = *instance->producer;
15377343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	consumer = *instance->consumer;
15387343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15397343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	while (consumer != producer) {
15407343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		context = instance->reply_queue[consumer];
154139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (context >= instance->max_fw_cmds) {
154239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_ERR "Unexpected context value %x\n",
154339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				context);
154439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			BUG();
154539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
15467343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15477343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		cmd = instance->cmd_list[context];
15487343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15497343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		megasas_complete_cmd(instance, cmd, DID_OK);
15507343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15517343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		consumer++;
15527343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		if (consumer == (instance->max_fw_cmds + 1)) {
15537343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang			consumer = 0;
15547343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		}
15557343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	}
15567343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15577343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	*instance->consumer = producer;
15587343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15597343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	spin_unlock_irqrestore(&instance->completion_lock, flags);
15607343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15617343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	/*
15627343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	 * Check if we can restore can_queue
15637343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	 */
15647343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	if (instance->flag & MEGASAS_FW_BUSY
15657343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		&& time_after(jiffies, instance->last_time + 5 * HZ)
15667343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		&& atomic_read(&instance->fw_outstanding) < 17) {
15677343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15687343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		spin_lock_irqsave(instance->host->host_lock, flags);
15697343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		instance->flag &= ~MEGASAS_FW_BUSY;
15707bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo		if ((instance->pdev->device ==
15717bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo			PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
15727bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo			(instance->pdev->device ==
15737bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo			PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
15747bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo			instance->host->can_queue =
15757bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo				instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
15767bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo		} else
15777bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo			instance->host->can_queue =
15787343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang				instance->max_fw_cmds - MEGASAS_INT_CMDS;
15797343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
15807343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang		spin_unlock_irqrestore(instance->host->host_lock, flags);
15817343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	}
15827343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang}
15837343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang
1584707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bostatic void
1585707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bomegasas_internal_reset_defer_cmds(struct megasas_instance *instance);
1586707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo
1587707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bostatic void
1588707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Boprocess_fw_state_change_wq(struct work_struct *work);
1589707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo
1590707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bovoid megasas_do_ocr(struct megasas_instance *instance)
1591707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo{
1592707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
1593707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	(instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
1594707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	(instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
1595707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo		*instance->consumer     = MEGASAS_ADPRESET_INPROG_SIGN;
1596707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	}
1597707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	instance->instancet->disable_intr(instance->reg_set);
1598707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	instance->adprecovery   = MEGASAS_ADPRESET_SM_INFAULT;
1599707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	instance->issuepend_done = 0;
1600707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo
1601707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	atomic_set(&instance->fw_outstanding, 0);
1602707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	megasas_internal_reset_defer_cmds(instance);
1603707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	process_fw_state_change_wq(&instance->work_init);
1604707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo}
1605707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo
16067343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang/**
1607c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_wait_for_outstanding -	Wait for all outstanding cmds
1608c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:				Adapter soft state
1609c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
1610c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function waits for upto MEGASAS_RESET_WAIT_TIME seconds for FW to
1611c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * complete all its outstanding commands. Returns error if one or more IOs
1612c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * are pending after this time period. It also marks the controller dead.
1613c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1614c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_wait_for_outstanding(struct megasas_instance *instance)
1615c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
1616c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
161739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 reset_index;
1618c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 wait_time = MEGASAS_RESET_WAIT_TIME;
161939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u8 adprecovery;
162039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
162139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	struct list_head clist_local;
162239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	struct megasas_cmd *reset_cmd;
1623707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	u32 fw_state;
1624707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	u8 kill_adapter_flag;
162539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
162639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->hba_lock, flags);
162739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	adprecovery = instance->adprecovery;
162839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->hba_lock, flags);
162939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
163039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
163139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
163239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		INIT_LIST_HEAD(&clist_local);
163339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_lock_irqsave(&instance->hba_lock, flags);
163439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		list_splice_init(&instance->internal_reset_pending_q,
163539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				&clist_local);
163639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_unlock_irqrestore(&instance->hba_lock, flags);
163739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
163839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "megasas: HBA reset wait ...\n");
163939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		for (i = 0; i < wait_time; i++) {
164039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			msleep(1000);
164139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			spin_lock_irqsave(&instance->hba_lock, flags);
164239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			adprecovery = instance->adprecovery;
164339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			spin_unlock_irqrestore(&instance->hba_lock, flags);
164439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			if (adprecovery == MEGASAS_HBA_OPERATIONAL)
164539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				break;
164639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
164739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
164839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
164939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megasas: reset: Stopping HBA.\n");
165039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			spin_lock_irqsave(&instance->hba_lock, flags);
165139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			instance->adprecovery	= MEGASAS_HW_CRITICAL_ERROR;
165239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			spin_unlock_irqrestore(&instance->hba_lock, flags);
165339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			return FAILED;
165439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
165539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
165639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		reset_index	= 0;
165739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		while (!list_empty(&clist_local)) {
165839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			reset_cmd	= list_entry((&clist_local)->next,
165939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						struct megasas_cmd, list);
166039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			list_del_init(&reset_cmd->list);
166139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			if (reset_cmd->scmd) {
166239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				reset_cmd->scmd->result = DID_RESET << 16;
166339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				printk(KERN_NOTICE "%d:%p reset [%02x], %#lx\n",
166439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					reset_index, reset_cmd,
166539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					reset_cmd->scmd->cmnd[0],
166639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					reset_cmd->scmd->serial_number);
166739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
166839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				reset_cmd->scmd->scsi_done(reset_cmd->scmd);
166939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				megasas_return_cmd(instance, reset_cmd);
167039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			} else if (reset_cmd->sync_cmd) {
167139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				printk(KERN_NOTICE "megasas:%p synch cmds"
167239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						"reset queue\n",
167339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						reset_cmd);
167439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
167539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				reset_cmd->cmd_status = ENODATA;
167639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				instance->instancet->fire_cmd(instance,
167739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						reset_cmd->frame_phys_addr,
167839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						0, instance->reg_set);
167939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			} else {
168039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				printk(KERN_NOTICE "megasas: %p unexpected"
168139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					"cmds lst\n",
168239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					reset_cmd);
168339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			}
168439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			reset_index++;
168539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
168639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
168739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return SUCCESS;
168839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
1689c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1690c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; i < wait_time; i++) {
1691c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1692e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro		int outstanding = atomic_read(&instance->fw_outstanding);
1693e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro
1694e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro		if (!outstanding)
1695c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
1696c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1697c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
1698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
1699e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro			       "commands to complete\n",i,outstanding);
17007343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang			/*
17017343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang			 * Call cmd completion routine. Cmd to be
17027343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang			 * be completed directly without depending on isr.
17037343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang			 */
17047343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang			megasas_complete_cmd_dpc((unsigned long)instance);
1705c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
1706c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1707c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		msleep(1000);
1708c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
1709c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1710707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	i = 0;
1711707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	kill_adapter_flag = 0;
1712707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	do {
1713707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo		fw_state = instance->instancet->read_fw_status_reg(
1714707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo					instance->reg_set) & MFI_STATE_MASK;
1715707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo		if ((fw_state == MFI_STATE_FAULT) &&
1716707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			(instance->disableOnlineCtrlReset == 0)) {
1717707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			if (i == 3) {
1718707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo				kill_adapter_flag = 2;
1719707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo				break;
1720707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			}
1721707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			megasas_do_ocr(instance);
1722707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			kill_adapter_flag = 1;
1723707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo
1724707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			/* wait for 1 secs to let FW finish the pending cmds */
1725707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			msleep(1000);
1726707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo		}
1727707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo		i++;
1728707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	} while (i <= 3);
1729707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo
1730707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	if (atomic_read(&instance->fw_outstanding) &&
1731707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo					!kill_adapter_flag) {
1732707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo		if (instance->disableOnlineCtrlReset == 0) {
1733707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo
1734707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			megasas_do_ocr(instance);
1735707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo
1736707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			/* wait for 5 secs to let FW finish the pending cmds */
1737707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			for (i = 0; i < wait_time; i++) {
1738707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo				int outstanding =
1739707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo					atomic_read(&instance->fw_outstanding);
1740707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo				if (!outstanding)
1741707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo					return SUCCESS;
1742707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo				msleep(1000);
1743707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo			}
1744707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo		}
1745707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	}
1746707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo
1747707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo	if (atomic_read(&instance->fw_outstanding) ||
1748707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo					(kill_adapter_flag == 2)) {
174939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n");
1750e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro		/*
1751e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro		* Send signal to FW to stop processing any pending cmds.
1752e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro		* The controller will be taken offline by the OS now.
1753e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro		*/
17540c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		if ((instance->pdev->device ==
17550c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
17560c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			(instance->pdev->device ==
17570c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
17580c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			writel(MFI_STOP_ADP,
17590c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo				&instance->reg_set->reserved_0[0]);
17600c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		} else {
17610c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			writel(MFI_STOP_ADP,
1762e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro				&instance->reg_set->inbound_doorbell);
17630c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		}
1764658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		megasas_dump_pending_frames(instance);
176539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_lock_irqsave(&instance->hba_lock, flags);
176639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		instance->adprecovery	= MEGASAS_HW_CRITICAL_ERROR;
176739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_unlock_irqrestore(&instance->hba_lock, flags);
1768c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return FAILED;
1769c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
1770c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
177139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	printk(KERN_NOTICE "megaraid_sas: no pending cmds after reset\n");
177239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
1773c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return SUCCESS;
1774c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
1775c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1776c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
1777c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_generic_reset -	Generic reset routine
1778c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scmd:			Mid-layer SCSI command
1779c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
1780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This routine implements a generic reset handler for device, bus and host
1781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * reset requests. Device, bus and host specific reset handlers can use this
1782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * function after they do their specific tasks.
1783c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1784c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_generic_reset(struct scsi_cmnd *scmd)
1785c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
1786c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int ret_val;
1787c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_instance *instance;
1788c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1789c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance = (struct megasas_instance *)scmd->device->host->hostdata;
1790c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
179105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n",
179205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro		 scmd->serial_number, scmd->cmnd[0], scmd->retries);
1793c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
179439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
1795c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_ERR "megasas: cannot recover from previous reset "
1796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		       "failures\n");
1797c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return FAILED;
1798c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
1799c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1800c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ret_val = megasas_wait_for_outstanding(instance);
1801c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (ret_val == SUCCESS)
1802c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_NOTICE "megasas: reset successful \n");
1803c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	else
1804c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_ERR "megasas: failed to do reset\n");
1805c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1806c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return ret_val;
1807c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
1808c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1809c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
181005e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * megasas_reset_timer - quiesce the adapter if required
181105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * @scmd:		scsi cmnd
181205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro *
181305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * Sets the FW busy flag and reduces the host->can_queue if the
181405e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * cmd has not been completed within the timeout period.
181505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro */
181605e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patrostatic enum
1817242f9dcb8ba6f68fcd217a119a7648a4f69290e9Jens Axboeblk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
181805e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro{
181905e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
182005e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	struct megasas_instance *instance;
182105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	unsigned long flags;
182205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro
182305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	if (time_after(jiffies, scmd->jiffies_at_alloc +
182405e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro				(MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
1825242f9dcb8ba6f68fcd217a119a7648a4f69290e9Jens Axboe		return BLK_EH_NOT_HANDLED;
182605e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	}
182705e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro
182805e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	instance = cmd->instance;
182905e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	if (!(instance->flag & MEGASAS_FW_BUSY)) {
183005e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro		/* FW is busy, throttle IO */
183105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro		spin_lock_irqsave(instance->host->host_lock, flags);
183205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro
183305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro		instance->host->can_queue = 16;
183405e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro		instance->last_time = jiffies;
183505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro		instance->flag |= MEGASAS_FW_BUSY;
183605e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro
183705e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro		spin_unlock_irqrestore(instance->host->host_lock, flags);
183805e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	}
1839242f9dcb8ba6f68fcd217a119a7648a4f69290e9Jens Axboe	return BLK_EH_RESET_TIMER;
184005e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro}
184105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro
184205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro/**
1843c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_reset_device -	Device reset handler entry point
1844c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1845c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_reset_device(struct scsi_cmnd *scmd)
1846c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
1847c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int ret;
1848c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1849c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1850c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * First wait for all commands to complete
1851c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1852c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ret = megasas_generic_reset(scmd);
1853c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1854c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return ret;
1855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
1856c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1857c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
1858c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_reset_bus_host -	Bus & host reset handler entry point
1859c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1860c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_reset_bus_host(struct scsi_cmnd *scmd)
1861c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
1862c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int ret;
1863c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1864c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
186580682fa9f70932950c913fd10411c004c4c2e8b0Uwe Zeisberger	 * First wait for all commands to complete
1866c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1867c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ret = megasas_generic_reset(scmd);
1868c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1869c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return ret;
1870c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
1871c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1872c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
1873cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * megasas_bios_param - Returns disk geometry for a disk
1874cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @sdev: 		device handle
1875cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @bdev:		block device
1876cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @capacity:		drive capacity
1877cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @geom:		geometry parameters
1878cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro */
1879cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patrostatic int
1880cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patromegasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
1881cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro		 sector_t capacity, int geom[])
1882cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro{
1883cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	int heads;
1884cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	int sectors;
1885cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	sector_t cylinders;
1886cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	unsigned long tmp;
1887cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	/* Default heads (64) & sectors (32) */
1888cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	heads = 64;
1889cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	sectors = 32;
1890cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro
1891cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	tmp = heads * sectors;
1892cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	cylinders = capacity;
1893cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro
1894cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	sector_div(cylinders, tmp);
1895cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro
1896cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	/*
1897cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	 * Handle extended translation size for logical drives > 1Gb
1898cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	 */
1899cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro
1900cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	if (capacity >= 0x200000) {
1901cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro		heads = 255;
1902cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro		sectors = 63;
1903cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro		tmp = heads*sectors;
1904cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro		cylinders = capacity;
1905cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro		sector_div(cylinders, tmp);
1906cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	}
1907cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro
1908cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	geom[0] = heads;
1909cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	geom[1] = sectors;
1910cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	geom[2] = cylinders;
1911cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro
1912cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	return 0;
1913cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro}
1914cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro
19157e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bostatic void megasas_aen_polling(struct work_struct *work);
19167e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
1917cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro/**
1918c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_service_aen -	Processes an event notification
1919c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
1920c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd:			AEN command completed by the ISR
1921c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
1922c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * For AEN, driver sends a command down to FW that is held by the FW till an
1923c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * event occurs. When an event of interest occurs, FW completes the command
1924c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * that it was previously holding.
1925c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
1926c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This routines sends SIGIO signal to processes that have registered with the
1927c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * driver for AEN.
1928c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1929c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void
1930c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
1931c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
1932c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	unsigned long flags;
1933c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
1934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Don't signal app if it is just an aborted previously registered aen
1935c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
1936c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	if ((!cmd->abort_aen) && (instance->unload == 0)) {
1937c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo		spin_lock_irqsave(&poll_aen_lock, flags);
1938c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo		megasas_poll_wait_aen = 1;
1939c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo		spin_unlock_irqrestore(&poll_aen_lock, flags);
1940c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo		wake_up(&megasas_poll_wait);
1941c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
1942c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	}
1943c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	else
1944c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd->abort_aen = 0;
1945c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1946c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->aen_cmd = NULL;
1947c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_return_cmd(instance, cmd);
19487e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
194939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if ((instance->unload == 0) &&
195039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		((instance->issuepend_done == 1))) {
19517e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		struct megasas_aen_event *ev;
19527e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
19537e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		if (!ev) {
19547e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			printk(KERN_ERR "megasas_service_aen: out of memory\n");
19557e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		} else {
19567e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			ev->instance = instance;
19577e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			instance->ev = ev;
19587e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
19597e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			schedule_delayed_work(
19607e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo				(struct delayed_work *)&ev->hotplug_work, 0);
19617e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		}
19627e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	}
1963c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
1964c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1965c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/*
1966c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Scsi host template for megaraid_sas driver
1967c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1968c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct scsi_host_template megasas_template = {
1969c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1970c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.module = THIS_MODULE,
1971f28cd7cf8f696eafe42d1632b5a306fbf784d3cdbo yang	.name = "LSI SAS based MegaRAID driver",
1972c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.proc_name = "megaraid_sas",
1973147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig	.slave_configure = megasas_slave_configure,
1974044833b572b96afe91506a0edec42efd84ba4939Yang, Bo	.slave_alloc = megasas_slave_alloc,
1975c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.queuecommand = megasas_queue_command,
1976c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.eh_device_reset_handler = megasas_reset_device,
1977c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.eh_bus_reset_handler = megasas_reset_bus_host,
1978c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.eh_host_reset_handler = megasas_reset_bus_host,
197905e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	.eh_timed_out = megasas_reset_timer,
1980cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro	.bios_param = megasas_bios_param,
1981c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.use_clustering = ENABLE_CLUSTERING,
1982c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas};
1983c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1984c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
1985c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_complete_int_cmd -	Completes an internal command
1986c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
1987c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd:			Command to be completed
1988c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
1989c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * The megasas_issue_blocked_cmd() function waits for a command to complete
1990c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * after it issues a command. This function wakes up that waiting routine by
1991c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * calling wake_up() on the wait queue.
1992c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
1993c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void
1994c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_complete_int_cmd(struct megasas_instance *instance,
1995c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 struct megasas_cmd *cmd)
1996c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
1997c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd->cmd_status = cmd->frame->io.cmd_status;
1998c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
1999c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (cmd->cmd_status == ENODATA) {
2000c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd->cmd_status = 0;
2001c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2002c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	wake_up(&instance->int_cmd_wait_q);
2003c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
2004c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2005c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
2006c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_complete_abort -	Completes aborting a command
2007c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
2008c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd:			Cmd that was issued to abort another cmd
2009c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
20100d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
20110d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * after it issues an abort on a previously issued command. This function
2012c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * wakes up all functions waiting on the same wait queue.
2013c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
2014c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void
2015c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_complete_abort(struct megasas_instance *instance,
2016c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		       struct megasas_cmd *cmd)
2017c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
2018c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (cmd->sync_cmd) {
2019c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd->sync_cmd = 0;
2020c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd->cmd_status = 0;
2021c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		wake_up(&instance->abort_cmd_wait_q);
2022c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2023c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2024c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return;
2025c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
2026c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2027c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
2028c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_complete_cmd -	Completes a command
2029c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
2030c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd:			Command to be completed
20310d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * @alt_status:			If non-zero, use this value as status to
2032c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 				SCSI mid-layer instead of the value returned
2033c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 				by the FW. This should be used if caller wants
2034c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 				an alternate status (as in the case of aborted
2035c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 				commands)
2036c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
2037858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic void
2038c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
2039c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		     u8 alt_status)
2040c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
2041c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int exception = 0;
2042c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_header *hdr = &cmd->frame->hdr;
2043c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	unsigned long flags;
2044c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
204539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	/* flag for the retry reset */
204639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	cmd->retry_for_fw_reset = 0;
204739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
204805e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	if (cmd->scmd)
204905e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro		cmd->scmd->SCp.ptr = NULL;
2050c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2051c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	switch (hdr->cmd) {
2052c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2053c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MFI_CMD_PD_SCSI_IO:
2054c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MFI_CMD_LD_SCSI_IO:
2055c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2056c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/*
2057c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been
2058c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * issued either through an IO path or an IOCTL path. If it
2059c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * was via IOCTL, we will send it to internal completion.
2060c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 */
2061c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (cmd->sync_cmd) {
2062c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cmd->sync_cmd = 0;
2063c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			megasas_complete_int_cmd(instance, cmd);
2064c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2065c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
2066c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2067c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MFI_CMD_LD_READ:
2068c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MFI_CMD_LD_WRITE:
2069c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2070c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (alt_status) {
2071c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cmd->scmd->result = alt_status << 16;
2072c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			exception = 1;
2073c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
2074c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2075c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (exception) {
2076c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2077e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro			atomic_dec(&instance->fw_outstanding);
2078c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2079155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori			scsi_dma_unmap(cmd->scmd);
2080c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cmd->scmd->scsi_done(cmd->scmd);
2081c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			megasas_return_cmd(instance, cmd);
2082c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2083c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2084c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
2085c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2086c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		switch (hdr->cmd_status) {
2087c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2088c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STAT_OK:
2089c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cmd->scmd->result = DID_OK << 16;
2090c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2091c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2092c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STAT_SCSI_IO_FAILED:
2093c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STAT_LD_INIT_IN_PROGRESS:
2094c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cmd->scmd->result =
2095c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			    (DID_ERROR << 16) | hdr->scsi_status;
2096c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2097c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2098c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STAT_SCSI_DONE_WITH_ERROR:
2099c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status;
2101c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2102c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) {
2103c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				memset(cmd->scmd->sense_buffer, 0,
2104c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				       SCSI_SENSE_BUFFERSIZE);
2105c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				memcpy(cmd->scmd->sense_buffer, cmd->sense,
2106c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				       hdr->sense_len);
2107c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2108c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				cmd->scmd->result |= DRIVER_SENSE << 24;
2109c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			}
2110c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2111c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2112c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2113c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STAT_LD_OFFLINE:
2114c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STAT_DEVICE_NOT_FOUND:
2115c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cmd->scmd->result = DID_BAD_TARGET << 16;
2116c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2117c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2118c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		default:
2119c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			printk(KERN_DEBUG "megasas: MFI FW status %#x\n",
2120c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			       hdr->cmd_status);
2121c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cmd->scmd->result = DID_ERROR << 16;
2122c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2123c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
2124c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2125e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro		atomic_dec(&instance->fw_outstanding);
2126c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2127155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori		scsi_dma_unmap(cmd->scmd);
2128c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd->scmd->scsi_done(cmd->scmd);
2129c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		megasas_return_cmd(instance, cmd);
2130c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2131c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		break;
2132c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2133c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MFI_CMD_SMP:
2134c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MFI_CMD_STP:
2135c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MFI_CMD_DCMD:
2136c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo		if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
2137c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo			cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
2138c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo			spin_lock_irqsave(&poll_aen_lock, flags);
2139c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo			megasas_poll_wait_aen = 0;
2140c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo			spin_unlock_irqrestore(&poll_aen_lock, flags);
2141c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo		}
2142c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2143c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/*
2144c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * See if got an event notification
2145c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 */
2146c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_WAIT)
2147c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			megasas_service_aen(instance, cmd);
2148c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		else
2149c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			megasas_complete_int_cmd(instance, cmd);
2150c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2151c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		break;
2152c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2153c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MFI_CMD_ABORT:
2154c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/*
2155c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * Cmd issued to abort another cmd returned
2156c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 */
2157c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		megasas_complete_abort(instance, cmd);
2158c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		break;
2159c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2160c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	default:
2161c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk("megasas: Unknown command completed! [0x%X]\n",
2162c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		       hdr->cmd);
2163c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		break;
2164c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2165c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
2166c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2167c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
216839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_issue_pending_cmds_again -	issue all pending cmds
216939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang *                              	in FW again because of the fw reset
217039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @instance:				Adapter soft state
217139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */
217239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic inline void
217339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_issue_pending_cmds_again(struct megasas_instance *instance)
217439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
217539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	struct megasas_cmd *cmd;
217639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	struct list_head clist_local;
217739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	union megasas_evt_class_locale class_locale;
217839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
217939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 seq_num;
218039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
218139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	INIT_LIST_HEAD(&clist_local);
218239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->hba_lock, flags);
218339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	list_splice_init(&instance->internal_reset_pending_q, &clist_local);
218439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->hba_lock, flags);
218539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
218639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	while (!list_empty(&clist_local)) {
218739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		cmd	= list_entry((&clist_local)->next,
218839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					struct megasas_cmd, list);
218939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		list_del_init(&cmd->list);
219039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
219139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (cmd->sync_cmd || cmd->scmd) {
219239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megaraid_sas: command %p, %p:%d"
219339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				"detected to be pending while HBA reset.\n",
219439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					cmd, cmd->scmd, cmd->sync_cmd);
219539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
219639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			cmd->retry_for_fw_reset++;
219739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
219839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			if (cmd->retry_for_fw_reset == 3) {
219939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				printk(KERN_NOTICE "megaraid_sas: cmd %p, %p:%d"
220039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					"was tried multiple times during reset."
220139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					"Shutting down the HBA\n",
220239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					cmd, cmd->scmd, cmd->sync_cmd);
220339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				megaraid_sas_kill_hba(instance);
220439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
220539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				instance->adprecovery =
220639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						MEGASAS_HW_CRITICAL_ERROR;
220739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				return;
220839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			}
220939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
221039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
221139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (cmd->sync_cmd == 1) {
221239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			if (cmd->scmd) {
221339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				printk(KERN_NOTICE "megaraid_sas: unexpected"
221439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					"cmd attached to internal command!\n");
221539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			}
221639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megasas: %p synchronous cmd"
221739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						"on the internal reset queue,"
221839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						"issue it again.\n", cmd);
221939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			cmd->cmd_status = ENODATA;
222039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			instance->instancet->fire_cmd(instance,
222139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang							cmd->frame_phys_addr ,
222239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang							0, instance->reg_set);
222339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		} else if (cmd->scmd) {
222439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megasas: %p scsi cmd [%02x],%#lx"
222539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			"detected on the internal queue, issue again.\n",
222639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			cmd, cmd->scmd->cmnd[0], cmd->scmd->serial_number);
222739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
222839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			atomic_inc(&instance->fw_outstanding);
222939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			instance->instancet->fire_cmd(instance,
223039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					cmd->frame_phys_addr,
223139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					cmd->frame_count-1, instance->reg_set);
223239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		} else {
223339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megasas: %p unexpected cmd on the"
223439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				"internal reset defer list while re-issue!!\n",
223539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				cmd);
223639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
223739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
223839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
223939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->aen_cmd) {
224039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "megaraid_sas: aen_cmd in def process\n");
224139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		megasas_return_cmd(instance, instance->aen_cmd);
224239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
224339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		instance->aen_cmd	= NULL;
224439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
224539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
224639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	/*
224739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	* Initiate AEN (Asynchronous Event Notification)
224839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	*/
224939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	seq_num = instance->last_seq_num;
225039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	class_locale.members.reserved = 0;
225139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	class_locale.members.locale = MR_EVT_LOCALE_ALL;
225239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	class_locale.members.class = MR_EVT_CLASS_DEBUG;
225339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
225439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	megasas_register_aen(instance, seq_num, class_locale.word);
225539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
225639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
225739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/**
225839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * Move the internal reset pending commands to a deferred queue.
225939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang *
226039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * We move the commands pending at internal reset time to a
226139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * pending queue. This queue would be flushed after successful
226239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * completion of the internal reset sequence. if the internal reset
226339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * did not complete in time, the kernel reset handler would flush
226439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * these commands.
226539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang **/
226639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic void
226739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_internal_reset_defer_cmds(struct megasas_instance *instance)
226839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
226939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	struct megasas_cmd *cmd;
227039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	int i;
227139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 max_cmd = instance->max_fw_cmds;
227239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 defer_index;
227339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
227439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
227539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	defer_index     = 0;
227639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->cmd_pool_lock, flags);
227739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	for (i = 0; i < max_cmd; i++) {
227839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		cmd = instance->cmd_list[i];
227939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (cmd->sync_cmd == 1 || cmd->scmd) {
228039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megasas: moving cmd[%d]:%p:%d:%p"
228139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					"on the defer queue as internal\n",
228239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				defer_index, cmd, cmd->sync_cmd, cmd->scmd);
228339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
228439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			if (!list_empty(&cmd->list)) {
228539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				printk(KERN_NOTICE "megaraid_sas: ERROR while"
228639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					" moving this cmd:%p, %d %p, it was"
228739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					"discovered on some list?\n",
228839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					cmd, cmd->sync_cmd, cmd->scmd);
228939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
229039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				list_del_init(&cmd->list);
229139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			}
229239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			defer_index++;
229339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			list_add_tail(&cmd->list,
229439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				&instance->internal_reset_pending_q);
229539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
229639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
229739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
229839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
229939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
230039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
230139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic void
230239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangprocess_fw_state_change_wq(struct work_struct *work)
230339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{
230439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	struct megasas_instance *instance =
230539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		container_of(work, struct megasas_instance, work_init);
230639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 wait;
230739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
230839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
230939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery != MEGASAS_ADPRESET_SM_INFAULT) {
231039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "megaraid_sas: error, recovery st %x \n",
231139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				instance->adprecovery);
231239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return ;
231339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
231439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
231539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) {
231639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault"
231739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					"state, restarting it...\n");
231839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
231939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		instance->instancet->disable_intr(instance->reg_set);
232039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		atomic_set(&instance->fw_outstanding, 0);
232139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
232239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		atomic_set(&instance->fw_reset_no_pci_access, 1);
232339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		instance->instancet->adp_reset(instance, instance->reg_set);
232439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		atomic_set(&instance->fw_reset_no_pci_access, 0 );
232539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
232639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "megaraid_sas: FW restarted successfully,"
232739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					"initiating next stage...\n");
232839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
232939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_NOTICE "megaraid_sas: HBA recovery state machine,"
233039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					"state 2 starting...\n");
233139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
233239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		/*waitting for about 20 second before start the second init*/
233339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		for (wait = 0; wait < 30; wait++) {
233439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			msleep(1000);
233539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
233639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
233739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (megasas_transition_to_ready(instance)) {
233839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megaraid_sas:adapter not ready\n");
233939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
234039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			megaraid_sas_kill_hba(instance);
234139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			instance->adprecovery	= MEGASAS_HW_CRITICAL_ERROR;
234239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			return ;
234339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
234439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
234539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
234639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			(instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
234739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			(instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)
234839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			) {
234939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			*instance->consumer = *instance->producer;
235039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		} else {
235139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			*instance->consumer = 0;
235239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			*instance->producer = 0;
235339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
235439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
235539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		megasas_issue_init_mfi(instance);
235639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
235739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_lock_irqsave(&instance->hba_lock, flags);
235839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		instance->adprecovery	= MEGASAS_HBA_OPERATIONAL;
235939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_unlock_irqrestore(&instance->hba_lock, flags);
236039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		instance->instancet->enable_intr(instance->reg_set);
236139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
236239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		megasas_issue_pending_cmds_again(instance);
236339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		instance->issuepend_done = 1;
236439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
236539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return ;
236639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang}
236739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
236839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/**
2369c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_deplete_reply_queue -	Processes all completed commands
2370c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:				Adapter soft state
2371c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @alt_status:				Alternate status to be returned to
2372c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 					SCSI mid-layer instead of the status
2373c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 					returned by the FW
237439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * Note: this must be called with hba lock held
2375c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
2376858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int
237739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_deplete_reply_queue(struct megasas_instance *instance,
237839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					u8 alt_status)
2379c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
238039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 mfiStatus;
238139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 fw_state;
238239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
238339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if ((mfiStatus = instance->instancet->check_reset(instance,
238439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					instance->reg_set)) == 1) {
238539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return IRQ_HANDLED;
238639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
238739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
238839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if ((mfiStatus = instance->instancet->clear_intr(
238939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						instance->reg_set)
239039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						) == 0) {
2391c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return IRQ_NONE;
239239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
239339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
239439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	instance->mfiStatus = mfiStatus;
239539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
239639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) {
239739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		fw_state = instance->instancet->read_fw_status_reg(
239839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				instance->reg_set) & MFI_STATE_MASK;
239939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
240039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (fw_state != MFI_STATE_FAULT) {
240139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megaraid_sas: fw state:%x\n",
240239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						fw_state);
240339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
240439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
240539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if ((fw_state == MFI_STATE_FAULT) &&
240639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				(instance->disableOnlineCtrlReset == 0)) {
240739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megaraid_sas: wait adp restart\n");
240839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
240939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			if ((instance->pdev->device ==
241039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					PCI_DEVICE_ID_LSI_SAS1064R) ||
241139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				(instance->pdev->device ==
241239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					PCI_DEVICE_ID_DELL_PERC5) ||
241339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				(instance->pdev->device ==
241439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
241539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
241639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				*instance->consumer =
241739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					MEGASAS_ADPRESET_INPROG_SIGN;
241839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			}
241939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
242039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
242139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			instance->instancet->disable_intr(instance->reg_set);
242239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			instance->adprecovery	= MEGASAS_ADPRESET_SM_INFAULT;
242339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			instance->issuepend_done = 0;
242439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
242539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			atomic_set(&instance->fw_outstanding, 0);
242639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			megasas_internal_reset_defer_cmds(instance);
242739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
242839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megasas: fwState=%x, stage:%d\n",
242939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang					fw_state, instance->adprecovery);
243039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
243139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			schedule_work(&instance->work_init);
243239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			return IRQ_HANDLED;
243339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
243439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		} else {
243539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megasas: fwstate:%x, dis_OCR=%x\n",
243639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				fw_state, instance->disableOnlineCtrlReset);
243739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
243839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
2439c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
24405d018ad057347995e5c4564b3e43339e6497f839Sumant Patro	tasklet_schedule(&instance->isr_tasklet);
2441c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return IRQ_HANDLED;
2442c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
2443c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
2444c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_isr - isr entry point
2445c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
24467d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t megasas_isr(int irq, void *devp)
2447c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
244839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	struct megasas_instance *instance;
244939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
245039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	irqreturn_t	rc;
245139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
245239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (atomic_read(
245339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		&(((struct megasas_instance *)devp)->fw_reset_no_pci_access)))
245439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return IRQ_HANDLED;
245539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
245639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	instance = (struct megasas_instance *)devp;
245739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
245839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->hba_lock, flags);
245939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	rc =  megasas_deplete_reply_queue(instance, DID_OK);
246039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->hba_lock, flags);
246139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
246239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	return rc;
2463c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
2464c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2465c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
2466c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_transition_to_ready -	Move the FW to READY state
24671341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @instance:				Adapter soft state
2468c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
2469c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * During the initialization, FW passes can potentially be in any one of
2470c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * several possible states. If the FW in operational, waiting-for-handshake
2471c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * states, driver must take steps to bring it to ready state. Otherwise, it
2472c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * has to wait for the ready state.
2473c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
2474c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int
24751341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_transition_to_ready(struct megasas_instance* instance)
2476c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
2477c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
2478c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u8 max_wait;
2479c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 fw_state;
2480c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 cur_state;
24817218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo	u32 abs_state, curr_abs_state;
2482c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
24831341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
2484c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2485e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro	if (fw_state != MFI_STATE_READY)
24860d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford		printk(KERN_INFO "megasas: Waiting for FW to come to ready"
24870d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford		       " state\n");
2488e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro
2489c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	while (fw_state != MFI_STATE_READY) {
2490c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
24917218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo		abs_state =
24927218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo		instance->instancet->read_fw_status_reg(instance->reg_set);
24937218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo
2494c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		switch (fw_state) {
2495c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2496c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STATE_FAULT:
2497c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2498c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			printk(KERN_DEBUG "megasas: FW in FAULT state!!\n");
2499c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			return -ENODEV;
2500c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2501c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STATE_WAIT_HANDSHAKE:
2502c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			/*
2503c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 * Set the CLR bit in inbound doorbell
2504c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 */
25050c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			if ((instance->pdev->device ==
2506879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2507879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				(instance->pdev->device ==
2508879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
2509879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo
2510879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				writel(
2511879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				  MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
2512879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				  &instance->reg_set->reserved_0[0]);
2513879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo			} else {
2514879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				writel(
2515879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				    MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
2516879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo					&instance->reg_set->inbound_doorbell);
2517879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo			}
2518c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
25197218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo			max_wait = MEGASAS_RESET_WAIT_TIME;
2520c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cur_state = MFI_STATE_WAIT_HANDSHAKE;
2521c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2522c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2523e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro		case MFI_STATE_BOOT_MESSAGE_PENDING:
2524879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo			if ((instance->pdev->device ==
2525879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2526879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo			(instance->pdev->device ==
2527879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
2528879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				writel(MFI_INIT_HOTPLUG,
2529879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				&instance->reg_set->reserved_0[0]);
2530879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo			} else
2531879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				writel(MFI_INIT_HOTPLUG,
2532879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo					&instance->reg_set->inbound_doorbell);
2533e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro
25347218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo			max_wait = MEGASAS_RESET_WAIT_TIME;
2535e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro			cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
2536e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro			break;
2537e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro
2538c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STATE_OPERATIONAL:
2539c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			/*
2540e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro			 * Bring it to READY state; assuming max wait 10 secs
2541c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 */
2542b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro			instance->instancet->disable_intr(instance->reg_set);
2543879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo			if ((instance->pdev->device ==
2544879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2545879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				(instance->pdev->device ==
2546879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
2547879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				writel(MFI_RESET_FLAGS,
2548879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo					&instance->reg_set->reserved_0[0]);
2549879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo			} else
2550879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo				writel(MFI_RESET_FLAGS,
2551879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo					&instance->reg_set->inbound_doorbell);
2552c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
25537218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo			max_wait = MEGASAS_RESET_WAIT_TIME;
2554c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cur_state = MFI_STATE_OPERATIONAL;
2555c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2556c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2557c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STATE_UNDEFINED:
2558c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			/*
2559c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 * This state should not last for more than 2 seconds
2560c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 */
25617218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo			max_wait = MEGASAS_RESET_WAIT_TIME;
2562c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cur_state = MFI_STATE_UNDEFINED;
2563c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2564c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2565c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STATE_BB_INIT:
25667218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo			max_wait = MEGASAS_RESET_WAIT_TIME;
2567c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cur_state = MFI_STATE_BB_INIT;
2568c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2569c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2570c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STATE_FW_INIT:
25717218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo			max_wait = MEGASAS_RESET_WAIT_TIME;
2572c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cur_state = MFI_STATE_FW_INIT;
2573c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2574c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2575c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STATE_FW_INIT_2:
25767218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo			max_wait = MEGASAS_RESET_WAIT_TIME;
2577c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cur_state = MFI_STATE_FW_INIT_2;
2578c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2579c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2580c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STATE_DEVICE_SCAN:
25817218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo			max_wait = MEGASAS_RESET_WAIT_TIME;
2582c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cur_state = MFI_STATE_DEVICE_SCAN;
2583c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2584c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2585c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		case MFI_STATE_FLUSH_CACHE:
25867218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo			max_wait = MEGASAS_RESET_WAIT_TIME;
2587c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			cur_state = MFI_STATE_FLUSH_CACHE;
2588c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
2589c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2590c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		default:
2591c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			printk(KERN_DEBUG "megasas: Unknown state 0x%x\n",
2592c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			       fw_state);
2593c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			return -ENODEV;
2594c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
2595c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2596c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/*
2597c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * The cur_state should not last for more than max_wait secs
2598c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 */
2599c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		for (i = 0; i < (max_wait * 1000); i++) {
26000d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford			fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
26011341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro					MFI_STATE_MASK ;
26027218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo		curr_abs_state =
26037218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo		instance->instancet->read_fw_status_reg(instance->reg_set);
2604c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
26057218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo			if (abs_state == curr_abs_state) {
2606c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				msleep(1);
2607c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			} else
2608c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				break;
2609c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
2610c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2611c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/*
2612c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * Return error if fw_state hasn't changed after max_wait
2613c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 */
26147218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo		if (curr_abs_state == abs_state) {
2615c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			printk(KERN_DEBUG "FW state [%d] hasn't changed "
2616c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			       "in %d secs\n", fw_state, max_wait);
2617c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			return -ENODEV;
2618c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
261939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
26200d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford	printk(KERN_INFO "megasas: FW now in Ready state\n");
2621c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2622c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
2623c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
2624c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2625c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
2626c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_teardown_frame_pool -	Destroy the cmd frame DMA pool
2627c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:				Adapter soft state
2628c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
2629c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_teardown_frame_pool(struct megasas_instance *instance)
2630c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
2631c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
2632c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 max_cmd = instance->max_fw_cmds;
2633c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
2634c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2635c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!instance->frame_dma_pool)
2636c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return;
2637c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2638c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
2639c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Return all frames to pool
2640c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
2641c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; i < max_cmd; i++) {
2642c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2643c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd = instance->cmd_list[i];
2644c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2645c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (cmd->frame)
2646c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			pci_pool_free(instance->frame_dma_pool, cmd->frame,
2647c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				      cmd->frame_phys_addr);
2648c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2649c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (cmd->sense)
2650e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro			pci_pool_free(instance->sense_dma_pool, cmd->sense,
2651c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				      cmd->sense_phys_addr);
2652c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2653c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2654c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
2655c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Now destroy the pool itself
2656c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
2657c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_pool_destroy(instance->frame_dma_pool);
2658c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_pool_destroy(instance->sense_dma_pool);
2659c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2660c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->frame_dma_pool = NULL;
2661c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->sense_dma_pool = NULL;
2662c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
2663c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2664c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
2665c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_create_frame_pool -	Creates DMA pool for cmd frames
2666c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
2667c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
2668c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Each command packet has an embedded DMA memory buffer that is used for
2669c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * filling MFI frame and the SG list that immediately follows the frame. This
2670c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * function creates those DMA memory buffers for each command packet by using
2671c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI pool facility.
2672c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
2673c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_create_frame_pool(struct megasas_instance *instance)
2674c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
2675c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
2676c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 max_cmd;
2677c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 sge_sz;
2678c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 sgl_sz;
2679c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 total_sz;
2680c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 frame_count;
2681c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
2682c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2683c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	max_cmd = instance->max_fw_cmds;
2684c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2685c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
2686c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Size of our frame is 64 bytes for MFI frame, followed by max SG
2687c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer
2688c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
2689c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
2690c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    sizeof(struct megasas_sge32);
2691c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2692f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	if (instance->flag_ieee) {
2693f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		sge_sz = sizeof(struct megasas_sge_skinny);
2694f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	}
2695f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo
2696c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
2697c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Calculated the number of 64byte frames required for SGL
2698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
2699c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	sgl_sz = sge_sz * instance->max_num_sge;
2700c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	frame_count = (sgl_sz + MEGAMFI_FRAME_SIZE - 1) / MEGAMFI_FRAME_SIZE;
270139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	frame_count = 15;
2702c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2703c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
2704c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * We need one extra frame for the MFI command
2705c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
2706c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	frame_count++;
2707c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2708c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	total_sz = MEGAMFI_FRAME_SIZE * frame_count;
2709c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
2710c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Use DMA pool facility provided by PCI layer
2711c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
2712c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->frame_dma_pool = pci_pool_create("megasas frame pool",
2713c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						   instance->pdev, total_sz, 64,
2714c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						   0);
2715c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2716c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!instance->frame_dma_pool) {
2717c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: failed to setup frame pool\n");
2718c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENOMEM;
2719c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2720c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2721c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->sense_dma_pool = pci_pool_create("megasas sense pool",
2722c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						   instance->pdev, 128, 4, 0);
2723c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2724c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!instance->sense_dma_pool) {
2725c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: failed to setup sense pool\n");
2726c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2727c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		pci_pool_destroy(instance->frame_dma_pool);
2728c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		instance->frame_dma_pool = NULL;
2729c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2730c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENOMEM;
2731c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2732c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2733c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
2734c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Allocate and attach a frame to each of the commands in cmd_list.
2735c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * By making cmd->index as the context instead of the &cmd, we can
2736c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * always use 32bit context regardless of the architecture
2737c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
2738c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; i < max_cmd; i++) {
2739c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2740c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd = instance->cmd_list[i];
2741c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2742c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd->frame = pci_pool_alloc(instance->frame_dma_pool,
2743c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas					    GFP_KERNEL, &cmd->frame_phys_addr);
2744c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2745c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd->sense = pci_pool_alloc(instance->sense_dma_pool,
2746c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas					    GFP_KERNEL, &cmd->sense_phys_addr);
2747c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2748c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/*
2749c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * megasas_teardown_frame_pool() takes care of freeing
2750c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * whatever has been allocated
2751c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 */
2752c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (!cmd->frame || !cmd->sense) {
2753c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			printk(KERN_DEBUG "megasas: pci_pool_alloc failed \n");
2754c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			megasas_teardown_frame_pool(instance);
2755c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			return -ENOMEM;
2756c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
2757c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2758707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo		memset(cmd->frame, 0, total_sz);
2759c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd->frame->io.context = cmd->index;
27607e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		cmd->frame->io.pad_0 = 0;
2761c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2762c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2763c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
2764c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
2765c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2766c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
2767c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_free_cmds -	Free all the cmds in the free cmd pool
2768c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
2769c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
2770c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_free_cmds(struct megasas_instance *instance)
2771c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
2772c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
2773c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/* First free the MFI frame pool */
2774c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_teardown_frame_pool(instance);
2775c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2776c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/* Free all the commands in the cmd_list */
2777c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; i < instance->max_fw_cmds; i++)
2778c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		kfree(instance->cmd_list[i]);
2779c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/* Free the cmd_list buffer itself */
2781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	kfree(instance->cmd_list);
2782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->cmd_list = NULL;
2783c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2784c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	INIT_LIST_HEAD(&instance->cmd_pool);
2785c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
2786c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2787c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
2788c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_alloc_cmds -	Allocates the command packets
2789c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
2790c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
2791c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Each command that is issued to the FW, whether IO commands from the OS or
2792c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * internal commands like IOCTLs, are wrapped in local data structure called
2793c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to
2794c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the FW.
2795c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
2796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Each frame has a 32-bit field called context (tag). This context is used
2797c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to get back the megasas_cmd from the frame when a frame gets completed in
2798c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the ISR. Typically the address of the megasas_cmd itself would be used as
2799c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the context. But we wanted to keep the differences between 32 and 64 bit
2800c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * systems to the mininum. We always use 32 bit integers for the context. In
2801c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * this driver, the 32 bit values are the indices into an array cmd_list.
2802c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This array is used only to look up the megasas_cmd given the context. The
2803c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * free commands themselves are maintained in a linked list called cmd_pool.
2804c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
2805c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_alloc_cmds(struct megasas_instance *instance)
2806c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
2807c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
2808c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int j;
2809c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 max_cmd;
2810c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
2811c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2812c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	max_cmd = instance->max_fw_cmds;
2813c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2814c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
2815c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * instance->cmd_list is an array of struct megasas_cmd pointers.
2816c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Allocate the dynamic array first and then allocate individual
2817c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * commands.
2818c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
2819dd00cc486ab1c17049a535413d1751ef3482141cYoann Padioleau	instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL);
2820c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2821c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!instance->cmd_list) {
2822c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: out of memory\n");
2823c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENOMEM;
2824c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2825c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2826c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2827c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; i < max_cmd; i++) {
2828c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd),
2829c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						GFP_KERNEL);
2830c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2831c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (!instance->cmd_list[i]) {
2832c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2833c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			for (j = 0; j < i; j++)
2834c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				kfree(instance->cmd_list[j]);
2835c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2836c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			kfree(instance->cmd_list);
2837c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			instance->cmd_list = NULL;
2838c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2839c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			return -ENOMEM;
2840c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
2841c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2842c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2843c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
2844c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Add all the commands to command pool (instance->cmd_pool)
2845c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
2846c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; i < max_cmd; i++) {
2847c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd = instance->cmd_list[i];
2848c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		memset(cmd, 0, sizeof(struct megasas_cmd));
2849c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd->index = i;
285039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		cmd->scmd = NULL;
2851c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		cmd->instance = instance;
2852c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2853c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		list_add_tail(&cmd->list, &instance->cmd_pool);
2854c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2856c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
2857c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Create a frame pool and assign one frame to each cmd
2858c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
2859c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (megasas_create_frame_pool(instance)) {
2860c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n");
2861c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		megasas_free_cmds(instance);
2862c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
2863c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
2864c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
2865c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
2866c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
286781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo/*
286881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * megasas_get_pd_list_info -	Returns FW's pd_list structure
286981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * @instance:				Adapter soft state
287081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * @pd_list:				pd_list structure
287181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo *
287281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * Issues an internal command (DCMD) to get the FW's controller PD
287381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * list structure.  This information is mainly used to find out SYSTEM
287481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * supported by the FW.
287581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo */
287681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bostatic int
287781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bomegasas_get_pd_list(struct megasas_instance *instance)
287881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo{
287981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	int ret = 0, pd_index = 0;
288081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	struct megasas_cmd *cmd;
288181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	struct megasas_dcmd_frame *dcmd;
288281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	struct MR_PD_LIST *ci;
288381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	struct MR_PD_ADDRESS *pd_addr;
288481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dma_addr_t ci_h = 0;
288581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
288681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	cmd = megasas_get_cmd(instance);
288781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
288881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	if (!cmd) {
288981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
289081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		return -ENOMEM;
289181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	}
289281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
289381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd = &cmd->frame->dcmd;
289481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
289581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	ci = pci_alloc_consistent(instance->pdev,
289681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		  MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
289781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
289881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	if (!ci) {
289981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
290081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		megasas_return_cmd(instance, cmd);
290181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		return -ENOMEM;
290281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	}
290381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
290481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	memset(ci, 0, sizeof(*ci));
290581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
290681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
290781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
290881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->mbox.b[1] = 0;
290981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->cmd = MFI_CMD_DCMD;
291081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->cmd_status = 0xFF;
291181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->sge_count = 1;
291281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->flags = MFI_FRAME_DIR_READ;
291381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->timeout = 0;
2914780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo	dcmd->pad_0 = 0;
291581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
291681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
291781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->sgl.sge32[0].phys_addr = ci_h;
291881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
291981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
292081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	if (!megasas_issue_polled(instance, cmd)) {
292181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		ret = 0;
292281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	} else {
292381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		ret = -1;
292481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	}
292581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
292681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	/*
292781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	* the following function will get the instance PD LIST.
292881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	*/
292981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
293081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	pd_addr = ci->addr;
293181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
293281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	if ( ret == 0 &&
293381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		(ci->count <
293481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		  (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
293581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
293681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		memset(instance->pd_list, 0,
293781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo			MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
293881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
293981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		for (pd_index = 0; pd_index < ci->count; pd_index++) {
294081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
294181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo			instance->pd_list[pd_addr->deviceId].tid	=
294281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo							pd_addr->deviceId;
294381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo			instance->pd_list[pd_addr->deviceId].driveType	=
294481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo							pd_addr->scsiDevType;
294581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo			instance->pd_list[pd_addr->deviceId].driveState	=
294681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo							MR_PD_STATE_SYSTEM;
294781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo			pd_addr++;
294881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		}
294981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	}
295081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
295181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	pci_free_consistent(instance->pdev,
295281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo				MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
295381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo				ci, ci_h);
295481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	megasas_return_cmd(instance, cmd);
295581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
295681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	return ret;
295781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo}
295881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
2959bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo/*
2960bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * megasas_get_ld_list_info -	Returns FW's ld_list structure
2961bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * @instance:				Adapter soft state
2962bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * @ld_list:				ld_list structure
2963bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo *
2964bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * Issues an internal command (DCMD) to get the FW's controller PD
2965bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * list structure.  This information is mainly used to find out SYSTEM
2966bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * supported by the FW.
2967bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo */
2968bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bostatic int
2969bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bomegasas_get_ld_list(struct megasas_instance *instance)
2970bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo{
2971bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	int ret = 0, ld_index = 0, ids = 0;
2972bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	struct megasas_cmd *cmd;
2973bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	struct megasas_dcmd_frame *dcmd;
2974bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	struct MR_LD_LIST *ci;
2975bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dma_addr_t ci_h = 0;
2976bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
2977bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	cmd = megasas_get_cmd(instance);
2978bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
2979bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	if (!cmd) {
2980bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n");
2981bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		return -ENOMEM;
2982bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	}
2983bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
2984bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd = &cmd->frame->dcmd;
2985bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
2986bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	ci = pci_alloc_consistent(instance->pdev,
2987bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo				sizeof(struct MR_LD_LIST),
2988bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo				&ci_h);
2989bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
2990bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	if (!ci) {
2991bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n");
2992bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		megasas_return_cmd(instance, cmd);
2993bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		return -ENOMEM;
2994bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	}
2995bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
2996bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	memset(ci, 0, sizeof(*ci));
2997bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2998bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
2999bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd->cmd = MFI_CMD_DCMD;
3000bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd->cmd_status = 0xFF;
3001bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd->sge_count = 1;
3002bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd->flags = MFI_FRAME_DIR_READ;
3003bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd->timeout = 0;
3004bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd->data_xfer_len = sizeof(struct MR_LD_LIST);
3005bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd->opcode = MR_DCMD_LD_GET_LIST;
3006bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd->sgl.sge32[0].phys_addr = ci_h;
3007bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_LIST);
3008bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	dcmd->pad_0  = 0;
3009bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
3010bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	if (!megasas_issue_polled(instance, cmd)) {
3011bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		ret = 0;
3012bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	} else {
3013bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		ret = -1;
3014bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	}
3015bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
3016bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	/* the following function will get the instance PD LIST */
3017bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
301839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if ((ret == 0) && (ci->ldCount <= MAX_LOGICAL_DRIVES)) {
3019bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
3020bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
3021bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		for (ld_index = 0; ld_index < ci->ldCount; ld_index++) {
3022bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo			if (ci->ldList[ld_index].state != 0) {
3023bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo				ids = ci->ldList[ld_index].ref.targetId;
3024bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo				instance->ld_ids[ids] =
3025bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo					ci->ldList[ld_index].ref.targetId;
3026bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo			}
3027bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo		}
3028bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	}
3029bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
3030bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	pci_free_consistent(instance->pdev,
3031bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo				sizeof(struct MR_LD_LIST),
3032bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo				ci,
3033bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo				ci_h);
3034bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
3035bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	megasas_return_cmd(instance, cmd);
3036bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	return ret;
3037bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo}
3038bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
3039c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
3040c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_get_controller_info -	Returns FW's controller structure
3041c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:				Adapter soft state
3042c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @ctrl_info:				Controller information structure
3043c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
3044c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Issues an internal command (DCMD) to get the FW's controller structure.
3045c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This information is mainly used to find out the maximum IO transfer per
3046c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * command supported by the FW.
3047c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
3048c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int
3049c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_get_ctrl_info(struct megasas_instance *instance,
3050c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		      struct megasas_ctrl_info *ctrl_info)
3051c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
3052c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int ret = 0;
3053c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
3054c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_dcmd_frame *dcmd;
3055c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_ctrl_info *ci;
3056c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dma_addr_t ci_h = 0;
3057c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3058c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd = megasas_get_cmd(instance);
3059c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3060c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!cmd) {
3061c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: Failed to get a free cmd\n");
3062c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENOMEM;
3063c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3064c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3065c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd = &cmd->frame->dcmd;
3066c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3067c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ci = pci_alloc_consistent(instance->pdev,
3068c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				  sizeof(struct megasas_ctrl_info), &ci_h);
3069c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3070c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!ci) {
3071c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "Failed to alloc mem for ctrl info\n");
3072c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		megasas_return_cmd(instance, cmd);
3073c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENOMEM;
3074c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3075c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3076c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(ci, 0, sizeof(*ci));
3077c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3078c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3079c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->cmd = MFI_CMD_DCMD;
3080c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->cmd_status = 0xFF;
3081c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sge_count = 1;
3082c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->flags = MFI_FRAME_DIR_READ;
3083c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->timeout = 0;
3084780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo	dcmd->pad_0 = 0;
3085c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->data_xfer_len = sizeof(struct megasas_ctrl_info);
3086c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->opcode = MR_DCMD_CTRL_GET_INFO;
3087c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sgl.sge32[0].phys_addr = ci_h;
3088c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sgl.sge32[0].length = sizeof(struct megasas_ctrl_info);
3089c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3090c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!megasas_issue_polled(instance, cmd)) {
3091c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ret = 0;
3092c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info));
3093c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	} else {
3094c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		ret = -1;
3095c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3096c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3097c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
3098c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			    ci, ci_h);
3099c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_return_cmd(instance, cmd);
3101c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return ret;
3102c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
3103c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3104c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
310531ea7088974c2405e19d72f17c2afb103ef19e02bo yang * megasas_issue_init_mfi -	Initializes the FW
310631ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @instance:		Adapter soft state
310731ea7088974c2405e19d72f17c2afb103ef19e02bo yang *
310831ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Issues the INIT MFI cmd
310931ea7088974c2405e19d72f17c2afb103ef19e02bo yang */
311031ea7088974c2405e19d72f17c2afb103ef19e02bo yangstatic int
311131ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_issue_init_mfi(struct megasas_instance *instance)
311231ea7088974c2405e19d72f17c2afb103ef19e02bo yang{
311331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	u32 context;
311431ea7088974c2405e19d72f17c2afb103ef19e02bo yang
311531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	struct megasas_cmd *cmd;
311631ea7088974c2405e19d72f17c2afb103ef19e02bo yang
311731ea7088974c2405e19d72f17c2afb103ef19e02bo yang	struct megasas_init_frame *init_frame;
311831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	struct megasas_init_queue_info *initq_info;
311931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	dma_addr_t init_frame_h;
312031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	dma_addr_t initq_info_h;
312131ea7088974c2405e19d72f17c2afb103ef19e02bo yang
312231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	/*
312331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * Prepare a init frame. Note the init frame points to queue info
312431ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * structure. Each frame has SGL allocated after first 64 bytes. For
312531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * this frame - since we don't need any SGL - we use SGL's space as
312631ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * queue info structure
312731ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 *
312831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * We will not get a NULL command below. We just created the pool.
312931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 */
313031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	cmd = megasas_get_cmd(instance);
313131ea7088974c2405e19d72f17c2afb103ef19e02bo yang
313231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	init_frame = (struct megasas_init_frame *)cmd->frame;
313331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	initq_info = (struct megasas_init_queue_info *)
313431ea7088974c2405e19d72f17c2afb103ef19e02bo yang		((unsigned long)init_frame + 64);
313531ea7088974c2405e19d72f17c2afb103ef19e02bo yang
313631ea7088974c2405e19d72f17c2afb103ef19e02bo yang	init_frame_h = cmd->frame_phys_addr;
313731ea7088974c2405e19d72f17c2afb103ef19e02bo yang	initq_info_h = init_frame_h + 64;
313831ea7088974c2405e19d72f17c2afb103ef19e02bo yang
313931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	context = init_frame->context;
314031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
314131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
314231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	init_frame->context = context;
314331ea7088974c2405e19d72f17c2afb103ef19e02bo yang
314431ea7088974c2405e19d72f17c2afb103ef19e02bo yang	initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
314531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h;
314631ea7088974c2405e19d72f17c2afb103ef19e02bo yang
314731ea7088974c2405e19d72f17c2afb103ef19e02bo yang	initq_info->producer_index_phys_addr_lo = instance->producer_h;
314831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	initq_info->consumer_index_phys_addr_lo = instance->consumer_h;
314931ea7088974c2405e19d72f17c2afb103ef19e02bo yang
315031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	init_frame->cmd = MFI_CMD_INIT;
315131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	init_frame->cmd_status = 0xFF;
315231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	init_frame->queue_info_new_phys_addr_lo = initq_info_h;
315331ea7088974c2405e19d72f17c2afb103ef19e02bo yang
315431ea7088974c2405e19d72f17c2afb103ef19e02bo yang	init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);
315531ea7088974c2405e19d72f17c2afb103ef19e02bo yang
315631ea7088974c2405e19d72f17c2afb103ef19e02bo yang	/*
315731ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * disable the intr before firing the init frame to FW
315831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 */
315931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	instance->instancet->disable_intr(instance->reg_set);
316031ea7088974c2405e19d72f17c2afb103ef19e02bo yang
316131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	/*
316231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * Issue the init frame in polled mode
316331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 */
316431ea7088974c2405e19d72f17c2afb103ef19e02bo yang
316531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (megasas_issue_polled(instance, cmd)) {
316631ea7088974c2405e19d72f17c2afb103ef19e02bo yang		printk(KERN_ERR "megasas: Failed to init firmware\n");
316731ea7088974c2405e19d72f17c2afb103ef19e02bo yang		megasas_return_cmd(instance, cmd);
316831ea7088974c2405e19d72f17c2afb103ef19e02bo yang		goto fail_fw_init;
316931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	}
317031ea7088974c2405e19d72f17c2afb103ef19e02bo yang
317131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	megasas_return_cmd(instance, cmd);
317231ea7088974c2405e19d72f17c2afb103ef19e02bo yang
317331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	return 0;
317431ea7088974c2405e19d72f17c2afb103ef19e02bo yang
317531ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_fw_init:
317631ea7088974c2405e19d72f17c2afb103ef19e02bo yang	return -EINVAL;
317731ea7088974c2405e19d72f17c2afb103ef19e02bo yang}
317831ea7088974c2405e19d72f17c2afb103ef19e02bo yang
317931ea7088974c2405e19d72f17c2afb103ef19e02bo yang/**
3180ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * megasas_start_timer - Initializes a timer object
3181ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @instance:		Adapter soft state
3182ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @timer:		timer object to be initialized
3183ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @fn:			timer function
3184ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @interval:		time interval between timer function call
3185ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang */
3186ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangstatic inline void
3187ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangmegasas_start_timer(struct megasas_instance *instance,
3188ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			struct timer_list *timer,
3189ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			void *fn, unsigned long interval)
3190ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang{
3191ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	init_timer(timer);
3192ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	timer->expires = jiffies + interval;
3193ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	timer->data = (unsigned long)instance;
3194ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	timer->function = fn;
3195ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	add_timer(timer);
3196ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang}
3197ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
3198ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang/**
3199ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * megasas_io_completion_timer - Timer fn
3200ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @instance_addr:	Address of adapter soft state
3201ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang *
3202ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * Schedules tasklet for cmd completion
3203ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * if poll_mode_io is set
3204ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang */
3205ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangstatic void
3206ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangmegasas_io_completion_timer(unsigned long instance_addr)
3207ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang{
3208ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	struct megasas_instance *instance =
3209ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			(struct megasas_instance *)instance_addr;
3210ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
3211ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if (atomic_read(&instance->fw_outstanding))
3212ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		tasklet_schedule(&instance->isr_tasklet);
3213ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
3214ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	/* Restart timer */
3215ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if (poll_mode_io)
3216ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		mod_timer(&instance->io_completion_timer,
3217ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL);
3218ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang}
3219ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
3220ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang/**
3221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_init_mfi -	Initializes the FW
3222c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
3223c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
3224c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This is the main function for initializing MFI firmware.
3225c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
3226c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_init_mfi(struct megasas_instance *instance)
3227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
3228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 context_sz;
3229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 reply_q_sz;
3230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 max_sectors_1;
3231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 max_sectors_2;
323214faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang	u32 tmp_sectors;
3233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_register_set __iomem *reg_set;
3234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_ctrl_info *ctrl_info;
3235c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Map the message registers
3237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
32386610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
3239879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
3240879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
32416610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
32426610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo		instance->base_addr = pci_resource_start(instance->pdev, 1);
32436610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	} else {
32446610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo		instance->base_addr = pci_resource_start(instance->pdev, 0);
32456610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo	}
3246c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3247aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii	if (pci_request_selected_regions(instance->pdev,
3248aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii		pci_select_bars(instance->pdev, IORESOURCE_MEM),
3249aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii		"megasas: LSI")) {
3250c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: IO memory region busy!\n");
3251c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -EBUSY;
3252c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3253c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3254c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
3255c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3256c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!instance->reg_set) {
3257c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
3258c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_ioremap;
3259c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3260c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3261c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	reg_set = instance->reg_set;
3262c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3263f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	switch(instance->pdev->device)
3264f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	{
3265af7a5647c03c18f5ea58033710ccb23d71727e0cbo yang		case PCI_DEVICE_ID_LSI_SAS1078R:
3266af7a5647c03c18f5ea58033710ccb23d71727e0cbo yang		case PCI_DEVICE_ID_LSI_SAS1078DE:
3267f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro			instance->instancet = &megasas_instance_template_ppc;
3268f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro			break;
32696610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo		case PCI_DEVICE_ID_LSI_SAS1078GEN2:
32706610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo		case PCI_DEVICE_ID_LSI_SAS0079GEN2:
32716610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo			instance->instancet = &megasas_instance_template_gen2;
32726610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo			break;
3273879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo		case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
3274879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo		case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
3275879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo			instance->instancet = &megasas_instance_template_skinny;
3276879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo			break;
3277f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro		case PCI_DEVICE_ID_LSI_SAS1064R:
3278f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro		case PCI_DEVICE_ID_DELL_PERC5:
3279f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro		default:
3280f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro			instance->instancet = &megasas_instance_template_xscale;
3281f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro			break;
3282f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro	}
32831341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro
3284c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3285c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * We expect the FW state to be READY
3286c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
32871341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	if (megasas_transition_to_ready(instance))
3288c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_ready_state;
3289c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3290c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3291c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Get various operational parameters from status register
3292c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
32931341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
3294e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro	/*
3295e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro	 * Reduce the max supported cmds by 1. This is to ensure that the
3296e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro	 * reply_q_sz (1 more than the max cmd that driver may send)
3297e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro	 * does not exceed max cmds that the FW can support
3298e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro	 */
3299e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro	instance->max_fw_cmds = instance->max_fw_cmds-1;
33000d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford	instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
33011341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro					0x10;
3302c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3303c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Create a pool of commands
3304c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3305c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (megasas_alloc_cmds(instance))
3306c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_alloc_cmds;
3307c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3308c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3309c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Allocate memory for reply queue. Length of reply queue should
3310c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * be _one_ more than the maximum commands handled by the firmware.
3311c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 *
3312c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Note: When FW completes commands, it places corresponding contex
3313c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * values in this circular reply queue. This circular queue is a fairly
3314c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * typical producer-consumer queue. FW is the producer (of completed
3315c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * commands) and the driver is the consumer.
3316c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3317c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	context_sz = sizeof(u32);
3318c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	reply_q_sz = context_sz * (instance->max_fw_cmds + 1);
3319c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3320c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->reply_queue = pci_alloc_consistent(instance->pdev,
3321c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						     reply_q_sz,
3322c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						     &instance->reply_queue_h);
3323c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3324c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!instance->reply_queue) {
3325c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n");
3326c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_reply_queue;
3327c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3328c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
332931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (megasas_issue_init_mfi(instance))
3330c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_fw_init;
3331c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
333239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	instance->fw_support_ieee = 0;
333339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	instance->fw_support_ieee =
333439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		(instance->instancet->read_fw_status_reg(reg_set) &
333539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		0x04000000);
333639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
333739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	printk(KERN_NOTICE "megasas_init_mfi: fw_support_ieee=%d",
333839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			instance->fw_support_ieee);
333939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
334039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->fw_support_ieee)
334139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		instance->flag_ieee = 1;
334239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
334339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	/** for passthrough
334439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	* the following function will get the PD LIST.
334539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	*/
334639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
334781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	memset(instance->pd_list, 0 ,
334881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo		(MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
334981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo	megasas_get_pd_list(instance);
335081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo
3351bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
3352bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo	megasas_get_ld_list(instance);
3353bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo
3354c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
3355c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3356c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3357c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Compute the max allowed sectors per IO: The controller info has two
3358c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * limits on max sectors. Driver should use the minimum of these two.
3359c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 *
3360c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * 1 << stripe_sz_ops.min = max sectors per strip
3361c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 *
3362c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Note that older firmwares ( < FW ver 30) didn't report information
3363c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * to calculate max_sectors_1. So the number ended up as zero always.
3364c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
336514faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang	tmp_sectors = 0;
3366c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) {
3367c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3368c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
3369c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    ctrl_info->max_strips_per_io;
3370c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		max_sectors_2 = ctrl_info->max_request_size;
3371c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
337214faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang		tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2);
337339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		instance->disableOnlineCtrlReset =
337439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
337514faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang	}
337614faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang
337714faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang	instance->max_sectors_per_req = instance->max_num_sge *
337814faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang						PAGE_SIZE / 512;
337914faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang	if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
338014faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang		instance->max_sectors_per_req = tmp_sectors;
3381c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3382c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	kfree(ctrl_info);
3383c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
33845d018ad057347995e5c4564b3e43339e6497f839Sumant Patro        /*
33855d018ad057347995e5c4564b3e43339e6497f839Sumant Patro	* Setup tasklet for cmd completion
33865d018ad057347995e5c4564b3e43339e6497f839Sumant Patro	*/
33875d018ad057347995e5c4564b3e43339e6497f839Sumant Patro
3388ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
3389ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		(unsigned long)instance);
3390ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
3391ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	/* Initialize the cmd completion timer */
3392ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if (poll_mode_io)
3393ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		megasas_start_timer(instance, &instance->io_completion_timer,
3394ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang				megasas_io_completion_timer,
3395ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang				MEGASAS_COMPLETION_TIMER_INTERVAL);
3396c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
3397c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3398c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_fw_init:
3399c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3400c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_free_consistent(instance->pdev, reply_q_sz,
3401c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			    instance->reply_queue, instance->reply_queue_h);
3402c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_reply_queue:
3403c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_free_cmds(instance);
3404c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3405c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_alloc_cmds:
3406c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_ready_state:
3407c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	iounmap(instance->reg_set);
3408c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3409c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_ioremap:
3410aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii	pci_release_selected_regions(instance->pdev,
3411aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii		pci_select_bars(instance->pdev, IORESOURCE_MEM));
3412c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3413c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return -EINVAL;
3414c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
3415c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3416c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
3417c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_release_mfi -	Reverses the FW initialization
3418c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @intance:			Adapter soft state
3419c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
3420c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_release_mfi(struct megasas_instance *instance)
3421c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
3422c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	u32 reply_q_sz = sizeof(u32) * (instance->max_fw_cmds + 1);
3423c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3424c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_free_consistent(instance->pdev, reply_q_sz,
3425c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			    instance->reply_queue, instance->reply_queue_h);
3426c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3427c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_free_cmds(instance);
3428c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3429c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	iounmap(instance->reg_set);
3430c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3431aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii	pci_release_selected_regions(instance->pdev,
3432aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii		pci_select_bars(instance->pdev, IORESOURCE_MEM));
3433c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
3434c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3435c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
3436c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_get_seq_num -	Gets latest event sequence numbers
3437c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
3438c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @eli:			FW event log sequence numbers information
3439c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
3440c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * FW maintains a log of all events in a non-volatile area. Upper layers would
3441c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * usually find out the latest sequence number of the events, the seq number at
3442c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the boot etc. They would "read" all the events below the latest seq number
3443c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq
3444c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * number), they would subsribe to AEN (asynchronous event notification) and
3445c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * wait for the events to happen.
3446c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
3447c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int
3448c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_get_seq_num(struct megasas_instance *instance,
3449c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    struct megasas_evt_log_info *eli)
3450c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
3451c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
3452c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_dcmd_frame *dcmd;
3453c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_evt_log_info *el_info;
3454c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dma_addr_t el_info_h = 0;
3455c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3456c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd = megasas_get_cmd(instance);
3457c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3458c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!cmd) {
3459c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENOMEM;
3460c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3461c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3462c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd = &cmd->frame->dcmd;
3463c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	el_info = pci_alloc_consistent(instance->pdev,
3464c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				       sizeof(struct megasas_evt_log_info),
3465c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				       &el_info_h);
3466c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3467c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!el_info) {
3468c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		megasas_return_cmd(instance, cmd);
3469c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENOMEM;
3470c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3471c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3472c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(el_info, 0, sizeof(*el_info));
3473c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3474c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3475c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->cmd = MFI_CMD_DCMD;
3476c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->cmd_status = 0x0;
3477c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sge_count = 1;
3478c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->flags = MFI_FRAME_DIR_READ;
3479c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->timeout = 0;
3480780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo	dcmd->pad_0 = 0;
3481c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->data_xfer_len = sizeof(struct megasas_evt_log_info);
3482c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO;
3483c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sgl.sge32[0].phys_addr = el_info_h;
3484c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_log_info);
3485c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3486c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_issue_blocked_cmd(instance, cmd);
3487c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3488c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3489c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Copy the data back into callers buffer
3490c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3491c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memcpy(eli, el_info, sizeof(struct megasas_evt_log_info));
3492c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3493c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info),
3494c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			    el_info, el_info_h);
3495c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3496c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_return_cmd(instance, cmd);
3497c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3498c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
3499c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
3500c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3501c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
3502c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_register_aen -	Registers for asynchronous event notification
3503c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
3504c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @seq_num:			The starting sequence number
3505c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @class_locale:		Class of the event
3506c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
3507c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function subscribes for AEN for events beyond the @seq_num. It requests
3508c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to be notified if and only if the event is of type @class_locale
3509c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
3510c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int
3511c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_register_aen(struct megasas_instance *instance, u32 seq_num,
3512c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		     u32 class_locale_word)
3513c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
3514c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int ret_val;
3515c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
3516c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_dcmd_frame *dcmd;
3517c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	union megasas_evt_class_locale curr_aen;
3518c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	union megasas_evt_class_locale prev_aen;
3519c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3520c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3521c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * If there an AEN pending already (aen_cmd), check if the
3522c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * class_locale of that pending AEN is inclusive of the new
3523c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * AEN request we currently have. If it is, then we don't have
3524c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * to do anything. In other words, whichever events the current
3525c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * AEN request is subscribing to, have already been subscribed
3526c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * to.
3527c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 *
3528c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * If the old_cmd is _not_ inclusive, then we have to abort
3529c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * that command, form a class_locale that is superset of both
3530c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * old and current and re-issue to the FW
3531c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3532c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3533c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	curr_aen.word = class_locale_word;
3534c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3535c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (instance->aen_cmd) {
3536c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3537c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1];
3538c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3539c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/*
3540c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * A class whose enum value is smaller is inclusive of all
3541c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * higher values. If a PROGRESS (= -1) was previously
3542c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * registered, then a new registration requests for higher
3543c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * classes need not be sent to FW. They are automatically
3544c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * included.
3545c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 *
3546c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * Locale numbers don't have such hierarchy. They are bitmap
3547c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * values
3548c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 */
3549c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if ((prev_aen.members.class <= curr_aen.members.class) &&
3550c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    !((prev_aen.members.locale & curr_aen.members.locale) ^
3551c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		      curr_aen.members.locale)) {
3552c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			/*
3553c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 * Previously issued event registration includes
3554c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 * current request. Nothing to do.
3555c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 */
3556c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			return 0;
3557c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		} else {
3558c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			curr_aen.members.locale |= prev_aen.members.locale;
3559c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3560c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			if (prev_aen.members.class < curr_aen.members.class)
3561c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				curr_aen.members.class = prev_aen.members.class;
3562c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3563c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			instance->aen_cmd->abort_aen = 1;
3564c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			ret_val = megasas_issue_blocked_abort_cmd(instance,
3565c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas								  instance->
3566c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas								  aen_cmd);
3567c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3568c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			if (ret_val) {
3569c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				printk(KERN_DEBUG "megasas: Failed to abort "
3570c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				       "previous AEN command\n");
3571c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				return ret_val;
3572c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			}
3573c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
3574c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3575c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3576c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd = megasas_get_cmd(instance);
3577c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3578c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!cmd)
3579c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENOMEM;
3580c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3581c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd = &cmd->frame->dcmd;
3582c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3583c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail));
3584c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3585c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3586c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Prepare DCMD for aen registration
3587c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3588c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3589c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3590c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->cmd = MFI_CMD_DCMD;
3591c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->cmd_status = 0x0;
3592c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sge_count = 1;
3593c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->flags = MFI_FRAME_DIR_READ;
3594c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->timeout = 0;
3595780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo	dcmd->pad_0 = 0;
359639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	instance->last_seq_num = seq_num;
3597c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->data_xfer_len = sizeof(struct megasas_evt_detail);
3598c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT;
3599c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->mbox.w[0] = seq_num;
3600c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->mbox.w[1] = curr_aen.word;
3601c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
3602c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
3603c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3604f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	if (instance->aen_cmd != NULL) {
3605f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		megasas_return_cmd(instance, cmd);
3606f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		return 0;
3607f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	}
3608f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo
3609c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3610c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Store reference to the cmd used to register for AEN. When an
3611c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * application wants us to register for AEN, we have to abort this
3612c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * cmd and re-register with a new EVENT LOCALE supplied by that app
3613c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3614c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->aen_cmd = cmd;
3615c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3616c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3617c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Issue the aen registration frame
3618c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
36190c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	instance->instancet->fire_cmd(instance,
36200c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo			cmd->frame_phys_addr, 0, instance->reg_set);
3621c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3622c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
3623c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
3624c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3625c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
3626c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_start_aen -	Subscribes to AEN during driver load time
3627c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
3628c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
3629c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_start_aen(struct megasas_instance *instance)
3630c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
3631c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_evt_log_info eli;
3632c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	union megasas_evt_class_locale class_locale;
3633c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3634c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3635c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Get the latest sequence number from FW
3636c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3637c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(&eli, 0, sizeof(eli));
3638c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3639c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (megasas_get_seq_num(instance, &eli))
3640c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -1;
3641c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3642c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3643c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Register AEN with FW for latest sequence number plus 1
3644c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3645c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	class_locale.members.reserved = 0;
3646c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	class_locale.members.locale = MR_EVT_LOCALE_ALL;
3647c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	class_locale.members.class = MR_EVT_CLASS_DEBUG;
3648c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3649c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return megasas_register_aen(instance, eli.newest_seq_num + 1,
3650c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				    class_locale.word);
3651c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
3652c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3653c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
3654c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_io_attach -	Attaches this driver to SCSI mid-layer
3655c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:		Adapter soft state
3656c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
3657c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_io_attach(struct megasas_instance *instance)
3658c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
3659c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct Scsi_Host *host = instance->host;
3660c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3661c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3662c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Export parameters required by SCSI mid-layer
3663c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3664c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host->irq = instance->pdev->irq;
3665c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host->unique_id = instance->unique_id;
36667bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
36677bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
36687bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo		host->can_queue =
36697bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo			instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
36707bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo	} else
36717bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo		host->can_queue =
36727bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo			instance->max_fw_cmds - MEGASAS_INT_CMDS;
3673c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host->this_id = instance->init_id;
3674c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host->sg_tablesize = instance->max_num_sge;
36751fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo	/*
36761fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo	 * Check if the module parameter value for max_sectors can be used
36771fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo	 */
36781fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo	if (max_sectors && max_sectors < instance->max_sectors_per_req)
36791fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo		instance->max_sectors_per_req = max_sectors;
36801fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo	else {
36811fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo		if (max_sectors) {
36821fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo			if (((instance->pdev->device ==
36831fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo				PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
36841fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo				(instance->pdev->device ==
36851fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo				PCI_DEVICE_ID_LSI_SAS0079GEN2)) &&
36861fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo				(max_sectors <= MEGASAS_MAX_SECTORS)) {
36871fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo				instance->max_sectors_per_req = max_sectors;
36881fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo			} else {
36891fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo			printk(KERN_INFO "megasas: max_sectors should be > 0"
36901fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo				"and <= %d (or < 1MB for GEN2 controller)\n",
36911fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo				instance->max_sectors_per_req);
36921fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo			}
36931fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo		}
36941fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo	}
36951fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo
3696c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host->max_sectors = instance->max_sectors_per_req;
3697c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host->cmd_per_lun = 128;
3698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host->max_channel = MEGASAS_MAX_CHANNELS - 1;
3699c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
3700c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host->max_lun = MEGASAS_MAX_LUN;
3701122da30223c06cee181044af6d32e88b256d10dfJoshua Giles	host->max_cmd_len = 16;
3702c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3703c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3704c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Notify the mid-layer about the new controller
3705c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3706c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (scsi_add_host(host, &instance->pdev->dev)) {
3707c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: scsi_add_host failed\n");
3708c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENODEV;
3709c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3710c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3711c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3712c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Trigger SCSI to scan our drives
3713c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3714c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	scsi_scan_host(host);
3715c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
3716c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
3717c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
371831ea7088974c2405e19d72f17c2afb103ef19e02bo yangstatic int
371931ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_set_dma_mask(struct pci_dev *pdev)
372031ea7088974c2405e19d72f17c2afb103ef19e02bo yang{
372131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	/*
372231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * All our contollers are capable of performing 64-bit DMA
372331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 */
372431ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (IS_DMA64) {
37256a35528a8346f6e6fd32ed7e51f04d1fa4ca2c01Yang Hongyang		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
372631ea7088974c2405e19d72f17c2afb103ef19e02bo yang
3727284901a90a9e0b812ca3f5f852cbbfb60d10249dYang Hongyang			if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
372831ea7088974c2405e19d72f17c2afb103ef19e02bo yang				goto fail_set_dma_mask;
372931ea7088974c2405e19d72f17c2afb103ef19e02bo yang		}
373031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	} else {
3731284901a90a9e0b812ca3f5f852cbbfb60d10249dYang Hongyang		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
373231ea7088974c2405e19d72f17c2afb103ef19e02bo yang			goto fail_set_dma_mask;
373331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	}
373431ea7088974c2405e19d72f17c2afb103ef19e02bo yang	return 0;
373531ea7088974c2405e19d72f17c2afb103ef19e02bo yang
373631ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_set_dma_mask:
373731ea7088974c2405e19d72f17c2afb103ef19e02bo yang	return 1;
373831ea7088974c2405e19d72f17c2afb103ef19e02bo yang}
373931ea7088974c2405e19d72f17c2afb103ef19e02bo yang
3740c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
3741c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_probe_one -	PCI hotplug entry point
3742c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @pdev:		PCI device structure
37430d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * @id:			PCI ids of supported hotplugged adapter
3744c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
3745c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int __devinit
3746c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
3747c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
3748c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int rval;
3749c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct Scsi_Host *host;
3750c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_instance *instance;
3751c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3752c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3753c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Announce PCI information
3754c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3755c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	printk(KERN_INFO "megasas: %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
3756c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	       pdev->vendor, pdev->device, pdev->subsystem_vendor,
3757c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	       pdev->subsystem_device);
3758c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3759c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	printk("bus %d:slot %d:func %d\n",
3760c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	       pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
3761c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3762c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3763c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * PCI prepping: enable device set bus mastering and dma mask
3764c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3765aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii	rval = pci_enable_device_mem(pdev);
3766c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3767c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (rval) {
3768c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return rval;
3769c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3770c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3771c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_set_master(pdev);
3772c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
377331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (megasas_set_dma_mask(pdev))
377431ea7088974c2405e19d72f17c2afb103ef19e02bo yang		goto fail_set_dma_mask;
3775c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3776c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host = scsi_host_alloc(&megasas_template,
3777c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			       sizeof(struct megasas_instance));
3778c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3779c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!host) {
3780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: scsi_host_alloc failed\n");
3781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_alloc_instance;
3782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3783c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3784c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance = (struct megasas_instance *)host->hostdata;
3785c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(instance, 0, sizeof(*instance));
378639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	atomic_set( &instance->fw_reset_no_pci_access, 0 );
3787c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3788c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->producer = pci_alloc_consistent(pdev, sizeof(u32),
3789c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						  &instance->producer_h);
3790c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->consumer = pci_alloc_consistent(pdev, sizeof(u32),
3791c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						  &instance->consumer_h);
3792c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3793c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!instance->producer || !instance->consumer) {
3794c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: Failed to allocate memory for "
3795c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		       "producer, consumer\n");
3796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_alloc_dma_buf;
3797c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3798c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3799c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	*instance->producer = 0;
3800c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	*instance->consumer = 0;
3801c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	megasas_poll_wait_aen = 0;
3802f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo	instance->flag_ieee = 0;
38037e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	instance->ev = NULL;
380439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	instance->issuepend_done = 1;
380539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
380639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	megasas_poll_wait_aen = 0;
3807c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3808c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->evt_detail = pci_alloc_consistent(pdev,
3809c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						    sizeof(struct
3810c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas							   megasas_evt_detail),
3811c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						    &instance->evt_detail_h);
3812c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3813c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!instance->evt_detail) {
3814c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: Failed to allocate memory for "
3815c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		       "event detail structure\n");
3816c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_alloc_dma_buf;
3817c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3818c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3819c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3820c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Initialize locks and queues
3821c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3822c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	INIT_LIST_HEAD(&instance->cmd_pool);
382339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	INIT_LIST_HEAD(&instance->internal_reset_pending_q);
3824c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3825e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro	atomic_set(&instance->fw_outstanding,0);
3826e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro
3827c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	init_waitqueue_head(&instance->int_cmd_wait_q);
3828c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	init_waitqueue_head(&instance->abort_cmd_wait_q);
3829c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3830c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	spin_lock_init(&instance->cmd_pool_lock);
383139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_init(&instance->hba_lock);
38327343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang	spin_lock_init(&instance->completion_lock);
3833c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	spin_lock_init(&poll_aen_lock);
3834c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3835e5a69e27cc193f98c9a5a9086e3bf85528170623Matthias Kaehlcke	mutex_init(&instance->aen_mutex);
3836c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3837c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3838c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Initialize PCI related and misc parameters
3839c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3840c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->pdev = pdev;
3841c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->host = host;
3842c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
3843c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance->init_id = MEGASAS_DEFAULT_INIT_ID;
3844c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
38457bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
38467bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
3847f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo		instance->flag_ieee = 1;
38487bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo		sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
38497bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo	} else
38507bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo		sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
38517bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo
3852658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	megasas_dbg_lvl = 0;
385305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	instance->flag = 0;
38540c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	instance->unload = 1;
385505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro	instance->last_time = 0;
385639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	instance->disableOnlineCtrlReset = 1;
385739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
385839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	INIT_WORK(&instance->work_init, process_fw_state_change_wq);
3859658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro
3860c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3861c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Initialize MFI Firmware
3862c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3863c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (megasas_init_mfi(instance))
3864c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_init_mfi;
3865c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3866c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3867c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Register IRQ
3868c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
38691d6f359a2e06296418481239f8054a878f36e819Thomas Gleixner	if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED, "megasas", instance)) {
3870c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
3871c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_irq;
3872c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3873c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
38741341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro	instance->instancet->enable_intr(instance->reg_set);
3875c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3876c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3877c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Store instance in PCI softstate
3878c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3879c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_set_drvdata(pdev, instance);
3880c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3881c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3882c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Add this controller to megasas_mgmt_info structure so that it
3883c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * can be exported to management applications
3884c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3885c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_mgmt_info.count++;
3886c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance;
3887c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_mgmt_info.max_index++;
3888c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3889c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3890c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Initiate AEN (Asynchronous Event Notification)
3891c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3892c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (megasas_start_aen(instance)) {
3893c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: start aen failed\n");
3894c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_start_aen;
3895c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
3896c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3897c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
3898c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Register with SCSI mid-layer
3899c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
3900c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (megasas_io_attach(instance))
3901c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto fail_io_attach;
3902c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
39030c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	instance->unload = 0;
3904c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
3905c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3906c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_start_aen:
3907c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_io_attach:
3908c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_mgmt_info.count--;
3909c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
3910c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_mgmt_info.max_index--;
3911c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3912c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_set_drvdata(pdev, NULL);
3913b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	instance->instancet->disable_intr(instance->reg_set);
3914c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	free_irq(instance->pdev->irq, instance);
3915c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3916c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_release_mfi(instance);
3917c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3918c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_irq:
3919c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_init_mfi:
3920c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_alloc_dma_buf:
3921c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (instance->evt_detail)
3922c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
3923c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				    instance->evt_detail,
3924c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				    instance->evt_detail_h);
3925c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3926c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (instance->producer)
3927c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		pci_free_consistent(pdev, sizeof(u32), instance->producer,
3928c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				    instance->producer_h);
3929c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (instance->consumer)
3930c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		pci_free_consistent(pdev, sizeof(u32), instance->consumer,
3931c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				    instance->consumer_h);
3932c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	scsi_host_put(host);
3933c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_alloc_instance:
3935c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      fail_set_dma_mask:
3936c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_disable_device(pdev);
3937c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3938c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return -ENODEV;
3939c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
3940c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3941c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
3942c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_flush_cache -	Requests FW to flush all its caches
3943c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
3944c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
3945c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_flush_cache(struct megasas_instance *instance)
3946c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
3947c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
3948c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_dcmd_frame *dcmd;
3949c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
395039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
395139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return;
395239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
3953c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd = megasas_get_cmd(instance);
3954c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3955c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!cmd)
3956c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return;
3957c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3958c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd = &cmd->frame->dcmd;
3959c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3960c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3961c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3962c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->cmd = MFI_CMD_DCMD;
3963c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->cmd_status = 0x0;
3964c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sge_count = 0;
3965c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->flags = MFI_FRAME_DIR_NONE;
3966c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->timeout = 0;
3967780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo	dcmd->pad_0 = 0;
3968c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->data_xfer_len = 0;
3969c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH;
3970c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
3971c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3972c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_issue_blocked_cmd(instance, cmd);
3973c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3974c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_return_cmd(instance, cmd);
3975c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3976c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return;
3977c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
3978c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3979c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
3980c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_shutdown_controller -	Instructs FW to shutdown the controller
3981c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:				Adapter soft state
398231ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @opcode:				Shutdown/Hibernate
3983c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
398431ea7088974c2405e19d72f17c2afb103ef19e02bo yangstatic void megasas_shutdown_controller(struct megasas_instance *instance,
398531ea7088974c2405e19d72f17c2afb103ef19e02bo yang					u32 opcode)
3986c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
3987c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
3988c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_dcmd_frame *dcmd;
3989c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
399039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
399139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return;
399239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
3993c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd = megasas_get_cmd(instance);
3994c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3995c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!cmd)
3996c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return;
3997c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
3998c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (instance->aen_cmd)
3999c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd);
4000c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4001c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd = &cmd->frame->dcmd;
4002c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4003c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4004c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4005c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->cmd = MFI_CMD_DCMD;
4006c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->cmd_status = 0x0;
4007c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->sge_count = 0;
4008c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->flags = MFI_FRAME_DIR_NONE;
4009c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->timeout = 0;
4010780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo	dcmd->pad_0 = 0;
4011c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dcmd->data_xfer_len = 0;
401231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	dcmd->opcode = opcode;
4013c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4014c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_issue_blocked_cmd(instance, cmd);
4015c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4016c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_return_cmd(instance, cmd);
4017c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4018c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return;
4019c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4020c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
402133139b21013aba815924b421159fab35e5175483Jiri Slaby#ifdef CONFIG_PM
4022c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
4023ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * megasas_suspend -	driver suspend entry point
4024ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @pdev:		PCI device structure
402531ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @state:		PCI power state to suspend routine
402631ea7088974c2405e19d72f17c2afb103ef19e02bo yang */
402733139b21013aba815924b421159fab35e5175483Jiri Slabystatic int
402831ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_suspend(struct pci_dev *pdev, pm_message_t state)
402931ea7088974c2405e19d72f17c2afb103ef19e02bo yang{
403031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	struct Scsi_Host *host;
403131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	struct megasas_instance *instance;
403231ea7088974c2405e19d72f17c2afb103ef19e02bo yang
403331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	instance = pci_get_drvdata(pdev);
403431ea7088974c2405e19d72f17c2afb103ef19e02bo yang	host = instance->host;
40350c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	instance->unload = 1;
403631ea7088974c2405e19d72f17c2afb103ef19e02bo yang
4037ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if (poll_mode_io)
4038ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		del_timer_sync(&instance->io_completion_timer);
4039ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
404031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	megasas_flush_cache(instance);
404131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
40427e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
40437e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	/* cancel the delayed work if this work still in queue */
40447e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	if (instance->ev != NULL) {
40457e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		struct megasas_aen_event *ev = instance->ev;
40467e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		cancel_delayed_work(
40477e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			(struct delayed_work *)&ev->hotplug_work);
40487e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		flush_scheduled_work();
40497e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		instance->ev = NULL;
40507e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	}
40517e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
405231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	tasklet_kill(&instance->isr_tasklet);
405331ea7088974c2405e19d72f17c2afb103ef19e02bo yang
405431ea7088974c2405e19d72f17c2afb103ef19e02bo yang	pci_set_drvdata(instance->pdev, instance);
405531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	instance->instancet->disable_intr(instance->reg_set);
405631ea7088974c2405e19d72f17c2afb103ef19e02bo yang	free_irq(instance->pdev->irq, instance);
405731ea7088974c2405e19d72f17c2afb103ef19e02bo yang
405831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	pci_save_state(pdev);
405931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	pci_disable_device(pdev);
406031ea7088974c2405e19d72f17c2afb103ef19e02bo yang
406131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	pci_set_power_state(pdev, pci_choose_state(pdev, state));
406231ea7088974c2405e19d72f17c2afb103ef19e02bo yang
406331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	return 0;
406431ea7088974c2405e19d72f17c2afb103ef19e02bo yang}
406531ea7088974c2405e19d72f17c2afb103ef19e02bo yang
406631ea7088974c2405e19d72f17c2afb103ef19e02bo yang/**
406731ea7088974c2405e19d72f17c2afb103ef19e02bo yang * megasas_resume-      driver resume entry point
406831ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @pdev:               PCI device structure
406931ea7088974c2405e19d72f17c2afb103ef19e02bo yang */
407033139b21013aba815924b421159fab35e5175483Jiri Slabystatic int
407131ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_resume(struct pci_dev *pdev)
407231ea7088974c2405e19d72f17c2afb103ef19e02bo yang{
407331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	int rval;
407431ea7088974c2405e19d72f17c2afb103ef19e02bo yang	struct Scsi_Host *host;
407531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	struct megasas_instance *instance;
407631ea7088974c2405e19d72f17c2afb103ef19e02bo yang
407731ea7088974c2405e19d72f17c2afb103ef19e02bo yang	instance = pci_get_drvdata(pdev);
407831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	host = instance->host;
407931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	pci_set_power_state(pdev, PCI_D0);
408031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	pci_enable_wake(pdev, PCI_D0, 0);
408131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	pci_restore_state(pdev);
408231ea7088974c2405e19d72f17c2afb103ef19e02bo yang
408331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	/*
408431ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * PCI prepping: enable device set bus mastering and dma mask
408531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 */
4086aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii	rval = pci_enable_device_mem(pdev);
408731ea7088974c2405e19d72f17c2afb103ef19e02bo yang
408831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (rval) {
408931ea7088974c2405e19d72f17c2afb103ef19e02bo yang		printk(KERN_ERR "megasas: Enable device failed\n");
409031ea7088974c2405e19d72f17c2afb103ef19e02bo yang		return rval;
409131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	}
409231ea7088974c2405e19d72f17c2afb103ef19e02bo yang
409331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	pci_set_master(pdev);
409431ea7088974c2405e19d72f17c2afb103ef19e02bo yang
409531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (megasas_set_dma_mask(pdev))
409631ea7088974c2405e19d72f17c2afb103ef19e02bo yang		goto fail_set_dma_mask;
409731ea7088974c2405e19d72f17c2afb103ef19e02bo yang
409831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	/*
409931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * Initialize MFI Firmware
410031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 */
410131ea7088974c2405e19d72f17c2afb103ef19e02bo yang
410231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	*instance->producer = 0;
410331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	*instance->consumer = 0;
410431ea7088974c2405e19d72f17c2afb103ef19e02bo yang
410531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	atomic_set(&instance->fw_outstanding, 0);
410631ea7088974c2405e19d72f17c2afb103ef19e02bo yang
410731ea7088974c2405e19d72f17c2afb103ef19e02bo yang	/*
410831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * We expect the FW state to be READY
410931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 */
411031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (megasas_transition_to_ready(instance))
411131ea7088974c2405e19d72f17c2afb103ef19e02bo yang		goto fail_ready_state;
411231ea7088974c2405e19d72f17c2afb103ef19e02bo yang
411331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (megasas_issue_init_mfi(instance))
411431ea7088974c2405e19d72f17c2afb103ef19e02bo yang		goto fail_init_mfi;
411531ea7088974c2405e19d72f17c2afb103ef19e02bo yang
411631ea7088974c2405e19d72f17c2afb103ef19e02bo yang	tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
411731ea7088974c2405e19d72f17c2afb103ef19e02bo yang			(unsigned long)instance);
411831ea7088974c2405e19d72f17c2afb103ef19e02bo yang
411931ea7088974c2405e19d72f17c2afb103ef19e02bo yang	/*
412031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * Register IRQ
412131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 */
412231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED,
412331ea7088974c2405e19d72f17c2afb103ef19e02bo yang		"megasas", instance)) {
412431ea7088974c2405e19d72f17c2afb103ef19e02bo yang		printk(KERN_ERR "megasas: Failed to register IRQ\n");
412531ea7088974c2405e19d72f17c2afb103ef19e02bo yang		goto fail_irq;
412631ea7088974c2405e19d72f17c2afb103ef19e02bo yang	}
412731ea7088974c2405e19d72f17c2afb103ef19e02bo yang
412831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	instance->instancet->enable_intr(instance->reg_set);
412931ea7088974c2405e19d72f17c2afb103ef19e02bo yang
413031ea7088974c2405e19d72f17c2afb103ef19e02bo yang	/*
413131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 * Initiate AEN (Asynchronous Event Notification)
413231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	 */
413331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (megasas_start_aen(instance))
413431ea7088974c2405e19d72f17c2afb103ef19e02bo yang		printk(KERN_ERR "megasas: Start AEN failed\n");
413531ea7088974c2405e19d72f17c2afb103ef19e02bo yang
4136ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	/* Initialize the cmd completion timer */
4137ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if (poll_mode_io)
4138ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		megasas_start_timer(instance, &instance->io_completion_timer,
4139ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang				megasas_io_completion_timer,
4140ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang				MEGASAS_COMPLETION_TIMER_INTERVAL);
41410c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	instance->unload = 0;
41420c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo
414331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	return 0;
414431ea7088974c2405e19d72f17c2afb103ef19e02bo yang
414531ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_irq:
414631ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_init_mfi:
414731ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (instance->evt_detail)
414831ea7088974c2405e19d72f17c2afb103ef19e02bo yang		pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
414931ea7088974c2405e19d72f17c2afb103ef19e02bo yang				instance->evt_detail,
415031ea7088974c2405e19d72f17c2afb103ef19e02bo yang				instance->evt_detail_h);
415131ea7088974c2405e19d72f17c2afb103ef19e02bo yang
415231ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (instance->producer)
415331ea7088974c2405e19d72f17c2afb103ef19e02bo yang		pci_free_consistent(pdev, sizeof(u32), instance->producer,
415431ea7088974c2405e19d72f17c2afb103ef19e02bo yang				instance->producer_h);
415531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	if (instance->consumer)
415631ea7088974c2405e19d72f17c2afb103ef19e02bo yang		pci_free_consistent(pdev, sizeof(u32), instance->consumer,
415731ea7088974c2405e19d72f17c2afb103ef19e02bo yang				instance->consumer_h);
415831ea7088974c2405e19d72f17c2afb103ef19e02bo yang	scsi_host_put(host);
415931ea7088974c2405e19d72f17c2afb103ef19e02bo yang
416031ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_set_dma_mask:
416131ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_ready_state:
416231ea7088974c2405e19d72f17c2afb103ef19e02bo yang
416331ea7088974c2405e19d72f17c2afb103ef19e02bo yang	pci_disable_device(pdev);
416431ea7088974c2405e19d72f17c2afb103ef19e02bo yang
416531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	return -ENODEV;
416631ea7088974c2405e19d72f17c2afb103ef19e02bo yang}
416733139b21013aba815924b421159fab35e5175483Jiri Slaby#else
416833139b21013aba815924b421159fab35e5175483Jiri Slaby#define megasas_suspend	NULL
416933139b21013aba815924b421159fab35e5175483Jiri Slaby#define megasas_resume	NULL
417033139b21013aba815924b421159fab35e5175483Jiri Slaby#endif
417131ea7088974c2405e19d72f17c2afb103ef19e02bo yang
417231ea7088974c2405e19d72f17c2afb103ef19e02bo yang/**
4173c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_detach_one -	PCI hot"un"plug entry point
4174c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @pdev:		PCI device structure
4175c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
417633139b21013aba815924b421159fab35e5175483Jiri Slabystatic void __devexit megasas_detach_one(struct pci_dev *pdev)
4177c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4178c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
4179c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct Scsi_Host *host;
4180c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_instance *instance;
4181c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4182c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance = pci_get_drvdata(pdev);
4183c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	instance->unload = 1;
4184c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	host = instance->host;
4185c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4186ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if (poll_mode_io)
4187ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		del_timer_sync(&instance->io_completion_timer);
4188ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
4189c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	scsi_remove_host(instance->host);
4190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_flush_cache(instance);
419131ea7088974c2405e19d72f17c2afb103ef19e02bo yang	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
41927e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
41937e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	/* cancel the delayed work if this work still in queue*/
41947e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	if (instance->ev != NULL) {
41957e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		struct megasas_aen_event *ev = instance->ev;
41967e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		cancel_delayed_work(
41977e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			(struct delayed_work *)&ev->hotplug_work);
41987e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		flush_scheduled_work();
41997e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		instance->ev = NULL;
42007e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	}
42017e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
42025d018ad057347995e5c4564b3e43339e6497f839Sumant Patro	tasklet_kill(&instance->isr_tasklet);
4203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
4205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Take the instance off the instance array. Note that we will not
4206c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * decrement the max_index. We let this array be sparse array
4207c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
4208c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; i < megasas_mgmt_info.max_index; i++) {
4209c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (megasas_mgmt_info.instance[i] == instance) {
4210c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			megasas_mgmt_info.count--;
4211c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			megasas_mgmt_info.instance[i] = NULL;
4212c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4213c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			break;
4214c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
4215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4216c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4217c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_set_drvdata(instance->pdev, NULL);
4218c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4219b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro	instance->instancet->disable_intr(instance->reg_set);
4220c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	free_irq(instance->pdev->irq, instance);
4222c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4223c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_release_mfi(instance);
4224c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4225c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
4226c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			    instance->evt_detail, instance->evt_detail_h);
4227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_free_consistent(pdev, sizeof(u32), instance->producer,
4229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			    instance->producer_h);
4230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_free_consistent(pdev, sizeof(u32), instance->consumer,
4232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			    instance->consumer_h);
4233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	scsi_host_put(host);
4235c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_set_drvdata(pdev, NULL);
4237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_disable_device(pdev);
4239c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4240c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return;
4241c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4242c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4243c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
4244c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_shutdown -	Shutdown entry point
4245c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @device:		Generic device structure
4246c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
4247c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_shutdown(struct pci_dev *pdev)
4248c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4249c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_instance *instance = pci_get_drvdata(pdev);
42500c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	instance->unload = 1;
4251c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_flush_cache(instance);
4252530e6fc1e05f14762aea954ca8d6422c5a7077c1Yang, Bo	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
4253c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4254c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4255c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
4256c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_open -	char node "open" entry point
4257c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
4258c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_open(struct inode *inode, struct file *filep)
4259c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4260c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
4261c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Allow only those users with admin rights
4262c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
4263c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!capable(CAP_SYS_ADMIN))
4264c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -EACCES;
4265c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4266c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return 0;
4267c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4268c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4269c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
4270c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_fasync -	Async notifier registration from applications
4271c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *
4272c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function adds the calling process to a driver global queue. When an
4273c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * event occurs, SIGIO will be sent to all processes in this queue.
4274c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
4275c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
4276c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4277c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int rc;
4278c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
42790b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven	mutex_lock(&megasas_async_queue_mutex);
4280c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4281c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
4282c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
42830b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven	mutex_unlock(&megasas_async_queue_mutex);
4284c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4285c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (rc >= 0) {
4286c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/* For sanity check when we get ioctl */
4287c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		filep->private_data = filep;
4288c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return 0;
4289c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4290c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4291c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc);
4292c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4293c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return rc;
4294c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4295c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4296c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
4297c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo * megasas_mgmt_poll -  char node "poll" entry point
4298c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo * */
4299c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bostatic unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
4300c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo{
4301c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	unsigned int mask;
4302c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	unsigned long flags;
4303c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	poll_wait(file, &megasas_poll_wait, wait);
4304c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	spin_lock_irqsave(&poll_aen_lock, flags);
4305c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	if (megasas_poll_wait_aen)
4306c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo		mask =   (POLLIN | POLLRDNORM);
4307c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	else
4308c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo		mask = 0;
4309c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	spin_unlock_irqrestore(&poll_aen_lock, flags);
4310c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	return mask;
4311c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo}
4312c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo
4313c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo/**
4314c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_fw_ioctl -	Issues management ioctls to FW
4315c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance:			Adapter soft state
4316c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @argp:			User's ioctl packet
4317c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
4318c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int
4319c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_mgmt_fw_ioctl(struct megasas_instance *instance,
4320c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		      struct megasas_iocpacket __user * user_ioc,
4321c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		      struct megasas_iocpacket *ioc)
4322c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4323c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_sge32 *kern_sge32;
4324c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_cmd *cmd;
4325c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	void *kbuff_arr[MAX_IOCTL_SGE];
4326c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dma_addr_t buf_handle = 0;
4327c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int error = 0, i;
4328c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	void *sense = NULL;
4329c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	dma_addr_t sense_handle;
43307b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo	unsigned long *sense_ptr;
4331c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4332c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(kbuff_arr, 0, sizeof(kbuff_arr));
4333c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4334c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (ioc->sge_count > MAX_IOCTL_SGE) {
4335c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: SGE count [%d] >  max limit [%d]\n",
4336c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		       ioc->sge_count, MAX_IOCTL_SGE);
4337c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -EINVAL;
4338c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4339c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4340c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd = megasas_get_cmd(instance);
4341c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!cmd) {
4342c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: Failed to get a cmd packet\n");
4343c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENOMEM;
4344c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4345c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4346c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
4347c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * User's IOCTL packet has 2 frames (maximum). Copy those two
4348c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * frames into our cmd's frames. cmd->frame's context will get
4349c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * overwritten when we copy from user's frames. So set that value
4350c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * alone separately
4351c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
4352c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
4353c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd->frame->hdr.context = cmd->index;
4354c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	cmd->frame->hdr.pad_0 = 0;
4355c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4356c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
4357c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * The management interface between applications and the fw uses
4358c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * MFI frames. E.g, RAID configuration changes, LD property changes
4359c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * etc are accomplishes through different kinds of MFI frames. The
4360c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * driver needs to care only about substituting user buffers with
4361c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * kernel buffers in SGLs. The location of SGL is embedded in the
4362c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * struct iocpacket itself.
4363c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
4364c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	kern_sge32 = (struct megasas_sge32 *)
4365c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    ((unsigned long)cmd->frame + ioc->sgl_off);
4366c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4367c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
4368c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * For each user buffer, create a mirror buffer and copy in
4369c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
4370c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; i < ioc->sge_count; i++) {
43719f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro		kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev,
4372c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas						    ioc->sgl[i].iov_len,
43739f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro						    &buf_handle, GFP_KERNEL);
4374c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (!kbuff_arr[i]) {
4375c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			printk(KERN_DEBUG "megasas: Failed to alloc "
4376c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			       "kernel SGL buffer for IOCTL \n");
4377c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			error = -ENOMEM;
4378c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			goto out;
4379c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
4380c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4381c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/*
4382c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * We don't change the dma_coherent_mask, so
4383c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * pci_alloc_consistent only returns 32bit addresses
4384c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 */
4385c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		kern_sge32[i].phys_addr = (u32) buf_handle;
4386c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		kern_sge32[i].length = ioc->sgl[i].iov_len;
4387c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4388c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/*
4389c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * We created a kernel buffer corresponding to the
4390c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * user buffer. Now copy in from the user buffer
4391c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 */
4392c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base,
4393c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				   (u32) (ioc->sgl[i].iov_len))) {
4394c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			error = -EFAULT;
4395c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			goto out;
4396c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
4397c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4398c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4399c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (ioc->sense_len) {
44009f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro		sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,
44019f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro					     &sense_handle, GFP_KERNEL);
4402c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (!sense) {
4403c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			error = -ENOMEM;
4404c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			goto out;
4405c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
4406c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4407c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		sense_ptr =
44087b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo		(unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
4409c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		*sense_ptr = sense_handle;
4410c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4411c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4412c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
4413c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Set the sync_cmd flag so that the ISR knows not to complete this
4414c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * cmd to the SCSI mid-layer
4415c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
4416c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd->sync_cmd = 1;
4417c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_issue_blocked_cmd(instance, cmd);
4418c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	cmd->sync_cmd = 0;
4419c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4420c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
4421c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * copy out the kernel buffers to user buffers
4422c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
4423c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; i < ioc->sge_count; i++) {
4424c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i],
4425c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				 ioc->sgl[i].iov_len)) {
4426c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			error = -EFAULT;
4427c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			goto out;
4428c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
4429c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4430c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4431c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
4432c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * copy out the sense
4433c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
4434c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (ioc->sense_len) {
4435c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		/*
4436b70a41e077b3405d4b41d34db31b39c05bf142b5bo yang		 * sense_ptr points to the location that has the user
4437c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 * sense buffer address
4438c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		 */
44397b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo		sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
44407b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo				ioc->sense_off);
4441c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4442b70a41e077b3405d4b41d34db31b39c05bf142b5bo yang		if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
4443b70a41e077b3405d4b41d34db31b39c05bf142b5bo yang				 sense, ioc->sense_len)) {
4444b10c36a57552f03582c0ab3ece04f3cce791922dbo yang			printk(KERN_ERR "megasas: Failed to copy out to user "
4445b10c36a57552f03582c0ab3ece04f3cce791922dbo yang					"sense data\n");
4446c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			error = -EFAULT;
4447c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			goto out;
4448c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		}
4449c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4450c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4451c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
4452c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * copy the status codes returned by the fw
4453c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
4454c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (copy_to_user(&user_ioc->frame.hdr.cmd_status,
4455c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 &cmd->frame->hdr.cmd_status, sizeof(u8))) {
4456c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: Error copying out cmd_status\n");
4457c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		error = -EFAULT;
4458c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4459c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4460c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      out:
4461c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (sense) {
44629f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro		dma_free_coherent(&instance->pdev->dev, ioc->sense_len,
4463c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				    sense, sense_handle);
4464c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4465c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4466c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) {
44679f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro		dma_free_coherent(&instance->pdev->dev,
4468c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				    kern_sge32[i].length,
4469c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				    kbuff_arr[i], kern_sge32[i].phys_addr);
4470c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4471c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4472c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_return_cmd(instance, cmd);
4473c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return error;
4474c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4475c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4476c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
4477c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4478c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_iocpacket __user *user_ioc =
4479c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    (struct megasas_iocpacket __user *)arg;
4480c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_iocpacket *ioc;
4481c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_instance *instance;
4482c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int error;
448339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	int i;
448439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
448539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 wait_time = MEGASAS_RESET_WAIT_TIME;
4486c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4487c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
4488c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!ioc)
4489c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENOMEM;
4490c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4491c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (copy_from_user(ioc, user_ioc, sizeof(*ioc))) {
4492c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		error = -EFAULT;
4493c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto out_kfree_ioc;
4494c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4495c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4496c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance = megasas_lookup_instance(ioc->host_no);
4497c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!instance) {
4498c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		error = -ENODEV;
4499c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto out_kfree_ioc;
4500c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4501c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
450239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
450339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_ERR "Controller in crit error\n");
45040c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		error = -ENODEV;
45050c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		goto out_kfree_ioc;
45060c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	}
45070c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo
45080c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	if (instance->unload == 1) {
45090c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		error = -ENODEV;
45100c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		goto out_kfree_ioc;
45110c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	}
45120c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo
4513c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
4514c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
4515c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
4516c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (down_interruptible(&instance->ioctl_sem)) {
4517c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		error = -ERESTARTSYS;
4518c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		goto out_kfree_ioc;
4519c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
452039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
452139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	for (i = 0; i < wait_time; i++) {
452239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
452339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_lock_irqsave(&instance->hba_lock, flags);
452439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
452539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			spin_unlock_irqrestore(&instance->hba_lock, flags);
452639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			break;
452739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
452839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_unlock_irqrestore(&instance->hba_lock, flags);
452939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
453039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
453139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megasas: waiting"
453239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				"for controller reset to finish\n");
453339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
453439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
453539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		msleep(1000);
453639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
453739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
453839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->hba_lock, flags);
453939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
454039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_unlock_irqrestore(&instance->hba_lock, flags);
454139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
454239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_ERR "megaraid_sas: timed out while"
454339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			"waiting for HBA to recover\n");
454439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		error = -ENODEV;
454539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		goto out_kfree_ioc;
454639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
454739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->hba_lock, flags);
454839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
4549c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
4550c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	up(&instance->ioctl_sem);
4551c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4552c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas      out_kfree_ioc:
4553c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	kfree(ioc);
4554c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return error;
4555c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4556c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4557c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
4558c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4559c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_instance *instance;
4560c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_aen aen;
4561c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int error;
456239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	int i;
456339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	unsigned long flags;
456439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	u32 wait_time = MEGASAS_RESET_WAIT_TIME;
4565c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4566c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (file->private_data != file) {
4567c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: fasync_helper was not "
4568c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		       "called first\n");
4569c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -EINVAL;
4570c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4571c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4572c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (copy_from_user(&aen, (void __user *)arg, sizeof(aen)))
4573c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -EFAULT;
4574c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4575c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	instance = megasas_lookup_instance(aen.host_no);
4576c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4577c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (!instance)
4578c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -ENODEV;
4579c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
458039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
458139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return -ENODEV;
45820c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	}
45830c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo
45840c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	if (instance->unload == 1) {
45850c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo		return -ENODEV;
45860c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo	}
45870c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo
458839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	for (i = 0; i < wait_time; i++) {
458939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
459039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_lock_irqsave(&instance->hba_lock, flags);
459139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
459239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			spin_unlock_irqrestore(&instance->hba_lock,
459339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang						flags);
459439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			break;
459539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
459639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
459739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_unlock_irqrestore(&instance->hba_lock, flags);
459839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
459939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
460039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang			printk(KERN_NOTICE "megasas: waiting for"
460139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				"controller reset to finish\n");
460239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		}
460339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
460439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		msleep(1000);
460539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
460639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
460739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_lock_irqsave(&instance->hba_lock, flags);
460839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
460939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		spin_unlock_irqrestore(&instance->hba_lock, flags);
461039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		printk(KERN_ERR "megaraid_sas: timed out while waiting"
461139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang				"for HBA to recover.\n");
461239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang		return -ENODEV;
461339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	}
461439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang	spin_unlock_irqrestore(&instance->hba_lock, flags);
461539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang
4616e5a69e27cc193f98c9a5a9086e3bf85528170623Matthias Kaehlcke	mutex_lock(&instance->aen_mutex);
4617c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	error = megasas_register_aen(instance, aen.seq_num,
4618c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				     aen.class_locale_word);
4619e5a69e27cc193f98c9a5a9086e3bf85528170623Matthias Kaehlcke	mutex_unlock(&instance->aen_mutex);
4620c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return error;
4621c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4622c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4623c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
4624c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_ioctl -	char node ioctl entry point
4625c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
4626c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic long
4627c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
4628c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4629c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	switch (cmd) {
4630c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MEGASAS_IOC_FIRMWARE:
4631c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return megasas_mgmt_ioctl_fw(file, arg);
4632c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4633c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MEGASAS_IOC_GET_AEN:
4634c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return megasas_mgmt_ioctl_aen(file, arg);
4635c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4636c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4637c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return -ENOTTY;
4638c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4639c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4640c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#ifdef CONFIG_COMPAT
4641c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
4642c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4643c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct compat_megasas_iocpacket __user *cioc =
4644c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    (struct compat_megasas_iocpacket __user *)arg;
4645c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	struct megasas_iocpacket __user *ioc =
4646c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    compat_alloc_user_space(sizeof(struct megasas_iocpacket));
4647c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int i;
4648c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int error = 0;
4649b3dc1a212e5167984616445990c76056034f8eebTomas Henzl	compat_uptr_t ptr;
4650c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
465183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	if (clear_user(ioc, sizeof(*ioc)))
465283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik		return -EFAULT;
4653c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4654c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) ||
4655c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) ||
4656c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) ||
4657c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) ||
4658c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) ||
4659c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	    copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
4660c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -EFAULT;
4661c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4662b3dc1a212e5167984616445990c76056034f8eebTomas Henzl	/*
4663b3dc1a212e5167984616445990c76056034f8eebTomas Henzl	 * The sense_ptr is used in megasas_mgmt_fw_ioctl only when
4664b3dc1a212e5167984616445990c76056034f8eebTomas Henzl	 * sense_len is not null, so prepare the 64bit value under
4665b3dc1a212e5167984616445990c76056034f8eebTomas Henzl	 * the same condition.
4666b3dc1a212e5167984616445990c76056034f8eebTomas Henzl	 */
4667b3dc1a212e5167984616445990c76056034f8eebTomas Henzl	if (ioc->sense_len) {
4668b3dc1a212e5167984616445990c76056034f8eebTomas Henzl		void __user **sense_ioc_ptr =
4669b3dc1a212e5167984616445990c76056034f8eebTomas Henzl			(void __user **)(ioc->frame.raw + ioc->sense_off);
4670b3dc1a212e5167984616445990c76056034f8eebTomas Henzl		compat_uptr_t *sense_cioc_ptr =
4671b3dc1a212e5167984616445990c76056034f8eebTomas Henzl			(compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
4672b3dc1a212e5167984616445990c76056034f8eebTomas Henzl		if (get_user(ptr, sense_cioc_ptr) ||
4673b3dc1a212e5167984616445990c76056034f8eebTomas Henzl		    put_user(compat_ptr(ptr), sense_ioc_ptr))
4674b3dc1a212e5167984616445990c76056034f8eebTomas Henzl			return -EFAULT;
4675b3dc1a212e5167984616445990c76056034f8eebTomas Henzl	}
4676c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4677b3dc1a212e5167984616445990c76056034f8eebTomas Henzl	for (i = 0; i < MAX_IOCTL_SGE; i++) {
4678c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		if (get_user(ptr, &cioc->sgl[i].iov_base) ||
4679c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
4680c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		    copy_in_user(&ioc->sgl[i].iov_len,
4681c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas				 &cioc->sgl[i].iov_len, sizeof(compat_size_t)))
4682c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			return -EFAULT;
4683c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4684c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4685c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc);
4686c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4687c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (copy_in_user(&cioc->frame.hdr.cmd_status,
4688c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			 &ioc->frame.hdr.cmd_status, sizeof(u8))) {
4689c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n");
4690c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return -EFAULT;
4691c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4692c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return error;
4693c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4694c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4695c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic long
4696c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd,
4697c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			  unsigned long arg)
4698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4699c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	switch (cmd) {
4700cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro	case MEGASAS_IOC_FIRMWARE32:
4701cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro		return megasas_mgmt_compat_ioctl_fw(file, arg);
4702c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	case MEGASAS_IOC_GET_AEN:
4703c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return megasas_mgmt_ioctl_aen(file, arg);
4704c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
4705c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4706c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return -ENOTTY;
4707c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4708c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#endif
4709c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4710c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/*
4711c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * File operations structure for management interface
4712c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
471300977a59b951207d38380c75f03a36829950265cArjan van de Venstatic const struct file_operations megasas_mgmt_fops = {
4714c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.owner = THIS_MODULE,
4715c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.open = megasas_mgmt_open,
4716c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.fasync = megasas_mgmt_fasync,
4717c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.unlocked_ioctl = megasas_mgmt_ioctl,
4718c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo	.poll = megasas_mgmt_poll,
4719c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#ifdef CONFIG_COMPAT
4720c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.compat_ioctl = megasas_mgmt_compat_ioctl,
4721c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#endif
47226038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek = noop_llseek,
4723c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas};
4724c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4725c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/*
4726c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI hotplug support registration structure
4727c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
4728c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct pci_driver megasas_pci_driver = {
4729c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4730c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.name = "megaraid_sas",
4731c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.id_table = megasas_pci_table,
4732c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.probe = megasas_probe_one,
4733c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.remove = __devexit_p(megasas_detach_one),
473431ea7088974c2405e19d72f17c2afb103ef19e02bo yang	.suspend = megasas_suspend,
473531ea7088974c2405e19d72f17c2afb103ef19e02bo yang	.resume = megasas_resume,
4736c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	.shutdown = megasas_shutdown,
4737c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas};
4738c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4739c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/*
4740c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Sysfs driver attributes
4741c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
4742c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf)
4743c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4744c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n",
4745c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			MEGASAS_VERSION);
4746c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4747c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4748c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL);
4749c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4750c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic ssize_t
4751c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_sysfs_show_release_date(struct device_driver *dd, char *buf)
4752c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
4753c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n",
4754c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas			MEGASAS_RELDATE);
4755c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
4756c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4757c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
4758c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		   NULL);
4759c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
4760658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patrostatic ssize_t
476172c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bomegasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
476272c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo{
476372c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo	return sprintf(buf, "%u\n", support_poll_for_event);
476472c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo}
476572c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo
476672c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bostatic DRIVER_ATTR(support_poll_for_event, S_IRUGO,
476772c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo			megasas_sysfs_show_support_poll_for_event, NULL);
476872c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo
4769837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo static ssize_t
4770837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bomegasas_sysfs_show_support_device_change(struct device_driver *dd, char *buf)
4771837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo{
4772837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo	return sprintf(buf, "%u\n", support_device_change);
4773837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo}
4774837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo
4775837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bostatic DRIVER_ATTR(support_device_change, S_IRUGO,
4776837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo			megasas_sysfs_show_support_device_change, NULL);
4777837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo
477872c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bostatic ssize_t
4779658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patromegasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
4780658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro{
4781ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	return sprintf(buf, "%u\n", megasas_dbg_lvl);
4782658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro}
4783658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro
4784658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patrostatic ssize_t
4785658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patromegasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count)
4786658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro{
4787658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	int retval = count;
4788658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){
4789658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		printk(KERN_ERR "megasas: could not set dbg_lvl\n");
4790658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro		retval = -EINVAL;
4791658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	}
4792658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	return retval;
4793658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro}
4794658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro
479566dca9b8c50b5e59d3bea8b21cee5c6dae6c9c46Joe Malickistatic DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl,
4796ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		megasas_sysfs_set_dbg_lvl);
4797ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
4798ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangstatic ssize_t
4799ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangmegasas_sysfs_show_poll_mode_io(struct device_driver *dd, char *buf)
4800ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang{
4801ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	return sprintf(buf, "%u\n", poll_mode_io);
4802ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang}
4803ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
4804ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangstatic ssize_t
4805ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangmegasas_sysfs_set_poll_mode_io(struct device_driver *dd,
4806ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang				const char *buf, size_t count)
4807ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang{
4808ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	int retval = count;
4809ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	int tmp = poll_mode_io;
4810ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	int i;
4811ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	struct megasas_instance *instance;
4812ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
4813ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if (sscanf(buf, "%u", &poll_mode_io) < 1) {
4814ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		printk(KERN_ERR "megasas: could not set poll_mode_io\n");
4815ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		retval = -EINVAL;
4816ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	}
4817ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
4818ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	/*
4819ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	 * Check if poll_mode_io is already set or is same as previous value
4820ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	 */
4821ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if ((tmp && poll_mode_io) || (tmp == poll_mode_io))
4822ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		goto out;
4823ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
4824ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if (poll_mode_io) {
4825ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		/*
4826ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		 * Start timers for all adapters
4827ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		 */
4828ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		for (i = 0; i < megasas_mgmt_info.max_index; i++) {
4829ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			instance = megasas_mgmt_info.instance[i];
4830ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			if (instance) {
4831ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang				megasas_start_timer(instance,
4832ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang					&instance->io_completion_timer,
4833ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang					megasas_io_completion_timer,
4834ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang					MEGASAS_COMPLETION_TIMER_INTERVAL);
4835ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			}
4836ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		}
4837ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	} else {
4838ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		/*
4839ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		 * Delete timers for all adapters
4840ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		 */
4841ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		for (i = 0; i < megasas_mgmt_info.max_index; i++) {
4842ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			instance = megasas_mgmt_info.instance[i];
4843ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			if (instance)
4844ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang				del_timer_sync(&instance->io_completion_timer);
4845ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		}
4846ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	}
4847ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
4848ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangout:
4849ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	return retval;
4850ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang}
4851ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
48527e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bostatic void
48537e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bomegasas_aen_polling(struct work_struct *work)
48547e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo{
48557e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	struct megasas_aen_event *ev =
48567e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		container_of(work, struct megasas_aen_event, hotplug_work);
48577e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	struct megasas_instance *instance = ev->instance;
48587e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	union megasas_evt_class_locale class_locale;
48597e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	struct  Scsi_Host *host;
48607e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	struct  scsi_device *sdev1;
48617e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	u16     pd_index = 0;
4862c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo	u16	ld_index = 0;
48637e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	int     i, j, doscan = 0;
48647e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	u32 seq_num;
48657e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	int error;
48667e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
48677e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	if (!instance) {
48687e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		printk(KERN_ERR "invalid instance!\n");
48697e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		kfree(ev);
48707e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		return;
48717e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	}
48727e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	instance->ev = NULL;
48737e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	host = instance->host;
48747e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	if (instance->evt_detail) {
48757e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
48767e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		switch (instance->evt_detail->code) {
48777e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		case MR_EVT_PD_INSERTED:
4878c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			if (megasas_get_pd_list(instance) == 0) {
4879c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
4880c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				for (j = 0;
4881c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				j < MEGASAS_MAX_DEV_PER_CHANNEL;
4882c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				j++) {
4883c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4884c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				pd_index =
4885c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4886c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4887c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				sdev1 =
4888c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				scsi_device_lookup(host, i, j, 0);
4889c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4890c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				if (instance->pd_list[pd_index].driveState
4891c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						== MR_PD_STATE_SYSTEM) {
4892c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						if (!sdev1) {
4893c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_add_device(host, i, j, 0);
4894c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						}
4895c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4896c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					if (sdev1)
4897c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_device_put(sdev1);
4898c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					}
4899c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				}
4900c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			}
4901c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			}
4902c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			doscan = 0;
4903c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			break;
4904c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
49057e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		case MR_EVT_PD_REMOVED:
4906c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			if (megasas_get_pd_list(instance) == 0) {
4907c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			megasas_get_pd_list(instance);
4908c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
4909c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				for (j = 0;
4910c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				j < MEGASAS_MAX_DEV_PER_CHANNEL;
4911c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				j++) {
4912c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4913c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				pd_index =
4914c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4915c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4916c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				sdev1 =
4917c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				scsi_device_lookup(host, i, j, 0);
4918c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4919c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				if (instance->pd_list[pd_index].driveState
4920c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					== MR_PD_STATE_SYSTEM) {
4921c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					if (sdev1) {
4922c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_device_put(sdev1);
4923c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					}
4924c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				} else {
4925c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					if (sdev1) {
4926c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_remove_device(sdev1);
4927c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_device_put(sdev1);
4928c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					}
4929c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				}
4930c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				}
4931c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			}
4932c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			}
4933c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			doscan = 0;
4934c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			break;
4935c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4936c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo		case MR_EVT_LD_OFFLINE:
4937c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo		case MR_EVT_LD_DELETED:
4938c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			megasas_get_ld_list(instance);
4939c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
4940c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				for (j = 0;
4941c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				j < MEGASAS_MAX_DEV_PER_CHANNEL;
4942c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				j++) {
4943c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4944c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				ld_index =
4945c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4946c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4947c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				sdev1 = scsi_device_lookup(host,
4948c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					i + MEGASAS_MAX_LD_CHANNELS,
4949c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					j,
4950c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					0);
4951c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4952c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				if (instance->ld_ids[ld_index] != 0xff) {
4953c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					if (sdev1) {
4954c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_device_put(sdev1);
4955c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					}
4956c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				} else {
4957c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					if (sdev1) {
4958c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_remove_device(sdev1);
4959c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_device_put(sdev1);
4960c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					}
4961c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				}
4962c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				}
4963c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			}
4964c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			doscan = 0;
4965c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			break;
4966c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo		case MR_EVT_LD_CREATED:
4967c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			megasas_get_ld_list(instance);
4968c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
4969c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				for (j = 0;
4970c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					j < MEGASAS_MAX_DEV_PER_CHANNEL;
4971c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					j++) {
4972c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					ld_index =
4973c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4974c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4975c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					sdev1 = scsi_device_lookup(host,
4976c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						i+MEGASAS_MAX_LD_CHANNELS,
4977c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						j, 0);
4978c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
4979c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					if (instance->ld_ids[ld_index] !=
4980c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo								0xff) {
4981c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						if (!sdev1) {
4982c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo							scsi_add_device(host,
4983c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo								i + 2,
4984c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo								j, 0);
4985c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						}
4986c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					}
4987c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					if (sdev1) {
4988c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_device_put(sdev1);
4989c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					}
4990c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				}
4991c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			}
4992c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			doscan = 0;
4993c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			break;
49947e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
4995c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo		case MR_EVT_FOREIGN_CFG_IMPORTED:
49967e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			doscan = 1;
49977e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			break;
49987e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		default:
49997e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			doscan = 0;
50007e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			break;
50017e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		}
50027e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	} else {
50037e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		printk(KERN_ERR "invalid evt_detail!\n");
50047e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		kfree(ev);
50057e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		return;
50067e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	}
50077e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
50087e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	if (doscan) {
50097e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		printk(KERN_INFO "scanning ...\n");
50107e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		megasas_get_pd_list(instance);
50117e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
50127e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
50137e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo				pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
50147e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo				sdev1 = scsi_device_lookup(host, i, j, 0);
50157e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo				if (instance->pd_list[pd_index].driveState ==
50167e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo							MR_PD_STATE_SYSTEM) {
50177e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo					if (!sdev1) {
50187e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo						scsi_add_device(host, i, j, 0);
50197e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo					}
50207e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo					if (sdev1)
50217e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo						scsi_device_put(sdev1);
50227e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo				} else {
50237e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo					if (sdev1) {
50247e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo						scsi_remove_device(sdev1);
50257e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo						scsi_device_put(sdev1);
50267e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo					}
50277e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo				}
50287e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo			}
50297e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		}
5030c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
5031c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo		megasas_get_ld_list(instance);
5032c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo		for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
5033c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
5034c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				ld_index =
5035c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
5036c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo
5037c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				sdev1 = scsi_device_lookup(host,
5038c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					i+MEGASAS_MAX_LD_CHANNELS, j, 0);
5039c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				if (instance->ld_ids[ld_index] != 0xff) {
5040c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					if (!sdev1) {
5041c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_add_device(host,
5042c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo								i+2,
5043c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo								j, 0);
5044c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					} else {
5045c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_device_put(sdev1);
5046c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					}
5047c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				} else {
5048c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					if (sdev1) {
5049c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_remove_device(sdev1);
5050c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo						scsi_device_put(sdev1);
5051c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo					}
5052c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo				}
5053c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo			}
5054c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo		}
50557e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	}
50567e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
50577e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	if ( instance->aen_cmd != NULL ) {
50587e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		kfree(ev);
50597e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		return ;
50607e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	}
50617e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
50627e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	seq_num = instance->evt_detail->seq_num + 1;
50637e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
50647e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	/* Register AEN with FW for latest sequence number plus 1 */
50657e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	class_locale.members.reserved = 0;
50667e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	class_locale.members.locale = MR_EVT_LOCALE_ALL;
50677e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	class_locale.members.class = MR_EVT_CLASS_DEBUG;
50687e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	mutex_lock(&instance->aen_mutex);
50697e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	error = megasas_register_aen(instance, seq_num,
50707e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo					class_locale.word);
50717e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	mutex_unlock(&instance->aen_mutex);
50727e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
50737e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	if (error)
50747e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo		printk(KERN_ERR "register aen failed error %x\n", error);
50757e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
50767e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo	kfree(ev);
50777e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo}
50787e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
50797e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo
5080bb7d3f24c71e528989501617651b669fbed798cbBryn M. Reevesstatic DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUSR,
5081ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		megasas_sysfs_show_poll_mode_io,
5082ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		megasas_sysfs_set_poll_mode_io);
5083658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro
5084c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
5085c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_init - Driver load entry point
5086c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
5087c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int __init megasas_init(void)
5088c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
5089c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	int rval;
5090c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
5091c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
5092c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Announce driver version and other information
5093c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
5094c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
5095c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	       MEGASAS_EXT_VERSION);
5096c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
509772c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo	support_poll_for_event = 2;
5098837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo	support_device_change = 1;
509972c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo
5100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
5101c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
5102c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
5103c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Register character device node
5104c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
5105c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops);
5106c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
5107c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (rval < 0) {
5108c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: failed to open device node\n");
5109c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		return rval;
5110c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	}
5111c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
5112c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	megasas_mgmt_majorno = rval;
5113c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
5114c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	/*
5115c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 * Register ourselves as PCI hotplug module
5116c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	 */
51174041b9cd87d97a7c73a5bf5a9305dffee2599386Michal Piotrowski	rval = pci_register_driver(&megasas_pci_driver);
5118c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
5119c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	if (rval) {
5120c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas		printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n");
512183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik		goto err_pcidrv;
512283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	}
512383aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik
512483aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	rval = driver_create_file(&megasas_pci_driver.driver,
512583aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik				  &driver_attr_version);
512683aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	if (rval)
512783aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik		goto err_dcf_attr_ver;
512883aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	rval = driver_create_file(&megasas_pci_driver.driver,
512983aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik				  &driver_attr_release_date);
513083aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	if (rval)
513183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik		goto err_dcf_rel_date;
513272c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo
513372c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo	rval = driver_create_file(&megasas_pci_driver.driver,
513472c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo				&driver_attr_support_poll_for_event);
513572c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo	if (rval)
513672c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo		goto err_dcf_support_poll_for_event;
513772c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo
513883aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	rval = driver_create_file(&megasas_pci_driver.driver,
513983aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik				  &driver_attr_dbg_lvl);
514083aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	if (rval)
514183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik		goto err_dcf_dbg_lvl;
5142ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	rval = driver_create_file(&megasas_pci_driver.driver,
5143ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang				  &driver_attr_poll_mode_io);
5144ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	if (rval)
5145ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang		goto err_dcf_poll_mode_io;
5146c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
5147837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo	rval = driver_create_file(&megasas_pci_driver.driver,
5148837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo				&driver_attr_support_device_change);
5149837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo	if (rval)
5150837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo		goto err_dcf_support_device_change;
5151837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo
5152c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	return rval;
5153ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang
5154837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Boerr_dcf_support_device_change:
5155837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo	driver_remove_file(&megasas_pci_driver.driver,
5156837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo		  &driver_attr_poll_mode_io);
5157837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo
5158ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangerr_dcf_poll_mode_io:
5159ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	driver_remove_file(&megasas_pci_driver.driver,
5160ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			   &driver_attr_dbg_lvl);
516183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_dcf_dbg_lvl:
516283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	driver_remove_file(&megasas_pci_driver.driver,
516372c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo			&driver_attr_support_poll_for_event);
516472c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo
516572c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Boerr_dcf_support_poll_for_event:
516672c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo	driver_remove_file(&megasas_pci_driver.driver,
516783aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik			   &driver_attr_release_date);
516872c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo
516983aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_dcf_rel_date:
517083aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
517183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_dcf_attr_ver:
517283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	pci_unregister_driver(&megasas_pci_driver);
517383aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_pcidrv:
517483aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
51750d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford	return rval;
5176c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
5177c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
5178c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/**
5179c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_exit - Driver unload entry point
5180c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */
5181c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void __exit megasas_exit(void)
5182c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{
5183658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro	driver_remove_file(&megasas_pci_driver.driver,
5184ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang			   &driver_attr_poll_mode_io);
5185ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang	driver_remove_file(&megasas_pci_driver.driver,
5186658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro			   &driver_attr_dbg_lvl);
518783aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	driver_remove_file(&megasas_pci_driver.driver,
5188837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo			&driver_attr_support_poll_for_event);
5189837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo	driver_remove_file(&megasas_pci_driver.driver,
5190837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo			&driver_attr_support_device_change);
5191837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo	driver_remove_file(&megasas_pci_driver.driver,
519283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik			   &driver_attr_release_date);
519383aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik	driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
5194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
5195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	pci_unregister_driver(&megasas_pci_driver);
5196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas	unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
5197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}
5198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas
5199c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmodule_init(megasas_init);
5200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmodule_exit(megasas_exit);
5201