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(®s->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, ®s->outbound_intr_mask); 203b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro /* Dummy readl to force pci flush */ 204b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro readl(®s->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(®s->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, ®s->outbound_intr_status); 2401341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 24106f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo /* Dummy readl to force pci flush */ 24206f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo readl(®s->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, ®s->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(®s->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, ®s->outbound_intr_mask); 369b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro /* Dummy readl to force pci flush */ 370b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro readl(®s->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(®s->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, ®s->outbound_doorbell_clear); 404f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 40506f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo /* Dummy readl to force pci flush */ 40606f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo readl(®s->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(®s->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, ®s->outbound_intr_mask); 485879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* Dummy readl to force pci flush */ 486879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo readl(®s->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(®s->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, ®s->outbound_intr_status); 520879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 521879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* 522879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * dummy read to flush PCI 523879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 524879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo readl(®s->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(®s->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, ®s->outbound_intr_mask); 6136610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* Dummy readl to force pci flush */ 6146610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo readl(®s->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(®s->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, ®s->outbound_doorbell_clear); 6536610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6546610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* Dummy readl to force pci flush */ 6556610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo readl(®s->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, ®_set->seq_offset); 69039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(4, ®_set->seq_offset); 69139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(0xb, ®_set->seq_offset); 69239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(2, ®_set->seq_offset); 69339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(7, ®_set->seq_offset); 69439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(0xd, ®_set->seq_offset); 69539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 69639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 69739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang HostDiag = (u32)readl(®_set->host_diag); 69839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 69939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang while ( !( HostDiag & DIAG_WRITE_ENABLE) ) { 70039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(100); 70139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang HostDiag = (u32)readl(®_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), ®_set->host_diag); 71339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 71439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ssleep(10); 71539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 71639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang HostDiag = (u32)readl(®_set->host_diag); 71739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang while ( ( HostDiag & DIAG_RESET_ADAPTER) ) { 71839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(100); 71939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang HostDiag = (u32)readl(®_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