18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * linux/drivers/scsi/esas2r/esas2r.h 38c2ecf20Sopenharmony_ci * For use with ATTO ExpressSAS R6xx SAS/SATA RAID controllers 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2001-2013 ATTO Technology, Inc. 68c2ecf20Sopenharmony_ci * (mailto:linuxdrivers@attotech.com) 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or 98c2ecf20Sopenharmony_ci * modify it under the terms of the GNU General Public License 108c2ecf20Sopenharmony_ci * as published by the Free Software Foundation; either version 2 118c2ecf20Sopenharmony_ci * of the License, or (at your option) any later version. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * This program is distributed in the hope that it will be useful, 148c2ecf20Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 158c2ecf20Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 168c2ecf20Sopenharmony_ci * GNU General Public License for more details. 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * NO WARRANTY 198c2ecf20Sopenharmony_ci * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 208c2ecf20Sopenharmony_ci * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 218c2ecf20Sopenharmony_ci * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 228c2ecf20Sopenharmony_ci * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 238c2ecf20Sopenharmony_ci * solely responsible for determining the appropriateness of using and 248c2ecf20Sopenharmony_ci * distributing the Program and assumes all risks associated with its 258c2ecf20Sopenharmony_ci * exercise of rights under this Agreement, including but not limited to 268c2ecf20Sopenharmony_ci * the risks and costs of program errors, damage to or loss of data, 278c2ecf20Sopenharmony_ci * programs or equipment, and unavailability or interruption of operations. 288c2ecf20Sopenharmony_ci * 298c2ecf20Sopenharmony_ci * DISCLAIMER OF LIABILITY 308c2ecf20Sopenharmony_ci * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 318c2ecf20Sopenharmony_ci * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 328c2ecf20Sopenharmony_ci * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 338c2ecf20Sopenharmony_ci * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 348c2ecf20Sopenharmony_ci * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 358c2ecf20Sopenharmony_ci * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 368c2ecf20Sopenharmony_ci * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 378c2ecf20Sopenharmony_ci * 388c2ecf20Sopenharmony_ci * You should have received a copy of the GNU General Public License 398c2ecf20Sopenharmony_ci * along with this program; if not, write to the Free Software 408c2ecf20Sopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 418c2ecf20Sopenharmony_ci * USA. 428c2ecf20Sopenharmony_ci */ 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#include <linux/kernel.h> 458c2ecf20Sopenharmony_ci#include <linux/delay.h> 468c2ecf20Sopenharmony_ci#include <linux/pci.h> 478c2ecf20Sopenharmony_ci#include <linux/proc_fs.h> 488c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 498c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 508c2ecf20Sopenharmony_ci#include <linux/module.h> 518c2ecf20Sopenharmony_ci#include <linux/vmalloc.h> 528c2ecf20Sopenharmony_ci#include <scsi/scsi.h> 538c2ecf20Sopenharmony_ci#include <scsi/scsi_host.h> 548c2ecf20Sopenharmony_ci#include <scsi/scsi_cmnd.h> 558c2ecf20Sopenharmony_ci#include <scsi/scsi_device.h> 568c2ecf20Sopenharmony_ci#include <scsi/scsi_eh.h> 578c2ecf20Sopenharmony_ci#include <scsi/scsi_tcq.h> 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#include "esas2r_log.h" 608c2ecf20Sopenharmony_ci#include "atioctl.h" 618c2ecf20Sopenharmony_ci#include "atvda.h" 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci#ifndef ESAS2R_H 648c2ecf20Sopenharmony_ci#define ESAS2R_H 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci/* Global Variables */ 678c2ecf20Sopenharmony_ciextern struct esas2r_adapter *esas2r_adapters[]; 688c2ecf20Sopenharmony_ciextern u8 *esas2r_buffered_ioctl; 698c2ecf20Sopenharmony_ciextern dma_addr_t esas2r_buffered_ioctl_addr; 708c2ecf20Sopenharmony_ciextern u32 esas2r_buffered_ioctl_size; 718c2ecf20Sopenharmony_ciextern struct pci_dev *esas2r_buffered_ioctl_pcid; 728c2ecf20Sopenharmony_ci#define SGL_PG_SZ_MIN 64 738c2ecf20Sopenharmony_ci#define SGL_PG_SZ_MAX 1024 748c2ecf20Sopenharmony_ciextern int sgl_page_size; 758c2ecf20Sopenharmony_ci#define NUM_SGL_MIN 8 768c2ecf20Sopenharmony_ci#define NUM_SGL_MAX 2048 778c2ecf20Sopenharmony_ciextern int num_sg_lists; 788c2ecf20Sopenharmony_ci#define NUM_REQ_MIN 4 798c2ecf20Sopenharmony_ci#define NUM_REQ_MAX 256 808c2ecf20Sopenharmony_ciextern int num_requests; 818c2ecf20Sopenharmony_ci#define NUM_AE_MIN 2 828c2ecf20Sopenharmony_ci#define NUM_AE_MAX 8 838c2ecf20Sopenharmony_ciextern int num_ae_requests; 848c2ecf20Sopenharmony_ciextern int cmd_per_lun; 858c2ecf20Sopenharmony_ciextern int can_queue; 868c2ecf20Sopenharmony_ciextern int esas2r_max_sectors; 878c2ecf20Sopenharmony_ciextern int sg_tablesize; 888c2ecf20Sopenharmony_ciextern int interrupt_mode; 898c2ecf20Sopenharmony_ciextern int num_io_requests; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci/* Macro defintions */ 928c2ecf20Sopenharmony_ci#define ESAS2R_MAX_ID 255 938c2ecf20Sopenharmony_ci#define MAX_ADAPTERS 32 948c2ecf20Sopenharmony_ci#define ESAS2R_DRVR_NAME "esas2r" 958c2ecf20Sopenharmony_ci#define ESAS2R_LONGNAME "ATTO ExpressSAS 6GB RAID Adapter" 968c2ecf20Sopenharmony_ci#define ESAS2R_MAX_DEVICES 32 978c2ecf20Sopenharmony_ci#define ATTONODE_NAME "ATTONode" 988c2ecf20Sopenharmony_ci#define ESAS2R_MAJOR_REV 1 998c2ecf20Sopenharmony_ci#define ESAS2R_MINOR_REV 00 1008c2ecf20Sopenharmony_ci#define ESAS2R_VERSION_STR DEFINED_NUM_TO_STR(ESAS2R_MAJOR_REV) "." \ 1018c2ecf20Sopenharmony_ci DEFINED_NUM_TO_STR(ESAS2R_MINOR_REV) 1028c2ecf20Sopenharmony_ci#define ESAS2R_COPYRIGHT_YEARS "2001-2013" 1038c2ecf20Sopenharmony_ci#define ESAS2R_DEFAULT_SGL_PAGE_SIZE 384 1048c2ecf20Sopenharmony_ci#define ESAS2R_DEFAULT_CMD_PER_LUN 64 1058c2ecf20Sopenharmony_ci#define ESAS2R_DEFAULT_NUM_SG_LISTS 1024 1068c2ecf20Sopenharmony_ci#define DEFINED_NUM_TO_STR(num) NUM_TO_STR(num) 1078c2ecf20Sopenharmony_ci#define NUM_TO_STR(num) #num 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci#define ESAS2R_SGL_ALIGN 16 1108c2ecf20Sopenharmony_ci#define ESAS2R_LIST_ALIGN 16 1118c2ecf20Sopenharmony_ci#define ESAS2R_LIST_EXTRA ESAS2R_NUM_EXTRA 1128c2ecf20Sopenharmony_ci#define ESAS2R_DATA_BUF_LEN 256 1138c2ecf20Sopenharmony_ci#define ESAS2R_DEFAULT_TMO 5000 1148c2ecf20Sopenharmony_ci#define ESAS2R_DISC_BUF_LEN 512 1158c2ecf20Sopenharmony_ci#define ESAS2R_FWCOREDUMP_SZ 0x80000 1168c2ecf20Sopenharmony_ci#define ESAS2R_NUM_PHYS 8 1178c2ecf20Sopenharmony_ci#define ESAS2R_TARG_ID_INV 0xFFFF 1188c2ecf20Sopenharmony_ci#define ESAS2R_INT_STS_MASK MU_INTSTAT_MASK 1198c2ecf20Sopenharmony_ci#define ESAS2R_INT_ENB_MASK MU_INTSTAT_MASK 1208c2ecf20Sopenharmony_ci#define ESAS2R_INT_DIS_MASK 0 1218c2ecf20Sopenharmony_ci#define ESAS2R_MAX_TARGETS 256 1228c2ecf20Sopenharmony_ci#define ESAS2R_KOBJ_NAME_LEN 20 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci/* u16 (WORD) component macros */ 1258c2ecf20Sopenharmony_ci#define LOBYTE(w) ((u8)(u16)(w)) 1268c2ecf20Sopenharmony_ci#define HIBYTE(w) ((u8)(((u16)(w)) >> 8)) 1278c2ecf20Sopenharmony_ci#define MAKEWORD(lo, hi) ((u16)((u8)(lo) | ((u16)(u8)(hi) << 8))) 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci/* u32 (DWORD) component macros */ 1308c2ecf20Sopenharmony_ci#define LOWORD(d) ((u16)(u32)(d)) 1318c2ecf20Sopenharmony_ci#define HIWORD(d) ((u16)(((u32)(d)) >> 16)) 1328c2ecf20Sopenharmony_ci#define MAKEDWORD(lo, hi) ((u32)((u16)(lo) | ((u32)(u16)(hi) << 16))) 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci/* macro to get the lowest nonzero bit of a value */ 1358c2ecf20Sopenharmony_ci#define LOBIT(x) ((x) & (0 - (x))) 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci/* These functions are provided to access the chip's control registers. 1388c2ecf20Sopenharmony_ci * The register is specified by its byte offset from the register base 1398c2ecf20Sopenharmony_ci * for the adapter. 1408c2ecf20Sopenharmony_ci */ 1418c2ecf20Sopenharmony_ci#define esas2r_read_register_dword(a, reg) \ 1428c2ecf20Sopenharmony_ci readl((void __iomem *)a->regs + (reg) + MW_REG_OFFSET_HWREG) 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci#define esas2r_write_register_dword(a, reg, data) \ 1458c2ecf20Sopenharmony_ci writel(data, (void __iomem *)(a->regs + (reg) + MW_REG_OFFSET_HWREG)) 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci#define esas2r_flush_register_dword(a, r) esas2r_read_register_dword(a, r) 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci/* This function is provided to access the chip's data window. The 1508c2ecf20Sopenharmony_ci * register is specified by its byte offset from the window base 1518c2ecf20Sopenharmony_ci * for the adapter. 1528c2ecf20Sopenharmony_ci */ 1538c2ecf20Sopenharmony_ci#define esas2r_read_data_byte(a, reg) \ 1548c2ecf20Sopenharmony_ci readb((void __iomem *)a->data_window + (reg)) 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci/* ATTO vendor and device Ids */ 1578c2ecf20Sopenharmony_ci#define ATTO_VENDOR_ID 0x117C 1588c2ecf20Sopenharmony_ci#define ATTO_DID_INTEL_IOP348 0x002C 1598c2ecf20Sopenharmony_ci#define ATTO_DID_MV_88RC9580 0x0049 1608c2ecf20Sopenharmony_ci#define ATTO_DID_MV_88RC9580TS 0x0066 1618c2ecf20Sopenharmony_ci#define ATTO_DID_MV_88RC9580TSE 0x0067 1628c2ecf20Sopenharmony_ci#define ATTO_DID_MV_88RC9580TL 0x0068 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci/* ATTO subsystem device Ids */ 1658c2ecf20Sopenharmony_ci#define ATTO_SSDID_TBT 0x4000 1668c2ecf20Sopenharmony_ci#define ATTO_TSSC_3808 0x4066 1678c2ecf20Sopenharmony_ci#define ATTO_TSSC_3808E 0x4067 1688c2ecf20Sopenharmony_ci#define ATTO_TLSH_1068 0x4068 1698c2ecf20Sopenharmony_ci#define ATTO_ESAS_R680 0x0049 1708c2ecf20Sopenharmony_ci#define ATTO_ESAS_R608 0x004A 1718c2ecf20Sopenharmony_ci#define ATTO_ESAS_R60F 0x004B 1728c2ecf20Sopenharmony_ci#define ATTO_ESAS_R6F0 0x004C 1738c2ecf20Sopenharmony_ci#define ATTO_ESAS_R644 0x004D 1748c2ecf20Sopenharmony_ci#define ATTO_ESAS_R648 0x004E 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci/* 1778c2ecf20Sopenharmony_ci * flash definitions & structures 1788c2ecf20Sopenharmony_ci * define the code types 1798c2ecf20Sopenharmony_ci */ 1808c2ecf20Sopenharmony_ci#define FBT_CPYR 0xAA00 1818c2ecf20Sopenharmony_ci#define FBT_SETUP 0xAA02 1828c2ecf20Sopenharmony_ci#define FBT_FLASH_VER 0xAA04 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci/* offsets to various locations in flash */ 1858c2ecf20Sopenharmony_ci#define FLS_OFFSET_BOOT (u32)(0x00700000) 1868c2ecf20Sopenharmony_ci#define FLS_OFFSET_NVR (u32)(0x007C0000) 1878c2ecf20Sopenharmony_ci#define FLS_OFFSET_CPYR FLS_OFFSET_NVR 1888c2ecf20Sopenharmony_ci#define FLS_LENGTH_BOOT (FLS_OFFSET_CPYR - FLS_OFFSET_BOOT) 1898c2ecf20Sopenharmony_ci#define FLS_BLOCK_SIZE (u32)(0x00020000) 1908c2ecf20Sopenharmony_ci#define FI_NVR_2KB 0x0800 1918c2ecf20Sopenharmony_ci#define FI_NVR_8KB 0x2000 1928c2ecf20Sopenharmony_ci#define FM_BUF_SZ 0x800 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci/* 1958c2ecf20Sopenharmony_ci * marvell frey (88R9580) register definitions 1968c2ecf20Sopenharmony_ci * chip revision identifiers 1978c2ecf20Sopenharmony_ci */ 1988c2ecf20Sopenharmony_ci#define MVR_FREY_B2 0xB2 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci/* 2018c2ecf20Sopenharmony_ci * memory window definitions. window 0 is the data window with definitions 2028c2ecf20Sopenharmony_ci * of MW_DATA_XXX. window 1 is the register window with definitions of 2038c2ecf20Sopenharmony_ci * MW_REG_XXX. 2048c2ecf20Sopenharmony_ci */ 2058c2ecf20Sopenharmony_ci#define MW_REG_WINDOW_SIZE (u32)(0x00040000) 2068c2ecf20Sopenharmony_ci#define MW_REG_OFFSET_HWREG (u32)(0x00000000) 2078c2ecf20Sopenharmony_ci#define MW_REG_OFFSET_PCI (u32)(0x00008000) 2088c2ecf20Sopenharmony_ci#define MW_REG_PCI_HWREG_DELTA (MW_REG_OFFSET_PCI - MW_REG_OFFSET_HWREG) 2098c2ecf20Sopenharmony_ci#define MW_DATA_WINDOW_SIZE (u32)(0x00020000) 2108c2ecf20Sopenharmony_ci#define MW_DATA_ADDR_SER_FLASH (u32)(0xEC000000) 2118c2ecf20Sopenharmony_ci#define MW_DATA_ADDR_SRAM (u32)(0xF4000000) 2128c2ecf20Sopenharmony_ci#define MW_DATA_ADDR_PAR_FLASH (u32)(0xFC000000) 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci/* 2158c2ecf20Sopenharmony_ci * the following registers are for the communication 2168c2ecf20Sopenharmony_ci * list interface (AKA message unit (MU)) 2178c2ecf20Sopenharmony_ci */ 2188c2ecf20Sopenharmony_ci#define MU_IN_LIST_ADDR_LO (u32)(0x00004000) 2198c2ecf20Sopenharmony_ci#define MU_IN_LIST_ADDR_HI (u32)(0x00004004) 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci#define MU_IN_LIST_WRITE (u32)(0x00004018) 2228c2ecf20Sopenharmony_ci #define MU_ILW_TOGGLE (u32)(0x00004000) 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci#define MU_IN_LIST_READ (u32)(0x0000401C) 2258c2ecf20Sopenharmony_ci #define MU_ILR_TOGGLE (u32)(0x00004000) 2268c2ecf20Sopenharmony_ci #define MU_ILIC_LIST (u32)(0x0000000F) 2278c2ecf20Sopenharmony_ci #define MU_ILIC_LIST_F0 (u32)(0x00000000) 2288c2ecf20Sopenharmony_ci #define MU_ILIC_DEST (u32)(0x00000F00) 2298c2ecf20Sopenharmony_ci #define MU_ILIC_DEST_DDR (u32)(0x00000200) 2308c2ecf20Sopenharmony_ci#define MU_IN_LIST_IFC_CONFIG (u32)(0x00004028) 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci#define MU_IN_LIST_CONFIG (u32)(0x0000402C) 2338c2ecf20Sopenharmony_ci #define MU_ILC_ENABLE (u32)(0x00000001) 2348c2ecf20Sopenharmony_ci #define MU_ILC_ENTRY_MASK (u32)(0x000000F0) 2358c2ecf20Sopenharmony_ci #define MU_ILC_ENTRY_4_DW (u32)(0x00000020) 2368c2ecf20Sopenharmony_ci #define MU_ILC_DYNAMIC_SRC (u32)(0x00008000) 2378c2ecf20Sopenharmony_ci #define MU_ILC_NUMBER_MASK (u32)(0x7FFF0000) 2388c2ecf20Sopenharmony_ci #define MU_ILC_NUMBER_SHIFT 16 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci#define MU_OUT_LIST_ADDR_LO (u32)(0x00004050) 2418c2ecf20Sopenharmony_ci#define MU_OUT_LIST_ADDR_HI (u32)(0x00004054) 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci#define MU_OUT_LIST_COPY_PTR_LO (u32)(0x00004058) 2448c2ecf20Sopenharmony_ci#define MU_OUT_LIST_COPY_PTR_HI (u32)(0x0000405C) 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci#define MU_OUT_LIST_WRITE (u32)(0x00004068) 2478c2ecf20Sopenharmony_ci #define MU_OLW_TOGGLE (u32)(0x00004000) 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci#define MU_OUT_LIST_COPY (u32)(0x0000406C) 2508c2ecf20Sopenharmony_ci #define MU_OLC_TOGGLE (u32)(0x00004000) 2518c2ecf20Sopenharmony_ci #define MU_OLC_WRT_PTR (u32)(0x00003FFF) 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci#define MU_OUT_LIST_IFC_CONFIG (u32)(0x00004078) 2548c2ecf20Sopenharmony_ci #define MU_OLIC_LIST (u32)(0x0000000F) 2558c2ecf20Sopenharmony_ci #define MU_OLIC_LIST_F0 (u32)(0x00000000) 2568c2ecf20Sopenharmony_ci #define MU_OLIC_SOURCE (u32)(0x00000F00) 2578c2ecf20Sopenharmony_ci #define MU_OLIC_SOURCE_DDR (u32)(0x00000200) 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci#define MU_OUT_LIST_CONFIG (u32)(0x0000407C) 2608c2ecf20Sopenharmony_ci #define MU_OLC_ENABLE (u32)(0x00000001) 2618c2ecf20Sopenharmony_ci #define MU_OLC_ENTRY_MASK (u32)(0x000000F0) 2628c2ecf20Sopenharmony_ci #define MU_OLC_ENTRY_4_DW (u32)(0x00000020) 2638c2ecf20Sopenharmony_ci #define MU_OLC_NUMBER_MASK (u32)(0x7FFF0000) 2648c2ecf20Sopenharmony_ci #define MU_OLC_NUMBER_SHIFT 16 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci#define MU_OUT_LIST_INT_STAT (u32)(0x00004088) 2678c2ecf20Sopenharmony_ci #define MU_OLIS_INT (u32)(0x00000001) 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci#define MU_OUT_LIST_INT_MASK (u32)(0x0000408C) 2708c2ecf20Sopenharmony_ci #define MU_OLIS_MASK (u32)(0x00000001) 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci/* 2738c2ecf20Sopenharmony_ci * the maximum size of the communication lists is two greater than the 2748c2ecf20Sopenharmony_ci * maximum amount of VDA requests. the extra are to prevent queue overflow. 2758c2ecf20Sopenharmony_ci */ 2768c2ecf20Sopenharmony_ci#define ESAS2R_MAX_NUM_REQS 256 2778c2ecf20Sopenharmony_ci#define ESAS2R_NUM_EXTRA 2 2788c2ecf20Sopenharmony_ci#define ESAS2R_MAX_COMM_LIST_SIZE (ESAS2R_MAX_NUM_REQS + ESAS2R_NUM_EXTRA) 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci/* 2818c2ecf20Sopenharmony_ci * the following registers are for the CPU interface 2828c2ecf20Sopenharmony_ci */ 2838c2ecf20Sopenharmony_ci#define MU_CTL_STATUS_IN (u32)(0x00010108) 2848c2ecf20Sopenharmony_ci #define MU_CTL_IN_FULL_RST (u32)(0x00000020) 2858c2ecf20Sopenharmony_ci#define MU_CTL_STATUS_IN_B2 (u32)(0x00010130) 2868c2ecf20Sopenharmony_ci #define MU_CTL_IN_FULL_RST2 (u32)(0x80000000) 2878c2ecf20Sopenharmony_ci#define MU_DOORBELL_IN (u32)(0x00010460) 2888c2ecf20Sopenharmony_ci #define DRBL_RESET_BUS (u32)(0x00000002) 2898c2ecf20Sopenharmony_ci #define DRBL_PAUSE_AE (u32)(0x00000004) 2908c2ecf20Sopenharmony_ci #define DRBL_RESUME_AE (u32)(0x00000008) 2918c2ecf20Sopenharmony_ci #define DRBL_MSG_IFC_DOWN (u32)(0x00000010) 2928c2ecf20Sopenharmony_ci #define DRBL_FLASH_REQ (u32)(0x00000020) 2938c2ecf20Sopenharmony_ci #define DRBL_FLASH_DONE (u32)(0x00000040) 2948c2ecf20Sopenharmony_ci #define DRBL_FORCE_INT (u32)(0x00000080) 2958c2ecf20Sopenharmony_ci #define DRBL_MSG_IFC_INIT (u32)(0x00000100) 2968c2ecf20Sopenharmony_ci #define DRBL_POWER_DOWN (u32)(0x00000200) 2978c2ecf20Sopenharmony_ci #define DRBL_DRV_VER_1 (u32)(0x00010000) 2988c2ecf20Sopenharmony_ci #define DRBL_DRV_VER DRBL_DRV_VER_1 2998c2ecf20Sopenharmony_ci#define MU_DOORBELL_IN_ENB (u32)(0x00010464) 3008c2ecf20Sopenharmony_ci#define MU_DOORBELL_OUT (u32)(0x00010480) 3018c2ecf20Sopenharmony_ci #define DRBL_PANIC_REASON_MASK (u32)(0x00F00000) 3028c2ecf20Sopenharmony_ci #define DRBL_UNUSED_HANDLER (u32)(0x00100000) 3038c2ecf20Sopenharmony_ci #define DRBL_UNDEF_INSTR (u32)(0x00200000) 3048c2ecf20Sopenharmony_ci #define DRBL_PREFETCH_ABORT (u32)(0x00300000) 3058c2ecf20Sopenharmony_ci #define DRBL_DATA_ABORT (u32)(0x00400000) 3068c2ecf20Sopenharmony_ci #define DRBL_JUMP_TO_ZERO (u32)(0x00500000) 3078c2ecf20Sopenharmony_ci #define DRBL_FW_RESET (u32)(0x00080000) 3088c2ecf20Sopenharmony_ci #define DRBL_FW_VER_MSK (u32)(0x00070000) 3098c2ecf20Sopenharmony_ci #define DRBL_FW_VER_0 (u32)(0x00000000) 3108c2ecf20Sopenharmony_ci #define DRBL_FW_VER_1 (u32)(0x00010000) 3118c2ecf20Sopenharmony_ci #define DRBL_FW_VER DRBL_FW_VER_1 3128c2ecf20Sopenharmony_ci#define MU_DOORBELL_OUT_ENB (u32)(0x00010484) 3138c2ecf20Sopenharmony_ci #define DRBL_ENB_MASK (u32)(0x00F803FF) 3148c2ecf20Sopenharmony_ci#define MU_INT_STATUS_OUT (u32)(0x00010200) 3158c2ecf20Sopenharmony_ci #define MU_INTSTAT_POST_OUT (u32)(0x00000010) 3168c2ecf20Sopenharmony_ci #define MU_INTSTAT_DRBL_IN (u32)(0x00000100) 3178c2ecf20Sopenharmony_ci #define MU_INTSTAT_DRBL (u32)(0x00001000) 3188c2ecf20Sopenharmony_ci #define MU_INTSTAT_MASK (u32)(0x00001010) 3198c2ecf20Sopenharmony_ci#define MU_INT_MASK_OUT (u32)(0x0001020C) 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* PCI express registers accessed via window 1 */ 3228c2ecf20Sopenharmony_ci#define MVR_PCI_WIN1_REMAP (u32)(0x00008438) 3238c2ecf20Sopenharmony_ci #define MVRPW1R_ENABLE (u32)(0x00000001) 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci/* structures */ 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci/* inbound list dynamic source entry */ 3298c2ecf20Sopenharmony_cistruct esas2r_inbound_list_source_entry { 3308c2ecf20Sopenharmony_ci u64 address; 3318c2ecf20Sopenharmony_ci u32 length; 3328c2ecf20Sopenharmony_ci #define HWILSE_INTERFACE_F0 0x00000000 3338c2ecf20Sopenharmony_ci u32 reserved; 3348c2ecf20Sopenharmony_ci}; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci/* PCI data structure in expansion ROM images */ 3378c2ecf20Sopenharmony_cistruct __packed esas2r_boot_header { 3388c2ecf20Sopenharmony_ci char signature[4]; 3398c2ecf20Sopenharmony_ci u16 vendor_id; 3408c2ecf20Sopenharmony_ci u16 device_id; 3418c2ecf20Sopenharmony_ci u16 VPD; 3428c2ecf20Sopenharmony_ci u16 struct_length; 3438c2ecf20Sopenharmony_ci u8 struct_revision; 3448c2ecf20Sopenharmony_ci u8 class_code[3]; 3458c2ecf20Sopenharmony_ci u16 image_length; 3468c2ecf20Sopenharmony_ci u16 code_revision; 3478c2ecf20Sopenharmony_ci u8 code_type; 3488c2ecf20Sopenharmony_ci #define CODE_TYPE_PC 0 3498c2ecf20Sopenharmony_ci #define CODE_TYPE_OPEN 1 3508c2ecf20Sopenharmony_ci #define CODE_TYPE_EFI 3 3518c2ecf20Sopenharmony_ci u8 indicator; 3528c2ecf20Sopenharmony_ci #define INDICATOR_LAST 0x80 3538c2ecf20Sopenharmony_ci u8 reserved[2]; 3548c2ecf20Sopenharmony_ci}; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_cistruct __packed esas2r_boot_image { 3578c2ecf20Sopenharmony_ci u16 signature; 3588c2ecf20Sopenharmony_ci u8 reserved[22]; 3598c2ecf20Sopenharmony_ci u16 header_offset; 3608c2ecf20Sopenharmony_ci u16 pnp_offset; 3618c2ecf20Sopenharmony_ci}; 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_cistruct __packed esas2r_pc_image { 3648c2ecf20Sopenharmony_ci u16 signature; 3658c2ecf20Sopenharmony_ci u8 length; 3668c2ecf20Sopenharmony_ci u8 entry_point[3]; 3678c2ecf20Sopenharmony_ci u8 checksum; 3688c2ecf20Sopenharmony_ci u16 image_end; 3698c2ecf20Sopenharmony_ci u16 min_size; 3708c2ecf20Sopenharmony_ci u8 rom_flags; 3718c2ecf20Sopenharmony_ci u8 reserved[12]; 3728c2ecf20Sopenharmony_ci u16 header_offset; 3738c2ecf20Sopenharmony_ci u16 pnp_offset; 3748c2ecf20Sopenharmony_ci struct esas2r_boot_header boot_image; 3758c2ecf20Sopenharmony_ci}; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_cistruct __packed esas2r_efi_image { 3788c2ecf20Sopenharmony_ci u16 signature; 3798c2ecf20Sopenharmony_ci u16 length; 3808c2ecf20Sopenharmony_ci u32 efi_signature; 3818c2ecf20Sopenharmony_ci #define EFI_ROM_SIG 0x00000EF1 3828c2ecf20Sopenharmony_ci u16 image_type; 3838c2ecf20Sopenharmony_ci #define EFI_IMAGE_APP 10 3848c2ecf20Sopenharmony_ci #define EFI_IMAGE_BSD 11 3858c2ecf20Sopenharmony_ci #define EFI_IMAGE_RTD 12 3868c2ecf20Sopenharmony_ci u16 machine_type; 3878c2ecf20Sopenharmony_ci #define EFI_MACHINE_IA32 0x014c 3888c2ecf20Sopenharmony_ci #define EFI_MACHINE_IA64 0x0200 3898c2ecf20Sopenharmony_ci #define EFI_MACHINE_X64 0x8664 3908c2ecf20Sopenharmony_ci #define EFI_MACHINE_EBC 0x0EBC 3918c2ecf20Sopenharmony_ci u16 compression; 3928c2ecf20Sopenharmony_ci #define EFI_UNCOMPRESSED 0x0000 3938c2ecf20Sopenharmony_ci #define EFI_COMPRESSED 0x0001 3948c2ecf20Sopenharmony_ci u8 reserved[8]; 3958c2ecf20Sopenharmony_ci u16 efi_offset; 3968c2ecf20Sopenharmony_ci u16 header_offset; 3978c2ecf20Sopenharmony_ci u16 reserved2; 3988c2ecf20Sopenharmony_ci struct esas2r_boot_header boot_image; 3998c2ecf20Sopenharmony_ci}; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_cistruct esas2r_adapter; 4028c2ecf20Sopenharmony_cistruct esas2r_sg_context; 4038c2ecf20Sopenharmony_cistruct esas2r_request; 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_citypedef void (*RQCALLBK) (struct esas2r_adapter *a, 4068c2ecf20Sopenharmony_ci struct esas2r_request *rq); 4078c2ecf20Sopenharmony_citypedef bool (*RQBUILDSGL) (struct esas2r_adapter *a, 4088c2ecf20Sopenharmony_ci struct esas2r_sg_context *sgc); 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_cistruct esas2r_component_header { 4118c2ecf20Sopenharmony_ci u8 img_type; 4128c2ecf20Sopenharmony_ci #define CH_IT_FW 0x00 4138c2ecf20Sopenharmony_ci #define CH_IT_NVR 0x01 4148c2ecf20Sopenharmony_ci #define CH_IT_BIOS 0x02 4158c2ecf20Sopenharmony_ci #define CH_IT_MAC 0x03 4168c2ecf20Sopenharmony_ci #define CH_IT_CFG 0x04 4178c2ecf20Sopenharmony_ci #define CH_IT_EFI 0x05 4188c2ecf20Sopenharmony_ci u8 status; 4198c2ecf20Sopenharmony_ci #define CH_STAT_PENDING 0xff 4208c2ecf20Sopenharmony_ci #define CH_STAT_FAILED 0x00 4218c2ecf20Sopenharmony_ci #define CH_STAT_SUCCESS 0x01 4228c2ecf20Sopenharmony_ci #define CH_STAT_RETRY 0x02 4238c2ecf20Sopenharmony_ci #define CH_STAT_INVALID 0x03 4248c2ecf20Sopenharmony_ci u8 pad[2]; 4258c2ecf20Sopenharmony_ci u32 version; 4268c2ecf20Sopenharmony_ci u32 length; 4278c2ecf20Sopenharmony_ci u32 image_offset; 4288c2ecf20Sopenharmony_ci}; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci#define FI_REL_VER_SZ 16 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_cistruct esas2r_flash_img_v0 { 4338c2ecf20Sopenharmony_ci u8 fi_version; 4348c2ecf20Sopenharmony_ci #define FI_VERSION_0 00 4358c2ecf20Sopenharmony_ci u8 status; 4368c2ecf20Sopenharmony_ci u8 adap_typ; 4378c2ecf20Sopenharmony_ci u8 action; 4388c2ecf20Sopenharmony_ci u32 length; 4398c2ecf20Sopenharmony_ci u16 checksum; 4408c2ecf20Sopenharmony_ci u16 driver_error; 4418c2ecf20Sopenharmony_ci u16 flags; 4428c2ecf20Sopenharmony_ci u16 num_comps; 4438c2ecf20Sopenharmony_ci #define FI_NUM_COMPS_V0 5 4448c2ecf20Sopenharmony_ci u8 rel_version[FI_REL_VER_SZ]; 4458c2ecf20Sopenharmony_ci struct esas2r_component_header cmp_hdr[FI_NUM_COMPS_V0]; 4468c2ecf20Sopenharmony_ci u8 scratch_buf[FM_BUF_SZ]; 4478c2ecf20Sopenharmony_ci}; 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_cistruct esas2r_flash_img { 4508c2ecf20Sopenharmony_ci u8 fi_version; 4518c2ecf20Sopenharmony_ci #define FI_VERSION_1 01 4528c2ecf20Sopenharmony_ci u8 status; 4538c2ecf20Sopenharmony_ci #define FI_STAT_SUCCESS 0x00 4548c2ecf20Sopenharmony_ci #define FI_STAT_FAILED 0x01 4558c2ecf20Sopenharmony_ci #define FI_STAT_REBOOT 0x02 4568c2ecf20Sopenharmony_ci #define FI_STAT_ADAPTYP 0x03 4578c2ecf20Sopenharmony_ci #define FI_STAT_INVALID 0x04 4588c2ecf20Sopenharmony_ci #define FI_STAT_CHKSUM 0x05 4598c2ecf20Sopenharmony_ci #define FI_STAT_LENGTH 0x06 4608c2ecf20Sopenharmony_ci #define FI_STAT_UNKNOWN 0x07 4618c2ecf20Sopenharmony_ci #define FI_STAT_IMG_VER 0x08 4628c2ecf20Sopenharmony_ci #define FI_STAT_BUSY 0x09 4638c2ecf20Sopenharmony_ci #define FI_STAT_DUAL 0x0A 4648c2ecf20Sopenharmony_ci #define FI_STAT_MISSING 0x0B 4658c2ecf20Sopenharmony_ci #define FI_STAT_UNSUPP 0x0C 4668c2ecf20Sopenharmony_ci #define FI_STAT_ERASE 0x0D 4678c2ecf20Sopenharmony_ci #define FI_STAT_FLASH 0x0E 4688c2ecf20Sopenharmony_ci #define FI_STAT_DEGRADED 0x0F 4698c2ecf20Sopenharmony_ci u8 adap_typ; 4708c2ecf20Sopenharmony_ci #define FI_AT_UNKNWN 0xFF 4718c2ecf20Sopenharmony_ci #define FI_AT_SUN_LAKE 0x0B 4728c2ecf20Sopenharmony_ci #define FI_AT_MV_9580 0x0F 4738c2ecf20Sopenharmony_ci u8 action; 4748c2ecf20Sopenharmony_ci #define FI_ACT_DOWN 0x00 4758c2ecf20Sopenharmony_ci #define FI_ACT_UP 0x01 4768c2ecf20Sopenharmony_ci #define FI_ACT_UPSZ 0x02 4778c2ecf20Sopenharmony_ci #define FI_ACT_MAX 0x02 4788c2ecf20Sopenharmony_ci #define FI_ACT_DOWN1 0x80 4798c2ecf20Sopenharmony_ci u32 length; 4808c2ecf20Sopenharmony_ci u16 checksum; 4818c2ecf20Sopenharmony_ci u16 driver_error; 4828c2ecf20Sopenharmony_ci u16 flags; 4838c2ecf20Sopenharmony_ci #define FI_FLG_NVR_DEF 0x0001 4848c2ecf20Sopenharmony_ci u16 num_comps; 4858c2ecf20Sopenharmony_ci #define FI_NUM_COMPS_V1 6 4868c2ecf20Sopenharmony_ci u8 rel_version[FI_REL_VER_SZ]; 4878c2ecf20Sopenharmony_ci struct esas2r_component_header cmp_hdr[FI_NUM_COMPS_V1]; 4888c2ecf20Sopenharmony_ci u8 scratch_buf[FM_BUF_SZ]; 4898c2ecf20Sopenharmony_ci}; 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci/* definitions for flash script (FS) commands */ 4928c2ecf20Sopenharmony_cistruct esas2r_ioctlfs_command { 4938c2ecf20Sopenharmony_ci u8 command; 4948c2ecf20Sopenharmony_ci #define ESAS2R_FS_CMD_ERASE 0 4958c2ecf20Sopenharmony_ci #define ESAS2R_FS_CMD_READ 1 4968c2ecf20Sopenharmony_ci #define ESAS2R_FS_CMD_BEGINW 2 4978c2ecf20Sopenharmony_ci #define ESAS2R_FS_CMD_WRITE 3 4988c2ecf20Sopenharmony_ci #define ESAS2R_FS_CMD_COMMIT 4 4998c2ecf20Sopenharmony_ci #define ESAS2R_FS_CMD_CANCEL 5 5008c2ecf20Sopenharmony_ci u8 checksum; 5018c2ecf20Sopenharmony_ci u8 reserved[2]; 5028c2ecf20Sopenharmony_ci u32 flash_addr; 5038c2ecf20Sopenharmony_ci u32 length; 5048c2ecf20Sopenharmony_ci u32 image_offset; 5058c2ecf20Sopenharmony_ci}; 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_cistruct esas2r_ioctl_fs { 5088c2ecf20Sopenharmony_ci u8 version; 5098c2ecf20Sopenharmony_ci #define ESAS2R_FS_VER 0 5108c2ecf20Sopenharmony_ci u8 status; 5118c2ecf20Sopenharmony_ci u8 driver_error; 5128c2ecf20Sopenharmony_ci u8 adap_type; 5138c2ecf20Sopenharmony_ci #define ESAS2R_FS_AT_ESASRAID2 3 5148c2ecf20Sopenharmony_ci #define ESAS2R_FS_AT_TSSASRAID2 4 5158c2ecf20Sopenharmony_ci #define ESAS2R_FS_AT_TSSASRAID2E 5 5168c2ecf20Sopenharmony_ci #define ESAS2R_FS_AT_TLSASHBA 6 5178c2ecf20Sopenharmony_ci u8 driver_ver; 5188c2ecf20Sopenharmony_ci u8 reserved[11]; 5198c2ecf20Sopenharmony_ci struct esas2r_ioctlfs_command command; 5208c2ecf20Sopenharmony_ci u8 data[1]; 5218c2ecf20Sopenharmony_ci}; 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_cistruct esas2r_sas_nvram { 5248c2ecf20Sopenharmony_ci u8 signature[4]; 5258c2ecf20Sopenharmony_ci u8 version; 5268c2ecf20Sopenharmony_ci #define SASNVR_VERSION_0 0x00 5278c2ecf20Sopenharmony_ci #define SASNVR_VERSION SASNVR_VERSION_0 5288c2ecf20Sopenharmony_ci u8 checksum; 5298c2ecf20Sopenharmony_ci #define SASNVR_CKSUM_SEED 0x5A 5308c2ecf20Sopenharmony_ci u8 max_lun_for_target; 5318c2ecf20Sopenharmony_ci u8 pci_latency; 5328c2ecf20Sopenharmony_ci #define SASNVR_PCILAT_DIS 0x00 5338c2ecf20Sopenharmony_ci #define SASNVR_PCILAT_MIN 0x10 5348c2ecf20Sopenharmony_ci #define SASNVR_PCILAT_MAX 0xF8 5358c2ecf20Sopenharmony_ci u8 options1; 5368c2ecf20Sopenharmony_ci #define SASNVR1_BOOT_DRVR 0x01 5378c2ecf20Sopenharmony_ci #define SASNVR1_BOOT_SCAN 0x02 5388c2ecf20Sopenharmony_ci #define SASNVR1_DIS_PCI_MWI 0x04 5398c2ecf20Sopenharmony_ci #define SASNVR1_FORCE_ORD_Q 0x08 5408c2ecf20Sopenharmony_ci #define SASNVR1_CACHELINE_0 0x10 5418c2ecf20Sopenharmony_ci #define SASNVR1_DIS_DEVSORT 0x20 5428c2ecf20Sopenharmony_ci #define SASNVR1_PWR_MGT_EN 0x40 5438c2ecf20Sopenharmony_ci #define SASNVR1_WIDEPORT 0x80 5448c2ecf20Sopenharmony_ci u8 options2; 5458c2ecf20Sopenharmony_ci #define SASNVR2_SINGLE_BUS 0x01 5468c2ecf20Sopenharmony_ci #define SASNVR2_SLOT_BIND 0x02 5478c2ecf20Sopenharmony_ci #define SASNVR2_EXP_PROG 0x04 5488c2ecf20Sopenharmony_ci #define SASNVR2_CMDTHR_LUN 0x08 5498c2ecf20Sopenharmony_ci #define SASNVR2_HEARTBEAT 0x10 5508c2ecf20Sopenharmony_ci #define SASNVR2_INT_CONNECT 0x20 5518c2ecf20Sopenharmony_ci #define SASNVR2_SW_MUX_CTRL 0x40 5528c2ecf20Sopenharmony_ci #define SASNVR2_DISABLE_NCQ 0x80 5538c2ecf20Sopenharmony_ci u8 int_coalescing; 5548c2ecf20Sopenharmony_ci #define SASNVR_COAL_DIS 0x00 5558c2ecf20Sopenharmony_ci #define SASNVR_COAL_LOW 0x01 5568c2ecf20Sopenharmony_ci #define SASNVR_COAL_MED 0x02 5578c2ecf20Sopenharmony_ci #define SASNVR_COAL_HI 0x03 5588c2ecf20Sopenharmony_ci u8 cmd_throttle; 5598c2ecf20Sopenharmony_ci #define SASNVR_CMDTHR_NONE 0x00 5608c2ecf20Sopenharmony_ci u8 dev_wait_time; 5618c2ecf20Sopenharmony_ci u8 dev_wait_count; 5628c2ecf20Sopenharmony_ci u8 spin_up_delay; 5638c2ecf20Sopenharmony_ci #define SASNVR_SPINUP_MAX 0x14 5648c2ecf20Sopenharmony_ci u8 ssp_align_rate; 5658c2ecf20Sopenharmony_ci u8 sas_addr[8]; 5668c2ecf20Sopenharmony_ci u8 phy_speed[16]; 5678c2ecf20Sopenharmony_ci #define SASNVR_SPEED_AUTO 0x00 5688c2ecf20Sopenharmony_ci #define SASNVR_SPEED_1_5GB 0x01 5698c2ecf20Sopenharmony_ci #define SASNVR_SPEED_3GB 0x02 5708c2ecf20Sopenharmony_ci #define SASNVR_SPEED_6GB 0x03 5718c2ecf20Sopenharmony_ci #define SASNVR_SPEED_12GB 0x04 5728c2ecf20Sopenharmony_ci u8 phy_mux[16]; 5738c2ecf20Sopenharmony_ci #define SASNVR_MUX_DISABLED 0x00 5748c2ecf20Sopenharmony_ci #define SASNVR_MUX_1_5GB 0x01 5758c2ecf20Sopenharmony_ci #define SASNVR_MUX_3GB 0x02 5768c2ecf20Sopenharmony_ci #define SASNVR_MUX_6GB 0x03 5778c2ecf20Sopenharmony_ci u8 phy_flags[16]; 5788c2ecf20Sopenharmony_ci #define SASNVR_PHF_DISABLED 0x01 5798c2ecf20Sopenharmony_ci #define SASNVR_PHF_RD_ONLY 0x02 5808c2ecf20Sopenharmony_ci u8 sort_type; 5818c2ecf20Sopenharmony_ci #define SASNVR_SORT_SAS_ADDR 0x00 5828c2ecf20Sopenharmony_ci #define SASNVR_SORT_H308_CONN 0x01 5838c2ecf20Sopenharmony_ci #define SASNVR_SORT_PHY_ID 0x02 5848c2ecf20Sopenharmony_ci #define SASNVR_SORT_SLOT_ID 0x03 5858c2ecf20Sopenharmony_ci u8 dpm_reqcmd_lmt; 5868c2ecf20Sopenharmony_ci u8 dpm_stndby_time; 5878c2ecf20Sopenharmony_ci u8 dpm_active_time; 5888c2ecf20Sopenharmony_ci u8 phy_target_id[16]; 5898c2ecf20Sopenharmony_ci #define SASNVR_PTI_DISABLED 0xFF 5908c2ecf20Sopenharmony_ci u8 virt_ses_mode; 5918c2ecf20Sopenharmony_ci #define SASNVR_VSMH_DISABLED 0x00 5928c2ecf20Sopenharmony_ci u8 read_write_mode; 5938c2ecf20Sopenharmony_ci #define SASNVR_RWM_DEFAULT 0x00 5948c2ecf20Sopenharmony_ci u8 link_down_to; 5958c2ecf20Sopenharmony_ci u8 reserved[0xA1]; 5968c2ecf20Sopenharmony_ci}; 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_citypedef u32 (*PGETPHYSADDR) (struct esas2r_sg_context *sgc, u64 *addr); 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_cistruct esas2r_sg_context { 6018c2ecf20Sopenharmony_ci struct esas2r_adapter *adapter; 6028c2ecf20Sopenharmony_ci struct esas2r_request *first_req; 6038c2ecf20Sopenharmony_ci u32 length; 6048c2ecf20Sopenharmony_ci u8 *cur_offset; 6058c2ecf20Sopenharmony_ci PGETPHYSADDR get_phys_addr; 6068c2ecf20Sopenharmony_ci union { 6078c2ecf20Sopenharmony_ci struct { 6088c2ecf20Sopenharmony_ci struct atto_vda_sge *curr; 6098c2ecf20Sopenharmony_ci struct atto_vda_sge *last; 6108c2ecf20Sopenharmony_ci struct atto_vda_sge *limit; 6118c2ecf20Sopenharmony_ci struct atto_vda_sge *chain; 6128c2ecf20Sopenharmony_ci } a64; 6138c2ecf20Sopenharmony_ci struct { 6148c2ecf20Sopenharmony_ci struct atto_physical_region_description *curr; 6158c2ecf20Sopenharmony_ci struct atto_physical_region_description *chain; 6168c2ecf20Sopenharmony_ci u32 sgl_max_cnt; 6178c2ecf20Sopenharmony_ci u32 sge_cnt; 6188c2ecf20Sopenharmony_ci } prd; 6198c2ecf20Sopenharmony_ci } sge; 6208c2ecf20Sopenharmony_ci struct scatterlist *cur_sgel; 6218c2ecf20Sopenharmony_ci u8 *exp_offset; 6228c2ecf20Sopenharmony_ci int num_sgel; 6238c2ecf20Sopenharmony_ci int sgel_count; 6248c2ecf20Sopenharmony_ci}; 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_cistruct esas2r_target { 6278c2ecf20Sopenharmony_ci u8 flags; 6288c2ecf20Sopenharmony_ci #define TF_PASS_THRU 0x01 6298c2ecf20Sopenharmony_ci #define TF_USED 0x02 6308c2ecf20Sopenharmony_ci u8 new_target_state; 6318c2ecf20Sopenharmony_ci u8 target_state; 6328c2ecf20Sopenharmony_ci u8 buffered_target_state; 6338c2ecf20Sopenharmony_ci#define TS_NOT_PRESENT 0x00 6348c2ecf20Sopenharmony_ci#define TS_PRESENT 0x05 6358c2ecf20Sopenharmony_ci#define TS_LUN_CHANGE 0x06 6368c2ecf20Sopenharmony_ci#define TS_INVALID 0xFF 6378c2ecf20Sopenharmony_ci u32 block_size; 6388c2ecf20Sopenharmony_ci u32 inter_block; 6398c2ecf20Sopenharmony_ci u32 inter_byte; 6408c2ecf20Sopenharmony_ci u16 virt_targ_id; 6418c2ecf20Sopenharmony_ci u16 phys_targ_id; 6428c2ecf20Sopenharmony_ci u8 identifier_len; 6438c2ecf20Sopenharmony_ci u64 sas_addr; 6448c2ecf20Sopenharmony_ci u8 identifier[60]; 6458c2ecf20Sopenharmony_ci struct atto_vda_ae_lu lu_event; 6468c2ecf20Sopenharmony_ci}; 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_cistruct esas2r_request { 6498c2ecf20Sopenharmony_ci struct list_head comp_list; 6508c2ecf20Sopenharmony_ci struct list_head req_list; 6518c2ecf20Sopenharmony_ci union atto_vda_req *vrq; 6528c2ecf20Sopenharmony_ci struct esas2r_mem_desc *vrq_md; 6538c2ecf20Sopenharmony_ci union { 6548c2ecf20Sopenharmony_ci void *data_buf; 6558c2ecf20Sopenharmony_ci union atto_vda_rsp_data *vda_rsp_data; 6568c2ecf20Sopenharmony_ci }; 6578c2ecf20Sopenharmony_ci u8 *sense_buf; 6588c2ecf20Sopenharmony_ci struct list_head sg_table_head; 6598c2ecf20Sopenharmony_ci struct esas2r_mem_desc *sg_table; 6608c2ecf20Sopenharmony_ci u32 timeout; 6618c2ecf20Sopenharmony_ci #define RQ_TIMEOUT_S1 0xFFFFFFFF 6628c2ecf20Sopenharmony_ci #define RQ_TIMEOUT_S2 0xFFFFFFFE 6638c2ecf20Sopenharmony_ci #define RQ_MAX_TIMEOUT 0xFFFFFFFD 6648c2ecf20Sopenharmony_ci u16 target_id; 6658c2ecf20Sopenharmony_ci u8 req_type; 6668c2ecf20Sopenharmony_ci #define RT_INI_REQ 0x01 6678c2ecf20Sopenharmony_ci #define RT_DISC_REQ 0x02 6688c2ecf20Sopenharmony_ci u8 sense_len; 6698c2ecf20Sopenharmony_ci union atto_vda_func_rsp func_rsp; 6708c2ecf20Sopenharmony_ci RQCALLBK comp_cb; 6718c2ecf20Sopenharmony_ci RQCALLBK interrupt_cb; 6728c2ecf20Sopenharmony_ci void *interrupt_cx; 6738c2ecf20Sopenharmony_ci u8 flags; 6748c2ecf20Sopenharmony_ci #define RF_1ST_IBLK_BASE 0x04 6758c2ecf20Sopenharmony_ci #define RF_FAILURE_OK 0x08 6768c2ecf20Sopenharmony_ci u8 req_stat; 6778c2ecf20Sopenharmony_ci u16 vda_req_sz; 6788c2ecf20Sopenharmony_ci #define RQ_SIZE_DEFAULT 0 6798c2ecf20Sopenharmony_ci u64 lba; 6808c2ecf20Sopenharmony_ci RQCALLBK aux_req_cb; 6818c2ecf20Sopenharmony_ci void *aux_req_cx; 6828c2ecf20Sopenharmony_ci u32 blk_len; 6838c2ecf20Sopenharmony_ci u32 max_blk_len; 6848c2ecf20Sopenharmony_ci union { 6858c2ecf20Sopenharmony_ci struct scsi_cmnd *cmd; 6868c2ecf20Sopenharmony_ci u8 *task_management_status_ptr; 6878c2ecf20Sopenharmony_ci }; 6888c2ecf20Sopenharmony_ci}; 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_cistruct esas2r_flash_context { 6918c2ecf20Sopenharmony_ci struct esas2r_flash_img *fi; 6928c2ecf20Sopenharmony_ci RQCALLBK interrupt_cb; 6938c2ecf20Sopenharmony_ci u8 *sgc_offset; 6948c2ecf20Sopenharmony_ci u8 *scratch; 6958c2ecf20Sopenharmony_ci u32 fi_hdr_len; 6968c2ecf20Sopenharmony_ci u8 task; 6978c2ecf20Sopenharmony_ci #define FMTSK_ERASE_BOOT 0 6988c2ecf20Sopenharmony_ci #define FMTSK_WRTBIOS 1 6998c2ecf20Sopenharmony_ci #define FMTSK_READBIOS 2 7008c2ecf20Sopenharmony_ci #define FMTSK_WRTMAC 3 7018c2ecf20Sopenharmony_ci #define FMTSK_READMAC 4 7028c2ecf20Sopenharmony_ci #define FMTSK_WRTEFI 5 7038c2ecf20Sopenharmony_ci #define FMTSK_READEFI 6 7048c2ecf20Sopenharmony_ci #define FMTSK_WRTCFG 7 7058c2ecf20Sopenharmony_ci #define FMTSK_READCFG 8 7068c2ecf20Sopenharmony_ci u8 func; 7078c2ecf20Sopenharmony_ci u16 num_comps; 7088c2ecf20Sopenharmony_ci u32 cmp_len; 7098c2ecf20Sopenharmony_ci u32 flsh_addr; 7108c2ecf20Sopenharmony_ci u32 curr_len; 7118c2ecf20Sopenharmony_ci u8 comp_typ; 7128c2ecf20Sopenharmony_ci struct esas2r_sg_context sgc; 7138c2ecf20Sopenharmony_ci}; 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_cistruct esas2r_disc_context { 7168c2ecf20Sopenharmony_ci u8 disc_evt; 7178c2ecf20Sopenharmony_ci #define DCDE_DEV_CHANGE 0x01 7188c2ecf20Sopenharmony_ci #define DCDE_DEV_SCAN 0x02 7198c2ecf20Sopenharmony_ci u8 state; 7208c2ecf20Sopenharmony_ci #define DCS_DEV_RMV 0x00 7218c2ecf20Sopenharmony_ci #define DCS_DEV_ADD 0x01 7228c2ecf20Sopenharmony_ci #define DCS_BLOCK_DEV_SCAN 0x02 7238c2ecf20Sopenharmony_ci #define DCS_RAID_GRP_INFO 0x03 7248c2ecf20Sopenharmony_ci #define DCS_PART_INFO 0x04 7258c2ecf20Sopenharmony_ci #define DCS_PT_DEV_INFO 0x05 7268c2ecf20Sopenharmony_ci #define DCS_PT_DEV_ADDR 0x06 7278c2ecf20Sopenharmony_ci #define DCS_DISC_DONE 0xFF 7288c2ecf20Sopenharmony_ci u16 flags; 7298c2ecf20Sopenharmony_ci #define DCF_DEV_CHANGE 0x0001 7308c2ecf20Sopenharmony_ci #define DCF_DEV_SCAN 0x0002 7318c2ecf20Sopenharmony_ci #define DCF_POLLED 0x8000 7328c2ecf20Sopenharmony_ci u32 interleave; 7338c2ecf20Sopenharmony_ci u32 block_size; 7348c2ecf20Sopenharmony_ci u16 dev_ix; 7358c2ecf20Sopenharmony_ci u8 part_num; 7368c2ecf20Sopenharmony_ci u8 raid_grp_ix; 7378c2ecf20Sopenharmony_ci char raid_grp_name[16]; 7388c2ecf20Sopenharmony_ci struct esas2r_target *curr_targ; 7398c2ecf20Sopenharmony_ci u16 curr_virt_id; 7408c2ecf20Sopenharmony_ci u16 curr_phys_id; 7418c2ecf20Sopenharmony_ci u8 scan_gen; 7428c2ecf20Sopenharmony_ci u8 dev_addr_type; 7438c2ecf20Sopenharmony_ci u64 sas_addr; 7448c2ecf20Sopenharmony_ci}; 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_cistruct esas2r_mem_desc { 7478c2ecf20Sopenharmony_ci struct list_head next_desc; 7488c2ecf20Sopenharmony_ci void *virt_addr; 7498c2ecf20Sopenharmony_ci u64 phys_addr; 7508c2ecf20Sopenharmony_ci void *pad; 7518c2ecf20Sopenharmony_ci void *esas2r_data; 7528c2ecf20Sopenharmony_ci u32 esas2r_param; 7538c2ecf20Sopenharmony_ci u32 size; 7548c2ecf20Sopenharmony_ci}; 7558c2ecf20Sopenharmony_ci 7568c2ecf20Sopenharmony_cienum fw_event_type { 7578c2ecf20Sopenharmony_ci fw_event_null, 7588c2ecf20Sopenharmony_ci fw_event_lun_change, 7598c2ecf20Sopenharmony_ci fw_event_present, 7608c2ecf20Sopenharmony_ci fw_event_not_present, 7618c2ecf20Sopenharmony_ci fw_event_vda_ae 7628c2ecf20Sopenharmony_ci}; 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_cistruct esas2r_vda_ae { 7658c2ecf20Sopenharmony_ci u32 signature; 7668c2ecf20Sopenharmony_ci#define ESAS2R_VDA_EVENT_SIG 0x4154544F 7678c2ecf20Sopenharmony_ci u8 bus_number; 7688c2ecf20Sopenharmony_ci u8 devfn; 7698c2ecf20Sopenharmony_ci u8 pad[2]; 7708c2ecf20Sopenharmony_ci union atto_vda_ae vda_ae; 7718c2ecf20Sopenharmony_ci}; 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_cistruct esas2r_fw_event_work { 7748c2ecf20Sopenharmony_ci struct list_head list; 7758c2ecf20Sopenharmony_ci struct delayed_work work; 7768c2ecf20Sopenharmony_ci struct esas2r_adapter *a; 7778c2ecf20Sopenharmony_ci enum fw_event_type type; 7788c2ecf20Sopenharmony_ci u8 data[sizeof(struct esas2r_vda_ae)]; 7798c2ecf20Sopenharmony_ci}; 7808c2ecf20Sopenharmony_ci 7818c2ecf20Sopenharmony_cienum state { 7828c2ecf20Sopenharmony_ci FW_INVALID_ST, 7838c2ecf20Sopenharmony_ci FW_STATUS_ST, 7848c2ecf20Sopenharmony_ci FW_COMMAND_ST 7858c2ecf20Sopenharmony_ci}; 7868c2ecf20Sopenharmony_ci 7878c2ecf20Sopenharmony_cistruct esas2r_firmware { 7888c2ecf20Sopenharmony_ci enum state state; 7898c2ecf20Sopenharmony_ci struct esas2r_flash_img header; 7908c2ecf20Sopenharmony_ci u8 *data; 7918c2ecf20Sopenharmony_ci u64 phys; 7928c2ecf20Sopenharmony_ci int orig_len; 7938c2ecf20Sopenharmony_ci void *header_buff; 7948c2ecf20Sopenharmony_ci u64 header_buff_phys; 7958c2ecf20Sopenharmony_ci}; 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_cistruct esas2r_adapter { 7988c2ecf20Sopenharmony_ci struct esas2r_target targetdb[ESAS2R_MAX_TARGETS]; 7998c2ecf20Sopenharmony_ci struct esas2r_target *targetdb_end; 8008c2ecf20Sopenharmony_ci unsigned char *regs; 8018c2ecf20Sopenharmony_ci unsigned char *data_window; 8028c2ecf20Sopenharmony_ci long flags; 8038c2ecf20Sopenharmony_ci #define AF_PORT_CHANGE 0 8048c2ecf20Sopenharmony_ci #define AF_CHPRST_NEEDED 1 8058c2ecf20Sopenharmony_ci #define AF_CHPRST_PENDING 2 8068c2ecf20Sopenharmony_ci #define AF_CHPRST_DETECTED 3 8078c2ecf20Sopenharmony_ci #define AF_BUSRST_NEEDED 4 8088c2ecf20Sopenharmony_ci #define AF_BUSRST_PENDING 5 8098c2ecf20Sopenharmony_ci #define AF_BUSRST_DETECTED 6 8108c2ecf20Sopenharmony_ci #define AF_DISABLED 7 8118c2ecf20Sopenharmony_ci #define AF_FLASH_LOCK 8 8128c2ecf20Sopenharmony_ci #define AF_OS_RESET 9 8138c2ecf20Sopenharmony_ci #define AF_FLASHING 10 8148c2ecf20Sopenharmony_ci #define AF_POWER_MGT 11 8158c2ecf20Sopenharmony_ci #define AF_NVR_VALID 12 8168c2ecf20Sopenharmony_ci #define AF_DEGRADED_MODE 13 8178c2ecf20Sopenharmony_ci #define AF_DISC_PENDING 14 8188c2ecf20Sopenharmony_ci #define AF_TASKLET_SCHEDULED 15 8198c2ecf20Sopenharmony_ci #define AF_HEARTBEAT 16 8208c2ecf20Sopenharmony_ci #define AF_HEARTBEAT_ENB 17 8218c2ecf20Sopenharmony_ci #define AF_NOT_PRESENT 18 8228c2ecf20Sopenharmony_ci #define AF_CHPRST_STARTED 19 8238c2ecf20Sopenharmony_ci #define AF_FIRST_INIT 20 8248c2ecf20Sopenharmony_ci #define AF_POWER_DOWN 21 8258c2ecf20Sopenharmony_ci #define AF_DISC_IN_PROG 22 8268c2ecf20Sopenharmony_ci #define AF_COMM_LIST_TOGGLE 23 8278c2ecf20Sopenharmony_ci #define AF_LEGACY_SGE_MODE 24 8288c2ecf20Sopenharmony_ci #define AF_DISC_POLLED 25 8298c2ecf20Sopenharmony_ci long flags2; 8308c2ecf20Sopenharmony_ci #define AF2_SERIAL_FLASH 0 8318c2ecf20Sopenharmony_ci #define AF2_DEV_SCAN 1 8328c2ecf20Sopenharmony_ci #define AF2_DEV_CNT_OK 2 8338c2ecf20Sopenharmony_ci #define AF2_COREDUMP_AVAIL 3 8348c2ecf20Sopenharmony_ci #define AF2_COREDUMP_SAVED 4 8358c2ecf20Sopenharmony_ci #define AF2_VDA_POWER_DOWN 5 8368c2ecf20Sopenharmony_ci #define AF2_THUNDERLINK 6 8378c2ecf20Sopenharmony_ci #define AF2_THUNDERBOLT 7 8388c2ecf20Sopenharmony_ci #define AF2_INIT_DONE 8 8398c2ecf20Sopenharmony_ci #define AF2_INT_PENDING 9 8408c2ecf20Sopenharmony_ci #define AF2_TIMER_TICK 10 8418c2ecf20Sopenharmony_ci #define AF2_IRQ_CLAIMED 11 8428c2ecf20Sopenharmony_ci #define AF2_MSI_ENABLED 12 8438c2ecf20Sopenharmony_ci atomic_t disable_cnt; 8448c2ecf20Sopenharmony_ci atomic_t dis_ints_cnt; 8458c2ecf20Sopenharmony_ci u32 int_stat; 8468c2ecf20Sopenharmony_ci u32 int_mask; 8478c2ecf20Sopenharmony_ci u32 volatile *outbound_copy; 8488c2ecf20Sopenharmony_ci struct list_head avail_request; 8498c2ecf20Sopenharmony_ci spinlock_t request_lock; 8508c2ecf20Sopenharmony_ci spinlock_t sg_list_lock; 8518c2ecf20Sopenharmony_ci spinlock_t queue_lock; 8528c2ecf20Sopenharmony_ci spinlock_t mem_lock; 8538c2ecf20Sopenharmony_ci struct list_head free_sg_list_head; 8548c2ecf20Sopenharmony_ci struct esas2r_mem_desc *sg_list_mds; 8558c2ecf20Sopenharmony_ci struct list_head active_list; 8568c2ecf20Sopenharmony_ci struct list_head defer_list; 8578c2ecf20Sopenharmony_ci struct esas2r_request **req_table; 8588c2ecf20Sopenharmony_ci union { 8598c2ecf20Sopenharmony_ci u16 prev_dev_cnt; 8608c2ecf20Sopenharmony_ci u32 heartbeat_time; 8618c2ecf20Sopenharmony_ci #define ESAS2R_HEARTBEAT_TIME (3000) 8628c2ecf20Sopenharmony_ci }; 8638c2ecf20Sopenharmony_ci u32 chip_uptime; 8648c2ecf20Sopenharmony_ci #define ESAS2R_CHP_UPTIME_MAX (60000) 8658c2ecf20Sopenharmony_ci #define ESAS2R_CHP_UPTIME_CNT (20000) 8668c2ecf20Sopenharmony_ci u64 uncached_phys; 8678c2ecf20Sopenharmony_ci u8 *uncached; 8688c2ecf20Sopenharmony_ci struct esas2r_sas_nvram *nvram; 8698c2ecf20Sopenharmony_ci struct esas2r_request general_req; 8708c2ecf20Sopenharmony_ci u8 init_msg; 8718c2ecf20Sopenharmony_ci #define ESAS2R_INIT_MSG_START 1 8728c2ecf20Sopenharmony_ci #define ESAS2R_INIT_MSG_INIT 2 8738c2ecf20Sopenharmony_ci #define ESAS2R_INIT_MSG_GET_INIT 3 8748c2ecf20Sopenharmony_ci #define ESAS2R_INIT_MSG_REINIT 4 8758c2ecf20Sopenharmony_ci u16 cmd_ref_no; 8768c2ecf20Sopenharmony_ci u32 fw_version; 8778c2ecf20Sopenharmony_ci u32 fw_build; 8788c2ecf20Sopenharmony_ci u32 chip_init_time; 8798c2ecf20Sopenharmony_ci #define ESAS2R_CHPRST_TIME (180000) 8808c2ecf20Sopenharmony_ci #define ESAS2R_CHPRST_WAIT_TIME (2000) 8818c2ecf20Sopenharmony_ci u32 last_tick_time; 8828c2ecf20Sopenharmony_ci u32 window_base; 8838c2ecf20Sopenharmony_ci RQBUILDSGL build_sgl; 8848c2ecf20Sopenharmony_ci struct esas2r_request *first_ae_req; 8858c2ecf20Sopenharmony_ci u32 list_size; 8868c2ecf20Sopenharmony_ci u32 last_write; 8878c2ecf20Sopenharmony_ci u32 last_read; 8888c2ecf20Sopenharmony_ci u16 max_vdareq_size; 8898c2ecf20Sopenharmony_ci u16 disc_wait_cnt; 8908c2ecf20Sopenharmony_ci struct esas2r_mem_desc inbound_list_md; 8918c2ecf20Sopenharmony_ci struct esas2r_mem_desc outbound_list_md; 8928c2ecf20Sopenharmony_ci struct esas2r_disc_context disc_ctx; 8938c2ecf20Sopenharmony_ci u8 *disc_buffer; 8948c2ecf20Sopenharmony_ci u32 disc_start_time; 8958c2ecf20Sopenharmony_ci u32 disc_wait_time; 8968c2ecf20Sopenharmony_ci u32 flash_ver; 8978c2ecf20Sopenharmony_ci char flash_rev[16]; 8988c2ecf20Sopenharmony_ci char fw_rev[16]; 8998c2ecf20Sopenharmony_ci char image_type[16]; 9008c2ecf20Sopenharmony_ci struct esas2r_flash_context flash_context; 9018c2ecf20Sopenharmony_ci u32 num_targets_backend; 9028c2ecf20Sopenharmony_ci u32 ioctl_tunnel; 9038c2ecf20Sopenharmony_ci struct tasklet_struct tasklet; 9048c2ecf20Sopenharmony_ci struct pci_dev *pcid; 9058c2ecf20Sopenharmony_ci struct Scsi_Host *host; 9068c2ecf20Sopenharmony_ci unsigned int index; 9078c2ecf20Sopenharmony_ci char name[32]; 9088c2ecf20Sopenharmony_ci struct timer_list timer; 9098c2ecf20Sopenharmony_ci struct esas2r_firmware firmware; 9108c2ecf20Sopenharmony_ci wait_queue_head_t nvram_waiter; 9118c2ecf20Sopenharmony_ci int nvram_command_done; 9128c2ecf20Sopenharmony_ci wait_queue_head_t fm_api_waiter; 9138c2ecf20Sopenharmony_ci int fm_api_command_done; 9148c2ecf20Sopenharmony_ci wait_queue_head_t vda_waiter; 9158c2ecf20Sopenharmony_ci int vda_command_done; 9168c2ecf20Sopenharmony_ci u8 *vda_buffer; 9178c2ecf20Sopenharmony_ci u64 ppvda_buffer; 9188c2ecf20Sopenharmony_ci#define VDA_BUFFER_HEADER_SZ (offsetof(struct atto_ioctl_vda, data)) 9198c2ecf20Sopenharmony_ci#define VDA_MAX_BUFFER_SIZE (0x40000 + VDA_BUFFER_HEADER_SZ) 9208c2ecf20Sopenharmony_ci wait_queue_head_t fs_api_waiter; 9218c2ecf20Sopenharmony_ci int fs_api_command_done; 9228c2ecf20Sopenharmony_ci u64 ppfs_api_buffer; 9238c2ecf20Sopenharmony_ci u8 *fs_api_buffer; 9248c2ecf20Sopenharmony_ci u32 fs_api_buffer_size; 9258c2ecf20Sopenharmony_ci wait_queue_head_t buffered_ioctl_waiter; 9268c2ecf20Sopenharmony_ci int buffered_ioctl_done; 9278c2ecf20Sopenharmony_ci int uncached_size; 9288c2ecf20Sopenharmony_ci struct workqueue_struct *fw_event_q; 9298c2ecf20Sopenharmony_ci struct list_head fw_event_list; 9308c2ecf20Sopenharmony_ci spinlock_t fw_event_lock; 9318c2ecf20Sopenharmony_ci u8 fw_events_off; /* if '1', then ignore events */ 9328c2ecf20Sopenharmony_ci char fw_event_q_name[ESAS2R_KOBJ_NAME_LEN]; 9338c2ecf20Sopenharmony_ci /* 9348c2ecf20Sopenharmony_ci * intr_mode stores the interrupt mode currently being used by this 9358c2ecf20Sopenharmony_ci * adapter. it is based on the interrupt_mode module parameter, but 9368c2ecf20Sopenharmony_ci * can be changed based on the ability (or not) to utilize the 9378c2ecf20Sopenharmony_ci * mode requested by the parameter. 9388c2ecf20Sopenharmony_ci */ 9398c2ecf20Sopenharmony_ci int intr_mode; 9408c2ecf20Sopenharmony_ci#define INTR_MODE_LEGACY 0 9418c2ecf20Sopenharmony_ci#define INTR_MODE_MSI 1 9428c2ecf20Sopenharmony_ci#define INTR_MODE_MSIX 2 9438c2ecf20Sopenharmony_ci struct esas2r_sg_context fm_api_sgc; 9448c2ecf20Sopenharmony_ci u8 *save_offset; 9458c2ecf20Sopenharmony_ci struct list_head vrq_mds_head; 9468c2ecf20Sopenharmony_ci struct esas2r_mem_desc *vrq_mds; 9478c2ecf20Sopenharmony_ci int num_vrqs; 9488c2ecf20Sopenharmony_ci struct mutex fm_api_mutex; 9498c2ecf20Sopenharmony_ci struct mutex fs_api_mutex; 9508c2ecf20Sopenharmony_ci struct semaphore nvram_semaphore; 9518c2ecf20Sopenharmony_ci struct atto_ioctl *local_atto_ioctl; 9528c2ecf20Sopenharmony_ci u8 fw_coredump_buff[ESAS2R_FWCOREDUMP_SZ]; 9538c2ecf20Sopenharmony_ci unsigned int sysfs_fw_created:1; 9548c2ecf20Sopenharmony_ci unsigned int sysfs_fs_created:1; 9558c2ecf20Sopenharmony_ci unsigned int sysfs_vda_created:1; 9568c2ecf20Sopenharmony_ci unsigned int sysfs_hw_created:1; 9578c2ecf20Sopenharmony_ci unsigned int sysfs_live_nvram_created:1; 9588c2ecf20Sopenharmony_ci unsigned int sysfs_default_nvram_created:1; 9598c2ecf20Sopenharmony_ci}; 9608c2ecf20Sopenharmony_ci 9618c2ecf20Sopenharmony_ci/* 9628c2ecf20Sopenharmony_ci * Function Declarations 9638c2ecf20Sopenharmony_ci * SCSI functions 9648c2ecf20Sopenharmony_ci */ 9658c2ecf20Sopenharmony_ciconst char *esas2r_info(struct Scsi_Host *); 9668c2ecf20Sopenharmony_ciint esas2r_write_params(struct esas2r_adapter *a, struct esas2r_request *rq, 9678c2ecf20Sopenharmony_ci struct esas2r_sas_nvram *data); 9688c2ecf20Sopenharmony_ciint esas2r_ioctl_handler(void *hostdata, unsigned int cmd, void __user *arg); 9698c2ecf20Sopenharmony_ciint esas2r_ioctl(struct scsi_device *dev, unsigned int cmd, void __user *arg); 9708c2ecf20Sopenharmony_ciu8 handle_hba_ioctl(struct esas2r_adapter *a, 9718c2ecf20Sopenharmony_ci struct atto_ioctl *ioctl_hba); 9728c2ecf20Sopenharmony_ciint esas2r_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd); 9738c2ecf20Sopenharmony_ciint esas2r_show_info(struct seq_file *m, struct Scsi_Host *sh); 9748c2ecf20Sopenharmony_cilong esas2r_proc_ioctl(struct file *fp, unsigned int cmd, unsigned long arg); 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_ci/* SCSI error handler (eh) functions */ 9778c2ecf20Sopenharmony_ciint esas2r_eh_abort(struct scsi_cmnd *cmd); 9788c2ecf20Sopenharmony_ciint esas2r_device_reset(struct scsi_cmnd *cmd); 9798c2ecf20Sopenharmony_ciint esas2r_host_reset(struct scsi_cmnd *cmd); 9808c2ecf20Sopenharmony_ciint esas2r_bus_reset(struct scsi_cmnd *cmd); 9818c2ecf20Sopenharmony_ciint esas2r_target_reset(struct scsi_cmnd *cmd); 9828c2ecf20Sopenharmony_ci 9838c2ecf20Sopenharmony_ci/* Internal functions */ 9848c2ecf20Sopenharmony_ciint esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid, 9858c2ecf20Sopenharmony_ci int index); 9868c2ecf20Sopenharmony_ciint esas2r_read_fw(struct esas2r_adapter *a, char *buf, long off, int count); 9878c2ecf20Sopenharmony_ciint esas2r_write_fw(struct esas2r_adapter *a, const char *buf, long off, 9888c2ecf20Sopenharmony_ci int count); 9898c2ecf20Sopenharmony_ciint esas2r_read_vda(struct esas2r_adapter *a, char *buf, long off, int count); 9908c2ecf20Sopenharmony_ciint esas2r_write_vda(struct esas2r_adapter *a, const char *buf, long off, 9918c2ecf20Sopenharmony_ci int count); 9928c2ecf20Sopenharmony_ciint esas2r_read_fs(struct esas2r_adapter *a, char *buf, long off, int count); 9938c2ecf20Sopenharmony_ciint esas2r_write_fs(struct esas2r_adapter *a, const char *buf, long off, 9948c2ecf20Sopenharmony_ci int count); 9958c2ecf20Sopenharmony_civoid esas2r_adapter_tasklet(unsigned long context); 9968c2ecf20Sopenharmony_ciirqreturn_t esas2r_interrupt(int irq, void *dev_id); 9978c2ecf20Sopenharmony_ciirqreturn_t esas2r_msi_interrupt(int irq, void *dev_id); 9988c2ecf20Sopenharmony_civoid esas2r_kickoff_timer(struct esas2r_adapter *a); 9998c2ecf20Sopenharmony_ciint esas2r_suspend(struct pci_dev *pcid, pm_message_t state); 10008c2ecf20Sopenharmony_ciint esas2r_resume(struct pci_dev *pcid); 10018c2ecf20Sopenharmony_civoid esas2r_fw_event_off(struct esas2r_adapter *a); 10028c2ecf20Sopenharmony_civoid esas2r_fw_event_on(struct esas2r_adapter *a); 10038c2ecf20Sopenharmony_cibool esas2r_nvram_write(struct esas2r_adapter *a, struct esas2r_request *rq, 10048c2ecf20Sopenharmony_ci struct esas2r_sas_nvram *nvram); 10058c2ecf20Sopenharmony_civoid esas2r_nvram_get_defaults(struct esas2r_adapter *a, 10068c2ecf20Sopenharmony_ci struct esas2r_sas_nvram *nvram); 10078c2ecf20Sopenharmony_civoid esas2r_complete_request_cb(struct esas2r_adapter *a, 10088c2ecf20Sopenharmony_ci struct esas2r_request *rq); 10098c2ecf20Sopenharmony_civoid esas2r_reset_detected(struct esas2r_adapter *a); 10108c2ecf20Sopenharmony_civoid esas2r_target_state_changed(struct esas2r_adapter *ha, u16 targ_id, 10118c2ecf20Sopenharmony_ci u8 state); 10128c2ecf20Sopenharmony_ciint esas2r_req_status_to_error(u8 req_stat); 10138c2ecf20Sopenharmony_civoid esas2r_kill_adapter(int i); 10148c2ecf20Sopenharmony_civoid esas2r_free_request(struct esas2r_adapter *a, struct esas2r_request *rq); 10158c2ecf20Sopenharmony_cistruct esas2r_request *esas2r_alloc_request(struct esas2r_adapter *a); 10168c2ecf20Sopenharmony_ciu32 esas2r_get_uncached_size(struct esas2r_adapter *a); 10178c2ecf20Sopenharmony_cibool esas2r_init_adapter_struct(struct esas2r_adapter *a, 10188c2ecf20Sopenharmony_ci void **uncached_area); 10198c2ecf20Sopenharmony_cibool esas2r_check_adapter(struct esas2r_adapter *a); 10208c2ecf20Sopenharmony_cibool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll); 10218c2ecf20Sopenharmony_civoid esas2r_start_request(struct esas2r_adapter *a, struct esas2r_request *rq); 10228c2ecf20Sopenharmony_cibool esas2r_send_task_mgmt(struct esas2r_adapter *a, 10238c2ecf20Sopenharmony_ci struct esas2r_request *rqaux, u8 task_mgt_func); 10248c2ecf20Sopenharmony_civoid esas2r_do_tasklet_tasks(struct esas2r_adapter *a); 10258c2ecf20Sopenharmony_civoid esas2r_adapter_interrupt(struct esas2r_adapter *a); 10268c2ecf20Sopenharmony_civoid esas2r_do_deferred_processes(struct esas2r_adapter *a); 10278c2ecf20Sopenharmony_civoid esas2r_reset_bus(struct esas2r_adapter *a); 10288c2ecf20Sopenharmony_civoid esas2r_reset_adapter(struct esas2r_adapter *a); 10298c2ecf20Sopenharmony_civoid esas2r_timer_tick(struct esas2r_adapter *a); 10308c2ecf20Sopenharmony_ciconst char *esas2r_get_model_name(struct esas2r_adapter *a); 10318c2ecf20Sopenharmony_ciconst char *esas2r_get_model_name_short(struct esas2r_adapter *a); 10328c2ecf20Sopenharmony_ciu32 esas2r_stall_execution(struct esas2r_adapter *a, u32 start_time, 10338c2ecf20Sopenharmony_ci u32 *delay); 10348c2ecf20Sopenharmony_civoid esas2r_build_flash_req(struct esas2r_adapter *a, 10358c2ecf20Sopenharmony_ci struct esas2r_request *rq, 10368c2ecf20Sopenharmony_ci u8 sub_func, 10378c2ecf20Sopenharmony_ci u8 cksum, 10388c2ecf20Sopenharmony_ci u32 addr, 10398c2ecf20Sopenharmony_ci u32 length); 10408c2ecf20Sopenharmony_civoid esas2r_build_mgt_req(struct esas2r_adapter *a, 10418c2ecf20Sopenharmony_ci struct esas2r_request *rq, 10428c2ecf20Sopenharmony_ci u8 sub_func, 10438c2ecf20Sopenharmony_ci u8 scan_gen, 10448c2ecf20Sopenharmony_ci u16 dev_index, 10458c2ecf20Sopenharmony_ci u32 length, 10468c2ecf20Sopenharmony_ci void *data); 10478c2ecf20Sopenharmony_civoid esas2r_build_ae_req(struct esas2r_adapter *a, struct esas2r_request *rq); 10488c2ecf20Sopenharmony_civoid esas2r_build_cli_req(struct esas2r_adapter *a, 10498c2ecf20Sopenharmony_ci struct esas2r_request *rq, 10508c2ecf20Sopenharmony_ci u32 length, 10518c2ecf20Sopenharmony_ci u32 cmd_rsp_len); 10528c2ecf20Sopenharmony_civoid esas2r_build_ioctl_req(struct esas2r_adapter *a, 10538c2ecf20Sopenharmony_ci struct esas2r_request *rq, 10548c2ecf20Sopenharmony_ci u32 length, 10558c2ecf20Sopenharmony_ci u8 sub_func); 10568c2ecf20Sopenharmony_civoid esas2r_build_cfg_req(struct esas2r_adapter *a, 10578c2ecf20Sopenharmony_ci struct esas2r_request *rq, 10588c2ecf20Sopenharmony_ci u8 sub_func, 10598c2ecf20Sopenharmony_ci u32 length, 10608c2ecf20Sopenharmony_ci void *data); 10618c2ecf20Sopenharmony_civoid esas2r_power_down(struct esas2r_adapter *a); 10628c2ecf20Sopenharmony_cibool esas2r_power_up(struct esas2r_adapter *a, bool init_poll); 10638c2ecf20Sopenharmony_civoid esas2r_wait_request(struct esas2r_adapter *a, struct esas2r_request *rq); 10648c2ecf20Sopenharmony_ciu32 esas2r_map_data_window(struct esas2r_adapter *a, u32 addr_lo); 10658c2ecf20Sopenharmony_cibool esas2r_process_fs_ioctl(struct esas2r_adapter *a, 10668c2ecf20Sopenharmony_ci struct esas2r_ioctl_fs *fs, 10678c2ecf20Sopenharmony_ci struct esas2r_request *rq, 10688c2ecf20Sopenharmony_ci struct esas2r_sg_context *sgc); 10698c2ecf20Sopenharmony_cibool esas2r_read_flash_block(struct esas2r_adapter *a, void *to, u32 from, 10708c2ecf20Sopenharmony_ci u32 size); 10718c2ecf20Sopenharmony_cibool esas2r_read_mem_block(struct esas2r_adapter *a, void *to, u32 from, 10728c2ecf20Sopenharmony_ci u32 size); 10738c2ecf20Sopenharmony_cibool esas2r_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi, 10748c2ecf20Sopenharmony_ci struct esas2r_request *rq, struct esas2r_sg_context *sgc); 10758c2ecf20Sopenharmony_civoid esas2r_force_interrupt(struct esas2r_adapter *a); 10768c2ecf20Sopenharmony_civoid esas2r_local_start_request(struct esas2r_adapter *a, 10778c2ecf20Sopenharmony_ci struct esas2r_request *rq); 10788c2ecf20Sopenharmony_civoid esas2r_process_adapter_reset(struct esas2r_adapter *a); 10798c2ecf20Sopenharmony_civoid esas2r_complete_request(struct esas2r_adapter *a, 10808c2ecf20Sopenharmony_ci struct esas2r_request *rq); 10818c2ecf20Sopenharmony_civoid esas2r_dummy_complete(struct esas2r_adapter *a, 10828c2ecf20Sopenharmony_ci struct esas2r_request *rq); 10838c2ecf20Sopenharmony_civoid esas2r_ae_complete(struct esas2r_adapter *a, struct esas2r_request *rq); 10848c2ecf20Sopenharmony_civoid esas2r_start_vda_request(struct esas2r_adapter *a, 10858c2ecf20Sopenharmony_ci struct esas2r_request *rq); 10868c2ecf20Sopenharmony_cibool esas2r_read_flash_rev(struct esas2r_adapter *a); 10878c2ecf20Sopenharmony_cibool esas2r_read_image_type(struct esas2r_adapter *a); 10888c2ecf20Sopenharmony_cibool esas2r_nvram_read_direct(struct esas2r_adapter *a); 10898c2ecf20Sopenharmony_cibool esas2r_nvram_validate(struct esas2r_adapter *a); 10908c2ecf20Sopenharmony_civoid esas2r_nvram_set_defaults(struct esas2r_adapter *a); 10918c2ecf20Sopenharmony_cibool esas2r_print_flash_rev(struct esas2r_adapter *a); 10928c2ecf20Sopenharmony_civoid esas2r_send_reset_ae(struct esas2r_adapter *a, bool pwr_mgt); 10938c2ecf20Sopenharmony_cibool esas2r_init_msgs(struct esas2r_adapter *a); 10948c2ecf20Sopenharmony_cibool esas2r_is_adapter_present(struct esas2r_adapter *a); 10958c2ecf20Sopenharmony_civoid esas2r_nuxi_mgt_data(u8 function, void *data); 10968c2ecf20Sopenharmony_civoid esas2r_nuxi_cfg_data(u8 function, void *data); 10978c2ecf20Sopenharmony_civoid esas2r_nuxi_ae_data(union atto_vda_ae *ae); 10988c2ecf20Sopenharmony_civoid esas2r_reset_chip(struct esas2r_adapter *a); 10998c2ecf20Sopenharmony_civoid esas2r_log_request_failure(struct esas2r_adapter *a, 11008c2ecf20Sopenharmony_ci struct esas2r_request *rq); 11018c2ecf20Sopenharmony_civoid esas2r_polled_interrupt(struct esas2r_adapter *a); 11028c2ecf20Sopenharmony_cibool esas2r_ioreq_aborted(struct esas2r_adapter *a, struct esas2r_request *rq, 11038c2ecf20Sopenharmony_ci u8 status); 11048c2ecf20Sopenharmony_cibool esas2r_build_sg_list_sge(struct esas2r_adapter *a, 11058c2ecf20Sopenharmony_ci struct esas2r_sg_context *sgc); 11068c2ecf20Sopenharmony_cibool esas2r_build_sg_list_prd(struct esas2r_adapter *a, 11078c2ecf20Sopenharmony_ci struct esas2r_sg_context *sgc); 11088c2ecf20Sopenharmony_civoid esas2r_targ_db_initialize(struct esas2r_adapter *a); 11098c2ecf20Sopenharmony_civoid esas2r_targ_db_remove_all(struct esas2r_adapter *a, bool notify); 11108c2ecf20Sopenharmony_civoid esas2r_targ_db_report_changes(struct esas2r_adapter *a); 11118c2ecf20Sopenharmony_cistruct esas2r_target *esas2r_targ_db_add_raid(struct esas2r_adapter *a, 11128c2ecf20Sopenharmony_ci struct esas2r_disc_context *dc); 11138c2ecf20Sopenharmony_cistruct esas2r_target *esas2r_targ_db_add_pthru(struct esas2r_adapter *a, 11148c2ecf20Sopenharmony_ci struct esas2r_disc_context *dc, 11158c2ecf20Sopenharmony_ci u8 *ident, 11168c2ecf20Sopenharmony_ci u8 ident_len); 11178c2ecf20Sopenharmony_civoid esas2r_targ_db_remove(struct esas2r_adapter *a, struct esas2r_target *t); 11188c2ecf20Sopenharmony_cistruct esas2r_target *esas2r_targ_db_find_by_sas_addr(struct esas2r_adapter *a, 11198c2ecf20Sopenharmony_ci u64 *sas_addr); 11208c2ecf20Sopenharmony_cistruct esas2r_target *esas2r_targ_db_find_by_ident(struct esas2r_adapter *a, 11218c2ecf20Sopenharmony_ci void *identifier, 11228c2ecf20Sopenharmony_ci u8 ident_len); 11238c2ecf20Sopenharmony_ciu16 esas2r_targ_db_find_next_present(struct esas2r_adapter *a, u16 target_id); 11248c2ecf20Sopenharmony_cistruct esas2r_target *esas2r_targ_db_find_by_virt_id(struct esas2r_adapter *a, 11258c2ecf20Sopenharmony_ci u16 virt_id); 11268c2ecf20Sopenharmony_ciu16 esas2r_targ_db_get_tgt_cnt(struct esas2r_adapter *a); 11278c2ecf20Sopenharmony_civoid esas2r_disc_initialize(struct esas2r_adapter *a); 11288c2ecf20Sopenharmony_civoid esas2r_disc_start_waiting(struct esas2r_adapter *a); 11298c2ecf20Sopenharmony_civoid esas2r_disc_check_for_work(struct esas2r_adapter *a); 11308c2ecf20Sopenharmony_civoid esas2r_disc_check_complete(struct esas2r_adapter *a); 11318c2ecf20Sopenharmony_civoid esas2r_disc_queue_event(struct esas2r_adapter *a, u8 disc_evt); 11328c2ecf20Sopenharmony_cibool esas2r_disc_start_port(struct esas2r_adapter *a); 11338c2ecf20Sopenharmony_civoid esas2r_disc_local_start_request(struct esas2r_adapter *a, 11348c2ecf20Sopenharmony_ci struct esas2r_request *rq); 11358c2ecf20Sopenharmony_cibool esas2r_set_degraded_mode(struct esas2r_adapter *a, char *error_str); 11368c2ecf20Sopenharmony_cibool esas2r_process_vda_ioctl(struct esas2r_adapter *a, 11378c2ecf20Sopenharmony_ci struct atto_ioctl_vda *vi, 11388c2ecf20Sopenharmony_ci struct esas2r_request *rq, 11398c2ecf20Sopenharmony_ci struct esas2r_sg_context *sgc); 11408c2ecf20Sopenharmony_civoid esas2r_queue_fw_event(struct esas2r_adapter *a, 11418c2ecf20Sopenharmony_ci enum fw_event_type type, 11428c2ecf20Sopenharmony_ci void *data, 11438c2ecf20Sopenharmony_ci int data_sz); 11448c2ecf20Sopenharmony_ci 11458c2ecf20Sopenharmony_ci/* Inline functions */ 11468c2ecf20Sopenharmony_ci 11478c2ecf20Sopenharmony_ci/* Allocate a chip scatter/gather list entry */ 11488c2ecf20Sopenharmony_cistatic inline struct esas2r_mem_desc *esas2r_alloc_sgl(struct esas2r_adapter *a) 11498c2ecf20Sopenharmony_ci{ 11508c2ecf20Sopenharmony_ci unsigned long flags; 11518c2ecf20Sopenharmony_ci struct list_head *sgl; 11528c2ecf20Sopenharmony_ci struct esas2r_mem_desc *result = NULL; 11538c2ecf20Sopenharmony_ci 11548c2ecf20Sopenharmony_ci spin_lock_irqsave(&a->sg_list_lock, flags); 11558c2ecf20Sopenharmony_ci if (likely(!list_empty(&a->free_sg_list_head))) { 11568c2ecf20Sopenharmony_ci sgl = a->free_sg_list_head.next; 11578c2ecf20Sopenharmony_ci result = list_entry(sgl, struct esas2r_mem_desc, next_desc); 11588c2ecf20Sopenharmony_ci list_del_init(sgl); 11598c2ecf20Sopenharmony_ci } 11608c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&a->sg_list_lock, flags); 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci return result; 11638c2ecf20Sopenharmony_ci} 11648c2ecf20Sopenharmony_ci 11658c2ecf20Sopenharmony_ci/* Initialize a scatter/gather context */ 11668c2ecf20Sopenharmony_cistatic inline void esas2r_sgc_init(struct esas2r_sg_context *sgc, 11678c2ecf20Sopenharmony_ci struct esas2r_adapter *a, 11688c2ecf20Sopenharmony_ci struct esas2r_request *rq, 11698c2ecf20Sopenharmony_ci struct atto_vda_sge *first) 11708c2ecf20Sopenharmony_ci{ 11718c2ecf20Sopenharmony_ci sgc->adapter = a; 11728c2ecf20Sopenharmony_ci sgc->first_req = rq; 11738c2ecf20Sopenharmony_ci 11748c2ecf20Sopenharmony_ci /* 11758c2ecf20Sopenharmony_ci * set the limit pointer such that an SGE pointer above this value 11768c2ecf20Sopenharmony_ci * would be the first one to overflow the SGL. 11778c2ecf20Sopenharmony_ci */ 11788c2ecf20Sopenharmony_ci sgc->sge.a64.limit = (struct atto_vda_sge *)((u8 *)rq->vrq 11798c2ecf20Sopenharmony_ci + (sizeof(union 11808c2ecf20Sopenharmony_ci atto_vda_req) / 11818c2ecf20Sopenharmony_ci 8) 11828c2ecf20Sopenharmony_ci - sizeof(struct 11838c2ecf20Sopenharmony_ci atto_vda_sge)); 11848c2ecf20Sopenharmony_ci if (first) { 11858c2ecf20Sopenharmony_ci sgc->sge.a64.last = 11868c2ecf20Sopenharmony_ci sgc->sge.a64.curr = first; 11878c2ecf20Sopenharmony_ci rq->vrq->scsi.sg_list_offset = (u8) 11888c2ecf20Sopenharmony_ci ((u8 *)first - 11898c2ecf20Sopenharmony_ci (u8 *)rq->vrq); 11908c2ecf20Sopenharmony_ci } else { 11918c2ecf20Sopenharmony_ci sgc->sge.a64.last = 11928c2ecf20Sopenharmony_ci sgc->sge.a64.curr = &rq->vrq->scsi.u.sge[0]; 11938c2ecf20Sopenharmony_ci rq->vrq->scsi.sg_list_offset = 11948c2ecf20Sopenharmony_ci (u8)offsetof(struct atto_vda_scsi_req, u.sge); 11958c2ecf20Sopenharmony_ci } 11968c2ecf20Sopenharmony_ci sgc->sge.a64.chain = NULL; 11978c2ecf20Sopenharmony_ci} 11988c2ecf20Sopenharmony_ci 11998c2ecf20Sopenharmony_cistatic inline void esas2r_rq_init_request(struct esas2r_request *rq, 12008c2ecf20Sopenharmony_ci struct esas2r_adapter *a) 12018c2ecf20Sopenharmony_ci{ 12028c2ecf20Sopenharmony_ci union atto_vda_req *vrq = rq->vrq; 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&rq->sg_table_head); 12058c2ecf20Sopenharmony_ci rq->data_buf = (void *)(vrq + 1); 12068c2ecf20Sopenharmony_ci rq->interrupt_cb = NULL; 12078c2ecf20Sopenharmony_ci rq->comp_cb = esas2r_complete_request_cb; 12088c2ecf20Sopenharmony_ci rq->flags = 0; 12098c2ecf20Sopenharmony_ci rq->timeout = 0; 12108c2ecf20Sopenharmony_ci rq->req_stat = RS_PENDING; 12118c2ecf20Sopenharmony_ci rq->req_type = RT_INI_REQ; 12128c2ecf20Sopenharmony_ci 12138c2ecf20Sopenharmony_ci /* clear the outbound response */ 12148c2ecf20Sopenharmony_ci rq->func_rsp.dwords[0] = 0; 12158c2ecf20Sopenharmony_ci rq->func_rsp.dwords[1] = 0; 12168c2ecf20Sopenharmony_ci 12178c2ecf20Sopenharmony_ci /* 12188c2ecf20Sopenharmony_ci * clear the size of the VDA request. esas2r_build_sg_list() will 12198c2ecf20Sopenharmony_ci * only allow the size of the request to grow. there are some 12208c2ecf20Sopenharmony_ci * management requests that go through there twice and the second 12218c2ecf20Sopenharmony_ci * time through sets a smaller request size. if this is not modified 12228c2ecf20Sopenharmony_ci * at all we'll set it to the size of the entire VDA request. 12238c2ecf20Sopenharmony_ci */ 12248c2ecf20Sopenharmony_ci rq->vda_req_sz = RQ_SIZE_DEFAULT; 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_ci /* req_table entry should be NULL at this point - if not, halt */ 12278c2ecf20Sopenharmony_ci 12288c2ecf20Sopenharmony_ci if (a->req_table[LOWORD(vrq->scsi.handle)]) { 12298c2ecf20Sopenharmony_ci esas2r_bugon(); 12308c2ecf20Sopenharmony_ci } 12318c2ecf20Sopenharmony_ci 12328c2ecf20Sopenharmony_ci /* fill in the table for this handle so we can get back to the 12338c2ecf20Sopenharmony_ci * request. 12348c2ecf20Sopenharmony_ci */ 12358c2ecf20Sopenharmony_ci a->req_table[LOWORD(vrq->scsi.handle)] = rq; 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_ci /* 12388c2ecf20Sopenharmony_ci * add a reference number to the handle to make it unique (until it 12398c2ecf20Sopenharmony_ci * wraps of course) while preserving the least significant word 12408c2ecf20Sopenharmony_ci */ 12418c2ecf20Sopenharmony_ci vrq->scsi.handle = (a->cmd_ref_no++ << 16) | (u16)vrq->scsi.handle; 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ci /* 12448c2ecf20Sopenharmony_ci * the following formats a SCSI request. the caller can override as 12458c2ecf20Sopenharmony_ci * necessary. clear_vda_request can be called to clear the VDA 12468c2ecf20Sopenharmony_ci * request for another type of request. 12478c2ecf20Sopenharmony_ci */ 12488c2ecf20Sopenharmony_ci vrq->scsi.function = VDA_FUNC_SCSI; 12498c2ecf20Sopenharmony_ci vrq->scsi.sense_len = SENSE_DATA_SZ; 12508c2ecf20Sopenharmony_ci 12518c2ecf20Sopenharmony_ci /* clear out sg_list_offset and chain_offset */ 12528c2ecf20Sopenharmony_ci vrq->scsi.sg_list_offset = 0; 12538c2ecf20Sopenharmony_ci vrq->scsi.chain_offset = 0; 12548c2ecf20Sopenharmony_ci vrq->scsi.flags = 0; 12558c2ecf20Sopenharmony_ci vrq->scsi.reserved = 0; 12568c2ecf20Sopenharmony_ci 12578c2ecf20Sopenharmony_ci /* set the sense buffer to be the data payload buffer */ 12588c2ecf20Sopenharmony_ci vrq->scsi.ppsense_buf 12598c2ecf20Sopenharmony_ci = cpu_to_le64(rq->vrq_md->phys_addr + 12608c2ecf20Sopenharmony_ci sizeof(union atto_vda_req)); 12618c2ecf20Sopenharmony_ci} 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_cistatic inline void esas2r_rq_free_sg_lists(struct esas2r_request *rq, 12648c2ecf20Sopenharmony_ci struct esas2r_adapter *a) 12658c2ecf20Sopenharmony_ci{ 12668c2ecf20Sopenharmony_ci unsigned long flags; 12678c2ecf20Sopenharmony_ci 12688c2ecf20Sopenharmony_ci if (list_empty(&rq->sg_table_head)) 12698c2ecf20Sopenharmony_ci return; 12708c2ecf20Sopenharmony_ci 12718c2ecf20Sopenharmony_ci spin_lock_irqsave(&a->sg_list_lock, flags); 12728c2ecf20Sopenharmony_ci list_splice_tail_init(&rq->sg_table_head, &a->free_sg_list_head); 12738c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&a->sg_list_lock, flags); 12748c2ecf20Sopenharmony_ci} 12758c2ecf20Sopenharmony_ci 12768c2ecf20Sopenharmony_cistatic inline void esas2r_rq_destroy_request(struct esas2r_request *rq, 12778c2ecf20Sopenharmony_ci struct esas2r_adapter *a) 12788c2ecf20Sopenharmony_ci 12798c2ecf20Sopenharmony_ci{ 12808c2ecf20Sopenharmony_ci esas2r_rq_free_sg_lists(rq, a); 12818c2ecf20Sopenharmony_ci a->req_table[LOWORD(rq->vrq->scsi.handle)] = NULL; 12828c2ecf20Sopenharmony_ci rq->data_buf = NULL; 12838c2ecf20Sopenharmony_ci} 12848c2ecf20Sopenharmony_ci 12858c2ecf20Sopenharmony_cistatic inline bool esas2r_is_tasklet_pending(struct esas2r_adapter *a) 12868c2ecf20Sopenharmony_ci{ 12878c2ecf20Sopenharmony_ci 12888c2ecf20Sopenharmony_ci return test_bit(AF_BUSRST_NEEDED, &a->flags) || 12898c2ecf20Sopenharmony_ci test_bit(AF_BUSRST_DETECTED, &a->flags) || 12908c2ecf20Sopenharmony_ci test_bit(AF_CHPRST_NEEDED, &a->flags) || 12918c2ecf20Sopenharmony_ci test_bit(AF_CHPRST_DETECTED, &a->flags) || 12928c2ecf20Sopenharmony_ci test_bit(AF_PORT_CHANGE, &a->flags); 12938c2ecf20Sopenharmony_ci 12948c2ecf20Sopenharmony_ci} 12958c2ecf20Sopenharmony_ci 12968c2ecf20Sopenharmony_ci/* 12978c2ecf20Sopenharmony_ci * Build the scatter/gather list for an I/O request according to the 12988c2ecf20Sopenharmony_ci * specifications placed in the esas2r_sg_context. The caller must initialize 12998c2ecf20Sopenharmony_ci * struct esas2r_sg_context prior to the initial call by calling 13008c2ecf20Sopenharmony_ci * esas2r_sgc_init() 13018c2ecf20Sopenharmony_ci */ 13028c2ecf20Sopenharmony_cistatic inline bool esas2r_build_sg_list(struct esas2r_adapter *a, 13038c2ecf20Sopenharmony_ci struct esas2r_request *rq, 13048c2ecf20Sopenharmony_ci struct esas2r_sg_context *sgc) 13058c2ecf20Sopenharmony_ci{ 13068c2ecf20Sopenharmony_ci if (unlikely(le32_to_cpu(rq->vrq->scsi.length) == 0)) 13078c2ecf20Sopenharmony_ci return true; 13088c2ecf20Sopenharmony_ci 13098c2ecf20Sopenharmony_ci return (*a->build_sgl)(a, sgc); 13108c2ecf20Sopenharmony_ci} 13118c2ecf20Sopenharmony_ci 13128c2ecf20Sopenharmony_cistatic inline void esas2r_disable_chip_interrupts(struct esas2r_adapter *a) 13138c2ecf20Sopenharmony_ci{ 13148c2ecf20Sopenharmony_ci if (atomic_inc_return(&a->dis_ints_cnt) == 1) 13158c2ecf20Sopenharmony_ci esas2r_write_register_dword(a, MU_INT_MASK_OUT, 13168c2ecf20Sopenharmony_ci ESAS2R_INT_DIS_MASK); 13178c2ecf20Sopenharmony_ci} 13188c2ecf20Sopenharmony_ci 13198c2ecf20Sopenharmony_cistatic inline void esas2r_enable_chip_interrupts(struct esas2r_adapter *a) 13208c2ecf20Sopenharmony_ci{ 13218c2ecf20Sopenharmony_ci if (atomic_dec_return(&a->dis_ints_cnt) == 0) 13228c2ecf20Sopenharmony_ci esas2r_write_register_dword(a, MU_INT_MASK_OUT, 13238c2ecf20Sopenharmony_ci ESAS2R_INT_ENB_MASK); 13248c2ecf20Sopenharmony_ci} 13258c2ecf20Sopenharmony_ci 13268c2ecf20Sopenharmony_ci/* Schedule a TASKLET to perform non-interrupt tasks that may require delays 13278c2ecf20Sopenharmony_ci * or long completion times. 13288c2ecf20Sopenharmony_ci */ 13298c2ecf20Sopenharmony_cistatic inline void esas2r_schedule_tasklet(struct esas2r_adapter *a) 13308c2ecf20Sopenharmony_ci{ 13318c2ecf20Sopenharmony_ci /* make sure we don't schedule twice */ 13328c2ecf20Sopenharmony_ci if (!test_and_set_bit(AF_TASKLET_SCHEDULED, &a->flags)) 13338c2ecf20Sopenharmony_ci tasklet_hi_schedule(&a->tasklet); 13348c2ecf20Sopenharmony_ci} 13358c2ecf20Sopenharmony_ci 13368c2ecf20Sopenharmony_cistatic inline void esas2r_enable_heartbeat(struct esas2r_adapter *a) 13378c2ecf20Sopenharmony_ci{ 13388c2ecf20Sopenharmony_ci if (!test_bit(AF_DEGRADED_MODE, &a->flags) && 13398c2ecf20Sopenharmony_ci !test_bit(AF_CHPRST_PENDING, &a->flags) && 13408c2ecf20Sopenharmony_ci (a->nvram->options2 & SASNVR2_HEARTBEAT)) 13418c2ecf20Sopenharmony_ci set_bit(AF_HEARTBEAT_ENB, &a->flags); 13428c2ecf20Sopenharmony_ci else 13438c2ecf20Sopenharmony_ci clear_bit(AF_HEARTBEAT_ENB, &a->flags); 13448c2ecf20Sopenharmony_ci} 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_cistatic inline void esas2r_disable_heartbeat(struct esas2r_adapter *a) 13478c2ecf20Sopenharmony_ci{ 13488c2ecf20Sopenharmony_ci clear_bit(AF_HEARTBEAT_ENB, &a->flags); 13498c2ecf20Sopenharmony_ci clear_bit(AF_HEARTBEAT, &a->flags); 13508c2ecf20Sopenharmony_ci} 13518c2ecf20Sopenharmony_ci 13528c2ecf20Sopenharmony_ci/* Set the initial state for resetting the adapter on the next pass through 13538c2ecf20Sopenharmony_ci * esas2r_do_deferred. 13548c2ecf20Sopenharmony_ci */ 13558c2ecf20Sopenharmony_cistatic inline void esas2r_local_reset_adapter(struct esas2r_adapter *a) 13568c2ecf20Sopenharmony_ci{ 13578c2ecf20Sopenharmony_ci esas2r_disable_heartbeat(a); 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_ci set_bit(AF_CHPRST_NEEDED, &a->flags); 13608c2ecf20Sopenharmony_ci set_bit(AF_CHPRST_PENDING, &a->flags); 13618c2ecf20Sopenharmony_ci set_bit(AF_DISC_PENDING, &a->flags); 13628c2ecf20Sopenharmony_ci} 13638c2ecf20Sopenharmony_ci 13648c2ecf20Sopenharmony_ci/* See if an interrupt is pending on the adapter. */ 13658c2ecf20Sopenharmony_cistatic inline bool esas2r_adapter_interrupt_pending(struct esas2r_adapter *a) 13668c2ecf20Sopenharmony_ci{ 13678c2ecf20Sopenharmony_ci u32 intstat; 13688c2ecf20Sopenharmony_ci 13698c2ecf20Sopenharmony_ci if (a->int_mask == 0) 13708c2ecf20Sopenharmony_ci return false; 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT); 13738c2ecf20Sopenharmony_ci 13748c2ecf20Sopenharmony_ci if ((intstat & a->int_mask) == 0) 13758c2ecf20Sopenharmony_ci return false; 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_ci esas2r_disable_chip_interrupts(a); 13788c2ecf20Sopenharmony_ci 13798c2ecf20Sopenharmony_ci a->int_stat = intstat; 13808c2ecf20Sopenharmony_ci a->int_mask = 0; 13818c2ecf20Sopenharmony_ci 13828c2ecf20Sopenharmony_ci return true; 13838c2ecf20Sopenharmony_ci} 13848c2ecf20Sopenharmony_ci 13858c2ecf20Sopenharmony_cistatic inline u16 esas2r_targ_get_id(struct esas2r_target *t, 13868c2ecf20Sopenharmony_ci struct esas2r_adapter *a) 13878c2ecf20Sopenharmony_ci{ 13888c2ecf20Sopenharmony_ci return (u16)(uintptr_t)(t - a->targetdb); 13898c2ecf20Sopenharmony_ci} 13908c2ecf20Sopenharmony_ci 13918c2ecf20Sopenharmony_ci/* Build and start an asynchronous event request */ 13928c2ecf20Sopenharmony_cistatic inline void esas2r_start_ae_request(struct esas2r_adapter *a, 13938c2ecf20Sopenharmony_ci struct esas2r_request *rq) 13948c2ecf20Sopenharmony_ci{ 13958c2ecf20Sopenharmony_ci unsigned long flags; 13968c2ecf20Sopenharmony_ci 13978c2ecf20Sopenharmony_ci esas2r_build_ae_req(a, rq); 13988c2ecf20Sopenharmony_ci 13998c2ecf20Sopenharmony_ci spin_lock_irqsave(&a->queue_lock, flags); 14008c2ecf20Sopenharmony_ci esas2r_start_vda_request(a, rq); 14018c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&a->queue_lock, flags); 14028c2ecf20Sopenharmony_ci} 14038c2ecf20Sopenharmony_ci 14048c2ecf20Sopenharmony_cistatic inline void esas2r_comp_list_drain(struct esas2r_adapter *a, 14058c2ecf20Sopenharmony_ci struct list_head *comp_list) 14068c2ecf20Sopenharmony_ci{ 14078c2ecf20Sopenharmony_ci struct esas2r_request *rq; 14088c2ecf20Sopenharmony_ci struct list_head *element, *next; 14098c2ecf20Sopenharmony_ci 14108c2ecf20Sopenharmony_ci list_for_each_safe(element, next, comp_list) { 14118c2ecf20Sopenharmony_ci rq = list_entry(element, struct esas2r_request, comp_list); 14128c2ecf20Sopenharmony_ci list_del_init(element); 14138c2ecf20Sopenharmony_ci esas2r_complete_request(a, rq); 14148c2ecf20Sopenharmony_ci } 14158c2ecf20Sopenharmony_ci} 14168c2ecf20Sopenharmony_ci 14178c2ecf20Sopenharmony_ci/* sysfs handlers */ 14188c2ecf20Sopenharmony_ciextern struct bin_attribute bin_attr_fw; 14198c2ecf20Sopenharmony_ciextern struct bin_attribute bin_attr_fs; 14208c2ecf20Sopenharmony_ciextern struct bin_attribute bin_attr_vda; 14218c2ecf20Sopenharmony_ciextern struct bin_attribute bin_attr_hw; 14228c2ecf20Sopenharmony_ciextern struct bin_attribute bin_attr_live_nvram; 14238c2ecf20Sopenharmony_ciextern struct bin_attribute bin_attr_default_nvram; 14248c2ecf20Sopenharmony_ci 14258c2ecf20Sopenharmony_ci#endif /* ESAS2R_H */ 1426