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 21798edaadba97612224c250d50f880405d75a3af1Adam Radford * Version : v00.00.06.14-rc1 22c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 233f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford * Authors: LSI Corporation 243f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford * Sreenivas Bagalkote 253f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford * Sumant Patro 263f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford * Bo Yang 2700fa2b191b4bd74e9d22ac177e3d9e8ecd3582d3Adam Radford * Adam Radford <linuxraid@lsi.com> 28c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 293f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford * Send feedback to: <megaraidlinux@lsi.com> 303f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford * 313f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035 323f1530c1e1f7fc570672f4a54565949070fad05fAdam Radford * ATTN: Linuxraid 33c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 34c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 35c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/kernel.h> 36c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/types.h> 37c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/pci.h> 38c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/list.h> 39c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/moduleparam.h> 40c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/module.h> 41c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/spinlock.h> 42c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/interrupt.h> 43c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/delay.h> 44c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/uio.h> 455a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 46c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <asm/uaccess.h> 47433992361ce95a1da76b76c9c24d4c957b058affAl Viro#include <linux/fs.h> 48c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <linux/compat.h> 49cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro#include <linux/blkdev.h> 500b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven#include <linux/mutex.h> 51c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo#include <linux/poll.h> 52c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 53c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <scsi/scsi.h> 54c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <scsi/scsi_cmnd.h> 55c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <scsi/scsi_device.h> 56c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include <scsi/scsi_host.h> 574bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford#include <scsi/scsi_tcq.h> 589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford#include "megaraid_sas_fusion.h" 59c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include "megaraid_sas.h" 60c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 61ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang/* 621fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo * Number of sectors per IO command 631fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo * Will be set in megasas_init_mfi if user does not provide 641fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo */ 651fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bostatic unsigned int max_sectors; 661fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bomodule_param_named(max_sectors, max_sectors, int, 0); 671fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, BoMODULE_PARM_DESC(max_sectors, 681fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo "Maximum number of sectors per IO command"); 691fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo 7080d9da98b4034edd31f6bacdb96c7489c4460173Adam Radfordstatic int msix_disable; 7180d9da98b4034edd31f6bacdb96c7489c4460173Adam Radfordmodule_param(msix_disable, int, S_IRUGO); 7280d9da98b4034edd31f6bacdb96c7489c4460173Adam RadfordMODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0"); 7380d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford 74c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, SreenivasMODULE_LICENSE("GPL"); 75c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, SreenivasMODULE_VERSION(MEGASAS_VERSION); 763d6d174a0888fe082e87ce1d4a0f1a85044a4515Sumant PatroMODULE_AUTHOR("megaraidlinux@lsi.com"); 77f28cd7cf8f696eafe42d1632b5a306fbf784d3cdbo yangMODULE_DESCRIPTION("LSI MegaRAID SAS Driver"); 78c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 79058a8facfe1ee091b7188661937240fd0d950cf4Adam Radfordint megasas_transition_to_ready(struct megasas_instance *instance, int ocr); 8039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int megasas_get_pd_list(struct megasas_instance *instance); 8139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int megasas_issue_init_mfi(struct megasas_instance *instance); 8239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int megasas_register_aen(struct megasas_instance *instance, 8339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 seq_num, u32 class_locale_word); 84c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/* 85c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI ID table for all supported controllers 86c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 87c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct pci_device_id megasas_pci_table[] = { 88c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 89f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064R)}, 90f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar /* xscale IOP */ 91f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)}, 92f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar /* ppc IOP */ 93af7a5647c03c18f5ea58033710ccb23d71727e0cbo yang {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)}, 94af7a5647c03c18f5ea58033710ccb23d71727e0cbo yang /* ppc IOP */ 956610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)}, 966610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* gen2*/ 976610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)}, 986610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* gen2*/ 99879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)}, 100879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* skinny*/ 101879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)}, 102879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* skinny*/ 103f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, 104f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar /* xscale IOP, vega */ 105f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)}, 106f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar /* xscale IOP */ 1079c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FUSION)}, 1089c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford /* Fusion */ 10936807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INVADER)}, 11036807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford /* Invader */ 111f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar {} 112c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}; 113c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 114c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, SreenivasMODULE_DEVICE_TABLE(pci, megasas_pci_table); 115c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 116c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_majorno; 117c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct megasas_mgmt_info megasas_mgmt_info; 118c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct fasync_struct *megasas_async_queue; 1190b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Venstatic DEFINE_MUTEX(megasas_async_queue_mutex); 120c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 121c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bostatic int megasas_poll_wait_aen; 122c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bostatic DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait); 12372c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bostatic u32 support_poll_for_event; 1249c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordu32 megasas_dbg_lvl; 125837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bostatic u32 support_device_change; 126658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 127c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo/* define lock for aen poll */ 128c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bospinlock_t poll_aen_lock; 129c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo 1309c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid 1317343eb6570ae3b299e7b5185b139d8335ef60e9bbo yangmegasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, 1327343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang u8 alt_status); 133ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radfordstatic u32 134ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radfordmegasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs); 135ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radfordstatic int 136ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radfordmegasas_adp_reset_gen2(struct megasas_instance *instance, 137ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford struct megasas_register_set __iomem *reg_set); 138cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordstatic irqreturn_t megasas_isr(int irq, void *devp); 139cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordstatic u32 140cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordmegasas_init_adapter_mfi(struct megasas_instance *instance); 141cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordu32 142cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordmegasas_build_and_issue_cmd(struct megasas_instance *instance, 143cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct scsi_cmnd *scmd); 144cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordstatic void megasas_complete_cmd_dpc(unsigned long instance_addr); 1459c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid 1469c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_release_fusion(struct megasas_instance *instance); 1479c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint 1489c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_ioc_init_fusion(struct megasas_instance *instance); 1499c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid 1509c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_free_cmds_fusion(struct megasas_instance *instance); 1519c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordu8 1529c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_get_map_info(struct megasas_instance *instance); 1539c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint 1549c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_sync_map_info(struct megasas_instance *instance); 1559c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint 1569c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordwait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd); 1579c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid megasas_reset_reply_desc(struct megasas_instance *instance); 1589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordu8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map, 1599c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford struct LD_LOAD_BALANCE_INFO *lbInfo); 1609c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint megasas_reset_fusion(struct Scsi_Host *shost); 1619c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid megasas_fusion_ocr_wq(struct work_struct *work); 162cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 163cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordvoid 164cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordmegasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd) 165cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford{ 166cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet->fire_cmd(instance, 167cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford cmd->frame_phys_addr, 0, instance->reg_set); 168cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford} 1697343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 170c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 171c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_get_cmd - Get a command from the free pool 172c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 173c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 174c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Returns a free command from the pool 175c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1769c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordstruct megasas_cmd *megasas_get_cmd(struct megasas_instance 177c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *instance) 178c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 179c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas unsigned long flags; 180c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd = NULL; 181c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 182c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas spin_lock_irqsave(&instance->cmd_pool_lock, flags); 183c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 184c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!list_empty(&instance->cmd_pool)) { 185c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = list_entry((&instance->cmd_pool)->next, 186c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd, list); 187c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas list_del_init(&cmd->list); 188c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else { 189c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_ERR "megasas: Command pool empty!\n"); 190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 191c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 192c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas spin_unlock_irqrestore(&instance->cmd_pool_lock, flags); 193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return cmd; 194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_return_cmd - Return a cmd to free command pool 198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 199c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Command packet to be returned to free command pool 200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2019c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordinline void 202c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) 203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas unsigned long flags; 205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 206c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas spin_lock_irqsave(&instance->cmd_pool_lock, flags); 207c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 208c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd = NULL; 2099c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford cmd->frame_count = 0; 210e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) && 211e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) && 212e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford (reset_devices)) 213e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford cmd->frame->hdr.cmd = MFI_CMD_INVALID; 214c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas list_add_tail(&cmd->list, &instance->cmd_pool); 215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 216c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas spin_unlock_irqrestore(&instance->cmd_pool_lock, flags); 217c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 218c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2191341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 2201341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/** 2210d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford* The following functions are defined for xscale 2221341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro* (deviceid : 1064R, PERC5) controllers 2231341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro*/ 2241341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 225c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2261341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_enable_intr_xscale - Enables interrupts 227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @regs: MFI register set 228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic inline void 2301341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_enable_intr_xscale(struct megasas_register_set __iomem * regs) 231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 23239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(0, &(regs)->outbound_intr_mask); 233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* Dummy readl to force pci flush */ 235c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas readl(®s->outbound_intr_mask); 236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 239b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * megasas_disable_intr_xscale -Disables interrupt 240b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * @regs: MFI register set 241b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro */ 242b274cab779219325fd480cc696a456d1c3893bd8Sumant Patrostatic inline void 243b274cab779219325fd480cc696a456d1c3893bd8Sumant Patromegasas_disable_intr_xscale(struct megasas_register_set __iomem * regs) 244b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro{ 245b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro u32 mask = 0x1f; 246b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro writel(mask, ®s->outbound_intr_mask); 247b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro /* Dummy readl to force pci flush */ 248b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro readl(®s->outbound_intr_mask); 249b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro} 250b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro 251b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro/** 2521341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_read_fw_status_reg_xscale - returns the current FW status value 2531341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @regs: MFI register set 2541341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */ 2551341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patrostatic u32 2561341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs) 2571341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro{ 2581341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro return readl(&(regs)->outbound_msg_0); 2591341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro} 2601341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/** 2611341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_clear_interrupt_xscale - Check & clear interrupt 2621341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @regs: MFI register set 2631341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */ 2640d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic int 2651341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_clear_intr_xscale(struct megasas_register_set __iomem * regs) 2661341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro{ 2671341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro u32 status; 26839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 mfiStatus = 0; 2691341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro /* 2701341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * Check if it is our interrupt 2711341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */ 2721341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro status = readl(®s->outbound_intr_status); 2731341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 27439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (status & MFI_OB_INTR_STATUS_MASK) 27539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; 27639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (status & MFI_XSCALE_OMR0_CHANGE_INTERRUPT) 27739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; 2781341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 2791341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro /* 2801341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * Clear the interrupt by writing back the same value 2811341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */ 28239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (mfiStatus) 28339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(status, ®s->outbound_intr_status); 2841341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 28506f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo /* Dummy readl to force pci flush */ 28606f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo readl(®s->outbound_intr_status); 28706f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo 28839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return mfiStatus; 2891341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro} 2901341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 2911341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/** 2921341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_fire_cmd_xscale - Sends command to the FW 2931341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @frame_phys_addr : Physical address of cmd 2941341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @frame_count : Number of frames for the command 2951341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @regs : MFI register set 2961341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */ 2970d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic inline void 2980c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_xscale(struct megasas_instance *instance, 2990c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo dma_addr_t frame_phys_addr, 3000c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo u32 frame_count, 3010c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo struct megasas_register_set __iomem *regs) 3021341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro{ 30339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 30439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 3051341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro writel((frame_phys_addr >> 3)|(frame_count), 3061341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro &(regs)->inbound_queue_port); 30739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 30839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 30939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 31039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 31139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_adp_reset_xscale - For controller reset 31239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 31339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 31439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 31539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_adp_reset_xscale(struct megasas_instance *instance, 31639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 31739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 31839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 i; 31939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 pcidata; 32039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(MFI_ADP_RESET, ®s->inbound_doorbell); 32139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 32239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < 3; i++) 32339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); /* sleep for 3 secs */ 32439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pcidata = 0; 32539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata); 32639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "pcidata = %x\n", pcidata); 32739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (pcidata & 0x2) { 32839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "mfi 1068 offset read=%x\n", pcidata); 32939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pcidata &= ~0x2; 33039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pci_write_config_dword(instance->pdev, 33139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang MFI_1068_PCSR_OFFSET, pcidata); 33239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 33339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < 2; i++) 33439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); /* need to wait 2 secs again */ 33539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 33639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pcidata = 0; 33739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pci_read_config_dword(instance->pdev, 33839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata); 33939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "1068 offset handshake read=%x\n", pcidata); 34039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) { 34139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "1068 offset pcidt=%x\n", pcidata); 34239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pcidata = 0; 34339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pci_write_config_dword(instance->pdev, 34439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang MFI_1068_FW_HANDSHAKE_OFFSET, pcidata); 34539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 34639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 34739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 34839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 34939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 35039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 35139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_xscale - For controller reset check 35239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 35339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 35439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 35539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_xscale(struct megasas_instance *instance, 35639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 35739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 35839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 consumer; 35939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang consumer = *instance->consumer; 36039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 36139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((instance->adprecovery != MEGASAS_HBA_OPERATIONAL) && 36239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (*instance->consumer == MEGASAS_ADPRESET_INPROG_SIGN)) { 36339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 1; 36439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 36539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 3661341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro} 3671341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 3681341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patrostatic struct megasas_instance_template megasas_instance_template_xscale = { 3691341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 3701341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro .fire_cmd = megasas_fire_cmd_xscale, 3711341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro .enable_intr = megasas_enable_intr_xscale, 372b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro .disable_intr = megasas_disable_intr_xscale, 3731341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro .clear_intr = megasas_clear_intr_xscale, 3741341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro .read_fw_status_reg = megasas_read_fw_status_reg_xscale, 37539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .adp_reset = megasas_adp_reset_xscale, 37639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .check_reset = megasas_check_reset_xscale, 377cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .service_isr = megasas_isr, 378cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .tasklet = megasas_complete_cmd_dpc, 379cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .init_adapter = megasas_init_adapter_mfi, 380cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .build_and_issue_cmd = megasas_build_and_issue_cmd, 381cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .issue_dcmd = megasas_issue_dcmd, 3821341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro}; 3831341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 3841341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/** 3850d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford* This is the end of set of functions & definitions specific 3861341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro* to xscale (deviceid : 1064R, PERC5) controllers 3871341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro*/ 3881341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 3891341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/** 3900d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford* The following functions are defined for ppc (deviceid : 0x60) 391f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro* controllers 392f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro*/ 393f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 394f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 395f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_enable_intr_ppc - Enables interrupts 396f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs: MFI register set 397f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 398f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patrostatic inline void 399f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patromegasas_enable_intr_ppc(struct megasas_register_set __iomem * regs) 400f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{ 401f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); 4020d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford 40339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(~0x80000000, &(regs)->outbound_intr_mask); 404f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 405f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro /* Dummy readl to force pci flush */ 406f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro readl(®s->outbound_intr_mask); 407f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro} 408f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 409f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 410b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * megasas_disable_intr_ppc - Disable interrupt 411b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * @regs: MFI register set 412b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro */ 413b274cab779219325fd480cc696a456d1c3893bd8Sumant Patrostatic inline void 414b274cab779219325fd480cc696a456d1c3893bd8Sumant Patromegasas_disable_intr_ppc(struct megasas_register_set __iomem * regs) 415b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro{ 416b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro u32 mask = 0xFFFFFFFF; 417b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro writel(mask, ®s->outbound_intr_mask); 418b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro /* Dummy readl to force pci flush */ 419b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro readl(®s->outbound_intr_mask); 420b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro} 421b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro 422b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro/** 423f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_read_fw_status_reg_ppc - returns the current FW status value 424f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs: MFI register set 425f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 426f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patrostatic u32 427f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patromegasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs) 428f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{ 429f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro return readl(&(regs)->outbound_scratch_pad); 430f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro} 431f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 432f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 433f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_clear_interrupt_ppc - Check & clear interrupt 434f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs: MFI register set 435f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 4360d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic int 437f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patromegasas_clear_intr_ppc(struct megasas_register_set __iomem * regs) 438f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{ 4393cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford u32 status, mfiStatus = 0; 4403cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford 441f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro /* 442f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * Check if it is our interrupt 443f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 444f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro status = readl(®s->outbound_intr_status); 445f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 4463cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford if (status & MFI_REPLY_1078_MESSAGE_INTERRUPT) 4473cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; 4483cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford 4493cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) 4503cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; 451f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 452f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro /* 453f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * Clear the interrupt by writing back the same value 454f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 455f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro writel(status, ®s->outbound_doorbell_clear); 456f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 45706f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo /* Dummy readl to force pci flush */ 45806f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo readl(®s->outbound_doorbell_clear); 45906f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo 4603cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford return mfiStatus; 461f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro} 4623cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford 463f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 464f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_fire_cmd_ppc - Sends command to the FW 465f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @frame_phys_addr : Physical address of cmd 466f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @frame_count : Number of frames for the command 467f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs : MFI register set 468f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 4690d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic inline void 4700c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_ppc(struct megasas_instance *instance, 4710c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo dma_addr_t frame_phys_addr, 4720c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo u32 frame_count, 4730c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo struct megasas_register_set __iomem *regs) 474f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{ 47539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 47639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 4770d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford writel((frame_phys_addr | (frame_count<<1))|1, 478f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro &(regs)->inbound_queue_port); 47939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 480f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro} 481f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 48239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 48339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_ppc - For controller reset check 48439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 48539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 48639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 48739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_ppc(struct megasas_instance *instance, 48839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 48939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 4903cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) 4913cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford return 1; 4923cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford 49339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 49439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 4953cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford 496f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patrostatic struct megasas_instance_template megasas_instance_template_ppc = { 4970d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford 498f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro .fire_cmd = megasas_fire_cmd_ppc, 499f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro .enable_intr = megasas_enable_intr_ppc, 500b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro .disable_intr = megasas_disable_intr_ppc, 501f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro .clear_intr = megasas_clear_intr_ppc, 502f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro .read_fw_status_reg = megasas_read_fw_status_reg_ppc, 5033cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford .adp_reset = megasas_adp_reset_xscale, 50439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .check_reset = megasas_check_reset_ppc, 505cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .service_isr = megasas_isr, 506cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .tasklet = megasas_complete_cmd_dpc, 507cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .init_adapter = megasas_init_adapter_mfi, 508cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .build_and_issue_cmd = megasas_build_and_issue_cmd, 509cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .issue_dcmd = megasas_issue_dcmd, 510f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro}; 511f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 512f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 513879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_enable_intr_skinny - Enables interrupts 514879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs: MFI register set 515879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 516879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic inline void 517879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_enable_intr_skinny(struct megasas_register_set __iomem *regs) 518879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{ 519879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(0xFFFFFFFF, &(regs)->outbound_intr_mask); 520879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 521879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask); 522879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 523879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* Dummy readl to force pci flush */ 524879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo readl(®s->outbound_intr_mask); 525879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo} 526879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 527879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/** 528879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_disable_intr_skinny - Disables interrupt 529879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs: MFI register set 530879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 531879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic inline void 532879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_disable_intr_skinny(struct megasas_register_set __iomem *regs) 533879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{ 534879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo u32 mask = 0xFFFFFFFF; 535879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(mask, ®s->outbound_intr_mask); 536879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* Dummy readl to force pci flush */ 537879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo readl(®s->outbound_intr_mask); 538879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo} 539879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 540879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/** 541879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_read_fw_status_reg_skinny - returns the current FW status value 542879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs: MFI register set 543879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 544879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic u32 545879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs) 546879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{ 547879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo return readl(&(regs)->outbound_scratch_pad); 548879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo} 549879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 550879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/** 551879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_clear_interrupt_skinny - Check & clear interrupt 552879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs: MFI register set 553879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 554879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic int 555879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) 556879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{ 557879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo u32 status; 558ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford u32 mfiStatus = 0; 559ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford 560879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* 561879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * Check if it is our interrupt 562879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 563879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo status = readl(®s->outbound_intr_status); 564879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 565879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) { 56639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 567879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo } 568879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 569879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* 570ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford * Check if it is our interrupt 571ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford */ 572ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford if ((megasas_read_fw_status_reg_gen2(regs) & MFI_STATE_MASK) == 573ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford MFI_STATE_FAULT) { 574ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; 575ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford } else 576ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; 577ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford 578ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford /* 579879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * Clear the interrupt by writing back the same value 580879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 581879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(status, ®s->outbound_intr_status); 582879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 583879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* 584879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * dummy read to flush PCI 585879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 586879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo readl(®s->outbound_intr_status); 587879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 588ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford return mfiStatus; 589879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo} 590879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 591879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/** 592879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_fire_cmd_skinny - Sends command to the FW 593879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @frame_phys_addr : Physical address of cmd 594879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @frame_count : Number of frames for the command 595879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs : MFI register set 596879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 597879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic inline void 5980c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_skinny(struct megasas_instance *instance, 5990c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo dma_addr_t frame_phys_addr, 6000c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo u32 frame_count, 601879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo struct megasas_register_set __iomem *regs) 602879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{ 6030c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo unsigned long flags; 60439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 605879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(0, &(regs)->inbound_high_queue_port); 606879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel((frame_phys_addr | (frame_count<<1))|1, 607879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo &(regs)->inbound_low_queue_port); 60839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 60939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 61039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 61139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 61239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_skinny - For controller reset check 61339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 61439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 61539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 61639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_skinny(struct megasas_instance *instance, 61739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 61839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 6193cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) 6203cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford return 1; 6213cc6851f9a3509e2ced0eb218599857b07c0ab46Adam Radford 62239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 623879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo} 624879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 625879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic struct megasas_instance_template megasas_instance_template_skinny = { 626879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 627879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo .fire_cmd = megasas_fire_cmd_skinny, 628879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo .enable_intr = megasas_enable_intr_skinny, 629879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo .disable_intr = megasas_disable_intr_skinny, 630879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo .clear_intr = megasas_clear_intr_skinny, 631879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo .read_fw_status_reg = megasas_read_fw_status_reg_skinny, 632ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford .adp_reset = megasas_adp_reset_gen2, 63339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .check_reset = megasas_check_reset_skinny, 634cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .service_isr = megasas_isr, 635cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .tasklet = megasas_complete_cmd_dpc, 636cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .init_adapter = megasas_init_adapter_mfi, 637cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .build_and_issue_cmd = megasas_build_and_issue_cmd, 638cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .issue_dcmd = megasas_issue_dcmd, 639879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo}; 640879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 641879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 642879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/** 6436610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo* The following functions are defined for gen2 (deviceid : 0x78 0x79) 6446610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo* controllers 6456610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo*/ 6466610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6476610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 6486610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_enable_intr_gen2 - Enables interrupts 6496610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs: MFI register set 6506610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 6516610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic inline void 6526610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_enable_intr_gen2(struct megasas_register_set __iomem *regs) 6536610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{ 6546610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); 6556610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6566610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* write ~0x00000005 (4 & 1) to the intr mask*/ 6576610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask); 6586610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6596610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* Dummy readl to force pci flush */ 6606610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo readl(®s->outbound_intr_mask); 6616610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo} 6626610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6636610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 6646610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_disable_intr_gen2 - Disables interrupt 6656610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs: MFI register set 6666610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 6676610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic inline void 6686610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_disable_intr_gen2(struct megasas_register_set __iomem *regs) 6696610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{ 6706610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo u32 mask = 0xFFFFFFFF; 6716610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo writel(mask, ®s->outbound_intr_mask); 6726610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* Dummy readl to force pci flush */ 6736610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo readl(®s->outbound_intr_mask); 6746610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo} 6756610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6766610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 6776610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_read_fw_status_reg_gen2 - returns the current FW status value 6786610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs: MFI register set 6796610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 6806610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic u32 6816610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs) 6826610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{ 6836610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo return readl(&(regs)->outbound_scratch_pad); 6846610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo} 6856610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6866610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 6876610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_clear_interrupt_gen2 - Check & clear interrupt 6886610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs: MFI register set 6896610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 6906610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic int 6916610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_clear_intr_gen2(struct megasas_register_set __iomem *regs) 6926610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{ 6936610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo u32 status; 69439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 mfiStatus = 0; 6956610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* 6966610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * Check if it is our interrupt 6976610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 6986610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo status = readl(®s->outbound_intr_status); 6996610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 70039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (status & MFI_GEN2_ENABLE_INTERRUPT_MASK) { 70139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; 70239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 70339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) { 70439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; 70539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 7066610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 7076610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* 7086610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * Clear the interrupt by writing back the same value 7096610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 71039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (mfiStatus) 71139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(status, ®s->outbound_doorbell_clear); 7126610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 7136610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* Dummy readl to force pci flush */ 7146610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo readl(®s->outbound_intr_status); 7156610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 71639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return mfiStatus; 7176610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo} 7186610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 7196610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_fire_cmd_gen2 - Sends command to the FW 7206610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @frame_phys_addr : Physical address of cmd 7216610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @frame_count : Number of frames for the command 7226610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs : MFI register set 7236610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 7246610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic inline void 7250c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_gen2(struct megasas_instance *instance, 7260c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo dma_addr_t frame_phys_addr, 7270c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo u32 frame_count, 7286610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo struct megasas_register_set __iomem *regs) 7296610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{ 73039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 73139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 7326610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo writel((frame_phys_addr | (frame_count<<1))|1, 7336610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo &(regs)->inbound_queue_port); 73439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 73539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 73639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 73739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 73839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_adp_reset_gen2 - For controller reset 73939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 74039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 74139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 74239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_adp_reset_gen2(struct megasas_instance *instance, 74339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *reg_set) 74439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 74539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 retry = 0 ; 74639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 HostDiag; 747ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford u32 *seq_offset = ®_set->seq_offset; 748ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford u32 *hostdiag_offset = ®_set->host_diag; 749ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford 750ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford if (instance->instancet == &megasas_instance_template_skinny) { 751ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford seq_offset = ®_set->fusion_seq_offset; 752ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford hostdiag_offset = ®_set->fusion_host_diag; 753ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford } 754ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford 755ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(0, seq_offset); 756ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(4, seq_offset); 757ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(0xb, seq_offset); 758ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(2, seq_offset); 759ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(7, seq_offset); 760ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(0xd, seq_offset); 76139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 76239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 76339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 764ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford HostDiag = (u32)readl(hostdiag_offset); 76539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 76639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang while ( !( HostDiag & DIAG_WRITE_ENABLE) ) { 76739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(100); 768ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford HostDiag = (u32)readl(hostdiag_offset); 76939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n", 77039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang retry, HostDiag); 77139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 77239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (retry++ >= 100) 77339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 1; 77439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 77539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 77639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 77739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag); 77839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 779ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset); 78039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 78139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ssleep(10); 78239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 783ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford HostDiag = (u32)readl(hostdiag_offset); 78439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang while ( ( HostDiag & DIAG_RESET_ADAPTER) ) { 78539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(100); 786ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford HostDiag = (u32)readl(hostdiag_offset); 78739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n", 78839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang retry, HostDiag); 78939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 79039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (retry++ >= 1000) 79139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 1; 79239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 79339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 79439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 79539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 79639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 79739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 79839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_gen2 - For controller reset check 79939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 80039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 80139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 80239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_gen2(struct megasas_instance *instance, 80339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 80439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 805707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) { 806707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo return 1; 807707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 808707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 80939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 8106610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo} 8116610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 8126610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic struct megasas_instance_template megasas_instance_template_gen2 = { 8136610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 8146610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo .fire_cmd = megasas_fire_cmd_gen2, 8156610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo .enable_intr = megasas_enable_intr_gen2, 8166610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo .disable_intr = megasas_disable_intr_gen2, 8176610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo .clear_intr = megasas_clear_intr_gen2, 8186610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo .read_fw_status_reg = megasas_read_fw_status_reg_gen2, 81939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .adp_reset = megasas_adp_reset_gen2, 82039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .check_reset = megasas_check_reset_gen2, 821cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .service_isr = megasas_isr, 822cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .tasklet = megasas_complete_cmd_dpc, 823cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .init_adapter = megasas_init_adapter_mfi, 824cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .build_and_issue_cmd = megasas_build_and_issue_cmd, 825cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .issue_dcmd = megasas_issue_dcmd, 8266610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo}; 8276610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 8286610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 829f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro* This is the end of set of functions & definitions 83039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang* specific to gen2 (deviceid : 0x78, 0x79) controllers 831f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro*/ 832f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 8339c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford/* 8349c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford * Template added for TB (Fusion) 8359c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford */ 8369c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordextern struct megasas_instance_template megasas_instance_template_fusion; 8379c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 838f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 839c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_issue_polled - Issues a polling command 840c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 8410d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * @cmd: Command packet to be issued 842c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 843c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * For polling, MFI requires the cmd_status to be set to 0xFF before posting. 844c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 8459c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint 846c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd) 847c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 848c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 849c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_header *frame_hdr = &cmd->frame->hdr; 850c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 851c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas frame_hdr->cmd_status = 0xFF; 852c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE; 853c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 854c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Issue the frame using inbound queue port 856c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 8579c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->instancet->issue_dcmd(instance, cmd); 858c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 859c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 860c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Wait for cmd_status to change 861c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 8629c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford return wait_and_poll(instance, cmd); 863c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 864c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 865c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 866c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds 867c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 868c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Command to be issued 869c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 870c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function waits on an event for the command to be returned from ISR. 8712a3681e56e825bce469d2ccf3c85741b5005e1f1Sumant Patro * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs 872c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Used to issue ioctl commands. 873c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 874c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 875c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_issue_blocked_cmd(struct megasas_instance *instance, 876c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd) 877c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 878c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->cmd_status = ENODATA; 879c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 8809c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->instancet->issue_dcmd(instance, cmd); 881c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 88239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang wait_event(instance->int_cmd_wait_q, cmd->cmd_status != ENODATA); 883c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 884c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 885c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 886c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 887c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 888c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd 889c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 890c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd_to_abort: Previously issued cmd to be aborted 891c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 8928e572bab39c484cdf512715f98626337f25cfc32Justin P. Mattock * MFI firmware can abort previously issued AEN command (automatic event 893c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * notification). The megasas_issue_blocked_abort_cmd() issues such abort 8942a3681e56e825bce469d2ccf3c85741b5005e1f1Sumant Patro * cmd and waits for return status. 8952a3681e56e825bce469d2ccf3c85741b5005e1f1Sumant Patro * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs 896c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 897c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 898c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_issue_blocked_abort_cmd(struct megasas_instance *instance, 899c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd_to_abort) 900c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 901c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 902c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_abort_frame *abort_fr; 903c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 904c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 905c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 906c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) 907c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -1; 908c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 909c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr = &cmd->frame->abort; 910c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 911c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 912c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Prepare and issue the abort frame 913c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 914c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->cmd = MFI_CMD_ABORT; 915c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->cmd_status = 0xFF; 916c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->flags = 0; 917c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->abort_context = cmd_to_abort->index; 918c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->abort_mfi_phys_addr_lo = cmd_to_abort->frame_phys_addr; 919c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->abort_mfi_phys_addr_hi = 0; 920c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 921c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sync_cmd = 1; 922c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->cmd_status = 0xFF; 923c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 9249c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->instancet->issue_dcmd(instance, cmd); 925c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 926c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 927c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Wait for this cmd to complete 928c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 92939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang wait_event(instance->abort_cmd_wait_q, cmd->cmd_status != 0xFF); 93039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->sync_cmd = 0; 931c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 932c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 933c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 935c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 936c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 937c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_make_sgl32 - Prepares 32-bit SGL 938c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 939c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp: SCSI command from the mid-layer 940c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @mfi_sgl: SGL to be filled in 941c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 942c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * If successful, this function returns the number of SG elements. Otherwise, 943c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * it returnes -1. 944c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 945858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int 946c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp, 947c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas union megasas_sgl *mfi_sgl) 948c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 949c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 950c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int sge_count; 951c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct scatterlist *os_sgl; 952c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 953155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori sge_count = scsi_dma_map(scp); 954155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori BUG_ON(sge_count < 0); 955c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 956155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori if (sge_count) { 957155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori scsi_for_each_sg(scp, os_sgl, sge_count, i) { 958155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori mfi_sgl->sge32[i].length = sg_dma_len(os_sgl); 959155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl); 960155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori } 961c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 962c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return sge_count; 963c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 964c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 965c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 966c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_make_sgl64 - Prepares 64-bit SGL 967c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 968c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp: SCSI command from the mid-layer 969c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @mfi_sgl: SGL to be filled in 970c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 971c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * If successful, this function returns the number of SG elements. Otherwise, 972c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * it returnes -1. 973c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 974858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int 975c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, 976c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas union megasas_sgl *mfi_sgl) 977c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 978c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 979c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int sge_count; 980c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct scatterlist *os_sgl; 981c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 982155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori sge_count = scsi_dma_map(scp); 983155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori BUG_ON(sge_count < 0); 984c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 985155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori if (sge_count) { 986155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori scsi_for_each_sg(scp, os_sgl, sge_count, i) { 987155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori mfi_sgl->sge64[i].length = sg_dma_len(os_sgl); 988155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl); 989155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori } 990c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 991c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return sge_count; 992c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 993c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 994f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo/** 995f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * megasas_make_sgl_skinny - Prepares IEEE SGL 996f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * @instance: Adapter soft state 997f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * @scp: SCSI command from the mid-layer 998f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * @mfi_sgl: SGL to be filled in 999f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * 1000f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * If successful, this function returns the number of SG elements. Otherwise, 1001f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * it returnes -1. 1002f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo */ 1003f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bostatic int 1004f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bomegasas_make_sgl_skinny(struct megasas_instance *instance, 1005f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl) 1006f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo{ 1007f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo int i; 1008f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo int sge_count; 1009f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo struct scatterlist *os_sgl; 1010f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1011f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo sge_count = scsi_dma_map(scp); 1012f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1013f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (sge_count) { 1014f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo scsi_for_each_sg(scp, os_sgl, sge_count, i) { 1015f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl); 1016f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo mfi_sgl->sge_skinny[i].phys_addr = 1017f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo sg_dma_address(os_sgl); 1018707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo mfi_sgl->sge_skinny[i].flag = 0; 1019f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 1020f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 1021f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo return sge_count; 1022f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo} 1023f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1024b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro /** 1025b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * megasas_get_frame_count - Computes the number of frames 1026d532dbe2cb71586ab520dbef732d1af54a689313bo yang * @frame_type : type of frame- io or pthru frame 1027b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * @sge_count : number of sg elements 1028b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * 1029b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * Returns the number of frames required for numnber of sge's (sge_count) 1030b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro */ 1031b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1032f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bostatic u32 megasas_get_frame_count(struct megasas_instance *instance, 1033f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo u8 sge_count, u8 frame_type) 1034b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro{ 1035b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro int num_cnt; 1036b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro int sge_bytes; 1037b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro u32 sge_sz; 1038b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro u32 frame_count=0; 1039b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1040b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : 1041b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro sizeof(struct megasas_sge32); 1042b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1043f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee) { 1044f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo sge_sz = sizeof(struct megasas_sge_skinny); 1045f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 1046f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1047b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro /* 1048d532dbe2cb71586ab520dbef732d1af54a689313bo yang * Main frame can contain 2 SGEs for 64-bit SGLs and 1049d532dbe2cb71586ab520dbef732d1af54a689313bo yang * 3 SGEs for 32-bit SGLs for ldio & 1050d532dbe2cb71586ab520dbef732d1af54a689313bo yang * 1 SGEs for 64-bit SGLs and 1051d532dbe2cb71586ab520dbef732d1af54a689313bo yang * 2 SGEs for 32-bit SGLs for pthru frame 1052d532dbe2cb71586ab520dbef732d1af54a689313bo yang */ 1053d532dbe2cb71586ab520dbef732d1af54a689313bo yang if (unlikely(frame_type == PTHRU_FRAME)) { 1054f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee == 1) { 1055f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo num_cnt = sge_count - 1; 1056f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } else if (IS_DMA64) 1057d532dbe2cb71586ab520dbef732d1af54a689313bo yang num_cnt = sge_count - 1; 1058d532dbe2cb71586ab520dbef732d1af54a689313bo yang else 1059d532dbe2cb71586ab520dbef732d1af54a689313bo yang num_cnt = sge_count - 2; 1060d532dbe2cb71586ab520dbef732d1af54a689313bo yang } else { 1061f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee == 1) { 1062f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo num_cnt = sge_count - 1; 1063f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } else if (IS_DMA64) 1064d532dbe2cb71586ab520dbef732d1af54a689313bo yang num_cnt = sge_count - 2; 1065d532dbe2cb71586ab520dbef732d1af54a689313bo yang else 1066d532dbe2cb71586ab520dbef732d1af54a689313bo yang num_cnt = sge_count - 3; 1067d532dbe2cb71586ab520dbef732d1af54a689313bo yang } 1068b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1069b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro if(num_cnt>0){ 1070b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro sge_bytes = sge_sz * num_cnt; 1071b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1072b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) + 1073b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ; 1074b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro } 1075b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro /* Main frame */ 1076b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro frame_count +=1; 1077b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1078b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro if (frame_count > 7) 1079b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro frame_count = 8; 1080b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro return frame_count; 1081b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro} 1082b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1083c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1084c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_build_dcdb - Prepares a direct cdb (DCDB) command 1085c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 1086c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp: SCSI command 1087c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Command to be prepared in 1088c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 1089c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function prepares CDB commands. These are typcially pass-through 1090c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * commands to the devices. 1091c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1092858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int 1093c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, 1094c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd) 1095c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1096c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 is_logical; 1097c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 device_id; 1098c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u16 flags = 0; 1099c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_pthru_frame *pthru; 1100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1101c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas is_logical = MEGASAS_IS_LOGICAL(scp); 1102c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas device_id = MEGASAS_DEV_INDEX(instance, scp); 1103c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru = (struct megasas_pthru_frame *)cmd->frame; 1104c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1105c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (scp->sc_data_direction == PCI_DMA_TODEVICE) 1106c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas flags = MFI_FRAME_DIR_WRITE; 1107c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) 1108c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas flags = MFI_FRAME_DIR_READ; 1109c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->sc_data_direction == PCI_DMA_NONE) 1110c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas flags = MFI_FRAME_DIR_NONE; 1111c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1112f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee == 1) { 1113f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo flags |= MFI_FRAME_IEEE; 1114f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 1115f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1116c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1117c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Prepare the DCDB frame 1118c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1119c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO; 1120c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->cmd_status = 0x0; 1121c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->scsi_status = 0x0; 1122c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->target_id = device_id; 1123c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->lun = scp->device->lun; 1124c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->cdb_len = scp->cmd_len; 1125c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->timeout = 0; 1126780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo pthru->pad_0 = 0; 1127c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->flags = flags; 1128155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori pthru->data_xfer_len = scsi_bufflen(scp); 1129c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1130c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memcpy(pthru->cdb, scp->cmnd, scp->cmd_len); 1131c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1132c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 11338d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo * If the command is for the tape device, set the 11348d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo * pthru timeout to the os layer timeout value. 11358d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo */ 11368d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo if (scp->device->type == TYPE_TAPE) { 11378d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo if ((scp->request->timeout / HZ) > 0xFFFF) 11388d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo pthru->timeout = 0xFFFF; 11398d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo else 11408d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo pthru->timeout = scp->request->timeout / HZ; 11418d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo } 11428d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo 11438d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo /* 1144c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Construct SGL 1145c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1146f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee == 1) { 1147f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo pthru->flags |= MFI_FRAME_SGL64; 1148f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo pthru->sge_count = megasas_make_sgl_skinny(instance, scp, 1149f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo &pthru->sgl); 1150f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } else if (IS_DMA64) { 1151c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->flags |= MFI_FRAME_SGL64; 1152c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->sge_count = megasas_make_sgl64(instance, scp, 1153c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &pthru->sgl); 1154c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else 1155c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->sge_count = megasas_make_sgl32(instance, scp, 1156c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &pthru->sgl); 1157c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1158bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (pthru->sge_count > instance->max_num_sge) { 1159bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo printk(KERN_ERR "megasas: DCDB two many SGE NUM=%x\n", 1160bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo pthru->sge_count); 1161bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo return 0; 1162bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 1163bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 1164c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1165c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Sense info specific 1166c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1167c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->sense_len = SCSI_SENSE_BUFFERSIZE; 1168c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->sense_buf_phys_addr_hi = 0; 1169c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; 1170c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1171c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1172c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Compute the total number of frames this command consumes. FW uses 1173c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * this number to pull sufficient number of frames from host memory. 1174c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1175f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count, 1176d532dbe2cb71586ab520dbef732d1af54a689313bo yang PTHRU_FRAME); 1177c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1178c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return cmd->frame_count; 1179c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1180c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1181c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1182c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_build_ldio - Prepares IOs to logical devices 1183c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 1184c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp: SCSI command 1185fd589a8f0a13f53a2dd580b1fe170633cf6b095fAnand Gadiyar * @cmd: Command to be prepared 1186c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 1187c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Frames (and accompanying SGLs) for regular SCSI IOs use this function. 1188c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1189858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int 1190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, 1191c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd) 1192c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 device_id; 1194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u8 sc = scp->cmnd[0]; 1195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u16 flags = 0; 1196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_io_frame *ldio; 1197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas device_id = MEGASAS_DEV_INDEX(instance, scp); 1199c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio = (struct megasas_io_frame *)cmd->frame; 1200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1201c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (scp->sc_data_direction == PCI_DMA_TODEVICE) 1202c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas flags = MFI_FRAME_DIR_WRITE; 1203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) 1204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas flags = MFI_FRAME_DIR_READ; 1205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1206f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee == 1) { 1207f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo flags |= MFI_FRAME_IEEE; 1208f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 1209f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1210c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1211b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * Prepare the Logical IO frame: 2nd bit is zero for all read cmds 1212c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1213c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ; 1214c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->cmd_status = 0x0; 1215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->scsi_status = 0x0; 1216c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->target_id = device_id; 1217c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->timeout = 0; 1218c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->reserved_0 = 0; 1219c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->pad_0 = 0; 1220c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->flags = flags; 1221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_hi = 0; 1222c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->access_byte = (scp->cmd_len != 6) ? scp->cmnd[1] : 0; 1223c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1224c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1225c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 6-byte READ(0x08) or WRITE(0x0A) cdb 1226c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (scp->cmd_len == 6) { 1228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->lba_count = (u32) scp->cmnd[4]; 1229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_lo = ((u32) scp->cmnd[1] << 16) | 1230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3]; 1231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_lo &= 0x1FFFFF; 1233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1235c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 10-byte READ(0x28) or WRITE(0x2A) cdb 1237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->cmd_len == 10) { 1239c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->lba_count = (u32) scp->cmnd[8] | 1240c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[7] << 8); 1241c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) | 1242c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[3] << 16) | 1243c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5]; 1244c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1245c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1246c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1247c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 12-byte READ(0xA8) or WRITE(0xAA) cdb 1248c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1249c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->cmd_len == 12) { 1250c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->lba_count = ((u32) scp->cmnd[6] << 24) | 1251c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[7] << 16) | 1252c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9]; 1253c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1254c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) | 1255c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[3] << 16) | 1256c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5]; 1257c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1258c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1259c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1260c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 16-byte READ(0x88) or WRITE(0x8A) cdb 1261c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1262c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->cmd_len == 16) { 1263c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->lba_count = ((u32) scp->cmnd[10] << 24) | 1264c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[11] << 16) | 1265c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13]; 1266c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1267c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_lo = ((u32) scp->cmnd[6] << 24) | 1268c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[7] << 16) | 1269c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9]; 1270c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1271c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_hi = ((u32) scp->cmnd[2] << 24) | 1272c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[3] << 16) | 1273c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5]; 1274c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1275c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1276c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1277c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1278c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Construct SGL 1279c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1280f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee) { 1281f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo ldio->flags |= MFI_FRAME_SGL64; 1282f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo ldio->sge_count = megasas_make_sgl_skinny(instance, scp, 1283f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo &ldio->sgl); 1284f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } else if (IS_DMA64) { 1285c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->flags |= MFI_FRAME_SGL64; 1286c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl); 1287c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else 1288c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl); 1289c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1290bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (ldio->sge_count > instance->max_num_sge) { 1291bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo printk(KERN_ERR "megasas: build_ld_io: sge_count = %x\n", 1292bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ldio->sge_count); 1293bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo return 0; 1294bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 1295bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 1296c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1297c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Sense info specific 1298c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1299c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->sense_len = SCSI_SENSE_BUFFERSIZE; 1300c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->sense_buf_phys_addr_hi = 0; 1301c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr; 1302c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1303b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro /* 1304b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * Compute the total number of frames this command consumes. FW uses 1305b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * this number to pull sufficient number of frames from host memory. 1306b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro */ 1307f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo cmd->frame_count = megasas_get_frame_count(instance, 1308f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo ldio->sge_count, IO_FRAME); 1309c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1310c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return cmd->frame_count; 1311c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1312c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1313c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1314cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro * megasas_is_ldio - Checks if the cmd is for logical drive 1315cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro * @scmd: SCSI command 13160d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * 1317cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro * Called by megasas_queue_command to find out if the command to be queued 13180d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * is a logical drive command 1319c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 13209c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordinline int megasas_is_ldio(struct scsi_cmnd *cmd) 1321c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1322cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro if (!MEGASAS_IS_LOGICAL(cmd)) 1323cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return 0; 1324cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro switch (cmd->cmnd[0]) { 1325cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case READ_10: 1326cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case WRITE_10: 1327cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case READ_12: 1328cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case WRITE_12: 1329cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case READ_6: 1330cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case WRITE_6: 1331cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case READ_16: 1332cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case WRITE_16: 1333cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return 1; 1334cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro default: 1335cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return 0; 1336c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1337c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1338c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1339658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro /** 1340658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro * megasas_dump_pending_frames - Dumps the frame address of all pending cmds 1341658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro * in FW 1342658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro * @instance: Adapter soft state 1343658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro */ 1344658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patrostatic inline void 1345658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patromegasas_dump_pending_frames(struct megasas_instance *instance) 1346658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro{ 1347658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro struct megasas_cmd *cmd; 1348658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro int i,n; 1349658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro union megasas_sgl *mfi_sgl; 1350658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro struct megasas_io_frame *ldio; 1351658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro struct megasas_pthru_frame *pthru; 1352658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro u32 sgcount; 1353658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro u32 max_cmd = instance->max_fw_cmds; 1354658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 1355658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no); 1356658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding)); 1357658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if (IS_DMA64) 1358658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no); 1359658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro else 1360658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no); 1361658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 1362658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no); 1363658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro for (i = 0; i < max_cmd; i++) { 1364658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro cmd = instance->cmd_list[i]; 1365658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if(!cmd->scmd) 1366658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro continue; 1367658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr); 1368658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if (megasas_is_ldio(cmd->scmd)){ 1369658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro ldio = (struct megasas_io_frame *)cmd->frame; 1370658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro mfi_sgl = &ldio->sgl; 1371658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro sgcount = ldio->sge_count; 1372658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant 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); 1373658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1374658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro else { 1375658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro pthru = (struct megasas_pthru_frame *) cmd->frame; 1376658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro mfi_sgl = &pthru->sgl; 1377658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro sgcount = pthru->sge_count; 1378658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant 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); 1379658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1380658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if(megasas_dbg_lvl & MEGASAS_DBG_LVL){ 1381658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro for (n = 0; n < sgcount; n++){ 1382658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if (IS_DMA64) 1383658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant 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) ; 1384658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro else 1385658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",mfi_sgl->sge32[n].length , mfi_sgl->sge32[n].phys_addr) ; 1386658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1387658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1388658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "\n"); 1389658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } /*for max_cmd*/ 1390658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no); 1391658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro for (i = 0; i < max_cmd; i++) { 1392658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 1393658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro cmd = instance->cmd_list[i]; 1394658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 1395658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if(cmd->sync_cmd == 1){ 1396658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr); 1397658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1398658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1399658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no); 1400658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro} 1401658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 1402cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordu32 1403cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordmegasas_build_and_issue_cmd(struct megasas_instance *instance, 1404cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct scsi_cmnd *scmd) 1405cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford{ 1406cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct megasas_cmd *cmd; 1407cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford u32 frame_count; 1408cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1409cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford cmd = megasas_get_cmd(instance); 1410cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (!cmd) 1411cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return SCSI_MLQUEUE_HOST_BUSY; 1412cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1413cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* 1414cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * Logical drive command 1415cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford */ 1416cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (megasas_is_ldio(scmd)) 1417cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford frame_count = megasas_build_ldio(instance, scmd, cmd); 1418cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford else 1419cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford frame_count = megasas_build_dcdb(instance, scmd, cmd); 1420cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1421cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (!frame_count) 1422cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford goto out_return_cmd; 1423cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1424cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford cmd->scmd = scmd; 1425cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford scmd->SCp.ptr = (char *)cmd; 1426cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1427cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* 1428cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * Issue the command to the FW 1429cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford */ 1430cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford atomic_inc(&instance->fw_outstanding); 1431cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1432cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet->fire_cmd(instance, cmd->frame_phys_addr, 1433cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford cmd->frame_count-1, instance->reg_set); 1434cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1435cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return 0; 1436cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordout_return_cmd: 1437cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford megasas_return_cmd(instance, cmd); 1438cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return 1; 1439cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford} 1440cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1441cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1442c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1443c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_queue_command - Queue entry point 1444c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scmd: SCSI command to be queued 1445c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @done: Callback entry point 1446c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1447c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 1448f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzikmegasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) 1449c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1450c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 145139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 1452c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1453c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = (struct megasas_instance *) 1454c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scmd->device->host->hostdata; 1455af37acfb63d8e924550e67b884dbd1c478e26c96Sumant Patro 145639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->issuepend_done == 0) 1457af37acfb63d8e924550e67b884dbd1c478e26c96Sumant Patro return SCSI_MLQUEUE_HOST_BUSY; 1458af37acfb63d8e924550e67b884dbd1c478e26c96Sumant Patro 145939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 146039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) { 146139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 146239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return SCSI_MLQUEUE_HOST_BUSY; 146339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 146439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 146539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 146639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 1467c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scmd->scsi_done = done; 1468c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scmd->result = 0; 1469c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1470cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro if (MEGASAS_IS_LOGICAL(scmd) && 1471cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) { 1472cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro scmd->result = DID_BAD_TARGET << 16; 1473cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro goto out_done; 1474c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1475c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 147602b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro switch (scmd->cmnd[0]) { 147702b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro case SYNCHRONIZE_CACHE: 147802b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro /* 147902b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro * FW takes care of flush cache on its own 148002b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro * No need to send it down 148102b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro */ 148202b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro scmd->result = DID_OK << 16; 148302b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro goto out_done; 148402b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro default: 148502b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro break; 148602b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro } 148702b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro 1488cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (instance->instancet->build_and_issue_cmd(instance, scmd)) { 1489cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford printk(KERN_ERR "megasas: Err returned from build_and_issue_cmd\n"); 1490cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return SCSI_MLQUEUE_HOST_BUSY; 1491cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford } 1492c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1493c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 1494cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro 1495cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro out_done: 1496cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro done(scmd); 1497cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return 0; 1498c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1499c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1500f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzikstatic DEF_SCSI_QCMD(megasas_queue_command) 1501f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzik 1502044833b572b96afe91506a0edec42efd84ba4939Yang, Bostatic struct megasas_instance *megasas_lookup_instance(u16 host_no) 1503044833b572b96afe91506a0edec42efd84ba4939Yang, Bo{ 1504044833b572b96afe91506a0edec42efd84ba4939Yang, Bo int i; 1505044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1506044833b572b96afe91506a0edec42efd84ba4939Yang, Bo for (i = 0; i < megasas_mgmt_info.max_index; i++) { 1507044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1508044833b572b96afe91506a0edec42efd84ba4939Yang, Bo if ((megasas_mgmt_info.instance[i]) && 1509044833b572b96afe91506a0edec42efd84ba4939Yang, Bo (megasas_mgmt_info.instance[i]->host->host_no == host_no)) 1510044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return megasas_mgmt_info.instance[i]; 1511044833b572b96afe91506a0edec42efd84ba4939Yang, Bo } 1512044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1513044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return NULL; 1514044833b572b96afe91506a0edec42efd84ba4939Yang, Bo} 1515044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1516147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwigstatic int megasas_slave_configure(struct scsi_device *sdev) 1517147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig{ 1518044833b572b96afe91506a0edec42efd84ba4939Yang, Bo u16 pd_index = 0; 1519044833b572b96afe91506a0edec42efd84ba4939Yang, Bo struct megasas_instance *instance ; 1520044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1521044833b572b96afe91506a0edec42efd84ba4939Yang, Bo instance = megasas_lookup_instance(sdev->host->host_no); 1522044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1523147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig /* 1524044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * Don't export physical disk devices to the disk driver. 1525044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * 1526044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * FIXME: Currently we don't export them to the midlayer at all. 1527044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * That will be fixed once LSI engineers have audited the 1528044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * firmware for possible issues. 1529044833b572b96afe91506a0edec42efd84ba4939Yang, Bo */ 1530044833b572b96afe91506a0edec42efd84ba4939Yang, Bo if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && 1531044833b572b96afe91506a0edec42efd84ba4939Yang, Bo sdev->type == TYPE_DISK) { 1532044833b572b96afe91506a0edec42efd84ba4939Yang, Bo pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + 1533044833b572b96afe91506a0edec42efd84ba4939Yang, Bo sdev->id; 1534044833b572b96afe91506a0edec42efd84ba4939Yang, Bo if (instance->pd_list[pd_index].driveState == 1535044833b572b96afe91506a0edec42efd84ba4939Yang, Bo MR_PD_STATE_SYSTEM) { 1536044833b572b96afe91506a0edec42efd84ba4939Yang, Bo blk_queue_rq_timeout(sdev->request_queue, 1537044833b572b96afe91506a0edec42efd84ba4939Yang, Bo MEGASAS_DEFAULT_CMD_TIMEOUT * HZ); 1538044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return 0; 1539044833b572b96afe91506a0edec42efd84ba4939Yang, Bo } 1540147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig return -ENXIO; 1541044833b572b96afe91506a0edec42efd84ba4939Yang, Bo } 1542e5b3a65fd7244e662691cf617145983ecde28cc9Christoph Hellwig 1543e5b3a65fd7244e662691cf617145983ecde28cc9Christoph Hellwig /* 1544044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * The RAID firmware may require extended timeouts. 1545044833b572b96afe91506a0edec42efd84ba4939Yang, Bo */ 1546044833b572b96afe91506a0edec42efd84ba4939Yang, Bo blk_queue_rq_timeout(sdev->request_queue, 1547044833b572b96afe91506a0edec42efd84ba4939Yang, Bo MEGASAS_DEFAULT_CMD_TIMEOUT * HZ); 1548044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return 0; 1549044833b572b96afe91506a0edec42efd84ba4939Yang, Bo} 1550044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1551044833b572b96afe91506a0edec42efd84ba4939Yang, Bostatic int megasas_slave_alloc(struct scsi_device *sdev) 1552044833b572b96afe91506a0edec42efd84ba4939Yang, Bo{ 1553044833b572b96afe91506a0edec42efd84ba4939Yang, Bo u16 pd_index = 0; 1554044833b572b96afe91506a0edec42efd84ba4939Yang, Bo struct megasas_instance *instance ; 1555044833b572b96afe91506a0edec42efd84ba4939Yang, Bo instance = megasas_lookup_instance(sdev->host->host_no); 1556044833b572b96afe91506a0edec42efd84ba4939Yang, Bo if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) && 1557044833b572b96afe91506a0edec42efd84ba4939Yang, Bo (sdev->type == TYPE_DISK)) { 1558044833b572b96afe91506a0edec42efd84ba4939Yang, Bo /* 1559044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * Open the OS scan to the SYSTEM PD 1560044833b572b96afe91506a0edec42efd84ba4939Yang, Bo */ 1561044833b572b96afe91506a0edec42efd84ba4939Yang, Bo pd_index = 1562044833b572b96afe91506a0edec42efd84ba4939Yang, Bo (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + 1563044833b572b96afe91506a0edec42efd84ba4939Yang, Bo sdev->id; 1564044833b572b96afe91506a0edec42efd84ba4939Yang, Bo if ((instance->pd_list[pd_index].driveState == 1565044833b572b96afe91506a0edec42efd84ba4939Yang, Bo MR_PD_STATE_SYSTEM) && 1566044833b572b96afe91506a0edec42efd84ba4939Yang, Bo (instance->pd_list[pd_index].driveType == 1567044833b572b96afe91506a0edec42efd84ba4939Yang, Bo TYPE_DISK)) { 1568044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return 0; 1569044833b572b96afe91506a0edec42efd84ba4939Yang, Bo } 1570044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return -ENXIO; 1571044833b572b96afe91506a0edec42efd84ba4939Yang, Bo } 1572147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig return 0; 1573147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig} 1574147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig 15759c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid megaraid_sas_kill_hba(struct megasas_instance *instance) 157639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 157739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 15789c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 157936807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || 158036807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) { 15819c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford writel(MFI_STOP_ADP, &instance->reg_set->doorbell); 158239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else { 15839c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell); 15849c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 15859c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford} 15869c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 15879c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford /** 15889c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford * megasas_check_and_restore_queue_depth - Check if queue depth needs to be 15899c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford * restored to max value 15909c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford * @instance: Adapter soft state 15919c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford * 15929c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford */ 15939c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid 15949c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_check_and_restore_queue_depth(struct megasas_instance *instance) 15959c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford{ 15969c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford unsigned long flags; 15979c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (instance->flag & MEGASAS_FW_BUSY 15989c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford && time_after(jiffies, instance->last_time + 5 * HZ) 15999c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford && atomic_read(&instance->fw_outstanding) < 17) { 16009c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 16019c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_lock_irqsave(instance->host->host_lock, flags); 16029c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->flag &= ~MEGASAS_FW_BUSY; 16039c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if ((instance->pdev->device == 16049c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 16059c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == 16069c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { 16079c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->host->can_queue = 16089c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS; 16099c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } else 16109c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->host->can_queue = 16119c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->max_fw_cmds - MEGASAS_INT_CMDS; 16129c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 16139c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_unlock_irqrestore(instance->host->host_lock, flags); 161439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 161539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 161639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 1617c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 16187343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * megasas_complete_cmd_dpc - Returns FW's controller structure 16197343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * @instance_addr: Address of adapter soft state 16207343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * 16217343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * Tasklet to complete cmds 16227343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang */ 16237343eb6570ae3b299e7b5185b139d8335ef60e9bbo yangstatic void megasas_complete_cmd_dpc(unsigned long instance_addr) 16247343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang{ 16257343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang u32 producer; 16267343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang u32 consumer; 16277343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang u32 context; 16287343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang struct megasas_cmd *cmd; 16297343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang struct megasas_instance *instance = 16307343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang (struct megasas_instance *)instance_addr; 16317343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang unsigned long flags; 16327343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16337343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang /* If we have already declared adapter dead, donot complete cmds */ 163439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR ) 16357343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang return; 16367343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16377343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang spin_lock_irqsave(&instance->completion_lock, flags); 16387343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16397343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang producer = *instance->producer; 16407343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang consumer = *instance->consumer; 16417343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16427343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang while (consumer != producer) { 16437343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang context = instance->reply_queue[consumer]; 164439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (context >= instance->max_fw_cmds) { 164539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_ERR "Unexpected context value %x\n", 164639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang context); 164739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang BUG(); 164839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 16497343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16507343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang cmd = instance->cmd_list[context]; 16517343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16527343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang megasas_complete_cmd(instance, cmd, DID_OK); 16537343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16547343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang consumer++; 16557343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang if (consumer == (instance->max_fw_cmds + 1)) { 16567343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang consumer = 0; 16577343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang } 16587343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang } 16597343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16607343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang *instance->consumer = producer; 16617343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16627343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang spin_unlock_irqrestore(&instance->completion_lock, flags); 16637343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16647343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang /* 16657343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * Check if we can restore can_queue 16667343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang */ 16679c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_check_and_restore_queue_depth(instance); 16687343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang} 16697343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 1670707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bostatic void 1671707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bomegasas_internal_reset_defer_cmds(struct megasas_instance *instance); 1672707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1673707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bostatic void 1674707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Boprocess_fw_state_change_wq(struct work_struct *work); 1675707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1676707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bovoid megasas_do_ocr(struct megasas_instance *instance) 1677707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo{ 1678707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) || 1679707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) || 1680707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) { 1681707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo *instance->consumer = MEGASAS_ADPRESET_INPROG_SIGN; 1682707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1683707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo instance->instancet->disable_intr(instance->reg_set); 1684707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; 1685707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo instance->issuepend_done = 0; 1686707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1687707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo atomic_set(&instance->fw_outstanding, 0); 1688707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo megasas_internal_reset_defer_cmds(instance); 1689707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo process_fw_state_change_wq(&instance->work_init); 1690707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo} 1691707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 16927343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang/** 1693c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_wait_for_outstanding - Wait for all outstanding cmds 1694c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 1695c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 169625985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * This function waits for up to MEGASAS_RESET_WAIT_TIME seconds for FW to 1697c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * complete all its outstanding commands. Returns error if one or more IOs 1698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * are pending after this time period. It also marks the controller dead. 1699c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1700c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_wait_for_outstanding(struct megasas_instance *instance) 1701c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1702c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 170339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 reset_index; 1704c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 wait_time = MEGASAS_RESET_WAIT_TIME; 170539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u8 adprecovery; 170639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 170739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct list_head clist_local; 170839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_cmd *reset_cmd; 1709707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo u32 fw_state; 1710707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo u8 kill_adapter_flag; 171139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 171239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 171339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang adprecovery = instance->adprecovery; 171439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 171539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 171639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (adprecovery != MEGASAS_HBA_OPERATIONAL) { 171739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 171839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang INIT_LIST_HEAD(&clist_local); 171939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 172039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_splice_init(&instance->internal_reset_pending_q, 172139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang &clist_local); 172239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 172339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 172439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: HBA reset wait ...\n"); 172539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < wait_time; i++) { 172639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 172739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 172839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang adprecovery = instance->adprecovery; 172939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 173039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (adprecovery == MEGASAS_HBA_OPERATIONAL) 173139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang break; 173239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 173339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 173439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (adprecovery != MEGASAS_HBA_OPERATIONAL) { 173539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: reset: Stopping HBA.\n"); 173639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 173739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR; 173839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 173939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return FAILED; 174039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 174139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 174239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_index = 0; 174339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang while (!list_empty(&clist_local)) { 174439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd = list_entry((&clist_local)->next, 174539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_cmd, list); 174639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_del_init(&reset_cmd->list); 174739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (reset_cmd->scmd) { 174839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd->scmd->result = DID_RESET << 16; 17495cd049a59913f359e7d30c11d2dc6187822e77b1Christoph Hellwig printk(KERN_NOTICE "%d:%p reset [%02x]\n", 175039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_index, reset_cmd, 17515cd049a59913f359e7d30c11d2dc6187822e77b1Christoph Hellwig reset_cmd->scmd->cmnd[0]); 175239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 175339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd->scmd->scsi_done(reset_cmd->scmd); 175439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_return_cmd(instance, reset_cmd); 175539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else if (reset_cmd->sync_cmd) { 175639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas:%p synch cmds" 175739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "reset queue\n", 175839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd); 175939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 176039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd->cmd_status = ENODATA; 176139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->fire_cmd(instance, 176239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd->frame_phys_addr, 176339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 0, instance->reg_set); 176439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else { 176539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: %p unexpected" 176639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "cmds lst\n", 176739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd); 176839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 176939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_index++; 177039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 177139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 177239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return SUCCESS; 177339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 1774c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1775c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < wait_time; i++) { 1776c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1777e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro int outstanding = atomic_read(&instance->fw_outstanding); 1778e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro 1779e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro if (!outstanding) 1780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 1781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { 1783c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_NOTICE "megasas: [%2d]waiting for %d " 1784e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro "commands to complete\n",i,outstanding); 17857343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang /* 17867343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * Call cmd completion routine. Cmd to be 17877343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * be completed directly without depending on isr. 17887343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang */ 17897343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang megasas_complete_cmd_dpc((unsigned long)instance); 1790c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1791c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1792c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas msleep(1000); 1793c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1794c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1795707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo i = 0; 1796707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo kill_adapter_flag = 0; 1797707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo do { 1798707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo fw_state = instance->instancet->read_fw_status_reg( 1799707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo instance->reg_set) & MFI_STATE_MASK; 1800707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if ((fw_state == MFI_STATE_FAULT) && 1801707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo (instance->disableOnlineCtrlReset == 0)) { 1802707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (i == 3) { 1803707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo kill_adapter_flag = 2; 1804707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo break; 1805707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1806707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo megasas_do_ocr(instance); 1807707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo kill_adapter_flag = 1; 1808707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1809707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo /* wait for 1 secs to let FW finish the pending cmds */ 1810707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo msleep(1000); 1811707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1812707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo i++; 1813707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } while (i <= 3); 1814707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1815707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (atomic_read(&instance->fw_outstanding) && 1816707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo !kill_adapter_flag) { 1817707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (instance->disableOnlineCtrlReset == 0) { 1818707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1819707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo megasas_do_ocr(instance); 1820707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1821707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo /* wait for 5 secs to let FW finish the pending cmds */ 1822707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo for (i = 0; i < wait_time; i++) { 1823707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo int outstanding = 1824707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo atomic_read(&instance->fw_outstanding); 1825707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (!outstanding) 1826707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo return SUCCESS; 1827707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo msleep(1000); 1828707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1829707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1830707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1831707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1832707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (atomic_read(&instance->fw_outstanding) || 1833707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo (kill_adapter_flag == 2)) { 183439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n"); 1835e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro /* 1836e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * Send signal to FW to stop processing any pending cmds. 1837e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * The controller will be taken offline by the OS now. 1838e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro */ 18390c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo if ((instance->pdev->device == 18400c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 18410c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo (instance->pdev->device == 18420c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { 18430c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo writel(MFI_STOP_ADP, 18449c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->reg_set->doorbell); 18450c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } else { 18460c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo writel(MFI_STOP_ADP, 1847e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro &instance->reg_set->inbound_doorbell); 18480c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } 1849658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro megasas_dump_pending_frames(instance); 185039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 185139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR; 185239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 1853c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return FAILED; 1854c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 185639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: no pending cmds after reset\n"); 185739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 1858c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return SUCCESS; 1859c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1860c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1861c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1862c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_generic_reset - Generic reset routine 1863c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scmd: Mid-layer SCSI command 1864c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 1865c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This routine implements a generic reset handler for device, bus and host 1866c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * reset requests. Device, bus and host specific reset handlers can use this 1867c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * function after they do their specific tasks. 1868c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1869c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_generic_reset(struct scsi_cmnd *scmd) 1870c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1871c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int ret_val; 1872c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 1873c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1874c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = (struct megasas_instance *)scmd->device->host->hostdata; 1875c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 18765cd049a59913f359e7d30c11d2dc6187822e77b1Christoph Hellwig scmd_printk(KERN_NOTICE, scmd, "megasas: RESET cmd=%x retries=%x\n", 18775cd049a59913f359e7d30c11d2dc6187822e77b1Christoph Hellwig scmd->cmnd[0], scmd->retries); 1878c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 187939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { 1880c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_ERR "megasas: cannot recover from previous reset " 1881c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "failures\n"); 1882c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return FAILED; 1883c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1884c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1885c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ret_val = megasas_wait_for_outstanding(instance); 1886c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ret_val == SUCCESS) 1887c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_NOTICE "megasas: reset successful \n"); 1888c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else 1889c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_ERR "megasas: failed to do reset\n"); 1890c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1891c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return ret_val; 1892c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1893c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1894c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 189505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * megasas_reset_timer - quiesce the adapter if required 189605e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * @scmd: scsi cmnd 189705e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * 189805e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * Sets the FW busy flag and reduces the host->can_queue if the 189905e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * cmd has not been completed within the timeout period. 190005e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro */ 190105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patrostatic enum 1902242f9dcb8ba6f68fcd217a119a7648a4f69290e9Jens Axboeblk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd) 190305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro{ 190405e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro struct megasas_instance *instance; 190505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro unsigned long flags; 190605e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro 190705e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro if (time_after(jiffies, scmd->jiffies_at_alloc + 190805e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) { 1909242f9dcb8ba6f68fcd217a119a7648a4f69290e9Jens Axboe return BLK_EH_NOT_HANDLED; 191005e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro } 191105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro 1912f575c5d3ebdca3b0482847d8fcba971767754a9eAdam Radford instance = (struct megasas_instance *)scmd->device->host->hostdata; 191305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro if (!(instance->flag & MEGASAS_FW_BUSY)) { 191405e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro /* FW is busy, throttle IO */ 191505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro spin_lock_irqsave(instance->host->host_lock, flags); 191605e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro 191705e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance->host->can_queue = 16; 191805e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance->last_time = jiffies; 191905e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance->flag |= MEGASAS_FW_BUSY; 192005e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro 192105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro spin_unlock_irqrestore(instance->host->host_lock, flags); 192205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro } 1923242f9dcb8ba6f68fcd217a119a7648a4f69290e9Jens Axboe return BLK_EH_RESET_TIMER; 192405e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro} 192505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro 192605e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro/** 1927c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_reset_device - Device reset handler entry point 1928c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1929c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_reset_device(struct scsi_cmnd *scmd) 1930c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1931c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int ret; 1932c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1933c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * First wait for all commands to complete 1935c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1936c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ret = megasas_generic_reset(scmd); 1937c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1938c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return ret; 1939c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1940c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1941c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1942c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_reset_bus_host - Bus & host reset handler entry point 1943c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1944c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_reset_bus_host(struct scsi_cmnd *scmd) 1945c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1946c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int ret; 19479c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford struct megasas_instance *instance; 19489c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance = (struct megasas_instance *)scmd->device->host->hostdata; 1949c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1950c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 195180682fa9f70932950c913fd10411c004c4c2e8b0Uwe Zeisberger * First wait for all commands to complete 1952c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 195336807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || 195436807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) 19559c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford ret = megasas_reset_fusion(scmd->device->host); 19569c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford else 19579c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford ret = megasas_generic_reset(scmd); 1958c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1959c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return ret; 1960c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1961c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1962c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1963cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * megasas_bios_param - Returns disk geometry for a disk 1964cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @sdev: device handle 1965cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @bdev: block device 1966cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @capacity: drive capacity 1967cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @geom: geometry parameters 1968cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro */ 1969cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patrostatic int 1970cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patromegasas_bios_param(struct scsi_device *sdev, struct block_device *bdev, 1971cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sector_t capacity, int geom[]) 1972cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro{ 1973cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro int heads; 1974cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro int sectors; 1975cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sector_t cylinders; 1976cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro unsigned long tmp; 1977cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro /* Default heads (64) & sectors (32) */ 1978cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro heads = 64; 1979cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sectors = 32; 1980cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 1981cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro tmp = heads * sectors; 1982cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro cylinders = capacity; 1983cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 1984cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sector_div(cylinders, tmp); 1985cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 1986cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro /* 1987cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * Handle extended translation size for logical drives > 1Gb 1988cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro */ 1989cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 1990cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro if (capacity >= 0x200000) { 1991cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro heads = 255; 1992cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sectors = 63; 1993cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro tmp = heads*sectors; 1994cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro cylinders = capacity; 1995cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sector_div(cylinders, tmp); 1996cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro } 1997cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 1998cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro geom[0] = heads; 1999cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro geom[1] = sectors; 2000cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro geom[2] = cylinders; 2001cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 2002cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro return 0; 2003cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro} 2004cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 20057e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bostatic void megasas_aen_polling(struct work_struct *work); 20067e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 2007cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro/** 2008c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_service_aen - Processes an event notification 2009c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2010c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: AEN command completed by the ISR 2011c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2012c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * For AEN, driver sends a command down to FW that is held by the FW till an 2013c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * event occurs. When an event of interest occurs, FW completes the command 2014c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * that it was previously holding. 2015c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2016c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This routines sends SIGIO signal to processes that have registered with the 2017c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * driver for AEN. 2018c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2019c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void 2020c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) 2021c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2022c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo unsigned long flags; 2023c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2024c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Don't signal app if it is just an aborted previously registered aen 2025c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2026c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo if ((!cmd->abort_aen) && (instance->unload == 0)) { 2027c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_lock_irqsave(&poll_aen_lock, flags); 2028c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo megasas_poll_wait_aen = 1; 2029c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_unlock_irqrestore(&poll_aen_lock, flags); 2030c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo wake_up(&megasas_poll_wait); 2031c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kill_fasync(&megasas_async_queue, SIGIO, POLL_IN); 2032c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo } 2033c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else 2034c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->abort_aen = 0; 2035c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2036c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->aen_cmd = NULL; 2037c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 20387e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 203939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((instance->unload == 0) && 204039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ((instance->issuepend_done == 1))) { 20417e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct megasas_aen_event *ev; 20427e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo ev = kzalloc(sizeof(*ev), GFP_ATOMIC); 20437e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (!ev) { 20447e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo printk(KERN_ERR "megasas_service_aen: out of memory\n"); 20457e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } else { 20467e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo ev->instance = instance; 20477e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo instance->ev = ev; 20487e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo INIT_WORK(&ev->hotplug_work, megasas_aen_polling); 20497e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo schedule_delayed_work( 20507e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo (struct delayed_work *)&ev->hotplug_work, 0); 20517e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 20527e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 2053c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2054c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 20554bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radfordstatic int megasas_change_queue_depth(struct scsi_device *sdev, 20564bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford int queue_depth, int reason) 20574bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford{ 20584bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford if (reason != SCSI_QDEPTH_DEFAULT) 20594bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford return -EOPNOTSUPP; 20604bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford 20614bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford if (queue_depth > sdev->host->can_queue) 20624bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford queue_depth = sdev->host->can_queue; 20634bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), 20644bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford queue_depth); 20654bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford 20664bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford return queue_depth; 20674bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford} 20684bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford 2069c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/* 2070c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Scsi host template for megaraid_sas driver 2071c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2072c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct scsi_host_template megasas_template = { 2073c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2074c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .module = THIS_MODULE, 2075f28cd7cf8f696eafe42d1632b5a306fbf784d3cdbo yang .name = "LSI SAS based MegaRAID driver", 2076c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .proc_name = "megaraid_sas", 2077147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig .slave_configure = megasas_slave_configure, 2078044833b572b96afe91506a0edec42efd84ba4939Yang, Bo .slave_alloc = megasas_slave_alloc, 2079c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .queuecommand = megasas_queue_command, 2080c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .eh_device_reset_handler = megasas_reset_device, 2081c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .eh_bus_reset_handler = megasas_reset_bus_host, 2082c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .eh_host_reset_handler = megasas_reset_bus_host, 208305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro .eh_timed_out = megasas_reset_timer, 2084cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro .bios_param = megasas_bios_param, 2085c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .use_clustering = ENABLE_CLUSTERING, 20864bcde509a8fe664f2e688647d8427b6aedaa89b7Adam Radford .change_queue_depth = megasas_change_queue_depth, 2087c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}; 2088c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2089c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2090c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_complete_int_cmd - Completes an internal command 2091c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2092c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Command to be completed 2093c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2094c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * The megasas_issue_blocked_cmd() function waits for a command to complete 2095c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * after it issues a command. This function wakes up that waiting routine by 2096c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * calling wake_up() on the wait queue. 2097c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2098c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void 2099c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_complete_int_cmd(struct megasas_instance *instance, 2100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd) 2101c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2102c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->cmd_status = cmd->frame->io.cmd_status; 2103c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2104c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->cmd_status == ENODATA) { 2105c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->cmd_status = 0; 2106c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2107c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas wake_up(&instance->int_cmd_wait_q); 2108c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2109c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2110c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2111c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_complete_abort - Completes aborting a command 2112c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2113c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Cmd that was issued to abort another cmd 2114c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 21150d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q 21160d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * after it issues an abort on a previously issued command. This function 2117c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * wakes up all functions waiting on the same wait queue. 2118c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2119c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void 2120c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_complete_abort(struct megasas_instance *instance, 2121c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd) 2122c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2123c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->sync_cmd) { 2124c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sync_cmd = 0; 2125c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->cmd_status = 0; 2126c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas wake_up(&instance->abort_cmd_wait_q); 2127c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2128c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2129c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 2130c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2131c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2132c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2133c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_complete_cmd - Completes a command 2134c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2135c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Command to be completed 21360d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * @alt_status: If non-zero, use this value as status to 2137c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * SCSI mid-layer instead of the value returned 2138c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * by the FW. This should be used if caller wants 2139c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * an alternate status (as in the case of aborted 2140c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * commands) 2141c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 21429c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid 2143c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, 2144c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u8 alt_status) 2145c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2146c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int exception = 0; 2147c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_header *hdr = &cmd->frame->hdr; 2148c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo unsigned long flags; 21499c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford struct fusion_context *fusion = instance->ctrl_context; 2150c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 215139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang /* flag for the retry reset */ 215239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->retry_for_fw_reset = 0; 215339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 215405e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro if (cmd->scmd) 215505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro cmd->scmd->SCp.ptr = NULL; 2156c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2157c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas switch (hdr->cmd) { 2158e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford case MFI_CMD_INVALID: 2159e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford /* Some older 1068 controller FW may keep a pended 2160e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford MR_DCMD_CTRL_EVENT_GET_INFO left over from the main kernel 2161e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford when booting the kdump kernel. Ignore this command to 2162e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford prevent a kernel panic on shutdown of the kdump kernel. */ 2163e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford printk(KERN_WARNING "megaraid_sas: MFI_CMD_INVALID command " 2164e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford "completed.\n"); 2165e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford printk(KERN_WARNING "megaraid_sas: If you have a controller " 2166e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford "other than PERC5, please upgrade your firmware.\n"); 2167e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford break; 2168c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_PD_SCSI_IO: 2169c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_LD_SCSI_IO: 2170c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2171c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2172c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been 2173c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * issued either through an IO path or an IOCTL path. If it 2174c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * was via IOCTL, we will send it to internal completion. 2175c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2176c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->sync_cmd) { 2177c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sync_cmd = 0; 2178c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_complete_int_cmd(instance, cmd); 2179c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2180c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2181c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2182c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_LD_READ: 2183c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_LD_WRITE: 2184c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2185c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (alt_status) { 2186c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = alt_status << 16; 2187c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas exception = 1; 2188c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2189c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (exception) { 2191c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2192e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro atomic_dec(&instance->fw_outstanding); 2193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2194155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori scsi_dma_unmap(cmd->scmd); 2195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->scsi_done(cmd->scmd); 2196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 2197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2199c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2201c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas switch (hdr->cmd_status) { 2202c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_OK: 2204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = DID_OK << 16; 2205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2206c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2207c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_SCSI_IO_FAILED: 2208c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_LD_INIT_IN_PROGRESS: 2209c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = 2210c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas (DID_ERROR << 16) | hdr->scsi_status; 2211c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2212c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2213c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_SCSI_DONE_WITH_ERROR: 2214c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status; 2216c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2217c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) { 2218c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(cmd->scmd->sense_buffer, 0, 2219c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas SCSI_SENSE_BUFFERSIZE); 2220c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memcpy(cmd->scmd->sense_buffer, cmd->sense, 2221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas hdr->sense_len); 2222c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2223c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result |= DRIVER_SENSE << 24; 2224c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2225c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2226c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_LD_OFFLINE: 2229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_DEVICE_NOT_FOUND: 2230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = DID_BAD_TARGET << 16; 2231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas default: 2234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: MFI FW status %#x\n", 2235c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas hdr->cmd_status); 2236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = DID_ERROR << 16; 2237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2239c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2240e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro atomic_dec(&instance->fw_outstanding); 2241c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2242155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori scsi_dma_unmap(cmd->scmd); 2243c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->scsi_done(cmd->scmd); 2244c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 2245c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2246c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2247c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2248c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_SMP: 2249c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_STP: 2250c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_DCMD: 22519c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford /* Check for LD map update */ 22529c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if ((cmd->frame->dcmd.opcode == MR_DCMD_LD_MAP_GET_INFO) && 22539c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (cmd->frame->dcmd.mbox.b[1] == 1)) { 22549c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_lock_irqsave(instance->host->host_lock, flags); 22559c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (cmd->frame->hdr.cmd_status != 0) { 22569c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (cmd->frame->hdr.cmd_status != 22579c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford MFI_STAT_NOT_FOUND) 22589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford printk(KERN_WARNING "megasas: map sync" 22599c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford "failed, status = 0x%x.\n", 22609c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford cmd->frame->hdr.cmd_status); 22619c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford else { 22629c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_return_cmd(instance, cmd); 22639c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_unlock_irqrestore( 22649c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->host->host_lock, 22659c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford flags); 22669c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 22679c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 22689c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } else 22699c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->map_id++; 22709c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_return_cmd(instance, cmd); 22719c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (MR_ValidateMapInfo( 22729c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->ld_map[(instance->map_id & 1)], 22739c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->load_balance_info)) 22749c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->fast_path_io = 1; 22759c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford else 22769c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->fast_path_io = 0; 22779c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_sync_map_info(instance); 22789c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_unlock_irqrestore(instance->host->host_lock, 22799c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford flags); 22809c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 22819c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 2282c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO || 2283c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) { 2284c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_lock_irqsave(&poll_aen_lock, flags); 2285c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo megasas_poll_wait_aen = 0; 2286c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_unlock_irqrestore(&poll_aen_lock, flags); 2287c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo } 2288c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2289c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2290c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * See if got an event notification 2291c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2292c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_WAIT) 2293c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_service_aen(instance, cmd); 2294c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else 2295c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_complete_int_cmd(instance, cmd); 2296c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2297c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2298c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2299c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_ABORT: 2300c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2301c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Cmd issued to abort another cmd returned 2302c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2303c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_complete_abort(instance, cmd); 2304c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2305c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2306c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas default: 2307c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk("megasas: Unknown command completed! [0x%X]\n", 2308c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas hdr->cmd); 2309c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2310c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2311c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2312c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2313c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 231439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_issue_pending_cmds_again - issue all pending cmds 231539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * in FW again because of the fw reset 231639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @instance: Adapter soft state 231739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 231839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic inline void 231939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_issue_pending_cmds_again(struct megasas_instance *instance) 232039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 232139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_cmd *cmd; 232239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct list_head clist_local; 232339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang union megasas_evt_class_locale class_locale; 232439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 232539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 seq_num; 232639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 232739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang INIT_LIST_HEAD(&clist_local); 232839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 232939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_splice_init(&instance->internal_reset_pending_q, &clist_local); 233039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 233139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 233239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang while (!list_empty(&clist_local)) { 233339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd = list_entry((&clist_local)->next, 233439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_cmd, list); 233539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_del_init(&cmd->list); 233639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 233739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (cmd->sync_cmd || cmd->scmd) { 233839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: command %p, %p:%d" 233939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "detected to be pending while HBA reset.\n", 234039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd, cmd->scmd, cmd->sync_cmd); 234139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 234239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->retry_for_fw_reset++; 234339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 234439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (cmd->retry_for_fw_reset == 3) { 234539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: cmd %p, %p:%d" 234639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "was tried multiple times during reset." 234739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "Shutting down the HBA\n", 234839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd, cmd->scmd, cmd->sync_cmd); 234939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megaraid_sas_kill_hba(instance); 235039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 235139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = 235239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang MEGASAS_HW_CRITICAL_ERROR; 235339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return; 235439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 235539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 235639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 235739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (cmd->sync_cmd == 1) { 235839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (cmd->scmd) { 235939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: unexpected" 236039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "cmd attached to internal command!\n"); 236139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 236239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: %p synchronous cmd" 236339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "on the internal reset queue," 236439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "issue it again.\n", cmd); 236539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->cmd_status = ENODATA; 236639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->fire_cmd(instance, 236739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->frame_phys_addr , 236839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 0, instance->reg_set); 236939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else if (cmd->scmd) { 23705cd049a59913f359e7d30c11d2dc6187822e77b1Christoph Hellwig printk(KERN_NOTICE "megasas: %p scsi cmd [%02x]" 237139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "detected on the internal queue, issue again.\n", 23725cd049a59913f359e7d30c11d2dc6187822e77b1Christoph Hellwig cmd, cmd->scmd->cmnd[0]); 237339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 237439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_inc(&instance->fw_outstanding); 237539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->fire_cmd(instance, 237639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->frame_phys_addr, 237739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->frame_count-1, instance->reg_set); 237839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else { 237939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: %p unexpected cmd on the" 238039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "internal reset defer list while re-issue!!\n", 238139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd); 238239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 238339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 238439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 238539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->aen_cmd) { 238639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: aen_cmd in def process\n"); 238739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_return_cmd(instance, instance->aen_cmd); 238839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 238939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->aen_cmd = NULL; 239039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 239139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 239239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang /* 239339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * Initiate AEN (Asynchronous Event Notification) 239439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 239539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang seq_num = instance->last_seq_num; 239639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang class_locale.members.reserved = 0; 239739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang class_locale.members.locale = MR_EVT_LOCALE_ALL; 239839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang class_locale.members.class = MR_EVT_CLASS_DEBUG; 239939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 240039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_register_aen(instance, seq_num, class_locale.word); 240139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 240239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 240339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 240439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * Move the internal reset pending commands to a deferred queue. 240539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * 240639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * We move the commands pending at internal reset time to a 240739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * pending queue. This queue would be flushed after successful 240839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * completion of the internal reset sequence. if the internal reset 240939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * did not complete in time, the kernel reset handler would flush 241039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * these commands. 241139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang **/ 241239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic void 241339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_internal_reset_defer_cmds(struct megasas_instance *instance) 241439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 241539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_cmd *cmd; 241639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang int i; 241739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 max_cmd = instance->max_fw_cmds; 241839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 defer_index; 241939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 242039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 242139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang defer_index = 0; 242239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->cmd_pool_lock, flags); 242339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < max_cmd; i++) { 242439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd = instance->cmd_list[i]; 242539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (cmd->sync_cmd == 1 || cmd->scmd) { 242639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: moving cmd[%d]:%p:%d:%p" 242739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "on the defer queue as internal\n", 242839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang defer_index, cmd, cmd->sync_cmd, cmd->scmd); 242939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 243039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (!list_empty(&cmd->list)) { 243139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: ERROR while" 243239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang " moving this cmd:%p, %d %p, it was" 243339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "discovered on some list?\n", 243439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd, cmd->sync_cmd, cmd->scmd); 243539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 243639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_del_init(&cmd->list); 243739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 243839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang defer_index++; 243939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_add_tail(&cmd->list, 244039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang &instance->internal_reset_pending_q); 244139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 244239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 244339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->cmd_pool_lock, flags); 244439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 244539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 244639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 244739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic void 244839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangprocess_fw_state_change_wq(struct work_struct *work) 244939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 245039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_instance *instance = 245139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang container_of(work, struct megasas_instance, work_init); 245239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 wait; 245339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 245439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 245539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery != MEGASAS_ADPRESET_SM_INFAULT) { 245639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: error, recovery st %x \n", 245739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery); 245839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return ; 245939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 246039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 246139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) { 246239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault" 246339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "state, restarting it...\n"); 246439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 246539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->disable_intr(instance->reg_set); 246639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_set(&instance->fw_outstanding, 0); 246739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 246839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_set(&instance->fw_reset_no_pci_access, 1); 246939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->adp_reset(instance, instance->reg_set); 247039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_set(&instance->fw_reset_no_pci_access, 0 ); 247139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 247239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: FW restarted successfully," 247339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "initiating next stage...\n"); 247439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 247539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: HBA recovery state machine," 247639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "state 2 starting...\n"); 247739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 247839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang /*waitting for about 20 second before start the second init*/ 247939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (wait = 0; wait < 30; wait++) { 248039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 248139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 248239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 2483058a8facfe1ee091b7188661937240fd0d950cf4Adam Radford if (megasas_transition_to_ready(instance, 1)) { 248439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas:adapter not ready\n"); 248539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 248639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megaraid_sas_kill_hba(instance); 248739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR; 248839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return ; 248939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 249039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 249139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) || 249239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) || 249339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR) 249439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ) { 249539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang *instance->consumer = *instance->producer; 249639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else { 249739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang *instance->consumer = 0; 249839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang *instance->producer = 0; 249939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 250039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 250139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_issue_init_mfi(instance); 250239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 250339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 250439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_HBA_OPERATIONAL; 250539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 250639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->enable_intr(instance->reg_set); 250739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 250839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_issue_pending_cmds_again(instance); 250939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->issuepend_done = 1; 251039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 251139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return ; 251239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 251339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 251439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 2515c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_deplete_reply_queue - Processes all completed commands 2516c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2517c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @alt_status: Alternate status to be returned to 2518c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * SCSI mid-layer instead of the status 2519c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * returned by the FW 252039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * Note: this must be called with hba lock held 2521c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2522858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int 252339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_deplete_reply_queue(struct megasas_instance *instance, 252439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u8 alt_status) 2525c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 252639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 mfiStatus; 252739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 fw_state; 252839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 252939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((mfiStatus = instance->instancet->check_reset(instance, 253039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->reg_set)) == 1) { 253139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return IRQ_HANDLED; 253239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 253339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 253439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((mfiStatus = instance->instancet->clear_intr( 253539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->reg_set) 253639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ) == 0) { 2537e1419191d8d38098fb6ef29e94aadd15dabff3daAdam Radford /* Hardware may not set outbound_intr_status in MSI-X mode */ 2538c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (!instance->msix_vectors) 2539e1419191d8d38098fb6ef29e94aadd15dabff3daAdam Radford return IRQ_NONE; 254039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 254139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 254239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->mfiStatus = mfiStatus; 254339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 254439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) { 254539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang fw_state = instance->instancet->read_fw_status_reg( 254639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->reg_set) & MFI_STATE_MASK; 254739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 254839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (fw_state != MFI_STATE_FAULT) { 254939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: fw state:%x\n", 255039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang fw_state); 255139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 255239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 255339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((fw_state == MFI_STATE_FAULT) && 255439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->disableOnlineCtrlReset == 0)) { 255539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: wait adp restart\n"); 255639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 255739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((instance->pdev->device == 255839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang PCI_DEVICE_ID_LSI_SAS1064R) || 255939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->pdev->device == 256039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang PCI_DEVICE_ID_DELL_PERC5) || 256139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->pdev->device == 256239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang PCI_DEVICE_ID_LSI_VERDE_ZCR)) { 256339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 256439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang *instance->consumer = 256539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang MEGASAS_ADPRESET_INPROG_SIGN; 256639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 256739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 256839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 256939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->disable_intr(instance->reg_set); 257039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; 257139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->issuepend_done = 0; 257239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 257339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_set(&instance->fw_outstanding, 0); 257439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_internal_reset_defer_cmds(instance); 257539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 257639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: fwState=%x, stage:%d\n", 257739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang fw_state, instance->adprecovery); 257839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 257939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang schedule_work(&instance->work_init); 258039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return IRQ_HANDLED; 258139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 258239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else { 258339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: fwstate:%x, dis_OCR=%x\n", 258439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang fw_state, instance->disableOnlineCtrlReset); 258539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 258639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 2587c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 25885d018ad057347995e5c4564b3e43339e6497f839Sumant Patro tasklet_schedule(&instance->isr_tasklet); 2589c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return IRQ_HANDLED; 2590c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2591c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2592c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_isr - isr entry point 2593c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 25947d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t megasas_isr(int irq, void *devp) 2595c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2596c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford struct megasas_irq_context *irq_context = devp; 2597c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford struct megasas_instance *instance = irq_context->instance; 259839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 259939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang irqreturn_t rc; 260039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 2601c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (atomic_read(&instance->fw_reset_no_pci_access)) 260239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return IRQ_HANDLED; 260339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 260439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 260539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang rc = megasas_deplete_reply_queue(instance, DID_OK); 260639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 260739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 260839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return rc; 2609c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2610c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2611c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2612c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_transition_to_ready - Move the FW to READY state 26131341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @instance: Adapter soft state 2614c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2615c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * During the initialization, FW passes can potentially be in any one of 2616c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * several possible states. If the FW in operational, waiting-for-handshake 2617c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * states, driver must take steps to bring it to ready state. Otherwise, it 2618c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * has to wait for the ready state. 2619c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 26209c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint 2621058a8facfe1ee091b7188661937240fd0d950cf4Adam Radfordmegasas_transition_to_ready(struct megasas_instance *instance, int ocr) 2622c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2623c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 2624c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u8 max_wait; 2625c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 fw_state; 2626c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 cur_state; 26277218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo u32 abs_state, curr_abs_state; 2628c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 26291341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK; 2630c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2631e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro if (fw_state != MFI_STATE_READY) 26320d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford printk(KERN_INFO "megasas: Waiting for FW to come to ready" 26330d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford " state\n"); 2634e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro 2635c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas while (fw_state != MFI_STATE_READY) { 2636c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 26377218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo abs_state = 26387218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo instance->instancet->read_fw_status_reg(instance->reg_set); 26397218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo 2640c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas switch (fw_state) { 2641c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2642c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_FAULT: 2643c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: FW in FAULT state!!\n"); 2644058a8facfe1ee091b7188661937240fd0d950cf4Adam Radford if (ocr) { 2645058a8facfe1ee091b7188661937240fd0d950cf4Adam Radford max_wait = MEGASAS_RESET_WAIT_TIME; 2646058a8facfe1ee091b7188661937240fd0d950cf4Adam Radford cur_state = MFI_STATE_FAULT; 2647058a8facfe1ee091b7188661937240fd0d950cf4Adam Radford break; 2648058a8facfe1ee091b7188661937240fd0d950cf4Adam Radford } else 2649058a8facfe1ee091b7188661937240fd0d950cf4Adam Radford return -ENODEV; 2650c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2651c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_WAIT_HANDSHAKE: 2652c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2653c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Set the CLR bit in inbound doorbell 2654c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 26550c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo if ((instance->pdev->device == 2656879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 2657879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo (instance->pdev->device == 26589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 26599c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == 266036807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford PCI_DEVICE_ID_LSI_FUSION) || 266136807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford (instance->pdev->device == 266236807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford PCI_DEVICE_ID_LSI_INVADER)) { 2663879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel( 2664879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, 26659c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->reg_set->doorbell); 2666879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo } else { 2667879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel( 2668879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, 2669879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo &instance->reg_set->inbound_doorbell); 2670879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo } 2671c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 26727218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2673c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_WAIT_HANDSHAKE; 2674c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2675c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2676e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro case MFI_STATE_BOOT_MESSAGE_PENDING: 2677879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo if ((instance->pdev->device == 26789c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 26799c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == 26809c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 26819c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == 268236807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford PCI_DEVICE_ID_LSI_FUSION) || 268336807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford (instance->pdev->device == 268436807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford PCI_DEVICE_ID_LSI_INVADER)) { 2685879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(MFI_INIT_HOTPLUG, 26869c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->reg_set->doorbell); 2687879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo } else 2688879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(MFI_INIT_HOTPLUG, 2689879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo &instance->reg_set->inbound_doorbell); 2690e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro 26917218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2692e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro cur_state = MFI_STATE_BOOT_MESSAGE_PENDING; 2693e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro break; 2694e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro 2695c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_OPERATIONAL: 2696c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2697e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * Bring it to READY state; assuming max wait 10 secs 2698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2699b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro instance->instancet->disable_intr(instance->reg_set); 2700879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo if ((instance->pdev->device == 2701879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 2702879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo (instance->pdev->device == 27039c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 27049c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device 270536807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford == PCI_DEVICE_ID_LSI_FUSION) || 270636807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford (instance->pdev->device 270736807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford == PCI_DEVICE_ID_LSI_INVADER)) { 2708879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(MFI_RESET_FLAGS, 27099c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->reg_set->doorbell); 271036807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford if ((instance->pdev->device == 271136807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford PCI_DEVICE_ID_LSI_FUSION) || 271236807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford (instance->pdev->device == 271336807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford PCI_DEVICE_ID_LSI_INVADER)) { 27149c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford for (i = 0; i < (10 * 1000); i += 20) { 27159c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (readl( 27169c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance-> 27179c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford reg_set-> 27189c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford doorbell) & 1) 27199c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford msleep(20); 27209c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford else 27219c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 27229c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 27239c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 2724879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo } else 2725879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(MFI_RESET_FLAGS, 2726879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo &instance->reg_set->inbound_doorbell); 2727c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 27287218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2729c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_OPERATIONAL; 2730c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2731c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2732c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_UNDEFINED: 2733c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2734c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This state should not last for more than 2 seconds 2735c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 27367218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2737c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_UNDEFINED; 2738c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2739c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2740c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_BB_INIT: 27417218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2742c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_BB_INIT; 2743c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2744c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2745c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_FW_INIT: 27467218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2747c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_FW_INIT; 2748c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2749c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2750c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_FW_INIT_2: 27517218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2752c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_FW_INIT_2; 2753c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2754c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2755c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_DEVICE_SCAN: 27567218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2757c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_DEVICE_SCAN; 2758c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2759c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2760c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_FLUSH_CACHE: 27617218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2762c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_FLUSH_CACHE; 2763c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2764c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2765c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas default: 2766c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Unknown state 0x%x\n", 2767c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fw_state); 2768c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENODEV; 2769c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2770c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2771c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2772c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * The cur_state should not last for more than max_wait secs 2773c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2774c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < (max_wait * 1000); i++) { 27750d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & 27761341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro MFI_STATE_MASK ; 27777218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo curr_abs_state = 27787218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo instance->instancet->read_fw_status_reg(instance->reg_set); 2779c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 27807218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo if (abs_state == curr_abs_state) { 2781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas msleep(1); 2782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else 2783c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2784c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2785c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2786c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2787c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Return error if fw_state hasn't changed after max_wait 2788c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 27897218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo if (curr_abs_state == abs_state) { 2790c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "FW state [%d] hasn't changed " 2791c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "in %d secs\n", fw_state, max_wait); 2792c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENODEV; 2793c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 279439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 27950d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford printk(KERN_INFO "megasas: FW now in Ready state\n"); 2796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2797c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 2798c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2799c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2800c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2801c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_teardown_frame_pool - Destroy the cmd frame DMA pool 2802c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2803c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2804c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_teardown_frame_pool(struct megasas_instance *instance) 2805c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2806c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 28079c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford u32 max_cmd = instance->max_mfi_cmds; 2808c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 2809c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2810c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->frame_dma_pool) 2811c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 2812c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2813c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2814c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Return all frames to pool 2815c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2816c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < max_cmd; i++) { 2817c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2818c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = instance->cmd_list[i]; 2819c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2820c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->frame) 2821c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_pool_free(instance->frame_dma_pool, cmd->frame, 2822c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->frame_phys_addr); 2823c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2824c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->sense) 2825e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro pci_pool_free(instance->sense_dma_pool, cmd->sense, 2826c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sense_phys_addr); 2827c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2828c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2829c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2830c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Now destroy the pool itself 2831c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2832c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_pool_destroy(instance->frame_dma_pool); 2833c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_pool_destroy(instance->sense_dma_pool); 2834c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2835c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->frame_dma_pool = NULL; 2836c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->sense_dma_pool = NULL; 2837c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2838c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2839c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2840c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_create_frame_pool - Creates DMA pool for cmd frames 2841c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2842c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2843c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Each command packet has an embedded DMA memory buffer that is used for 2844c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * filling MFI frame and the SG list that immediately follows the frame. This 2845c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * function creates those DMA memory buffers for each command packet by using 2846c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI pool facility. 2847c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2848c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_create_frame_pool(struct megasas_instance *instance) 2849c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2850c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 2851c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 max_cmd; 2852c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 sge_sz; 2853c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 sgl_sz; 2854c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 total_sz; 2855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 frame_count; 2856c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 2857c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 28589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford max_cmd = instance->max_mfi_cmds; 2859c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2860c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2861c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Size of our frame is 64 bytes for MFI frame, followed by max SG 2862c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer 2863c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2864c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : 2865c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sizeof(struct megasas_sge32); 2866c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2867f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee) { 2868f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo sge_sz = sizeof(struct megasas_sge_skinny); 2869f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 2870f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 2871c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2872c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Calculated the number of 64byte frames required for SGL 2873c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2874c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sgl_sz = sge_sz * instance->max_num_sge; 2875c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas frame_count = (sgl_sz + MEGAMFI_FRAME_SIZE - 1) / MEGAMFI_FRAME_SIZE; 287639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang frame_count = 15; 2877c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2878c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2879c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * We need one extra frame for the MFI command 2880c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2881c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas frame_count++; 2882c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2883c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas total_sz = MEGAMFI_FRAME_SIZE * frame_count; 2884c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2885c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Use DMA pool facility provided by PCI layer 2886c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2887c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->frame_dma_pool = pci_pool_create("megasas frame pool", 2888c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->pdev, total_sz, 64, 2889c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 0); 2890c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2891c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->frame_dma_pool) { 2892c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: failed to setup frame pool\n"); 2893c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 2894c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2895c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2896c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->sense_dma_pool = pci_pool_create("megasas sense pool", 2897c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->pdev, 128, 4, 0); 2898c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2899c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->sense_dma_pool) { 2900c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: failed to setup sense pool\n"); 2901c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2902c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_pool_destroy(instance->frame_dma_pool); 2903c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->frame_dma_pool = NULL; 2904c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2905c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 2906c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2907c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2908c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2909c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Allocate and attach a frame to each of the commands in cmd_list. 2910c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * By making cmd->index as the context instead of the &cmd, we can 2911c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * always use 32bit context regardless of the architecture 2912c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2913c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < max_cmd; i++) { 2914c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2915c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = instance->cmd_list[i]; 2916c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2917c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->frame = pci_pool_alloc(instance->frame_dma_pool, 2918c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas GFP_KERNEL, &cmd->frame_phys_addr); 2919c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2920c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sense = pci_pool_alloc(instance->sense_dma_pool, 2921c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas GFP_KERNEL, &cmd->sense_phys_addr); 2922c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2923c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2924c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_teardown_frame_pool() takes care of freeing 2925c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * whatever has been allocated 2926c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2927c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd->frame || !cmd->sense) { 2928c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: pci_pool_alloc failed \n"); 2929c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_teardown_frame_pool(instance); 2930c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 2931c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2932c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2933707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo memset(cmd->frame, 0, total_sz); 2934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->frame->io.context = cmd->index; 29357e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo cmd->frame->io.pad_0 = 0; 2936e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) && 2937e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) && 2938e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford (reset_devices)) 2939e5f93a36f72c9817b989f573f7140e3dfbce0f49Adam Radford cmd->frame->hdr.cmd = MFI_CMD_INVALID; 2940c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2941c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2942c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 2943c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2944c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2945c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2946c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_free_cmds - Free all the cmds in the free cmd pool 2947c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2948c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 29499c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid megasas_free_cmds(struct megasas_instance *instance) 2950c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2951c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 2952c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* First free the MFI frame pool */ 2953c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_teardown_frame_pool(instance); 2954c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2955c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* Free all the commands in the cmd_list */ 29569c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford for (i = 0; i < instance->max_mfi_cmds; i++) 29579c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 2958c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(instance->cmd_list[i]); 2959c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2960c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* Free the cmd_list buffer itself */ 2961c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(instance->cmd_list); 2962c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->cmd_list = NULL; 2963c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2964c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas INIT_LIST_HEAD(&instance->cmd_pool); 2965c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2966c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2967c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2968c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_alloc_cmds - Allocates the command packets 2969c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2970c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2971c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Each command that is issued to the FW, whether IO commands from the OS or 2972c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * internal commands like IOCTLs, are wrapped in local data structure called 2973c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to 2974c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the FW. 2975c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2976c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Each frame has a 32-bit field called context (tag). This context is used 2977c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to get back the megasas_cmd from the frame when a frame gets completed in 2978c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the ISR. Typically the address of the megasas_cmd itself would be used as 2979c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the context. But we wanted to keep the differences between 32 and 64 bit 2980c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * systems to the mininum. We always use 32 bit integers for the context. In 2981c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * this driver, the 32 bit values are the indices into an array cmd_list. 2982c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This array is used only to look up the megasas_cmd given the context. The 2983c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * free commands themselves are maintained in a linked list called cmd_pool. 2984c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 29859c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint megasas_alloc_cmds(struct megasas_instance *instance) 2986c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2987c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 2988c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int j; 2989c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 max_cmd; 2990c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 2991c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 29929c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford max_cmd = instance->max_mfi_cmds; 2993c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2994c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2995c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * instance->cmd_list is an array of struct megasas_cmd pointers. 2996c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Allocate the dynamic array first and then allocate individual 2997c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * commands. 2998c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2999dd00cc486ab1c17049a535413d1751ef3482141cYoann Padioleau instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL); 3000c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3001c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->cmd_list) { 3002c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: out of memory\n"); 3003c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3004c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3005c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 30069c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) *max_cmd); 3007c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3008c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < max_cmd; i++) { 3009c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd), 3010c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas GFP_KERNEL); 3011c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3012c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->cmd_list[i]) { 3013c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3014c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (j = 0; j < i; j++) 3015c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(instance->cmd_list[j]); 3016c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3017c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(instance->cmd_list); 3018c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->cmd_list = NULL; 3019c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3020c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3021c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3022c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3023c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3024c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3025c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Add all the commands to command pool (instance->cmd_pool) 3026c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3027c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < max_cmd; i++) { 3028c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = instance->cmd_list[i]; 3029c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(cmd, 0, sizeof(struct megasas_cmd)); 3030c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->index = i; 303139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->scmd = NULL; 3032c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->instance = instance; 3033c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3034c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas list_add_tail(&cmd->list, &instance->cmd_pool); 3035c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3036c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3037c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3038c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Create a frame pool and assign one frame to each cmd 3039c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3040c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_create_frame_pool(instance)) { 3041c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n"); 3042c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_free_cmds(instance); 3043c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3044c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3045c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3046c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3047c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 304881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo/* 304981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * megasas_get_pd_list_info - Returns FW's pd_list structure 305081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * @instance: Adapter soft state 305181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * @pd_list: pd_list structure 305281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * 305381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * Issues an internal command (DCMD) to get the FW's controller PD 305481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * list structure. This information is mainly used to find out SYSTEM 305581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * supported by the FW. 305681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo */ 305781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bostatic int 305881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bomegasas_get_pd_list(struct megasas_instance *instance) 305981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo{ 306081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo int ret = 0, pd_index = 0; 306181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo struct megasas_cmd *cmd; 306281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo struct megasas_dcmd_frame *dcmd; 306381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo struct MR_PD_LIST *ci; 306481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo struct MR_PD_ADDRESS *pd_addr; 306581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dma_addr_t ci_h = 0; 306681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 306781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo cmd = megasas_get_cmd(instance); 306881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 306981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo if (!cmd) { 307081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n"); 307181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo return -ENOMEM; 307281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } 307381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 307481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd = &cmd->frame->dcmd; 307581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 307681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo ci = pci_alloc_consistent(instance->pdev, 307781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h); 307881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 307981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo if (!ci) { 308081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo printk(KERN_DEBUG "Failed to alloc mem for pd_list\n"); 308181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo megasas_return_cmd(instance, cmd); 308281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo return -ENOMEM; 308381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } 308481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 308581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo memset(ci, 0, sizeof(*ci)); 308681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 308781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 308881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST; 308981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->mbox.b[1] = 0; 309081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->cmd = MFI_CMD_DCMD; 309181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->cmd_status = 0xFF; 309281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->sge_count = 1; 309381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->flags = MFI_FRAME_DIR_READ; 309481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->timeout = 0; 3095780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 309681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST); 309781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->opcode = MR_DCMD_PD_LIST_QUERY; 309881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->sgl.sge32[0].phys_addr = ci_h; 309981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST); 310081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 310181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo if (!megasas_issue_polled(instance, cmd)) { 310281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo ret = 0; 310381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } else { 310481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo ret = -1; 310581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } 310681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 310781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo /* 310881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * the following function will get the instance PD LIST. 310981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo */ 311081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 311181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo pd_addr = ci->addr; 311281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 311381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo if ( ret == 0 && 311481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo (ci->count < 311581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) { 311681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 311781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo memset(instance->pd_list, 0, 311881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)); 311981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 312081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo for (pd_index = 0; pd_index < ci->count; pd_index++) { 312181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 312281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo instance->pd_list[pd_addr->deviceId].tid = 312381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo pd_addr->deviceId; 312481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo instance->pd_list[pd_addr->deviceId].driveType = 312581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo pd_addr->scsiDevType; 312681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo instance->pd_list[pd_addr->deviceId].driveState = 312781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo MR_PD_STATE_SYSTEM; 312881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo pd_addr++; 312981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } 313081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } 313181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 313281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo pci_free_consistent(instance->pdev, 313381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), 313481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo ci, ci_h); 313581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo megasas_return_cmd(instance, cmd); 313681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 313781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo return ret; 313881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo} 313981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 3140bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo/* 3141bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * megasas_get_ld_list_info - Returns FW's ld_list structure 3142bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * @instance: Adapter soft state 3143bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * @ld_list: ld_list structure 3144bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * 3145bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * Issues an internal command (DCMD) to get the FW's controller PD 3146bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * list structure. This information is mainly used to find out SYSTEM 3147bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * supported by the FW. 3148bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo */ 3149bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bostatic int 3150bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bomegasas_get_ld_list(struct megasas_instance *instance) 3151bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo{ 3152bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo int ret = 0, ld_index = 0, ids = 0; 3153bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo struct megasas_cmd *cmd; 3154bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo struct megasas_dcmd_frame *dcmd; 3155bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo struct MR_LD_LIST *ci; 3156bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dma_addr_t ci_h = 0; 3157bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3158bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo cmd = megasas_get_cmd(instance); 3159bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3160bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (!cmd) { 3161bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n"); 3162bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo return -ENOMEM; 3163bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3164bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3165bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd = &cmd->frame->dcmd; 3166bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3167bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ci = pci_alloc_consistent(instance->pdev, 3168bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo sizeof(struct MR_LD_LIST), 3169bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo &ci_h); 3170bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3171bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (!ci) { 3172bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n"); 3173bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo megasas_return_cmd(instance, cmd); 3174bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo return -ENOMEM; 3175bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3176bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3177bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo memset(ci, 0, sizeof(*ci)); 3178bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 3179bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3180bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->cmd = MFI_CMD_DCMD; 3181bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->cmd_status = 0xFF; 3182bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->sge_count = 1; 3183bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->flags = MFI_FRAME_DIR_READ; 3184bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->timeout = 0; 3185bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->data_xfer_len = sizeof(struct MR_LD_LIST); 3186bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->opcode = MR_DCMD_LD_GET_LIST; 3187bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->sgl.sge32[0].phys_addr = ci_h; 3188bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_LIST); 3189bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->pad_0 = 0; 3190bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3191bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (!megasas_issue_polled(instance, cmd)) { 3192bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ret = 0; 3193bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } else { 3194bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ret = -1; 3195bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3196bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3197bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo /* the following function will get the instance PD LIST */ 3198bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 319939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((ret == 0) && (ci->ldCount <= MAX_LOGICAL_DRIVES)) { 3200bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); 3201bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3202bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo for (ld_index = 0; ld_index < ci->ldCount; ld_index++) { 3203bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (ci->ldList[ld_index].state != 0) { 3204bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ids = ci->ldList[ld_index].ref.targetId; 3205bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo instance->ld_ids[ids] = 3206bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ci->ldList[ld_index].ref.targetId; 3207bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3208bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3209bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3210bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3211bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo pci_free_consistent(instance->pdev, 3212bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo sizeof(struct MR_LD_LIST), 3213bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ci, 3214bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ci_h); 3215bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3216bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo megasas_return_cmd(instance, cmd); 3217bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo return ret; 3218bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo} 3219bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3220c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_get_controller_info - Returns FW's controller structure 3222c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 3223c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @ctrl_info: Controller information structure 3224c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3225c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Issues an internal command (DCMD) to get the FW's controller structure. 3226c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This information is mainly used to find out the maximum IO transfer per 3227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * command supported by the FW. 3228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 3230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_get_ctrl_info(struct megasas_instance *instance, 3231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_ctrl_info *ctrl_info) 3232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int ret = 0; 3234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 3235c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_dcmd_frame *dcmd; 3236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_ctrl_info *ci; 3237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dma_addr_t ci_h = 0; 3238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3239c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 3240c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3241c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) { 3242c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to get a free cmd\n"); 3243c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3244c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3245c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3246c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd = &cmd->frame->dcmd; 3247c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3248c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ci = pci_alloc_consistent(instance->pdev, 3249c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sizeof(struct megasas_ctrl_info), &ci_h); 3250c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3251c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!ci) { 3252c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "Failed to alloc mem for ctrl info\n"); 3253c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 3254c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3255c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3256c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3257c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(ci, 0, sizeof(*ci)); 3258c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 3259c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3260c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd = MFI_CMD_DCMD; 3261c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd_status = 0xFF; 3262c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sge_count = 1; 3263c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->flags = MFI_FRAME_DIR_READ; 3264c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->timeout = 0; 3265780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 3266c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->data_xfer_len = sizeof(struct megasas_ctrl_info); 3267c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->opcode = MR_DCMD_CTRL_GET_INFO; 3268c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].phys_addr = ci_h; 3269c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].length = sizeof(struct megasas_ctrl_info); 3270c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3271c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!megasas_issue_polled(instance, cmd)) { 3272c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ret = 0; 3273c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info)); 3274c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else { 3275c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ret = -1; 3276c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3277c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3278c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info), 3279c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ci, ci_h); 3280c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3281c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 3282c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return ret; 3283c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3284c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3285c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 328631ea7088974c2405e19d72f17c2afb103ef19e02bo yang * megasas_issue_init_mfi - Initializes the FW 328731ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @instance: Adapter soft state 328831ea7088974c2405e19d72f17c2afb103ef19e02bo yang * 328931ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Issues the INIT MFI cmd 329031ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 329131ea7088974c2405e19d72f17c2afb103ef19e02bo yangstatic int 329231ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_issue_init_mfi(struct megasas_instance *instance) 329331ea7088974c2405e19d72f17c2afb103ef19e02bo yang{ 329431ea7088974c2405e19d72f17c2afb103ef19e02bo yang u32 context; 329531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 329631ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct megasas_cmd *cmd; 329731ea7088974c2405e19d72f17c2afb103ef19e02bo yang 329831ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct megasas_init_frame *init_frame; 329931ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct megasas_init_queue_info *initq_info; 330031ea7088974c2405e19d72f17c2afb103ef19e02bo yang dma_addr_t init_frame_h; 330131ea7088974c2405e19d72f17c2afb103ef19e02bo yang dma_addr_t initq_info_h; 330231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 330331ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 330431ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Prepare a init frame. Note the init frame points to queue info 330531ea7088974c2405e19d72f17c2afb103ef19e02bo yang * structure. Each frame has SGL allocated after first 64 bytes. For 330631ea7088974c2405e19d72f17c2afb103ef19e02bo yang * this frame - since we don't need any SGL - we use SGL's space as 330731ea7088974c2405e19d72f17c2afb103ef19e02bo yang * queue info structure 330831ea7088974c2405e19d72f17c2afb103ef19e02bo yang * 330931ea7088974c2405e19d72f17c2afb103ef19e02bo yang * We will not get a NULL command below. We just created the pool. 331031ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 331131ea7088974c2405e19d72f17c2afb103ef19e02bo yang cmd = megasas_get_cmd(instance); 331231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 331331ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame = (struct megasas_init_frame *)cmd->frame; 331431ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info = (struct megasas_init_queue_info *) 331531ea7088974c2405e19d72f17c2afb103ef19e02bo yang ((unsigned long)init_frame + 64); 331631ea7088974c2405e19d72f17c2afb103ef19e02bo yang 331731ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame_h = cmd->frame_phys_addr; 331831ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info_h = init_frame_h + 64; 331931ea7088974c2405e19d72f17c2afb103ef19e02bo yang 332031ea7088974c2405e19d72f17c2afb103ef19e02bo yang context = init_frame->context; 332131ea7088974c2405e19d72f17c2afb103ef19e02bo yang memset(init_frame, 0, MEGAMFI_FRAME_SIZE); 332231ea7088974c2405e19d72f17c2afb103ef19e02bo yang memset(initq_info, 0, sizeof(struct megasas_init_queue_info)); 332331ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame->context = context; 332431ea7088974c2405e19d72f17c2afb103ef19e02bo yang 332531ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info->reply_queue_entries = instance->max_fw_cmds + 1; 332631ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h; 332731ea7088974c2405e19d72f17c2afb103ef19e02bo yang 332831ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info->producer_index_phys_addr_lo = instance->producer_h; 332931ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info->consumer_index_phys_addr_lo = instance->consumer_h; 333031ea7088974c2405e19d72f17c2afb103ef19e02bo yang 333131ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame->cmd = MFI_CMD_INIT; 333231ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame->cmd_status = 0xFF; 333331ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame->queue_info_new_phys_addr_lo = initq_info_h; 333431ea7088974c2405e19d72f17c2afb103ef19e02bo yang 333531ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); 333631ea7088974c2405e19d72f17c2afb103ef19e02bo yang 333731ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 333831ea7088974c2405e19d72f17c2afb103ef19e02bo yang * disable the intr before firing the init frame to FW 333931ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 334031ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->instancet->disable_intr(instance->reg_set); 334131ea7088974c2405e19d72f17c2afb103ef19e02bo yang 334231ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 334331ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Issue the init frame in polled mode 334431ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 334531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 334631ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (megasas_issue_polled(instance, cmd)) { 334731ea7088974c2405e19d72f17c2afb103ef19e02bo yang printk(KERN_ERR "megasas: Failed to init firmware\n"); 334831ea7088974c2405e19d72f17c2afb103ef19e02bo yang megasas_return_cmd(instance, cmd); 334931ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_fw_init; 335031ea7088974c2405e19d72f17c2afb103ef19e02bo yang } 335131ea7088974c2405e19d72f17c2afb103ef19e02bo yang 335231ea7088974c2405e19d72f17c2afb103ef19e02bo yang megasas_return_cmd(instance, cmd); 335331ea7088974c2405e19d72f17c2afb103ef19e02bo yang 335431ea7088974c2405e19d72f17c2afb103ef19e02bo yang return 0; 335531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 335631ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_fw_init: 335731ea7088974c2405e19d72f17c2afb103ef19e02bo yang return -EINVAL; 335831ea7088974c2405e19d72f17c2afb103ef19e02bo yang} 335931ea7088974c2405e19d72f17c2afb103ef19e02bo yang 3360cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordstatic u32 3361cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordmegasas_init_adapter_mfi(struct megasas_instance *instance) 3362c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3363cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct megasas_register_set __iomem *reg_set; 3364c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 context_sz; 3365c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 reply_q_sz; 3366c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3367c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas reg_set = instance->reg_set; 3368c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3369c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3370c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Get various operational parameters from status register 3371c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 33721341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF; 3373e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro /* 3374e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * Reduce the max supported cmds by 1. This is to ensure that the 3375e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * reply_q_sz (1 more than the max cmd that driver may send) 3376e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * does not exceed max cmds that the FW can support 3377e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro */ 3378e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro instance->max_fw_cmds = instance->max_fw_cmds-1; 33799c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->max_mfi_cmds = instance->max_fw_cmds; 33800d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> 33811341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 0x10; 3382c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3383c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Create a pool of commands 3384c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3385c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_alloc_cmds(instance)) 3386c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_alloc_cmds; 3387c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3388c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3389c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Allocate memory for reply queue. Length of reply queue should 3390c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * be _one_ more than the maximum commands handled by the firmware. 3391c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3392c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Note: When FW completes commands, it places corresponding contex 3393c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * values in this circular reply queue. This circular queue is a fairly 3394c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * typical producer-consumer queue. FW is the producer (of completed 3395c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * commands) and the driver is the consumer. 3396c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3397c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas context_sz = sizeof(u32); 3398c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas reply_q_sz = context_sz * (instance->max_fw_cmds + 1); 3399c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3400c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->reply_queue = pci_alloc_consistent(instance->pdev, 3401c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas reply_q_sz, 3402c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &instance->reply_queue_h); 3403c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3404c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->reply_queue) { 3405c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n"); 3406c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_reply_queue; 3407c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3408c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 340931ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (megasas_issue_init_mfi(instance)) 3410c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_fw_init; 3411c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 341239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->fw_support_ieee = 0; 341339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->fw_support_ieee = 341439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->instancet->read_fw_status_reg(reg_set) & 341539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 0x04000000); 341639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 341739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas_init_mfi: fw_support_ieee=%d", 341839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->fw_support_ieee); 341939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 342039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->fw_support_ieee) 342139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->flag_ieee = 1; 342239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 3423cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return 0; 3424cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3425cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordfail_fw_init: 3426cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3427cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford pci_free_consistent(instance->pdev, reply_q_sz, 3428cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->reply_queue, instance->reply_queue_h); 3429cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordfail_reply_queue: 3430cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford megasas_free_cmds(instance); 3431cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3432cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordfail_alloc_cmds: 3433cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return 1; 3434cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford} 3435cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3436cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford/** 3437cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * megasas_init_fw - Initializes the FW 3438cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * @instance: Adapter soft state 3439cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * 3440cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * This is the main function for initializing firmware 3441cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford */ 3442cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3443cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordstatic int megasas_init_fw(struct megasas_instance *instance) 3444cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford{ 3445cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford u32 max_sectors_1; 3446cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford u32 max_sectors_2; 34473f1abce4aba4ced0ba8be54b22f2882bdd01c746Adam Radford u32 tmp_sectors, msix_enable; 3448cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct megasas_register_set __iomem *reg_set; 3449cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct megasas_ctrl_info *ctrl_info; 3450cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford unsigned long bar_list; 3451c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford int i; 3452cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3453cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* Find first memory bar */ 3454cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM); 3455cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->bar = find_first_bit(&bar_list, sizeof(unsigned long)); 3456cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->base_addr = pci_resource_start(instance->pdev, instance->bar); 3457cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (pci_request_selected_regions(instance->pdev, instance->bar, 3458cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford "megasas: LSI")) { 3459cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford printk(KERN_DEBUG "megasas: IO memory region busy!\n"); 3460cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return -EBUSY; 3461cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford } 3462cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3463cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->reg_set = ioremap_nocache(instance->base_addr, 8192); 3464cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3465cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (!instance->reg_set) { 3466cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford printk(KERN_DEBUG "megasas: Failed to map IO mem\n"); 3467cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford goto fail_ioremap; 3468cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford } 3469cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3470cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford reg_set = instance->reg_set; 3471cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3472cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford switch (instance->pdev->device) { 34739c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford case PCI_DEVICE_ID_LSI_FUSION: 347436807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford case PCI_DEVICE_ID_LSI_INVADER: 34759c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->instancet = &megasas_instance_template_fusion; 34769c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 3477cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS1078R: 3478cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS1078DE: 3479cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet = &megasas_instance_template_ppc; 3480cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford break; 3481cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS1078GEN2: 3482cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS0079GEN2: 3483cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet = &megasas_instance_template_gen2; 3484cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford break; 3485cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS0073SKINNY: 3486cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS0071SKINNY: 3487cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet = &megasas_instance_template_skinny; 3488cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford break; 3489cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS1064R: 3490cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_DELL_PERC5: 3491cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford default: 3492cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet = &megasas_instance_template_xscale; 3493cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford break; 3494cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford } 3495cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3496cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* 3497cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * We expect the FW state to be READY 3498cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford */ 3499058a8facfe1ee091b7188661937240fd0d950cf4Adam Radford if (megasas_transition_to_ready(instance, 0)) 3500cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford goto fail_ready_state; 3501cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 35023f1abce4aba4ced0ba8be54b22f2882bdd01c746Adam Radford /* Check if MSI-X is supported while in ready state */ 35033f1abce4aba4ced0ba8be54b22f2882bdd01c746Adam Radford msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & 35043f1abce4aba4ced0ba8be54b22f2882bdd01c746Adam Radford 0x4000000) >> 0x1a; 3505c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (msix_enable && !msix_disable) { 3506c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford /* Check max MSI-X vectors */ 3507c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || 3508c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) { 3509c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msix_vectors = (readl(&instance->reg_set-> 3510c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford outbound_scratch_pad_2 3511c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford ) & 0x1F) + 1; 3512c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } else 3513c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msix_vectors = 1; 3514c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford /* Don't bother allocating more MSI-X vectors than cpus */ 3515c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msix_vectors = min(instance->msix_vectors, 3516c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford (unsigned int)num_online_cpus()); 3517c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford for (i = 0; i < instance->msix_vectors; i++) 3518c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msixentry[i].entry = i; 3519c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford i = pci_enable_msix(instance->pdev, instance->msixentry, 3520c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msix_vectors); 3521c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (i >= 0) { 3522c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (i) { 3523c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (!pci_enable_msix(instance->pdev, 3524c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msixentry, i)) 3525c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msix_vectors = i; 3526c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford else 3527c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msix_vectors = 0; 3528c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } 3529c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } else 3530c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msix_vectors = 0; 3531c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } 35323f1abce4aba4ced0ba8be54b22f2882bdd01c746Adam Radford 3533cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* Get operational params, sge flags, send init cmd to controller */ 3534cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (instance->instancet->init_adapter(instance)) 3535eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford goto fail_init_adapter; 3536cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3537cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford printk(KERN_ERR "megasas: INIT adapter done\n"); 3538cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 353939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang /** for passthrough 354039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * the following function will get the PD LIST. 354139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 354239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 354381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo memset(instance->pd_list, 0 , 354481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); 354581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo megasas_get_pd_list(instance); 354681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 3547bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); 3548bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo megasas_get_ld_list(instance); 3549bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3550c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL); 3551c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3552c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3553c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Compute the max allowed sectors per IO: The controller info has two 3554c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * limits on max sectors. Driver should use the minimum of these two. 3555c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3556c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 1 << stripe_sz_ops.min = max sectors per strip 3557c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3558c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Note that older firmwares ( < FW ver 30) didn't report information 3559c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to calculate max_sectors_1. So the number ended up as zero always. 3560c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 356114faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang tmp_sectors = 0; 3562c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) { 3563c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3564c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) * 3565c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ctrl_info->max_strips_per_io; 3566c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas max_sectors_2 = ctrl_info->max_request_size; 3567c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 356814faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2); 356939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->disableOnlineCtrlReset = 357039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; 357114faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang } 357214faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang 357314faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang instance->max_sectors_per_req = instance->max_num_sge * 357414faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang PAGE_SIZE / 512; 357514faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors)) 357614faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang instance->max_sectors_per_req = tmp_sectors; 3577c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3578c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(ctrl_info); 3579c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 35805d018ad057347995e5c4564b3e43339e6497f839Sumant Patro /* 35815d018ad057347995e5c4564b3e43339e6497f839Sumant Patro * Setup tasklet for cmd completion 35825d018ad057347995e5c4564b3e43339e6497f839Sumant Patro */ 35835d018ad057347995e5c4564b3e43339e6497f839Sumant Patro 3584f86c5424b02717a9eb9b1049a67ff3e7e9e92edfAdam Radford tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, 3585ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang (unsigned long)instance); 3586ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 3587c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3588c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3589eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radfordfail_init_adapter: 3590cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordfail_ready_state: 3591c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas iounmap(instance->reg_set); 3592c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3593c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_ioremap: 3594b6d5d8808b4c563a56414a4c4c6d652b5f87c088Adam Radford pci_release_selected_regions(instance->pdev, instance->bar); 3595c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3596c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EINVAL; 3597c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3598c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3599c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3600c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_release_mfi - Reverses the FW initialization 3601c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @intance: Adapter soft state 3602c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3603c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_release_mfi(struct megasas_instance *instance) 3604c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 36059c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1); 3606c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 36079c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (instance->reply_queue) 36089c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_free_consistent(instance->pdev, reply_q_sz, 3609c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->reply_queue, instance->reply_queue_h); 3610c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3611c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_free_cmds(instance); 3612c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3613c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas iounmap(instance->reg_set); 3614c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3615b6d5d8808b4c563a56414a4c4c6d652b5f87c088Adam Radford pci_release_selected_regions(instance->pdev, instance->bar); 3616c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3617c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3618c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3619c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_get_seq_num - Gets latest event sequence numbers 3620c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 3621c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @eli: FW event log sequence numbers information 3622c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3623c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * FW maintains a log of all events in a non-volatile area. Upper layers would 3624c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * usually find out the latest sequence number of the events, the seq number at 3625c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the boot etc. They would "read" all the events below the latest seq number 3626c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq 3627c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * number), they would subsribe to AEN (asynchronous event notification) and 3628c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * wait for the events to happen. 3629c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3630c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 3631c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_get_seq_num(struct megasas_instance *instance, 3632c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_evt_log_info *eli) 3633c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3634c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 3635c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_dcmd_frame *dcmd; 3636c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_evt_log_info *el_info; 3637c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dma_addr_t el_info_h = 0; 3638c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3639c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 3640c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3641c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) { 3642c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3643c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3644c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3645c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd = &cmd->frame->dcmd; 3646c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas el_info = pci_alloc_consistent(instance->pdev, 3647c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sizeof(struct megasas_evt_log_info), 3648c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &el_info_h); 3649c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3650c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!el_info) { 3651c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 3652c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3653c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3654c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3655c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(el_info, 0, sizeof(*el_info)); 3656c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 3657c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3658c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd = MFI_CMD_DCMD; 3659c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd_status = 0x0; 3660c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sge_count = 1; 3661c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->flags = MFI_FRAME_DIR_READ; 3662c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->timeout = 0; 3663780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 3664c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->data_xfer_len = sizeof(struct megasas_evt_log_info); 3665c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO; 3666c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].phys_addr = el_info_h; 3667c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_log_info); 3668c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3669c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_issue_blocked_cmd(instance, cmd); 3670c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3671c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3672c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Copy the data back into callers buffer 3673c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3674c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memcpy(eli, el_info, sizeof(struct megasas_evt_log_info)); 3675c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3676c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info), 3677c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas el_info, el_info_h); 3678c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3679c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 3680c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3681c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3682c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3683c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3684c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3685c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_register_aen - Registers for asynchronous event notification 3686c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 3687c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @seq_num: The starting sequence number 3688c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @class_locale: Class of the event 3689c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3690c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function subscribes for AEN for events beyond the @seq_num. It requests 3691c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to be notified if and only if the event is of type @class_locale 3692c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3693c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 3694c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_register_aen(struct megasas_instance *instance, u32 seq_num, 3695c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 class_locale_word) 3696c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3697c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int ret_val; 3698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 3699c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_dcmd_frame *dcmd; 3700c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas union megasas_evt_class_locale curr_aen; 3701c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas union megasas_evt_class_locale prev_aen; 3702c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3703c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3704c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * If there an AEN pending already (aen_cmd), check if the 3705c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * class_locale of that pending AEN is inclusive of the new 3706c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * AEN request we currently have. If it is, then we don't have 3707c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to do anything. In other words, whichever events the current 3708c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * AEN request is subscribing to, have already been subscribed 3709c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to. 3710c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3711c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * If the old_cmd is _not_ inclusive, then we have to abort 3712c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * that command, form a class_locale that is superset of both 3713c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * old and current and re-issue to the FW 3714c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3715c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3716c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas curr_aen.word = class_locale_word; 3717c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3718c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (instance->aen_cmd) { 3719c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3720c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1]; 3721c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3722c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3723c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * A class whose enum value is smaller is inclusive of all 3724c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * higher values. If a PROGRESS (= -1) was previously 3725c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * registered, then a new registration requests for higher 3726c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * classes need not be sent to FW. They are automatically 3727c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * included. 3728c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3729c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Locale numbers don't have such hierarchy. They are bitmap 3730c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * values 3731c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3732c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if ((prev_aen.members.class <= curr_aen.members.class) && 3733c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas !((prev_aen.members.locale & curr_aen.members.locale) ^ 3734c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas curr_aen.members.locale)) { 3735c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3736c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Previously issued event registration includes 3737c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * current request. Nothing to do. 3738c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3739c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3740c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else { 3741c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas curr_aen.members.locale |= prev_aen.members.locale; 3742c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3743c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (prev_aen.members.class < curr_aen.members.class) 3744c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas curr_aen.members.class = prev_aen.members.class; 3745c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3746c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->aen_cmd->abort_aen = 1; 3747c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ret_val = megasas_issue_blocked_abort_cmd(instance, 3748c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance-> 3749c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas aen_cmd); 3750c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3751c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ret_val) { 3752c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to abort " 3753c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "previous AEN command\n"); 3754c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return ret_val; 3755c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3756c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3757c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3758c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3759c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 3760c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3761c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) 3762c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3763c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3764c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd = &cmd->frame->dcmd; 3765c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3766c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail)); 3767c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3768c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3769c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Prepare DCMD for aen registration 3770c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3771c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 3772c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3773c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd = MFI_CMD_DCMD; 3774c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd_status = 0x0; 3775c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sge_count = 1; 3776c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->flags = MFI_FRAME_DIR_READ; 3777c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->timeout = 0; 3778780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 377939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->last_seq_num = seq_num; 3780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->data_xfer_len = sizeof(struct megasas_evt_detail); 3781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT; 3782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->mbox.w[0] = seq_num; 3783c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->mbox.w[1] = curr_aen.word; 3784c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h; 3785c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail); 3786c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3787f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->aen_cmd != NULL) { 3788f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo megasas_return_cmd(instance, cmd); 3789f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo return 0; 3790f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 3791f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 3792c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3793c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Store reference to the cmd used to register for AEN. When an 3794c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * application wants us to register for AEN, we have to abort this 3795c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * cmd and re-register with a new EVENT LOCALE supplied by that app 3796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3797c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->aen_cmd = cmd; 3798c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3799c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3800c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Issue the aen registration frame 3801c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 38029c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->instancet->issue_dcmd(instance, cmd); 3803c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3804c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3805c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3806c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3807c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3808c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_start_aen - Subscribes to AEN during driver load time 3809c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 3810c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3811c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_start_aen(struct megasas_instance *instance) 3812c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3813c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_evt_log_info eli; 3814c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas union megasas_evt_class_locale class_locale; 3815c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3816c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3817c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Get the latest sequence number from FW 3818c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3819c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(&eli, 0, sizeof(eli)); 3820c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3821c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_get_seq_num(instance, &eli)) 3822c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -1; 3823c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3824c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3825c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Register AEN with FW for latest sequence number plus 1 3826c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3827c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas class_locale.members.reserved = 0; 3828c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas class_locale.members.locale = MR_EVT_LOCALE_ALL; 3829c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas class_locale.members.class = MR_EVT_CLASS_DEBUG; 3830c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3831c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return megasas_register_aen(instance, eli.newest_seq_num + 1, 3832c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas class_locale.word); 3833c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3834c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3835c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3836c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_io_attach - Attaches this driver to SCSI mid-layer 3837c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 3838c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3839c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_io_attach(struct megasas_instance *instance) 3840c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3841c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct Scsi_Host *host = instance->host; 3842c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3843c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3844c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Export parameters required by SCSI mid-layer 3845c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3846c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->irq = instance->pdev->irq; 3847c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->unique_id = instance->unique_id; 38487bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 38497bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { 38507bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo host->can_queue = 38517bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS; 38527bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo } else 38537bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo host->can_queue = 38547bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo instance->max_fw_cmds - MEGASAS_INT_CMDS; 3855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->this_id = instance->init_id; 3856c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->sg_tablesize = instance->max_num_sge; 385742a8d2b34d107df34533ea4840daf8d62bdc90aaAdam Radford 385842a8d2b34d107df34533ea4840daf8d62bdc90aaAdam Radford if (instance->fw_support_ieee) 385942a8d2b34d107df34533ea4840daf8d62bdc90aaAdam Radford instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE; 386042a8d2b34d107df34533ea4840daf8d62bdc90aaAdam Radford 38611fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo /* 38621fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo * Check if the module parameter value for max_sectors can be used 38631fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo */ 38641fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo if (max_sectors && max_sectors < instance->max_sectors_per_req) 38651fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo instance->max_sectors_per_req = max_sectors; 38661fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo else { 38671fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo if (max_sectors) { 38681fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo if (((instance->pdev->device == 38691fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo PCI_DEVICE_ID_LSI_SAS1078GEN2) || 38701fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo (instance->pdev->device == 38711fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo PCI_DEVICE_ID_LSI_SAS0079GEN2)) && 38721fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo (max_sectors <= MEGASAS_MAX_SECTORS)) { 38731fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo instance->max_sectors_per_req = max_sectors; 38741fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo } else { 38751fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo printk(KERN_INFO "megasas: max_sectors should be > 0" 38761fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo "and <= %d (or < 1MB for GEN2 controller)\n", 38771fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo instance->max_sectors_per_req); 38781fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo } 38791fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo } 38801fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo } 38811fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo 3882c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->max_sectors = instance->max_sectors_per_req; 38839c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN; 3884c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->max_channel = MEGASAS_MAX_CHANNELS - 1; 3885c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL; 3886c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->max_lun = MEGASAS_MAX_LUN; 3887122da30223c06cee181044af6d32e88b256d10dfJoshua Giles host->max_cmd_len = 16; 3888c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 38899c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford /* Fusion only supports host reset */ 389036807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || 389136807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) { 38929c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford host->hostt->eh_device_reset_handler = NULL; 38939c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford host->hostt->eh_bus_reset_handler = NULL; 38949c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 38959c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 3896c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3897c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Notify the mid-layer about the new controller 3898c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3899c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (scsi_add_host(host, &instance->pdev->dev)) { 3900c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: scsi_add_host failed\n"); 3901c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENODEV; 3902c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3903c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3904c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3905c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Trigger SCSI to scan our drives 3906c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3907c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scsi_scan_host(host); 3908c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3909c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3910c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 391131ea7088974c2405e19d72f17c2afb103ef19e02bo yangstatic int 391231ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_set_dma_mask(struct pci_dev *pdev) 391331ea7088974c2405e19d72f17c2afb103ef19e02bo yang{ 391431ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 391531ea7088974c2405e19d72f17c2afb103ef19e02bo yang * All our contollers are capable of performing 64-bit DMA 391631ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 391731ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (IS_DMA64) { 39186a35528a8346f6e6fd32ed7e51f04d1fa4ca2c01Yang Hongyang if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) { 391931ea7088974c2405e19d72f17c2afb103ef19e02bo yang 3920284901a90a9e0b812ca3f5f852cbbfb60d10249dYang Hongyang if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) 392131ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_set_dma_mask; 392231ea7088974c2405e19d72f17c2afb103ef19e02bo yang } 392331ea7088974c2405e19d72f17c2afb103ef19e02bo yang } else { 3924284901a90a9e0b812ca3f5f852cbbfb60d10249dYang Hongyang if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) 392531ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_set_dma_mask; 392631ea7088974c2405e19d72f17c2afb103ef19e02bo yang } 392731ea7088974c2405e19d72f17c2afb103ef19e02bo yang return 0; 392831ea7088974c2405e19d72f17c2afb103ef19e02bo yang 392931ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_set_dma_mask: 393031ea7088974c2405e19d72f17c2afb103ef19e02bo yang return 1; 393131ea7088974c2405e19d72f17c2afb103ef19e02bo yang} 393231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 3933c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_probe_one - PCI hotplug entry point 3935c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @pdev: PCI device structure 39360d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * @id: PCI ids of supported hotplugged adapter 3937c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3938c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int __devinit 3939c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) 3940c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3941c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford int rval, pos, i, j; 3942c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct Scsi_Host *host; 3943c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 394466192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford u16 control = 0; 394566192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford 394666192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford /* Reset MSI-X in the kdump kernel */ 394766192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford if (reset_devices) { 394866192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); 394966192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford if (pos) { 395066192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford pci_read_config_word(pdev, msi_control_reg(pos), 395166192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford &control); 395266192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford if (control & PCI_MSIX_FLAGS_ENABLE) { 395366192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford dev_info(&pdev->dev, "resetting MSI-X\n"); 395466192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford pci_write_config_word(pdev, 395566192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford msi_control_reg(pos), 395666192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford control & 395766192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford ~PCI_MSIX_FLAGS_ENABLE); 395866192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford } 395966192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford } 396066192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford } 3961c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3962c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3963c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Announce PCI information 3964c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3965c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_INFO "megasas: %#4.04x:%#4.04x:%#4.04x:%#4.04x: ", 3966c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pdev->vendor, pdev->device, pdev->subsystem_vendor, 3967c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pdev->subsystem_device); 3968c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3969c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk("bus %d:slot %d:func %d\n", 3970c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); 3971c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3972c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3973c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI prepping: enable device set bus mastering and dma mask 3974c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3975aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii rval = pci_enable_device_mem(pdev); 3976c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3977c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (rval) { 3978c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return rval; 3979c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3980c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3981c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_set_master(pdev); 3982c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 398331ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (megasas_set_dma_mask(pdev)) 398431ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_set_dma_mask; 3985c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3986c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host = scsi_host_alloc(&megasas_template, 3987c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sizeof(struct megasas_instance)); 3988c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3989c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!host) { 3990c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: scsi_host_alloc failed\n"); 3991c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_alloc_instance; 3992c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3993c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3994c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = (struct megasas_instance *)host->hostdata; 3995c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(instance, 0, sizeof(*instance)); 399639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_set( &instance->fw_reset_no_pci_access, 0 ); 39979c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->pdev = pdev; 3998c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 39999c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford switch (instance->pdev->device) { 40009c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford case PCI_DEVICE_ID_LSI_FUSION: 400136807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford case PCI_DEVICE_ID_LSI_INVADER: 40029c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford { 40039c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford struct fusion_context *fusion; 40049c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 40059c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->ctrl_context = 40069c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford kzalloc(sizeof(struct fusion_context), GFP_KERNEL); 40079c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (!instance->ctrl_context) { 40089c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford printk(KERN_DEBUG "megasas: Failed to allocate " 40099c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford "memory for Fusion context info\n"); 40109c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford goto fail_alloc_dma_buf; 40119c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 40129c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion = instance->ctrl_context; 40139c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford INIT_LIST_HEAD(&fusion->cmd_pool); 40149c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_lock_init(&fusion->cmd_pool_lock); 40159c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 40169c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 40179c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford default: /* For all other supported controllers */ 40189c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 40199c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->producer = 40209c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_alloc_consistent(pdev, sizeof(u32), 40219c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->producer_h); 40229c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->consumer = 40239c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_alloc_consistent(pdev, sizeof(u32), 40249c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->consumer_h); 40259c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 40269c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (!instance->producer || !instance->consumer) { 40279c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford printk(KERN_DEBUG "megasas: Failed to allocate" 40289c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford "memory for producer, consumer\n"); 40299c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford goto fail_alloc_dma_buf; 40309c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 4031c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 40329c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford *instance->producer = 0; 40339c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford *instance->consumer = 0; 40349c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 4035c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4036c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4037c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo megasas_poll_wait_aen = 0; 4038f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo instance->flag_ieee = 0; 40397e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo instance->ev = NULL; 404039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->issuepend_done = 1; 404139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_HBA_OPERATIONAL; 404239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_poll_wait_aen = 0; 4043c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4044c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->evt_detail = pci_alloc_consistent(pdev, 4045c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sizeof(struct 4046c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_evt_detail), 4047c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &instance->evt_detail_h); 4048c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4049c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->evt_detail) { 4050c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to allocate memory for " 4051c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "event detail structure\n"); 4052c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_alloc_dma_buf; 4053c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4054c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4055c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4056c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Initialize locks and queues 4057c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4058c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas INIT_LIST_HEAD(&instance->cmd_pool); 405939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang INIT_LIST_HEAD(&instance->internal_reset_pending_q); 4060c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4061e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro atomic_set(&instance->fw_outstanding,0); 4062e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro 4063c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas init_waitqueue_head(&instance->int_cmd_wait_q); 4064c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas init_waitqueue_head(&instance->abort_cmd_wait_q); 4065c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4066c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas spin_lock_init(&instance->cmd_pool_lock); 406739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_init(&instance->hba_lock); 40687343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang spin_lock_init(&instance->completion_lock); 4069c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_lock_init(&poll_aen_lock); 4070c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4071e5a69e27cc193f98c9a5a9086e3bf85528170623Matthias Kaehlcke mutex_init(&instance->aen_mutex); 40729c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford mutex_init(&instance->reset_mutex); 4073c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4074c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4075c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Initialize PCI related and misc parameters 4076c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4077c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->host = host; 4078c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->unique_id = pdev->bus->number << 8 | pdev->devfn; 4079c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->init_id = MEGASAS_DEFAULT_INIT_ID; 4080c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 40817bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 40827bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { 4083f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo instance->flag_ieee = 1; 40847bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS); 40857bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo } else 40867bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS); 40877bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo 4088658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro megasas_dbg_lvl = 0; 408905e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance->flag = 0; 40900c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo instance->unload = 1; 409105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance->last_time = 0; 409239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->disableOnlineCtrlReset = 1; 409339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 409436807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || 409536807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) 40969c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq); 40979c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford else 40989c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford INIT_WORK(&instance->work_init, process_fw_state_change_wq); 4099658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 4100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 41010a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford * Initialize MFI Firmware 41020a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford */ 41030a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford if (megasas_init_fw(instance)) 41040a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford goto fail_init_mfi; 41050a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford 41060a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford /* 4107c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Register IRQ 4108c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4109c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) { 4110c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford for (i = 0 ; i < instance->msix_vectors; i++) { 4111c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->irq_context[i].instance = instance; 4112c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->irq_context[i].MSIxIndex = i; 4113c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (request_irq(instance->msixentry[i].vector, 4114c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->instancet->service_isr, 0, 4115c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford "megasas", 4116c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford &instance->irq_context[i])) { 4117c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford printk(KERN_DEBUG "megasas: Failed to " 4118c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford "register IRQ for vector %d.\n", i); 4119c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford for (j = 0 ; j < i ; j++) 4120c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford free_irq( 4121c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msixentry[j].vector, 4122c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford &instance->irq_context[j]); 4123c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford goto fail_irq; 4124c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } 4125c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } 4126c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } else { 4127c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->irq_context[0].instance = instance; 4128c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->irq_context[0].MSIxIndex = 0; 4129c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (request_irq(pdev->irq, instance->instancet->service_isr, 4130c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford IRQF_SHARED, "megasas", 4131c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford &instance->irq_context[0])) { 4132c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); 4133c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford goto fail_irq; 4134c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } 4135c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4136c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 41371341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro instance->instancet->enable_intr(instance->reg_set); 4138c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4139c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4140c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Store instance in PCI softstate 4141c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4142c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_set_drvdata(pdev, instance); 4143c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4144c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4145c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Add this controller to megasas_mgmt_info structure so that it 4146c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * can be exported to management applications 4147c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4148c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.count++; 4149c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance; 4150c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.max_index++; 4151c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4152c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4153541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford * Register with SCSI mid-layer 4154541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford */ 4155541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford if (megasas_io_attach(instance)) 4156541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford goto fail_io_attach; 4157541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford 4158541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford instance->unload = 0; 4159541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford 4160541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford /* 4161c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Initiate AEN (Asynchronous Event Notification) 4162c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4163c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_start_aen(instance)) { 4164c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: start aen failed\n"); 4165c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_start_aen; 4166c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4167c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4168c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 4169c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4170c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_start_aen: 4171c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_io_attach: 4172c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.count--; 4173c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL; 4174c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.max_index--; 4175c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4176c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_set_drvdata(pdev, NULL); 4177b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro instance->instancet->disable_intr(instance->reg_set); 4178c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) 4179c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford for (i = 0 ; i < instance->msix_vectors; i++) 4180c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford free_irq(instance->msixentry[i].vector, 4181c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford &instance->irq_context[i]); 4182c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford else 4183c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford free_irq(instance->pdev->irq, &instance->irq_context[0]); 4184eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radfordfail_irq: 418536807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || 418636807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) 4187eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford megasas_release_fusion(instance); 4188eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford else 4189eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford megasas_release_mfi(instance); 4190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_init_mfi: 4191c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) 41920a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford pci_disable_msix(instance->pdev); 4193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_alloc_dma_buf: 4194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (instance->evt_detail) 4195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), 4196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->evt_detail, 4197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->evt_detail_h); 4198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4199eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford if (instance->producer) 4200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_free_consistent(pdev, sizeof(u32), instance->producer, 4201c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->producer_h); 4202c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (instance->consumer) 4203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_free_consistent(pdev, sizeof(u32), instance->consumer, 4204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->consumer_h); 4205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scsi_host_put(host); 4206c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4207c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_alloc_instance: 4208c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_set_dma_mask: 4209c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_disable_device(pdev); 4210c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4211c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENODEV; 4212c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4213c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4214c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_flush_cache - Requests FW to flush all its caches 4216c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 4217c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4218c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_flush_cache(struct megasas_instance *instance) 4219c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4220c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 4221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_dcmd_frame *dcmd; 4222c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 422339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) 422439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return; 422539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 4226c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 4227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) 4229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 4230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd = &cmd->frame->dcmd; 4232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 4234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4235c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd = MFI_CMD_DCMD; 4236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd_status = 0x0; 4237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sge_count = 0; 4238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->flags = MFI_FRAME_DIR_NONE; 4239c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->timeout = 0; 4240780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 4241c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->data_xfer_len = 0; 4242c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH; 4243c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; 4244c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4245c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_issue_blocked_cmd(instance, cmd); 4246c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4247c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 4248c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4249c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 4250c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4251c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4252c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4253c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_shutdown_controller - Instructs FW to shutdown the controller 4254c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 425531ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @opcode: Shutdown/Hibernate 4256c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 425731ea7088974c2405e19d72f17c2afb103ef19e02bo yangstatic void megasas_shutdown_controller(struct megasas_instance *instance, 425831ea7088974c2405e19d72f17c2afb103ef19e02bo yang u32 opcode) 4259c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4260c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 4261c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_dcmd_frame *dcmd; 4262c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 426339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) 426439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return; 426539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 4266c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 4267c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4268c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) 4269c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 4270c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4271c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (instance->aen_cmd) 4272c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd); 42739c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (instance->map_update_cmd) 42749c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_issue_blocked_abort_cmd(instance, 42759c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->map_update_cmd); 4276c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd = &cmd->frame->dcmd; 4277c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4278c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 4279c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4280c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd = MFI_CMD_DCMD; 4281c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd_status = 0x0; 4282c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sge_count = 0; 4283c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->flags = MFI_FRAME_DIR_NONE; 4284c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->timeout = 0; 4285780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 4286c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->data_xfer_len = 0; 428731ea7088974c2405e19d72f17c2afb103ef19e02bo yang dcmd->opcode = opcode; 4288c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4289c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_issue_blocked_cmd(instance, cmd); 4290c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4291c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 4292c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4293c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 4294c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4295c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 429633139b21013aba815924b421159fab35e5175483Jiri Slaby#ifdef CONFIG_PM 4297c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4298ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * megasas_suspend - driver suspend entry point 4299ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @pdev: PCI device structure 430031ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @state: PCI power state to suspend routine 430131ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 430233139b21013aba815924b421159fab35e5175483Jiri Slabystatic int 430331ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_suspend(struct pci_dev *pdev, pm_message_t state) 430431ea7088974c2405e19d72f17c2afb103ef19e02bo yang{ 430531ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct Scsi_Host *host; 430631ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct megasas_instance *instance; 4307c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford int i; 430831ea7088974c2405e19d72f17c2afb103ef19e02bo yang 430931ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance = pci_get_drvdata(pdev); 431031ea7088974c2405e19d72f17c2afb103ef19e02bo yang host = instance->host; 43110c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo instance->unload = 1; 431231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 431331ea7088974c2405e19d72f17c2afb103ef19e02bo yang megasas_flush_cache(instance); 431431ea7088974c2405e19d72f17c2afb103ef19e02bo yang megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN); 43157e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 43167e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo /* cancel the delayed work if this work still in queue */ 43177e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (instance->ev != NULL) { 43187e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct megasas_aen_event *ev = instance->ev; 4319a684b8da35a429a246ec2a91e2742bdff5209709Tejun Heo cancel_delayed_work_sync( 43207e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo (struct delayed_work *)&ev->hotplug_work); 43217e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo instance->ev = NULL; 43227e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 43237e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 432431ea7088974c2405e19d72f17c2afb103ef19e02bo yang tasklet_kill(&instance->isr_tasklet); 432531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 432631ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_set_drvdata(instance->pdev, instance); 432731ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->instancet->disable_intr(instance->reg_set); 4328c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford 4329c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) 4330c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford for (i = 0 ; i < instance->msix_vectors; i++) 4331c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford free_irq(instance->msixentry[i].vector, 4332c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford &instance->irq_context[i]); 4333c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford else 4334c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford free_irq(instance->pdev->irq, &instance->irq_context[0]); 4335c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) 433680d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford pci_disable_msix(instance->pdev); 433731ea7088974c2405e19d72f17c2afb103ef19e02bo yang 433831ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_save_state(pdev); 433931ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_disable_device(pdev); 434031ea7088974c2405e19d72f17c2afb103ef19e02bo yang 434131ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_set_power_state(pdev, pci_choose_state(pdev, state)); 434231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 434331ea7088974c2405e19d72f17c2afb103ef19e02bo yang return 0; 434431ea7088974c2405e19d72f17c2afb103ef19e02bo yang} 434531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 434631ea7088974c2405e19d72f17c2afb103ef19e02bo yang/** 434731ea7088974c2405e19d72f17c2afb103ef19e02bo yang * megasas_resume- driver resume entry point 434831ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @pdev: PCI device structure 434931ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 435033139b21013aba815924b421159fab35e5175483Jiri Slabystatic int 435131ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_resume(struct pci_dev *pdev) 435231ea7088974c2405e19d72f17c2afb103ef19e02bo yang{ 4353c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford int rval, i, j; 435431ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct Scsi_Host *host; 435531ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct megasas_instance *instance; 435631ea7088974c2405e19d72f17c2afb103ef19e02bo yang 435731ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance = pci_get_drvdata(pdev); 435831ea7088974c2405e19d72f17c2afb103ef19e02bo yang host = instance->host; 435931ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_set_power_state(pdev, PCI_D0); 436031ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_enable_wake(pdev, PCI_D0, 0); 436131ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_restore_state(pdev); 436231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 436331ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 436431ea7088974c2405e19d72f17c2afb103ef19e02bo yang * PCI prepping: enable device set bus mastering and dma mask 436531ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 4366aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii rval = pci_enable_device_mem(pdev); 436731ea7088974c2405e19d72f17c2afb103ef19e02bo yang 436831ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (rval) { 436931ea7088974c2405e19d72f17c2afb103ef19e02bo yang printk(KERN_ERR "megasas: Enable device failed\n"); 437031ea7088974c2405e19d72f17c2afb103ef19e02bo yang return rval; 437131ea7088974c2405e19d72f17c2afb103ef19e02bo yang } 437231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 437331ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_set_master(pdev); 437431ea7088974c2405e19d72f17c2afb103ef19e02bo yang 437531ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (megasas_set_dma_mask(pdev)) 437631ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_set_dma_mask; 437731ea7088974c2405e19d72f17c2afb103ef19e02bo yang 437831ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 437931ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Initialize MFI Firmware 438031ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 438131ea7088974c2405e19d72f17c2afb103ef19e02bo yang 438231ea7088974c2405e19d72f17c2afb103ef19e02bo yang atomic_set(&instance->fw_outstanding, 0); 438331ea7088974c2405e19d72f17c2afb103ef19e02bo yang 438431ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 438531ea7088974c2405e19d72f17c2afb103ef19e02bo yang * We expect the FW state to be READY 438631ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 4387058a8facfe1ee091b7188661937240fd0d950cf4Adam Radford if (megasas_transition_to_ready(instance, 0)) 438831ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_ready_state; 438931ea7088974c2405e19d72f17c2afb103ef19e02bo yang 43903f1abce4aba4ced0ba8be54b22f2882bdd01c746Adam Radford /* Now re-enable MSI-X */ 4391c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) 4392c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford pci_enable_msix(instance->pdev, instance->msixentry, 4393c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msix_vectors); 43943f1abce4aba4ced0ba8be54b22f2882bdd01c746Adam Radford 43959c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford switch (instance->pdev->device) { 43969c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford case PCI_DEVICE_ID_LSI_FUSION: 439736807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford case PCI_DEVICE_ID_LSI_INVADER: 43989c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford { 43999c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_reset_reply_desc(instance); 44009c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (megasas_ioc_init_fusion(instance)) { 44019c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_free_cmds(instance); 44029c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_free_cmds_fusion(instance); 44039c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford goto fail_init_mfi; 44049c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 44059c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (!megasas_get_map_info(instance)) 44069c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_sync_map_info(instance); 44079c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 44089c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 44099c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford default: 44109c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford *instance->producer = 0; 44119c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford *instance->consumer = 0; 44129c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (megasas_issue_init_mfi(instance)) 44139c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford goto fail_init_mfi; 44149c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 44159c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 441631ea7088974c2405e19d72f17c2afb103ef19e02bo yang 44179c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, 44189c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (unsigned long)instance); 441931ea7088974c2405e19d72f17c2afb103ef19e02bo yang 442031ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 442131ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Register IRQ 442231ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 4423c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) { 4424c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford for (i = 0 ; i < instance->msix_vectors; i++) { 4425c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->irq_context[i].instance = instance; 4426c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->irq_context[i].MSIxIndex = i; 4427c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (request_irq(instance->msixentry[i].vector, 4428c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->instancet->service_isr, 0, 4429c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford "megasas", 4430c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford &instance->irq_context[i])) { 4431c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford printk(KERN_DEBUG "megasas: Failed to " 4432c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford "register IRQ for vector %d.\n", i); 4433c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford for (j = 0 ; j < i ; j++) 4434c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford free_irq( 4435c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->msixentry[j].vector, 4436c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford &instance->irq_context[j]); 4437c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford goto fail_irq; 4438c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } 4439c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } 4440c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } else { 4441c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->irq_context[0].instance = instance; 4442c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford instance->irq_context[0].MSIxIndex = 0; 4443c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (request_irq(pdev->irq, instance->instancet->service_isr, 4444c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford IRQF_SHARED, "megasas", 4445c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford &instance->irq_context[0])) { 4446c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); 4447c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford goto fail_irq; 4448c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford } 444931ea7088974c2405e19d72f17c2afb103ef19e02bo yang } 445031ea7088974c2405e19d72f17c2afb103ef19e02bo yang 445131ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->instancet->enable_intr(instance->reg_set); 44520c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo instance->unload = 0; 44530c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo 4454541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford /* 4455541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford * Initiate AEN (Asynchronous Event Notification) 4456541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford */ 4457541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford if (megasas_start_aen(instance)) 4458541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford printk(KERN_ERR "megasas: Start AEN failed\n"); 4459541f90b7c6dffe4cf4a3e8142ac8bd047da94733Adam Radford 446031ea7088974c2405e19d72f17c2afb103ef19e02bo yang return 0; 446131ea7088974c2405e19d72f17c2afb103ef19e02bo yang 446231ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_irq: 446331ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_init_mfi: 446431ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (instance->evt_detail) 446531ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), 446631ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->evt_detail, 446731ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->evt_detail_h); 446831ea7088974c2405e19d72f17c2afb103ef19e02bo yang 446931ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (instance->producer) 447031ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_free_consistent(pdev, sizeof(u32), instance->producer, 447131ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->producer_h); 447231ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (instance->consumer) 447331ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_free_consistent(pdev, sizeof(u32), instance->consumer, 447431ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->consumer_h); 447531ea7088974c2405e19d72f17c2afb103ef19e02bo yang scsi_host_put(host); 447631ea7088974c2405e19d72f17c2afb103ef19e02bo yang 447731ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_set_dma_mask: 447831ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_ready_state: 447931ea7088974c2405e19d72f17c2afb103ef19e02bo yang 448031ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_disable_device(pdev); 448131ea7088974c2405e19d72f17c2afb103ef19e02bo yang 448231ea7088974c2405e19d72f17c2afb103ef19e02bo yang return -ENODEV; 448331ea7088974c2405e19d72f17c2afb103ef19e02bo yang} 448433139b21013aba815924b421159fab35e5175483Jiri Slaby#else 448533139b21013aba815924b421159fab35e5175483Jiri Slaby#define megasas_suspend NULL 448633139b21013aba815924b421159fab35e5175483Jiri Slaby#define megasas_resume NULL 448733139b21013aba815924b421159fab35e5175483Jiri Slaby#endif 448831ea7088974c2405e19d72f17c2afb103ef19e02bo yang 448931ea7088974c2405e19d72f17c2afb103ef19e02bo yang/** 4490c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_detach_one - PCI hot"un"plug entry point 4491c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @pdev: PCI device structure 4492c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 449333139b21013aba815924b421159fab35e5175483Jiri Slabystatic void __devexit megasas_detach_one(struct pci_dev *pdev) 4494c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4495c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 4496c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct Scsi_Host *host; 4497c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 44989c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford struct fusion_context *fusion; 4499c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4500c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = pci_get_drvdata(pdev); 4501c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo instance->unload = 1; 4502c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host = instance->host; 45039c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion = instance->ctrl_context; 4504c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4505c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scsi_remove_host(instance->host); 4506c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_flush_cache(instance); 450731ea7088974c2405e19d72f17c2afb103ef19e02bo yang megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); 45087e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 45097e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo /* cancel the delayed work if this work still in queue*/ 45107e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (instance->ev != NULL) { 45117e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct megasas_aen_event *ev = instance->ev; 4512a684b8da35a429a246ec2a91e2742bdff5209709Tejun Heo cancel_delayed_work_sync( 45137e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo (struct delayed_work *)&ev->hotplug_work); 45147e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo instance->ev = NULL; 45157e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 45167e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 45175d018ad057347995e5c4564b3e43339e6497f839Sumant Patro tasklet_kill(&instance->isr_tasklet); 4518c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4519c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4520c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Take the instance off the instance array. Note that we will not 4521c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * decrement the max_index. We let this array be sparse array 4522c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4523c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < megasas_mgmt_info.max_index; i++) { 4524c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_mgmt_info.instance[i] == instance) { 4525c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.count--; 4526c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.instance[i] = NULL; 4527c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4528c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 4529c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4530c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4531c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4532c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_set_drvdata(instance->pdev, NULL); 4533c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4534b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro instance->instancet->disable_intr(instance->reg_set); 4535c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4536c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) 4537c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford for (i = 0 ; i < instance->msix_vectors; i++) 4538c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford free_irq(instance->msixentry[i].vector, 4539c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford &instance->irq_context[i]); 4540c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford else 4541c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford free_irq(instance->pdev->irq, &instance->irq_context[0]); 4542c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) 454380d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford pci_disable_msix(instance->pdev); 4544c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 45459c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford switch (instance->pdev->device) { 45469c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford case PCI_DEVICE_ID_LSI_FUSION: 454736807e6799dcd8f961137b74c7edce10c6fcb1d2Adam Radford case PCI_DEVICE_ID_LSI_INVADER: 45489c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_release_fusion(instance); 45499c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford for (i = 0; i < 2 ; i++) 45509c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (fusion->ld_map[i]) 45519c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford dma_free_coherent(&instance->pdev->dev, 45529c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->map_sz, 45539c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->ld_map[i], 45549c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion-> 45559c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford ld_map_phys[i]); 45569c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford kfree(instance->ctrl_context); 45579c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 45589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford default: 45599c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_release_mfi(instance); 45609c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_free_consistent(pdev, 45619c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford sizeof(struct megasas_evt_detail), 45629c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->evt_detail, 45639c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->evt_detail_h); 45649c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_free_consistent(pdev, sizeof(u32), 45659c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->producer, 45669c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->producer_h); 45679c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_free_consistent(pdev, sizeof(u32), 45689c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->consumer, 45699c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->consumer_h); 45709c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 45719c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 4572c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4573c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scsi_host_put(host); 4574c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4575c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_set_drvdata(pdev, NULL); 4576c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4577c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_disable_device(pdev); 4578c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4579c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 4580c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4581c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4582c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4583c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_shutdown - Shutdown entry point 4584c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @device: Generic device structure 4585c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4586c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_shutdown(struct pci_dev *pdev) 4587c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4588c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford int i; 4589c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance = pci_get_drvdata(pdev); 4590c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford 45910c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo instance->unload = 1; 4592c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_flush_cache(instance); 4593530e6fc1e05f14762aea954ca8d6422c5a7077c1Yang, Bo megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); 459446fd256e05581e4a04d5a8ec107d35afe938c65bAdam Radford instance->instancet->disable_intr(instance->reg_set); 4595c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) 4596c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford for (i = 0 ; i < instance->msix_vectors; i++) 4597c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford free_irq(instance->msixentry[i].vector, 4598c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford &instance->irq_context[i]); 4599c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford else 4600c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford free_irq(instance->pdev->irq, &instance->irq_context[0]); 4601c8e858fe72230dd2ad07abcbec7c9f201672a8b4Adam Radford if (instance->msix_vectors) 460246fd256e05581e4a04d5a8ec107d35afe938c65bAdam Radford pci_disable_msix(instance->pdev); 4603c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4604c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4605c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4606c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_open - char node "open" entry point 4607c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4608c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_open(struct inode *inode, struct file *filep) 4609c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4610c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4611c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Allow only those users with admin rights 4612c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4613c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!capable(CAP_SYS_ADMIN)) 4614c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EACCES; 4615c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4616c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 4617c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4618c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4619c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4620c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_fasync - Async notifier registration from applications 4621c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 4622c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function adds the calling process to a driver global queue. When an 4623c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * event occurs, SIGIO will be sent to all processes in this queue. 4624c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4625c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_fasync(int fd, struct file *filep, int mode) 4626c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4627c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int rc; 4628c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 46290b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_lock(&megasas_async_queue_mutex); 4630c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4631c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas rc = fasync_helper(fd, filep, mode, &megasas_async_queue); 4632c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 46330b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_unlock(&megasas_async_queue_mutex); 4634c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4635c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (rc >= 0) { 4636c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* For sanity check when we get ioctl */ 4637c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas filep->private_data = filep; 4638c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 4639c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4640c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4641c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc); 4642c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4643c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return rc; 4644c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4645c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4646c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4647c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo * megasas_mgmt_poll - char node "poll" entry point 4648c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo * */ 4649c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bostatic unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait) 4650c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo{ 4651c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo unsigned int mask; 4652c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo unsigned long flags; 4653c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo poll_wait(file, &megasas_poll_wait, wait); 4654c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_lock_irqsave(&poll_aen_lock, flags); 4655c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo if (megasas_poll_wait_aen) 4656c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo mask = (POLLIN | POLLRDNORM); 4657c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo else 4658c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo mask = 0; 4659c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_unlock_irqrestore(&poll_aen_lock, flags); 4660c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo return mask; 4661c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo} 4662c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo 4663c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo/** 4664c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_fw_ioctl - Issues management ioctls to FW 4665c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 4666c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @argp: User's ioctl packet 4667c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4668c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 4669c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_mgmt_fw_ioctl(struct megasas_instance *instance, 4670c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_iocpacket __user * user_ioc, 4671c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_iocpacket *ioc) 4672c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4673c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_sge32 *kern_sge32; 4674c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 4675c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas void *kbuff_arr[MAX_IOCTL_SGE]; 4676c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dma_addr_t buf_handle = 0; 4677c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int error = 0, i; 4678c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas void *sense = NULL; 4679c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dma_addr_t sense_handle; 46807b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo unsigned long *sense_ptr; 4681c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4682c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(kbuff_arr, 0, sizeof(kbuff_arr)); 4683c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4684c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ioc->sge_count > MAX_IOCTL_SGE) { 4685c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: SGE count [%d] > max limit [%d]\n", 4686c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ioc->sge_count, MAX_IOCTL_SGE); 4687c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EINVAL; 4688c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4689c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4690c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 4691c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) { 4692c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to get a cmd packet\n"); 4693c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 4694c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4695c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4696c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4697c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * User's IOCTL packet has 2 frames (maximum). Copy those two 4698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * frames into our cmd's frames. cmd->frame's context will get 4699c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * overwritten when we copy from user's frames. So set that value 4700c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * alone separately 4701c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4702c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE); 4703c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->frame->hdr.context = cmd->index; 4704c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo cmd->frame->hdr.pad_0 = 0; 4705882be7c3be72f6d72ae7a81e707154287ea5d289Adam Radford cmd->frame->hdr.flags &= ~(MFI_FRAME_IEEE | MFI_FRAME_SGL64 | 4706882be7c3be72f6d72ae7a81e707154287ea5d289Adam Radford MFI_FRAME_SENSE64); 4707c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4708c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4709c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * The management interface between applications and the fw uses 4710c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * MFI frames. E.g, RAID configuration changes, LD property changes 4711c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * etc are accomplishes through different kinds of MFI frames. The 4712c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * driver needs to care only about substituting user buffers with 4713c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * kernel buffers in SGLs. The location of SGL is embedded in the 4714c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * struct iocpacket itself. 4715c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4716c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kern_sge32 = (struct megasas_sge32 *) 4717c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((unsigned long)cmd->frame + ioc->sgl_off); 4718c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4719c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4720c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * For each user buffer, create a mirror buffer and copy in 4721c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4722c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < ioc->sge_count; i++) { 472398cb7e4413d189cd2b54daf993a4667d9788c0bbBjørn Mork if (!ioc->sgl[i].iov_len) 472498cb7e4413d189cd2b54daf993a4667d9788c0bbBjørn Mork continue; 472598cb7e4413d189cd2b54daf993a4667d9788c0bbBjørn Mork 47269f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev, 4727c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ioc->sgl[i].iov_len, 47289f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro &buf_handle, GFP_KERNEL); 4729c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!kbuff_arr[i]) { 4730c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to alloc " 4731c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "kernel SGL buffer for IOCTL \n"); 4732c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -ENOMEM; 4733c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out; 4734c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4735c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4736c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4737c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * We don't change the dma_coherent_mask, so 4738c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * pci_alloc_consistent only returns 32bit addresses 4739c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4740c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kern_sge32[i].phys_addr = (u32) buf_handle; 4741c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kern_sge32[i].length = ioc->sgl[i].iov_len; 4742c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4743c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4744c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * We created a kernel buffer corresponding to the 4745c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * user buffer. Now copy in from the user buffer 4746c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4747c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base, 4748c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas (u32) (ioc->sgl[i].iov_len))) { 4749c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -EFAULT; 4750c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out; 4751c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4752c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4753c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4754c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ioc->sense_len) { 47559f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len, 47569f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro &sense_handle, GFP_KERNEL); 4757c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!sense) { 4758c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -ENOMEM; 4759c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out; 4760c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4761c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4762c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sense_ptr = 47637b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off); 4764c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *sense_ptr = sense_handle; 4765c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4766c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4767c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4768c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Set the sync_cmd flag so that the ISR knows not to complete this 4769c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * cmd to the SCSI mid-layer 4770c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4771c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sync_cmd = 1; 4772c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_issue_blocked_cmd(instance, cmd); 4773c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sync_cmd = 0; 4774c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4775c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4776c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * copy out the kernel buffers to user buffers 4777c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4778c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < ioc->sge_count; i++) { 4779c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i], 4780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ioc->sgl[i].iov_len)) { 4781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -EFAULT; 4782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out; 4783c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4784c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4785c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4786c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4787c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * copy out the sense 4788c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4789c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ioc->sense_len) { 4790c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4791b70a41e077b3405d4b41d34db31b39c05bf142b5bo yang * sense_ptr points to the location that has the user 4792c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * sense buffer address 4793c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 47947b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw + 47957b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo ioc->sense_off); 4796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4797b70a41e077b3405d4b41d34db31b39c05bf142b5bo yang if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), 4798b70a41e077b3405d4b41d34db31b39c05bf142b5bo yang sense, ioc->sense_len)) { 4799b10c36a57552f03582c0ab3ece04f3cce791922dbo yang printk(KERN_ERR "megasas: Failed to copy out to user " 4800b10c36a57552f03582c0ab3ece04f3cce791922dbo yang "sense data\n"); 4801c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -EFAULT; 4802c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out; 4803c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4804c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4805c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4806c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4807c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * copy the status codes returned by the fw 4808c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4809c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_to_user(&user_ioc->frame.hdr.cmd_status, 4810c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &cmd->frame->hdr.cmd_status, sizeof(u8))) { 4811c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Error copying out cmd_status\n"); 4812c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -EFAULT; 4813c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4814c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4815c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas out: 4816c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (sense) { 48179f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro dma_free_coherent(&instance->pdev->dev, ioc->sense_len, 4818c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sense, sense_handle); 4819c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4820c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4821c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) { 48229f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro dma_free_coherent(&instance->pdev->dev, 4823c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kern_sge32[i].length, 4824c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kbuff_arr[i], kern_sge32[i].phys_addr); 4825c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4826c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4827c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 4828c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return error; 4829c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4830c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4831c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg) 4832c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4833c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_iocpacket __user *user_ioc = 4834c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas (struct megasas_iocpacket __user *)arg; 4835c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_iocpacket *ioc; 4836c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 4837c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int error; 483839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang int i; 483939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 484039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 wait_time = MEGASAS_RESET_WAIT_TIME; 4841c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4842c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ioc = kmalloc(sizeof(*ioc), GFP_KERNEL); 4843c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!ioc) 4844c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 4845c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4846c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_from_user(ioc, user_ioc, sizeof(*ioc))) { 4847c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -EFAULT; 4848c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out_kfree_ioc; 4849c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4850c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4851c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = megasas_lookup_instance(ioc->host_no); 4852c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance) { 4853c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -ENODEV; 4854c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out_kfree_ioc; 4855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4856c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 485739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { 485839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_ERR "Controller in crit error\n"); 48590c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo error = -ENODEV; 48600c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo goto out_kfree_ioc; 48610c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } 48620c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo 48630c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo if (instance->unload == 1) { 48640c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo error = -ENODEV; 48650c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo goto out_kfree_ioc; 48660c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } 48670c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo 4868c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4869c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds 4870c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4871c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (down_interruptible(&instance->ioctl_sem)) { 4872c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -ERESTARTSYS; 4873c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out_kfree_ioc; 4874c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 487539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 487639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < wait_time; i++) { 487739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 487839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 487939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) { 488039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 488139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang break; 488239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 488339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 488439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 488539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { 488639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: waiting" 488739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "for controller reset to finish\n"); 488839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 488939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 489039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 489139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 489239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 489339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 489439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) { 489539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 489639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 489739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_ERR "megaraid_sas: timed out while" 489839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "waiting for HBA to recover\n"); 489939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang error = -ENODEV; 490039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang goto out_kfree_ioc; 490139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 490239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 490339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 4904c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc); 4905c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas up(&instance->ioctl_sem); 4906c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4907c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas out_kfree_ioc: 4908c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(ioc); 4909c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return error; 4910c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4911c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4912c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg) 4913c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4914c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 4915c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_aen aen; 4916c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int error; 491739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang int i; 491839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 491939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 wait_time = MEGASAS_RESET_WAIT_TIME; 4920c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4921c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (file->private_data != file) { 4922c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: fasync_helper was not " 4923c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "called first\n"); 4924c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EINVAL; 4925c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4926c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4927c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_from_user(&aen, (void __user *)arg, sizeof(aen))) 4928c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EFAULT; 4929c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4930c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = megasas_lookup_instance(aen.host_no); 4931c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4932c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance) 4933c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENODEV; 4934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 493539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { 493639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return -ENODEV; 49370c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } 49380c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo 49390c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo if (instance->unload == 1) { 49400c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo return -ENODEV; 49410c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } 49420c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo 494339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < wait_time; i++) { 494439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 494539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 494639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) { 494739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, 494839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang flags); 494939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang break; 495039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 495139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 495239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 495339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 495439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { 495539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: waiting for" 495639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "controller reset to finish\n"); 495739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 495839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 495939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 496039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 496139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 496239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 496339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) { 496439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 496539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_ERR "megaraid_sas: timed out while waiting" 496639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "for HBA to recover.\n"); 496739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return -ENODEV; 496839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 496939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 497039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 4971e5a69e27cc193f98c9a5a9086e3bf85528170623Matthias Kaehlcke mutex_lock(&instance->aen_mutex); 4972c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = megasas_register_aen(instance, aen.seq_num, 4973c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas aen.class_locale_word); 4974e5a69e27cc193f98c9a5a9086e3bf85528170623Matthias Kaehlcke mutex_unlock(&instance->aen_mutex); 4975c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return error; 4976c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4977c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4978c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4979c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_ioctl - char node ioctl entry point 4980c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4981c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic long 4982c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 4983c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4984c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas switch (cmd) { 4985c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MEGASAS_IOC_FIRMWARE: 4986c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return megasas_mgmt_ioctl_fw(file, arg); 4987c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4988c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MEGASAS_IOC_GET_AEN: 4989c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return megasas_mgmt_ioctl_aen(file, arg); 4990c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4991c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4992c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOTTY; 4993c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4994c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4995c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#ifdef CONFIG_COMPAT 4996c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) 4997c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4998c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct compat_megasas_iocpacket __user *cioc = 4999c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas (struct compat_megasas_iocpacket __user *)arg; 5000c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_iocpacket __user *ioc = 5001c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas compat_alloc_user_space(sizeof(struct megasas_iocpacket)); 5002c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 5003c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int error = 0; 5004b3dc1a212e5167984616445990c76056034f8eebTomas Henzl compat_uptr_t ptr; 5005c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 500683aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik if (clear_user(ioc, sizeof(*ioc))) 500783aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik return -EFAULT; 5008c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5009c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) || 5010c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) || 5011c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) || 5012c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) || 5013c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) || 5014c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32))) 5015c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EFAULT; 5016c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5017b3dc1a212e5167984616445990c76056034f8eebTomas Henzl /* 5018b3dc1a212e5167984616445990c76056034f8eebTomas Henzl * The sense_ptr is used in megasas_mgmt_fw_ioctl only when 5019b3dc1a212e5167984616445990c76056034f8eebTomas Henzl * sense_len is not null, so prepare the 64bit value under 5020b3dc1a212e5167984616445990c76056034f8eebTomas Henzl * the same condition. 5021b3dc1a212e5167984616445990c76056034f8eebTomas Henzl */ 5022b3dc1a212e5167984616445990c76056034f8eebTomas Henzl if (ioc->sense_len) { 5023b3dc1a212e5167984616445990c76056034f8eebTomas Henzl void __user **sense_ioc_ptr = 5024b3dc1a212e5167984616445990c76056034f8eebTomas Henzl (void __user **)(ioc->frame.raw + ioc->sense_off); 5025b3dc1a212e5167984616445990c76056034f8eebTomas Henzl compat_uptr_t *sense_cioc_ptr = 5026b3dc1a212e5167984616445990c76056034f8eebTomas Henzl (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off); 5027b3dc1a212e5167984616445990c76056034f8eebTomas Henzl if (get_user(ptr, sense_cioc_ptr) || 5028b3dc1a212e5167984616445990c76056034f8eebTomas Henzl put_user(compat_ptr(ptr), sense_ioc_ptr)) 5029b3dc1a212e5167984616445990c76056034f8eebTomas Henzl return -EFAULT; 5030b3dc1a212e5167984616445990c76056034f8eebTomas Henzl } 5031c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5032b3dc1a212e5167984616445990c76056034f8eebTomas Henzl for (i = 0; i < MAX_IOCTL_SGE; i++) { 5033c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (get_user(ptr, &cioc->sgl[i].iov_base) || 5034c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) || 5035c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(&ioc->sgl[i].iov_len, 5036c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &cioc->sgl[i].iov_len, sizeof(compat_size_t))) 5037c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EFAULT; 5038c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 5039c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5040c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc); 5041c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5042c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_in_user(&cioc->frame.hdr.cmd_status, 5043c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &ioc->frame.hdr.cmd_status, sizeof(u8))) { 5044c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n"); 5045c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EFAULT; 5046c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 5047c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return error; 5048c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 5049c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5050c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic long 5051c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd, 5052c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas unsigned long arg) 5053c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 5054c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas switch (cmd) { 5055cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case MEGASAS_IOC_FIRMWARE32: 5056cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return megasas_mgmt_compat_ioctl_fw(file, arg); 5057c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MEGASAS_IOC_GET_AEN: 5058c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return megasas_mgmt_ioctl_aen(file, arg); 5059c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 5060c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5061c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOTTY; 5062c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 5063c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#endif 5064c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5065c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/* 5066c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * File operations structure for management interface 5067c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 506800977a59b951207d38380c75f03a36829950265cArjan van de Venstatic const struct file_operations megasas_mgmt_fops = { 5069c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .owner = THIS_MODULE, 5070c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .open = megasas_mgmt_open, 5071c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .fasync = megasas_mgmt_fasync, 5072c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .unlocked_ioctl = megasas_mgmt_ioctl, 5073c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo .poll = megasas_mgmt_poll, 5074c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#ifdef CONFIG_COMPAT 5075c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .compat_ioctl = megasas_mgmt_compat_ioctl, 5076c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#endif 50776038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = noop_llseek, 5078c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}; 5079c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5080c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/* 5081c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI hotplug support registration structure 5082c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5083c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct pci_driver megasas_pci_driver = { 5084c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5085c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .name = "megaraid_sas", 5086c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .id_table = megasas_pci_table, 5087c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .probe = megasas_probe_one, 5088c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .remove = __devexit_p(megasas_detach_one), 508931ea7088974c2405e19d72f17c2afb103ef19e02bo yang .suspend = megasas_suspend, 509031ea7088974c2405e19d72f17c2afb103ef19e02bo yang .resume = megasas_resume, 5091c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .shutdown = megasas_shutdown, 5092c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}; 5093c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5094c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/* 5095c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Sysfs driver attributes 5096c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5097c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf) 5098c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 5099c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n", 5100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas MEGASAS_VERSION); 5101c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 5102c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5103c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL); 5104c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5105c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic ssize_t 5106c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_sysfs_show_release_date(struct device_driver *dd, char *buf) 5107c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 5108c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n", 5109c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas MEGASAS_RELDATE); 5110c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 5111c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5112c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date, 5113c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas NULL); 5114c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5115658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patrostatic ssize_t 511672c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bomegasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf) 511772c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo{ 511872c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo return sprintf(buf, "%u\n", support_poll_for_event); 511972c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo} 512072c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 512172c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bostatic DRIVER_ATTR(support_poll_for_event, S_IRUGO, 512272c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo megasas_sysfs_show_support_poll_for_event, NULL); 512372c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 5124837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo static ssize_t 5125837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bomegasas_sysfs_show_support_device_change(struct device_driver *dd, char *buf) 5126837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo{ 5127837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo return sprintf(buf, "%u\n", support_device_change); 5128837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo} 5129837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo 5130837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bostatic DRIVER_ATTR(support_device_change, S_IRUGO, 5131837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo megasas_sysfs_show_support_device_change, NULL); 5132837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo 513372c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bostatic ssize_t 5134658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patromegasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf) 5135658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro{ 5136ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang return sprintf(buf, "%u\n", megasas_dbg_lvl); 5137658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro} 5138658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 5139658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patrostatic ssize_t 5140658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patromegasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count) 5141658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro{ 5142658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro int retval = count; 5143658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){ 5144658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas: could not set dbg_lvl\n"); 5145658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro retval = -EINVAL; 5146658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 5147658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro return retval; 5148658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro} 5149658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 515066dca9b8c50b5e59d3bea8b21cee5c6dae6c9c46Joe Malickistatic DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl, 5151ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang megasas_sysfs_set_dbg_lvl); 5152ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 51537e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bostatic void 51547e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bomegasas_aen_polling(struct work_struct *work) 51557e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo{ 51567e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct megasas_aen_event *ev = 51577e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo container_of(work, struct megasas_aen_event, hotplug_work); 51587e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct megasas_instance *instance = ev->instance; 51597e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo union megasas_evt_class_locale class_locale; 51607e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct Scsi_Host *host; 51617e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct scsi_device *sdev1; 51627e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo u16 pd_index = 0; 5163c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo u16 ld_index = 0; 51647e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo int i, j, doscan = 0; 51657e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo u32 seq_num; 51667e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo int error; 51677e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 51687e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (!instance) { 51697e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo printk(KERN_ERR "invalid instance!\n"); 51707e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo kfree(ev); 51717e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo return; 51727e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 51737e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo instance->ev = NULL; 51747e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo host = instance->host; 51757e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (instance->evt_detail) { 51767e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 51777e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo switch (instance->evt_detail->code) { 51787e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo case MR_EVT_PD_INSERTED: 5179c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (megasas_get_pd_list(instance) == 0) { 5180c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { 5181c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (j = 0; 5182c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j < MEGASAS_MAX_DEV_PER_CHANNEL; 5183c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j++) { 5184c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5185c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo pd_index = 5186c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; 5187c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5188c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo sdev1 = 5189c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_lookup(host, i, j, 0); 5190c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5191c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (instance->pd_list[pd_index].driveState 5192c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo == MR_PD_STATE_SYSTEM) { 5193c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (!sdev1) { 5194c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_add_device(host, i, j, 0); 5195c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5196c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5197c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) 5198c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5199c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5200c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5201c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5202c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5203c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo doscan = 0; 5204c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo break; 5205c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 52067e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo case MR_EVT_PD_REMOVED: 5207c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (megasas_get_pd_list(instance) == 0) { 5208c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo megasas_get_pd_list(instance); 5209c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { 5210c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (j = 0; 5211c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j < MEGASAS_MAX_DEV_PER_CHANNEL; 5212c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j++) { 5213c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5214c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo pd_index = 5215c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; 5216c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5217c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo sdev1 = 5218c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_lookup(host, i, j, 0); 5219c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5220c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (instance->pd_list[pd_index].driveState 5221c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo == MR_PD_STATE_SYSTEM) { 5222c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5223c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5224c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5225c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } else { 5226c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5227c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_remove_device(sdev1); 5228c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5229c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5230c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5231c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5232c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5233c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5234c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo doscan = 0; 5235c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo break; 5236c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5237c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo case MR_EVT_LD_OFFLINE: 52384c598b23807a3bf0e4f7e65f7934965acc47e1b9Adam Radford case MR_EVT_CFG_CLEARED: 5239c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo case MR_EVT_LD_DELETED: 5240c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo megasas_get_ld_list(instance); 5241c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { 5242c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (j = 0; 5243c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j < MEGASAS_MAX_DEV_PER_CHANNEL; 5244c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j++) { 5245c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5246c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo ld_index = 5247c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; 5248c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5249c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo sdev1 = scsi_device_lookup(host, 5250c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo i + MEGASAS_MAX_LD_CHANNELS, 5251c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j, 5252c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 0); 5253c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5254c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (instance->ld_ids[ld_index] != 0xff) { 5255c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5256c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5257c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5258c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } else { 5259c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5260c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_remove_device(sdev1); 5261c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5262c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5263c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5264c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5265c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5266c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo doscan = 0; 5267c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo break; 5268c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo case MR_EVT_LD_CREATED: 5269c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo megasas_get_ld_list(instance); 5270c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { 5271c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (j = 0; 5272c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j < MEGASAS_MAX_DEV_PER_CHANNEL; 5273c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j++) { 5274c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo ld_index = 5275c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; 5276c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5277c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo sdev1 = scsi_device_lookup(host, 5278c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo i+MEGASAS_MAX_LD_CHANNELS, 5279c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j, 0); 5280c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5281c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (instance->ld_ids[ld_index] != 5282c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 0xff) { 5283c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (!sdev1) { 5284c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_add_device(host, 5285c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo i + 2, 5286c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j, 0); 5287c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5288c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5289c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5290c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5291c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5292c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5293c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5294c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo doscan = 0; 5295c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo break; 52967e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED: 5297c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo case MR_EVT_FOREIGN_CFG_IMPORTED: 52989c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford case MR_EVT_LD_STATE_CHANGE: 52997e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo doscan = 1; 53007e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo break; 53017e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo default: 53027e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo doscan = 0; 53037e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo break; 53047e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53057e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } else { 53067e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo printk(KERN_ERR "invalid evt_detail!\n"); 53077e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo kfree(ev); 53087e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo return; 53097e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53107e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53117e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (doscan) { 53127e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo printk(KERN_INFO "scanning ...\n"); 53137e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo megasas_get_pd_list(instance); 53147e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { 53157e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) { 53167e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j; 53177e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo sdev1 = scsi_device_lookup(host, i, j, 0); 53187e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (instance->pd_list[pd_index].driveState == 53197e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo MR_PD_STATE_SYSTEM) { 53207e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (!sdev1) { 53217e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo scsi_add_device(host, i, j, 0); 53227e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53237e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (sdev1) 53247e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo scsi_device_put(sdev1); 53257e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } else { 53267e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (sdev1) { 53277e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo scsi_remove_device(sdev1); 53287e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo scsi_device_put(sdev1); 53297e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53307e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53317e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53327e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 5333c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5334c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo megasas_get_ld_list(instance); 5335c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { 5336c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) { 5337c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo ld_index = 5338c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; 5339c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5340c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo sdev1 = scsi_device_lookup(host, 5341c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo i+MEGASAS_MAX_LD_CHANNELS, j, 0); 5342c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (instance->ld_ids[ld_index] != 0xff) { 5343c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (!sdev1) { 5344c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_add_device(host, 5345c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo i+2, 5346c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j, 0); 5347c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } else { 5348c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5349c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5350c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } else { 5351c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5352c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_remove_device(sdev1); 5353c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5354c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5355c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5356c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5357c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 53587e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53597e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53607e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if ( instance->aen_cmd != NULL ) { 53617e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo kfree(ev); 53627e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo return ; 53637e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53647e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53657e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo seq_num = instance->evt_detail->seq_num + 1; 53667e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53677e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo /* Register AEN with FW for latest sequence number plus 1 */ 53687e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo class_locale.members.reserved = 0; 53697e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo class_locale.members.locale = MR_EVT_LOCALE_ALL; 53707e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo class_locale.members.class = MR_EVT_CLASS_DEBUG; 53717e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo mutex_lock(&instance->aen_mutex); 53727e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo error = megasas_register_aen(instance, seq_num, 53737e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo class_locale.word); 53747e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo mutex_unlock(&instance->aen_mutex); 53757e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53767e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (error) 53777e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo printk(KERN_ERR "register aen failed error %x\n", error); 53787e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53797e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo kfree(ev); 53807e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo} 53817e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 5382c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 5383c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_init - Driver load entry point 5384c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5385c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int __init megasas_init(void) 5386c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 5387c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int rval; 5388c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5389c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 5390c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Announce driver version and other information 5391c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5392c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, 5393c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas MEGASAS_EXT_VERSION); 5394c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 539572c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo support_poll_for_event = 2; 5396837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo support_device_change = 1; 539772c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 5398c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info)); 5399c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5400c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 5401c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Register character device node 5402c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5403c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops); 5404c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5405c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (rval < 0) { 5406c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: failed to open device node\n"); 5407c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return rval; 5408c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 5409c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5410c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_majorno = rval; 5411c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5412c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 5413c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Register ourselves as PCI hotplug module 5414c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 54154041b9cd87d97a7c73a5bf5a9305dffee2599386Michal Piotrowski rval = pci_register_driver(&megasas_pci_driver); 5416c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5417c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (rval) { 5418c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n"); 541983aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik goto err_pcidrv; 542083aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik } 542183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik 542283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik rval = driver_create_file(&megasas_pci_driver.driver, 542383aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik &driver_attr_version); 542483aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik if (rval) 542583aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik goto err_dcf_attr_ver; 542683aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik rval = driver_create_file(&megasas_pci_driver.driver, 542783aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik &driver_attr_release_date); 542883aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik if (rval) 542983aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik goto err_dcf_rel_date; 543072c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 543172c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo rval = driver_create_file(&megasas_pci_driver.driver, 543272c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo &driver_attr_support_poll_for_event); 543372c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo if (rval) 543472c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo goto err_dcf_support_poll_for_event; 543572c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 543683aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik rval = driver_create_file(&megasas_pci_driver.driver, 543783aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik &driver_attr_dbg_lvl); 543883aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik if (rval) 543983aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik goto err_dcf_dbg_lvl; 5440ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang rval = driver_create_file(&megasas_pci_driver.driver, 5441837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo &driver_attr_support_device_change); 5442837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo if (rval) 5443837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo goto err_dcf_support_device_change; 5444837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo 5445c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return rval; 5446ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 5447837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Boerr_dcf_support_device_change: 5448837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo driver_remove_file(&megasas_pci_driver.driver, 5449ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang &driver_attr_dbg_lvl); 545083aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_dcf_dbg_lvl: 545183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik driver_remove_file(&megasas_pci_driver.driver, 545272c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo &driver_attr_support_poll_for_event); 545372c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 545472c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Boerr_dcf_support_poll_for_event: 545572c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo driver_remove_file(&megasas_pci_driver.driver, 545683aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik &driver_attr_release_date); 545772c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 545883aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_dcf_rel_date: 545983aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); 546083aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_dcf_attr_ver: 546183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik pci_unregister_driver(&megasas_pci_driver); 546283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_pcidrv: 546383aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); 54640d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford return rval; 5465c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 5466c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5467c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 5468c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_exit - Driver unload entry point 5469c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5470c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void __exit megasas_exit(void) 5471c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 5472658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro driver_remove_file(&megasas_pci_driver.driver, 5473658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro &driver_attr_dbg_lvl); 547483aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik driver_remove_file(&megasas_pci_driver.driver, 5475837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo &driver_attr_support_poll_for_event); 5476837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo driver_remove_file(&megasas_pci_driver.driver, 5477837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo &driver_attr_support_device_change); 5478837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo driver_remove_file(&megasas_pci_driver.driver, 547983aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik &driver_attr_release_date); 548083aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); 5481c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5482c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_unregister_driver(&megasas_pci_driver); 5483c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); 5484c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 5485c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5486c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmodule_init(megasas_init); 5487c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmodule_exit(megasas_exit); 5488