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