megaraid_sas_base.c revision 25985edcedea6396277003854657b5f3cb31a628
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 2100fa2b191b4bd74e9d22ac177e3d9e8ecd3582d3Adam Radford * Version : v00.00.05.34-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> 579c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford#include "megaraid_sas_fusion.h" 58c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#include "megaraid_sas.h" 59c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 60ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang/* 61ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * poll_mode_io:1- schedule complete completion from q cmd 62ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang */ 63ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangstatic unsigned int poll_mode_io; 64ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangmodule_param_named(poll_mode_io, poll_mode_io, int, 0); 65ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangMODULE_PARM_DESC(poll_mode_io, 66ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang "Complete cmds from IO path, (default=0)"); 67ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 681fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo/* 691fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo * Number of sectors per IO command 701fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo * Will be set in megasas_init_mfi if user does not provide 711fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo */ 721fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bostatic unsigned int max_sectors; 731fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bomodule_param_named(max_sectors, max_sectors, int, 0); 741fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, BoMODULE_PARM_DESC(max_sectors, 751fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo "Maximum number of sectors per IO command"); 761fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo 7780d9da98b4034edd31f6bacdb96c7489c4460173Adam Radfordstatic int msix_disable; 7880d9da98b4034edd31f6bacdb96c7489c4460173Adam Radfordmodule_param(msix_disable, int, S_IRUGO); 7980d9da98b4034edd31f6bacdb96c7489c4460173Adam RadfordMODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0"); 8080d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford 81c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, SreenivasMODULE_LICENSE("GPL"); 82c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, SreenivasMODULE_VERSION(MEGASAS_VERSION); 833d6d174a0888fe082e87ce1d4a0f1a85044a4515Sumant PatroMODULE_AUTHOR("megaraidlinux@lsi.com"); 84f28cd7cf8f696eafe42d1632b5a306fbf784d3cdbo yangMODULE_DESCRIPTION("LSI MegaRAID SAS Driver"); 85c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 869c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint megasas_transition_to_ready(struct megasas_instance *instance); 8739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int megasas_get_pd_list(struct megasas_instance *instance); 8839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int megasas_issue_init_mfi(struct megasas_instance *instance); 8939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int megasas_register_aen(struct megasas_instance *instance, 9039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 seq_num, u32 class_locale_word); 91c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/* 92c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI ID table for all supported controllers 93c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 94c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct pci_device_id megasas_pci_table[] = { 95c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 96f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064R)}, 97f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar /* xscale IOP */ 98f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)}, 99f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar /* ppc IOP */ 100af7a5647c03c18f5ea58033710ccb23d71727e0cbo yang {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)}, 101af7a5647c03c18f5ea58033710ccb23d71727e0cbo yang /* ppc IOP */ 1026610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)}, 1036610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* gen2*/ 1046610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)}, 1056610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* gen2*/ 106879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)}, 107879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* skinny*/ 108879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)}, 109879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* skinny*/ 110f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, 111f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar /* xscale IOP, vega */ 112f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)}, 113f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar /* xscale IOP */ 1149c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FUSION)}, 1159c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford /* Fusion */ 116f3d7271c5ac9029d19fc0252a85bc045334382ccHenrik Kretzschmar {} 117c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}; 118c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 119c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, SreenivasMODULE_DEVICE_TABLE(pci, megasas_pci_table); 120c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 121c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_majorno; 122c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct megasas_mgmt_info megasas_mgmt_info; 123c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct fasync_struct *megasas_async_queue; 1240b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Venstatic DEFINE_MUTEX(megasas_async_queue_mutex); 125c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 126c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bostatic int megasas_poll_wait_aen; 127c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bostatic DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait); 12872c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bostatic u32 support_poll_for_event; 1299c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordu32 megasas_dbg_lvl; 130837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bostatic u32 support_device_change; 131658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 132c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo/* define lock for aen poll */ 133c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bospinlock_t poll_aen_lock; 134c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo 1359c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid 1367343eb6570ae3b299e7b5185b139d8335ef60e9bbo yangmegasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, 1377343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang u8 alt_status); 138ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radfordstatic u32 139ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radfordmegasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs); 140ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radfordstatic int 141ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radfordmegasas_adp_reset_gen2(struct megasas_instance *instance, 142ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford struct megasas_register_set __iomem *reg_set); 143cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordstatic irqreturn_t megasas_isr(int irq, void *devp); 144cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordstatic u32 145cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordmegasas_init_adapter_mfi(struct megasas_instance *instance); 146cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordu32 147cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordmegasas_build_and_issue_cmd(struct megasas_instance *instance, 148cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct scsi_cmnd *scmd); 149cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordstatic void megasas_complete_cmd_dpc(unsigned long instance_addr); 1509c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid 1519c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_release_fusion(struct megasas_instance *instance); 1529c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint 1539c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_ioc_init_fusion(struct megasas_instance *instance); 1549c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid 1559c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_free_cmds_fusion(struct megasas_instance *instance); 1569c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordu8 1579c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_get_map_info(struct megasas_instance *instance); 1589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint 1599c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_sync_map_info(struct megasas_instance *instance); 1609c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint 1619c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordwait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd); 1629c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid megasas_reset_reply_desc(struct megasas_instance *instance); 1639c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordu8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map, 1649c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford struct LD_LOAD_BALANCE_INFO *lbInfo); 1659c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint megasas_reset_fusion(struct Scsi_Host *shost); 1669c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid megasas_fusion_ocr_wq(struct work_struct *work); 167cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 168cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordvoid 169cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordmegasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd) 170cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford{ 171cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet->fire_cmd(instance, 172cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford cmd->frame_phys_addr, 0, instance->reg_set); 173cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford} 1747343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 175c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 176c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_get_cmd - Get a command from the free pool 177c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 178c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 179c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Returns a free command from the pool 180c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1819c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordstruct megasas_cmd *megasas_get_cmd(struct megasas_instance 182c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *instance) 183c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 184c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas unsigned long flags; 185c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd = NULL; 186c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 187c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas spin_lock_irqsave(&instance->cmd_pool_lock, flags); 188c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 189c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!list_empty(&instance->cmd_pool)) { 190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = list_entry((&instance->cmd_pool)->next, 191c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd, list); 192c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas list_del_init(&cmd->list); 193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else { 194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_ERR "megasas: Command pool empty!\n"); 195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas spin_unlock_irqrestore(&instance->cmd_pool_lock, flags); 198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return cmd; 199c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 201c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 202c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_return_cmd - Return a cmd to free command pool 203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Command packet to be returned to free command pool 205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2069c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordinline void 207c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) 208c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 209c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas unsigned long flags; 210c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 211c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas spin_lock_irqsave(&instance->cmd_pool_lock, flags); 212c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 213c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd = NULL; 2149c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford cmd->frame_count = 0; 215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas list_add_tail(&cmd->list, &instance->cmd_pool); 216c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 217c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas spin_unlock_irqrestore(&instance->cmd_pool_lock, flags); 218c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 219c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2201341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 2211341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/** 2220d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford* The following functions are defined for xscale 2231341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro* (deviceid : 1064R, PERC5) controllers 2241341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro*/ 2251341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 226c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2271341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_enable_intr_xscale - Enables interrupts 228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @regs: MFI register set 229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic inline void 2311341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_enable_intr_xscale(struct megasas_register_set __iomem * regs) 232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 23339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(0, &(regs)->outbound_intr_mask); 234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 235c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* Dummy readl to force pci flush */ 236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas readl(®s->outbound_intr_mask); 237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 239c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 240b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * megasas_disable_intr_xscale -Disables interrupt 241b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * @regs: MFI register set 242b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro */ 243b274cab779219325fd480cc696a456d1c3893bd8Sumant Patrostatic inline void 244b274cab779219325fd480cc696a456d1c3893bd8Sumant Patromegasas_disable_intr_xscale(struct megasas_register_set __iomem * regs) 245b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro{ 246b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro u32 mask = 0x1f; 247b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro writel(mask, ®s->outbound_intr_mask); 248b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro /* Dummy readl to force pci flush */ 249b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro readl(®s->outbound_intr_mask); 250b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro} 251b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro 252b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro/** 2531341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_read_fw_status_reg_xscale - returns the current FW status value 2541341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @regs: MFI register set 2551341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */ 2561341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patrostatic u32 2571341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs) 2581341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro{ 2591341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro return readl(&(regs)->outbound_msg_0); 2601341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro} 2611341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/** 2621341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_clear_interrupt_xscale - Check & clear interrupt 2631341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @regs: MFI register set 2641341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */ 2650d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic int 2661341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_clear_intr_xscale(struct megasas_register_set __iomem * regs) 2671341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro{ 2681341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro u32 status; 26939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 mfiStatus = 0; 2701341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro /* 2711341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * Check if it is our interrupt 2721341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */ 2731341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro status = readl(®s->outbound_intr_status); 2741341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 27539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (status & MFI_OB_INTR_STATUS_MASK) 27639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; 27739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (status & MFI_XSCALE_OMR0_CHANGE_INTERRUPT) 27839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; 2791341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 2801341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro /* 2811341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * Clear the interrupt by writing back the same value 2821341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */ 28339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (mfiStatus) 28439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(status, ®s->outbound_intr_status); 2851341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 28606f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo /* Dummy readl to force pci flush */ 28706f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo readl(®s->outbound_intr_status); 28806f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo 28939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return mfiStatus; 2901341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro} 2911341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 2921341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/** 2931341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * megasas_fire_cmd_xscale - Sends command to the FW 2941341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @frame_phys_addr : Physical address of cmd 2951341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @frame_count : Number of frames for the command 2961341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @regs : MFI register set 2971341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro */ 2980d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic inline void 2990c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_xscale(struct megasas_instance *instance, 3000c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo dma_addr_t frame_phys_addr, 3010c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo u32 frame_count, 3020c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo struct megasas_register_set __iomem *regs) 3031341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro{ 30439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 30539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 3061341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro writel((frame_phys_addr >> 3)|(frame_count), 3071341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro &(regs)->inbound_queue_port); 30839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 30939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 31039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 31139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 31239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_adp_reset_xscale - For controller reset 31339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 31439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 31539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 31639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_adp_reset_xscale(struct megasas_instance *instance, 31739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 31839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 31939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 i; 32039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 pcidata; 32139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(MFI_ADP_RESET, ®s->inbound_doorbell); 32239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 32339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < 3; i++) 32439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); /* sleep for 3 secs */ 32539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pcidata = 0; 32639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata); 32739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "pcidata = %x\n", pcidata); 32839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (pcidata & 0x2) { 32939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "mfi 1068 offset read=%x\n", pcidata); 33039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pcidata &= ~0x2; 33139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pci_write_config_dword(instance->pdev, 33239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang MFI_1068_PCSR_OFFSET, pcidata); 33339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 33439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < 2; i++) 33539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); /* need to wait 2 secs again */ 33639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 33739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pcidata = 0; 33839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pci_read_config_dword(instance->pdev, 33939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata); 34039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "1068 offset handshake read=%x\n", pcidata); 34139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) { 34239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "1068 offset pcidt=%x\n", pcidata); 34339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pcidata = 0; 34439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang pci_write_config_dword(instance->pdev, 34539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang MFI_1068_FW_HANDSHAKE_OFFSET, pcidata); 34639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 34739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 34839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 34939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 35039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 35139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 35239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_xscale - For controller reset check 35339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 35439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 35539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 35639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_xscale(struct megasas_instance *instance, 35739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 35839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 35939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 consumer; 36039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang consumer = *instance->consumer; 36139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 36239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((instance->adprecovery != MEGASAS_HBA_OPERATIONAL) && 36339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (*instance->consumer == MEGASAS_ADPRESET_INPROG_SIGN)) { 36439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 1; 36539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 36639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 3671341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro} 3681341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 3691341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patrostatic struct megasas_instance_template megasas_instance_template_xscale = { 3701341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 3711341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro .fire_cmd = megasas_fire_cmd_xscale, 3721341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro .enable_intr = megasas_enable_intr_xscale, 373b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro .disable_intr = megasas_disable_intr_xscale, 3741341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro .clear_intr = megasas_clear_intr_xscale, 3751341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro .read_fw_status_reg = megasas_read_fw_status_reg_xscale, 37639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .adp_reset = megasas_adp_reset_xscale, 37739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .check_reset = megasas_check_reset_xscale, 378cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .service_isr = megasas_isr, 379cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .tasklet = megasas_complete_cmd_dpc, 380cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .init_adapter = megasas_init_adapter_mfi, 381cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .build_and_issue_cmd = megasas_build_and_issue_cmd, 382cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .issue_dcmd = megasas_issue_dcmd, 3831341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro}; 3841341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 3851341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/** 3860d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford* This is the end of set of functions & definitions specific 3871341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro* to xscale (deviceid : 1064R, PERC5) controllers 3881341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro*/ 3891341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 3901341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro/** 3910d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford* The following functions are defined for ppc (deviceid : 0x60) 392f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro* controllers 393f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro*/ 394f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 395f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 396f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_enable_intr_ppc - Enables interrupts 397f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs: MFI register set 398f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 399f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patrostatic inline void 400f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patromegasas_enable_intr_ppc(struct megasas_register_set __iomem * regs) 401f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{ 402f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); 4030d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford 40439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(~0x80000000, &(regs)->outbound_intr_mask); 405f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 406f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro /* Dummy readl to force pci flush */ 407f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro readl(®s->outbound_intr_mask); 408f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro} 409f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 410f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 411b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * megasas_disable_intr_ppc - Disable interrupt 412b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro * @regs: MFI register set 413b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro */ 414b274cab779219325fd480cc696a456d1c3893bd8Sumant Patrostatic inline void 415b274cab779219325fd480cc696a456d1c3893bd8Sumant Patromegasas_disable_intr_ppc(struct megasas_register_set __iomem * regs) 416b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro{ 417b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro u32 mask = 0xFFFFFFFF; 418b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro writel(mask, ®s->outbound_intr_mask); 419b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro /* Dummy readl to force pci flush */ 420b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro readl(®s->outbound_intr_mask); 421b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro} 422b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro 423b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro/** 424f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_read_fw_status_reg_ppc - returns the current FW status value 425f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs: MFI register set 426f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 427f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patrostatic u32 428f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patromegasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs) 429f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{ 430f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro return readl(&(regs)->outbound_scratch_pad); 431f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro} 432f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 433f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 434f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_clear_interrupt_ppc - Check & clear interrupt 435f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs: MFI register set 436f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 4370d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic int 438f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patromegasas_clear_intr_ppc(struct megasas_register_set __iomem * regs) 439f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{ 440f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro u32 status; 441f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro /* 442f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * Check if it is our interrupt 443f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 444f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro status = readl(®s->outbound_intr_status); 445f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 446f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) { 44739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 448f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro } 449f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 450f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro /* 451f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * Clear the interrupt by writing back the same value 452f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 453f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro writel(status, ®s->outbound_doorbell_clear); 454f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 45506f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo /* Dummy readl to force pci flush */ 45606f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo readl(®s->outbound_doorbell_clear); 45706f579dee5dd75c2aaf8fe83d034b5470eeee2f4Yang, Bo 45839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 1; 459f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro} 460f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 461f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * megasas_fire_cmd_ppc - Sends command to the FW 462f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @frame_phys_addr : Physical address of cmd 463f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @frame_count : Number of frames for the command 464f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro * @regs : MFI register set 465f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro */ 4660d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radfordstatic inline void 4670c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_ppc(struct megasas_instance *instance, 4680c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo dma_addr_t frame_phys_addr, 4690c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo u32 frame_count, 4700c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo struct megasas_register_set __iomem *regs) 471f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro{ 47239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 47339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 4740d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford writel((frame_phys_addr | (frame_count<<1))|1, 475f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro &(regs)->inbound_queue_port); 47639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 477f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro} 478f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 47939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 48039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_adp_reset_ppc - For controller reset 48139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 48239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 48339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 48439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_adp_reset_ppc(struct megasas_instance *instance, 48539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 48639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 48739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 48839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 48939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 49039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 49139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_ppc - For controller reset check 49239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 49339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 49439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 49539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_ppc(struct megasas_instance *instance, 49639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 49739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 49839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 49939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 500f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patrostatic struct megasas_instance_template megasas_instance_template_ppc = { 5010d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford 502f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro .fire_cmd = megasas_fire_cmd_ppc, 503f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro .enable_intr = megasas_enable_intr_ppc, 504b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro .disable_intr = megasas_disable_intr_ppc, 505f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro .clear_intr = megasas_clear_intr_ppc, 506f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro .read_fw_status_reg = megasas_read_fw_status_reg_ppc, 50739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .adp_reset = megasas_adp_reset_ppc, 50839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .check_reset = megasas_check_reset_ppc, 509cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .service_isr = megasas_isr, 510cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .tasklet = megasas_complete_cmd_dpc, 511cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .init_adapter = megasas_init_adapter_mfi, 512cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .build_and_issue_cmd = megasas_build_and_issue_cmd, 513cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .issue_dcmd = megasas_issue_dcmd, 514f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro}; 515f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 516f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 517879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_enable_intr_skinny - Enables interrupts 518879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs: MFI register set 519879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 520879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic inline void 521879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_enable_intr_skinny(struct megasas_register_set __iomem *regs) 522879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{ 523879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(0xFFFFFFFF, &(regs)->outbound_intr_mask); 524879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 525879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask); 526879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 527879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* Dummy readl to force pci flush */ 528879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo readl(®s->outbound_intr_mask); 529879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo} 530879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 531879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/** 532879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_disable_intr_skinny - Disables interrupt 533879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs: MFI register set 534879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 535879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic inline void 536879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_disable_intr_skinny(struct megasas_register_set __iomem *regs) 537879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{ 538879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo u32 mask = 0xFFFFFFFF; 539879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(mask, ®s->outbound_intr_mask); 540879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* Dummy readl to force pci flush */ 541879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo readl(®s->outbound_intr_mask); 542879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo} 543879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 544879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/** 545879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_read_fw_status_reg_skinny - returns the current FW status value 546879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs: MFI register set 547879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 548879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic u32 549879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs) 550879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{ 551879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo return readl(&(regs)->outbound_scratch_pad); 552879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo} 553879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 554879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/** 555879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_clear_interrupt_skinny - Check & clear interrupt 556879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs: MFI register set 557879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 558879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic int 559879111224d0784eab623fe8130a1f4481e0e1966Yang, Bomegasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) 560879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{ 561879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo u32 status; 562ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford u32 mfiStatus = 0; 563ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford 564879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* 565879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * Check if it is our interrupt 566879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 567879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo status = readl(®s->outbound_intr_status); 568879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 569879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) { 57039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 571879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo } 572879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 573879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* 574ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford * Check if it is our interrupt 575ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford */ 576ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford if ((megasas_read_fw_status_reg_gen2(regs) & MFI_STATE_MASK) == 577ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford MFI_STATE_FAULT) { 578ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; 579ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford } else 580ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; 581ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford 582ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford /* 583879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * Clear the interrupt by writing back the same value 584879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 585879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(status, ®s->outbound_intr_status); 586879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 587879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo /* 588879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * dummy read to flush PCI 589879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 590879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo readl(®s->outbound_intr_status); 591879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 592ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford return mfiStatus; 593879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo} 594879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 595879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/** 596879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * megasas_fire_cmd_skinny - Sends command to the FW 597879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @frame_phys_addr : Physical address of cmd 598879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @frame_count : Number of frames for the command 599879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo * @regs : MFI register set 600879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo */ 601879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic inline void 6020c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_skinny(struct megasas_instance *instance, 6030c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo dma_addr_t frame_phys_addr, 6040c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo u32 frame_count, 605879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo struct megasas_register_set __iomem *regs) 606879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo{ 6070c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo unsigned long flags; 60839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 609879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(0, &(regs)->inbound_high_queue_port); 610879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel((frame_phys_addr | (frame_count<<1))|1, 611879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo &(regs)->inbound_low_queue_port); 61239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 61339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 61439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 61539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 61639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_skinny - For controller reset check 61739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 61839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 61939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 62039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_skinny(struct megasas_instance *instance, 62139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 62239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 62339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 624879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo} 625879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 626879111224d0784eab623fe8130a1f4481e0e1966Yang, Bostatic struct megasas_instance_template megasas_instance_template_skinny = { 627879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 628879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo .fire_cmd = megasas_fire_cmd_skinny, 629879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo .enable_intr = megasas_enable_intr_skinny, 630879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo .disable_intr = megasas_disable_intr_skinny, 631879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo .clear_intr = megasas_clear_intr_skinny, 632879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo .read_fw_status_reg = megasas_read_fw_status_reg_skinny, 633ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford .adp_reset = megasas_adp_reset_gen2, 63439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .check_reset = megasas_check_reset_skinny, 635cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .service_isr = megasas_isr, 636cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .tasklet = megasas_complete_cmd_dpc, 637cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .init_adapter = megasas_init_adapter_mfi, 638cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .build_and_issue_cmd = megasas_build_and_issue_cmd, 639cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .issue_dcmd = megasas_issue_dcmd, 640879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo}; 641879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 642879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo 643879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo/** 6446610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo* The following functions are defined for gen2 (deviceid : 0x78 0x79) 6456610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo* controllers 6466610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo*/ 6476610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6486610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 6496610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_enable_intr_gen2 - Enables interrupts 6506610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs: MFI register set 6516610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 6526610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic inline void 6536610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_enable_intr_gen2(struct megasas_register_set __iomem *regs) 6546610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{ 6556610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); 6566610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6576610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* write ~0x00000005 (4 & 1) to the intr mask*/ 6586610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask); 6596610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6606610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* Dummy readl to force pci flush */ 6616610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo readl(®s->outbound_intr_mask); 6626610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo} 6636610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6646610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 6656610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_disable_intr_gen2 - Disables interrupt 6666610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs: MFI register set 6676610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 6686610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic inline void 6696610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_disable_intr_gen2(struct megasas_register_set __iomem *regs) 6706610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{ 6716610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo u32 mask = 0xFFFFFFFF; 6726610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo writel(mask, ®s->outbound_intr_mask); 6736610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* Dummy readl to force pci flush */ 6746610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo readl(®s->outbound_intr_mask); 6756610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo} 6766610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6776610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 6786610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_read_fw_status_reg_gen2 - returns the current FW status value 6796610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs: MFI register set 6806610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 6816610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic u32 6826610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs) 6836610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{ 6846610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo return readl(&(regs)->outbound_scratch_pad); 6856610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo} 6866610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 6876610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 6886610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_clear_interrupt_gen2 - Check & clear interrupt 6896610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs: MFI register set 6906610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 6916610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic int 6926610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bomegasas_clear_intr_gen2(struct megasas_register_set __iomem *regs) 6936610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{ 6946610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo u32 status; 69539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 mfiStatus = 0; 6966610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* 6976610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * Check if it is our interrupt 6986610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 6996610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo status = readl(®s->outbound_intr_status); 7006610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 70139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (status & MFI_GEN2_ENABLE_INTERRUPT_MASK) { 70239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; 70339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 70439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) { 70539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; 70639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 7076610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 7086610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* 7096610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * Clear the interrupt by writing back the same value 7106610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 71139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (mfiStatus) 71239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang writel(status, ®s->outbound_doorbell_clear); 7136610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 7146610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo /* Dummy readl to force pci flush */ 7156610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo readl(®s->outbound_intr_status); 7166610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 71739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return mfiStatus; 7186610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo} 7196610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 7206610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * megasas_fire_cmd_gen2 - Sends command to the FW 7216610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @frame_phys_addr : Physical address of cmd 7226610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @frame_count : Number of frames for the command 7236610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo * @regs : MFI register set 7246610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo */ 7256610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic inline void 7260c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bomegasas_fire_cmd_gen2(struct megasas_instance *instance, 7270c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo dma_addr_t frame_phys_addr, 7280c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo u32 frame_count, 7296610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo struct megasas_register_set __iomem *regs) 7306610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo{ 73139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 73239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 7336610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo writel((frame_phys_addr | (frame_count<<1))|1, 7346610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo &(regs)->inbound_queue_port); 73539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 73639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 73739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 73839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 73939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_adp_reset_gen2 - For controller reset 74039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 74139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 74239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 74339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_adp_reset_gen2(struct megasas_instance *instance, 74439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *reg_set) 74539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 74639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 retry = 0 ; 74739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 HostDiag; 748ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford u32 *seq_offset = ®_set->seq_offset; 749ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford u32 *hostdiag_offset = ®_set->host_diag; 750ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford 751ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford if (instance->instancet == &megasas_instance_template_skinny) { 752ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford seq_offset = ®_set->fusion_seq_offset; 753ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford hostdiag_offset = ®_set->fusion_host_diag; 754ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford } 755ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford 756ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(0, seq_offset); 757ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(4, seq_offset); 758ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(0xb, seq_offset); 759ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(2, seq_offset); 760ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(7, seq_offset); 761ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel(0xd, seq_offset); 76239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 76339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 76439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 765ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford HostDiag = (u32)readl(hostdiag_offset); 76639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 76739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang while ( !( HostDiag & DIAG_WRITE_ENABLE) ) { 76839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(100); 769ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford HostDiag = (u32)readl(hostdiag_offset); 77039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n", 77139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang retry, HostDiag); 77239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 77339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (retry++ >= 100) 77439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 1; 77539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 77639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 77739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 77839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag); 77939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 780ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset); 78139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 78239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ssleep(10); 78339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 784ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford HostDiag = (u32)readl(hostdiag_offset); 78539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang while ( ( HostDiag & DIAG_RESET_ADAPTER) ) { 78639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(100); 787ebf054b00b0a6dfa81dc4472d8b19301318b7f47Adam Radford HostDiag = (u32)readl(hostdiag_offset); 78839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n", 78939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang retry, HostDiag); 79039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 79139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (retry++ >= 1000) 79239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 1; 79339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 79439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 79539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 79639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 79739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 79839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 79939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_check_reset_gen2 - For controller reset check 80039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @regs: MFI register set 80139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 80239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic int 80339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_check_reset_gen2(struct megasas_instance *instance, 80439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_register_set __iomem *regs) 80539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 806707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) { 807707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo return 1; 808707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 809707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 81039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return 0; 8116610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo} 8126610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 8136610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bostatic struct megasas_instance_template megasas_instance_template_gen2 = { 8146610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 8156610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo .fire_cmd = megasas_fire_cmd_gen2, 8166610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo .enable_intr = megasas_enable_intr_gen2, 8176610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo .disable_intr = megasas_disable_intr_gen2, 8186610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo .clear_intr = megasas_clear_intr_gen2, 8196610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo .read_fw_status_reg = megasas_read_fw_status_reg_gen2, 82039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .adp_reset = megasas_adp_reset_gen2, 82139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang .check_reset = megasas_check_reset_gen2, 822cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .service_isr = megasas_isr, 823cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .tasklet = megasas_complete_cmd_dpc, 824cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .init_adapter = megasas_init_adapter_mfi, 825cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .build_and_issue_cmd = megasas_build_and_issue_cmd, 826cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford .issue_dcmd = megasas_issue_dcmd, 8276610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo}; 8286610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo 8296610a6b354d6c3377a1e79cd1d760ffe4358245cYang, Bo/** 830f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro* This is the end of set of functions & definitions 83139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang* specific to gen2 (deviceid : 0x78, 0x79) controllers 832f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro*/ 833f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro 8349c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford/* 8359c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford * Template added for TB (Fusion) 8369c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford */ 8379c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordextern struct megasas_instance_template megasas_instance_template_fusion; 8389c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 839f9876f0b67c3f0b04ee2167602df54e7ae139ad7Sumant Patro/** 840c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_issue_polled - Issues a polling command 841c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 8420d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * @cmd: Command packet to be issued 843c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 844c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * For polling, MFI requires the cmd_status to be set to 0xFF before posting. 845c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 8469c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint 847c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd) 848c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 849c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 850c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_header *frame_hdr = &cmd->frame->hdr; 851c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 852c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas frame_hdr->cmd_status = 0xFF; 853c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE; 854c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 856c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Issue the frame using inbound queue port 857c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 8589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->instancet->issue_dcmd(instance, cmd); 859c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 860c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 861c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Wait for cmd_status to change 862c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 8639c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford return wait_and_poll(instance, cmd); 864c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 865c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 866c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 867c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds 868c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 869c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Command to be issued 870c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 871c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function waits on an event for the command to be returned from ISR. 8722a3681e56e825bce469d2ccf3c85741b5005e1f1Sumant Patro * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs 873c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Used to issue ioctl commands. 874c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 875c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 876c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_issue_blocked_cmd(struct megasas_instance *instance, 877c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd) 878c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 879c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->cmd_status = ENODATA; 880c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 8819c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->instancet->issue_dcmd(instance, cmd); 882c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 88339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang wait_event(instance->int_cmd_wait_q, cmd->cmd_status != ENODATA); 884c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 885c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 886c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 887c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 888c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 889c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd 890c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 891c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd_to_abort: Previously issued cmd to be aborted 892c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 8938e572bab39c484cdf512715f98626337f25cfc32Justin P. Mattock * MFI firmware can abort previously issued AEN command (automatic event 894c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * notification). The megasas_issue_blocked_abort_cmd() issues such abort 8952a3681e56e825bce469d2ccf3c85741b5005e1f1Sumant Patro * cmd and waits for return status. 8962a3681e56e825bce469d2ccf3c85741b5005e1f1Sumant Patro * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs 897c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 898c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 899c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_issue_blocked_abort_cmd(struct megasas_instance *instance, 900c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd_to_abort) 901c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 902c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 903c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_abort_frame *abort_fr; 904c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 905c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 906c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 907c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) 908c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -1; 909c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 910c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr = &cmd->frame->abort; 911c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 912c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 913c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Prepare and issue the abort frame 914c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 915c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->cmd = MFI_CMD_ABORT; 916c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->cmd_status = 0xFF; 917c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->flags = 0; 918c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->abort_context = cmd_to_abort->index; 919c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->abort_mfi_phys_addr_lo = cmd_to_abort->frame_phys_addr; 920c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas abort_fr->abort_mfi_phys_addr_hi = 0; 921c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 922c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sync_cmd = 1; 923c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->cmd_status = 0xFF; 924c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 9259c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->instancet->issue_dcmd(instance, cmd); 926c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 927c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 928c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Wait for this cmd to complete 929c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 93039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang wait_event(instance->abort_cmd_wait_q, cmd->cmd_status != 0xFF); 93139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->sync_cmd = 0; 932c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 933c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 935c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 936c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 937c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 938c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_make_sgl32 - Prepares 32-bit SGL 939c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 940c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp: SCSI command from the mid-layer 941c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @mfi_sgl: SGL to be filled in 942c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 943c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * If successful, this function returns the number of SG elements. Otherwise, 944c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * it returnes -1. 945c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 946858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int 947c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp, 948c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas union megasas_sgl *mfi_sgl) 949c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 950c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 951c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int sge_count; 952c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct scatterlist *os_sgl; 953c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 954155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori sge_count = scsi_dma_map(scp); 955155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori BUG_ON(sge_count < 0); 956c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 957155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori if (sge_count) { 958155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori scsi_for_each_sg(scp, os_sgl, sge_count, i) { 959155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori mfi_sgl->sge32[i].length = sg_dma_len(os_sgl); 960155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl); 961155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori } 962c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 963c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return sge_count; 964c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 965c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 966c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 967c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_make_sgl64 - Prepares 64-bit SGL 968c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 969c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp: SCSI command from the mid-layer 970c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @mfi_sgl: SGL to be filled in 971c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 972c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * If successful, this function returns the number of SG elements. Otherwise, 973c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * it returnes -1. 974c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 975858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int 976c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, 977c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas union megasas_sgl *mfi_sgl) 978c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 979c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 980c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int sge_count; 981c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct scatterlist *os_sgl; 982c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 983155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori sge_count = scsi_dma_map(scp); 984155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori BUG_ON(sge_count < 0); 985c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 986155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori if (sge_count) { 987155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori scsi_for_each_sg(scp, os_sgl, sge_count, i) { 988155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori mfi_sgl->sge64[i].length = sg_dma_len(os_sgl); 989155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl); 990155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori } 991c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 992c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return sge_count; 993c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 994c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 995f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo/** 996f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * megasas_make_sgl_skinny - Prepares IEEE SGL 997f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * @instance: Adapter soft state 998f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * @scp: SCSI command from the mid-layer 999f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * @mfi_sgl: SGL to be filled in 1000f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * 1001f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * If successful, this function returns the number of SG elements. Otherwise, 1002f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo * it returnes -1. 1003f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo */ 1004f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bostatic int 1005f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bomegasas_make_sgl_skinny(struct megasas_instance *instance, 1006f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl) 1007f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo{ 1008f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo int i; 1009f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo int sge_count; 1010f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo struct scatterlist *os_sgl; 1011f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1012f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo sge_count = scsi_dma_map(scp); 1013f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1014f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (sge_count) { 1015f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo scsi_for_each_sg(scp, os_sgl, sge_count, i) { 1016f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl); 1017f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo mfi_sgl->sge_skinny[i].phys_addr = 1018f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo sg_dma_address(os_sgl); 1019707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo mfi_sgl->sge_skinny[i].flag = 0; 1020f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 1021f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 1022f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo return sge_count; 1023f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo} 1024f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1025b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro /** 1026b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * megasas_get_frame_count - Computes the number of frames 1027d532dbe2cb71586ab520dbef732d1af54a689313bo yang * @frame_type : type of frame- io or pthru frame 1028b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * @sge_count : number of sg elements 1029b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * 1030b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * Returns the number of frames required for numnber of sge's (sge_count) 1031b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro */ 1032b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1033f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bostatic u32 megasas_get_frame_count(struct megasas_instance *instance, 1034f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo u8 sge_count, u8 frame_type) 1035b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro{ 1036b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro int num_cnt; 1037b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro int sge_bytes; 1038b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro u32 sge_sz; 1039b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro u32 frame_count=0; 1040b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1041b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : 1042b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro sizeof(struct megasas_sge32); 1043b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1044f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee) { 1045f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo sge_sz = sizeof(struct megasas_sge_skinny); 1046f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 1047f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1048b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro /* 1049d532dbe2cb71586ab520dbef732d1af54a689313bo yang * Main frame can contain 2 SGEs for 64-bit SGLs and 1050d532dbe2cb71586ab520dbef732d1af54a689313bo yang * 3 SGEs for 32-bit SGLs for ldio & 1051d532dbe2cb71586ab520dbef732d1af54a689313bo yang * 1 SGEs for 64-bit SGLs and 1052d532dbe2cb71586ab520dbef732d1af54a689313bo yang * 2 SGEs for 32-bit SGLs for pthru frame 1053d532dbe2cb71586ab520dbef732d1af54a689313bo yang */ 1054d532dbe2cb71586ab520dbef732d1af54a689313bo yang if (unlikely(frame_type == PTHRU_FRAME)) { 1055f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee == 1) { 1056f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo num_cnt = sge_count - 1; 1057f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } else if (IS_DMA64) 1058d532dbe2cb71586ab520dbef732d1af54a689313bo yang num_cnt = sge_count - 1; 1059d532dbe2cb71586ab520dbef732d1af54a689313bo yang else 1060d532dbe2cb71586ab520dbef732d1af54a689313bo yang num_cnt = sge_count - 2; 1061d532dbe2cb71586ab520dbef732d1af54a689313bo yang } else { 1062f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee == 1) { 1063f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo num_cnt = sge_count - 1; 1064f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } else if (IS_DMA64) 1065d532dbe2cb71586ab520dbef732d1af54a689313bo yang num_cnt = sge_count - 2; 1066d532dbe2cb71586ab520dbef732d1af54a689313bo yang else 1067d532dbe2cb71586ab520dbef732d1af54a689313bo yang num_cnt = sge_count - 3; 1068d532dbe2cb71586ab520dbef732d1af54a689313bo yang } 1069b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1070b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro if(num_cnt>0){ 1071b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro sge_bytes = sge_sz * num_cnt; 1072b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1073b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) + 1074b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ; 1075b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro } 1076b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro /* Main frame */ 1077b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro frame_count +=1; 1078b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1079b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro if (frame_count > 7) 1080b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro frame_count = 8; 1081b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro return frame_count; 1082b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro} 1083b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro 1084c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1085c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_build_dcdb - Prepares a direct cdb (DCDB) command 1086c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 1087c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp: SCSI command 1088c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Command to be prepared in 1089c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 1090c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function prepares CDB commands. These are typcially pass-through 1091c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * commands to the devices. 1092c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1093858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int 1094c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, 1095c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd) 1096c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1097c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 is_logical; 1098c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 device_id; 1099c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u16 flags = 0; 1100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_pthru_frame *pthru; 1101c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1102c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas is_logical = MEGASAS_IS_LOGICAL(scp); 1103c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas device_id = MEGASAS_DEV_INDEX(instance, scp); 1104c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru = (struct megasas_pthru_frame *)cmd->frame; 1105c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1106c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (scp->sc_data_direction == PCI_DMA_TODEVICE) 1107c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas flags = MFI_FRAME_DIR_WRITE; 1108c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) 1109c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas flags = MFI_FRAME_DIR_READ; 1110c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->sc_data_direction == PCI_DMA_NONE) 1111c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas flags = MFI_FRAME_DIR_NONE; 1112c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1113f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee == 1) { 1114f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo flags |= MFI_FRAME_IEEE; 1115f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 1116f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1117c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1118c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Prepare the DCDB frame 1119c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1120c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO; 1121c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->cmd_status = 0x0; 1122c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->scsi_status = 0x0; 1123c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->target_id = device_id; 1124c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->lun = scp->device->lun; 1125c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->cdb_len = scp->cmd_len; 1126c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->timeout = 0; 1127780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo pthru->pad_0 = 0; 1128c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->flags = flags; 1129155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori pthru->data_xfer_len = scsi_bufflen(scp); 1130c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1131c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memcpy(pthru->cdb, scp->cmnd, scp->cmd_len); 1132c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1133c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 11348d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo * If the command is for the tape device, set the 11358d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo * pthru timeout to the os layer timeout value. 11368d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo */ 11378d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo if (scp->device->type == TYPE_TAPE) { 11388d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo if ((scp->request->timeout / HZ) > 0xFFFF) 11398d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo pthru->timeout = 0xFFFF; 11408d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo else 11418d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo pthru->timeout = scp->request->timeout / HZ; 11428d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo } 11438d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo 11448d56825321339f0ef7ad08eb58332e1836881e3bYang, Bo /* 1145c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Construct SGL 1146c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1147f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee == 1) { 1148f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo pthru->flags |= MFI_FRAME_SGL64; 1149f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo pthru->sge_count = megasas_make_sgl_skinny(instance, scp, 1150f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo &pthru->sgl); 1151f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } else if (IS_DMA64) { 1152c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->flags |= MFI_FRAME_SGL64; 1153c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->sge_count = megasas_make_sgl64(instance, scp, 1154c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &pthru->sgl); 1155c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else 1156c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->sge_count = megasas_make_sgl32(instance, scp, 1157c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &pthru->sgl); 1158c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1159bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (pthru->sge_count > instance->max_num_sge) { 1160bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo printk(KERN_ERR "megasas: DCDB two many SGE NUM=%x\n", 1161bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo pthru->sge_count); 1162bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo return 0; 1163bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 1164bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 1165c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1166c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Sense info specific 1167c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1168c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->sense_len = SCSI_SENSE_BUFFERSIZE; 1169c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->sense_buf_phys_addr_hi = 0; 1170c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; 1171c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1172c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1173c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Compute the total number of frames this command consumes. FW uses 1174c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * this number to pull sufficient number of frames from host memory. 1175c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1176f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count, 1177d532dbe2cb71586ab520dbef732d1af54a689313bo yang PTHRU_FRAME); 1178c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1179c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return cmd->frame_count; 1180c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1181c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1182c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1183c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_build_ldio - Prepares IOs to logical devices 1184c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 1185c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scp: SCSI command 1186fd589a8f0a13f53a2dd580b1fe170633cf6b095fAnand Gadiyar * @cmd: Command to be prepared 1187c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 1188c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Frames (and accompanying SGLs) for regular SCSI IOs use this function. 1189c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1190858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int 1191c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, 1192c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd) 1193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 device_id; 1195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u8 sc = scp->cmnd[0]; 1196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u16 flags = 0; 1197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_io_frame *ldio; 1198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1199c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas device_id = MEGASAS_DEV_INDEX(instance, scp); 1200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio = (struct megasas_io_frame *)cmd->frame; 1201c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1202c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (scp->sc_data_direction == PCI_DMA_TODEVICE) 1203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas flags = MFI_FRAME_DIR_WRITE; 1204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) 1205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas flags = MFI_FRAME_DIR_READ; 1206c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1207f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee == 1) { 1208f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo flags |= MFI_FRAME_IEEE; 1209f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 1210f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 1211c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1212b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * Prepare the Logical IO frame: 2nd bit is zero for all read cmds 1213c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1214c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ; 1215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->cmd_status = 0x0; 1216c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->scsi_status = 0x0; 1217c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->target_id = device_id; 1218c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->timeout = 0; 1219c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->reserved_0 = 0; 1220c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->pad_0 = 0; 1221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->flags = flags; 1222c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_hi = 0; 1223c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->access_byte = (scp->cmd_len != 6) ? scp->cmnd[1] : 0; 1224c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1225c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1226c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 6-byte READ(0x08) or WRITE(0x0A) cdb 1227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (scp->cmd_len == 6) { 1229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->lba_count = (u32) scp->cmnd[4]; 1230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_lo = ((u32) scp->cmnd[1] << 16) | 1231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3]; 1232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_lo &= 0x1FFFFF; 1234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1235c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 10-byte READ(0x28) or WRITE(0x2A) cdb 1238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1239c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->cmd_len == 10) { 1240c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->lba_count = (u32) scp->cmnd[8] | 1241c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[7] << 8); 1242c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) | 1243c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[3] << 16) | 1244c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5]; 1245c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1246c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1247c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1248c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 12-byte READ(0xA8) or WRITE(0xAA) cdb 1249c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1250c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->cmd_len == 12) { 1251c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->lba_count = ((u32) scp->cmnd[6] << 24) | 1252c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[7] << 16) | 1253c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9]; 1254c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1255c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) | 1256c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[3] << 16) | 1257c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5]; 1258c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1259c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1260c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1261c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 16-byte READ(0x88) or WRITE(0x8A) cdb 1262c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1263c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else if (scp->cmd_len == 16) { 1264c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->lba_count = ((u32) scp->cmnd[10] << 24) | 1265c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[11] << 16) | 1266c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13]; 1267c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1268c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_lo = ((u32) scp->cmnd[6] << 24) | 1269c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[7] << 16) | 1270c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9]; 1271c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1272c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->start_lba_hi = ((u32) scp->cmnd[2] << 24) | 1273c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[3] << 16) | 1274c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5]; 1275c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1276c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1277c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1278c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1279c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Construct SGL 1280c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1281f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee) { 1282f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo ldio->flags |= MFI_FRAME_SGL64; 1283f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo ldio->sge_count = megasas_make_sgl_skinny(instance, scp, 1284f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo &ldio->sgl); 1285f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } else if (IS_DMA64) { 1286c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->flags |= MFI_FRAME_SGL64; 1287c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl); 1288c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else 1289c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl); 1290c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1291bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (ldio->sge_count > instance->max_num_sge) { 1292bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo printk(KERN_ERR "megasas: build_ld_io: sge_count = %x\n", 1293bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ldio->sge_count); 1294bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo return 0; 1295bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 1296bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 1297c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1298c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Sense info specific 1299c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1300c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->sense_len = SCSI_SENSE_BUFFERSIZE; 1301c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->sense_buf_phys_addr_hi = 0; 1302c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr; 1303c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1304b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro /* 1305b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * Compute the total number of frames this command consumes. FW uses 1306b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro * this number to pull sufficient number of frames from host memory. 1307b1df99d9434edf3fc26f9e36ee6a443e3611e829Sumant Patro */ 1308f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo cmd->frame_count = megasas_get_frame_count(instance, 1309f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo ldio->sge_count, IO_FRAME); 1310c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1311c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return cmd->frame_count; 1312c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1313c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1314c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1315cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro * megasas_is_ldio - Checks if the cmd is for logical drive 1316cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro * @scmd: SCSI command 13170d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * 1318cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro * Called by megasas_queue_command to find out if the command to be queued 13190d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * is a logical drive command 1320c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 13219c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordinline int megasas_is_ldio(struct scsi_cmnd *cmd) 1322c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1323cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro if (!MEGASAS_IS_LOGICAL(cmd)) 1324cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return 0; 1325cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro switch (cmd->cmnd[0]) { 1326cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case READ_10: 1327cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case WRITE_10: 1328cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case READ_12: 1329cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case WRITE_12: 1330cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case READ_6: 1331cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case WRITE_6: 1332cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case READ_16: 1333cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case WRITE_16: 1334cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return 1; 1335cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro default: 1336cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return 0; 1337c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1338c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1339c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1340658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro /** 1341658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro * megasas_dump_pending_frames - Dumps the frame address of all pending cmds 1342658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro * in FW 1343658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro * @instance: Adapter soft state 1344658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro */ 1345658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patrostatic inline void 1346658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patromegasas_dump_pending_frames(struct megasas_instance *instance) 1347658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro{ 1348658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro struct megasas_cmd *cmd; 1349658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro int i,n; 1350658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro union megasas_sgl *mfi_sgl; 1351658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro struct megasas_io_frame *ldio; 1352658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro struct megasas_pthru_frame *pthru; 1353658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro u32 sgcount; 1354658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro u32 max_cmd = instance->max_fw_cmds; 1355658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 1356658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no); 1357658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding)); 1358658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if (IS_DMA64) 1359658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no); 1360658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro else 1361658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no); 1362658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 1363658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no); 1364658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro for (i = 0; i < max_cmd; i++) { 1365658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro cmd = instance->cmd_list[i]; 1366658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if(!cmd->scmd) 1367658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro continue; 1368658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr); 1369658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if (megasas_is_ldio(cmd->scmd)){ 1370658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro ldio = (struct megasas_io_frame *)cmd->frame; 1371658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro mfi_sgl = &ldio->sgl; 1372658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro sgcount = ldio->sge_count; 1373658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant 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); 1374658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1375658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro else { 1376658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro pthru = (struct megasas_pthru_frame *) cmd->frame; 1377658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro mfi_sgl = &pthru->sgl; 1378658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro sgcount = pthru->sge_count; 1379658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant 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); 1380658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1381658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if(megasas_dbg_lvl & MEGASAS_DBG_LVL){ 1382658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro for (n = 0; n < sgcount; n++){ 1383658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if (IS_DMA64) 1384658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant 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) ; 1385658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro else 1386658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",mfi_sgl->sge32[n].length , mfi_sgl->sge32[n].phys_addr) ; 1387658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1388658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1389658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "\n"); 1390658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } /*for max_cmd*/ 1391658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no); 1392658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro for (i = 0; i < max_cmd; i++) { 1393658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 1394658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro cmd = instance->cmd_list[i]; 1395658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 1396658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if(cmd->sync_cmd == 1){ 1397658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr); 1398658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1399658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 1400658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no); 1401658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro} 1402658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 1403cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordu32 1404cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordmegasas_build_and_issue_cmd(struct megasas_instance *instance, 1405cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct scsi_cmnd *scmd) 1406cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford{ 1407cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct megasas_cmd *cmd; 1408cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford u32 frame_count; 1409cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1410cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford cmd = megasas_get_cmd(instance); 1411cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (!cmd) 1412cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return SCSI_MLQUEUE_HOST_BUSY; 1413cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1414cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* 1415cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * Logical drive command 1416cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford */ 1417cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (megasas_is_ldio(scmd)) 1418cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford frame_count = megasas_build_ldio(instance, scmd, cmd); 1419cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford else 1420cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford frame_count = megasas_build_dcdb(instance, scmd, cmd); 1421cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1422cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (!frame_count) 1423cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford goto out_return_cmd; 1424cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1425cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford cmd->scmd = scmd; 1426cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford scmd->SCp.ptr = (char *)cmd; 1427cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1428cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* 1429cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * Issue the command to the FW 1430cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford */ 1431cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford atomic_inc(&instance->fw_outstanding); 1432cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1433cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet->fire_cmd(instance, cmd->frame_phys_addr, 1434cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford cmd->frame_count-1, instance->reg_set); 1435cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* 1436cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * Check if we have pend cmds to be completed 1437cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford */ 1438cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (poll_mode_io && atomic_read(&instance->fw_outstanding)) 1439cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford tasklet_schedule(&instance->isr_tasklet); 1440cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1441cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return 0; 1442cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordout_return_cmd: 1443cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford megasas_return_cmd(instance, cmd); 1444cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return 1; 1445cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford} 1446cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1447cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 1448c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1449c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_queue_command - Queue entry point 1450c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scmd: SCSI command to be queued 1451c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @done: Callback entry point 1452c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1453c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 1454f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzikmegasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) 1455c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1456c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 145739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 1458c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1459c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = (struct megasas_instance *) 1460c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scmd->device->host->hostdata; 1461af37acfb63d8e924550e67b884dbd1c478e26c96Sumant Patro 146239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->issuepend_done == 0) 1463af37acfb63d8e924550e67b884dbd1c478e26c96Sumant Patro return SCSI_MLQUEUE_HOST_BUSY; 1464af37acfb63d8e924550e67b884dbd1c478e26c96Sumant Patro 146539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 146639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) { 146739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 146839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return SCSI_MLQUEUE_HOST_BUSY; 146939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 147039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 147139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 147239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 1473c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scmd->scsi_done = done; 1474c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scmd->result = 0; 1475c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1476cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro if (MEGASAS_IS_LOGICAL(scmd) && 1477cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) { 1478cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro scmd->result = DID_BAD_TARGET << 16; 1479cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro goto out_done; 1480c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1481c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 148202b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro switch (scmd->cmnd[0]) { 148302b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro case SYNCHRONIZE_CACHE: 148402b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro /* 148502b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro * FW takes care of flush cache on its own 148602b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro * No need to send it down 148702b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro */ 148802b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro scmd->result = DID_OK << 16; 148902b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro goto out_done; 149002b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro default: 149102b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro break; 149202b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro } 149302b01e010afeeb49328d35650d70721d2ca3fd59Sumant Patro 1494cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (instance->instancet->build_and_issue_cmd(instance, scmd)) { 1495cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford printk(KERN_ERR "megasas: Err returned from build_and_issue_cmd\n"); 1496cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return SCSI_MLQUEUE_HOST_BUSY; 1497cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford } 1498c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1499c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 1500cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro 1501cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro out_done: 1502cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro done(scmd); 1503cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return 0; 1504c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1505c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1506f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzikstatic DEF_SCSI_QCMD(megasas_queue_command) 1507f281233d3eba15fb225d21ae2e228fd4553d824aJeff Garzik 1508044833b572b96afe91506a0edec42efd84ba4939Yang, Bostatic struct megasas_instance *megasas_lookup_instance(u16 host_no) 1509044833b572b96afe91506a0edec42efd84ba4939Yang, Bo{ 1510044833b572b96afe91506a0edec42efd84ba4939Yang, Bo int i; 1511044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1512044833b572b96afe91506a0edec42efd84ba4939Yang, Bo for (i = 0; i < megasas_mgmt_info.max_index; i++) { 1513044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1514044833b572b96afe91506a0edec42efd84ba4939Yang, Bo if ((megasas_mgmt_info.instance[i]) && 1515044833b572b96afe91506a0edec42efd84ba4939Yang, Bo (megasas_mgmt_info.instance[i]->host->host_no == host_no)) 1516044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return megasas_mgmt_info.instance[i]; 1517044833b572b96afe91506a0edec42efd84ba4939Yang, Bo } 1518044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1519044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return NULL; 1520044833b572b96afe91506a0edec42efd84ba4939Yang, Bo} 1521044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1522147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwigstatic int megasas_slave_configure(struct scsi_device *sdev) 1523147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig{ 1524044833b572b96afe91506a0edec42efd84ba4939Yang, Bo u16 pd_index = 0; 1525044833b572b96afe91506a0edec42efd84ba4939Yang, Bo struct megasas_instance *instance ; 1526044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1527044833b572b96afe91506a0edec42efd84ba4939Yang, Bo instance = megasas_lookup_instance(sdev->host->host_no); 1528044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1529147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig /* 1530044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * Don't export physical disk devices to the disk driver. 1531044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * 1532044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * FIXME: Currently we don't export them to the midlayer at all. 1533044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * That will be fixed once LSI engineers have audited the 1534044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * firmware for possible issues. 1535044833b572b96afe91506a0edec42efd84ba4939Yang, Bo */ 1536044833b572b96afe91506a0edec42efd84ba4939Yang, Bo if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && 1537044833b572b96afe91506a0edec42efd84ba4939Yang, Bo sdev->type == TYPE_DISK) { 1538044833b572b96afe91506a0edec42efd84ba4939Yang, Bo pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + 1539044833b572b96afe91506a0edec42efd84ba4939Yang, Bo sdev->id; 1540044833b572b96afe91506a0edec42efd84ba4939Yang, Bo if (instance->pd_list[pd_index].driveState == 1541044833b572b96afe91506a0edec42efd84ba4939Yang, Bo MR_PD_STATE_SYSTEM) { 1542044833b572b96afe91506a0edec42efd84ba4939Yang, Bo blk_queue_rq_timeout(sdev->request_queue, 1543044833b572b96afe91506a0edec42efd84ba4939Yang, Bo MEGASAS_DEFAULT_CMD_TIMEOUT * HZ); 1544044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return 0; 1545044833b572b96afe91506a0edec42efd84ba4939Yang, Bo } 1546147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig return -ENXIO; 1547044833b572b96afe91506a0edec42efd84ba4939Yang, Bo } 1548e5b3a65fd7244e662691cf617145983ecde28cc9Christoph Hellwig 1549e5b3a65fd7244e662691cf617145983ecde28cc9Christoph Hellwig /* 1550044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * The RAID firmware may require extended timeouts. 1551044833b572b96afe91506a0edec42efd84ba4939Yang, Bo */ 1552044833b572b96afe91506a0edec42efd84ba4939Yang, Bo blk_queue_rq_timeout(sdev->request_queue, 1553044833b572b96afe91506a0edec42efd84ba4939Yang, Bo MEGASAS_DEFAULT_CMD_TIMEOUT * HZ); 1554044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return 0; 1555044833b572b96afe91506a0edec42efd84ba4939Yang, Bo} 1556044833b572b96afe91506a0edec42efd84ba4939Yang, Bo 1557044833b572b96afe91506a0edec42efd84ba4939Yang, Bostatic int megasas_slave_alloc(struct scsi_device *sdev) 1558044833b572b96afe91506a0edec42efd84ba4939Yang, Bo{ 1559044833b572b96afe91506a0edec42efd84ba4939Yang, Bo u16 pd_index = 0; 1560044833b572b96afe91506a0edec42efd84ba4939Yang, Bo struct megasas_instance *instance ; 1561044833b572b96afe91506a0edec42efd84ba4939Yang, Bo instance = megasas_lookup_instance(sdev->host->host_no); 1562044833b572b96afe91506a0edec42efd84ba4939Yang, Bo if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) && 1563044833b572b96afe91506a0edec42efd84ba4939Yang, Bo (sdev->type == TYPE_DISK)) { 1564044833b572b96afe91506a0edec42efd84ba4939Yang, Bo /* 1565044833b572b96afe91506a0edec42efd84ba4939Yang, Bo * Open the OS scan to the SYSTEM PD 1566044833b572b96afe91506a0edec42efd84ba4939Yang, Bo */ 1567044833b572b96afe91506a0edec42efd84ba4939Yang, Bo pd_index = 1568044833b572b96afe91506a0edec42efd84ba4939Yang, Bo (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + 1569044833b572b96afe91506a0edec42efd84ba4939Yang, Bo sdev->id; 1570044833b572b96afe91506a0edec42efd84ba4939Yang, Bo if ((instance->pd_list[pd_index].driveState == 1571044833b572b96afe91506a0edec42efd84ba4939Yang, Bo MR_PD_STATE_SYSTEM) && 1572044833b572b96afe91506a0edec42efd84ba4939Yang, Bo (instance->pd_list[pd_index].driveType == 1573044833b572b96afe91506a0edec42efd84ba4939Yang, Bo TYPE_DISK)) { 1574044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return 0; 1575044833b572b96afe91506a0edec42efd84ba4939Yang, Bo } 1576044833b572b96afe91506a0edec42efd84ba4939Yang, Bo return -ENXIO; 1577044833b572b96afe91506a0edec42efd84ba4939Yang, Bo } 1578147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig return 0; 1579147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig} 1580147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig 15819c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid megaraid_sas_kill_hba(struct megasas_instance *instance) 158239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 158339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 15849c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 15859c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION)) { 15869c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford writel(MFI_STOP_ADP, &instance->reg_set->doorbell); 158739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else { 15889c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell); 15899c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 15909c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford} 15919c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 15929c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford /** 15939c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford * megasas_check_and_restore_queue_depth - Check if queue depth needs to be 15949c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford * restored to max value 15959c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford * @instance: Adapter soft state 15969c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford * 15979c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford */ 15989c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid 15999c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordmegasas_check_and_restore_queue_depth(struct megasas_instance *instance) 16009c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford{ 16019c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford unsigned long flags; 16029c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (instance->flag & MEGASAS_FW_BUSY 16039c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford && time_after(jiffies, instance->last_time + 5 * HZ) 16049c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford && atomic_read(&instance->fw_outstanding) < 17) { 16059c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 16069c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_lock_irqsave(instance->host->host_lock, flags); 16079c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->flag &= ~MEGASAS_FW_BUSY; 16089c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if ((instance->pdev->device == 16099c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 16109c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == 16119c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { 16129c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->host->can_queue = 16139c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS; 16149c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } else 16159c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->host->can_queue = 16169c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->max_fw_cmds - MEGASAS_INT_CMDS; 16179c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 16189c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_unlock_irqrestore(instance->host->host_lock, flags); 161939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 162039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 162139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 1622c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 16237343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * megasas_complete_cmd_dpc - Returns FW's controller structure 16247343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * @instance_addr: Address of adapter soft state 16257343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * 16267343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * Tasklet to complete cmds 16277343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang */ 16287343eb6570ae3b299e7b5185b139d8335ef60e9bbo yangstatic void megasas_complete_cmd_dpc(unsigned long instance_addr) 16297343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang{ 16307343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang u32 producer; 16317343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang u32 consumer; 16327343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang u32 context; 16337343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang struct megasas_cmd *cmd; 16347343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang struct megasas_instance *instance = 16357343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang (struct megasas_instance *)instance_addr; 16367343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang unsigned long flags; 16377343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16387343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang /* If we have already declared adapter dead, donot complete cmds */ 163939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR ) 16407343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang return; 16417343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16427343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang spin_lock_irqsave(&instance->completion_lock, flags); 16437343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16447343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang producer = *instance->producer; 16457343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang consumer = *instance->consumer; 16467343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16477343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang while (consumer != producer) { 16487343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang context = instance->reply_queue[consumer]; 164939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (context >= instance->max_fw_cmds) { 165039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_ERR "Unexpected context value %x\n", 165139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang context); 165239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang BUG(); 165339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 16547343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16557343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang cmd = instance->cmd_list[context]; 16567343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16577343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang megasas_complete_cmd(instance, cmd, DID_OK); 16587343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16597343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang consumer++; 16607343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang if (consumer == (instance->max_fw_cmds + 1)) { 16617343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang consumer = 0; 16627343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang } 16637343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang } 16647343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16657343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang *instance->consumer = producer; 16667343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16677343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang spin_unlock_irqrestore(&instance->completion_lock, flags); 16687343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 16697343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang /* 16707343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * Check if we can restore can_queue 16717343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang */ 16729c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_check_and_restore_queue_depth(instance); 16737343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang} 16747343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang 1675707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bostatic void 1676707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bomegasas_internal_reset_defer_cmds(struct megasas_instance *instance); 1677707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1678707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bostatic void 1679707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Boprocess_fw_state_change_wq(struct work_struct *work); 1680707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1681707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bovoid megasas_do_ocr(struct megasas_instance *instance) 1682707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo{ 1683707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) || 1684707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) || 1685707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) { 1686707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo *instance->consumer = MEGASAS_ADPRESET_INPROG_SIGN; 1687707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1688707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo instance->instancet->disable_intr(instance->reg_set); 1689707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; 1690707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo instance->issuepend_done = 0; 1691707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1692707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo atomic_set(&instance->fw_outstanding, 0); 1693707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo megasas_internal_reset_defer_cmds(instance); 1694707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo process_fw_state_change_wq(&instance->work_init); 1695707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo} 1696707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 16977343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang/** 1698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_wait_for_outstanding - Wait for all outstanding cmds 1699c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 1700c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 170125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * This function waits for up to MEGASAS_RESET_WAIT_TIME seconds for FW to 1702c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * complete all its outstanding commands. Returns error if one or more IOs 1703c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * are pending after this time period. It also marks the controller dead. 1704c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1705c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_wait_for_outstanding(struct megasas_instance *instance) 1706c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1707c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 170839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 reset_index; 1709c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 wait_time = MEGASAS_RESET_WAIT_TIME; 171039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u8 adprecovery; 171139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 171239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct list_head clist_local; 171339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_cmd *reset_cmd; 1714707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo u32 fw_state; 1715707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo u8 kill_adapter_flag; 171639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 171739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 171839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang adprecovery = instance->adprecovery; 171939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 172039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 172139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (adprecovery != MEGASAS_HBA_OPERATIONAL) { 172239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 172339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang INIT_LIST_HEAD(&clist_local); 172439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 172539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_splice_init(&instance->internal_reset_pending_q, 172639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang &clist_local); 172739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 172839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 172939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: HBA reset wait ...\n"); 173039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < wait_time; i++) { 173139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 173239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 173339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang adprecovery = instance->adprecovery; 173439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 173539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (adprecovery == MEGASAS_HBA_OPERATIONAL) 173639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang break; 173739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 173839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 173939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (adprecovery != MEGASAS_HBA_OPERATIONAL) { 174039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: reset: Stopping HBA.\n"); 174139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 174239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR; 174339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 174439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return FAILED; 174539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 174639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 174739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_index = 0; 174839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang while (!list_empty(&clist_local)) { 174939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd = list_entry((&clist_local)->next, 175039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_cmd, list); 175139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_del_init(&reset_cmd->list); 175239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (reset_cmd->scmd) { 175339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd->scmd->result = DID_RESET << 16; 175439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "%d:%p reset [%02x], %#lx\n", 175539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_index, reset_cmd, 175639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd->scmd->cmnd[0], 175739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd->scmd->serial_number); 175839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 175939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd->scmd->scsi_done(reset_cmd->scmd); 176039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_return_cmd(instance, reset_cmd); 176139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else if (reset_cmd->sync_cmd) { 176239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas:%p synch cmds" 176339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "reset queue\n", 176439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd); 176539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 176639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd->cmd_status = ENODATA; 176739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->fire_cmd(instance, 176839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd->frame_phys_addr, 176939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 0, instance->reg_set); 177039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else { 177139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: %p unexpected" 177239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "cmds lst\n", 177339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_cmd); 177439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 177539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang reset_index++; 177639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 177739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 177839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return SUCCESS; 177939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 1780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < wait_time; i++) { 1782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1783e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro int outstanding = atomic_read(&instance->fw_outstanding); 1784e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro 1785e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro if (!outstanding) 1786c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 1787c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1788c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { 1789c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_NOTICE "megasas: [%2d]waiting for %d " 1790e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro "commands to complete\n",i,outstanding); 17917343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang /* 17927343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * Call cmd completion routine. Cmd to be 17937343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang * be completed directly without depending on isr. 17947343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang */ 17957343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang megasas_complete_cmd_dpc((unsigned long)instance); 1796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1797c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1798c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas msleep(1000); 1799c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1800c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1801707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo i = 0; 1802707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo kill_adapter_flag = 0; 1803707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo do { 1804707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo fw_state = instance->instancet->read_fw_status_reg( 1805707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo instance->reg_set) & MFI_STATE_MASK; 1806707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if ((fw_state == MFI_STATE_FAULT) && 1807707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo (instance->disableOnlineCtrlReset == 0)) { 1808707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (i == 3) { 1809707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo kill_adapter_flag = 2; 1810707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo break; 1811707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1812707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo megasas_do_ocr(instance); 1813707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo kill_adapter_flag = 1; 1814707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1815707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo /* wait for 1 secs to let FW finish the pending cmds */ 1816707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo msleep(1000); 1817707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1818707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo i++; 1819707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } while (i <= 3); 1820707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1821707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (atomic_read(&instance->fw_outstanding) && 1822707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo !kill_adapter_flag) { 1823707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (instance->disableOnlineCtrlReset == 0) { 1824707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1825707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo megasas_do_ocr(instance); 1826707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1827707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo /* wait for 5 secs to let FW finish the pending cmds */ 1828707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo for (i = 0; i < wait_time; i++) { 1829707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo int outstanding = 1830707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo atomic_read(&instance->fw_outstanding); 1831707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (!outstanding) 1832707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo return SUCCESS; 1833707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo msleep(1000); 1834707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1835707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1836707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo } 1837707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo 1838707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo if (atomic_read(&instance->fw_outstanding) || 1839707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo (kill_adapter_flag == 2)) { 184039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n"); 1841e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro /* 1842e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * Send signal to FW to stop processing any pending cmds. 1843e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * The controller will be taken offline by the OS now. 1844e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro */ 18450c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo if ((instance->pdev->device == 18460c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 18470c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo (instance->pdev->device == 18480c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { 18490c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo writel(MFI_STOP_ADP, 18509c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->reg_set->doorbell); 18510c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } else { 18520c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo writel(MFI_STOP_ADP, 1853e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro &instance->reg_set->inbound_doorbell); 18540c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } 1855658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro megasas_dump_pending_frames(instance); 185639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 185739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR; 185839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 1859c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return FAILED; 1860c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1861c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 186239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: no pending cmds after reset\n"); 186339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 1864c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return SUCCESS; 1865c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1866c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1867c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1868c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_generic_reset - Generic reset routine 1869c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @scmd: Mid-layer SCSI command 1870c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 1871c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This routine implements a generic reset handler for device, bus and host 1872c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * reset requests. Device, bus and host specific reset handlers can use this 1873c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * function after they do their specific tasks. 1874c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1875c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_generic_reset(struct scsi_cmnd *scmd) 1876c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1877c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int ret_val; 1878c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 1879c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1880c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = (struct megasas_instance *)scmd->device->host->hostdata; 1881c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 188205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n", 188305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro scmd->serial_number, scmd->cmnd[0], scmd->retries); 1884c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 188539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { 1886c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_ERR "megasas: cannot recover from previous reset " 1887c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "failures\n"); 1888c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return FAILED; 1889c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 1890c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1891c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ret_val = megasas_wait_for_outstanding(instance); 1892c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ret_val == SUCCESS) 1893c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_NOTICE "megasas: reset successful \n"); 1894c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else 1895c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_ERR "megasas: failed to do reset\n"); 1896c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1897c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return ret_val; 1898c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1899c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1900c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 190105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * megasas_reset_timer - quiesce the adapter if required 190205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * @scmd: scsi cmnd 190305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * 190405e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * Sets the FW busy flag and reduces the host->can_queue if the 190505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro * cmd has not been completed within the timeout period. 190605e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro */ 190705e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patrostatic enum 1908242f9dcb8ba6f68fcd217a119a7648a4f69290e9Jens Axboeblk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd) 190905e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro{ 191005e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr; 191105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro struct megasas_instance *instance; 191205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro unsigned long flags; 191305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro 191405e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro if (time_after(jiffies, scmd->jiffies_at_alloc + 191505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) { 1916242f9dcb8ba6f68fcd217a119a7648a4f69290e9Jens Axboe return BLK_EH_NOT_HANDLED; 191705e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro } 191805e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro 191905e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance = cmd->instance; 192005e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro if (!(instance->flag & MEGASAS_FW_BUSY)) { 192105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro /* FW is busy, throttle IO */ 192205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro spin_lock_irqsave(instance->host->host_lock, flags); 192305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro 192405e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance->host->can_queue = 16; 192505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance->last_time = jiffies; 192605e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance->flag |= MEGASAS_FW_BUSY; 192705e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro 192805e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro spin_unlock_irqrestore(instance->host->host_lock, flags); 192905e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro } 1930242f9dcb8ba6f68fcd217a119a7648a4f69290e9Jens Axboe return BLK_EH_RESET_TIMER; 193105e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro} 193205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro 193305e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro/** 1934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_reset_device - Device reset handler entry point 1935c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1936c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_reset_device(struct scsi_cmnd *scmd) 1937c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1938c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int ret; 1939c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1940c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 1941c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * First wait for all commands to complete 1942c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1943c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ret = megasas_generic_reset(scmd); 1944c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1945c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return ret; 1946c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1947c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1948c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1949c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_reset_bus_host - Bus & host reset handler entry point 1950c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 1951c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_reset_bus_host(struct scsi_cmnd *scmd) 1952c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 1953c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int ret; 19549c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford struct megasas_instance *instance; 19559c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance = (struct megasas_instance *)scmd->device->host->hostdata; 1956c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1957c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 195880682fa9f70932950c913fd10411c004c4c2e8b0Uwe Zeisberger * First wait for all commands to complete 1959c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 19609c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) 19619c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford ret = megasas_reset_fusion(scmd->device->host); 19629c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford else 19639c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford ret = megasas_generic_reset(scmd); 1964c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1965c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return ret; 1966c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 1967c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 1968c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 1969cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * megasas_bios_param - Returns disk geometry for a disk 1970cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @sdev: device handle 1971cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @bdev: block device 1972cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @capacity: drive capacity 1973cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * @geom: geometry parameters 1974cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro */ 1975cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patrostatic int 1976cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patromegasas_bios_param(struct scsi_device *sdev, struct block_device *bdev, 1977cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sector_t capacity, int geom[]) 1978cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro{ 1979cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro int heads; 1980cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro int sectors; 1981cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sector_t cylinders; 1982cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro unsigned long tmp; 1983cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro /* Default heads (64) & sectors (32) */ 1984cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro heads = 64; 1985cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sectors = 32; 1986cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 1987cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro tmp = heads * sectors; 1988cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro cylinders = capacity; 1989cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 1990cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sector_div(cylinders, tmp); 1991cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 1992cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro /* 1993cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro * Handle extended translation size for logical drives > 1Gb 1994cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro */ 1995cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 1996cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro if (capacity >= 0x200000) { 1997cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro heads = 255; 1998cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sectors = 63; 1999cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro tmp = heads*sectors; 2000cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro cylinders = capacity; 2001cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro sector_div(cylinders, tmp); 2002cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro } 2003cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 2004cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro geom[0] = heads; 2005cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro geom[1] = sectors; 2006cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro geom[2] = cylinders; 2007cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 2008cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro return 0; 2009cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro} 2010cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro 20117e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bostatic void megasas_aen_polling(struct work_struct *work); 20127e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 2013cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro/** 2014c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_service_aen - Processes an event notification 2015c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2016c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: AEN command completed by the ISR 2017c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2018c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * For AEN, driver sends a command down to FW that is held by the FW till an 2019c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * event occurs. When an event of interest occurs, FW completes the command 2020c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * that it was previously holding. 2021c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2022c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This routines sends SIGIO signal to processes that have registered with the 2023c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * driver for AEN. 2024c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2025c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void 2026c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) 2027c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2028c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo unsigned long flags; 2029c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2030c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Don't signal app if it is just an aborted previously registered aen 2031c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2032c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo if ((!cmd->abort_aen) && (instance->unload == 0)) { 2033c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_lock_irqsave(&poll_aen_lock, flags); 2034c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo megasas_poll_wait_aen = 1; 2035c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_unlock_irqrestore(&poll_aen_lock, flags); 2036c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo wake_up(&megasas_poll_wait); 2037c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kill_fasync(&megasas_async_queue, SIGIO, POLL_IN); 2038c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo } 2039c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else 2040c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->abort_aen = 0; 2041c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2042c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->aen_cmd = NULL; 2043c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 20447e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 204539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((instance->unload == 0) && 204639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ((instance->issuepend_done == 1))) { 20477e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct megasas_aen_event *ev; 20487e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo ev = kzalloc(sizeof(*ev), GFP_ATOMIC); 20497e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (!ev) { 20507e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo printk(KERN_ERR "megasas_service_aen: out of memory\n"); 20517e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } else { 20527e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo ev->instance = instance; 20537e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo instance->ev = ev; 20547e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo INIT_WORK(&ev->hotplug_work, megasas_aen_polling); 20557e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo schedule_delayed_work( 20567e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo (struct delayed_work *)&ev->hotplug_work, 0); 20577e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 20587e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 2059c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2060c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2061c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/* 2062c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Scsi host template for megaraid_sas driver 2063c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2064c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct scsi_host_template megasas_template = { 2065c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2066c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .module = THIS_MODULE, 2067f28cd7cf8f696eafe42d1632b5a306fbf784d3cdbo yang .name = "LSI SAS based MegaRAID driver", 2068c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .proc_name = "megaraid_sas", 2069147aab6aa22ce7775be944f8fb9932aa000dda61Christoph Hellwig .slave_configure = megasas_slave_configure, 2070044833b572b96afe91506a0edec42efd84ba4939Yang, Bo .slave_alloc = megasas_slave_alloc, 2071c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .queuecommand = megasas_queue_command, 2072c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .eh_device_reset_handler = megasas_reset_device, 2073c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .eh_bus_reset_handler = megasas_reset_bus_host, 2074c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .eh_host_reset_handler = megasas_reset_bus_host, 207505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro .eh_timed_out = megasas_reset_timer, 2076cf62a0a543fbab15286509d2e04e3dcf5549e966Sumant Patro .bios_param = megasas_bios_param, 2077c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .use_clustering = ENABLE_CLUSTERING, 2078c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}; 2079c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2080c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2081c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_complete_int_cmd - Completes an internal command 2082c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2083c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Command to be completed 2084c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2085c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * The megasas_issue_blocked_cmd() function waits for a command to complete 2086c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * after it issues a command. This function wakes up that waiting routine by 2087c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * calling wake_up() on the wait queue. 2088c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2089c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void 2090c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_complete_int_cmd(struct megasas_instance *instance, 2091c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd) 2092c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2093c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->cmd_status = cmd->frame->io.cmd_status; 2094c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2095c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->cmd_status == ENODATA) { 2096c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->cmd_status = 0; 2097c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2098c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas wake_up(&instance->int_cmd_wait_q); 2099c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2101c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2102c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_complete_abort - Completes aborting a command 2103c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2104c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Cmd that was issued to abort another cmd 2105c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 21060d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q 21070d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * after it issues an abort on a previously issued command. This function 2108c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * wakes up all functions waiting on the same wait queue. 2109c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2110c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void 2111c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_complete_abort(struct megasas_instance *instance, 2112c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd) 2113c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2114c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->sync_cmd) { 2115c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sync_cmd = 0; 2116c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->cmd_status = 0; 2117c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas wake_up(&instance->abort_cmd_wait_q); 2118c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2119c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2120c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 2121c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2122c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2123c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2124c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_complete_cmd - Completes a command 2125c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2126c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @cmd: Command to be completed 21270d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * @alt_status: If non-zero, use this value as status to 2128c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * SCSI mid-layer instead of the value returned 2129c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * by the FW. This should be used if caller wants 2130c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * an alternate status (as in the case of aborted 2131c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * commands) 2132c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 21339c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid 2134c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, 2135c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u8 alt_status) 2136c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2137c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int exception = 0; 2138c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_header *hdr = &cmd->frame->hdr; 2139c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo unsigned long flags; 21409c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford struct fusion_context *fusion = instance->ctrl_context; 2141c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 214239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang /* flag for the retry reset */ 214339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->retry_for_fw_reset = 0; 214439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 214505e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro if (cmd->scmd) 214605e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro cmd->scmd->SCp.ptr = NULL; 2147c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2148c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas switch (hdr->cmd) { 2149c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2150c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_PD_SCSI_IO: 2151c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_LD_SCSI_IO: 2152c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2153c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2154c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been 2155c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * issued either through an IO path or an IOCTL path. If it 2156c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * was via IOCTL, we will send it to internal completion. 2157c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2158c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->sync_cmd) { 2159c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sync_cmd = 0; 2160c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_complete_int_cmd(instance, cmd); 2161c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2162c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2163c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2164c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_LD_READ: 2165c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_LD_WRITE: 2166c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2167c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (alt_status) { 2168c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = alt_status << 16; 2169c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas exception = 1; 2170c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2171c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2172c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (exception) { 2173c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2174e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro atomic_dec(&instance->fw_outstanding); 2175c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2176155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori scsi_dma_unmap(cmd->scmd); 2177c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->scsi_done(cmd->scmd); 2178c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 2179c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2180c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2181c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2182c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2183c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas switch (hdr->cmd_status) { 2184c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2185c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_OK: 2186c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = DID_OK << 16; 2187c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2188c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2189c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_SCSI_IO_FAILED: 2190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_LD_INIT_IN_PROGRESS: 2191c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = 2192c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas (DID_ERROR << 16) | hdr->scsi_status; 2193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_SCSI_DONE_WITH_ERROR: 2196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status; 2198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2199c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) { 2200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(cmd->scmd->sense_buffer, 0, 2201c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas SCSI_SENSE_BUFFERSIZE); 2202c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memcpy(cmd->scmd->sense_buffer, cmd->sense, 2203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas hdr->sense_len); 2204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result |= DRIVER_SENSE << 24; 2206c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2207c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2208c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2209c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2210c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_LD_OFFLINE: 2211c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STAT_DEVICE_NOT_FOUND: 2212c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = DID_BAD_TARGET << 16; 2213c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2214c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas default: 2216c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: MFI FW status %#x\n", 2217c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas hdr->cmd_status); 2218c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->result = DID_ERROR << 16; 2219c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2220c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2222e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro atomic_dec(&instance->fw_outstanding); 2223c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2224155d98f072bbb4ffb5cefc7cecbba06df37699abFUJITA Tomonori scsi_dma_unmap(cmd->scmd); 2225c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->scmd->scsi_done(cmd->scmd); 2226c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 2227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_SMP: 2231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_STP: 2232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_DCMD: 22339c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford /* Check for LD map update */ 22349c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if ((cmd->frame->dcmd.opcode == MR_DCMD_LD_MAP_GET_INFO) && 22359c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (cmd->frame->dcmd.mbox.b[1] == 1)) { 22369c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_lock_irqsave(instance->host->host_lock, flags); 22379c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (cmd->frame->hdr.cmd_status != 0) { 22389c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (cmd->frame->hdr.cmd_status != 22399c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford MFI_STAT_NOT_FOUND) 22409c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford printk(KERN_WARNING "megasas: map sync" 22419c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford "failed, status = 0x%x.\n", 22429c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford cmd->frame->hdr.cmd_status); 22439c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford else { 22449c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_return_cmd(instance, cmd); 22459c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_unlock_irqrestore( 22469c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->host->host_lock, 22479c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford flags); 22489c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 22499c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 22509c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } else 22519c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->map_id++; 22529c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_return_cmd(instance, cmd); 22539c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (MR_ValidateMapInfo( 22549c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->ld_map[(instance->map_id & 1)], 22559c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->load_balance_info)) 22569c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->fast_path_io = 1; 22579c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford else 22589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->fast_path_io = 0; 22599c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_sync_map_info(instance); 22609c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_unlock_irqrestore(instance->host->host_lock, 22619c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford flags); 22629c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 22639c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 2264c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO || 2265c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) { 2266c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_lock_irqsave(&poll_aen_lock, flags); 2267c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo megasas_poll_wait_aen = 0; 2268c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_unlock_irqrestore(&poll_aen_lock, flags); 2269c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo } 2270c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2271c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2272c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * See if got an event notification 2273c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2274c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_WAIT) 2275c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_service_aen(instance, cmd); 2276c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas else 2277c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_complete_int_cmd(instance, cmd); 2278c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2279c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2280c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2281c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_CMD_ABORT: 2282c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2283c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Cmd issued to abort another cmd returned 2284c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2285c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_complete_abort(instance, cmd); 2286c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2287c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2288c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas default: 2289c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk("megasas: Unknown command completed! [0x%X]\n", 2290c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas hdr->cmd); 2291c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2292c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2293c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2294c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2295c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 229639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * megasas_issue_pending_cmds_again - issue all pending cmds 229739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * in FW again because of the fw reset 229839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * @instance: Adapter soft state 229939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 230039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic inline void 230139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_issue_pending_cmds_again(struct megasas_instance *instance) 230239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 230339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_cmd *cmd; 230439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct list_head clist_local; 230539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang union megasas_evt_class_locale class_locale; 230639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 230739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 seq_num; 230839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 230939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang INIT_LIST_HEAD(&clist_local); 231039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 231139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_splice_init(&instance->internal_reset_pending_q, &clist_local); 231239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 231339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 231439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang while (!list_empty(&clist_local)) { 231539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd = list_entry((&clist_local)->next, 231639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_cmd, list); 231739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_del_init(&cmd->list); 231839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 231939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (cmd->sync_cmd || cmd->scmd) { 232039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: command %p, %p:%d" 232139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "detected to be pending while HBA reset.\n", 232239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd, cmd->scmd, cmd->sync_cmd); 232339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 232439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->retry_for_fw_reset++; 232539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 232639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (cmd->retry_for_fw_reset == 3) { 232739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: cmd %p, %p:%d" 232839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "was tried multiple times during reset." 232939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "Shutting down the HBA\n", 233039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd, cmd->scmd, cmd->sync_cmd); 233139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megaraid_sas_kill_hba(instance); 233239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 233339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = 233439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang MEGASAS_HW_CRITICAL_ERROR; 233539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return; 233639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 233739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 233839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 233939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (cmd->sync_cmd == 1) { 234039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (cmd->scmd) { 234139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: unexpected" 234239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "cmd attached to internal command!\n"); 234339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 234439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: %p synchronous cmd" 234539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "on the internal reset queue," 234639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "issue it again.\n", cmd); 234739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->cmd_status = ENODATA; 234839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->fire_cmd(instance, 234939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->frame_phys_addr , 235039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 0, instance->reg_set); 235139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else if (cmd->scmd) { 235239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: %p scsi cmd [%02x],%#lx" 235339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "detected on the internal queue, issue again.\n", 235439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd, cmd->scmd->cmnd[0], cmd->scmd->serial_number); 235539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 235639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_inc(&instance->fw_outstanding); 235739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->fire_cmd(instance, 235839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->frame_phys_addr, 235939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->frame_count-1, instance->reg_set); 236039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else { 236139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: %p unexpected cmd on the" 236239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "internal reset defer list while re-issue!!\n", 236339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd); 236439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 236539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 236639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 236739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->aen_cmd) { 236839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: aen_cmd in def process\n"); 236939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_return_cmd(instance, instance->aen_cmd); 237039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 237139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->aen_cmd = NULL; 237239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 237339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 237439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang /* 237539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * Initiate AEN (Asynchronous Event Notification) 237639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 237739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang seq_num = instance->last_seq_num; 237839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang class_locale.members.reserved = 0; 237939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang class_locale.members.locale = MR_EVT_LOCALE_ALL; 238039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang class_locale.members.class = MR_EVT_CLASS_DEBUG; 238139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 238239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_register_aen(instance, seq_num, class_locale.word); 238339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 238439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 238539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 238639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * Move the internal reset pending commands to a deferred queue. 238739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * 238839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * We move the commands pending at internal reset time to a 238939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * pending queue. This queue would be flushed after successful 239039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * completion of the internal reset sequence. if the internal reset 239139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * did not complete in time, the kernel reset handler would flush 239239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * these commands. 239339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang **/ 239439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic void 239539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_internal_reset_defer_cmds(struct megasas_instance *instance) 239639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 239739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_cmd *cmd; 239839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang int i; 239939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 max_cmd = instance->max_fw_cmds; 240039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 defer_index; 240139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 240239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 240339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang defer_index = 0; 240439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->cmd_pool_lock, flags); 240539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < max_cmd; i++) { 240639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd = instance->cmd_list[i]; 240739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (cmd->sync_cmd == 1 || cmd->scmd) { 240839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: moving cmd[%d]:%p:%d:%p" 240939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "on the defer queue as internal\n", 241039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang defer_index, cmd, cmd->sync_cmd, cmd->scmd); 241139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 241239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (!list_empty(&cmd->list)) { 241339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: ERROR while" 241439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang " moving this cmd:%p, %d %p, it was" 241539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "discovered on some list?\n", 241639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd, cmd->sync_cmd, cmd->scmd); 241739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 241839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_del_init(&cmd->list); 241939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 242039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang defer_index++; 242139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang list_add_tail(&cmd->list, 242239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang &instance->internal_reset_pending_q); 242339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 242439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 242539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->cmd_pool_lock, flags); 242639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 242739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 242839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 242939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangstatic void 243039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangprocess_fw_state_change_wq(struct work_struct *work) 243139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang{ 243239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_instance *instance = 243339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang container_of(work, struct megasas_instance, work_init); 243439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 wait; 243539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 243639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 243739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery != MEGASAS_ADPRESET_SM_INFAULT) { 243839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: error, recovery st %x \n", 243939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery); 244039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return ; 244139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 244239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 244339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) { 244439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault" 244539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "state, restarting it...\n"); 244639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 244739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->disable_intr(instance->reg_set); 244839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_set(&instance->fw_outstanding, 0); 244939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 245039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_set(&instance->fw_reset_no_pci_access, 1); 245139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->adp_reset(instance, instance->reg_set); 245239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_set(&instance->fw_reset_no_pci_access, 0 ); 245339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 245439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: FW restarted successfully," 245539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "initiating next stage...\n"); 245639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 245739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: HBA recovery state machine," 245839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "state 2 starting...\n"); 245939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 246039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang /*waitting for about 20 second before start the second init*/ 246139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (wait = 0; wait < 30; wait++) { 246239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 246339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 246439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 246539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (megasas_transition_to_ready(instance)) { 246639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas:adapter not ready\n"); 246739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 246839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megaraid_sas_kill_hba(instance); 246939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR; 247039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return ; 247139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 247239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 247339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) || 247439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) || 247539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR) 247639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ) { 247739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang *instance->consumer = *instance->producer; 247839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else { 247939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang *instance->consumer = 0; 248039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang *instance->producer = 0; 248139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 248239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 248339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_issue_init_mfi(instance); 248439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 248539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 248639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_HBA_OPERATIONAL; 248739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 248839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->enable_intr(instance->reg_set); 248939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 249039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_issue_pending_cmds_again(instance); 249139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->issuepend_done = 1; 249239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 249339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return ; 249439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang} 249539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 249639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang/** 2497c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_deplete_reply_queue - Processes all completed commands 2498c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2499c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @alt_status: Alternate status to be returned to 2500c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * SCSI mid-layer instead of the status 2501c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * returned by the FW 250239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * Note: this must be called with hba lock held 2503c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2504858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic int 250539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yangmegasas_deplete_reply_queue(struct megasas_instance *instance, 250639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u8 alt_status) 2507c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 250839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 mfiStatus; 250939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 fw_state; 251039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 251139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((mfiStatus = instance->instancet->check_reset(instance, 251239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->reg_set)) == 1) { 251339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return IRQ_HANDLED; 251439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 251539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 251639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((mfiStatus = instance->instancet->clear_intr( 251739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->reg_set) 251839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ) == 0) { 2519e1419191d8d38098fb6ef29e94aadd15dabff3daAdam Radford /* Hardware may not set outbound_intr_status in MSI-X mode */ 2520e1419191d8d38098fb6ef29e94aadd15dabff3daAdam Radford if (!instance->msi_flag) 2521e1419191d8d38098fb6ef29e94aadd15dabff3daAdam Radford return IRQ_NONE; 252239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 252339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 252439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->mfiStatus = mfiStatus; 252539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 252639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) { 252739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang fw_state = instance->instancet->read_fw_status_reg( 252839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->reg_set) & MFI_STATE_MASK; 252939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 253039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (fw_state != MFI_STATE_FAULT) { 253139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: fw state:%x\n", 253239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang fw_state); 253339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 253439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 253539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((fw_state == MFI_STATE_FAULT) && 253639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->disableOnlineCtrlReset == 0)) { 253739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megaraid_sas: wait adp restart\n"); 253839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 253939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((instance->pdev->device == 254039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang PCI_DEVICE_ID_LSI_SAS1064R) || 254139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->pdev->device == 254239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang PCI_DEVICE_ID_DELL_PERC5) || 254339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->pdev->device == 254439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang PCI_DEVICE_ID_LSI_VERDE_ZCR)) { 254539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 254639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang *instance->consumer = 254739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang MEGASAS_ADPRESET_INPROG_SIGN; 254839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 254939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 255039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 255139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->instancet->disable_intr(instance->reg_set); 255239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; 255339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->issuepend_done = 0; 255439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 255539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_set(&instance->fw_outstanding, 0); 255639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_internal_reset_defer_cmds(instance); 255739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 255839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: fwState=%x, stage:%d\n", 255939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang fw_state, instance->adprecovery); 256039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 256139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang schedule_work(&instance->work_init); 256239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return IRQ_HANDLED; 256339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 256439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } else { 256539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: fwstate:%x, dis_OCR=%x\n", 256639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang fw_state, instance->disableOnlineCtrlReset); 256739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 256839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 2569c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 25705d018ad057347995e5c4564b3e43339e6497f839Sumant Patro tasklet_schedule(&instance->isr_tasklet); 2571c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return IRQ_HANDLED; 2572c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2573c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2574c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_isr - isr entry point 2575c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 25767d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t megasas_isr(int irq, void *devp) 2577c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 257839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang struct megasas_instance *instance; 257939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 258039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang irqreturn_t rc; 258139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 258239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (atomic_read( 258339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang &(((struct megasas_instance *)devp)->fw_reset_no_pci_access))) 258439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return IRQ_HANDLED; 258539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 258639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance = (struct megasas_instance *)devp; 258739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 258839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 258939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang rc = megasas_deplete_reply_queue(instance, DID_OK); 259039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 259139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 259239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return rc; 2593c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2594c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2595c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2596c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_transition_to_ready - Move the FW to READY state 25971341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro * @instance: Adapter soft state 2598c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2599c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * During the initialization, FW passes can potentially be in any one of 2600c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * several possible states. If the FW in operational, waiting-for-handshake 2601c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * states, driver must take steps to bring it to ready state. Otherwise, it 2602c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * has to wait for the ready state. 2603c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 26049c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint 26051341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patromegasas_transition_to_ready(struct megasas_instance* instance) 2606c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2607c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 2608c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u8 max_wait; 2609c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 fw_state; 2610c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 cur_state; 26117218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo u32 abs_state, curr_abs_state; 2612c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 26131341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK; 2614c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2615e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro if (fw_state != MFI_STATE_READY) 26160d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford printk(KERN_INFO "megasas: Waiting for FW to come to ready" 26170d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford " state\n"); 2618e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro 2619c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas while (fw_state != MFI_STATE_READY) { 2620c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 26217218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo abs_state = 26227218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo instance->instancet->read_fw_status_reg(instance->reg_set); 26237218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo 2624c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas switch (fw_state) { 2625c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2626c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_FAULT: 2627c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2628c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: FW in FAULT state!!\n"); 26291ac515ef3f2f7ab32498b0e4907933ff8b9b98c0Adam Radford max_wait = MEGASAS_RESET_WAIT_TIME; 26301ac515ef3f2f7ab32498b0e4907933ff8b9b98c0Adam Radford cur_state = MFI_STATE_FAULT; 26311ac515ef3f2f7ab32498b0e4907933ff8b9b98c0Adam Radford break; 2632c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2633c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_WAIT_HANDSHAKE: 2634c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2635c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Set the CLR bit in inbound doorbell 2636c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 26370c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo if ((instance->pdev->device == 2638879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 2639879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo (instance->pdev->device == 26409c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 26419c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == 26429c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_FUSION)) { 2643879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel( 2644879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, 26459c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->reg_set->doorbell); 2646879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo } else { 2647879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel( 2648879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, 2649879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo &instance->reg_set->inbound_doorbell); 2650879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo } 2651c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 26527218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2653c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_WAIT_HANDSHAKE; 2654c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2655c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2656e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro case MFI_STATE_BOOT_MESSAGE_PENDING: 2657879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo if ((instance->pdev->device == 26589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 26599c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == 26609c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 26619c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device == 26629c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_FUSION)) { 2663879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(MFI_INIT_HOTPLUG, 26649c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->reg_set->doorbell); 2665879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo } else 2666879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(MFI_INIT_HOTPLUG, 2667879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo &instance->reg_set->inbound_doorbell); 2668e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro 26697218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2670e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro cur_state = MFI_STATE_BOOT_MESSAGE_PENDING; 2671e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro break; 2672e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro 2673c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_OPERATIONAL: 2674c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2675e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * Bring it to READY state; assuming max wait 10 secs 2676c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2677b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro instance->instancet->disable_intr(instance->reg_set); 2678879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo if ((instance->pdev->device == 2679879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 2680879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo (instance->pdev->device == 26819c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 26829c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (instance->pdev->device 26839c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford == PCI_DEVICE_ID_LSI_FUSION)) { 2684879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(MFI_RESET_FLAGS, 26859c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->reg_set->doorbell); 26869c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (instance->pdev->device == 26879c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford PCI_DEVICE_ID_LSI_FUSION) { 26889c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford for (i = 0; i < (10 * 1000); i += 20) { 26899c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (readl( 26909c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance-> 26919c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford reg_set-> 26929c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford doorbell) & 1) 26939c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford msleep(20); 26949c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford else 26959c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 26969c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 26979c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 2698879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo } else 2699879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo writel(MFI_RESET_FLAGS, 2700879111224d0784eab623fe8130a1f4481e0e1966Yang, Bo &instance->reg_set->inbound_doorbell); 2701c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 27027218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2703c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_OPERATIONAL; 2704c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2705c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2706c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_UNDEFINED: 2707c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2708c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This state should not last for more than 2 seconds 2709c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 27107218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2711c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_UNDEFINED; 2712c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2713c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2714c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_BB_INIT: 27157218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2716c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_BB_INIT; 2717c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2718c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2719c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_FW_INIT: 27207218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2721c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_FW_INIT; 2722c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2723c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2724c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_FW_INIT_2: 27257218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2726c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_FW_INIT_2; 2727c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2728c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2729c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_DEVICE_SCAN: 27307218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2731c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_DEVICE_SCAN; 2732c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2733c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2734c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MFI_STATE_FLUSH_CACHE: 27357218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo max_wait = MEGASAS_RESET_WAIT_TIME; 2736c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cur_state = MFI_STATE_FLUSH_CACHE; 2737c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2738c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2739c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas default: 2740c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Unknown state 0x%x\n", 2741c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fw_state); 2742c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENODEV; 2743c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2744c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2745c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2746c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * The cur_state should not last for more than max_wait secs 2747c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2748c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < (max_wait * 1000); i++) { 27490d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & 27501341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro MFI_STATE_MASK ; 27517218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo curr_abs_state = 27527218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo instance->instancet->read_fw_status_reg(instance->reg_set); 2753c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 27547218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo if (abs_state == curr_abs_state) { 2755c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas msleep(1); 2756c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else 2757c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 2758c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2759c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2760c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2761c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Return error if fw_state hasn't changed after max_wait 2762c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 27637218df69e3609d1fcf4d83cf8f3fc89dbfbf82a8Yang, Bo if (curr_abs_state == abs_state) { 2764c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "FW state [%d] hasn't changed " 2765c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "in %d secs\n", fw_state, max_wait); 2766c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENODEV; 2767c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 276839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 27690d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford printk(KERN_INFO "megasas: FW now in Ready state\n"); 2770c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2771c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 2772c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2773c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2774c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2775c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_teardown_frame_pool - Destroy the cmd frame DMA pool 2776c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2777c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2778c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_teardown_frame_pool(struct megasas_instance *instance) 2779c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 27819c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford u32 max_cmd = instance->max_mfi_cmds; 2782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 2783c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2784c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->frame_dma_pool) 2785c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 2786c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2787c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2788c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Return all frames to pool 2789c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2790c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < max_cmd; i++) { 2791c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2792c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = instance->cmd_list[i]; 2793c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2794c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->frame) 2795c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_pool_free(instance->frame_dma_pool, cmd->frame, 2796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->frame_phys_addr); 2797c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2798c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (cmd->sense) 2799e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro pci_pool_free(instance->sense_dma_pool, cmd->sense, 2800c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sense_phys_addr); 2801c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2802c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2803c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2804c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Now destroy the pool itself 2805c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2806c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_pool_destroy(instance->frame_dma_pool); 2807c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_pool_destroy(instance->sense_dma_pool); 2808c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2809c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->frame_dma_pool = NULL; 2810c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->sense_dma_pool = NULL; 2811c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2812c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2813c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2814c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_create_frame_pool - Creates DMA pool for cmd frames 2815c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2816c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2817c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Each command packet has an embedded DMA memory buffer that is used for 2818c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * filling MFI frame and the SG list that immediately follows the frame. This 2819c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * function creates those DMA memory buffers for each command packet by using 2820c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI pool facility. 2821c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2822c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_create_frame_pool(struct megasas_instance *instance) 2823c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2824c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 2825c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 max_cmd; 2826c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 sge_sz; 2827c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 sgl_sz; 2828c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 total_sz; 2829c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 frame_count; 2830c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 2831c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 28329c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford max_cmd = instance->max_mfi_cmds; 2833c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2834c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2835c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Size of our frame is 64 bytes for MFI frame, followed by max SG 2836c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer 2837c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2838c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : 2839c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sizeof(struct megasas_sge32); 2840c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2841f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->flag_ieee) { 2842f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo sge_sz = sizeof(struct megasas_sge_skinny); 2843f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 2844f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 2845c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2846c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Calculated the number of 64byte frames required for SGL 2847c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2848c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sgl_sz = sge_sz * instance->max_num_sge; 2849c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas frame_count = (sgl_sz + MEGAMFI_FRAME_SIZE - 1) / MEGAMFI_FRAME_SIZE; 285039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang frame_count = 15; 2851c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2852c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2853c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * We need one extra frame for the MFI command 2854c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas frame_count++; 2856c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2857c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas total_sz = MEGAMFI_FRAME_SIZE * frame_count; 2858c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2859c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Use DMA pool facility provided by PCI layer 2860c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2861c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->frame_dma_pool = pci_pool_create("megasas frame pool", 2862c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->pdev, total_sz, 64, 2863c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 0); 2864c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2865c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->frame_dma_pool) { 2866c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: failed to setup frame pool\n"); 2867c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 2868c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2869c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2870c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->sense_dma_pool = pci_pool_create("megasas sense pool", 2871c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->pdev, 128, 4, 0); 2872c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2873c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->sense_dma_pool) { 2874c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: failed to setup sense pool\n"); 2875c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2876c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_pool_destroy(instance->frame_dma_pool); 2877c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->frame_dma_pool = NULL; 2878c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2879c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 2880c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2881c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2882c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2883c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Allocate and attach a frame to each of the commands in cmd_list. 2884c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * By making cmd->index as the context instead of the &cmd, we can 2885c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * always use 32bit context regardless of the architecture 2886c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2887c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < max_cmd; i++) { 2888c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2889c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = instance->cmd_list[i]; 2890c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2891c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->frame = pci_pool_alloc(instance->frame_dma_pool, 2892c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas GFP_KERNEL, &cmd->frame_phys_addr); 2893c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2894c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sense = pci_pool_alloc(instance->sense_dma_pool, 2895c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas GFP_KERNEL, &cmd->sense_phys_addr); 2896c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2897c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2898c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_teardown_frame_pool() takes care of freeing 2899c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * whatever has been allocated 2900c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2901c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd->frame || !cmd->sense) { 2902c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: pci_pool_alloc failed \n"); 2903c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_teardown_frame_pool(instance); 2904c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 2905c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2906c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2907707e09bd867cee4cd0e5bff0a67513aa0232fcecYang, Bo memset(cmd->frame, 0, total_sz); 2908c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->frame->io.context = cmd->index; 29097e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo cmd->frame->io.pad_0 = 0; 2910c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2911c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2912c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 2913c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2914c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2915c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2916c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_free_cmds - Free all the cmds in the free cmd pool 2917c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2918c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 29199c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordvoid megasas_free_cmds(struct megasas_instance *instance) 2920c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2921c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 2922c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* First free the MFI frame pool */ 2923c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_teardown_frame_pool(instance); 2924c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2925c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* Free all the commands in the cmd_list */ 29269c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford for (i = 0; i < instance->max_mfi_cmds; i++) 29279c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 2928c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(instance->cmd_list[i]); 2929c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2930c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* Free the cmd_list buffer itself */ 2931c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(instance->cmd_list); 2932c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->cmd_list = NULL; 2933c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas INIT_LIST_HEAD(&instance->cmd_pool); 2935c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 2936c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2937c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 2938c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_alloc_cmds - Allocates the command packets 2939c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 2940c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2941c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Each command that is issued to the FW, whether IO commands from the OS or 2942c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * internal commands like IOCTLs, are wrapped in local data structure called 2943c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to 2944c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the FW. 2945c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 2946c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Each frame has a 32-bit field called context (tag). This context is used 2947c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to get back the megasas_cmd from the frame when a frame gets completed in 2948c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the ISR. Typically the address of the megasas_cmd itself would be used as 2949c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the context. But we wanted to keep the differences between 32 and 64 bit 2950c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * systems to the mininum. We always use 32 bit integers for the context. In 2951c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * this driver, the 32 bit values are the indices into an array cmd_list. 2952c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This array is used only to look up the megasas_cmd given the context. The 2953c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * free commands themselves are maintained in a linked list called cmd_pool. 2954c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 29559c915a8c99bce637226aa09cb05fc18486b229cbAdam Radfordint megasas_alloc_cmds(struct megasas_instance *instance) 2956c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 2957c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 2958c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int j; 2959c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 max_cmd; 2960c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 2961c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 29629c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford max_cmd = instance->max_mfi_cmds; 2963c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2964c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2965c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * instance->cmd_list is an array of struct megasas_cmd pointers. 2966c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Allocate the dynamic array first and then allocate individual 2967c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * commands. 2968c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2969dd00cc486ab1c17049a535413d1751ef3482141cYoann Padioleau instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL); 2970c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2971c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->cmd_list) { 2972c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: out of memory\n"); 2973c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 2974c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2975c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 29769c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) *max_cmd); 2977c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2978c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < max_cmd; i++) { 2979c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd), 2980c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas GFP_KERNEL); 2981c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2982c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->cmd_list[i]) { 2983c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2984c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (j = 0; j < i; j++) 2985c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(instance->cmd_list[j]); 2986c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2987c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(instance->cmd_list); 2988c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->cmd_list = NULL; 2989c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2990c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 2991c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2992c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 2993c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 2994c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 2995c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Add all the commands to command pool (instance->cmd_pool) 2996c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 2997c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < max_cmd; i++) { 2998c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = instance->cmd_list[i]; 2999c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(cmd, 0, sizeof(struct megasas_cmd)); 3000c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->index = i; 300139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang cmd->scmd = NULL; 3002c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->instance = instance; 3003c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3004c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas list_add_tail(&cmd->list, &instance->cmd_pool); 3005c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3006c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3007c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3008c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Create a frame pool and assign one frame to each cmd 3009c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3010c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_create_frame_pool(instance)) { 3011c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n"); 3012c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_free_cmds(instance); 3013c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3014c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3015c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3016c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3017c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 301881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo/* 301981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * megasas_get_pd_list_info - Returns FW's pd_list structure 302081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * @instance: Adapter soft state 302181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * @pd_list: pd_list structure 302281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * 302381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * Issues an internal command (DCMD) to get the FW's controller PD 302481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * list structure. This information is mainly used to find out SYSTEM 302581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * supported by the FW. 302681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo */ 302781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bostatic int 302881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bomegasas_get_pd_list(struct megasas_instance *instance) 302981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo{ 303081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo int ret = 0, pd_index = 0; 303181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo struct megasas_cmd *cmd; 303281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo struct megasas_dcmd_frame *dcmd; 303381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo struct MR_PD_LIST *ci; 303481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo struct MR_PD_ADDRESS *pd_addr; 303581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dma_addr_t ci_h = 0; 303681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 303781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo cmd = megasas_get_cmd(instance); 303881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 303981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo if (!cmd) { 304081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n"); 304181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo return -ENOMEM; 304281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } 304381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 304481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd = &cmd->frame->dcmd; 304581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 304681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo ci = pci_alloc_consistent(instance->pdev, 304781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h); 304881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 304981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo if (!ci) { 305081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo printk(KERN_DEBUG "Failed to alloc mem for pd_list\n"); 305181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo megasas_return_cmd(instance, cmd); 305281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo return -ENOMEM; 305381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } 305481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 305581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo memset(ci, 0, sizeof(*ci)); 305681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 305781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 305881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST; 305981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->mbox.b[1] = 0; 306081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->cmd = MFI_CMD_DCMD; 306181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->cmd_status = 0xFF; 306281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->sge_count = 1; 306381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->flags = MFI_FRAME_DIR_READ; 306481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->timeout = 0; 3065780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 306681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST); 306781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->opcode = MR_DCMD_PD_LIST_QUERY; 306881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->sgl.sge32[0].phys_addr = ci_h; 306981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST); 307081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 307181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo if (!megasas_issue_polled(instance, cmd)) { 307281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo ret = 0; 307381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } else { 307481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo ret = -1; 307581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } 307681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 307781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo /* 307881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo * the following function will get the instance PD LIST. 307981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo */ 308081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 308181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo pd_addr = ci->addr; 308281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 308381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo if ( ret == 0 && 308481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo (ci->count < 308581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) { 308681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 308781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo memset(instance->pd_list, 0, 308881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)); 308981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 309081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo for (pd_index = 0; pd_index < ci->count; pd_index++) { 309181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 309281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo instance->pd_list[pd_addr->deviceId].tid = 309381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo pd_addr->deviceId; 309481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo instance->pd_list[pd_addr->deviceId].driveType = 309581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo pd_addr->scsiDevType; 309681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo instance->pd_list[pd_addr->deviceId].driveState = 309781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo MR_PD_STATE_SYSTEM; 309881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo pd_addr++; 309981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } 310081e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo } 310181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 310281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo pci_free_consistent(instance->pdev, 310381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), 310481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo ci, ci_h); 310581e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo megasas_return_cmd(instance, cmd); 310681e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 310781e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo return ret; 310881e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo} 310981e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 3110bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo/* 3111bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * megasas_get_ld_list_info - Returns FW's ld_list structure 3112bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * @instance: Adapter soft state 3113bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * @ld_list: ld_list structure 3114bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * 3115bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * Issues an internal command (DCMD) to get the FW's controller PD 3116bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * list structure. This information is mainly used to find out SYSTEM 3117bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo * supported by the FW. 3118bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo */ 3119bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bostatic int 3120bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bomegasas_get_ld_list(struct megasas_instance *instance) 3121bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo{ 3122bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo int ret = 0, ld_index = 0, ids = 0; 3123bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo struct megasas_cmd *cmd; 3124bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo struct megasas_dcmd_frame *dcmd; 3125bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo struct MR_LD_LIST *ci; 3126bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dma_addr_t ci_h = 0; 3127bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3128bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo cmd = megasas_get_cmd(instance); 3129bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3130bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (!cmd) { 3131bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n"); 3132bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo return -ENOMEM; 3133bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3134bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3135bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd = &cmd->frame->dcmd; 3136bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3137bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ci = pci_alloc_consistent(instance->pdev, 3138bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo sizeof(struct MR_LD_LIST), 3139bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo &ci_h); 3140bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3141bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (!ci) { 3142bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n"); 3143bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo megasas_return_cmd(instance, cmd); 3144bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo return -ENOMEM; 3145bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3146bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3147bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo memset(ci, 0, sizeof(*ci)); 3148bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 3149bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3150bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->cmd = MFI_CMD_DCMD; 3151bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->cmd_status = 0xFF; 3152bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->sge_count = 1; 3153bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->flags = MFI_FRAME_DIR_READ; 3154bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->timeout = 0; 3155bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->data_xfer_len = sizeof(struct MR_LD_LIST); 3156bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->opcode = MR_DCMD_LD_GET_LIST; 3157bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->sgl.sge32[0].phys_addr = ci_h; 3158bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_LIST); 3159bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo dcmd->pad_0 = 0; 3160bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3161bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (!megasas_issue_polled(instance, cmd)) { 3162bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ret = 0; 3163bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } else { 3164bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ret = -1; 3165bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3166bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3167bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo /* the following function will get the instance PD LIST */ 3168bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 316939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if ((ret == 0) && (ci->ldCount <= MAX_LOGICAL_DRIVES)) { 3170bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); 3171bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3172bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo for (ld_index = 0; ld_index < ci->ldCount; ld_index++) { 3173bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo if (ci->ldList[ld_index].state != 0) { 3174bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ids = ci->ldList[ld_index].ref.targetId; 3175bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo instance->ld_ids[ids] = 3176bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ci->ldList[ld_index].ref.targetId; 3177bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3178bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3179bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo } 3180bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3181bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo pci_free_consistent(instance->pdev, 3182bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo sizeof(struct MR_LD_LIST), 3183bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ci, 3184bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo ci_h); 3185bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3186bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo megasas_return_cmd(instance, cmd); 3187bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo return ret; 3188bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo} 3189bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3191c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_get_controller_info - Returns FW's controller structure 3192c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 3193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @ctrl_info: Controller information structure 3194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Issues an internal command (DCMD) to get the FW's controller structure. 3196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This information is mainly used to find out the maximum IO transfer per 3197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * command supported by the FW. 3198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3199c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 3200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_get_ctrl_info(struct megasas_instance *instance, 3201c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_ctrl_info *ctrl_info) 3202c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int ret = 0; 3204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 3205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_dcmd_frame *dcmd; 3206c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_ctrl_info *ci; 3207c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dma_addr_t ci_h = 0; 3208c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3209c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 3210c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3211c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) { 3212c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to get a free cmd\n"); 3213c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3214c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3216c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd = &cmd->frame->dcmd; 3217c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3218c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ci = pci_alloc_consistent(instance->pdev, 3219c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sizeof(struct megasas_ctrl_info), &ci_h); 3220c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!ci) { 3222c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "Failed to alloc mem for ctrl info\n"); 3223c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 3224c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3225c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3226c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(ci, 0, sizeof(*ci)); 3228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 3229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd = MFI_CMD_DCMD; 3231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd_status = 0xFF; 3232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sge_count = 1; 3233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->flags = MFI_FRAME_DIR_READ; 3234c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->timeout = 0; 3235780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 3236c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->data_xfer_len = sizeof(struct megasas_ctrl_info); 3237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->opcode = MR_DCMD_CTRL_GET_INFO; 3238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].phys_addr = ci_h; 3239c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].length = sizeof(struct megasas_ctrl_info); 3240c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3241c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!megasas_issue_polled(instance, cmd)) { 3242c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ret = 0; 3243c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info)); 3244c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else { 3245c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ret = -1; 3246c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3247c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3248c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info), 3249c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ci, ci_h); 3250c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3251c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 3252c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return ret; 3253c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3254c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3255c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 325631ea7088974c2405e19d72f17c2afb103ef19e02bo yang * megasas_issue_init_mfi - Initializes the FW 325731ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @instance: Adapter soft state 325831ea7088974c2405e19d72f17c2afb103ef19e02bo yang * 325931ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Issues the INIT MFI cmd 326031ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 326131ea7088974c2405e19d72f17c2afb103ef19e02bo yangstatic int 326231ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_issue_init_mfi(struct megasas_instance *instance) 326331ea7088974c2405e19d72f17c2afb103ef19e02bo yang{ 326431ea7088974c2405e19d72f17c2afb103ef19e02bo yang u32 context; 326531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 326631ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct megasas_cmd *cmd; 326731ea7088974c2405e19d72f17c2afb103ef19e02bo yang 326831ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct megasas_init_frame *init_frame; 326931ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct megasas_init_queue_info *initq_info; 327031ea7088974c2405e19d72f17c2afb103ef19e02bo yang dma_addr_t init_frame_h; 327131ea7088974c2405e19d72f17c2afb103ef19e02bo yang dma_addr_t initq_info_h; 327231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 327331ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 327431ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Prepare a init frame. Note the init frame points to queue info 327531ea7088974c2405e19d72f17c2afb103ef19e02bo yang * structure. Each frame has SGL allocated after first 64 bytes. For 327631ea7088974c2405e19d72f17c2afb103ef19e02bo yang * this frame - since we don't need any SGL - we use SGL's space as 327731ea7088974c2405e19d72f17c2afb103ef19e02bo yang * queue info structure 327831ea7088974c2405e19d72f17c2afb103ef19e02bo yang * 327931ea7088974c2405e19d72f17c2afb103ef19e02bo yang * We will not get a NULL command below. We just created the pool. 328031ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 328131ea7088974c2405e19d72f17c2afb103ef19e02bo yang cmd = megasas_get_cmd(instance); 328231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 328331ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame = (struct megasas_init_frame *)cmd->frame; 328431ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info = (struct megasas_init_queue_info *) 328531ea7088974c2405e19d72f17c2afb103ef19e02bo yang ((unsigned long)init_frame + 64); 328631ea7088974c2405e19d72f17c2afb103ef19e02bo yang 328731ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame_h = cmd->frame_phys_addr; 328831ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info_h = init_frame_h + 64; 328931ea7088974c2405e19d72f17c2afb103ef19e02bo yang 329031ea7088974c2405e19d72f17c2afb103ef19e02bo yang context = init_frame->context; 329131ea7088974c2405e19d72f17c2afb103ef19e02bo yang memset(init_frame, 0, MEGAMFI_FRAME_SIZE); 329231ea7088974c2405e19d72f17c2afb103ef19e02bo yang memset(initq_info, 0, sizeof(struct megasas_init_queue_info)); 329331ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame->context = context; 329431ea7088974c2405e19d72f17c2afb103ef19e02bo yang 329531ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info->reply_queue_entries = instance->max_fw_cmds + 1; 329631ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h; 329731ea7088974c2405e19d72f17c2afb103ef19e02bo yang 329831ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info->producer_index_phys_addr_lo = instance->producer_h; 329931ea7088974c2405e19d72f17c2afb103ef19e02bo yang initq_info->consumer_index_phys_addr_lo = instance->consumer_h; 330031ea7088974c2405e19d72f17c2afb103ef19e02bo yang 330131ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame->cmd = MFI_CMD_INIT; 330231ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame->cmd_status = 0xFF; 330331ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame->queue_info_new_phys_addr_lo = initq_info_h; 330431ea7088974c2405e19d72f17c2afb103ef19e02bo yang 330531ea7088974c2405e19d72f17c2afb103ef19e02bo yang init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); 330631ea7088974c2405e19d72f17c2afb103ef19e02bo yang 330731ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 330831ea7088974c2405e19d72f17c2afb103ef19e02bo yang * disable the intr before firing the init frame to FW 330931ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 331031ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->instancet->disable_intr(instance->reg_set); 331131ea7088974c2405e19d72f17c2afb103ef19e02bo yang 331231ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 331331ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Issue the init frame in polled mode 331431ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 331531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 331631ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (megasas_issue_polled(instance, cmd)) { 331731ea7088974c2405e19d72f17c2afb103ef19e02bo yang printk(KERN_ERR "megasas: Failed to init firmware\n"); 331831ea7088974c2405e19d72f17c2afb103ef19e02bo yang megasas_return_cmd(instance, cmd); 331931ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_fw_init; 332031ea7088974c2405e19d72f17c2afb103ef19e02bo yang } 332131ea7088974c2405e19d72f17c2afb103ef19e02bo yang 332231ea7088974c2405e19d72f17c2afb103ef19e02bo yang megasas_return_cmd(instance, cmd); 332331ea7088974c2405e19d72f17c2afb103ef19e02bo yang 332431ea7088974c2405e19d72f17c2afb103ef19e02bo yang return 0; 332531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 332631ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_fw_init: 332731ea7088974c2405e19d72f17c2afb103ef19e02bo yang return -EINVAL; 332831ea7088974c2405e19d72f17c2afb103ef19e02bo yang} 332931ea7088974c2405e19d72f17c2afb103ef19e02bo yang 333031ea7088974c2405e19d72f17c2afb103ef19e02bo yang/** 3331ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * megasas_start_timer - Initializes a timer object 3332ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @instance: Adapter soft state 3333ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @timer: timer object to be initialized 3334ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @fn: timer function 3335ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @interval: time interval between timer function call 3336ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang */ 3337ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangstatic inline void 3338ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangmegasas_start_timer(struct megasas_instance *instance, 3339ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang struct timer_list *timer, 3340ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang void *fn, unsigned long interval) 3341ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang{ 3342ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang init_timer(timer); 3343ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang timer->expires = jiffies + interval; 3344ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang timer->data = (unsigned long)instance; 3345ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang timer->function = fn; 3346ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang add_timer(timer); 3347ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang} 3348ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 3349ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang/** 3350ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * megasas_io_completion_timer - Timer fn 3351ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @instance_addr: Address of adapter soft state 3352ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * 3353ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * Schedules tasklet for cmd completion 3354ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * if poll_mode_io is set 3355ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang */ 3356ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangstatic void 3357ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangmegasas_io_completion_timer(unsigned long instance_addr) 3358ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang{ 3359ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang struct megasas_instance *instance = 3360ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang (struct megasas_instance *)instance_addr; 3361ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 3362ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (atomic_read(&instance->fw_outstanding)) 3363ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang tasklet_schedule(&instance->isr_tasklet); 3364ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 3365ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang /* Restart timer */ 3366ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (poll_mode_io) 3367ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang mod_timer(&instance->io_completion_timer, 3368ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL); 3369ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang} 3370ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 3371cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordstatic u32 3372cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordmegasas_init_adapter_mfi(struct megasas_instance *instance) 3373c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3374cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct megasas_register_set __iomem *reg_set; 3375c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 context_sz; 3376c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 reply_q_sz; 3377c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3378c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas reg_set = instance->reg_set; 3379c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3380c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3381c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Get various operational parameters from status register 3382c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 33831341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF; 3384e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro /* 3385e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * Reduce the max supported cmds by 1. This is to ensure that the 3386e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * reply_q_sz (1 more than the max cmd that driver may send) 3387e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro * does not exceed max cmds that the FW can support 3388e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro */ 3389e3bbff9f3cf91c84c76cfdd5e80041ad1b487192Sumant Patro instance->max_fw_cmds = instance->max_fw_cmds-1; 33909c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->max_mfi_cmds = instance->max_fw_cmds; 33910d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> 33921341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro 0x10; 3393c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3394c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Create a pool of commands 3395c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3396c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_alloc_cmds(instance)) 3397c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_alloc_cmds; 3398c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3399c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3400c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Allocate memory for reply queue. Length of reply queue should 3401c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * be _one_ more than the maximum commands handled by the firmware. 3402c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3403c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Note: When FW completes commands, it places corresponding contex 3404c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * values in this circular reply queue. This circular queue is a fairly 3405c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * typical producer-consumer queue. FW is the producer (of completed 3406c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * commands) and the driver is the consumer. 3407c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3408c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas context_sz = sizeof(u32); 3409c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas reply_q_sz = context_sz * (instance->max_fw_cmds + 1); 3410c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3411c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->reply_queue = pci_alloc_consistent(instance->pdev, 3412c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas reply_q_sz, 3413c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &instance->reply_queue_h); 3414c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3415c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->reply_queue) { 3416c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n"); 3417c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_reply_queue; 3418c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3419c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 342031ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (megasas_issue_init_mfi(instance)) 3421c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_fw_init; 3422c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 342339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->fw_support_ieee = 0; 342439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->fw_support_ieee = 342539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang (instance->instancet->read_fw_status_reg(reg_set) & 342639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 0x04000000); 342739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 342839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas_init_mfi: fw_support_ieee=%d", 342939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->fw_support_ieee); 343039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 343139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->fw_support_ieee) 343239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->flag_ieee = 1; 343339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 3434cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return 0; 3435cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3436cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordfail_fw_init: 3437cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3438cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford pci_free_consistent(instance->pdev, reply_q_sz, 3439cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->reply_queue, instance->reply_queue_h); 3440cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordfail_reply_queue: 3441cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford megasas_free_cmds(instance); 3442cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3443cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordfail_alloc_cmds: 3444cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return 1; 3445cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford} 3446cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3447cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford/** 3448cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * megasas_init_fw - Initializes the FW 3449cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * @instance: Adapter soft state 3450cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * 3451cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * This is the main function for initializing firmware 3452cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford */ 3453cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3454cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordstatic int megasas_init_fw(struct megasas_instance *instance) 3455cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford{ 3456cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford u32 max_sectors_1; 3457cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford u32 max_sectors_2; 3458cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford u32 tmp_sectors; 3459cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct megasas_register_set __iomem *reg_set; 3460cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford struct megasas_ctrl_info *ctrl_info; 3461cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford unsigned long bar_list; 3462cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3463cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* Find first memory bar */ 3464cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM); 3465cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->bar = find_first_bit(&bar_list, sizeof(unsigned long)); 3466cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->base_addr = pci_resource_start(instance->pdev, instance->bar); 3467cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (pci_request_selected_regions(instance->pdev, instance->bar, 3468cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford "megasas: LSI")) { 3469cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford printk(KERN_DEBUG "megasas: IO memory region busy!\n"); 3470cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford return -EBUSY; 3471cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford } 3472cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3473cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->reg_set = ioremap_nocache(instance->base_addr, 8192); 3474cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3475cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (!instance->reg_set) { 3476cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford printk(KERN_DEBUG "megasas: Failed to map IO mem\n"); 3477cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford goto fail_ioremap; 3478cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford } 3479cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3480cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford reg_set = instance->reg_set; 3481cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3482cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford switch (instance->pdev->device) { 34839c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford case PCI_DEVICE_ID_LSI_FUSION: 34849c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->instancet = &megasas_instance_template_fusion; 34859c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 3486cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS1078R: 3487cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS1078DE: 3488cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet = &megasas_instance_template_ppc; 3489cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford break; 3490cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS1078GEN2: 3491cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS0079GEN2: 3492cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet = &megasas_instance_template_gen2; 3493cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford break; 3494cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS0073SKINNY: 3495cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS0071SKINNY: 3496cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet = &megasas_instance_template_skinny; 3497cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford break; 3498cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_LSI_SAS1064R: 3499cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford case PCI_DEVICE_ID_DELL_PERC5: 3500cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford default: 3501cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford instance->instancet = &megasas_instance_template_xscale; 3502cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford break; 3503cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford } 3504cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3505cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* 3506cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford * We expect the FW state to be READY 3507cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford */ 3508cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (megasas_transition_to_ready(instance)) 3509cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford goto fail_ready_state; 3510cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3511cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford /* Get operational params, sge flags, send init cmd to controller */ 3512cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford if (instance->instancet->init_adapter(instance)) 3513eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford goto fail_init_adapter; 3514cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 3515cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford printk(KERN_ERR "megasas: INIT adapter done\n"); 3516cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford 351739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang /** for passthrough 351839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang * the following function will get the PD LIST. 351939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang */ 352039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 352181e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo memset(instance->pd_list, 0 , 352281e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); 352381e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo megasas_get_pd_list(instance); 352481e403ce3c6a34cd705bf54d4cdeefdeb7068a8dYang, Bo 3525bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); 3526bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo megasas_get_ld_list(instance); 3527bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7dbYang, Bo 3528c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL); 3529c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3530c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3531c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Compute the max allowed sectors per IO: The controller info has two 3532c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * limits on max sectors. Driver should use the minimum of these two. 3533c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3534c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 1 << stripe_sz_ops.min = max sectors per strip 3535c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3536c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Note that older firmwares ( < FW ver 30) didn't report information 3537c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to calculate max_sectors_1. So the number ended up as zero always. 3538c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 353914faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang tmp_sectors = 0; 3540c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) { 3541c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3542c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) * 3543c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ctrl_info->max_strips_per_io; 3544c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas max_sectors_2 = ctrl_info->max_request_size; 3545c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 354614faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2); 354739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->disableOnlineCtrlReset = 354839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; 354914faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang } 355014faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang 355114faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang instance->max_sectors_per_req = instance->max_num_sge * 355214faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang PAGE_SIZE / 512; 355314faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors)) 355414faea9f7fe1e8805629b50cf14a65a85fe4a4fdbo yang instance->max_sectors_per_req = tmp_sectors; 3555c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3556c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(ctrl_info); 3557c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 35585d018ad057347995e5c4564b3e43339e6497f839Sumant Patro /* 35595d018ad057347995e5c4564b3e43339e6497f839Sumant Patro * Setup tasklet for cmd completion 35605d018ad057347995e5c4564b3e43339e6497f839Sumant Patro */ 35615d018ad057347995e5c4564b3e43339e6497f839Sumant Patro 3562f86c5424b02717a9eb9b1049a67ff3e7e9e92edfAdam Radford tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, 3563ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang (unsigned long)instance); 3564ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 3565ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang /* Initialize the cmd completion timer */ 3566ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (poll_mode_io) 3567ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang megasas_start_timer(instance, &instance->io_completion_timer, 3568ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang megasas_io_completion_timer, 3569ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang MEGASAS_COMPLETION_TIMER_INTERVAL); 3570c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3571c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3572eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radfordfail_init_adapter: 3573cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radfordfail_ready_state: 3574c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas iounmap(instance->reg_set); 3575c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3576c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_ioremap: 3577b6d5d8808b4c563a56414a4c4c6d652b5f87c088Adam Radford pci_release_selected_regions(instance->pdev, instance->bar); 3578c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3579c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EINVAL; 3580c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3581c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3582c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3583c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_release_mfi - Reverses the FW initialization 3584c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @intance: Adapter soft state 3585c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3586c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_release_mfi(struct megasas_instance *instance) 3587c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 35889c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1); 3589c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 35909c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (instance->reply_queue) 35919c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_free_consistent(instance->pdev, reply_q_sz, 3592c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->reply_queue, instance->reply_queue_h); 3593c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3594c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_free_cmds(instance); 3595c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3596c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas iounmap(instance->reg_set); 3597c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3598b6d5d8808b4c563a56414a4c4c6d652b5f87c088Adam Radford pci_release_selected_regions(instance->pdev, instance->bar); 3599c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3600c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3601c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3602c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_get_seq_num - Gets latest event sequence numbers 3603c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 3604c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @eli: FW event log sequence numbers information 3605c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3606c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * FW maintains a log of all events in a non-volatile area. Upper layers would 3607c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * usually find out the latest sequence number of the events, the seq number at 3608c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * the boot etc. They would "read" all the events below the latest seq number 3609c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq 3610c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * number), they would subsribe to AEN (asynchronous event notification) and 3611c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * wait for the events to happen. 3612c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3613c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 3614c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_get_seq_num(struct megasas_instance *instance, 3615c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_evt_log_info *eli) 3616c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3617c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 3618c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_dcmd_frame *dcmd; 3619c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_evt_log_info *el_info; 3620c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dma_addr_t el_info_h = 0; 3621c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3622c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 3623c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3624c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) { 3625c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3626c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3627c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3628c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd = &cmd->frame->dcmd; 3629c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas el_info = pci_alloc_consistent(instance->pdev, 3630c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sizeof(struct megasas_evt_log_info), 3631c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &el_info_h); 3632c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3633c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!el_info) { 3634c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 3635c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3636c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3637c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3638c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(el_info, 0, sizeof(*el_info)); 3639c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 3640c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3641c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd = MFI_CMD_DCMD; 3642c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd_status = 0x0; 3643c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sge_count = 1; 3644c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->flags = MFI_FRAME_DIR_READ; 3645c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->timeout = 0; 3646780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 3647c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->data_xfer_len = sizeof(struct megasas_evt_log_info); 3648c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO; 3649c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].phys_addr = el_info_h; 3650c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_log_info); 3651c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3652c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_issue_blocked_cmd(instance, cmd); 3653c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3654c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3655c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Copy the data back into callers buffer 3656c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3657c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memcpy(eli, el_info, sizeof(struct megasas_evt_log_info)); 3658c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3659c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info), 3660c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas el_info, el_info_h); 3661c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3662c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 3663c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3664c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3665c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3666c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3667c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3668c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_register_aen - Registers for asynchronous event notification 3669c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 3670c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @seq_num: The starting sequence number 3671c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @class_locale: Class of the event 3672c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3673c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function subscribes for AEN for events beyond the @seq_num. It requests 3674c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to be notified if and only if the event is of type @class_locale 3675c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3676c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 3677c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_register_aen(struct megasas_instance *instance, u32 seq_num, 3678c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas u32 class_locale_word) 3679c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3680c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int ret_val; 3681c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 3682c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_dcmd_frame *dcmd; 3683c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas union megasas_evt_class_locale curr_aen; 3684c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas union megasas_evt_class_locale prev_aen; 3685c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3686c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3687c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * If there an AEN pending already (aen_cmd), check if the 3688c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * class_locale of that pending AEN is inclusive of the new 3689c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * AEN request we currently have. If it is, then we don't have 3690c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to do anything. In other words, whichever events the current 3691c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * AEN request is subscribing to, have already been subscribed 3692c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * to. 3693c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3694c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * If the old_cmd is _not_ inclusive, then we have to abort 3695c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * that command, form a class_locale that is superset of both 3696c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * old and current and re-issue to the FW 3697c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3699c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas curr_aen.word = class_locale_word; 3700c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3701c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (instance->aen_cmd) { 3702c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3703c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1]; 3704c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3705c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3706c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * A class whose enum value is smaller is inclusive of all 3707c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * higher values. If a PROGRESS (= -1) was previously 3708c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * registered, then a new registration requests for higher 3709c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * classes need not be sent to FW. They are automatically 3710c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * included. 3711c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 3712c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Locale numbers don't have such hierarchy. They are bitmap 3713c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * values 3714c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3715c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if ((prev_aen.members.class <= curr_aen.members.class) && 3716c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas !((prev_aen.members.locale & curr_aen.members.locale) ^ 3717c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas curr_aen.members.locale)) { 3718c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3719c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Previously issued event registration includes 3720c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * current request. Nothing to do. 3721c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3722c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3723c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } else { 3724c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas curr_aen.members.locale |= prev_aen.members.locale; 3725c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3726c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (prev_aen.members.class < curr_aen.members.class) 3727c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas curr_aen.members.class = prev_aen.members.class; 3728c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3729c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->aen_cmd->abort_aen = 1; 3730c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ret_val = megasas_issue_blocked_abort_cmd(instance, 3731c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance-> 3732c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas aen_cmd); 3733c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3734c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ret_val) { 3735c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to abort " 3736c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "previous AEN command\n"); 3737c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return ret_val; 3738c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3739c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3740c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3741c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3742c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 3743c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3744c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) 3745c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 3746c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3747c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd = &cmd->frame->dcmd; 3748c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3749c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail)); 3750c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3751c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3752c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Prepare DCMD for aen registration 3753c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3754c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 3755c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3756c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd = MFI_CMD_DCMD; 3757c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd_status = 0x0; 3758c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sge_count = 1; 3759c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->flags = MFI_FRAME_DIR_READ; 3760c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->timeout = 0; 3761780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 376239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->last_seq_num = seq_num; 3763c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->data_xfer_len = sizeof(struct megasas_evt_detail); 3764c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT; 3765c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->mbox.w[0] = seq_num; 3766c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->mbox.w[1] = curr_aen.word; 3767c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h; 3768c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail); 3769c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3770f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo if (instance->aen_cmd != NULL) { 3771f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo megasas_return_cmd(instance, cmd); 3772f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo return 0; 3773f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo } 3774f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo 3775c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3776c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Store reference to the cmd used to register for AEN. When an 3777c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * application wants us to register for AEN, we have to abort this 3778c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * cmd and re-register with a new EVENT LOCALE supplied by that app 3779c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->aen_cmd = cmd; 3781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3783c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Issue the aen registration frame 3784c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 37859c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->instancet->issue_dcmd(instance, cmd); 3786c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3787c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3788c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3789c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3790c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3791c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_start_aen - Subscribes to AEN during driver load time 3792c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 3793c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3794c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_start_aen(struct megasas_instance *instance) 3795c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_evt_log_info eli; 3797c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas union megasas_evt_class_locale class_locale; 3798c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3799c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3800c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Get the latest sequence number from FW 3801c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3802c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(&eli, 0, sizeof(eli)); 3803c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3804c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_get_seq_num(instance, &eli)) 3805c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -1; 3806c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3807c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3808c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Register AEN with FW for latest sequence number plus 1 3809c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3810c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas class_locale.members.reserved = 0; 3811c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas class_locale.members.locale = MR_EVT_LOCALE_ALL; 3812c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas class_locale.members.class = MR_EVT_CLASS_DEBUG; 3813c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3814c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return megasas_register_aen(instance, eli.newest_seq_num + 1, 3815c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas class_locale.word); 3816c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3817c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3818c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3819c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_io_attach - Attaches this driver to SCSI mid-layer 3820c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 3821c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3822c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_io_attach(struct megasas_instance *instance) 3823c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 3824c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct Scsi_Host *host = instance->host; 3825c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3826c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3827c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Export parameters required by SCSI mid-layer 3828c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3829c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->irq = instance->pdev->irq; 3830c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->unique_id = instance->unique_id; 38317bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 38327bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { 38337bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo host->can_queue = 38347bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS; 38357bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo } else 38367bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo host->can_queue = 38377bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo instance->max_fw_cmds - MEGASAS_INT_CMDS; 3838c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->this_id = instance->init_id; 3839c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->sg_tablesize = instance->max_num_sge; 384042a8d2b34d107df34533ea4840daf8d62bdc90aaAdam Radford 384142a8d2b34d107df34533ea4840daf8d62bdc90aaAdam Radford if (instance->fw_support_ieee) 384242a8d2b34d107df34533ea4840daf8d62bdc90aaAdam Radford instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE; 384342a8d2b34d107df34533ea4840daf8d62bdc90aaAdam Radford 38441fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo /* 38451fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo * Check if the module parameter value for max_sectors can be used 38461fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo */ 38471fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo if (max_sectors && max_sectors < instance->max_sectors_per_req) 38481fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo instance->max_sectors_per_req = max_sectors; 38491fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo else { 38501fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo if (max_sectors) { 38511fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo if (((instance->pdev->device == 38521fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo PCI_DEVICE_ID_LSI_SAS1078GEN2) || 38531fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo (instance->pdev->device == 38541fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo PCI_DEVICE_ID_LSI_SAS0079GEN2)) && 38551fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo (max_sectors <= MEGASAS_MAX_SECTORS)) { 38561fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo instance->max_sectors_per_req = max_sectors; 38571fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo } else { 38581fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo printk(KERN_INFO "megasas: max_sectors should be > 0" 38591fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo "and <= %d (or < 1MB for GEN2 controller)\n", 38601fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo instance->max_sectors_per_req); 38611fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo } 38621fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo } 38631fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo } 38641fd106851698e9a858d20ab0e0f0afd5e9ec9332Yang, Bo 3865c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->max_sectors = instance->max_sectors_per_req; 38669c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN; 3867c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->max_channel = MEGASAS_MAX_CHANNELS - 1; 3868c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL; 3869c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host->max_lun = MEGASAS_MAX_LUN; 3870122da30223c06cee181044af6d32e88b256d10dfJoshua Giles host->max_cmd_len = 16; 3871c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 38729c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford /* Fusion only supports host reset */ 38739c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) { 38749c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford host->hostt->eh_device_reset_handler = NULL; 38759c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford host->hostt->eh_bus_reset_handler = NULL; 38769c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 38779c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 3878c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3879c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Notify the mid-layer about the new controller 3880c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3881c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (scsi_add_host(host, &instance->pdev->dev)) { 3882c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: scsi_add_host failed\n"); 3883c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENODEV; 3884c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3885c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3886c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3887c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Trigger SCSI to scan our drives 3888c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3889c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scsi_scan_host(host); 3890c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 3891c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 3892c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 389331ea7088974c2405e19d72f17c2afb103ef19e02bo yangstatic int 389431ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_set_dma_mask(struct pci_dev *pdev) 389531ea7088974c2405e19d72f17c2afb103ef19e02bo yang{ 389631ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 389731ea7088974c2405e19d72f17c2afb103ef19e02bo yang * All our contollers are capable of performing 64-bit DMA 389831ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 389931ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (IS_DMA64) { 39006a35528a8346f6e6fd32ed7e51f04d1fa4ca2c01Yang Hongyang if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) { 390131ea7088974c2405e19d72f17c2afb103ef19e02bo yang 3902284901a90a9e0b812ca3f5f852cbbfb60d10249dYang Hongyang if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) 390331ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_set_dma_mask; 390431ea7088974c2405e19d72f17c2afb103ef19e02bo yang } 390531ea7088974c2405e19d72f17c2afb103ef19e02bo yang } else { 3906284901a90a9e0b812ca3f5f852cbbfb60d10249dYang Hongyang if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) 390731ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_set_dma_mask; 390831ea7088974c2405e19d72f17c2afb103ef19e02bo yang } 390931ea7088974c2405e19d72f17c2afb103ef19e02bo yang return 0; 391031ea7088974c2405e19d72f17c2afb103ef19e02bo yang 391131ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_set_dma_mask: 391231ea7088974c2405e19d72f17c2afb103ef19e02bo yang return 1; 391331ea7088974c2405e19d72f17c2afb103ef19e02bo yang} 391431ea7088974c2405e19d72f17c2afb103ef19e02bo yang 3915c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 3916c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_probe_one - PCI hotplug entry point 3917c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @pdev: PCI device structure 39180d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford * @id: PCI ids of supported hotplugged adapter 3919c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3920c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int __devinit 3921c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) 3922c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 392366192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford int rval, pos; 3924c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct Scsi_Host *host; 3925c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 392666192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford u16 control = 0; 392766192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford 392866192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford /* Reset MSI-X in the kdump kernel */ 392966192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford if (reset_devices) { 393066192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); 393166192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford if (pos) { 393266192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford pci_read_config_word(pdev, msi_control_reg(pos), 393366192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford &control); 393466192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford if (control & PCI_MSIX_FLAGS_ENABLE) { 393566192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford dev_info(&pdev->dev, "resetting MSI-X\n"); 393666192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford pci_write_config_word(pdev, 393766192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford msi_control_reg(pos), 393866192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford control & 393966192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford ~PCI_MSIX_FLAGS_ENABLE); 394066192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford } 394166192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford } 394266192dfe1e74eae31a76cfc36092dabdba1324e6Adam Radford } 3943c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3944c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3945c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Announce PCI information 3946c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3947c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_INFO "megasas: %#4.04x:%#4.04x:%#4.04x:%#4.04x: ", 3948c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pdev->vendor, pdev->device, pdev->subsystem_vendor, 3949c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pdev->subsystem_device); 3950c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3951c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk("bus %d:slot %d:func %d\n", 3952c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); 3953c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3954c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 3955c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI prepping: enable device set bus mastering and dma mask 3956c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 3957aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii rval = pci_enable_device_mem(pdev); 3958c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3959c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (rval) { 3960c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return rval; 3961c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3962c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3963c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_set_master(pdev); 3964c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 396531ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (megasas_set_dma_mask(pdev)) 396631ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_set_dma_mask; 3967c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3968c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host = scsi_host_alloc(&megasas_template, 3969c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sizeof(struct megasas_instance)); 3970c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3971c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!host) { 3972c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: scsi_host_alloc failed\n"); 3973c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_alloc_instance; 3974c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 3975c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 3976c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = (struct megasas_instance *)host->hostdata; 3977c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(instance, 0, sizeof(*instance)); 397839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang atomic_set( &instance->fw_reset_no_pci_access, 0 ); 39799c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->pdev = pdev; 3980c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 39819c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford switch (instance->pdev->device) { 39829c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford case PCI_DEVICE_ID_LSI_FUSION: 39839c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford { 39849c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford struct fusion_context *fusion; 39859c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 39869c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->ctrl_context = 39879c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford kzalloc(sizeof(struct fusion_context), GFP_KERNEL); 39889c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (!instance->ctrl_context) { 39899c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford printk(KERN_DEBUG "megasas: Failed to allocate " 39909c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford "memory for Fusion context info\n"); 39919c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford goto fail_alloc_dma_buf; 39929c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 39939c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion = instance->ctrl_context; 39949c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford INIT_LIST_HEAD(&fusion->cmd_pool); 39959c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford spin_lock_init(&fusion->cmd_pool_lock); 39969c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 39979c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 39989c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford default: /* For all other supported controllers */ 39999c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 40009c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->producer = 40019c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_alloc_consistent(pdev, sizeof(u32), 40029c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->producer_h); 40039c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->consumer = 40049c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_alloc_consistent(pdev, sizeof(u32), 40059c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford &instance->consumer_h); 40069c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford 40079c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (!instance->producer || !instance->consumer) { 40089c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford printk(KERN_DEBUG "megasas: Failed to allocate" 40099c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford "memory for producer, consumer\n"); 40109c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford goto fail_alloc_dma_buf; 40119c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 4012c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 40139c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford *instance->producer = 0; 40149c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford *instance->consumer = 0; 40159c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 4016c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4017c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4018c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo megasas_poll_wait_aen = 0; 4019f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo instance->flag_ieee = 0; 40207e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo instance->ev = NULL; 402139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->issuepend_done = 1; 402239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->adprecovery = MEGASAS_HBA_OPERATIONAL; 402339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang megasas_poll_wait_aen = 0; 4024c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4025c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->evt_detail = pci_alloc_consistent(pdev, 4026c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sizeof(struct 4027c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_evt_detail), 4028c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &instance->evt_detail_h); 4029c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4030c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance->evt_detail) { 4031c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to allocate memory for " 4032c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "event detail structure\n"); 4033c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_alloc_dma_buf; 4034c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4035c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4036c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4037c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Initialize locks and queues 4038c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4039c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas INIT_LIST_HEAD(&instance->cmd_pool); 404039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang INIT_LIST_HEAD(&instance->internal_reset_pending_q); 4041c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4042e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro atomic_set(&instance->fw_outstanding,0); 4043e4a082c7c1f9a7b11fece6918e7ee5519b39ac46Sumant Patro 4044c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas init_waitqueue_head(&instance->int_cmd_wait_q); 4045c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas init_waitqueue_head(&instance->abort_cmd_wait_q); 4046c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4047c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas spin_lock_init(&instance->cmd_pool_lock); 404839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_init(&instance->hba_lock); 40497343eb6570ae3b299e7b5185b139d8335ef60e9bbo yang spin_lock_init(&instance->completion_lock); 4050c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_lock_init(&poll_aen_lock); 4051c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4052e5a69e27cc193f98c9a5a9086e3bf85528170623Matthias Kaehlcke mutex_init(&instance->aen_mutex); 40539c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford mutex_init(&instance->reset_mutex); 4054c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4055c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4056c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Initialize PCI related and misc parameters 4057c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4058c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->host = host; 4059c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->unique_id = pdev->bus->number << 8 | pdev->devfn; 4060c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->init_id = MEGASAS_DEFAULT_INIT_ID; 4061c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 40627bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 40637bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { 4064f4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0aYang, Bo instance->flag_ieee = 1; 40657bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS); 40667bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo } else 40677bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS); 40687bebf5c79cb62766c76c6c1b9c77b86496fd363eYang, Bo 4069658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro megasas_dbg_lvl = 0; 407005e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance->flag = 0; 40710c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo instance->unload = 1; 407205e9ebbefb379a4da782b21b8427c88ac28a2334Sumant Patro instance->last_time = 0; 407339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang instance->disableOnlineCtrlReset = 1; 407439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 40759c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) 40769c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq); 40779c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford else 40789c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford INIT_WORK(&instance->work_init, process_fw_state_change_wq); 4079658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 408080d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford /* Try to enable MSI-X */ 408180d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford if ((instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078R) && 408280d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford (instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078DE) && 408380d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford (instance->pdev->device != PCI_DEVICE_ID_LSI_VERDE_ZCR) && 408480d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford !msix_disable && !pci_enable_msix(instance->pdev, 408580d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford &instance->msixentry, 1)) 408680d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford instance->msi_flag = 1; 408780d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford 4088c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 40890a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford * Initialize MFI Firmware 40900a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford */ 40910a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford if (megasas_init_fw(instance)) 40920a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford goto fail_init_mfi; 40930a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford 40940a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford /* 4095c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Register IRQ 4096c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 409780d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford if (request_irq(instance->msi_flag ? instance->msixentry.vector : 4098cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford pdev->irq, instance->instancet->service_isr, 409980d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford IRQF_SHARED, "megasas", instance)) { 4100c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); 4101c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_irq; 4102c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4103c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 41041341c939222f4d1cc8d9eb2b794f26f089fe0a61Sumant Patro instance->instancet->enable_intr(instance->reg_set); 4105c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4106c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4107c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Store instance in PCI softstate 4108c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4109c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_set_drvdata(pdev, instance); 4110c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4111c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4112c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Add this controller to megasas_mgmt_info structure so that it 4113c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * can be exported to management applications 4114c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4115c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.count++; 4116c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance; 4117c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.max_index++; 4118c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4119c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4120c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Initiate AEN (Asynchronous Event Notification) 4121c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4122c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_start_aen(instance)) { 4123c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: start aen failed\n"); 4124c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_start_aen; 4125c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4126c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4127c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4128c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Register with SCSI mid-layer 4129c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4130c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_io_attach(instance)) 4131c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto fail_io_attach; 4132c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 41330c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo instance->unload = 0; 4134c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 4135c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4136c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_start_aen: 4137c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_io_attach: 4138c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.count--; 4139c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL; 4140c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.max_index--; 4141c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4142c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_set_drvdata(pdev, NULL); 4143b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro instance->instancet->disable_intr(instance->reg_set); 414480d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford free_irq(instance->msi_flag ? instance->msixentry.vector : 414580d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford instance->pdev->irq, instance); 4146eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radfordfail_irq: 4147eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) 4148eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford megasas_release_fusion(instance); 4149eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford else 4150eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford megasas_release_mfi(instance); 4151c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_init_mfi: 41520a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford if (instance->msi_flag) 41530a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford pci_disable_msix(instance->pdev); 4154c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_alloc_dma_buf: 4155c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (instance->evt_detail) 4156c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), 4157c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->evt_detail, 4158c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->evt_detail_h); 4159c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4160eb1b12377376e43aae4be338ffbbc32931ca4d10Adam Radford if (instance->producer) 4161c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_free_consistent(pdev, sizeof(u32), instance->producer, 4162c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->producer_h); 4163c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (instance->consumer) 4164c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_free_consistent(pdev, sizeof(u32), instance->consumer, 4165c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance->consumer_h); 4166c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scsi_host_put(host); 4167c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4168c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_alloc_instance: 4169c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas fail_set_dma_mask: 4170c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_disable_device(pdev); 4171c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4172c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENODEV; 4173c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4174c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4175c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4176c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_flush_cache - Requests FW to flush all its caches 4177c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 4178c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4179c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_flush_cache(struct megasas_instance *instance) 4180c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4181c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 4182c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_dcmd_frame *dcmd; 4183c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 418439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) 418539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return; 418639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 4187c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 4188c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4189c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) 4190c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 4191c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4192c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd = &cmd->frame->dcmd; 4193c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4194c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 4195c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4196c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd = MFI_CMD_DCMD; 4197c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd_status = 0x0; 4198c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sge_count = 0; 4199c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->flags = MFI_FRAME_DIR_NONE; 4200c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->timeout = 0; 4201780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 4202c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->data_xfer_len = 0; 4203c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH; 4204c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; 4205c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4206c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_issue_blocked_cmd(instance, cmd); 4207c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4208c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 4209c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4210c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 4211c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4212c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4213c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4214c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_shutdown_controller - Instructs FW to shutdown the controller 4215c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 421631ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @opcode: Shutdown/Hibernate 4217c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 421831ea7088974c2405e19d72f17c2afb103ef19e02bo yangstatic void megasas_shutdown_controller(struct megasas_instance *instance, 421931ea7088974c2405e19d72f17c2afb103ef19e02bo yang u32 opcode) 4220c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4221c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 4222c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_dcmd_frame *dcmd; 4223c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 422439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) 422539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return; 422639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 4227c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 4228c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4229c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) 4230c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 4231c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4232c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (instance->aen_cmd) 4233c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd); 42349c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (instance->map_update_cmd) 42359c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_issue_blocked_abort_cmd(instance, 42369c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->map_update_cmd); 4237c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd = &cmd->frame->dcmd; 4238c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4239c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 4240c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4241c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd = MFI_CMD_DCMD; 4242c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->cmd_status = 0x0; 4243c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->sge_count = 0; 4244c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->flags = MFI_FRAME_DIR_NONE; 4245c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->timeout = 0; 4246780a3762fb9208748baac5aa9c63a4d4c9287753Yang, Bo dcmd->pad_0 = 0; 4247c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dcmd->data_xfer_len = 0; 424831ea7088974c2405e19d72f17c2afb103ef19e02bo yang dcmd->opcode = opcode; 4249c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4250c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_issue_blocked_cmd(instance, cmd); 4251c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4252c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 4253c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4254c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 4255c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4256c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 425733139b21013aba815924b421159fab35e5175483Jiri Slaby#ifdef CONFIG_PM 4258c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4259ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * megasas_suspend - driver suspend entry point 4260ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * @pdev: PCI device structure 426131ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @state: PCI power state to suspend routine 426231ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 426333139b21013aba815924b421159fab35e5175483Jiri Slabystatic int 426431ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_suspend(struct pci_dev *pdev, pm_message_t state) 426531ea7088974c2405e19d72f17c2afb103ef19e02bo yang{ 426631ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct Scsi_Host *host; 426731ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct megasas_instance *instance; 426831ea7088974c2405e19d72f17c2afb103ef19e02bo yang 426931ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance = pci_get_drvdata(pdev); 427031ea7088974c2405e19d72f17c2afb103ef19e02bo yang host = instance->host; 42710c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo instance->unload = 1; 427231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 4273ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (poll_mode_io) 4274ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang del_timer_sync(&instance->io_completion_timer); 4275ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 427631ea7088974c2405e19d72f17c2afb103ef19e02bo yang megasas_flush_cache(instance); 427731ea7088974c2405e19d72f17c2afb103ef19e02bo yang megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN); 42787e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 42797e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo /* cancel the delayed work if this work still in queue */ 42807e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (instance->ev != NULL) { 42817e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct megasas_aen_event *ev = instance->ev; 4282a684b8da35a429a246ec2a91e2742bdff5209709Tejun Heo cancel_delayed_work_sync( 42837e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo (struct delayed_work *)&ev->hotplug_work); 42847e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo instance->ev = NULL; 42857e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 42867e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 428731ea7088974c2405e19d72f17c2afb103ef19e02bo yang tasklet_kill(&instance->isr_tasklet); 428831ea7088974c2405e19d72f17c2afb103ef19e02bo yang 428931ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_set_drvdata(instance->pdev, instance); 429031ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->instancet->disable_intr(instance->reg_set); 429180d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford free_irq(instance->msi_flag ? instance->msixentry.vector : 429280d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford instance->pdev->irq, instance); 429380d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford if (instance->msi_flag) 429480d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford pci_disable_msix(instance->pdev); 429531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 429631ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_save_state(pdev); 429731ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_disable_device(pdev); 429831ea7088974c2405e19d72f17c2afb103ef19e02bo yang 429931ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_set_power_state(pdev, pci_choose_state(pdev, state)); 430031ea7088974c2405e19d72f17c2afb103ef19e02bo yang 430131ea7088974c2405e19d72f17c2afb103ef19e02bo yang return 0; 430231ea7088974c2405e19d72f17c2afb103ef19e02bo yang} 430331ea7088974c2405e19d72f17c2afb103ef19e02bo yang 430431ea7088974c2405e19d72f17c2afb103ef19e02bo yang/** 430531ea7088974c2405e19d72f17c2afb103ef19e02bo yang * megasas_resume- driver resume entry point 430631ea7088974c2405e19d72f17c2afb103ef19e02bo yang * @pdev: PCI device structure 430731ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 430833139b21013aba815924b421159fab35e5175483Jiri Slabystatic int 430931ea7088974c2405e19d72f17c2afb103ef19e02bo yangmegasas_resume(struct pci_dev *pdev) 431031ea7088974c2405e19d72f17c2afb103ef19e02bo yang{ 431131ea7088974c2405e19d72f17c2afb103ef19e02bo yang int rval; 431231ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct Scsi_Host *host; 431331ea7088974c2405e19d72f17c2afb103ef19e02bo yang struct megasas_instance *instance; 431431ea7088974c2405e19d72f17c2afb103ef19e02bo yang 431531ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance = pci_get_drvdata(pdev); 431631ea7088974c2405e19d72f17c2afb103ef19e02bo yang host = instance->host; 431731ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_set_power_state(pdev, PCI_D0); 431831ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_enable_wake(pdev, PCI_D0, 0); 431931ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_restore_state(pdev); 432031ea7088974c2405e19d72f17c2afb103ef19e02bo yang 432131ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 432231ea7088974c2405e19d72f17c2afb103ef19e02bo yang * PCI prepping: enable device set bus mastering and dma mask 432331ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 4324aeab3fd7b865bc4086a80a83cfdd67dded3b41a0Noriyuki Fujii rval = pci_enable_device_mem(pdev); 432531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 432631ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (rval) { 432731ea7088974c2405e19d72f17c2afb103ef19e02bo yang printk(KERN_ERR "megasas: Enable device failed\n"); 432831ea7088974c2405e19d72f17c2afb103ef19e02bo yang return rval; 432931ea7088974c2405e19d72f17c2afb103ef19e02bo yang } 433031ea7088974c2405e19d72f17c2afb103ef19e02bo yang 433131ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_set_master(pdev); 433231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 433331ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (megasas_set_dma_mask(pdev)) 433431ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_set_dma_mask; 433531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 43360a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford /* Now re-enable MSI-X */ 43370a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford if (instance->msi_flag) 43380a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford pci_enable_msix(instance->pdev, &instance->msixentry, 1); 43390a77066acc78b4048b0afc9d70b7e91c06e63356Adam Radford 434031ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 434131ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Initialize MFI Firmware 434231ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 434331ea7088974c2405e19d72f17c2afb103ef19e02bo yang 434431ea7088974c2405e19d72f17c2afb103ef19e02bo yang atomic_set(&instance->fw_outstanding, 0); 434531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 434631ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 434731ea7088974c2405e19d72f17c2afb103ef19e02bo yang * We expect the FW state to be READY 434831ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 434931ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (megasas_transition_to_ready(instance)) 435031ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_ready_state; 435131ea7088974c2405e19d72f17c2afb103ef19e02bo yang 43529c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford switch (instance->pdev->device) { 43539c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford case PCI_DEVICE_ID_LSI_FUSION: 43549c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford { 43559c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_reset_reply_desc(instance); 43569c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (megasas_ioc_init_fusion(instance)) { 43579c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_free_cmds(instance); 43589c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_free_cmds_fusion(instance); 43599c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford goto fail_init_mfi; 43609c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 43619c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (!megasas_get_map_info(instance)) 43629c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_sync_map_info(instance); 43639c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 43649c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 43659c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford default: 43669c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford *instance->producer = 0; 43679c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford *instance->consumer = 0; 43689c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (megasas_issue_init_mfi(instance)) 43699c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford goto fail_init_mfi; 43709c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 43719c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 437231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 43739c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, 43749c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford (unsigned long)instance); 437531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 437631ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 437731ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Register IRQ 437831ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 437980d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford if (request_irq(instance->msi_flag ? instance->msixentry.vector : 4380cd50ba8ede5cd3c4606a8e5d163913da5ff36ad7Adam Radford pdev->irq, instance->instancet->service_isr, 438180d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford IRQF_SHARED, "megasas", instance)) { 438231ea7088974c2405e19d72f17c2afb103ef19e02bo yang printk(KERN_ERR "megasas: Failed to register IRQ\n"); 438331ea7088974c2405e19d72f17c2afb103ef19e02bo yang goto fail_irq; 438431ea7088974c2405e19d72f17c2afb103ef19e02bo yang } 438531ea7088974c2405e19d72f17c2afb103ef19e02bo yang 438631ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->instancet->enable_intr(instance->reg_set); 438731ea7088974c2405e19d72f17c2afb103ef19e02bo yang 438831ea7088974c2405e19d72f17c2afb103ef19e02bo yang /* 438931ea7088974c2405e19d72f17c2afb103ef19e02bo yang * Initiate AEN (Asynchronous Event Notification) 439031ea7088974c2405e19d72f17c2afb103ef19e02bo yang */ 439131ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (megasas_start_aen(instance)) 439231ea7088974c2405e19d72f17c2afb103ef19e02bo yang printk(KERN_ERR "megasas: Start AEN failed\n"); 439331ea7088974c2405e19d72f17c2afb103ef19e02bo yang 4394ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang /* Initialize the cmd completion timer */ 4395ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (poll_mode_io) 4396ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang megasas_start_timer(instance, &instance->io_completion_timer, 4397ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang megasas_io_completion_timer, 4398ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang MEGASAS_COMPLETION_TIMER_INTERVAL); 43990c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo instance->unload = 0; 44000c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo 440131ea7088974c2405e19d72f17c2afb103ef19e02bo yang return 0; 440231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 440331ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_irq: 440431ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_init_mfi: 440531ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (instance->evt_detail) 440631ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), 440731ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->evt_detail, 440831ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->evt_detail_h); 440931ea7088974c2405e19d72f17c2afb103ef19e02bo yang 441031ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (instance->producer) 441131ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_free_consistent(pdev, sizeof(u32), instance->producer, 441231ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->producer_h); 441331ea7088974c2405e19d72f17c2afb103ef19e02bo yang if (instance->consumer) 441431ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_free_consistent(pdev, sizeof(u32), instance->consumer, 441531ea7088974c2405e19d72f17c2afb103ef19e02bo yang instance->consumer_h); 441631ea7088974c2405e19d72f17c2afb103ef19e02bo yang scsi_host_put(host); 441731ea7088974c2405e19d72f17c2afb103ef19e02bo yang 441831ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_set_dma_mask: 441931ea7088974c2405e19d72f17c2afb103ef19e02bo yangfail_ready_state: 442031ea7088974c2405e19d72f17c2afb103ef19e02bo yang 442131ea7088974c2405e19d72f17c2afb103ef19e02bo yang pci_disable_device(pdev); 442231ea7088974c2405e19d72f17c2afb103ef19e02bo yang 442331ea7088974c2405e19d72f17c2afb103ef19e02bo yang return -ENODEV; 442431ea7088974c2405e19d72f17c2afb103ef19e02bo yang} 442533139b21013aba815924b421159fab35e5175483Jiri Slaby#else 442633139b21013aba815924b421159fab35e5175483Jiri Slaby#define megasas_suspend NULL 442733139b21013aba815924b421159fab35e5175483Jiri Slaby#define megasas_resume NULL 442833139b21013aba815924b421159fab35e5175483Jiri Slaby#endif 442931ea7088974c2405e19d72f17c2afb103ef19e02bo yang 443031ea7088974c2405e19d72f17c2afb103ef19e02bo yang/** 4431c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_detach_one - PCI hot"un"plug entry point 4432c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @pdev: PCI device structure 4433c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 443433139b21013aba815924b421159fab35e5175483Jiri Slabystatic void __devexit megasas_detach_one(struct pci_dev *pdev) 4435c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4436c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 4437c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct Scsi_Host *host; 4438c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 44399c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford struct fusion_context *fusion; 4440c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4441c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = pci_get_drvdata(pdev); 4442c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo instance->unload = 1; 4443c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas host = instance->host; 44449c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion = instance->ctrl_context; 4445c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4446ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (poll_mode_io) 4447ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang del_timer_sync(&instance->io_completion_timer); 4448ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 4449c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scsi_remove_host(instance->host); 4450c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_flush_cache(instance); 445131ea7088974c2405e19d72f17c2afb103ef19e02bo yang megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); 44527e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 44537e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo /* cancel the delayed work if this work still in queue*/ 44547e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (instance->ev != NULL) { 44557e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct megasas_aen_event *ev = instance->ev; 4456a684b8da35a429a246ec2a91e2742bdff5209709Tejun Heo cancel_delayed_work_sync( 44577e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo (struct delayed_work *)&ev->hotplug_work); 44587e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo instance->ev = NULL; 44597e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 44607e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 44615d018ad057347995e5c4564b3e43339e6497f839Sumant Patro tasklet_kill(&instance->isr_tasklet); 4462c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4463c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4464c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Take the instance off the instance array. Note that we will not 4465c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * decrement the max_index. We let this array be sparse array 4466c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4467c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < megasas_mgmt_info.max_index; i++) { 4468c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (megasas_mgmt_info.instance[i] == instance) { 4469c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.count--; 4470c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_info.instance[i] = NULL; 4471c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4472c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas break; 4473c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4474c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4475c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4476c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_set_drvdata(instance->pdev, NULL); 4477c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4478b274cab779219325fd480cc696a456d1c3893bd8Sumant Patro instance->instancet->disable_intr(instance->reg_set); 4479c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 448080d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford free_irq(instance->msi_flag ? instance->msixentry.vector : 448180d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford instance->pdev->irq, instance); 448280d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford if (instance->msi_flag) 448380d9da98b4034edd31f6bacdb96c7489c4460173Adam Radford pci_disable_msix(instance->pdev); 4484c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 44859c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford switch (instance->pdev->device) { 44869c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford case PCI_DEVICE_ID_LSI_FUSION: 44879c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_release_fusion(instance); 44889c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford for (i = 0; i < 2 ; i++) 44899c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford if (fusion->ld_map[i]) 44909c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford dma_free_coherent(&instance->pdev->dev, 44919c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->map_sz, 44929c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion->ld_map[i], 44939c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford fusion-> 44949c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford ld_map_phys[i]); 44959c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford kfree(instance->ctrl_context); 44969c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 44979c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford default: 44989c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford megasas_release_mfi(instance); 44999c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_free_consistent(pdev, 45009c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford sizeof(struct megasas_evt_detail), 45019c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->evt_detail, 45029c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->evt_detail_h); 45039c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_free_consistent(pdev, sizeof(u32), 45049c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->producer, 45059c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->producer_h); 45069c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford pci_free_consistent(pdev, sizeof(u32), 45079c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->consumer, 45089c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford instance->consumer_h); 45099c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford break; 45109c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford } 4511c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4512c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas scsi_host_put(host); 4513c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4514c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_set_drvdata(pdev, NULL); 4515c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4516c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_disable_device(pdev); 4517c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4518c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return; 4519c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4520c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4521c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4522c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_shutdown - Shutdown entry point 4523c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @device: Generic device structure 4524c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4525c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void megasas_shutdown(struct pci_dev *pdev) 4526c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4527c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance = pci_get_drvdata(pdev); 45280c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo instance->unload = 1; 4529c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_flush_cache(instance); 4530530e6fc1e05f14762aea954ca8d6422c5a7077c1Yang, Bo megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); 4531c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4532c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4533c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4534c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_open - char node "open" entry point 4535c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4536c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_open(struct inode *inode, struct file *filep) 4537c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4538c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4539c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Allow only those users with admin rights 4540c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4541c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!capable(CAP_SYS_ADMIN)) 4542c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EACCES; 4543c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4544c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 4545c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4546c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4547c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4548c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_fasync - Async notifier registration from applications 4549c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * 4550c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * This function adds the calling process to a driver global queue. When an 4551c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * event occurs, SIGIO will be sent to all processes in this queue. 4552c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4553c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_fasync(int fd, struct file *filep, int mode) 4554c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4555c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int rc; 4556c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 45570b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_lock(&megasas_async_queue_mutex); 4558c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4559c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas rc = fasync_helper(fd, filep, mode, &megasas_async_queue); 4560c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 45610b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_unlock(&megasas_async_queue_mutex); 4562c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4563c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (rc >= 0) { 4564c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* For sanity check when we get ioctl */ 4565c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas filep->private_data = filep; 4566c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return 0; 4567c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4568c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4569c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc); 4570c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4571c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return rc; 4572c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4573c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4574c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4575c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo * megasas_mgmt_poll - char node "poll" entry point 4576c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo * */ 4577c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bostatic unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait) 4578c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo{ 4579c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo unsigned int mask; 4580c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo unsigned long flags; 4581c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo poll_wait(file, &megasas_poll_wait, wait); 4582c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_lock_irqsave(&poll_aen_lock, flags); 4583c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo if (megasas_poll_wait_aen) 4584c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo mask = (POLLIN | POLLRDNORM); 4585c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo else 4586c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo mask = 0; 4587c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo spin_unlock_irqrestore(&poll_aen_lock, flags); 4588c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo return mask; 4589c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo} 4590c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo 4591c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo/** 4592c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_fw_ioctl - Issues management ioctls to FW 4593c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @instance: Adapter soft state 4594c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * @argp: User's ioctl packet 4595c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4596c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int 4597c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_mgmt_fw_ioctl(struct megasas_instance *instance, 4598c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_iocpacket __user * user_ioc, 4599c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_iocpacket *ioc) 4600c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4601c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_sge32 *kern_sge32; 4602c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_cmd *cmd; 4603c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas void *kbuff_arr[MAX_IOCTL_SGE]; 4604c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dma_addr_t buf_handle = 0; 4605c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int error = 0, i; 4606c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas void *sense = NULL; 4607c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas dma_addr_t sense_handle; 46087b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo unsigned long *sense_ptr; 4609c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4610c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(kbuff_arr, 0, sizeof(kbuff_arr)); 4611c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4612c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ioc->sge_count > MAX_IOCTL_SGE) { 4613c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: SGE count [%d] > max limit [%d]\n", 4614c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ioc->sge_count, MAX_IOCTL_SGE); 4615c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EINVAL; 4616c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4617c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4618c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd = megasas_get_cmd(instance); 4619c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!cmd) { 4620c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to get a cmd packet\n"); 4621c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 4622c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4623c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4624c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4625c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * User's IOCTL packet has 2 frames (maximum). Copy those two 4626c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * frames into our cmd's frames. cmd->frame's context will get 4627c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * overwritten when we copy from user's frames. So set that value 4628c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * alone separately 4629c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4630c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE); 4631c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->frame->hdr.context = cmd->index; 4632c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo cmd->frame->hdr.pad_0 = 0; 4633c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4634c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4635c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * The management interface between applications and the fw uses 4636c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * MFI frames. E.g, RAID configuration changes, LD property changes 4637c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * etc are accomplishes through different kinds of MFI frames. The 4638c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * driver needs to care only about substituting user buffers with 4639c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * kernel buffers in SGLs. The location of SGL is embedded in the 4640c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * struct iocpacket itself. 4641c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4642c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kern_sge32 = (struct megasas_sge32 *) 4643c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ((unsigned long)cmd->frame + ioc->sgl_off); 4644c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4645c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4646c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * For each user buffer, create a mirror buffer and copy in 4647c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4648c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < ioc->sge_count; i++) { 464998cb7e4413d189cd2b54daf993a4667d9788c0bbBjørn Mork if (!ioc->sgl[i].iov_len) 465098cb7e4413d189cd2b54daf993a4667d9788c0bbBjørn Mork continue; 465198cb7e4413d189cd2b54daf993a4667d9788c0bbBjørn Mork 46529f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev, 4653c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ioc->sgl[i].iov_len, 46549f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro &buf_handle, GFP_KERNEL); 4655c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!kbuff_arr[i]) { 4656c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Failed to alloc " 4657c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "kernel SGL buffer for IOCTL \n"); 4658c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -ENOMEM; 4659c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out; 4660c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4661c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4662c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4663c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * We don't change the dma_coherent_mask, so 4664c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * pci_alloc_consistent only returns 32bit addresses 4665c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4666c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kern_sge32[i].phys_addr = (u32) buf_handle; 4667c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kern_sge32[i].length = ioc->sgl[i].iov_len; 4668c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4669c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4670c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * We created a kernel buffer corresponding to the 4671c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * user buffer. Now copy in from the user buffer 4672c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4673c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base, 4674c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas (u32) (ioc->sgl[i].iov_len))) { 4675c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -EFAULT; 4676c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out; 4677c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4678c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4679c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4680c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ioc->sense_len) { 46819f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len, 46829f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro &sense_handle, GFP_KERNEL); 4683c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!sense) { 4684c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -ENOMEM; 4685c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out; 4686c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4687c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4688c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sense_ptr = 46897b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off); 4690c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas *sense_ptr = sense_handle; 4691c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4692c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4693c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4694c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Set the sync_cmd flag so that the ISR knows not to complete this 4695c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * cmd to the SCSI mid-layer 4696c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4697c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sync_cmd = 1; 4698c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_issue_blocked_cmd(instance, cmd); 4699c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas cmd->sync_cmd = 0; 4700c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4701c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4702c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * copy out the kernel buffers to user buffers 4703c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4704c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < ioc->sge_count; i++) { 4705c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i], 4706c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ioc->sgl[i].iov_len)) { 4707c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -EFAULT; 4708c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out; 4709c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4710c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4711c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4712c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4713c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * copy out the sense 4714c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4715c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (ioc->sense_len) { 4716c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4717b70a41e077b3405d4b41d34db31b39c05bf142b5bo yang * sense_ptr points to the location that has the user 4718c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * sense buffer address 4719c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 47207b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw + 47217b2519afa1abd1b9f63aa1e90879307842422daeYang, Bo ioc->sense_off); 4722c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4723b70a41e077b3405d4b41d34db31b39c05bf142b5bo yang if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), 4724b70a41e077b3405d4b41d34db31b39c05bf142b5bo yang sense, ioc->sense_len)) { 4725b10c36a57552f03582c0ab3ece04f3cce791922dbo yang printk(KERN_ERR "megasas: Failed to copy out to user " 4726b10c36a57552f03582c0ab3ece04f3cce791922dbo yang "sense data\n"); 4727c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -EFAULT; 4728c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out; 4729c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4730c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4731c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4732c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4733c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * copy the status codes returned by the fw 4734c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4735c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_to_user(&user_ioc->frame.hdr.cmd_status, 4736c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &cmd->frame->hdr.cmd_status, sizeof(u8))) { 4737c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: Error copying out cmd_status\n"); 4738c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -EFAULT; 4739c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4740c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4741c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas out: 4742c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (sense) { 47439f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro dma_free_coherent(&instance->pdev->dev, ioc->sense_len, 4744c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas sense, sense_handle); 4745c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4746c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4747c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) { 47489f35fa8a14e6216a859e2dfbe50ade497f9603efSumant Patro dma_free_coherent(&instance->pdev->dev, 4749c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kern_sge32[i].length, 4750c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kbuff_arr[i], kern_sge32[i].phys_addr); 4751c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4752c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4753c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_return_cmd(instance, cmd); 4754c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return error; 4755c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4756c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4757c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg) 4758c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4759c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_iocpacket __user *user_ioc = 4760c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas (struct megasas_iocpacket __user *)arg; 4761c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_iocpacket *ioc; 4762c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 4763c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int error; 476439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang int i; 476539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 476639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 wait_time = MEGASAS_RESET_WAIT_TIME; 4767c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4768c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas ioc = kmalloc(sizeof(*ioc), GFP_KERNEL); 4769c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!ioc) 4770c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOMEM; 4771c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4772c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_from_user(ioc, user_ioc, sizeof(*ioc))) { 4773c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -EFAULT; 4774c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out_kfree_ioc; 4775c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4776c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4777c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = megasas_lookup_instance(ioc->host_no); 4778c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance) { 4779c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -ENODEV; 4780c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out_kfree_ioc; 4781c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4782c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 478339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { 478439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_ERR "Controller in crit error\n"); 47850c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo error = -ENODEV; 47860c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo goto out_kfree_ioc; 47870c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } 47880c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo 47890c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo if (instance->unload == 1) { 47900c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo error = -ENODEV; 47910c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo goto out_kfree_ioc; 47920c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } 47930c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo 4794c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 4795c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds 4796c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4797c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (down_interruptible(&instance->ioctl_sem)) { 4798c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = -ERESTARTSYS; 4799c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas goto out_kfree_ioc; 4800c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 480139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 480239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < wait_time; i++) { 480339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 480439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 480539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) { 480639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 480739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang break; 480839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 480939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 481039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 481139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { 481239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: waiting" 481339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "for controller reset to finish\n"); 481439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 481539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 481639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 481739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 481839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 481939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 482039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) { 482139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 482239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 482339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_ERR "megaraid_sas: timed out while" 482439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "waiting for HBA to recover\n"); 482539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang error = -ENODEV; 482639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang goto out_kfree_ioc; 482739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 482839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 482939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 4830c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc); 4831c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas up(&instance->ioctl_sem); 4832c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4833c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas out_kfree_ioc: 4834c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas kfree(ioc); 4835c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return error; 4836c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4837c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4838c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg) 4839c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4840c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_instance *instance; 4841c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_aen aen; 4842c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int error; 484339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang int i; 484439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang unsigned long flags; 484539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang u32 wait_time = MEGASAS_RESET_WAIT_TIME; 4846c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4847c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (file->private_data != file) { 4848c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: fasync_helper was not " 4849c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas "called first\n"); 4850c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EINVAL; 4851c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4852c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4853c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_from_user(&aen, (void __user *)arg, sizeof(aen))) 4854c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EFAULT; 4855c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4856c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas instance = megasas_lookup_instance(aen.host_no); 4857c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4858c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (!instance) 4859c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENODEV; 4860c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 486139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { 486239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return -ENODEV; 48630c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } 48640c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo 48650c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo if (instance->unload == 1) { 48660c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo return -ENODEV; 48670c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo } 48680c79e681eef10810a5ed41a2eb1dce244ab1c37dYang, Bo 486939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang for (i = 0; i < wait_time; i++) { 487039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 487139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 487239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) { 487339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, 487439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang flags); 487539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang break; 487639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 487739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 487839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 487939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 488039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { 488139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_NOTICE "megasas: waiting for" 488239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "controller reset to finish\n"); 488339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 488439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 488539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang msleep(1000); 488639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 488739a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 488839a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_lock_irqsave(&instance->hba_lock, flags); 488939a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) { 489039a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 489139a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang printk(KERN_ERR "megaraid_sas: timed out while waiting" 489239a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang "for HBA to recover.\n"); 489339a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang return -ENODEV; 489439a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang } 489539a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang spin_unlock_irqrestore(&instance->hba_lock, flags); 489639a985547cbfcbb0b23667b69b8ae82a6cf312acbo yang 4897e5a69e27cc193f98c9a5a9086e3bf85528170623Matthias Kaehlcke mutex_lock(&instance->aen_mutex); 4898c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = megasas_register_aen(instance, aen.seq_num, 4899c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas aen.class_locale_word); 4900e5a69e27cc193f98c9a5a9086e3bf85528170623Matthias Kaehlcke mutex_unlock(&instance->aen_mutex); 4901c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return error; 4902c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4903c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4904c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 4905c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_mgmt_ioctl - char node ioctl entry point 4906c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 4907c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic long 4908c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 4909c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4910c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas switch (cmd) { 4911c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MEGASAS_IOC_FIRMWARE: 4912c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return megasas_mgmt_ioctl_fw(file, arg); 4913c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4914c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MEGASAS_IOC_GET_AEN: 4915c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return megasas_mgmt_ioctl_aen(file, arg); 4916c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4917c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4918c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOTTY; 4919c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4920c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4921c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#ifdef CONFIG_COMPAT 4922c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) 4923c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4924c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct compat_megasas_iocpacket __user *cioc = 4925c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas (struct compat_megasas_iocpacket __user *)arg; 4926c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas struct megasas_iocpacket __user *ioc = 4927c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas compat_alloc_user_space(sizeof(struct megasas_iocpacket)); 4928c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int i; 4929c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int error = 0; 4930b3dc1a212e5167984616445990c76056034f8eebTomas Henzl compat_uptr_t ptr; 4931c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 493283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik if (clear_user(ioc, sizeof(*ioc))) 493383aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik return -EFAULT; 4934c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4935c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) || 4936c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) || 4937c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) || 4938c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) || 4939c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) || 4940c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32))) 4941c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EFAULT; 4942c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4943b3dc1a212e5167984616445990c76056034f8eebTomas Henzl /* 4944b3dc1a212e5167984616445990c76056034f8eebTomas Henzl * The sense_ptr is used in megasas_mgmt_fw_ioctl only when 4945b3dc1a212e5167984616445990c76056034f8eebTomas Henzl * sense_len is not null, so prepare the 64bit value under 4946b3dc1a212e5167984616445990c76056034f8eebTomas Henzl * the same condition. 4947b3dc1a212e5167984616445990c76056034f8eebTomas Henzl */ 4948b3dc1a212e5167984616445990c76056034f8eebTomas Henzl if (ioc->sense_len) { 4949b3dc1a212e5167984616445990c76056034f8eebTomas Henzl void __user **sense_ioc_ptr = 4950b3dc1a212e5167984616445990c76056034f8eebTomas Henzl (void __user **)(ioc->frame.raw + ioc->sense_off); 4951b3dc1a212e5167984616445990c76056034f8eebTomas Henzl compat_uptr_t *sense_cioc_ptr = 4952b3dc1a212e5167984616445990c76056034f8eebTomas Henzl (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off); 4953b3dc1a212e5167984616445990c76056034f8eebTomas Henzl if (get_user(ptr, sense_cioc_ptr) || 4954b3dc1a212e5167984616445990c76056034f8eebTomas Henzl put_user(compat_ptr(ptr), sense_ioc_ptr)) 4955b3dc1a212e5167984616445990c76056034f8eebTomas Henzl return -EFAULT; 4956b3dc1a212e5167984616445990c76056034f8eebTomas Henzl } 4957c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4958b3dc1a212e5167984616445990c76056034f8eebTomas Henzl for (i = 0; i < MAX_IOCTL_SGE; i++) { 4959c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (get_user(ptr, &cioc->sgl[i].iov_base) || 4960c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) || 4961c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas copy_in_user(&ioc->sgl[i].iov_len, 4962c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &cioc->sgl[i].iov_len, sizeof(compat_size_t))) 4963c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EFAULT; 4964c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4965c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4966c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc); 4967c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4968c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (copy_in_user(&cioc->frame.hdr.cmd_status, 4969c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas &ioc->frame.hdr.cmd_status, sizeof(u8))) { 4970c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n"); 4971c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -EFAULT; 4972c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4973c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return error; 4974c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4975c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4976c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic long 4977c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd, 4978c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas unsigned long arg) 4979c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 4980c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas switch (cmd) { 4981cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro case MEGASAS_IOC_FIRMWARE32: 4982cb59aa6a7ca1ae40fd436c45dff568a83f3fab2fSumant Patro return megasas_mgmt_compat_ioctl_fw(file, arg); 4983c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas case MEGASAS_IOC_GET_AEN: 4984c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return megasas_mgmt_ioctl_aen(file, arg); 4985c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 4986c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4987c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return -ENOTTY; 4988c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 4989c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#endif 4990c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 4991c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/* 4992c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * File operations structure for management interface 4993c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 499400977a59b951207d38380c75f03a36829950265cArjan van de Venstatic const struct file_operations megasas_mgmt_fops = { 4995c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .owner = THIS_MODULE, 4996c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .open = megasas_mgmt_open, 4997c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .fasync = megasas_mgmt_fasync, 4998c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .unlocked_ioctl = megasas_mgmt_ioctl, 4999c35188377f12e5e0a74f18c3dfdd67baf88db514Yang, Bo .poll = megasas_mgmt_poll, 5000c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#ifdef CONFIG_COMPAT 5001c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .compat_ioctl = megasas_mgmt_compat_ioctl, 5002c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas#endif 50036038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = noop_llseek, 5004c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}; 5005c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5006c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/* 5007c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * PCI hotplug support registration structure 5008c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5009c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic struct pci_driver megasas_pci_driver = { 5010c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5011c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .name = "megaraid_sas", 5012c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .id_table = megasas_pci_table, 5013c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .probe = megasas_probe_one, 5014c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .remove = __devexit_p(megasas_detach_one), 501531ea7088974c2405e19d72f17c2afb103ef19e02bo yang .suspend = megasas_suspend, 501631ea7088974c2405e19d72f17c2afb103ef19e02bo yang .resume = megasas_resume, 5017c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas .shutdown = megasas_shutdown, 5018c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas}; 5019c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5020c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/* 5021c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Sysfs driver attributes 5022c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5023c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf) 5024c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 5025c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n", 5026c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas MEGASAS_VERSION); 5027c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 5028c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5029c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL); 5030c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5031c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic ssize_t 5032c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmegasas_sysfs_show_release_date(struct device_driver *dd, char *buf) 5033c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 5034c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n", 5035c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas MEGASAS_RELDATE); 5036c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 5037c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5038c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date, 5039c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas NULL); 5040c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5041658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patrostatic ssize_t 504272c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bomegasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf) 504372c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo{ 504472c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo return sprintf(buf, "%u\n", support_poll_for_event); 504572c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo} 504672c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 504772c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bostatic DRIVER_ATTR(support_poll_for_event, S_IRUGO, 504872c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo megasas_sysfs_show_support_poll_for_event, NULL); 504972c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 5050837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo static ssize_t 5051837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bomegasas_sysfs_show_support_device_change(struct device_driver *dd, char *buf) 5052837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo{ 5053837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo return sprintf(buf, "%u\n", support_device_change); 5054837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo} 5055837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo 5056837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bostatic DRIVER_ATTR(support_device_change, S_IRUGO, 5057837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo megasas_sysfs_show_support_device_change, NULL); 5058837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo 505972c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bostatic ssize_t 5060658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patromegasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf) 5061658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro{ 5062ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang return sprintf(buf, "%u\n", megasas_dbg_lvl); 5063658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro} 5064658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 5065658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patrostatic ssize_t 5066658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patromegasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count) 5067658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro{ 5068658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro int retval = count; 5069658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){ 5070658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro printk(KERN_ERR "megasas: could not set dbg_lvl\n"); 5071658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro retval = -EINVAL; 5072658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro } 5073658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro return retval; 5074658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro} 5075658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 507666dca9b8c50b5e59d3bea8b21cee5c6dae6c9c46Joe Malickistatic DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl, 5077ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang megasas_sysfs_set_dbg_lvl); 5078ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 5079ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangstatic ssize_t 5080ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangmegasas_sysfs_show_poll_mode_io(struct device_driver *dd, char *buf) 5081ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang{ 5082ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang return sprintf(buf, "%u\n", poll_mode_io); 5083ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang} 5084ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 5085ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangstatic ssize_t 5086ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangmegasas_sysfs_set_poll_mode_io(struct device_driver *dd, 5087ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang const char *buf, size_t count) 5088ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang{ 5089ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang int retval = count; 5090ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang int tmp = poll_mode_io; 5091ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang int i; 5092ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang struct megasas_instance *instance; 5093ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 5094ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (sscanf(buf, "%u", &poll_mode_io) < 1) { 5095ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang printk(KERN_ERR "megasas: could not set poll_mode_io\n"); 5096ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang retval = -EINVAL; 5097ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang } 5098ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 5099ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang /* 5100ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * Check if poll_mode_io is already set or is same as previous value 5101ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang */ 5102ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if ((tmp && poll_mode_io) || (tmp == poll_mode_io)) 5103ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang goto out; 5104ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 5105ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (poll_mode_io) { 5106ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang /* 5107ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * Start timers for all adapters 5108ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang */ 5109ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang for (i = 0; i < megasas_mgmt_info.max_index; i++) { 5110ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang instance = megasas_mgmt_info.instance[i]; 5111ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (instance) { 5112ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang megasas_start_timer(instance, 5113ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang &instance->io_completion_timer, 5114ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang megasas_io_completion_timer, 5115ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang MEGASAS_COMPLETION_TIMER_INTERVAL); 5116ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang } 5117ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang } 5118ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang } else { 5119ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang /* 5120ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang * Delete timers for all adapters 5121ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang */ 5122ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang for (i = 0; i < megasas_mgmt_info.max_index; i++) { 5123ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang instance = megasas_mgmt_info.instance[i]; 5124ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (instance) 5125ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang del_timer_sync(&instance->io_completion_timer); 5126ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang } 5127ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang } 5128ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 5129ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangout: 5130ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang return retval; 5131ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang} 5132ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 51337e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bostatic void 51347e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bomegasas_aen_polling(struct work_struct *work) 51357e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo{ 51367e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct megasas_aen_event *ev = 51377e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo container_of(work, struct megasas_aen_event, hotplug_work); 51387e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct megasas_instance *instance = ev->instance; 51397e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo union megasas_evt_class_locale class_locale; 51407e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct Scsi_Host *host; 51417e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo struct scsi_device *sdev1; 51427e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo u16 pd_index = 0; 5143c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo u16 ld_index = 0; 51447e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo int i, j, doscan = 0; 51457e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo u32 seq_num; 51467e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo int error; 51477e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 51487e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (!instance) { 51497e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo printk(KERN_ERR "invalid instance!\n"); 51507e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo kfree(ev); 51517e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo return; 51527e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 51537e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo instance->ev = NULL; 51547e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo host = instance->host; 51557e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (instance->evt_detail) { 51567e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 51577e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo switch (instance->evt_detail->code) { 51587e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo case MR_EVT_PD_INSERTED: 5159c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (megasas_get_pd_list(instance) == 0) { 5160c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { 5161c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (j = 0; 5162c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j < MEGASAS_MAX_DEV_PER_CHANNEL; 5163c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j++) { 5164c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5165c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo pd_index = 5166c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; 5167c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5168c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo sdev1 = 5169c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_lookup(host, i, j, 0); 5170c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5171c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (instance->pd_list[pd_index].driveState 5172c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo == MR_PD_STATE_SYSTEM) { 5173c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (!sdev1) { 5174c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_add_device(host, i, j, 0); 5175c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5176c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5177c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) 5178c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5179c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5180c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5181c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5182c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5183c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo doscan = 0; 5184c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo break; 5185c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 51867e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo case MR_EVT_PD_REMOVED: 5187c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (megasas_get_pd_list(instance) == 0) { 5188c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo megasas_get_pd_list(instance); 5189c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { 5190c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (j = 0; 5191c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j < MEGASAS_MAX_DEV_PER_CHANNEL; 5192c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j++) { 5193c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5194c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo pd_index = 5195c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; 5196c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5197c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo sdev1 = 5198c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_lookup(host, i, j, 0); 5199c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5200c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (instance->pd_list[pd_index].driveState 5201c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo == MR_PD_STATE_SYSTEM) { 5202c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5203c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5204c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5205c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } else { 5206c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5207c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_remove_device(sdev1); 5208c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5209c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5210c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5211c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5212c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5213c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5214c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo doscan = 0; 5215c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo break; 5216c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5217c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo case MR_EVT_LD_OFFLINE: 52184c598b23807a3bf0e4f7e65f7934965acc47e1b9Adam Radford case MR_EVT_CFG_CLEARED: 5219c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo case MR_EVT_LD_DELETED: 5220c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo megasas_get_ld_list(instance); 5221c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { 5222c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (j = 0; 5223c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j < MEGASAS_MAX_DEV_PER_CHANNEL; 5224c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j++) { 5225c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5226c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo ld_index = 5227c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; 5228c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5229c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo sdev1 = scsi_device_lookup(host, 5230c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo i + MEGASAS_MAX_LD_CHANNELS, 5231c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j, 5232c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 0); 5233c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5234c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (instance->ld_ids[ld_index] != 0xff) { 5235c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5236c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5237c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5238c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } else { 5239c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5240c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_remove_device(sdev1); 5241c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5242c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5243c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5244c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5245c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5246c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo doscan = 0; 5247c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo break; 5248c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo case MR_EVT_LD_CREATED: 5249c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo megasas_get_ld_list(instance); 5250c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { 5251c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (j = 0; 5252c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j < MEGASAS_MAX_DEV_PER_CHANNEL; 5253c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j++) { 5254c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo ld_index = 5255c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; 5256c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5257c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo sdev1 = scsi_device_lookup(host, 5258c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo i+MEGASAS_MAX_LD_CHANNELS, 5259c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j, 0); 5260c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5261c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (instance->ld_ids[ld_index] != 5262c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 0xff) { 5263c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (!sdev1) { 5264c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_add_device(host, 5265c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo i + 2, 5266c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j, 0); 5267c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5268c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5269c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5270c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5271c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5272c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5273c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5274c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo doscan = 0; 5275c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo break; 52767e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED: 5277c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo case MR_EVT_FOREIGN_CFG_IMPORTED: 52789c915a8c99bce637226aa09cb05fc18486b229cbAdam Radford case MR_EVT_LD_STATE_CHANGE: 52797e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo doscan = 1; 52807e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo break; 52817e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo default: 52827e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo doscan = 0; 52837e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo break; 52847e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 52857e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } else { 52867e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo printk(KERN_ERR "invalid evt_detail!\n"); 52877e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo kfree(ev); 52887e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo return; 52897e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 52907e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 52917e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (doscan) { 52927e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo printk(KERN_INFO "scanning ...\n"); 52937e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo megasas_get_pd_list(instance); 52947e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { 52957e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) { 52967e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j; 52977e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo sdev1 = scsi_device_lookup(host, i, j, 0); 52987e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (instance->pd_list[pd_index].driveState == 52997e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo MR_PD_STATE_SYSTEM) { 53007e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (!sdev1) { 53017e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo scsi_add_device(host, i, j, 0); 53027e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53037e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (sdev1) 53047e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo scsi_device_put(sdev1); 53057e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } else { 53067e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (sdev1) { 53077e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo scsi_remove_device(sdev1); 53087e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo scsi_device_put(sdev1); 53097e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53107e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53117e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53127e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 5313c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5314c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo megasas_get_ld_list(instance); 5315c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { 5316c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) { 5317c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo ld_index = 5318c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; 5319c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo 5320c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo sdev1 = scsi_device_lookup(host, 5321c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo i+MEGASAS_MAX_LD_CHANNELS, j, 0); 5322c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (instance->ld_ids[ld_index] != 0xff) { 5323c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (!sdev1) { 5324c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_add_device(host, 5325c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo i+2, 5326c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo j, 0); 5327c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } else { 5328c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5329c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5330c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } else { 5331c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo if (sdev1) { 5332c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_remove_device(sdev1); 5333c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo scsi_device_put(sdev1); 5334c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5335c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5336c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 5337c978684254d11e3768c5a0b2780302fb0cada29cYang, Bo } 53387e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53397e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53407e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if ( instance->aen_cmd != NULL ) { 53417e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo kfree(ev); 53427e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo return ; 53437e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo } 53447e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53457e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo seq_num = instance->evt_detail->seq_num + 1; 53467e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53477e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo /* Register AEN with FW for latest sequence number plus 1 */ 53487e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo class_locale.members.reserved = 0; 53497e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo class_locale.members.locale = MR_EVT_LOCALE_ALL; 53507e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo class_locale.members.class = MR_EVT_CLASS_DEBUG; 53517e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo mutex_lock(&instance->aen_mutex); 53527e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo error = megasas_register_aen(instance, seq_num, 53537e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo class_locale.word); 53547e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo mutex_unlock(&instance->aen_mutex); 53557e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53567e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo if (error) 53577e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo printk(KERN_ERR "register aen failed error %x\n", error); 53587e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53597e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo kfree(ev); 53607e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo} 53617e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 53627e8a75f4dfbff173977b2f58799c3eceb7b09afdYang, Bo 5363bb7d3f24c71e528989501617651b669fbed798cbBryn M. Reevesstatic DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUSR, 5364ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang megasas_sysfs_show_poll_mode_io, 5365ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang megasas_sysfs_set_poll_mode_io); 5366658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro 5367c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 5368c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_init - Driver load entry point 5369c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5370c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic int __init megasas_init(void) 5371c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 5372c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas int rval; 5373c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5374c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 5375c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Announce driver version and other information 5376c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5377c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, 5378c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas MEGASAS_EXT_VERSION); 5379c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 538072c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo support_poll_for_event = 2; 5381837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo support_device_change = 1; 538272c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 5383c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info)); 5384c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5385c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 5386c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Register character device node 5387c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5388c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops); 5389c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5390c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (rval < 0) { 5391c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: failed to open device node\n"); 5392c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return rval; 5393c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas } 5394c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5395c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas megasas_mgmt_majorno = rval; 5396c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5397c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas /* 5398c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * Register ourselves as PCI hotplug module 5399c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 54004041b9cd87d97a7c73a5bf5a9305dffee2599386Michal Piotrowski rval = pci_register_driver(&megasas_pci_driver); 5401c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5402c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas if (rval) { 5403c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n"); 540483aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik goto err_pcidrv; 540583aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik } 540683aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik 540783aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik rval = driver_create_file(&megasas_pci_driver.driver, 540883aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik &driver_attr_version); 540983aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik if (rval) 541083aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik goto err_dcf_attr_ver; 541183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik rval = driver_create_file(&megasas_pci_driver.driver, 541283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik &driver_attr_release_date); 541383aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik if (rval) 541483aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik goto err_dcf_rel_date; 541572c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 541672c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo rval = driver_create_file(&megasas_pci_driver.driver, 541772c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo &driver_attr_support_poll_for_event); 541872c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo if (rval) 541972c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo goto err_dcf_support_poll_for_event; 542072c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 542183aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik rval = driver_create_file(&megasas_pci_driver.driver, 542283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik &driver_attr_dbg_lvl); 542383aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik if (rval) 542483aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik goto err_dcf_dbg_lvl; 5425ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang rval = driver_create_file(&megasas_pci_driver.driver, 5426ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang &driver_attr_poll_mode_io); 5427ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang if (rval) 5428ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang goto err_dcf_poll_mode_io; 5429c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5430837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo rval = driver_create_file(&megasas_pci_driver.driver, 5431837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo &driver_attr_support_device_change); 5432837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo if (rval) 5433837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo goto err_dcf_support_device_change; 5434837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo 5435c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas return rval; 5436ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang 5437837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Boerr_dcf_support_device_change: 5438837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo driver_remove_file(&megasas_pci_driver.driver, 5439837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo &driver_attr_poll_mode_io); 5440837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo 5441ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yangerr_dcf_poll_mode_io: 5442ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang driver_remove_file(&megasas_pci_driver.driver, 5443ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang &driver_attr_dbg_lvl); 544483aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_dcf_dbg_lvl: 544583aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik driver_remove_file(&megasas_pci_driver.driver, 544672c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo &driver_attr_support_poll_for_event); 544772c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 544872c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Boerr_dcf_support_poll_for_event: 544972c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo driver_remove_file(&megasas_pci_driver.driver, 545083aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik &driver_attr_release_date); 545172c4fd36dc7f755a5245ef2495fe27d5084d776dYang, Bo 545283aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_dcf_rel_date: 545383aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); 545483aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_dcf_attr_ver: 545583aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik pci_unregister_driver(&megasas_pci_driver); 545683aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzikerr_pcidrv: 545783aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); 54580d49016bbab4fe9164710b1d4bbae116b89b7f7eAdam Radford return rval; 5459c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 5460c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5461c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas/** 5462c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas * megasas_exit - Driver unload entry point 5463c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas */ 5464c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasstatic void __exit megasas_exit(void) 5465c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas{ 5466658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro driver_remove_file(&megasas_pci_driver.driver, 5467ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang &driver_attr_poll_mode_io); 5468ad84db2e2e1817bb8a29e7c9108eb66bf023d99fbo yang driver_remove_file(&megasas_pci_driver.driver, 5469658dcedb4e35d77f7f6552b5a640d7d82c372053Sumant Patro &driver_attr_dbg_lvl); 547083aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik driver_remove_file(&megasas_pci_driver.driver, 5471837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo &driver_attr_support_poll_for_event); 5472837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo driver_remove_file(&megasas_pci_driver.driver, 5473837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo &driver_attr_support_device_change); 5474837f5fe89c843422452ef5e1a7e3d20e9caa3268Yang, Bo driver_remove_file(&megasas_pci_driver.driver, 547583aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik &driver_attr_release_date); 547683aabc1be551dd1f07266c125ff48ec62a2ce515Jeff Garzik driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); 5477c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5478c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas pci_unregister_driver(&megasas_pci_driver); 5479c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); 5480c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas} 5481c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivas 5482c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmodule_init(megasas_init); 5483c4a3e0a529ab3e65223e81681c7c6b1bc188fa58Bagalkote, Sreenivasmodule_exit(megasas_exit); 5484