162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * linux/drivers/scsi/esas2r/esas2r.h 362306a36Sopenharmony_ci * For use with ATTO ExpressSAS R6xx SAS/SATA RAID controllers 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2001-2013 ATTO Technology, Inc. 662306a36Sopenharmony_ci * (mailto:linuxdrivers@attotech.com) 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or 962306a36Sopenharmony_ci * modify it under the terms of the GNU General Public License 1062306a36Sopenharmony_ci * as published by the Free Software Foundation; either version 2 1162306a36Sopenharmony_ci * of the License, or (at your option) any later version. 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * This program is distributed in the hope that it will be useful, 1462306a36Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 1562306a36Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1662306a36Sopenharmony_ci * GNU General Public License for more details. 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci * NO WARRANTY 1962306a36Sopenharmony_ci * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 2062306a36Sopenharmony_ci * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 2162306a36Sopenharmony_ci * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 2262306a36Sopenharmony_ci * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 2362306a36Sopenharmony_ci * solely responsible for determining the appropriateness of using and 2462306a36Sopenharmony_ci * distributing the Program and assumes all risks associated with its 2562306a36Sopenharmony_ci * exercise of rights under this Agreement, including but not limited to 2662306a36Sopenharmony_ci * the risks and costs of program errors, damage to or loss of data, 2762306a36Sopenharmony_ci * programs or equipment, and unavailability or interruption of operations. 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * DISCLAIMER OF LIABILITY 3062306a36Sopenharmony_ci * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 3162306a36Sopenharmony_ci * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3262306a36Sopenharmony_ci * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 3362306a36Sopenharmony_ci * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 3462306a36Sopenharmony_ci * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 3562306a36Sopenharmony_ci * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 3662306a36Sopenharmony_ci * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * You should have received a copy of the GNU General Public License 3962306a36Sopenharmony_ci * along with this program; if not, write to the Free Software 4062306a36Sopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 4162306a36Sopenharmony_ci * USA. 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#include <linux/kernel.h> 4562306a36Sopenharmony_ci#include <linux/delay.h> 4662306a36Sopenharmony_ci#include <linux/pci.h> 4762306a36Sopenharmony_ci#include <linux/proc_fs.h> 4862306a36Sopenharmony_ci#include <linux/workqueue.h> 4962306a36Sopenharmony_ci#include <linux/interrupt.h> 5062306a36Sopenharmony_ci#include <linux/module.h> 5162306a36Sopenharmony_ci#include <linux/vmalloc.h> 5262306a36Sopenharmony_ci#include <scsi/scsi.h> 5362306a36Sopenharmony_ci#include <scsi/scsi_host.h> 5462306a36Sopenharmony_ci#include <scsi/scsi_cmnd.h> 5562306a36Sopenharmony_ci#include <scsi/scsi_device.h> 5662306a36Sopenharmony_ci#include <scsi/scsi_eh.h> 5762306a36Sopenharmony_ci#include <scsi/scsi_tcq.h> 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#include "esas2r_log.h" 6062306a36Sopenharmony_ci#include "atioctl.h" 6162306a36Sopenharmony_ci#include "atvda.h" 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#ifndef ESAS2R_H 6462306a36Sopenharmony_ci#define ESAS2R_H 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* Global Variables */ 6762306a36Sopenharmony_ciextern struct esas2r_adapter *esas2r_adapters[]; 6862306a36Sopenharmony_ciextern u8 *esas2r_buffered_ioctl; 6962306a36Sopenharmony_ciextern dma_addr_t esas2r_buffered_ioctl_addr; 7062306a36Sopenharmony_ciextern u32 esas2r_buffered_ioctl_size; 7162306a36Sopenharmony_ciextern struct pci_dev *esas2r_buffered_ioctl_pcid; 7262306a36Sopenharmony_ci#define SGL_PG_SZ_MIN 64 7362306a36Sopenharmony_ci#define SGL_PG_SZ_MAX 1024 7462306a36Sopenharmony_ciextern int sgl_page_size; 7562306a36Sopenharmony_ci#define NUM_SGL_MIN 8 7662306a36Sopenharmony_ci#define NUM_SGL_MAX 2048 7762306a36Sopenharmony_ciextern int num_sg_lists; 7862306a36Sopenharmony_ci#define NUM_REQ_MIN 4 7962306a36Sopenharmony_ci#define NUM_REQ_MAX 256 8062306a36Sopenharmony_ciextern int num_requests; 8162306a36Sopenharmony_ci#define NUM_AE_MIN 2 8262306a36Sopenharmony_ci#define NUM_AE_MAX 8 8362306a36Sopenharmony_ciextern int num_ae_requests; 8462306a36Sopenharmony_ciextern int cmd_per_lun; 8562306a36Sopenharmony_ciextern int can_queue; 8662306a36Sopenharmony_ciextern int esas2r_max_sectors; 8762306a36Sopenharmony_ciextern int sg_tablesize; 8862306a36Sopenharmony_ciextern int interrupt_mode; 8962306a36Sopenharmony_ciextern int num_io_requests; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci/* Macro defintions */ 9262306a36Sopenharmony_ci#define ESAS2R_MAX_ID 255 9362306a36Sopenharmony_ci#define MAX_ADAPTERS 32 9462306a36Sopenharmony_ci#define ESAS2R_DRVR_NAME "esas2r" 9562306a36Sopenharmony_ci#define ESAS2R_LONGNAME "ATTO ExpressSAS 6GB RAID Adapter" 9662306a36Sopenharmony_ci#define ESAS2R_MAX_DEVICES 32 9762306a36Sopenharmony_ci#define ATTONODE_NAME "ATTONode" 9862306a36Sopenharmony_ci#define ESAS2R_MAJOR_REV 1 9962306a36Sopenharmony_ci#define ESAS2R_MINOR_REV 00 10062306a36Sopenharmony_ci#define ESAS2R_VERSION_STR DEFINED_NUM_TO_STR(ESAS2R_MAJOR_REV) "." \ 10162306a36Sopenharmony_ci DEFINED_NUM_TO_STR(ESAS2R_MINOR_REV) 10262306a36Sopenharmony_ci#define ESAS2R_COPYRIGHT_YEARS "2001-2013" 10362306a36Sopenharmony_ci#define ESAS2R_DEFAULT_SGL_PAGE_SIZE 384 10462306a36Sopenharmony_ci#define ESAS2R_DEFAULT_CMD_PER_LUN 64 10562306a36Sopenharmony_ci#define ESAS2R_DEFAULT_NUM_SG_LISTS 1024 10662306a36Sopenharmony_ci#define DEFINED_NUM_TO_STR(num) NUM_TO_STR(num) 10762306a36Sopenharmony_ci#define NUM_TO_STR(num) #num 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci#define ESAS2R_SGL_ALIGN 16 11062306a36Sopenharmony_ci#define ESAS2R_LIST_ALIGN 16 11162306a36Sopenharmony_ci#define ESAS2R_LIST_EXTRA ESAS2R_NUM_EXTRA 11262306a36Sopenharmony_ci#define ESAS2R_DATA_BUF_LEN 256 11362306a36Sopenharmony_ci#define ESAS2R_DEFAULT_TMO 5000 11462306a36Sopenharmony_ci#define ESAS2R_DISC_BUF_LEN 512 11562306a36Sopenharmony_ci#define ESAS2R_FWCOREDUMP_SZ 0x80000 11662306a36Sopenharmony_ci#define ESAS2R_NUM_PHYS 8 11762306a36Sopenharmony_ci#define ESAS2R_TARG_ID_INV 0xFFFF 11862306a36Sopenharmony_ci#define ESAS2R_INT_STS_MASK MU_INTSTAT_MASK 11962306a36Sopenharmony_ci#define ESAS2R_INT_ENB_MASK MU_INTSTAT_MASK 12062306a36Sopenharmony_ci#define ESAS2R_INT_DIS_MASK 0 12162306a36Sopenharmony_ci#define ESAS2R_MAX_TARGETS 256 12262306a36Sopenharmony_ci#define ESAS2R_KOBJ_NAME_LEN 20 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci/* u16 (WORD) component macros */ 12562306a36Sopenharmony_ci#define LOBYTE(w) ((u8)(u16)(w)) 12662306a36Sopenharmony_ci#define HIBYTE(w) ((u8)(((u16)(w)) >> 8)) 12762306a36Sopenharmony_ci#define MAKEWORD(lo, hi) ((u16)((u8)(lo) | ((u16)(u8)(hi) << 8))) 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci/* u32 (DWORD) component macros */ 13062306a36Sopenharmony_ci#define LOWORD(d) ((u16)(u32)(d)) 13162306a36Sopenharmony_ci#define HIWORD(d) ((u16)(((u32)(d)) >> 16)) 13262306a36Sopenharmony_ci#define MAKEDWORD(lo, hi) ((u32)((u16)(lo) | ((u32)(u16)(hi) << 16))) 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/* macro to get the lowest nonzero bit of a value */ 13562306a36Sopenharmony_ci#define LOBIT(x) ((x) & (0 - (x))) 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci/* These functions are provided to access the chip's control registers. 13862306a36Sopenharmony_ci * The register is specified by its byte offset from the register base 13962306a36Sopenharmony_ci * for the adapter. 14062306a36Sopenharmony_ci */ 14162306a36Sopenharmony_ci#define esas2r_read_register_dword(a, reg) \ 14262306a36Sopenharmony_ci readl((void __iomem *)a->regs + (reg) + MW_REG_OFFSET_HWREG) 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci#define esas2r_write_register_dword(a, reg, data) \ 14562306a36Sopenharmony_ci writel(data, (void __iomem *)(a->regs + (reg) + MW_REG_OFFSET_HWREG)) 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci#define esas2r_flush_register_dword(a, r) esas2r_read_register_dword(a, r) 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci/* This function is provided to access the chip's data window. The 15062306a36Sopenharmony_ci * register is specified by its byte offset from the window base 15162306a36Sopenharmony_ci * for the adapter. 15262306a36Sopenharmony_ci */ 15362306a36Sopenharmony_ci#define esas2r_read_data_byte(a, reg) \ 15462306a36Sopenharmony_ci readb((void __iomem *)a->data_window + (reg)) 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci/* ATTO vendor and device Ids */ 15762306a36Sopenharmony_ci#define ATTO_VENDOR_ID 0x117C 15862306a36Sopenharmony_ci#define ATTO_DID_INTEL_IOP348 0x002C 15962306a36Sopenharmony_ci#define ATTO_DID_MV_88RC9580 0x0049 16062306a36Sopenharmony_ci#define ATTO_DID_MV_88RC9580TS 0x0066 16162306a36Sopenharmony_ci#define ATTO_DID_MV_88RC9580TSE 0x0067 16262306a36Sopenharmony_ci#define ATTO_DID_MV_88RC9580TL 0x0068 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci/* ATTO subsystem device Ids */ 16562306a36Sopenharmony_ci#define ATTO_SSDID_TBT 0x4000 16662306a36Sopenharmony_ci#define ATTO_TSSC_3808 0x4066 16762306a36Sopenharmony_ci#define ATTO_TSSC_3808E 0x4067 16862306a36Sopenharmony_ci#define ATTO_TLSH_1068 0x4068 16962306a36Sopenharmony_ci#define ATTO_ESAS_R680 0x0049 17062306a36Sopenharmony_ci#define ATTO_ESAS_R608 0x004A 17162306a36Sopenharmony_ci#define ATTO_ESAS_R60F 0x004B 17262306a36Sopenharmony_ci#define ATTO_ESAS_R6F0 0x004C 17362306a36Sopenharmony_ci#define ATTO_ESAS_R644 0x004D 17462306a36Sopenharmony_ci#define ATTO_ESAS_R648 0x004E 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci/* 17762306a36Sopenharmony_ci * flash definitions & structures 17862306a36Sopenharmony_ci * define the code types 17962306a36Sopenharmony_ci */ 18062306a36Sopenharmony_ci#define FBT_CPYR 0xAA00 18162306a36Sopenharmony_ci#define FBT_SETUP 0xAA02 18262306a36Sopenharmony_ci#define FBT_FLASH_VER 0xAA04 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci/* offsets to various locations in flash */ 18562306a36Sopenharmony_ci#define FLS_OFFSET_BOOT (u32)(0x00700000) 18662306a36Sopenharmony_ci#define FLS_OFFSET_NVR (u32)(0x007C0000) 18762306a36Sopenharmony_ci#define FLS_OFFSET_CPYR FLS_OFFSET_NVR 18862306a36Sopenharmony_ci#define FLS_LENGTH_BOOT (FLS_OFFSET_CPYR - FLS_OFFSET_BOOT) 18962306a36Sopenharmony_ci#define FLS_BLOCK_SIZE (u32)(0x00020000) 19062306a36Sopenharmony_ci#define FI_NVR_2KB 0x0800 19162306a36Sopenharmony_ci#define FI_NVR_8KB 0x2000 19262306a36Sopenharmony_ci#define FM_BUF_SZ 0x800 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci/* 19562306a36Sopenharmony_ci * marvell frey (88R9580) register definitions 19662306a36Sopenharmony_ci * chip revision identifiers 19762306a36Sopenharmony_ci */ 19862306a36Sopenharmony_ci#define MVR_FREY_B2 0xB2 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci/* 20162306a36Sopenharmony_ci * memory window definitions. window 0 is the data window with definitions 20262306a36Sopenharmony_ci * of MW_DATA_XXX. window 1 is the register window with definitions of 20362306a36Sopenharmony_ci * MW_REG_XXX. 20462306a36Sopenharmony_ci */ 20562306a36Sopenharmony_ci#define MW_REG_WINDOW_SIZE (u32)(0x00040000) 20662306a36Sopenharmony_ci#define MW_REG_OFFSET_HWREG (u32)(0x00000000) 20762306a36Sopenharmony_ci#define MW_REG_OFFSET_PCI (u32)(0x00008000) 20862306a36Sopenharmony_ci#define MW_REG_PCI_HWREG_DELTA (MW_REG_OFFSET_PCI - MW_REG_OFFSET_HWREG) 20962306a36Sopenharmony_ci#define MW_DATA_WINDOW_SIZE (u32)(0x00020000) 21062306a36Sopenharmony_ci#define MW_DATA_ADDR_SER_FLASH (u32)(0xEC000000) 21162306a36Sopenharmony_ci#define MW_DATA_ADDR_SRAM (u32)(0xF4000000) 21262306a36Sopenharmony_ci#define MW_DATA_ADDR_PAR_FLASH (u32)(0xFC000000) 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci/* 21562306a36Sopenharmony_ci * the following registers are for the communication 21662306a36Sopenharmony_ci * list interface (AKA message unit (MU)) 21762306a36Sopenharmony_ci */ 21862306a36Sopenharmony_ci#define MU_IN_LIST_ADDR_LO (u32)(0x00004000) 21962306a36Sopenharmony_ci#define MU_IN_LIST_ADDR_HI (u32)(0x00004004) 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci#define MU_IN_LIST_WRITE (u32)(0x00004018) 22262306a36Sopenharmony_ci #define MU_ILW_TOGGLE (u32)(0x00004000) 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci#define MU_IN_LIST_READ (u32)(0x0000401C) 22562306a36Sopenharmony_ci #define MU_ILR_TOGGLE (u32)(0x00004000) 22662306a36Sopenharmony_ci #define MU_ILIC_LIST (u32)(0x0000000F) 22762306a36Sopenharmony_ci #define MU_ILIC_LIST_F0 (u32)(0x00000000) 22862306a36Sopenharmony_ci #define MU_ILIC_DEST (u32)(0x00000F00) 22962306a36Sopenharmony_ci #define MU_ILIC_DEST_DDR (u32)(0x00000200) 23062306a36Sopenharmony_ci#define MU_IN_LIST_IFC_CONFIG (u32)(0x00004028) 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci#define MU_IN_LIST_CONFIG (u32)(0x0000402C) 23362306a36Sopenharmony_ci #define MU_ILC_ENABLE (u32)(0x00000001) 23462306a36Sopenharmony_ci #define MU_ILC_ENTRY_MASK (u32)(0x000000F0) 23562306a36Sopenharmony_ci #define MU_ILC_ENTRY_4_DW (u32)(0x00000020) 23662306a36Sopenharmony_ci #define MU_ILC_DYNAMIC_SRC (u32)(0x00008000) 23762306a36Sopenharmony_ci #define MU_ILC_NUMBER_MASK (u32)(0x7FFF0000) 23862306a36Sopenharmony_ci #define MU_ILC_NUMBER_SHIFT 16 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci#define MU_OUT_LIST_ADDR_LO (u32)(0x00004050) 24162306a36Sopenharmony_ci#define MU_OUT_LIST_ADDR_HI (u32)(0x00004054) 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci#define MU_OUT_LIST_COPY_PTR_LO (u32)(0x00004058) 24462306a36Sopenharmony_ci#define MU_OUT_LIST_COPY_PTR_HI (u32)(0x0000405C) 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci#define MU_OUT_LIST_WRITE (u32)(0x00004068) 24762306a36Sopenharmony_ci #define MU_OLW_TOGGLE (u32)(0x00004000) 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci#define MU_OUT_LIST_COPY (u32)(0x0000406C) 25062306a36Sopenharmony_ci #define MU_OLC_TOGGLE (u32)(0x00004000) 25162306a36Sopenharmony_ci #define MU_OLC_WRT_PTR (u32)(0x00003FFF) 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci#define MU_OUT_LIST_IFC_CONFIG (u32)(0x00004078) 25462306a36Sopenharmony_ci #define MU_OLIC_LIST (u32)(0x0000000F) 25562306a36Sopenharmony_ci #define MU_OLIC_LIST_F0 (u32)(0x00000000) 25662306a36Sopenharmony_ci #define MU_OLIC_SOURCE (u32)(0x00000F00) 25762306a36Sopenharmony_ci #define MU_OLIC_SOURCE_DDR (u32)(0x00000200) 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci#define MU_OUT_LIST_CONFIG (u32)(0x0000407C) 26062306a36Sopenharmony_ci #define MU_OLC_ENABLE (u32)(0x00000001) 26162306a36Sopenharmony_ci #define MU_OLC_ENTRY_MASK (u32)(0x000000F0) 26262306a36Sopenharmony_ci #define MU_OLC_ENTRY_4_DW (u32)(0x00000020) 26362306a36Sopenharmony_ci #define MU_OLC_NUMBER_MASK (u32)(0x7FFF0000) 26462306a36Sopenharmony_ci #define MU_OLC_NUMBER_SHIFT 16 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci#define MU_OUT_LIST_INT_STAT (u32)(0x00004088) 26762306a36Sopenharmony_ci #define MU_OLIS_INT (u32)(0x00000001) 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci#define MU_OUT_LIST_INT_MASK (u32)(0x0000408C) 27062306a36Sopenharmony_ci #define MU_OLIS_MASK (u32)(0x00000001) 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci/* 27362306a36Sopenharmony_ci * the maximum size of the communication lists is two greater than the 27462306a36Sopenharmony_ci * maximum amount of VDA requests. the extra are to prevent queue overflow. 27562306a36Sopenharmony_ci */ 27662306a36Sopenharmony_ci#define ESAS2R_MAX_NUM_REQS 256 27762306a36Sopenharmony_ci#define ESAS2R_NUM_EXTRA 2 27862306a36Sopenharmony_ci#define ESAS2R_MAX_COMM_LIST_SIZE (ESAS2R_MAX_NUM_REQS + ESAS2R_NUM_EXTRA) 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci/* 28162306a36Sopenharmony_ci * the following registers are for the CPU interface 28262306a36Sopenharmony_ci */ 28362306a36Sopenharmony_ci#define MU_CTL_STATUS_IN (u32)(0x00010108) 28462306a36Sopenharmony_ci #define MU_CTL_IN_FULL_RST (u32)(0x00000020) 28562306a36Sopenharmony_ci#define MU_CTL_STATUS_IN_B2 (u32)(0x00010130) 28662306a36Sopenharmony_ci #define MU_CTL_IN_FULL_RST2 (u32)(0x80000000) 28762306a36Sopenharmony_ci#define MU_DOORBELL_IN (u32)(0x00010460) 28862306a36Sopenharmony_ci #define DRBL_RESET_BUS (u32)(0x00000002) 28962306a36Sopenharmony_ci #define DRBL_PAUSE_AE (u32)(0x00000004) 29062306a36Sopenharmony_ci #define DRBL_RESUME_AE (u32)(0x00000008) 29162306a36Sopenharmony_ci #define DRBL_MSG_IFC_DOWN (u32)(0x00000010) 29262306a36Sopenharmony_ci #define DRBL_FLASH_REQ (u32)(0x00000020) 29362306a36Sopenharmony_ci #define DRBL_FLASH_DONE (u32)(0x00000040) 29462306a36Sopenharmony_ci #define DRBL_FORCE_INT (u32)(0x00000080) 29562306a36Sopenharmony_ci #define DRBL_MSG_IFC_INIT (u32)(0x00000100) 29662306a36Sopenharmony_ci #define DRBL_POWER_DOWN (u32)(0x00000200) 29762306a36Sopenharmony_ci #define DRBL_DRV_VER_1 (u32)(0x00010000) 29862306a36Sopenharmony_ci #define DRBL_DRV_VER DRBL_DRV_VER_1 29962306a36Sopenharmony_ci#define MU_DOORBELL_IN_ENB (u32)(0x00010464) 30062306a36Sopenharmony_ci#define MU_DOORBELL_OUT (u32)(0x00010480) 30162306a36Sopenharmony_ci #define DRBL_PANIC_REASON_MASK (u32)(0x00F00000) 30262306a36Sopenharmony_ci #define DRBL_UNUSED_HANDLER (u32)(0x00100000) 30362306a36Sopenharmony_ci #define DRBL_UNDEF_INSTR (u32)(0x00200000) 30462306a36Sopenharmony_ci #define DRBL_PREFETCH_ABORT (u32)(0x00300000) 30562306a36Sopenharmony_ci #define DRBL_DATA_ABORT (u32)(0x00400000) 30662306a36Sopenharmony_ci #define DRBL_JUMP_TO_ZERO (u32)(0x00500000) 30762306a36Sopenharmony_ci #define DRBL_FW_RESET (u32)(0x00080000) 30862306a36Sopenharmony_ci #define DRBL_FW_VER_MSK (u32)(0x00070000) 30962306a36Sopenharmony_ci #define DRBL_FW_VER_0 (u32)(0x00000000) 31062306a36Sopenharmony_ci #define DRBL_FW_VER_1 (u32)(0x00010000) 31162306a36Sopenharmony_ci #define DRBL_FW_VER DRBL_FW_VER_1 31262306a36Sopenharmony_ci#define MU_DOORBELL_OUT_ENB (u32)(0x00010484) 31362306a36Sopenharmony_ci #define DRBL_ENB_MASK (u32)(0x00F803FF) 31462306a36Sopenharmony_ci#define MU_INT_STATUS_OUT (u32)(0x00010200) 31562306a36Sopenharmony_ci #define MU_INTSTAT_POST_OUT (u32)(0x00000010) 31662306a36Sopenharmony_ci #define MU_INTSTAT_DRBL_IN (u32)(0x00000100) 31762306a36Sopenharmony_ci #define MU_INTSTAT_DRBL (u32)(0x00001000) 31862306a36Sopenharmony_ci #define MU_INTSTAT_MASK (u32)(0x00001010) 31962306a36Sopenharmony_ci#define MU_INT_MASK_OUT (u32)(0x0001020C) 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci/* PCI express registers accessed via window 1 */ 32262306a36Sopenharmony_ci#define MVR_PCI_WIN1_REMAP (u32)(0x00008438) 32362306a36Sopenharmony_ci #define MVRPW1R_ENABLE (u32)(0x00000001) 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci/* structures */ 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci/* inbound list dynamic source entry */ 32962306a36Sopenharmony_cistruct esas2r_inbound_list_source_entry { 33062306a36Sopenharmony_ci u64 address; 33162306a36Sopenharmony_ci u32 length; 33262306a36Sopenharmony_ci #define HWILSE_INTERFACE_F0 0x00000000 33362306a36Sopenharmony_ci u32 reserved; 33462306a36Sopenharmony_ci}; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci/* PCI data structure in expansion ROM images */ 33762306a36Sopenharmony_cistruct __packed esas2r_boot_header { 33862306a36Sopenharmony_ci char signature[4]; 33962306a36Sopenharmony_ci u16 vendor_id; 34062306a36Sopenharmony_ci u16 device_id; 34162306a36Sopenharmony_ci u16 VPD; 34262306a36Sopenharmony_ci u16 struct_length; 34362306a36Sopenharmony_ci u8 struct_revision; 34462306a36Sopenharmony_ci u8 class_code[3]; 34562306a36Sopenharmony_ci u16 image_length; 34662306a36Sopenharmony_ci u16 code_revision; 34762306a36Sopenharmony_ci u8 code_type; 34862306a36Sopenharmony_ci #define CODE_TYPE_PC 0 34962306a36Sopenharmony_ci #define CODE_TYPE_OPEN 1 35062306a36Sopenharmony_ci #define CODE_TYPE_EFI 3 35162306a36Sopenharmony_ci u8 indicator; 35262306a36Sopenharmony_ci #define INDICATOR_LAST 0x80 35362306a36Sopenharmony_ci u8 reserved[2]; 35462306a36Sopenharmony_ci}; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_cistruct __packed esas2r_boot_image { 35762306a36Sopenharmony_ci u16 signature; 35862306a36Sopenharmony_ci u8 reserved[22]; 35962306a36Sopenharmony_ci u16 header_offset; 36062306a36Sopenharmony_ci u16 pnp_offset; 36162306a36Sopenharmony_ci}; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_cistruct __packed esas2r_pc_image { 36462306a36Sopenharmony_ci u16 signature; 36562306a36Sopenharmony_ci u8 length; 36662306a36Sopenharmony_ci u8 entry_point[3]; 36762306a36Sopenharmony_ci u8 checksum; 36862306a36Sopenharmony_ci u16 image_end; 36962306a36Sopenharmony_ci u16 min_size; 37062306a36Sopenharmony_ci u8 rom_flags; 37162306a36Sopenharmony_ci u8 reserved[12]; 37262306a36Sopenharmony_ci u16 header_offset; 37362306a36Sopenharmony_ci u16 pnp_offset; 37462306a36Sopenharmony_ci struct esas2r_boot_header boot_image; 37562306a36Sopenharmony_ci}; 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_cistruct __packed esas2r_efi_image { 37862306a36Sopenharmony_ci u16 signature; 37962306a36Sopenharmony_ci u16 length; 38062306a36Sopenharmony_ci u32 efi_signature; 38162306a36Sopenharmony_ci #define EFI_ROM_SIG 0x00000EF1 38262306a36Sopenharmony_ci u16 image_type; 38362306a36Sopenharmony_ci #define EFI_IMAGE_APP 10 38462306a36Sopenharmony_ci #define EFI_IMAGE_BSD 11 38562306a36Sopenharmony_ci #define EFI_IMAGE_RTD 12 38662306a36Sopenharmony_ci u16 machine_type; 38762306a36Sopenharmony_ci #define EFI_MACHINE_IA32 0x014c 38862306a36Sopenharmony_ci #define EFI_MACHINE_IA64 0x0200 38962306a36Sopenharmony_ci #define EFI_MACHINE_X64 0x8664 39062306a36Sopenharmony_ci #define EFI_MACHINE_EBC 0x0EBC 39162306a36Sopenharmony_ci u16 compression; 39262306a36Sopenharmony_ci #define EFI_UNCOMPRESSED 0x0000 39362306a36Sopenharmony_ci #define EFI_COMPRESSED 0x0001 39462306a36Sopenharmony_ci u8 reserved[8]; 39562306a36Sopenharmony_ci u16 efi_offset; 39662306a36Sopenharmony_ci u16 header_offset; 39762306a36Sopenharmony_ci u16 reserved2; 39862306a36Sopenharmony_ci struct esas2r_boot_header boot_image; 39962306a36Sopenharmony_ci}; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistruct esas2r_adapter; 40262306a36Sopenharmony_cistruct esas2r_sg_context; 40362306a36Sopenharmony_cistruct esas2r_request; 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_citypedef void (*RQCALLBK) (struct esas2r_adapter *a, 40662306a36Sopenharmony_ci struct esas2r_request *rq); 40762306a36Sopenharmony_citypedef bool (*RQBUILDSGL) (struct esas2r_adapter *a, 40862306a36Sopenharmony_ci struct esas2r_sg_context *sgc); 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_cistruct esas2r_component_header { 41162306a36Sopenharmony_ci u8 img_type; 41262306a36Sopenharmony_ci #define CH_IT_FW 0x00 41362306a36Sopenharmony_ci #define CH_IT_NVR 0x01 41462306a36Sopenharmony_ci #define CH_IT_BIOS 0x02 41562306a36Sopenharmony_ci #define CH_IT_MAC 0x03 41662306a36Sopenharmony_ci #define CH_IT_CFG 0x04 41762306a36Sopenharmony_ci #define CH_IT_EFI 0x05 41862306a36Sopenharmony_ci u8 status; 41962306a36Sopenharmony_ci #define CH_STAT_PENDING 0xff 42062306a36Sopenharmony_ci #define CH_STAT_FAILED 0x00 42162306a36Sopenharmony_ci #define CH_STAT_SUCCESS 0x01 42262306a36Sopenharmony_ci #define CH_STAT_RETRY 0x02 42362306a36Sopenharmony_ci #define CH_STAT_INVALID 0x03 42462306a36Sopenharmony_ci u8 pad[2]; 42562306a36Sopenharmony_ci u32 version; 42662306a36Sopenharmony_ci u32 length; 42762306a36Sopenharmony_ci u32 image_offset; 42862306a36Sopenharmony_ci}; 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci#define FI_REL_VER_SZ 16 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_cistruct esas2r_flash_img_v0 { 43362306a36Sopenharmony_ci u8 fi_version; 43462306a36Sopenharmony_ci #define FI_VERSION_0 00 43562306a36Sopenharmony_ci u8 status; 43662306a36Sopenharmony_ci u8 adap_typ; 43762306a36Sopenharmony_ci u8 action; 43862306a36Sopenharmony_ci u32 length; 43962306a36Sopenharmony_ci u16 checksum; 44062306a36Sopenharmony_ci u16 driver_error; 44162306a36Sopenharmony_ci u16 flags; 44262306a36Sopenharmony_ci u16 num_comps; 44362306a36Sopenharmony_ci #define FI_NUM_COMPS_V0 5 44462306a36Sopenharmony_ci u8 rel_version[FI_REL_VER_SZ]; 44562306a36Sopenharmony_ci struct esas2r_component_header cmp_hdr[FI_NUM_COMPS_V0]; 44662306a36Sopenharmony_ci u8 scratch_buf[FM_BUF_SZ]; 44762306a36Sopenharmony_ci}; 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_cistruct esas2r_flash_img { 45062306a36Sopenharmony_ci u8 fi_version; 45162306a36Sopenharmony_ci #define FI_VERSION_1 01 45262306a36Sopenharmony_ci u8 status; 45362306a36Sopenharmony_ci #define FI_STAT_SUCCESS 0x00 45462306a36Sopenharmony_ci #define FI_STAT_FAILED 0x01 45562306a36Sopenharmony_ci #define FI_STAT_REBOOT 0x02 45662306a36Sopenharmony_ci #define FI_STAT_ADAPTYP 0x03 45762306a36Sopenharmony_ci #define FI_STAT_INVALID 0x04 45862306a36Sopenharmony_ci #define FI_STAT_CHKSUM 0x05 45962306a36Sopenharmony_ci #define FI_STAT_LENGTH 0x06 46062306a36Sopenharmony_ci #define FI_STAT_UNKNOWN 0x07 46162306a36Sopenharmony_ci #define FI_STAT_IMG_VER 0x08 46262306a36Sopenharmony_ci #define FI_STAT_BUSY 0x09 46362306a36Sopenharmony_ci #define FI_STAT_DUAL 0x0A 46462306a36Sopenharmony_ci #define FI_STAT_MISSING 0x0B 46562306a36Sopenharmony_ci #define FI_STAT_UNSUPP 0x0C 46662306a36Sopenharmony_ci #define FI_STAT_ERASE 0x0D 46762306a36Sopenharmony_ci #define FI_STAT_FLASH 0x0E 46862306a36Sopenharmony_ci #define FI_STAT_DEGRADED 0x0F 46962306a36Sopenharmony_ci u8 adap_typ; 47062306a36Sopenharmony_ci #define FI_AT_UNKNWN 0xFF 47162306a36Sopenharmony_ci #define FI_AT_SUN_LAKE 0x0B 47262306a36Sopenharmony_ci #define FI_AT_MV_9580 0x0F 47362306a36Sopenharmony_ci u8 action; 47462306a36Sopenharmony_ci #define FI_ACT_DOWN 0x00 47562306a36Sopenharmony_ci #define FI_ACT_UP 0x01 47662306a36Sopenharmony_ci #define FI_ACT_UPSZ 0x02 47762306a36Sopenharmony_ci #define FI_ACT_MAX 0x02 47862306a36Sopenharmony_ci #define FI_ACT_DOWN1 0x80 47962306a36Sopenharmony_ci u32 length; 48062306a36Sopenharmony_ci u16 checksum; 48162306a36Sopenharmony_ci u16 driver_error; 48262306a36Sopenharmony_ci u16 flags; 48362306a36Sopenharmony_ci #define FI_FLG_NVR_DEF 0x0001 48462306a36Sopenharmony_ci u16 num_comps; 48562306a36Sopenharmony_ci #define FI_NUM_COMPS_V1 6 48662306a36Sopenharmony_ci u8 rel_version[FI_REL_VER_SZ]; 48762306a36Sopenharmony_ci struct esas2r_component_header cmp_hdr[FI_NUM_COMPS_V1]; 48862306a36Sopenharmony_ci u8 scratch_buf[FM_BUF_SZ]; 48962306a36Sopenharmony_ci}; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci/* definitions for flash script (FS) commands */ 49262306a36Sopenharmony_cistruct esas2r_ioctlfs_command { 49362306a36Sopenharmony_ci u8 command; 49462306a36Sopenharmony_ci #define ESAS2R_FS_CMD_ERASE 0 49562306a36Sopenharmony_ci #define ESAS2R_FS_CMD_READ 1 49662306a36Sopenharmony_ci #define ESAS2R_FS_CMD_BEGINW 2 49762306a36Sopenharmony_ci #define ESAS2R_FS_CMD_WRITE 3 49862306a36Sopenharmony_ci #define ESAS2R_FS_CMD_COMMIT 4 49962306a36Sopenharmony_ci #define ESAS2R_FS_CMD_CANCEL 5 50062306a36Sopenharmony_ci u8 checksum; 50162306a36Sopenharmony_ci u8 reserved[2]; 50262306a36Sopenharmony_ci u32 flash_addr; 50362306a36Sopenharmony_ci u32 length; 50462306a36Sopenharmony_ci u32 image_offset; 50562306a36Sopenharmony_ci}; 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_cistruct esas2r_ioctl_fs { 50862306a36Sopenharmony_ci u8 version; 50962306a36Sopenharmony_ci #define ESAS2R_FS_VER 0 51062306a36Sopenharmony_ci u8 status; 51162306a36Sopenharmony_ci u8 driver_error; 51262306a36Sopenharmony_ci u8 adap_type; 51362306a36Sopenharmony_ci #define ESAS2R_FS_AT_ESASRAID2 3 51462306a36Sopenharmony_ci #define ESAS2R_FS_AT_TSSASRAID2 4 51562306a36Sopenharmony_ci #define ESAS2R_FS_AT_TSSASRAID2E 5 51662306a36Sopenharmony_ci #define ESAS2R_FS_AT_TLSASHBA 6 51762306a36Sopenharmony_ci u8 driver_ver; 51862306a36Sopenharmony_ci u8 reserved[11]; 51962306a36Sopenharmony_ci struct esas2r_ioctlfs_command command; 52062306a36Sopenharmony_ci u8 data[1]; 52162306a36Sopenharmony_ci}; 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_cistruct esas2r_sas_nvram { 52462306a36Sopenharmony_ci u8 signature[4]; 52562306a36Sopenharmony_ci u8 version; 52662306a36Sopenharmony_ci #define SASNVR_VERSION_0 0x00 52762306a36Sopenharmony_ci #define SASNVR_VERSION SASNVR_VERSION_0 52862306a36Sopenharmony_ci u8 checksum; 52962306a36Sopenharmony_ci #define SASNVR_CKSUM_SEED 0x5A 53062306a36Sopenharmony_ci u8 max_lun_for_target; 53162306a36Sopenharmony_ci u8 pci_latency; 53262306a36Sopenharmony_ci #define SASNVR_PCILAT_DIS 0x00 53362306a36Sopenharmony_ci #define SASNVR_PCILAT_MIN 0x10 53462306a36Sopenharmony_ci #define SASNVR_PCILAT_MAX 0xF8 53562306a36Sopenharmony_ci u8 options1; 53662306a36Sopenharmony_ci #define SASNVR1_BOOT_DRVR 0x01 53762306a36Sopenharmony_ci #define SASNVR1_BOOT_SCAN 0x02 53862306a36Sopenharmony_ci #define SASNVR1_DIS_PCI_MWI 0x04 53962306a36Sopenharmony_ci #define SASNVR1_FORCE_ORD_Q 0x08 54062306a36Sopenharmony_ci #define SASNVR1_CACHELINE_0 0x10 54162306a36Sopenharmony_ci #define SASNVR1_DIS_DEVSORT 0x20 54262306a36Sopenharmony_ci #define SASNVR1_PWR_MGT_EN 0x40 54362306a36Sopenharmony_ci #define SASNVR1_WIDEPORT 0x80 54462306a36Sopenharmony_ci u8 options2; 54562306a36Sopenharmony_ci #define SASNVR2_SINGLE_BUS 0x01 54662306a36Sopenharmony_ci #define SASNVR2_SLOT_BIND 0x02 54762306a36Sopenharmony_ci #define SASNVR2_EXP_PROG 0x04 54862306a36Sopenharmony_ci #define SASNVR2_CMDTHR_LUN 0x08 54962306a36Sopenharmony_ci #define SASNVR2_HEARTBEAT 0x10 55062306a36Sopenharmony_ci #define SASNVR2_INT_CONNECT 0x20 55162306a36Sopenharmony_ci #define SASNVR2_SW_MUX_CTRL 0x40 55262306a36Sopenharmony_ci #define SASNVR2_DISABLE_NCQ 0x80 55362306a36Sopenharmony_ci u8 int_coalescing; 55462306a36Sopenharmony_ci #define SASNVR_COAL_DIS 0x00 55562306a36Sopenharmony_ci #define SASNVR_COAL_LOW 0x01 55662306a36Sopenharmony_ci #define SASNVR_COAL_MED 0x02 55762306a36Sopenharmony_ci #define SASNVR_COAL_HI 0x03 55862306a36Sopenharmony_ci u8 cmd_throttle; 55962306a36Sopenharmony_ci #define SASNVR_CMDTHR_NONE 0x00 56062306a36Sopenharmony_ci u8 dev_wait_time; 56162306a36Sopenharmony_ci u8 dev_wait_count; 56262306a36Sopenharmony_ci u8 spin_up_delay; 56362306a36Sopenharmony_ci #define SASNVR_SPINUP_MAX 0x14 56462306a36Sopenharmony_ci u8 ssp_align_rate; 56562306a36Sopenharmony_ci u8 sas_addr[8]; 56662306a36Sopenharmony_ci u8 phy_speed[16]; 56762306a36Sopenharmony_ci #define SASNVR_SPEED_AUTO 0x00 56862306a36Sopenharmony_ci #define SASNVR_SPEED_1_5GB 0x01 56962306a36Sopenharmony_ci #define SASNVR_SPEED_3GB 0x02 57062306a36Sopenharmony_ci #define SASNVR_SPEED_6GB 0x03 57162306a36Sopenharmony_ci #define SASNVR_SPEED_12GB 0x04 57262306a36Sopenharmony_ci u8 phy_mux[16]; 57362306a36Sopenharmony_ci #define SASNVR_MUX_DISABLED 0x00 57462306a36Sopenharmony_ci #define SASNVR_MUX_1_5GB 0x01 57562306a36Sopenharmony_ci #define SASNVR_MUX_3GB 0x02 57662306a36Sopenharmony_ci #define SASNVR_MUX_6GB 0x03 57762306a36Sopenharmony_ci u8 phy_flags[16]; 57862306a36Sopenharmony_ci #define SASNVR_PHF_DISABLED 0x01 57962306a36Sopenharmony_ci #define SASNVR_PHF_RD_ONLY 0x02 58062306a36Sopenharmony_ci u8 sort_type; 58162306a36Sopenharmony_ci #define SASNVR_SORT_SAS_ADDR 0x00 58262306a36Sopenharmony_ci #define SASNVR_SORT_H308_CONN 0x01 58362306a36Sopenharmony_ci #define SASNVR_SORT_PHY_ID 0x02 58462306a36Sopenharmony_ci #define SASNVR_SORT_SLOT_ID 0x03 58562306a36Sopenharmony_ci u8 dpm_reqcmd_lmt; 58662306a36Sopenharmony_ci u8 dpm_stndby_time; 58762306a36Sopenharmony_ci u8 dpm_active_time; 58862306a36Sopenharmony_ci u8 phy_target_id[16]; 58962306a36Sopenharmony_ci #define SASNVR_PTI_DISABLED 0xFF 59062306a36Sopenharmony_ci u8 virt_ses_mode; 59162306a36Sopenharmony_ci #define SASNVR_VSMH_DISABLED 0x00 59262306a36Sopenharmony_ci u8 read_write_mode; 59362306a36Sopenharmony_ci #define SASNVR_RWM_DEFAULT 0x00 59462306a36Sopenharmony_ci u8 link_down_to; 59562306a36Sopenharmony_ci u8 reserved[0xA1]; 59662306a36Sopenharmony_ci}; 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_citypedef u32 (*PGETPHYSADDR) (struct esas2r_sg_context *sgc, u64 *addr); 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_cistruct esas2r_sg_context { 60162306a36Sopenharmony_ci struct esas2r_adapter *adapter; 60262306a36Sopenharmony_ci struct esas2r_request *first_req; 60362306a36Sopenharmony_ci u32 length; 60462306a36Sopenharmony_ci u8 *cur_offset; 60562306a36Sopenharmony_ci PGETPHYSADDR get_phys_addr; 60662306a36Sopenharmony_ci union { 60762306a36Sopenharmony_ci struct { 60862306a36Sopenharmony_ci struct atto_vda_sge *curr; 60962306a36Sopenharmony_ci struct atto_vda_sge *last; 61062306a36Sopenharmony_ci struct atto_vda_sge *limit; 61162306a36Sopenharmony_ci struct atto_vda_sge *chain; 61262306a36Sopenharmony_ci } a64; 61362306a36Sopenharmony_ci struct { 61462306a36Sopenharmony_ci struct atto_physical_region_description *curr; 61562306a36Sopenharmony_ci struct atto_physical_region_description *chain; 61662306a36Sopenharmony_ci u32 sgl_max_cnt; 61762306a36Sopenharmony_ci u32 sge_cnt; 61862306a36Sopenharmony_ci } prd; 61962306a36Sopenharmony_ci } sge; 62062306a36Sopenharmony_ci struct scatterlist *cur_sgel; 62162306a36Sopenharmony_ci u8 *exp_offset; 62262306a36Sopenharmony_ci int num_sgel; 62362306a36Sopenharmony_ci int sgel_count; 62462306a36Sopenharmony_ci}; 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_cistruct esas2r_target { 62762306a36Sopenharmony_ci u8 flags; 62862306a36Sopenharmony_ci #define TF_PASS_THRU 0x01 62962306a36Sopenharmony_ci #define TF_USED 0x02 63062306a36Sopenharmony_ci u8 new_target_state; 63162306a36Sopenharmony_ci u8 target_state; 63262306a36Sopenharmony_ci u8 buffered_target_state; 63362306a36Sopenharmony_ci#define TS_NOT_PRESENT 0x00 63462306a36Sopenharmony_ci#define TS_PRESENT 0x05 63562306a36Sopenharmony_ci#define TS_LUN_CHANGE 0x06 63662306a36Sopenharmony_ci#define TS_INVALID 0xFF 63762306a36Sopenharmony_ci u32 block_size; 63862306a36Sopenharmony_ci u32 inter_block; 63962306a36Sopenharmony_ci u32 inter_byte; 64062306a36Sopenharmony_ci u16 virt_targ_id; 64162306a36Sopenharmony_ci u16 phys_targ_id; 64262306a36Sopenharmony_ci u8 identifier_len; 64362306a36Sopenharmony_ci u64 sas_addr; 64462306a36Sopenharmony_ci u8 identifier[60]; 64562306a36Sopenharmony_ci struct atto_vda_ae_lu lu_event; 64662306a36Sopenharmony_ci}; 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_cistruct esas2r_request { 64962306a36Sopenharmony_ci struct list_head comp_list; 65062306a36Sopenharmony_ci struct list_head req_list; 65162306a36Sopenharmony_ci union atto_vda_req *vrq; 65262306a36Sopenharmony_ci struct esas2r_mem_desc *vrq_md; 65362306a36Sopenharmony_ci union { 65462306a36Sopenharmony_ci void *data_buf; 65562306a36Sopenharmony_ci union atto_vda_rsp_data *vda_rsp_data; 65662306a36Sopenharmony_ci }; 65762306a36Sopenharmony_ci u8 *sense_buf; 65862306a36Sopenharmony_ci struct list_head sg_table_head; 65962306a36Sopenharmony_ci struct esas2r_mem_desc *sg_table; 66062306a36Sopenharmony_ci u32 timeout; 66162306a36Sopenharmony_ci #define RQ_TIMEOUT_S1 0xFFFFFFFF 66262306a36Sopenharmony_ci #define RQ_TIMEOUT_S2 0xFFFFFFFE 66362306a36Sopenharmony_ci #define RQ_MAX_TIMEOUT 0xFFFFFFFD 66462306a36Sopenharmony_ci u16 target_id; 66562306a36Sopenharmony_ci u8 req_type; 66662306a36Sopenharmony_ci #define RT_INI_REQ 0x01 66762306a36Sopenharmony_ci #define RT_DISC_REQ 0x02 66862306a36Sopenharmony_ci u8 sense_len; 66962306a36Sopenharmony_ci union atto_vda_func_rsp func_rsp; 67062306a36Sopenharmony_ci RQCALLBK comp_cb; 67162306a36Sopenharmony_ci RQCALLBK interrupt_cb; 67262306a36Sopenharmony_ci void *interrupt_cx; 67362306a36Sopenharmony_ci u8 flags; 67462306a36Sopenharmony_ci #define RF_1ST_IBLK_BASE 0x04 67562306a36Sopenharmony_ci #define RF_FAILURE_OK 0x08 67662306a36Sopenharmony_ci u8 req_stat; 67762306a36Sopenharmony_ci u16 vda_req_sz; 67862306a36Sopenharmony_ci #define RQ_SIZE_DEFAULT 0 67962306a36Sopenharmony_ci u64 lba; 68062306a36Sopenharmony_ci RQCALLBK aux_req_cb; 68162306a36Sopenharmony_ci void *aux_req_cx; 68262306a36Sopenharmony_ci u32 blk_len; 68362306a36Sopenharmony_ci u32 max_blk_len; 68462306a36Sopenharmony_ci union { 68562306a36Sopenharmony_ci struct scsi_cmnd *cmd; 68662306a36Sopenharmony_ci u8 *task_management_status_ptr; 68762306a36Sopenharmony_ci }; 68862306a36Sopenharmony_ci}; 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_cistruct esas2r_flash_context { 69162306a36Sopenharmony_ci struct esas2r_flash_img *fi; 69262306a36Sopenharmony_ci RQCALLBK interrupt_cb; 69362306a36Sopenharmony_ci u8 *sgc_offset; 69462306a36Sopenharmony_ci u8 *scratch; 69562306a36Sopenharmony_ci u32 fi_hdr_len; 69662306a36Sopenharmony_ci u8 task; 69762306a36Sopenharmony_ci #define FMTSK_ERASE_BOOT 0 69862306a36Sopenharmony_ci #define FMTSK_WRTBIOS 1 69962306a36Sopenharmony_ci #define FMTSK_READBIOS 2 70062306a36Sopenharmony_ci #define FMTSK_WRTMAC 3 70162306a36Sopenharmony_ci #define FMTSK_READMAC 4 70262306a36Sopenharmony_ci #define FMTSK_WRTEFI 5 70362306a36Sopenharmony_ci #define FMTSK_READEFI 6 70462306a36Sopenharmony_ci #define FMTSK_WRTCFG 7 70562306a36Sopenharmony_ci #define FMTSK_READCFG 8 70662306a36Sopenharmony_ci u8 func; 70762306a36Sopenharmony_ci u16 num_comps; 70862306a36Sopenharmony_ci u32 cmp_len; 70962306a36Sopenharmony_ci u32 flsh_addr; 71062306a36Sopenharmony_ci u32 curr_len; 71162306a36Sopenharmony_ci u8 comp_typ; 71262306a36Sopenharmony_ci struct esas2r_sg_context sgc; 71362306a36Sopenharmony_ci}; 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_cistruct esas2r_disc_context { 71662306a36Sopenharmony_ci u8 disc_evt; 71762306a36Sopenharmony_ci #define DCDE_DEV_CHANGE 0x01 71862306a36Sopenharmony_ci #define DCDE_DEV_SCAN 0x02 71962306a36Sopenharmony_ci u8 state; 72062306a36Sopenharmony_ci #define DCS_DEV_RMV 0x00 72162306a36Sopenharmony_ci #define DCS_DEV_ADD 0x01 72262306a36Sopenharmony_ci #define DCS_BLOCK_DEV_SCAN 0x02 72362306a36Sopenharmony_ci #define DCS_RAID_GRP_INFO 0x03 72462306a36Sopenharmony_ci #define DCS_PART_INFO 0x04 72562306a36Sopenharmony_ci #define DCS_PT_DEV_INFO 0x05 72662306a36Sopenharmony_ci #define DCS_PT_DEV_ADDR 0x06 72762306a36Sopenharmony_ci #define DCS_DISC_DONE 0xFF 72862306a36Sopenharmony_ci u16 flags; 72962306a36Sopenharmony_ci #define DCF_DEV_CHANGE 0x0001 73062306a36Sopenharmony_ci #define DCF_DEV_SCAN 0x0002 73162306a36Sopenharmony_ci #define DCF_POLLED 0x8000 73262306a36Sopenharmony_ci u32 interleave; 73362306a36Sopenharmony_ci u32 block_size; 73462306a36Sopenharmony_ci u16 dev_ix; 73562306a36Sopenharmony_ci u8 part_num; 73662306a36Sopenharmony_ci u8 raid_grp_ix; 73762306a36Sopenharmony_ci char raid_grp_name[16]; 73862306a36Sopenharmony_ci struct esas2r_target *curr_targ; 73962306a36Sopenharmony_ci u16 curr_virt_id; 74062306a36Sopenharmony_ci u16 curr_phys_id; 74162306a36Sopenharmony_ci u8 scan_gen; 74262306a36Sopenharmony_ci u8 dev_addr_type; 74362306a36Sopenharmony_ci u64 sas_addr; 74462306a36Sopenharmony_ci}; 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_cistruct esas2r_mem_desc { 74762306a36Sopenharmony_ci struct list_head next_desc; 74862306a36Sopenharmony_ci void *virt_addr; 74962306a36Sopenharmony_ci u64 phys_addr; 75062306a36Sopenharmony_ci void *pad; 75162306a36Sopenharmony_ci void *esas2r_data; 75262306a36Sopenharmony_ci u32 esas2r_param; 75362306a36Sopenharmony_ci u32 size; 75462306a36Sopenharmony_ci}; 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_cienum fw_event_type { 75762306a36Sopenharmony_ci fw_event_null, 75862306a36Sopenharmony_ci fw_event_lun_change, 75962306a36Sopenharmony_ci fw_event_present, 76062306a36Sopenharmony_ci fw_event_not_present, 76162306a36Sopenharmony_ci fw_event_vda_ae 76262306a36Sopenharmony_ci}; 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_cistruct esas2r_vda_ae { 76562306a36Sopenharmony_ci u32 signature; 76662306a36Sopenharmony_ci#define ESAS2R_VDA_EVENT_SIG 0x4154544F 76762306a36Sopenharmony_ci u8 bus_number; 76862306a36Sopenharmony_ci u8 devfn; 76962306a36Sopenharmony_ci u8 pad[2]; 77062306a36Sopenharmony_ci union atto_vda_ae vda_ae; 77162306a36Sopenharmony_ci}; 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_cistruct esas2r_fw_event_work { 77462306a36Sopenharmony_ci struct list_head list; 77562306a36Sopenharmony_ci struct delayed_work work; 77662306a36Sopenharmony_ci struct esas2r_adapter *a; 77762306a36Sopenharmony_ci enum fw_event_type type; 77862306a36Sopenharmony_ci u8 data[sizeof(struct esas2r_vda_ae)]; 77962306a36Sopenharmony_ci}; 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_cienum state { 78262306a36Sopenharmony_ci FW_INVALID_ST, 78362306a36Sopenharmony_ci FW_STATUS_ST, 78462306a36Sopenharmony_ci FW_COMMAND_ST 78562306a36Sopenharmony_ci}; 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_cistruct esas2r_firmware { 78862306a36Sopenharmony_ci enum state state; 78962306a36Sopenharmony_ci struct esas2r_flash_img header; 79062306a36Sopenharmony_ci u8 *data; 79162306a36Sopenharmony_ci u64 phys; 79262306a36Sopenharmony_ci int orig_len; 79362306a36Sopenharmony_ci void *header_buff; 79462306a36Sopenharmony_ci u64 header_buff_phys; 79562306a36Sopenharmony_ci}; 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_cistruct esas2r_adapter { 79862306a36Sopenharmony_ci struct esas2r_target targetdb[ESAS2R_MAX_TARGETS]; 79962306a36Sopenharmony_ci struct esas2r_target *targetdb_end; 80062306a36Sopenharmony_ci unsigned char *regs; 80162306a36Sopenharmony_ci unsigned char *data_window; 80262306a36Sopenharmony_ci long flags; 80362306a36Sopenharmony_ci #define AF_PORT_CHANGE 0 80462306a36Sopenharmony_ci #define AF_CHPRST_NEEDED 1 80562306a36Sopenharmony_ci #define AF_CHPRST_PENDING 2 80662306a36Sopenharmony_ci #define AF_CHPRST_DETECTED 3 80762306a36Sopenharmony_ci #define AF_BUSRST_NEEDED 4 80862306a36Sopenharmony_ci #define AF_BUSRST_PENDING 5 80962306a36Sopenharmony_ci #define AF_BUSRST_DETECTED 6 81062306a36Sopenharmony_ci #define AF_DISABLED 7 81162306a36Sopenharmony_ci #define AF_FLASH_LOCK 8 81262306a36Sopenharmony_ci #define AF_OS_RESET 9 81362306a36Sopenharmony_ci #define AF_FLASHING 10 81462306a36Sopenharmony_ci #define AF_POWER_MGT 11 81562306a36Sopenharmony_ci #define AF_NVR_VALID 12 81662306a36Sopenharmony_ci #define AF_DEGRADED_MODE 13 81762306a36Sopenharmony_ci #define AF_DISC_PENDING 14 81862306a36Sopenharmony_ci #define AF_TASKLET_SCHEDULED 15 81962306a36Sopenharmony_ci #define AF_HEARTBEAT 16 82062306a36Sopenharmony_ci #define AF_HEARTBEAT_ENB 17 82162306a36Sopenharmony_ci #define AF_NOT_PRESENT 18 82262306a36Sopenharmony_ci #define AF_CHPRST_STARTED 19 82362306a36Sopenharmony_ci #define AF_FIRST_INIT 20 82462306a36Sopenharmony_ci #define AF_POWER_DOWN 21 82562306a36Sopenharmony_ci #define AF_DISC_IN_PROG 22 82662306a36Sopenharmony_ci #define AF_COMM_LIST_TOGGLE 23 82762306a36Sopenharmony_ci #define AF_LEGACY_SGE_MODE 24 82862306a36Sopenharmony_ci #define AF_DISC_POLLED 25 82962306a36Sopenharmony_ci long flags2; 83062306a36Sopenharmony_ci #define AF2_SERIAL_FLASH 0 83162306a36Sopenharmony_ci #define AF2_DEV_SCAN 1 83262306a36Sopenharmony_ci #define AF2_DEV_CNT_OK 2 83362306a36Sopenharmony_ci #define AF2_COREDUMP_AVAIL 3 83462306a36Sopenharmony_ci #define AF2_COREDUMP_SAVED 4 83562306a36Sopenharmony_ci #define AF2_VDA_POWER_DOWN 5 83662306a36Sopenharmony_ci #define AF2_THUNDERLINK 6 83762306a36Sopenharmony_ci #define AF2_THUNDERBOLT 7 83862306a36Sopenharmony_ci #define AF2_INIT_DONE 8 83962306a36Sopenharmony_ci #define AF2_INT_PENDING 9 84062306a36Sopenharmony_ci #define AF2_TIMER_TICK 10 84162306a36Sopenharmony_ci #define AF2_IRQ_CLAIMED 11 84262306a36Sopenharmony_ci #define AF2_MSI_ENABLED 12 84362306a36Sopenharmony_ci atomic_t disable_cnt; 84462306a36Sopenharmony_ci atomic_t dis_ints_cnt; 84562306a36Sopenharmony_ci u32 int_stat; 84662306a36Sopenharmony_ci u32 int_mask; 84762306a36Sopenharmony_ci u32 volatile *outbound_copy; 84862306a36Sopenharmony_ci struct list_head avail_request; 84962306a36Sopenharmony_ci spinlock_t request_lock; 85062306a36Sopenharmony_ci spinlock_t sg_list_lock; 85162306a36Sopenharmony_ci spinlock_t queue_lock; 85262306a36Sopenharmony_ci spinlock_t mem_lock; 85362306a36Sopenharmony_ci struct list_head free_sg_list_head; 85462306a36Sopenharmony_ci struct esas2r_mem_desc *sg_list_mds; 85562306a36Sopenharmony_ci struct list_head active_list; 85662306a36Sopenharmony_ci struct list_head defer_list; 85762306a36Sopenharmony_ci struct esas2r_request **req_table; 85862306a36Sopenharmony_ci union { 85962306a36Sopenharmony_ci u16 prev_dev_cnt; 86062306a36Sopenharmony_ci u32 heartbeat_time; 86162306a36Sopenharmony_ci #define ESAS2R_HEARTBEAT_TIME (3000) 86262306a36Sopenharmony_ci }; 86362306a36Sopenharmony_ci u32 chip_uptime; 86462306a36Sopenharmony_ci #define ESAS2R_CHP_UPTIME_MAX (60000) 86562306a36Sopenharmony_ci #define ESAS2R_CHP_UPTIME_CNT (20000) 86662306a36Sopenharmony_ci u64 uncached_phys; 86762306a36Sopenharmony_ci u8 *uncached; 86862306a36Sopenharmony_ci struct esas2r_sas_nvram *nvram; 86962306a36Sopenharmony_ci struct esas2r_request general_req; 87062306a36Sopenharmony_ci u8 init_msg; 87162306a36Sopenharmony_ci #define ESAS2R_INIT_MSG_START 1 87262306a36Sopenharmony_ci #define ESAS2R_INIT_MSG_INIT 2 87362306a36Sopenharmony_ci #define ESAS2R_INIT_MSG_GET_INIT 3 87462306a36Sopenharmony_ci #define ESAS2R_INIT_MSG_REINIT 4 87562306a36Sopenharmony_ci u16 cmd_ref_no; 87662306a36Sopenharmony_ci u32 fw_version; 87762306a36Sopenharmony_ci u32 fw_build; 87862306a36Sopenharmony_ci u32 chip_init_time; 87962306a36Sopenharmony_ci #define ESAS2R_CHPRST_TIME (180000) 88062306a36Sopenharmony_ci #define ESAS2R_CHPRST_WAIT_TIME (2000) 88162306a36Sopenharmony_ci u32 last_tick_time; 88262306a36Sopenharmony_ci u32 window_base; 88362306a36Sopenharmony_ci RQBUILDSGL build_sgl; 88462306a36Sopenharmony_ci struct esas2r_request *first_ae_req; 88562306a36Sopenharmony_ci u32 list_size; 88662306a36Sopenharmony_ci u32 last_write; 88762306a36Sopenharmony_ci u32 last_read; 88862306a36Sopenharmony_ci u16 max_vdareq_size; 88962306a36Sopenharmony_ci u16 disc_wait_cnt; 89062306a36Sopenharmony_ci struct esas2r_mem_desc inbound_list_md; 89162306a36Sopenharmony_ci struct esas2r_mem_desc outbound_list_md; 89262306a36Sopenharmony_ci struct esas2r_disc_context disc_ctx; 89362306a36Sopenharmony_ci u8 *disc_buffer; 89462306a36Sopenharmony_ci u32 disc_start_time; 89562306a36Sopenharmony_ci u32 disc_wait_time; 89662306a36Sopenharmony_ci u32 flash_ver; 89762306a36Sopenharmony_ci char flash_rev[16]; 89862306a36Sopenharmony_ci char fw_rev[16]; 89962306a36Sopenharmony_ci char image_type[16]; 90062306a36Sopenharmony_ci struct esas2r_flash_context flash_context; 90162306a36Sopenharmony_ci u32 num_targets_backend; 90262306a36Sopenharmony_ci u32 ioctl_tunnel; 90362306a36Sopenharmony_ci struct tasklet_struct tasklet; 90462306a36Sopenharmony_ci struct pci_dev *pcid; 90562306a36Sopenharmony_ci struct Scsi_Host *host; 90662306a36Sopenharmony_ci unsigned int index; 90762306a36Sopenharmony_ci char name[32]; 90862306a36Sopenharmony_ci struct timer_list timer; 90962306a36Sopenharmony_ci struct esas2r_firmware firmware; 91062306a36Sopenharmony_ci wait_queue_head_t nvram_waiter; 91162306a36Sopenharmony_ci int nvram_command_done; 91262306a36Sopenharmony_ci wait_queue_head_t fm_api_waiter; 91362306a36Sopenharmony_ci int fm_api_command_done; 91462306a36Sopenharmony_ci wait_queue_head_t vda_waiter; 91562306a36Sopenharmony_ci int vda_command_done; 91662306a36Sopenharmony_ci u8 *vda_buffer; 91762306a36Sopenharmony_ci u64 ppvda_buffer; 91862306a36Sopenharmony_ci#define VDA_BUFFER_HEADER_SZ (offsetof(struct atto_ioctl_vda, data)) 91962306a36Sopenharmony_ci#define VDA_MAX_BUFFER_SIZE (0x40000 + VDA_BUFFER_HEADER_SZ) 92062306a36Sopenharmony_ci wait_queue_head_t fs_api_waiter; 92162306a36Sopenharmony_ci int fs_api_command_done; 92262306a36Sopenharmony_ci u64 ppfs_api_buffer; 92362306a36Sopenharmony_ci u8 *fs_api_buffer; 92462306a36Sopenharmony_ci u32 fs_api_buffer_size; 92562306a36Sopenharmony_ci wait_queue_head_t buffered_ioctl_waiter; 92662306a36Sopenharmony_ci int buffered_ioctl_done; 92762306a36Sopenharmony_ci int uncached_size; 92862306a36Sopenharmony_ci struct workqueue_struct *fw_event_q; 92962306a36Sopenharmony_ci struct list_head fw_event_list; 93062306a36Sopenharmony_ci spinlock_t fw_event_lock; 93162306a36Sopenharmony_ci u8 fw_events_off; /* if '1', then ignore events */ 93262306a36Sopenharmony_ci char fw_event_q_name[ESAS2R_KOBJ_NAME_LEN]; 93362306a36Sopenharmony_ci /* 93462306a36Sopenharmony_ci * intr_mode stores the interrupt mode currently being used by this 93562306a36Sopenharmony_ci * adapter. it is based on the interrupt_mode module parameter, but 93662306a36Sopenharmony_ci * can be changed based on the ability (or not) to utilize the 93762306a36Sopenharmony_ci * mode requested by the parameter. 93862306a36Sopenharmony_ci */ 93962306a36Sopenharmony_ci int intr_mode; 94062306a36Sopenharmony_ci#define INTR_MODE_LEGACY 0 94162306a36Sopenharmony_ci#define INTR_MODE_MSI 1 94262306a36Sopenharmony_ci#define INTR_MODE_MSIX 2 94362306a36Sopenharmony_ci struct esas2r_sg_context fm_api_sgc; 94462306a36Sopenharmony_ci u8 *save_offset; 94562306a36Sopenharmony_ci struct list_head vrq_mds_head; 94662306a36Sopenharmony_ci struct esas2r_mem_desc *vrq_mds; 94762306a36Sopenharmony_ci int num_vrqs; 94862306a36Sopenharmony_ci struct mutex fm_api_mutex; 94962306a36Sopenharmony_ci struct mutex fs_api_mutex; 95062306a36Sopenharmony_ci struct semaphore nvram_semaphore; 95162306a36Sopenharmony_ci struct atto_ioctl *local_atto_ioctl; 95262306a36Sopenharmony_ci u8 fw_coredump_buff[ESAS2R_FWCOREDUMP_SZ]; 95362306a36Sopenharmony_ci unsigned int sysfs_fw_created:1; 95462306a36Sopenharmony_ci unsigned int sysfs_fs_created:1; 95562306a36Sopenharmony_ci unsigned int sysfs_vda_created:1; 95662306a36Sopenharmony_ci unsigned int sysfs_hw_created:1; 95762306a36Sopenharmony_ci unsigned int sysfs_live_nvram_created:1; 95862306a36Sopenharmony_ci unsigned int sysfs_default_nvram_created:1; 95962306a36Sopenharmony_ci}; 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci/* 96262306a36Sopenharmony_ci * Function Declarations 96362306a36Sopenharmony_ci * SCSI functions 96462306a36Sopenharmony_ci */ 96562306a36Sopenharmony_ciconst char *esas2r_info(struct Scsi_Host *); 96662306a36Sopenharmony_ciint esas2r_write_params(struct esas2r_adapter *a, struct esas2r_request *rq, 96762306a36Sopenharmony_ci struct esas2r_sas_nvram *data); 96862306a36Sopenharmony_ciint esas2r_ioctl_handler(void *hostdata, unsigned int cmd, void __user *arg); 96962306a36Sopenharmony_ciint esas2r_ioctl(struct scsi_device *dev, unsigned int cmd, void __user *arg); 97062306a36Sopenharmony_ciu8 handle_hba_ioctl(struct esas2r_adapter *a, 97162306a36Sopenharmony_ci struct atto_ioctl *ioctl_hba); 97262306a36Sopenharmony_ciint esas2r_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd); 97362306a36Sopenharmony_ciint esas2r_show_info(struct seq_file *m, struct Scsi_Host *sh); 97462306a36Sopenharmony_cilong esas2r_proc_ioctl(struct file *fp, unsigned int cmd, unsigned long arg); 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci/* SCSI error handler (eh) functions */ 97762306a36Sopenharmony_ciint esas2r_eh_abort(struct scsi_cmnd *cmd); 97862306a36Sopenharmony_ciint esas2r_device_reset(struct scsi_cmnd *cmd); 97962306a36Sopenharmony_ciint esas2r_host_reset(struct scsi_cmnd *cmd); 98062306a36Sopenharmony_ciint esas2r_bus_reset(struct scsi_cmnd *cmd); 98162306a36Sopenharmony_ciint esas2r_target_reset(struct scsi_cmnd *cmd); 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci/* Internal functions */ 98462306a36Sopenharmony_ciint esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid, 98562306a36Sopenharmony_ci int index); 98662306a36Sopenharmony_ciint esas2r_read_fw(struct esas2r_adapter *a, char *buf, long off, int count); 98762306a36Sopenharmony_ciint esas2r_write_fw(struct esas2r_adapter *a, const char *buf, long off, 98862306a36Sopenharmony_ci int count); 98962306a36Sopenharmony_ciint esas2r_read_vda(struct esas2r_adapter *a, char *buf, long off, int count); 99062306a36Sopenharmony_ciint esas2r_write_vda(struct esas2r_adapter *a, const char *buf, long off, 99162306a36Sopenharmony_ci int count); 99262306a36Sopenharmony_ciint esas2r_read_fs(struct esas2r_adapter *a, char *buf, long off, int count); 99362306a36Sopenharmony_ciint esas2r_write_fs(struct esas2r_adapter *a, const char *buf, long off, 99462306a36Sopenharmony_ci int count); 99562306a36Sopenharmony_civoid esas2r_adapter_tasklet(unsigned long context); 99662306a36Sopenharmony_ciirqreturn_t esas2r_interrupt(int irq, void *dev_id); 99762306a36Sopenharmony_ciirqreturn_t esas2r_msi_interrupt(int irq, void *dev_id); 99862306a36Sopenharmony_civoid esas2r_kickoff_timer(struct esas2r_adapter *a); 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_ciextern const struct dev_pm_ops esas2r_pm_ops; 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_civoid esas2r_fw_event_off(struct esas2r_adapter *a); 100362306a36Sopenharmony_civoid esas2r_fw_event_on(struct esas2r_adapter *a); 100462306a36Sopenharmony_cibool esas2r_nvram_write(struct esas2r_adapter *a, struct esas2r_request *rq, 100562306a36Sopenharmony_ci struct esas2r_sas_nvram *nvram); 100662306a36Sopenharmony_civoid esas2r_nvram_get_defaults(struct esas2r_adapter *a, 100762306a36Sopenharmony_ci struct esas2r_sas_nvram *nvram); 100862306a36Sopenharmony_civoid esas2r_complete_request_cb(struct esas2r_adapter *a, 100962306a36Sopenharmony_ci struct esas2r_request *rq); 101062306a36Sopenharmony_civoid esas2r_reset_detected(struct esas2r_adapter *a); 101162306a36Sopenharmony_civoid esas2r_target_state_changed(struct esas2r_adapter *ha, u16 targ_id, 101262306a36Sopenharmony_ci u8 state); 101362306a36Sopenharmony_ciint esas2r_req_status_to_error(u8 req_stat); 101462306a36Sopenharmony_civoid esas2r_kill_adapter(int i); 101562306a36Sopenharmony_civoid esas2r_free_request(struct esas2r_adapter *a, struct esas2r_request *rq); 101662306a36Sopenharmony_cistruct esas2r_request *esas2r_alloc_request(struct esas2r_adapter *a); 101762306a36Sopenharmony_ciu32 esas2r_get_uncached_size(struct esas2r_adapter *a); 101862306a36Sopenharmony_cibool esas2r_init_adapter_struct(struct esas2r_adapter *a, 101962306a36Sopenharmony_ci void **uncached_area); 102062306a36Sopenharmony_cibool esas2r_check_adapter(struct esas2r_adapter *a); 102162306a36Sopenharmony_cibool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll); 102262306a36Sopenharmony_civoid esas2r_start_request(struct esas2r_adapter *a, struct esas2r_request *rq); 102362306a36Sopenharmony_cibool esas2r_send_task_mgmt(struct esas2r_adapter *a, 102462306a36Sopenharmony_ci struct esas2r_request *rqaux, u8 task_mgt_func); 102562306a36Sopenharmony_civoid esas2r_do_tasklet_tasks(struct esas2r_adapter *a); 102662306a36Sopenharmony_civoid esas2r_adapter_interrupt(struct esas2r_adapter *a); 102762306a36Sopenharmony_civoid esas2r_do_deferred_processes(struct esas2r_adapter *a); 102862306a36Sopenharmony_civoid esas2r_reset_bus(struct esas2r_adapter *a); 102962306a36Sopenharmony_civoid esas2r_reset_adapter(struct esas2r_adapter *a); 103062306a36Sopenharmony_civoid esas2r_timer_tick(struct esas2r_adapter *a); 103162306a36Sopenharmony_ciconst char *esas2r_get_model_name(struct esas2r_adapter *a); 103262306a36Sopenharmony_ciconst char *esas2r_get_model_name_short(struct esas2r_adapter *a); 103362306a36Sopenharmony_ciu32 esas2r_stall_execution(struct esas2r_adapter *a, u32 start_time, 103462306a36Sopenharmony_ci u32 *delay); 103562306a36Sopenharmony_civoid esas2r_build_flash_req(struct esas2r_adapter *a, 103662306a36Sopenharmony_ci struct esas2r_request *rq, 103762306a36Sopenharmony_ci u8 sub_func, 103862306a36Sopenharmony_ci u8 cksum, 103962306a36Sopenharmony_ci u32 addr, 104062306a36Sopenharmony_ci u32 length); 104162306a36Sopenharmony_civoid esas2r_build_mgt_req(struct esas2r_adapter *a, 104262306a36Sopenharmony_ci struct esas2r_request *rq, 104362306a36Sopenharmony_ci u8 sub_func, 104462306a36Sopenharmony_ci u8 scan_gen, 104562306a36Sopenharmony_ci u16 dev_index, 104662306a36Sopenharmony_ci u32 length, 104762306a36Sopenharmony_ci void *data); 104862306a36Sopenharmony_civoid esas2r_build_ae_req(struct esas2r_adapter *a, struct esas2r_request *rq); 104962306a36Sopenharmony_civoid esas2r_build_cli_req(struct esas2r_adapter *a, 105062306a36Sopenharmony_ci struct esas2r_request *rq, 105162306a36Sopenharmony_ci u32 length, 105262306a36Sopenharmony_ci u32 cmd_rsp_len); 105362306a36Sopenharmony_civoid esas2r_build_ioctl_req(struct esas2r_adapter *a, 105462306a36Sopenharmony_ci struct esas2r_request *rq, 105562306a36Sopenharmony_ci u32 length, 105662306a36Sopenharmony_ci u8 sub_func); 105762306a36Sopenharmony_civoid esas2r_build_cfg_req(struct esas2r_adapter *a, 105862306a36Sopenharmony_ci struct esas2r_request *rq, 105962306a36Sopenharmony_ci u8 sub_func, 106062306a36Sopenharmony_ci u32 length, 106162306a36Sopenharmony_ci void *data); 106262306a36Sopenharmony_civoid esas2r_power_down(struct esas2r_adapter *a); 106362306a36Sopenharmony_cibool esas2r_power_up(struct esas2r_adapter *a, bool init_poll); 106462306a36Sopenharmony_civoid esas2r_wait_request(struct esas2r_adapter *a, struct esas2r_request *rq); 106562306a36Sopenharmony_ciu32 esas2r_map_data_window(struct esas2r_adapter *a, u32 addr_lo); 106662306a36Sopenharmony_cibool esas2r_process_fs_ioctl(struct esas2r_adapter *a, 106762306a36Sopenharmony_ci struct esas2r_ioctl_fs *fs, 106862306a36Sopenharmony_ci struct esas2r_request *rq, 106962306a36Sopenharmony_ci struct esas2r_sg_context *sgc); 107062306a36Sopenharmony_cibool esas2r_read_flash_block(struct esas2r_adapter *a, void *to, u32 from, 107162306a36Sopenharmony_ci u32 size); 107262306a36Sopenharmony_cibool esas2r_read_mem_block(struct esas2r_adapter *a, void *to, u32 from, 107362306a36Sopenharmony_ci u32 size); 107462306a36Sopenharmony_cibool esas2r_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi, 107562306a36Sopenharmony_ci struct esas2r_request *rq, struct esas2r_sg_context *sgc); 107662306a36Sopenharmony_civoid esas2r_force_interrupt(struct esas2r_adapter *a); 107762306a36Sopenharmony_civoid esas2r_local_start_request(struct esas2r_adapter *a, 107862306a36Sopenharmony_ci struct esas2r_request *rq); 107962306a36Sopenharmony_civoid esas2r_process_adapter_reset(struct esas2r_adapter *a); 108062306a36Sopenharmony_civoid esas2r_complete_request(struct esas2r_adapter *a, 108162306a36Sopenharmony_ci struct esas2r_request *rq); 108262306a36Sopenharmony_civoid esas2r_dummy_complete(struct esas2r_adapter *a, 108362306a36Sopenharmony_ci struct esas2r_request *rq); 108462306a36Sopenharmony_civoid esas2r_ae_complete(struct esas2r_adapter *a, struct esas2r_request *rq); 108562306a36Sopenharmony_civoid esas2r_start_vda_request(struct esas2r_adapter *a, 108662306a36Sopenharmony_ci struct esas2r_request *rq); 108762306a36Sopenharmony_cibool esas2r_read_flash_rev(struct esas2r_adapter *a); 108862306a36Sopenharmony_cibool esas2r_read_image_type(struct esas2r_adapter *a); 108962306a36Sopenharmony_cibool esas2r_nvram_read_direct(struct esas2r_adapter *a); 109062306a36Sopenharmony_cibool esas2r_nvram_validate(struct esas2r_adapter *a); 109162306a36Sopenharmony_civoid esas2r_nvram_set_defaults(struct esas2r_adapter *a); 109262306a36Sopenharmony_cibool esas2r_print_flash_rev(struct esas2r_adapter *a); 109362306a36Sopenharmony_civoid esas2r_send_reset_ae(struct esas2r_adapter *a, bool pwr_mgt); 109462306a36Sopenharmony_cibool esas2r_init_msgs(struct esas2r_adapter *a); 109562306a36Sopenharmony_cibool esas2r_is_adapter_present(struct esas2r_adapter *a); 109662306a36Sopenharmony_civoid esas2r_nuxi_mgt_data(u8 function, void *data); 109762306a36Sopenharmony_civoid esas2r_nuxi_cfg_data(u8 function, void *data); 109862306a36Sopenharmony_civoid esas2r_nuxi_ae_data(union atto_vda_ae *ae); 109962306a36Sopenharmony_civoid esas2r_reset_chip(struct esas2r_adapter *a); 110062306a36Sopenharmony_civoid esas2r_log_request_failure(struct esas2r_adapter *a, 110162306a36Sopenharmony_ci struct esas2r_request *rq); 110262306a36Sopenharmony_civoid esas2r_polled_interrupt(struct esas2r_adapter *a); 110362306a36Sopenharmony_cibool esas2r_ioreq_aborted(struct esas2r_adapter *a, struct esas2r_request *rq, 110462306a36Sopenharmony_ci u8 status); 110562306a36Sopenharmony_cibool esas2r_build_sg_list_sge(struct esas2r_adapter *a, 110662306a36Sopenharmony_ci struct esas2r_sg_context *sgc); 110762306a36Sopenharmony_cibool esas2r_build_sg_list_prd(struct esas2r_adapter *a, 110862306a36Sopenharmony_ci struct esas2r_sg_context *sgc); 110962306a36Sopenharmony_civoid esas2r_targ_db_initialize(struct esas2r_adapter *a); 111062306a36Sopenharmony_civoid esas2r_targ_db_remove_all(struct esas2r_adapter *a, bool notify); 111162306a36Sopenharmony_civoid esas2r_targ_db_report_changes(struct esas2r_adapter *a); 111262306a36Sopenharmony_cistruct esas2r_target *esas2r_targ_db_add_raid(struct esas2r_adapter *a, 111362306a36Sopenharmony_ci struct esas2r_disc_context *dc); 111462306a36Sopenharmony_cistruct esas2r_target *esas2r_targ_db_add_pthru(struct esas2r_adapter *a, 111562306a36Sopenharmony_ci struct esas2r_disc_context *dc, 111662306a36Sopenharmony_ci u8 *ident, 111762306a36Sopenharmony_ci u8 ident_len); 111862306a36Sopenharmony_civoid esas2r_targ_db_remove(struct esas2r_adapter *a, struct esas2r_target *t); 111962306a36Sopenharmony_cistruct esas2r_target *esas2r_targ_db_find_by_sas_addr(struct esas2r_adapter *a, 112062306a36Sopenharmony_ci u64 *sas_addr); 112162306a36Sopenharmony_cistruct esas2r_target *esas2r_targ_db_find_by_ident(struct esas2r_adapter *a, 112262306a36Sopenharmony_ci void *identifier, 112362306a36Sopenharmony_ci u8 ident_len); 112462306a36Sopenharmony_ciu16 esas2r_targ_db_find_next_present(struct esas2r_adapter *a, u16 target_id); 112562306a36Sopenharmony_cistruct esas2r_target *esas2r_targ_db_find_by_virt_id(struct esas2r_adapter *a, 112662306a36Sopenharmony_ci u16 virt_id); 112762306a36Sopenharmony_ciu16 esas2r_targ_db_get_tgt_cnt(struct esas2r_adapter *a); 112862306a36Sopenharmony_civoid esas2r_disc_initialize(struct esas2r_adapter *a); 112962306a36Sopenharmony_civoid esas2r_disc_start_waiting(struct esas2r_adapter *a); 113062306a36Sopenharmony_civoid esas2r_disc_check_for_work(struct esas2r_adapter *a); 113162306a36Sopenharmony_civoid esas2r_disc_check_complete(struct esas2r_adapter *a); 113262306a36Sopenharmony_civoid esas2r_disc_queue_event(struct esas2r_adapter *a, u8 disc_evt); 113362306a36Sopenharmony_cibool esas2r_disc_start_port(struct esas2r_adapter *a); 113462306a36Sopenharmony_civoid esas2r_disc_local_start_request(struct esas2r_adapter *a, 113562306a36Sopenharmony_ci struct esas2r_request *rq); 113662306a36Sopenharmony_cibool esas2r_set_degraded_mode(struct esas2r_adapter *a, char *error_str); 113762306a36Sopenharmony_cibool esas2r_process_vda_ioctl(struct esas2r_adapter *a, 113862306a36Sopenharmony_ci struct atto_ioctl_vda *vi, 113962306a36Sopenharmony_ci struct esas2r_request *rq, 114062306a36Sopenharmony_ci struct esas2r_sg_context *sgc); 114162306a36Sopenharmony_civoid esas2r_queue_fw_event(struct esas2r_adapter *a, 114262306a36Sopenharmony_ci enum fw_event_type type, 114362306a36Sopenharmony_ci void *data, 114462306a36Sopenharmony_ci int data_sz); 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci/* Inline functions */ 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_ci/* Allocate a chip scatter/gather list entry */ 114962306a36Sopenharmony_cistatic inline struct esas2r_mem_desc *esas2r_alloc_sgl(struct esas2r_adapter *a) 115062306a36Sopenharmony_ci{ 115162306a36Sopenharmony_ci unsigned long flags; 115262306a36Sopenharmony_ci struct list_head *sgl; 115362306a36Sopenharmony_ci struct esas2r_mem_desc *result = NULL; 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_ci spin_lock_irqsave(&a->sg_list_lock, flags); 115662306a36Sopenharmony_ci if (likely(!list_empty(&a->free_sg_list_head))) { 115762306a36Sopenharmony_ci sgl = a->free_sg_list_head.next; 115862306a36Sopenharmony_ci result = list_entry(sgl, struct esas2r_mem_desc, next_desc); 115962306a36Sopenharmony_ci list_del_init(sgl); 116062306a36Sopenharmony_ci } 116162306a36Sopenharmony_ci spin_unlock_irqrestore(&a->sg_list_lock, flags); 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci return result; 116462306a36Sopenharmony_ci} 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_ci/* Initialize a scatter/gather context */ 116762306a36Sopenharmony_cistatic inline void esas2r_sgc_init(struct esas2r_sg_context *sgc, 116862306a36Sopenharmony_ci struct esas2r_adapter *a, 116962306a36Sopenharmony_ci struct esas2r_request *rq, 117062306a36Sopenharmony_ci struct atto_vda_sge *first) 117162306a36Sopenharmony_ci{ 117262306a36Sopenharmony_ci sgc->adapter = a; 117362306a36Sopenharmony_ci sgc->first_req = rq; 117462306a36Sopenharmony_ci 117562306a36Sopenharmony_ci /* 117662306a36Sopenharmony_ci * set the limit pointer such that an SGE pointer above this value 117762306a36Sopenharmony_ci * would be the first one to overflow the SGL. 117862306a36Sopenharmony_ci */ 117962306a36Sopenharmony_ci sgc->sge.a64.limit = (struct atto_vda_sge *)((u8 *)rq->vrq 118062306a36Sopenharmony_ci + (sizeof(union 118162306a36Sopenharmony_ci atto_vda_req) / 118262306a36Sopenharmony_ci 8) 118362306a36Sopenharmony_ci - sizeof(struct 118462306a36Sopenharmony_ci atto_vda_sge)); 118562306a36Sopenharmony_ci if (first) { 118662306a36Sopenharmony_ci sgc->sge.a64.last = 118762306a36Sopenharmony_ci sgc->sge.a64.curr = first; 118862306a36Sopenharmony_ci rq->vrq->scsi.sg_list_offset = (u8) 118962306a36Sopenharmony_ci ((u8 *)first - 119062306a36Sopenharmony_ci (u8 *)rq->vrq); 119162306a36Sopenharmony_ci } else { 119262306a36Sopenharmony_ci sgc->sge.a64.last = 119362306a36Sopenharmony_ci sgc->sge.a64.curr = &rq->vrq->scsi.u.sge[0]; 119462306a36Sopenharmony_ci rq->vrq->scsi.sg_list_offset = 119562306a36Sopenharmony_ci (u8)offsetof(struct atto_vda_scsi_req, u.sge); 119662306a36Sopenharmony_ci } 119762306a36Sopenharmony_ci sgc->sge.a64.chain = NULL; 119862306a36Sopenharmony_ci} 119962306a36Sopenharmony_ci 120062306a36Sopenharmony_cistatic inline void esas2r_rq_init_request(struct esas2r_request *rq, 120162306a36Sopenharmony_ci struct esas2r_adapter *a) 120262306a36Sopenharmony_ci{ 120362306a36Sopenharmony_ci union atto_vda_req *vrq = rq->vrq; 120462306a36Sopenharmony_ci 120562306a36Sopenharmony_ci INIT_LIST_HEAD(&rq->sg_table_head); 120662306a36Sopenharmony_ci rq->data_buf = (void *)(vrq + 1); 120762306a36Sopenharmony_ci rq->interrupt_cb = NULL; 120862306a36Sopenharmony_ci rq->comp_cb = esas2r_complete_request_cb; 120962306a36Sopenharmony_ci rq->flags = 0; 121062306a36Sopenharmony_ci rq->timeout = 0; 121162306a36Sopenharmony_ci rq->req_stat = RS_PENDING; 121262306a36Sopenharmony_ci rq->req_type = RT_INI_REQ; 121362306a36Sopenharmony_ci 121462306a36Sopenharmony_ci /* clear the outbound response */ 121562306a36Sopenharmony_ci rq->func_rsp.dwords[0] = 0; 121662306a36Sopenharmony_ci rq->func_rsp.dwords[1] = 0; 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_ci /* 121962306a36Sopenharmony_ci * clear the size of the VDA request. esas2r_build_sg_list() will 122062306a36Sopenharmony_ci * only allow the size of the request to grow. there are some 122162306a36Sopenharmony_ci * management requests that go through there twice and the second 122262306a36Sopenharmony_ci * time through sets a smaller request size. if this is not modified 122362306a36Sopenharmony_ci * at all we'll set it to the size of the entire VDA request. 122462306a36Sopenharmony_ci */ 122562306a36Sopenharmony_ci rq->vda_req_sz = RQ_SIZE_DEFAULT; 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_ci /* req_table entry should be NULL at this point - if not, halt */ 122862306a36Sopenharmony_ci 122962306a36Sopenharmony_ci if (a->req_table[LOWORD(vrq->scsi.handle)]) { 123062306a36Sopenharmony_ci esas2r_bugon(); 123162306a36Sopenharmony_ci } 123262306a36Sopenharmony_ci 123362306a36Sopenharmony_ci /* fill in the table for this handle so we can get back to the 123462306a36Sopenharmony_ci * request. 123562306a36Sopenharmony_ci */ 123662306a36Sopenharmony_ci a->req_table[LOWORD(vrq->scsi.handle)] = rq; 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_ci /* 123962306a36Sopenharmony_ci * add a reference number to the handle to make it unique (until it 124062306a36Sopenharmony_ci * wraps of course) while preserving the least significant word 124162306a36Sopenharmony_ci */ 124262306a36Sopenharmony_ci vrq->scsi.handle = (a->cmd_ref_no++ << 16) | (u16)vrq->scsi.handle; 124362306a36Sopenharmony_ci 124462306a36Sopenharmony_ci /* 124562306a36Sopenharmony_ci * the following formats a SCSI request. the caller can override as 124662306a36Sopenharmony_ci * necessary. clear_vda_request can be called to clear the VDA 124762306a36Sopenharmony_ci * request for another type of request. 124862306a36Sopenharmony_ci */ 124962306a36Sopenharmony_ci vrq->scsi.function = VDA_FUNC_SCSI; 125062306a36Sopenharmony_ci vrq->scsi.sense_len = SENSE_DATA_SZ; 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_ci /* clear out sg_list_offset and chain_offset */ 125362306a36Sopenharmony_ci vrq->scsi.sg_list_offset = 0; 125462306a36Sopenharmony_ci vrq->scsi.chain_offset = 0; 125562306a36Sopenharmony_ci vrq->scsi.flags = 0; 125662306a36Sopenharmony_ci vrq->scsi.reserved = 0; 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_ci /* set the sense buffer to be the data payload buffer */ 125962306a36Sopenharmony_ci vrq->scsi.ppsense_buf 126062306a36Sopenharmony_ci = cpu_to_le64(rq->vrq_md->phys_addr + 126162306a36Sopenharmony_ci sizeof(union atto_vda_req)); 126262306a36Sopenharmony_ci} 126362306a36Sopenharmony_ci 126462306a36Sopenharmony_cistatic inline void esas2r_rq_free_sg_lists(struct esas2r_request *rq, 126562306a36Sopenharmony_ci struct esas2r_adapter *a) 126662306a36Sopenharmony_ci{ 126762306a36Sopenharmony_ci unsigned long flags; 126862306a36Sopenharmony_ci 126962306a36Sopenharmony_ci if (list_empty(&rq->sg_table_head)) 127062306a36Sopenharmony_ci return; 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_ci spin_lock_irqsave(&a->sg_list_lock, flags); 127362306a36Sopenharmony_ci list_splice_tail_init(&rq->sg_table_head, &a->free_sg_list_head); 127462306a36Sopenharmony_ci spin_unlock_irqrestore(&a->sg_list_lock, flags); 127562306a36Sopenharmony_ci} 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_cistatic inline void esas2r_rq_destroy_request(struct esas2r_request *rq, 127862306a36Sopenharmony_ci struct esas2r_adapter *a) 127962306a36Sopenharmony_ci 128062306a36Sopenharmony_ci{ 128162306a36Sopenharmony_ci esas2r_rq_free_sg_lists(rq, a); 128262306a36Sopenharmony_ci a->req_table[LOWORD(rq->vrq->scsi.handle)] = NULL; 128362306a36Sopenharmony_ci rq->data_buf = NULL; 128462306a36Sopenharmony_ci} 128562306a36Sopenharmony_ci 128662306a36Sopenharmony_cistatic inline bool esas2r_is_tasklet_pending(struct esas2r_adapter *a) 128762306a36Sopenharmony_ci{ 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci return test_bit(AF_BUSRST_NEEDED, &a->flags) || 129062306a36Sopenharmony_ci test_bit(AF_BUSRST_DETECTED, &a->flags) || 129162306a36Sopenharmony_ci test_bit(AF_CHPRST_NEEDED, &a->flags) || 129262306a36Sopenharmony_ci test_bit(AF_CHPRST_DETECTED, &a->flags) || 129362306a36Sopenharmony_ci test_bit(AF_PORT_CHANGE, &a->flags); 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_ci} 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_ci/* 129862306a36Sopenharmony_ci * Build the scatter/gather list for an I/O request according to the 129962306a36Sopenharmony_ci * specifications placed in the esas2r_sg_context. The caller must initialize 130062306a36Sopenharmony_ci * struct esas2r_sg_context prior to the initial call by calling 130162306a36Sopenharmony_ci * esas2r_sgc_init() 130262306a36Sopenharmony_ci */ 130362306a36Sopenharmony_cistatic inline bool esas2r_build_sg_list(struct esas2r_adapter *a, 130462306a36Sopenharmony_ci struct esas2r_request *rq, 130562306a36Sopenharmony_ci struct esas2r_sg_context *sgc) 130662306a36Sopenharmony_ci{ 130762306a36Sopenharmony_ci if (unlikely(le32_to_cpu(rq->vrq->scsi.length) == 0)) 130862306a36Sopenharmony_ci return true; 130962306a36Sopenharmony_ci 131062306a36Sopenharmony_ci return (*a->build_sgl)(a, sgc); 131162306a36Sopenharmony_ci} 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_cistatic inline void esas2r_disable_chip_interrupts(struct esas2r_adapter *a) 131462306a36Sopenharmony_ci{ 131562306a36Sopenharmony_ci if (atomic_inc_return(&a->dis_ints_cnt) == 1) 131662306a36Sopenharmony_ci esas2r_write_register_dword(a, MU_INT_MASK_OUT, 131762306a36Sopenharmony_ci ESAS2R_INT_DIS_MASK); 131862306a36Sopenharmony_ci} 131962306a36Sopenharmony_ci 132062306a36Sopenharmony_cistatic inline void esas2r_enable_chip_interrupts(struct esas2r_adapter *a) 132162306a36Sopenharmony_ci{ 132262306a36Sopenharmony_ci if (atomic_dec_return(&a->dis_ints_cnt) == 0) 132362306a36Sopenharmony_ci esas2r_write_register_dword(a, MU_INT_MASK_OUT, 132462306a36Sopenharmony_ci ESAS2R_INT_ENB_MASK); 132562306a36Sopenharmony_ci} 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci/* Schedule a TASKLET to perform non-interrupt tasks that may require delays 132862306a36Sopenharmony_ci * or long completion times. 132962306a36Sopenharmony_ci */ 133062306a36Sopenharmony_cistatic inline void esas2r_schedule_tasklet(struct esas2r_adapter *a) 133162306a36Sopenharmony_ci{ 133262306a36Sopenharmony_ci /* make sure we don't schedule twice */ 133362306a36Sopenharmony_ci if (!test_and_set_bit(AF_TASKLET_SCHEDULED, &a->flags)) 133462306a36Sopenharmony_ci tasklet_hi_schedule(&a->tasklet); 133562306a36Sopenharmony_ci} 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_cistatic inline void esas2r_enable_heartbeat(struct esas2r_adapter *a) 133862306a36Sopenharmony_ci{ 133962306a36Sopenharmony_ci if (!test_bit(AF_DEGRADED_MODE, &a->flags) && 134062306a36Sopenharmony_ci !test_bit(AF_CHPRST_PENDING, &a->flags) && 134162306a36Sopenharmony_ci (a->nvram->options2 & SASNVR2_HEARTBEAT)) 134262306a36Sopenharmony_ci set_bit(AF_HEARTBEAT_ENB, &a->flags); 134362306a36Sopenharmony_ci else 134462306a36Sopenharmony_ci clear_bit(AF_HEARTBEAT_ENB, &a->flags); 134562306a36Sopenharmony_ci} 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_cistatic inline void esas2r_disable_heartbeat(struct esas2r_adapter *a) 134862306a36Sopenharmony_ci{ 134962306a36Sopenharmony_ci clear_bit(AF_HEARTBEAT_ENB, &a->flags); 135062306a36Sopenharmony_ci clear_bit(AF_HEARTBEAT, &a->flags); 135162306a36Sopenharmony_ci} 135262306a36Sopenharmony_ci 135362306a36Sopenharmony_ci/* Set the initial state for resetting the adapter on the next pass through 135462306a36Sopenharmony_ci * esas2r_do_deferred. 135562306a36Sopenharmony_ci */ 135662306a36Sopenharmony_cistatic inline void esas2r_local_reset_adapter(struct esas2r_adapter *a) 135762306a36Sopenharmony_ci{ 135862306a36Sopenharmony_ci esas2r_disable_heartbeat(a); 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci set_bit(AF_CHPRST_NEEDED, &a->flags); 136162306a36Sopenharmony_ci set_bit(AF_CHPRST_PENDING, &a->flags); 136262306a36Sopenharmony_ci set_bit(AF_DISC_PENDING, &a->flags); 136362306a36Sopenharmony_ci} 136462306a36Sopenharmony_ci 136562306a36Sopenharmony_ci/* See if an interrupt is pending on the adapter. */ 136662306a36Sopenharmony_cistatic inline bool esas2r_adapter_interrupt_pending(struct esas2r_adapter *a) 136762306a36Sopenharmony_ci{ 136862306a36Sopenharmony_ci u32 intstat; 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci if (a->int_mask == 0) 137162306a36Sopenharmony_ci return false; 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT); 137462306a36Sopenharmony_ci 137562306a36Sopenharmony_ci if ((intstat & a->int_mask) == 0) 137662306a36Sopenharmony_ci return false; 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_ci esas2r_disable_chip_interrupts(a); 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_ci a->int_stat = intstat; 138162306a36Sopenharmony_ci a->int_mask = 0; 138262306a36Sopenharmony_ci 138362306a36Sopenharmony_ci return true; 138462306a36Sopenharmony_ci} 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_cistatic inline u16 esas2r_targ_get_id(struct esas2r_target *t, 138762306a36Sopenharmony_ci struct esas2r_adapter *a) 138862306a36Sopenharmony_ci{ 138962306a36Sopenharmony_ci return (u16)(uintptr_t)(t - a->targetdb); 139062306a36Sopenharmony_ci} 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_ci/* Build and start an asynchronous event request */ 139362306a36Sopenharmony_cistatic inline void esas2r_start_ae_request(struct esas2r_adapter *a, 139462306a36Sopenharmony_ci struct esas2r_request *rq) 139562306a36Sopenharmony_ci{ 139662306a36Sopenharmony_ci unsigned long flags; 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_ci esas2r_build_ae_req(a, rq); 139962306a36Sopenharmony_ci 140062306a36Sopenharmony_ci spin_lock_irqsave(&a->queue_lock, flags); 140162306a36Sopenharmony_ci esas2r_start_vda_request(a, rq); 140262306a36Sopenharmony_ci spin_unlock_irqrestore(&a->queue_lock, flags); 140362306a36Sopenharmony_ci} 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_cistatic inline void esas2r_comp_list_drain(struct esas2r_adapter *a, 140662306a36Sopenharmony_ci struct list_head *comp_list) 140762306a36Sopenharmony_ci{ 140862306a36Sopenharmony_ci struct esas2r_request *rq; 140962306a36Sopenharmony_ci struct list_head *element, *next; 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci list_for_each_safe(element, next, comp_list) { 141262306a36Sopenharmony_ci rq = list_entry(element, struct esas2r_request, comp_list); 141362306a36Sopenharmony_ci list_del_init(element); 141462306a36Sopenharmony_ci esas2r_complete_request(a, rq); 141562306a36Sopenharmony_ci } 141662306a36Sopenharmony_ci} 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ci/* sysfs handlers */ 141962306a36Sopenharmony_ciextern struct bin_attribute bin_attr_fw; 142062306a36Sopenharmony_ciextern struct bin_attribute bin_attr_fs; 142162306a36Sopenharmony_ciextern struct bin_attribute bin_attr_vda; 142262306a36Sopenharmony_ciextern struct bin_attribute bin_attr_hw; 142362306a36Sopenharmony_ciextern struct bin_attribute bin_attr_live_nvram; 142462306a36Sopenharmony_ciextern struct bin_attribute bin_attr_default_nvram; 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ci#endif /* ESAS2R_H */ 1427