1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * linux/drivers/scsi/esas2r/esas2r.h
3*4882a593Smuzhiyun * For use with ATTO ExpressSAS R6xx SAS/SATA RAID controllers
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (c) 2001-2013 ATTO Technology, Inc.
6*4882a593Smuzhiyun * (mailto:linuxdrivers@attotech.com)
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or
9*4882a593Smuzhiyun * modify it under the terms of the GNU General Public License
10*4882a593Smuzhiyun * as published by the Free Software Foundation; either version 2
11*4882a593Smuzhiyun * of the License, or (at your option) any later version.
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful,
14*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*4882a593Smuzhiyun * GNU General Public License for more details.
17*4882a593Smuzhiyun *
18*4882a593Smuzhiyun * NO WARRANTY
19*4882a593Smuzhiyun * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20*4882a593Smuzhiyun * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21*4882a593Smuzhiyun * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22*4882a593Smuzhiyun * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23*4882a593Smuzhiyun * solely responsible for determining the appropriateness of using and
24*4882a593Smuzhiyun * distributing the Program and assumes all risks associated with its
25*4882a593Smuzhiyun * exercise of rights under this Agreement, including but not limited to
26*4882a593Smuzhiyun * the risks and costs of program errors, damage to or loss of data,
27*4882a593Smuzhiyun * programs or equipment, and unavailability or interruption of operations.
28*4882a593Smuzhiyun *
29*4882a593Smuzhiyun * DISCLAIMER OF LIABILITY
30*4882a593Smuzhiyun * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
31*4882a593Smuzhiyun * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32*4882a593Smuzhiyun * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
33*4882a593Smuzhiyun * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34*4882a593Smuzhiyun * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35*4882a593Smuzhiyun * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
36*4882a593Smuzhiyun * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37*4882a593Smuzhiyun *
38*4882a593Smuzhiyun * You should have received a copy of the GNU General Public License
39*4882a593Smuzhiyun * along with this program; if not, write to the Free Software
40*4882a593Smuzhiyun * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41*4882a593Smuzhiyun * USA.
42*4882a593Smuzhiyun */
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #include <linux/kernel.h>
45*4882a593Smuzhiyun #include <linux/delay.h>
46*4882a593Smuzhiyun #include <linux/pci.h>
47*4882a593Smuzhiyun #include <linux/proc_fs.h>
48*4882a593Smuzhiyun #include <linux/workqueue.h>
49*4882a593Smuzhiyun #include <linux/interrupt.h>
50*4882a593Smuzhiyun #include <linux/module.h>
51*4882a593Smuzhiyun #include <linux/vmalloc.h>
52*4882a593Smuzhiyun #include <scsi/scsi.h>
53*4882a593Smuzhiyun #include <scsi/scsi_host.h>
54*4882a593Smuzhiyun #include <scsi/scsi_cmnd.h>
55*4882a593Smuzhiyun #include <scsi/scsi_device.h>
56*4882a593Smuzhiyun #include <scsi/scsi_eh.h>
57*4882a593Smuzhiyun #include <scsi/scsi_tcq.h>
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun #include "esas2r_log.h"
60*4882a593Smuzhiyun #include "atioctl.h"
61*4882a593Smuzhiyun #include "atvda.h"
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun #ifndef ESAS2R_H
64*4882a593Smuzhiyun #define ESAS2R_H
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun /* Global Variables */
67*4882a593Smuzhiyun extern struct esas2r_adapter *esas2r_adapters[];
68*4882a593Smuzhiyun extern u8 *esas2r_buffered_ioctl;
69*4882a593Smuzhiyun extern dma_addr_t esas2r_buffered_ioctl_addr;
70*4882a593Smuzhiyun extern u32 esas2r_buffered_ioctl_size;
71*4882a593Smuzhiyun extern struct pci_dev *esas2r_buffered_ioctl_pcid;
72*4882a593Smuzhiyun #define SGL_PG_SZ_MIN 64
73*4882a593Smuzhiyun #define SGL_PG_SZ_MAX 1024
74*4882a593Smuzhiyun extern int sgl_page_size;
75*4882a593Smuzhiyun #define NUM_SGL_MIN 8
76*4882a593Smuzhiyun #define NUM_SGL_MAX 2048
77*4882a593Smuzhiyun extern int num_sg_lists;
78*4882a593Smuzhiyun #define NUM_REQ_MIN 4
79*4882a593Smuzhiyun #define NUM_REQ_MAX 256
80*4882a593Smuzhiyun extern int num_requests;
81*4882a593Smuzhiyun #define NUM_AE_MIN 2
82*4882a593Smuzhiyun #define NUM_AE_MAX 8
83*4882a593Smuzhiyun extern int num_ae_requests;
84*4882a593Smuzhiyun extern int cmd_per_lun;
85*4882a593Smuzhiyun extern int can_queue;
86*4882a593Smuzhiyun extern int esas2r_max_sectors;
87*4882a593Smuzhiyun extern int sg_tablesize;
88*4882a593Smuzhiyun extern int interrupt_mode;
89*4882a593Smuzhiyun extern int num_io_requests;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* Macro defintions */
92*4882a593Smuzhiyun #define ESAS2R_MAX_ID 255
93*4882a593Smuzhiyun #define MAX_ADAPTERS 32
94*4882a593Smuzhiyun #define ESAS2R_DRVR_NAME "esas2r"
95*4882a593Smuzhiyun #define ESAS2R_LONGNAME "ATTO ExpressSAS 6GB RAID Adapter"
96*4882a593Smuzhiyun #define ESAS2R_MAX_DEVICES 32
97*4882a593Smuzhiyun #define ATTONODE_NAME "ATTONode"
98*4882a593Smuzhiyun #define ESAS2R_MAJOR_REV 1
99*4882a593Smuzhiyun #define ESAS2R_MINOR_REV 00
100*4882a593Smuzhiyun #define ESAS2R_VERSION_STR DEFINED_NUM_TO_STR(ESAS2R_MAJOR_REV) "." \
101*4882a593Smuzhiyun DEFINED_NUM_TO_STR(ESAS2R_MINOR_REV)
102*4882a593Smuzhiyun #define ESAS2R_COPYRIGHT_YEARS "2001-2013"
103*4882a593Smuzhiyun #define ESAS2R_DEFAULT_SGL_PAGE_SIZE 384
104*4882a593Smuzhiyun #define ESAS2R_DEFAULT_CMD_PER_LUN 64
105*4882a593Smuzhiyun #define ESAS2R_DEFAULT_NUM_SG_LISTS 1024
106*4882a593Smuzhiyun #define DEFINED_NUM_TO_STR(num) NUM_TO_STR(num)
107*4882a593Smuzhiyun #define NUM_TO_STR(num) #num
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun #define ESAS2R_SGL_ALIGN 16
110*4882a593Smuzhiyun #define ESAS2R_LIST_ALIGN 16
111*4882a593Smuzhiyun #define ESAS2R_LIST_EXTRA ESAS2R_NUM_EXTRA
112*4882a593Smuzhiyun #define ESAS2R_DATA_BUF_LEN 256
113*4882a593Smuzhiyun #define ESAS2R_DEFAULT_TMO 5000
114*4882a593Smuzhiyun #define ESAS2R_DISC_BUF_LEN 512
115*4882a593Smuzhiyun #define ESAS2R_FWCOREDUMP_SZ 0x80000
116*4882a593Smuzhiyun #define ESAS2R_NUM_PHYS 8
117*4882a593Smuzhiyun #define ESAS2R_TARG_ID_INV 0xFFFF
118*4882a593Smuzhiyun #define ESAS2R_INT_STS_MASK MU_INTSTAT_MASK
119*4882a593Smuzhiyun #define ESAS2R_INT_ENB_MASK MU_INTSTAT_MASK
120*4882a593Smuzhiyun #define ESAS2R_INT_DIS_MASK 0
121*4882a593Smuzhiyun #define ESAS2R_MAX_TARGETS 256
122*4882a593Smuzhiyun #define ESAS2R_KOBJ_NAME_LEN 20
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun /* u16 (WORD) component macros */
125*4882a593Smuzhiyun #define LOBYTE(w) ((u8)(u16)(w))
126*4882a593Smuzhiyun #define HIBYTE(w) ((u8)(((u16)(w)) >> 8))
127*4882a593Smuzhiyun #define MAKEWORD(lo, hi) ((u16)((u8)(lo) | ((u16)(u8)(hi) << 8)))
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun /* u32 (DWORD) component macros */
130*4882a593Smuzhiyun #define LOWORD(d) ((u16)(u32)(d))
131*4882a593Smuzhiyun #define HIWORD(d) ((u16)(((u32)(d)) >> 16))
132*4882a593Smuzhiyun #define MAKEDWORD(lo, hi) ((u32)((u16)(lo) | ((u32)(u16)(hi) << 16)))
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun /* macro to get the lowest nonzero bit of a value */
135*4882a593Smuzhiyun #define LOBIT(x) ((x) & (0 - (x)))
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun /* These functions are provided to access the chip's control registers.
138*4882a593Smuzhiyun * The register is specified by its byte offset from the register base
139*4882a593Smuzhiyun * for the adapter.
140*4882a593Smuzhiyun */
141*4882a593Smuzhiyun #define esas2r_read_register_dword(a, reg) \
142*4882a593Smuzhiyun readl((void __iomem *)a->regs + (reg) + MW_REG_OFFSET_HWREG)
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun #define esas2r_write_register_dword(a, reg, data) \
145*4882a593Smuzhiyun writel(data, (void __iomem *)(a->regs + (reg) + MW_REG_OFFSET_HWREG))
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun #define esas2r_flush_register_dword(a, r) esas2r_read_register_dword(a, r)
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /* This function is provided to access the chip's data window. The
150*4882a593Smuzhiyun * register is specified by its byte offset from the window base
151*4882a593Smuzhiyun * for the adapter.
152*4882a593Smuzhiyun */
153*4882a593Smuzhiyun #define esas2r_read_data_byte(a, reg) \
154*4882a593Smuzhiyun readb((void __iomem *)a->data_window + (reg))
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun /* ATTO vendor and device Ids */
157*4882a593Smuzhiyun #define ATTO_VENDOR_ID 0x117C
158*4882a593Smuzhiyun #define ATTO_DID_INTEL_IOP348 0x002C
159*4882a593Smuzhiyun #define ATTO_DID_MV_88RC9580 0x0049
160*4882a593Smuzhiyun #define ATTO_DID_MV_88RC9580TS 0x0066
161*4882a593Smuzhiyun #define ATTO_DID_MV_88RC9580TSE 0x0067
162*4882a593Smuzhiyun #define ATTO_DID_MV_88RC9580TL 0x0068
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /* ATTO subsystem device Ids */
165*4882a593Smuzhiyun #define ATTO_SSDID_TBT 0x4000
166*4882a593Smuzhiyun #define ATTO_TSSC_3808 0x4066
167*4882a593Smuzhiyun #define ATTO_TSSC_3808E 0x4067
168*4882a593Smuzhiyun #define ATTO_TLSH_1068 0x4068
169*4882a593Smuzhiyun #define ATTO_ESAS_R680 0x0049
170*4882a593Smuzhiyun #define ATTO_ESAS_R608 0x004A
171*4882a593Smuzhiyun #define ATTO_ESAS_R60F 0x004B
172*4882a593Smuzhiyun #define ATTO_ESAS_R6F0 0x004C
173*4882a593Smuzhiyun #define ATTO_ESAS_R644 0x004D
174*4882a593Smuzhiyun #define ATTO_ESAS_R648 0x004E
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun /*
177*4882a593Smuzhiyun * flash definitions & structures
178*4882a593Smuzhiyun * define the code types
179*4882a593Smuzhiyun */
180*4882a593Smuzhiyun #define FBT_CPYR 0xAA00
181*4882a593Smuzhiyun #define FBT_SETUP 0xAA02
182*4882a593Smuzhiyun #define FBT_FLASH_VER 0xAA04
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun /* offsets to various locations in flash */
185*4882a593Smuzhiyun #define FLS_OFFSET_BOOT (u32)(0x00700000)
186*4882a593Smuzhiyun #define FLS_OFFSET_NVR (u32)(0x007C0000)
187*4882a593Smuzhiyun #define FLS_OFFSET_CPYR FLS_OFFSET_NVR
188*4882a593Smuzhiyun #define FLS_LENGTH_BOOT (FLS_OFFSET_CPYR - FLS_OFFSET_BOOT)
189*4882a593Smuzhiyun #define FLS_BLOCK_SIZE (u32)(0x00020000)
190*4882a593Smuzhiyun #define FI_NVR_2KB 0x0800
191*4882a593Smuzhiyun #define FI_NVR_8KB 0x2000
192*4882a593Smuzhiyun #define FM_BUF_SZ 0x800
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /*
195*4882a593Smuzhiyun * marvell frey (88R9580) register definitions
196*4882a593Smuzhiyun * chip revision identifiers
197*4882a593Smuzhiyun */
198*4882a593Smuzhiyun #define MVR_FREY_B2 0xB2
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun /*
201*4882a593Smuzhiyun * memory window definitions. window 0 is the data window with definitions
202*4882a593Smuzhiyun * of MW_DATA_XXX. window 1 is the register window with definitions of
203*4882a593Smuzhiyun * MW_REG_XXX.
204*4882a593Smuzhiyun */
205*4882a593Smuzhiyun #define MW_REG_WINDOW_SIZE (u32)(0x00040000)
206*4882a593Smuzhiyun #define MW_REG_OFFSET_HWREG (u32)(0x00000000)
207*4882a593Smuzhiyun #define MW_REG_OFFSET_PCI (u32)(0x00008000)
208*4882a593Smuzhiyun #define MW_REG_PCI_HWREG_DELTA (MW_REG_OFFSET_PCI - MW_REG_OFFSET_HWREG)
209*4882a593Smuzhiyun #define MW_DATA_WINDOW_SIZE (u32)(0x00020000)
210*4882a593Smuzhiyun #define MW_DATA_ADDR_SER_FLASH (u32)(0xEC000000)
211*4882a593Smuzhiyun #define MW_DATA_ADDR_SRAM (u32)(0xF4000000)
212*4882a593Smuzhiyun #define MW_DATA_ADDR_PAR_FLASH (u32)(0xFC000000)
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun /*
215*4882a593Smuzhiyun * the following registers are for the communication
216*4882a593Smuzhiyun * list interface (AKA message unit (MU))
217*4882a593Smuzhiyun */
218*4882a593Smuzhiyun #define MU_IN_LIST_ADDR_LO (u32)(0x00004000)
219*4882a593Smuzhiyun #define MU_IN_LIST_ADDR_HI (u32)(0x00004004)
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun #define MU_IN_LIST_WRITE (u32)(0x00004018)
222*4882a593Smuzhiyun #define MU_ILW_TOGGLE (u32)(0x00004000)
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun #define MU_IN_LIST_READ (u32)(0x0000401C)
225*4882a593Smuzhiyun #define MU_ILR_TOGGLE (u32)(0x00004000)
226*4882a593Smuzhiyun #define MU_ILIC_LIST (u32)(0x0000000F)
227*4882a593Smuzhiyun #define MU_ILIC_LIST_F0 (u32)(0x00000000)
228*4882a593Smuzhiyun #define MU_ILIC_DEST (u32)(0x00000F00)
229*4882a593Smuzhiyun #define MU_ILIC_DEST_DDR (u32)(0x00000200)
230*4882a593Smuzhiyun #define MU_IN_LIST_IFC_CONFIG (u32)(0x00004028)
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun #define MU_IN_LIST_CONFIG (u32)(0x0000402C)
233*4882a593Smuzhiyun #define MU_ILC_ENABLE (u32)(0x00000001)
234*4882a593Smuzhiyun #define MU_ILC_ENTRY_MASK (u32)(0x000000F0)
235*4882a593Smuzhiyun #define MU_ILC_ENTRY_4_DW (u32)(0x00000020)
236*4882a593Smuzhiyun #define MU_ILC_DYNAMIC_SRC (u32)(0x00008000)
237*4882a593Smuzhiyun #define MU_ILC_NUMBER_MASK (u32)(0x7FFF0000)
238*4882a593Smuzhiyun #define MU_ILC_NUMBER_SHIFT 16
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun #define MU_OUT_LIST_ADDR_LO (u32)(0x00004050)
241*4882a593Smuzhiyun #define MU_OUT_LIST_ADDR_HI (u32)(0x00004054)
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun #define MU_OUT_LIST_COPY_PTR_LO (u32)(0x00004058)
244*4882a593Smuzhiyun #define MU_OUT_LIST_COPY_PTR_HI (u32)(0x0000405C)
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun #define MU_OUT_LIST_WRITE (u32)(0x00004068)
247*4882a593Smuzhiyun #define MU_OLW_TOGGLE (u32)(0x00004000)
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun #define MU_OUT_LIST_COPY (u32)(0x0000406C)
250*4882a593Smuzhiyun #define MU_OLC_TOGGLE (u32)(0x00004000)
251*4882a593Smuzhiyun #define MU_OLC_WRT_PTR (u32)(0x00003FFF)
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun #define MU_OUT_LIST_IFC_CONFIG (u32)(0x00004078)
254*4882a593Smuzhiyun #define MU_OLIC_LIST (u32)(0x0000000F)
255*4882a593Smuzhiyun #define MU_OLIC_LIST_F0 (u32)(0x00000000)
256*4882a593Smuzhiyun #define MU_OLIC_SOURCE (u32)(0x00000F00)
257*4882a593Smuzhiyun #define MU_OLIC_SOURCE_DDR (u32)(0x00000200)
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun #define MU_OUT_LIST_CONFIG (u32)(0x0000407C)
260*4882a593Smuzhiyun #define MU_OLC_ENABLE (u32)(0x00000001)
261*4882a593Smuzhiyun #define MU_OLC_ENTRY_MASK (u32)(0x000000F0)
262*4882a593Smuzhiyun #define MU_OLC_ENTRY_4_DW (u32)(0x00000020)
263*4882a593Smuzhiyun #define MU_OLC_NUMBER_MASK (u32)(0x7FFF0000)
264*4882a593Smuzhiyun #define MU_OLC_NUMBER_SHIFT 16
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun #define MU_OUT_LIST_INT_STAT (u32)(0x00004088)
267*4882a593Smuzhiyun #define MU_OLIS_INT (u32)(0x00000001)
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun #define MU_OUT_LIST_INT_MASK (u32)(0x0000408C)
270*4882a593Smuzhiyun #define MU_OLIS_MASK (u32)(0x00000001)
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun /*
273*4882a593Smuzhiyun * the maximum size of the communication lists is two greater than the
274*4882a593Smuzhiyun * maximum amount of VDA requests. the extra are to prevent queue overflow.
275*4882a593Smuzhiyun */
276*4882a593Smuzhiyun #define ESAS2R_MAX_NUM_REQS 256
277*4882a593Smuzhiyun #define ESAS2R_NUM_EXTRA 2
278*4882a593Smuzhiyun #define ESAS2R_MAX_COMM_LIST_SIZE (ESAS2R_MAX_NUM_REQS + ESAS2R_NUM_EXTRA)
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun /*
281*4882a593Smuzhiyun * the following registers are for the CPU interface
282*4882a593Smuzhiyun */
283*4882a593Smuzhiyun #define MU_CTL_STATUS_IN (u32)(0x00010108)
284*4882a593Smuzhiyun #define MU_CTL_IN_FULL_RST (u32)(0x00000020)
285*4882a593Smuzhiyun #define MU_CTL_STATUS_IN_B2 (u32)(0x00010130)
286*4882a593Smuzhiyun #define MU_CTL_IN_FULL_RST2 (u32)(0x80000000)
287*4882a593Smuzhiyun #define MU_DOORBELL_IN (u32)(0x00010460)
288*4882a593Smuzhiyun #define DRBL_RESET_BUS (u32)(0x00000002)
289*4882a593Smuzhiyun #define DRBL_PAUSE_AE (u32)(0x00000004)
290*4882a593Smuzhiyun #define DRBL_RESUME_AE (u32)(0x00000008)
291*4882a593Smuzhiyun #define DRBL_MSG_IFC_DOWN (u32)(0x00000010)
292*4882a593Smuzhiyun #define DRBL_FLASH_REQ (u32)(0x00000020)
293*4882a593Smuzhiyun #define DRBL_FLASH_DONE (u32)(0x00000040)
294*4882a593Smuzhiyun #define DRBL_FORCE_INT (u32)(0x00000080)
295*4882a593Smuzhiyun #define DRBL_MSG_IFC_INIT (u32)(0x00000100)
296*4882a593Smuzhiyun #define DRBL_POWER_DOWN (u32)(0x00000200)
297*4882a593Smuzhiyun #define DRBL_DRV_VER_1 (u32)(0x00010000)
298*4882a593Smuzhiyun #define DRBL_DRV_VER DRBL_DRV_VER_1
299*4882a593Smuzhiyun #define MU_DOORBELL_IN_ENB (u32)(0x00010464)
300*4882a593Smuzhiyun #define MU_DOORBELL_OUT (u32)(0x00010480)
301*4882a593Smuzhiyun #define DRBL_PANIC_REASON_MASK (u32)(0x00F00000)
302*4882a593Smuzhiyun #define DRBL_UNUSED_HANDLER (u32)(0x00100000)
303*4882a593Smuzhiyun #define DRBL_UNDEF_INSTR (u32)(0x00200000)
304*4882a593Smuzhiyun #define DRBL_PREFETCH_ABORT (u32)(0x00300000)
305*4882a593Smuzhiyun #define DRBL_DATA_ABORT (u32)(0x00400000)
306*4882a593Smuzhiyun #define DRBL_JUMP_TO_ZERO (u32)(0x00500000)
307*4882a593Smuzhiyun #define DRBL_FW_RESET (u32)(0x00080000)
308*4882a593Smuzhiyun #define DRBL_FW_VER_MSK (u32)(0x00070000)
309*4882a593Smuzhiyun #define DRBL_FW_VER_0 (u32)(0x00000000)
310*4882a593Smuzhiyun #define DRBL_FW_VER_1 (u32)(0x00010000)
311*4882a593Smuzhiyun #define DRBL_FW_VER DRBL_FW_VER_1
312*4882a593Smuzhiyun #define MU_DOORBELL_OUT_ENB (u32)(0x00010484)
313*4882a593Smuzhiyun #define DRBL_ENB_MASK (u32)(0x00F803FF)
314*4882a593Smuzhiyun #define MU_INT_STATUS_OUT (u32)(0x00010200)
315*4882a593Smuzhiyun #define MU_INTSTAT_POST_OUT (u32)(0x00000010)
316*4882a593Smuzhiyun #define MU_INTSTAT_DRBL_IN (u32)(0x00000100)
317*4882a593Smuzhiyun #define MU_INTSTAT_DRBL (u32)(0x00001000)
318*4882a593Smuzhiyun #define MU_INTSTAT_MASK (u32)(0x00001010)
319*4882a593Smuzhiyun #define MU_INT_MASK_OUT (u32)(0x0001020C)
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun /* PCI express registers accessed via window 1 */
322*4882a593Smuzhiyun #define MVR_PCI_WIN1_REMAP (u32)(0x00008438)
323*4882a593Smuzhiyun #define MVRPW1R_ENABLE (u32)(0x00000001)
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun /* structures */
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun /* inbound list dynamic source entry */
329*4882a593Smuzhiyun struct esas2r_inbound_list_source_entry {
330*4882a593Smuzhiyun u64 address;
331*4882a593Smuzhiyun u32 length;
332*4882a593Smuzhiyun #define HWILSE_INTERFACE_F0 0x00000000
333*4882a593Smuzhiyun u32 reserved;
334*4882a593Smuzhiyun };
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun /* PCI data structure in expansion ROM images */
337*4882a593Smuzhiyun struct __packed esas2r_boot_header {
338*4882a593Smuzhiyun char signature[4];
339*4882a593Smuzhiyun u16 vendor_id;
340*4882a593Smuzhiyun u16 device_id;
341*4882a593Smuzhiyun u16 VPD;
342*4882a593Smuzhiyun u16 struct_length;
343*4882a593Smuzhiyun u8 struct_revision;
344*4882a593Smuzhiyun u8 class_code[3];
345*4882a593Smuzhiyun u16 image_length;
346*4882a593Smuzhiyun u16 code_revision;
347*4882a593Smuzhiyun u8 code_type;
348*4882a593Smuzhiyun #define CODE_TYPE_PC 0
349*4882a593Smuzhiyun #define CODE_TYPE_OPEN 1
350*4882a593Smuzhiyun #define CODE_TYPE_EFI 3
351*4882a593Smuzhiyun u8 indicator;
352*4882a593Smuzhiyun #define INDICATOR_LAST 0x80
353*4882a593Smuzhiyun u8 reserved[2];
354*4882a593Smuzhiyun };
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun struct __packed esas2r_boot_image {
357*4882a593Smuzhiyun u16 signature;
358*4882a593Smuzhiyun u8 reserved[22];
359*4882a593Smuzhiyun u16 header_offset;
360*4882a593Smuzhiyun u16 pnp_offset;
361*4882a593Smuzhiyun };
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun struct __packed esas2r_pc_image {
364*4882a593Smuzhiyun u16 signature;
365*4882a593Smuzhiyun u8 length;
366*4882a593Smuzhiyun u8 entry_point[3];
367*4882a593Smuzhiyun u8 checksum;
368*4882a593Smuzhiyun u16 image_end;
369*4882a593Smuzhiyun u16 min_size;
370*4882a593Smuzhiyun u8 rom_flags;
371*4882a593Smuzhiyun u8 reserved[12];
372*4882a593Smuzhiyun u16 header_offset;
373*4882a593Smuzhiyun u16 pnp_offset;
374*4882a593Smuzhiyun struct esas2r_boot_header boot_image;
375*4882a593Smuzhiyun };
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun struct __packed esas2r_efi_image {
378*4882a593Smuzhiyun u16 signature;
379*4882a593Smuzhiyun u16 length;
380*4882a593Smuzhiyun u32 efi_signature;
381*4882a593Smuzhiyun #define EFI_ROM_SIG 0x00000EF1
382*4882a593Smuzhiyun u16 image_type;
383*4882a593Smuzhiyun #define EFI_IMAGE_APP 10
384*4882a593Smuzhiyun #define EFI_IMAGE_BSD 11
385*4882a593Smuzhiyun #define EFI_IMAGE_RTD 12
386*4882a593Smuzhiyun u16 machine_type;
387*4882a593Smuzhiyun #define EFI_MACHINE_IA32 0x014c
388*4882a593Smuzhiyun #define EFI_MACHINE_IA64 0x0200
389*4882a593Smuzhiyun #define EFI_MACHINE_X64 0x8664
390*4882a593Smuzhiyun #define EFI_MACHINE_EBC 0x0EBC
391*4882a593Smuzhiyun u16 compression;
392*4882a593Smuzhiyun #define EFI_UNCOMPRESSED 0x0000
393*4882a593Smuzhiyun #define EFI_COMPRESSED 0x0001
394*4882a593Smuzhiyun u8 reserved[8];
395*4882a593Smuzhiyun u16 efi_offset;
396*4882a593Smuzhiyun u16 header_offset;
397*4882a593Smuzhiyun u16 reserved2;
398*4882a593Smuzhiyun struct esas2r_boot_header boot_image;
399*4882a593Smuzhiyun };
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun struct esas2r_adapter;
402*4882a593Smuzhiyun struct esas2r_sg_context;
403*4882a593Smuzhiyun struct esas2r_request;
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun typedef void (*RQCALLBK) (struct esas2r_adapter *a,
406*4882a593Smuzhiyun struct esas2r_request *rq);
407*4882a593Smuzhiyun typedef bool (*RQBUILDSGL) (struct esas2r_adapter *a,
408*4882a593Smuzhiyun struct esas2r_sg_context *sgc);
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun struct esas2r_component_header {
411*4882a593Smuzhiyun u8 img_type;
412*4882a593Smuzhiyun #define CH_IT_FW 0x00
413*4882a593Smuzhiyun #define CH_IT_NVR 0x01
414*4882a593Smuzhiyun #define CH_IT_BIOS 0x02
415*4882a593Smuzhiyun #define CH_IT_MAC 0x03
416*4882a593Smuzhiyun #define CH_IT_CFG 0x04
417*4882a593Smuzhiyun #define CH_IT_EFI 0x05
418*4882a593Smuzhiyun u8 status;
419*4882a593Smuzhiyun #define CH_STAT_PENDING 0xff
420*4882a593Smuzhiyun #define CH_STAT_FAILED 0x00
421*4882a593Smuzhiyun #define CH_STAT_SUCCESS 0x01
422*4882a593Smuzhiyun #define CH_STAT_RETRY 0x02
423*4882a593Smuzhiyun #define CH_STAT_INVALID 0x03
424*4882a593Smuzhiyun u8 pad[2];
425*4882a593Smuzhiyun u32 version;
426*4882a593Smuzhiyun u32 length;
427*4882a593Smuzhiyun u32 image_offset;
428*4882a593Smuzhiyun };
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun #define FI_REL_VER_SZ 16
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun struct esas2r_flash_img_v0 {
433*4882a593Smuzhiyun u8 fi_version;
434*4882a593Smuzhiyun #define FI_VERSION_0 00
435*4882a593Smuzhiyun u8 status;
436*4882a593Smuzhiyun u8 adap_typ;
437*4882a593Smuzhiyun u8 action;
438*4882a593Smuzhiyun u32 length;
439*4882a593Smuzhiyun u16 checksum;
440*4882a593Smuzhiyun u16 driver_error;
441*4882a593Smuzhiyun u16 flags;
442*4882a593Smuzhiyun u16 num_comps;
443*4882a593Smuzhiyun #define FI_NUM_COMPS_V0 5
444*4882a593Smuzhiyun u8 rel_version[FI_REL_VER_SZ];
445*4882a593Smuzhiyun struct esas2r_component_header cmp_hdr[FI_NUM_COMPS_V0];
446*4882a593Smuzhiyun u8 scratch_buf[FM_BUF_SZ];
447*4882a593Smuzhiyun };
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun struct esas2r_flash_img {
450*4882a593Smuzhiyun u8 fi_version;
451*4882a593Smuzhiyun #define FI_VERSION_1 01
452*4882a593Smuzhiyun u8 status;
453*4882a593Smuzhiyun #define FI_STAT_SUCCESS 0x00
454*4882a593Smuzhiyun #define FI_STAT_FAILED 0x01
455*4882a593Smuzhiyun #define FI_STAT_REBOOT 0x02
456*4882a593Smuzhiyun #define FI_STAT_ADAPTYP 0x03
457*4882a593Smuzhiyun #define FI_STAT_INVALID 0x04
458*4882a593Smuzhiyun #define FI_STAT_CHKSUM 0x05
459*4882a593Smuzhiyun #define FI_STAT_LENGTH 0x06
460*4882a593Smuzhiyun #define FI_STAT_UNKNOWN 0x07
461*4882a593Smuzhiyun #define FI_STAT_IMG_VER 0x08
462*4882a593Smuzhiyun #define FI_STAT_BUSY 0x09
463*4882a593Smuzhiyun #define FI_STAT_DUAL 0x0A
464*4882a593Smuzhiyun #define FI_STAT_MISSING 0x0B
465*4882a593Smuzhiyun #define FI_STAT_UNSUPP 0x0C
466*4882a593Smuzhiyun #define FI_STAT_ERASE 0x0D
467*4882a593Smuzhiyun #define FI_STAT_FLASH 0x0E
468*4882a593Smuzhiyun #define FI_STAT_DEGRADED 0x0F
469*4882a593Smuzhiyun u8 adap_typ;
470*4882a593Smuzhiyun #define FI_AT_UNKNWN 0xFF
471*4882a593Smuzhiyun #define FI_AT_SUN_LAKE 0x0B
472*4882a593Smuzhiyun #define FI_AT_MV_9580 0x0F
473*4882a593Smuzhiyun u8 action;
474*4882a593Smuzhiyun #define FI_ACT_DOWN 0x00
475*4882a593Smuzhiyun #define FI_ACT_UP 0x01
476*4882a593Smuzhiyun #define FI_ACT_UPSZ 0x02
477*4882a593Smuzhiyun #define FI_ACT_MAX 0x02
478*4882a593Smuzhiyun #define FI_ACT_DOWN1 0x80
479*4882a593Smuzhiyun u32 length;
480*4882a593Smuzhiyun u16 checksum;
481*4882a593Smuzhiyun u16 driver_error;
482*4882a593Smuzhiyun u16 flags;
483*4882a593Smuzhiyun #define FI_FLG_NVR_DEF 0x0001
484*4882a593Smuzhiyun u16 num_comps;
485*4882a593Smuzhiyun #define FI_NUM_COMPS_V1 6
486*4882a593Smuzhiyun u8 rel_version[FI_REL_VER_SZ];
487*4882a593Smuzhiyun struct esas2r_component_header cmp_hdr[FI_NUM_COMPS_V1];
488*4882a593Smuzhiyun u8 scratch_buf[FM_BUF_SZ];
489*4882a593Smuzhiyun };
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun /* definitions for flash script (FS) commands */
492*4882a593Smuzhiyun struct esas2r_ioctlfs_command {
493*4882a593Smuzhiyun u8 command;
494*4882a593Smuzhiyun #define ESAS2R_FS_CMD_ERASE 0
495*4882a593Smuzhiyun #define ESAS2R_FS_CMD_READ 1
496*4882a593Smuzhiyun #define ESAS2R_FS_CMD_BEGINW 2
497*4882a593Smuzhiyun #define ESAS2R_FS_CMD_WRITE 3
498*4882a593Smuzhiyun #define ESAS2R_FS_CMD_COMMIT 4
499*4882a593Smuzhiyun #define ESAS2R_FS_CMD_CANCEL 5
500*4882a593Smuzhiyun u8 checksum;
501*4882a593Smuzhiyun u8 reserved[2];
502*4882a593Smuzhiyun u32 flash_addr;
503*4882a593Smuzhiyun u32 length;
504*4882a593Smuzhiyun u32 image_offset;
505*4882a593Smuzhiyun };
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun struct esas2r_ioctl_fs {
508*4882a593Smuzhiyun u8 version;
509*4882a593Smuzhiyun #define ESAS2R_FS_VER 0
510*4882a593Smuzhiyun u8 status;
511*4882a593Smuzhiyun u8 driver_error;
512*4882a593Smuzhiyun u8 adap_type;
513*4882a593Smuzhiyun #define ESAS2R_FS_AT_ESASRAID2 3
514*4882a593Smuzhiyun #define ESAS2R_FS_AT_TSSASRAID2 4
515*4882a593Smuzhiyun #define ESAS2R_FS_AT_TSSASRAID2E 5
516*4882a593Smuzhiyun #define ESAS2R_FS_AT_TLSASHBA 6
517*4882a593Smuzhiyun u8 driver_ver;
518*4882a593Smuzhiyun u8 reserved[11];
519*4882a593Smuzhiyun struct esas2r_ioctlfs_command command;
520*4882a593Smuzhiyun u8 data[1];
521*4882a593Smuzhiyun };
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun struct esas2r_sas_nvram {
524*4882a593Smuzhiyun u8 signature[4];
525*4882a593Smuzhiyun u8 version;
526*4882a593Smuzhiyun #define SASNVR_VERSION_0 0x00
527*4882a593Smuzhiyun #define SASNVR_VERSION SASNVR_VERSION_0
528*4882a593Smuzhiyun u8 checksum;
529*4882a593Smuzhiyun #define SASNVR_CKSUM_SEED 0x5A
530*4882a593Smuzhiyun u8 max_lun_for_target;
531*4882a593Smuzhiyun u8 pci_latency;
532*4882a593Smuzhiyun #define SASNVR_PCILAT_DIS 0x00
533*4882a593Smuzhiyun #define SASNVR_PCILAT_MIN 0x10
534*4882a593Smuzhiyun #define SASNVR_PCILAT_MAX 0xF8
535*4882a593Smuzhiyun u8 options1;
536*4882a593Smuzhiyun #define SASNVR1_BOOT_DRVR 0x01
537*4882a593Smuzhiyun #define SASNVR1_BOOT_SCAN 0x02
538*4882a593Smuzhiyun #define SASNVR1_DIS_PCI_MWI 0x04
539*4882a593Smuzhiyun #define SASNVR1_FORCE_ORD_Q 0x08
540*4882a593Smuzhiyun #define SASNVR1_CACHELINE_0 0x10
541*4882a593Smuzhiyun #define SASNVR1_DIS_DEVSORT 0x20
542*4882a593Smuzhiyun #define SASNVR1_PWR_MGT_EN 0x40
543*4882a593Smuzhiyun #define SASNVR1_WIDEPORT 0x80
544*4882a593Smuzhiyun u8 options2;
545*4882a593Smuzhiyun #define SASNVR2_SINGLE_BUS 0x01
546*4882a593Smuzhiyun #define SASNVR2_SLOT_BIND 0x02
547*4882a593Smuzhiyun #define SASNVR2_EXP_PROG 0x04
548*4882a593Smuzhiyun #define SASNVR2_CMDTHR_LUN 0x08
549*4882a593Smuzhiyun #define SASNVR2_HEARTBEAT 0x10
550*4882a593Smuzhiyun #define SASNVR2_INT_CONNECT 0x20
551*4882a593Smuzhiyun #define SASNVR2_SW_MUX_CTRL 0x40
552*4882a593Smuzhiyun #define SASNVR2_DISABLE_NCQ 0x80
553*4882a593Smuzhiyun u8 int_coalescing;
554*4882a593Smuzhiyun #define SASNVR_COAL_DIS 0x00
555*4882a593Smuzhiyun #define SASNVR_COAL_LOW 0x01
556*4882a593Smuzhiyun #define SASNVR_COAL_MED 0x02
557*4882a593Smuzhiyun #define SASNVR_COAL_HI 0x03
558*4882a593Smuzhiyun u8 cmd_throttle;
559*4882a593Smuzhiyun #define SASNVR_CMDTHR_NONE 0x00
560*4882a593Smuzhiyun u8 dev_wait_time;
561*4882a593Smuzhiyun u8 dev_wait_count;
562*4882a593Smuzhiyun u8 spin_up_delay;
563*4882a593Smuzhiyun #define SASNVR_SPINUP_MAX 0x14
564*4882a593Smuzhiyun u8 ssp_align_rate;
565*4882a593Smuzhiyun u8 sas_addr[8];
566*4882a593Smuzhiyun u8 phy_speed[16];
567*4882a593Smuzhiyun #define SASNVR_SPEED_AUTO 0x00
568*4882a593Smuzhiyun #define SASNVR_SPEED_1_5GB 0x01
569*4882a593Smuzhiyun #define SASNVR_SPEED_3GB 0x02
570*4882a593Smuzhiyun #define SASNVR_SPEED_6GB 0x03
571*4882a593Smuzhiyun #define SASNVR_SPEED_12GB 0x04
572*4882a593Smuzhiyun u8 phy_mux[16];
573*4882a593Smuzhiyun #define SASNVR_MUX_DISABLED 0x00
574*4882a593Smuzhiyun #define SASNVR_MUX_1_5GB 0x01
575*4882a593Smuzhiyun #define SASNVR_MUX_3GB 0x02
576*4882a593Smuzhiyun #define SASNVR_MUX_6GB 0x03
577*4882a593Smuzhiyun u8 phy_flags[16];
578*4882a593Smuzhiyun #define SASNVR_PHF_DISABLED 0x01
579*4882a593Smuzhiyun #define SASNVR_PHF_RD_ONLY 0x02
580*4882a593Smuzhiyun u8 sort_type;
581*4882a593Smuzhiyun #define SASNVR_SORT_SAS_ADDR 0x00
582*4882a593Smuzhiyun #define SASNVR_SORT_H308_CONN 0x01
583*4882a593Smuzhiyun #define SASNVR_SORT_PHY_ID 0x02
584*4882a593Smuzhiyun #define SASNVR_SORT_SLOT_ID 0x03
585*4882a593Smuzhiyun u8 dpm_reqcmd_lmt;
586*4882a593Smuzhiyun u8 dpm_stndby_time;
587*4882a593Smuzhiyun u8 dpm_active_time;
588*4882a593Smuzhiyun u8 phy_target_id[16];
589*4882a593Smuzhiyun #define SASNVR_PTI_DISABLED 0xFF
590*4882a593Smuzhiyun u8 virt_ses_mode;
591*4882a593Smuzhiyun #define SASNVR_VSMH_DISABLED 0x00
592*4882a593Smuzhiyun u8 read_write_mode;
593*4882a593Smuzhiyun #define SASNVR_RWM_DEFAULT 0x00
594*4882a593Smuzhiyun u8 link_down_to;
595*4882a593Smuzhiyun u8 reserved[0xA1];
596*4882a593Smuzhiyun };
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun typedef u32 (*PGETPHYSADDR) (struct esas2r_sg_context *sgc, u64 *addr);
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun struct esas2r_sg_context {
601*4882a593Smuzhiyun struct esas2r_adapter *adapter;
602*4882a593Smuzhiyun struct esas2r_request *first_req;
603*4882a593Smuzhiyun u32 length;
604*4882a593Smuzhiyun u8 *cur_offset;
605*4882a593Smuzhiyun PGETPHYSADDR get_phys_addr;
606*4882a593Smuzhiyun union {
607*4882a593Smuzhiyun struct {
608*4882a593Smuzhiyun struct atto_vda_sge *curr;
609*4882a593Smuzhiyun struct atto_vda_sge *last;
610*4882a593Smuzhiyun struct atto_vda_sge *limit;
611*4882a593Smuzhiyun struct atto_vda_sge *chain;
612*4882a593Smuzhiyun } a64;
613*4882a593Smuzhiyun struct {
614*4882a593Smuzhiyun struct atto_physical_region_description *curr;
615*4882a593Smuzhiyun struct atto_physical_region_description *chain;
616*4882a593Smuzhiyun u32 sgl_max_cnt;
617*4882a593Smuzhiyun u32 sge_cnt;
618*4882a593Smuzhiyun } prd;
619*4882a593Smuzhiyun } sge;
620*4882a593Smuzhiyun struct scatterlist *cur_sgel;
621*4882a593Smuzhiyun u8 *exp_offset;
622*4882a593Smuzhiyun int num_sgel;
623*4882a593Smuzhiyun int sgel_count;
624*4882a593Smuzhiyun };
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun struct esas2r_target {
627*4882a593Smuzhiyun u8 flags;
628*4882a593Smuzhiyun #define TF_PASS_THRU 0x01
629*4882a593Smuzhiyun #define TF_USED 0x02
630*4882a593Smuzhiyun u8 new_target_state;
631*4882a593Smuzhiyun u8 target_state;
632*4882a593Smuzhiyun u8 buffered_target_state;
633*4882a593Smuzhiyun #define TS_NOT_PRESENT 0x00
634*4882a593Smuzhiyun #define TS_PRESENT 0x05
635*4882a593Smuzhiyun #define TS_LUN_CHANGE 0x06
636*4882a593Smuzhiyun #define TS_INVALID 0xFF
637*4882a593Smuzhiyun u32 block_size;
638*4882a593Smuzhiyun u32 inter_block;
639*4882a593Smuzhiyun u32 inter_byte;
640*4882a593Smuzhiyun u16 virt_targ_id;
641*4882a593Smuzhiyun u16 phys_targ_id;
642*4882a593Smuzhiyun u8 identifier_len;
643*4882a593Smuzhiyun u64 sas_addr;
644*4882a593Smuzhiyun u8 identifier[60];
645*4882a593Smuzhiyun struct atto_vda_ae_lu lu_event;
646*4882a593Smuzhiyun };
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun struct esas2r_request {
649*4882a593Smuzhiyun struct list_head comp_list;
650*4882a593Smuzhiyun struct list_head req_list;
651*4882a593Smuzhiyun union atto_vda_req *vrq;
652*4882a593Smuzhiyun struct esas2r_mem_desc *vrq_md;
653*4882a593Smuzhiyun union {
654*4882a593Smuzhiyun void *data_buf;
655*4882a593Smuzhiyun union atto_vda_rsp_data *vda_rsp_data;
656*4882a593Smuzhiyun };
657*4882a593Smuzhiyun u8 *sense_buf;
658*4882a593Smuzhiyun struct list_head sg_table_head;
659*4882a593Smuzhiyun struct esas2r_mem_desc *sg_table;
660*4882a593Smuzhiyun u32 timeout;
661*4882a593Smuzhiyun #define RQ_TIMEOUT_S1 0xFFFFFFFF
662*4882a593Smuzhiyun #define RQ_TIMEOUT_S2 0xFFFFFFFE
663*4882a593Smuzhiyun #define RQ_MAX_TIMEOUT 0xFFFFFFFD
664*4882a593Smuzhiyun u16 target_id;
665*4882a593Smuzhiyun u8 req_type;
666*4882a593Smuzhiyun #define RT_INI_REQ 0x01
667*4882a593Smuzhiyun #define RT_DISC_REQ 0x02
668*4882a593Smuzhiyun u8 sense_len;
669*4882a593Smuzhiyun union atto_vda_func_rsp func_rsp;
670*4882a593Smuzhiyun RQCALLBK comp_cb;
671*4882a593Smuzhiyun RQCALLBK interrupt_cb;
672*4882a593Smuzhiyun void *interrupt_cx;
673*4882a593Smuzhiyun u8 flags;
674*4882a593Smuzhiyun #define RF_1ST_IBLK_BASE 0x04
675*4882a593Smuzhiyun #define RF_FAILURE_OK 0x08
676*4882a593Smuzhiyun u8 req_stat;
677*4882a593Smuzhiyun u16 vda_req_sz;
678*4882a593Smuzhiyun #define RQ_SIZE_DEFAULT 0
679*4882a593Smuzhiyun u64 lba;
680*4882a593Smuzhiyun RQCALLBK aux_req_cb;
681*4882a593Smuzhiyun void *aux_req_cx;
682*4882a593Smuzhiyun u32 blk_len;
683*4882a593Smuzhiyun u32 max_blk_len;
684*4882a593Smuzhiyun union {
685*4882a593Smuzhiyun struct scsi_cmnd *cmd;
686*4882a593Smuzhiyun u8 *task_management_status_ptr;
687*4882a593Smuzhiyun };
688*4882a593Smuzhiyun };
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun struct esas2r_flash_context {
691*4882a593Smuzhiyun struct esas2r_flash_img *fi;
692*4882a593Smuzhiyun RQCALLBK interrupt_cb;
693*4882a593Smuzhiyun u8 *sgc_offset;
694*4882a593Smuzhiyun u8 *scratch;
695*4882a593Smuzhiyun u32 fi_hdr_len;
696*4882a593Smuzhiyun u8 task;
697*4882a593Smuzhiyun #define FMTSK_ERASE_BOOT 0
698*4882a593Smuzhiyun #define FMTSK_WRTBIOS 1
699*4882a593Smuzhiyun #define FMTSK_READBIOS 2
700*4882a593Smuzhiyun #define FMTSK_WRTMAC 3
701*4882a593Smuzhiyun #define FMTSK_READMAC 4
702*4882a593Smuzhiyun #define FMTSK_WRTEFI 5
703*4882a593Smuzhiyun #define FMTSK_READEFI 6
704*4882a593Smuzhiyun #define FMTSK_WRTCFG 7
705*4882a593Smuzhiyun #define FMTSK_READCFG 8
706*4882a593Smuzhiyun u8 func;
707*4882a593Smuzhiyun u16 num_comps;
708*4882a593Smuzhiyun u32 cmp_len;
709*4882a593Smuzhiyun u32 flsh_addr;
710*4882a593Smuzhiyun u32 curr_len;
711*4882a593Smuzhiyun u8 comp_typ;
712*4882a593Smuzhiyun struct esas2r_sg_context sgc;
713*4882a593Smuzhiyun };
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun struct esas2r_disc_context {
716*4882a593Smuzhiyun u8 disc_evt;
717*4882a593Smuzhiyun #define DCDE_DEV_CHANGE 0x01
718*4882a593Smuzhiyun #define DCDE_DEV_SCAN 0x02
719*4882a593Smuzhiyun u8 state;
720*4882a593Smuzhiyun #define DCS_DEV_RMV 0x00
721*4882a593Smuzhiyun #define DCS_DEV_ADD 0x01
722*4882a593Smuzhiyun #define DCS_BLOCK_DEV_SCAN 0x02
723*4882a593Smuzhiyun #define DCS_RAID_GRP_INFO 0x03
724*4882a593Smuzhiyun #define DCS_PART_INFO 0x04
725*4882a593Smuzhiyun #define DCS_PT_DEV_INFO 0x05
726*4882a593Smuzhiyun #define DCS_PT_DEV_ADDR 0x06
727*4882a593Smuzhiyun #define DCS_DISC_DONE 0xFF
728*4882a593Smuzhiyun u16 flags;
729*4882a593Smuzhiyun #define DCF_DEV_CHANGE 0x0001
730*4882a593Smuzhiyun #define DCF_DEV_SCAN 0x0002
731*4882a593Smuzhiyun #define DCF_POLLED 0x8000
732*4882a593Smuzhiyun u32 interleave;
733*4882a593Smuzhiyun u32 block_size;
734*4882a593Smuzhiyun u16 dev_ix;
735*4882a593Smuzhiyun u8 part_num;
736*4882a593Smuzhiyun u8 raid_grp_ix;
737*4882a593Smuzhiyun char raid_grp_name[16];
738*4882a593Smuzhiyun struct esas2r_target *curr_targ;
739*4882a593Smuzhiyun u16 curr_virt_id;
740*4882a593Smuzhiyun u16 curr_phys_id;
741*4882a593Smuzhiyun u8 scan_gen;
742*4882a593Smuzhiyun u8 dev_addr_type;
743*4882a593Smuzhiyun u64 sas_addr;
744*4882a593Smuzhiyun };
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun struct esas2r_mem_desc {
747*4882a593Smuzhiyun struct list_head next_desc;
748*4882a593Smuzhiyun void *virt_addr;
749*4882a593Smuzhiyun u64 phys_addr;
750*4882a593Smuzhiyun void *pad;
751*4882a593Smuzhiyun void *esas2r_data;
752*4882a593Smuzhiyun u32 esas2r_param;
753*4882a593Smuzhiyun u32 size;
754*4882a593Smuzhiyun };
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun enum fw_event_type {
757*4882a593Smuzhiyun fw_event_null,
758*4882a593Smuzhiyun fw_event_lun_change,
759*4882a593Smuzhiyun fw_event_present,
760*4882a593Smuzhiyun fw_event_not_present,
761*4882a593Smuzhiyun fw_event_vda_ae
762*4882a593Smuzhiyun };
763*4882a593Smuzhiyun
764*4882a593Smuzhiyun struct esas2r_vda_ae {
765*4882a593Smuzhiyun u32 signature;
766*4882a593Smuzhiyun #define ESAS2R_VDA_EVENT_SIG 0x4154544F
767*4882a593Smuzhiyun u8 bus_number;
768*4882a593Smuzhiyun u8 devfn;
769*4882a593Smuzhiyun u8 pad[2];
770*4882a593Smuzhiyun union atto_vda_ae vda_ae;
771*4882a593Smuzhiyun };
772*4882a593Smuzhiyun
773*4882a593Smuzhiyun struct esas2r_fw_event_work {
774*4882a593Smuzhiyun struct list_head list;
775*4882a593Smuzhiyun struct delayed_work work;
776*4882a593Smuzhiyun struct esas2r_adapter *a;
777*4882a593Smuzhiyun enum fw_event_type type;
778*4882a593Smuzhiyun u8 data[sizeof(struct esas2r_vda_ae)];
779*4882a593Smuzhiyun };
780*4882a593Smuzhiyun
781*4882a593Smuzhiyun enum state {
782*4882a593Smuzhiyun FW_INVALID_ST,
783*4882a593Smuzhiyun FW_STATUS_ST,
784*4882a593Smuzhiyun FW_COMMAND_ST
785*4882a593Smuzhiyun };
786*4882a593Smuzhiyun
787*4882a593Smuzhiyun struct esas2r_firmware {
788*4882a593Smuzhiyun enum state state;
789*4882a593Smuzhiyun struct esas2r_flash_img header;
790*4882a593Smuzhiyun u8 *data;
791*4882a593Smuzhiyun u64 phys;
792*4882a593Smuzhiyun int orig_len;
793*4882a593Smuzhiyun void *header_buff;
794*4882a593Smuzhiyun u64 header_buff_phys;
795*4882a593Smuzhiyun };
796*4882a593Smuzhiyun
797*4882a593Smuzhiyun struct esas2r_adapter {
798*4882a593Smuzhiyun struct esas2r_target targetdb[ESAS2R_MAX_TARGETS];
799*4882a593Smuzhiyun struct esas2r_target *targetdb_end;
800*4882a593Smuzhiyun unsigned char *regs;
801*4882a593Smuzhiyun unsigned char *data_window;
802*4882a593Smuzhiyun long flags;
803*4882a593Smuzhiyun #define AF_PORT_CHANGE 0
804*4882a593Smuzhiyun #define AF_CHPRST_NEEDED 1
805*4882a593Smuzhiyun #define AF_CHPRST_PENDING 2
806*4882a593Smuzhiyun #define AF_CHPRST_DETECTED 3
807*4882a593Smuzhiyun #define AF_BUSRST_NEEDED 4
808*4882a593Smuzhiyun #define AF_BUSRST_PENDING 5
809*4882a593Smuzhiyun #define AF_BUSRST_DETECTED 6
810*4882a593Smuzhiyun #define AF_DISABLED 7
811*4882a593Smuzhiyun #define AF_FLASH_LOCK 8
812*4882a593Smuzhiyun #define AF_OS_RESET 9
813*4882a593Smuzhiyun #define AF_FLASHING 10
814*4882a593Smuzhiyun #define AF_POWER_MGT 11
815*4882a593Smuzhiyun #define AF_NVR_VALID 12
816*4882a593Smuzhiyun #define AF_DEGRADED_MODE 13
817*4882a593Smuzhiyun #define AF_DISC_PENDING 14
818*4882a593Smuzhiyun #define AF_TASKLET_SCHEDULED 15
819*4882a593Smuzhiyun #define AF_HEARTBEAT 16
820*4882a593Smuzhiyun #define AF_HEARTBEAT_ENB 17
821*4882a593Smuzhiyun #define AF_NOT_PRESENT 18
822*4882a593Smuzhiyun #define AF_CHPRST_STARTED 19
823*4882a593Smuzhiyun #define AF_FIRST_INIT 20
824*4882a593Smuzhiyun #define AF_POWER_DOWN 21
825*4882a593Smuzhiyun #define AF_DISC_IN_PROG 22
826*4882a593Smuzhiyun #define AF_COMM_LIST_TOGGLE 23
827*4882a593Smuzhiyun #define AF_LEGACY_SGE_MODE 24
828*4882a593Smuzhiyun #define AF_DISC_POLLED 25
829*4882a593Smuzhiyun long flags2;
830*4882a593Smuzhiyun #define AF2_SERIAL_FLASH 0
831*4882a593Smuzhiyun #define AF2_DEV_SCAN 1
832*4882a593Smuzhiyun #define AF2_DEV_CNT_OK 2
833*4882a593Smuzhiyun #define AF2_COREDUMP_AVAIL 3
834*4882a593Smuzhiyun #define AF2_COREDUMP_SAVED 4
835*4882a593Smuzhiyun #define AF2_VDA_POWER_DOWN 5
836*4882a593Smuzhiyun #define AF2_THUNDERLINK 6
837*4882a593Smuzhiyun #define AF2_THUNDERBOLT 7
838*4882a593Smuzhiyun #define AF2_INIT_DONE 8
839*4882a593Smuzhiyun #define AF2_INT_PENDING 9
840*4882a593Smuzhiyun #define AF2_TIMER_TICK 10
841*4882a593Smuzhiyun #define AF2_IRQ_CLAIMED 11
842*4882a593Smuzhiyun #define AF2_MSI_ENABLED 12
843*4882a593Smuzhiyun atomic_t disable_cnt;
844*4882a593Smuzhiyun atomic_t dis_ints_cnt;
845*4882a593Smuzhiyun u32 int_stat;
846*4882a593Smuzhiyun u32 int_mask;
847*4882a593Smuzhiyun u32 volatile *outbound_copy;
848*4882a593Smuzhiyun struct list_head avail_request;
849*4882a593Smuzhiyun spinlock_t request_lock;
850*4882a593Smuzhiyun spinlock_t sg_list_lock;
851*4882a593Smuzhiyun spinlock_t queue_lock;
852*4882a593Smuzhiyun spinlock_t mem_lock;
853*4882a593Smuzhiyun struct list_head free_sg_list_head;
854*4882a593Smuzhiyun struct esas2r_mem_desc *sg_list_mds;
855*4882a593Smuzhiyun struct list_head active_list;
856*4882a593Smuzhiyun struct list_head defer_list;
857*4882a593Smuzhiyun struct esas2r_request **req_table;
858*4882a593Smuzhiyun union {
859*4882a593Smuzhiyun u16 prev_dev_cnt;
860*4882a593Smuzhiyun u32 heartbeat_time;
861*4882a593Smuzhiyun #define ESAS2R_HEARTBEAT_TIME (3000)
862*4882a593Smuzhiyun };
863*4882a593Smuzhiyun u32 chip_uptime;
864*4882a593Smuzhiyun #define ESAS2R_CHP_UPTIME_MAX (60000)
865*4882a593Smuzhiyun #define ESAS2R_CHP_UPTIME_CNT (20000)
866*4882a593Smuzhiyun u64 uncached_phys;
867*4882a593Smuzhiyun u8 *uncached;
868*4882a593Smuzhiyun struct esas2r_sas_nvram *nvram;
869*4882a593Smuzhiyun struct esas2r_request general_req;
870*4882a593Smuzhiyun u8 init_msg;
871*4882a593Smuzhiyun #define ESAS2R_INIT_MSG_START 1
872*4882a593Smuzhiyun #define ESAS2R_INIT_MSG_INIT 2
873*4882a593Smuzhiyun #define ESAS2R_INIT_MSG_GET_INIT 3
874*4882a593Smuzhiyun #define ESAS2R_INIT_MSG_REINIT 4
875*4882a593Smuzhiyun u16 cmd_ref_no;
876*4882a593Smuzhiyun u32 fw_version;
877*4882a593Smuzhiyun u32 fw_build;
878*4882a593Smuzhiyun u32 chip_init_time;
879*4882a593Smuzhiyun #define ESAS2R_CHPRST_TIME (180000)
880*4882a593Smuzhiyun #define ESAS2R_CHPRST_WAIT_TIME (2000)
881*4882a593Smuzhiyun u32 last_tick_time;
882*4882a593Smuzhiyun u32 window_base;
883*4882a593Smuzhiyun RQBUILDSGL build_sgl;
884*4882a593Smuzhiyun struct esas2r_request *first_ae_req;
885*4882a593Smuzhiyun u32 list_size;
886*4882a593Smuzhiyun u32 last_write;
887*4882a593Smuzhiyun u32 last_read;
888*4882a593Smuzhiyun u16 max_vdareq_size;
889*4882a593Smuzhiyun u16 disc_wait_cnt;
890*4882a593Smuzhiyun struct esas2r_mem_desc inbound_list_md;
891*4882a593Smuzhiyun struct esas2r_mem_desc outbound_list_md;
892*4882a593Smuzhiyun struct esas2r_disc_context disc_ctx;
893*4882a593Smuzhiyun u8 *disc_buffer;
894*4882a593Smuzhiyun u32 disc_start_time;
895*4882a593Smuzhiyun u32 disc_wait_time;
896*4882a593Smuzhiyun u32 flash_ver;
897*4882a593Smuzhiyun char flash_rev[16];
898*4882a593Smuzhiyun char fw_rev[16];
899*4882a593Smuzhiyun char image_type[16];
900*4882a593Smuzhiyun struct esas2r_flash_context flash_context;
901*4882a593Smuzhiyun u32 num_targets_backend;
902*4882a593Smuzhiyun u32 ioctl_tunnel;
903*4882a593Smuzhiyun struct tasklet_struct tasklet;
904*4882a593Smuzhiyun struct pci_dev *pcid;
905*4882a593Smuzhiyun struct Scsi_Host *host;
906*4882a593Smuzhiyun unsigned int index;
907*4882a593Smuzhiyun char name[32];
908*4882a593Smuzhiyun struct timer_list timer;
909*4882a593Smuzhiyun struct esas2r_firmware firmware;
910*4882a593Smuzhiyun wait_queue_head_t nvram_waiter;
911*4882a593Smuzhiyun int nvram_command_done;
912*4882a593Smuzhiyun wait_queue_head_t fm_api_waiter;
913*4882a593Smuzhiyun int fm_api_command_done;
914*4882a593Smuzhiyun wait_queue_head_t vda_waiter;
915*4882a593Smuzhiyun int vda_command_done;
916*4882a593Smuzhiyun u8 *vda_buffer;
917*4882a593Smuzhiyun u64 ppvda_buffer;
918*4882a593Smuzhiyun #define VDA_BUFFER_HEADER_SZ (offsetof(struct atto_ioctl_vda, data))
919*4882a593Smuzhiyun #define VDA_MAX_BUFFER_SIZE (0x40000 + VDA_BUFFER_HEADER_SZ)
920*4882a593Smuzhiyun wait_queue_head_t fs_api_waiter;
921*4882a593Smuzhiyun int fs_api_command_done;
922*4882a593Smuzhiyun u64 ppfs_api_buffer;
923*4882a593Smuzhiyun u8 *fs_api_buffer;
924*4882a593Smuzhiyun u32 fs_api_buffer_size;
925*4882a593Smuzhiyun wait_queue_head_t buffered_ioctl_waiter;
926*4882a593Smuzhiyun int buffered_ioctl_done;
927*4882a593Smuzhiyun int uncached_size;
928*4882a593Smuzhiyun struct workqueue_struct *fw_event_q;
929*4882a593Smuzhiyun struct list_head fw_event_list;
930*4882a593Smuzhiyun spinlock_t fw_event_lock;
931*4882a593Smuzhiyun u8 fw_events_off; /* if '1', then ignore events */
932*4882a593Smuzhiyun char fw_event_q_name[ESAS2R_KOBJ_NAME_LEN];
933*4882a593Smuzhiyun /*
934*4882a593Smuzhiyun * intr_mode stores the interrupt mode currently being used by this
935*4882a593Smuzhiyun * adapter. it is based on the interrupt_mode module parameter, but
936*4882a593Smuzhiyun * can be changed based on the ability (or not) to utilize the
937*4882a593Smuzhiyun * mode requested by the parameter.
938*4882a593Smuzhiyun */
939*4882a593Smuzhiyun int intr_mode;
940*4882a593Smuzhiyun #define INTR_MODE_LEGACY 0
941*4882a593Smuzhiyun #define INTR_MODE_MSI 1
942*4882a593Smuzhiyun #define INTR_MODE_MSIX 2
943*4882a593Smuzhiyun struct esas2r_sg_context fm_api_sgc;
944*4882a593Smuzhiyun u8 *save_offset;
945*4882a593Smuzhiyun struct list_head vrq_mds_head;
946*4882a593Smuzhiyun struct esas2r_mem_desc *vrq_mds;
947*4882a593Smuzhiyun int num_vrqs;
948*4882a593Smuzhiyun struct mutex fm_api_mutex;
949*4882a593Smuzhiyun struct mutex fs_api_mutex;
950*4882a593Smuzhiyun struct semaphore nvram_semaphore;
951*4882a593Smuzhiyun struct atto_ioctl *local_atto_ioctl;
952*4882a593Smuzhiyun u8 fw_coredump_buff[ESAS2R_FWCOREDUMP_SZ];
953*4882a593Smuzhiyun unsigned int sysfs_fw_created:1;
954*4882a593Smuzhiyun unsigned int sysfs_fs_created:1;
955*4882a593Smuzhiyun unsigned int sysfs_vda_created:1;
956*4882a593Smuzhiyun unsigned int sysfs_hw_created:1;
957*4882a593Smuzhiyun unsigned int sysfs_live_nvram_created:1;
958*4882a593Smuzhiyun unsigned int sysfs_default_nvram_created:1;
959*4882a593Smuzhiyun };
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun /*
962*4882a593Smuzhiyun * Function Declarations
963*4882a593Smuzhiyun * SCSI functions
964*4882a593Smuzhiyun */
965*4882a593Smuzhiyun const char *esas2r_info(struct Scsi_Host *);
966*4882a593Smuzhiyun int esas2r_write_params(struct esas2r_adapter *a, struct esas2r_request *rq,
967*4882a593Smuzhiyun struct esas2r_sas_nvram *data);
968*4882a593Smuzhiyun int esas2r_ioctl_handler(void *hostdata, unsigned int cmd, void __user *arg);
969*4882a593Smuzhiyun int esas2r_ioctl(struct scsi_device *dev, unsigned int cmd, void __user *arg);
970*4882a593Smuzhiyun u8 handle_hba_ioctl(struct esas2r_adapter *a,
971*4882a593Smuzhiyun struct atto_ioctl *ioctl_hba);
972*4882a593Smuzhiyun int esas2r_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd);
973*4882a593Smuzhiyun int esas2r_show_info(struct seq_file *m, struct Scsi_Host *sh);
974*4882a593Smuzhiyun long esas2r_proc_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun /* SCSI error handler (eh) functions */
977*4882a593Smuzhiyun int esas2r_eh_abort(struct scsi_cmnd *cmd);
978*4882a593Smuzhiyun int esas2r_device_reset(struct scsi_cmnd *cmd);
979*4882a593Smuzhiyun int esas2r_host_reset(struct scsi_cmnd *cmd);
980*4882a593Smuzhiyun int esas2r_bus_reset(struct scsi_cmnd *cmd);
981*4882a593Smuzhiyun int esas2r_target_reset(struct scsi_cmnd *cmd);
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun /* Internal functions */
984*4882a593Smuzhiyun int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
985*4882a593Smuzhiyun int index);
986*4882a593Smuzhiyun int esas2r_read_fw(struct esas2r_adapter *a, char *buf, long off, int count);
987*4882a593Smuzhiyun int esas2r_write_fw(struct esas2r_adapter *a, const char *buf, long off,
988*4882a593Smuzhiyun int count);
989*4882a593Smuzhiyun int esas2r_read_vda(struct esas2r_adapter *a, char *buf, long off, int count);
990*4882a593Smuzhiyun int esas2r_write_vda(struct esas2r_adapter *a, const char *buf, long off,
991*4882a593Smuzhiyun int count);
992*4882a593Smuzhiyun int esas2r_read_fs(struct esas2r_adapter *a, char *buf, long off, int count);
993*4882a593Smuzhiyun int esas2r_write_fs(struct esas2r_adapter *a, const char *buf, long off,
994*4882a593Smuzhiyun int count);
995*4882a593Smuzhiyun void esas2r_adapter_tasklet(unsigned long context);
996*4882a593Smuzhiyun irqreturn_t esas2r_interrupt(int irq, void *dev_id);
997*4882a593Smuzhiyun irqreturn_t esas2r_msi_interrupt(int irq, void *dev_id);
998*4882a593Smuzhiyun void esas2r_kickoff_timer(struct esas2r_adapter *a);
999*4882a593Smuzhiyun int esas2r_suspend(struct pci_dev *pcid, pm_message_t state);
1000*4882a593Smuzhiyun int esas2r_resume(struct pci_dev *pcid);
1001*4882a593Smuzhiyun void esas2r_fw_event_off(struct esas2r_adapter *a);
1002*4882a593Smuzhiyun void esas2r_fw_event_on(struct esas2r_adapter *a);
1003*4882a593Smuzhiyun bool esas2r_nvram_write(struct esas2r_adapter *a, struct esas2r_request *rq,
1004*4882a593Smuzhiyun struct esas2r_sas_nvram *nvram);
1005*4882a593Smuzhiyun void esas2r_nvram_get_defaults(struct esas2r_adapter *a,
1006*4882a593Smuzhiyun struct esas2r_sas_nvram *nvram);
1007*4882a593Smuzhiyun void esas2r_complete_request_cb(struct esas2r_adapter *a,
1008*4882a593Smuzhiyun struct esas2r_request *rq);
1009*4882a593Smuzhiyun void esas2r_reset_detected(struct esas2r_adapter *a);
1010*4882a593Smuzhiyun void esas2r_target_state_changed(struct esas2r_adapter *ha, u16 targ_id,
1011*4882a593Smuzhiyun u8 state);
1012*4882a593Smuzhiyun int esas2r_req_status_to_error(u8 req_stat);
1013*4882a593Smuzhiyun void esas2r_kill_adapter(int i);
1014*4882a593Smuzhiyun void esas2r_free_request(struct esas2r_adapter *a, struct esas2r_request *rq);
1015*4882a593Smuzhiyun struct esas2r_request *esas2r_alloc_request(struct esas2r_adapter *a);
1016*4882a593Smuzhiyun u32 esas2r_get_uncached_size(struct esas2r_adapter *a);
1017*4882a593Smuzhiyun bool esas2r_init_adapter_struct(struct esas2r_adapter *a,
1018*4882a593Smuzhiyun void **uncached_area);
1019*4882a593Smuzhiyun bool esas2r_check_adapter(struct esas2r_adapter *a);
1020*4882a593Smuzhiyun bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll);
1021*4882a593Smuzhiyun void esas2r_start_request(struct esas2r_adapter *a, struct esas2r_request *rq);
1022*4882a593Smuzhiyun bool esas2r_send_task_mgmt(struct esas2r_adapter *a,
1023*4882a593Smuzhiyun struct esas2r_request *rqaux, u8 task_mgt_func);
1024*4882a593Smuzhiyun void esas2r_do_tasklet_tasks(struct esas2r_adapter *a);
1025*4882a593Smuzhiyun void esas2r_adapter_interrupt(struct esas2r_adapter *a);
1026*4882a593Smuzhiyun void esas2r_do_deferred_processes(struct esas2r_adapter *a);
1027*4882a593Smuzhiyun void esas2r_reset_bus(struct esas2r_adapter *a);
1028*4882a593Smuzhiyun void esas2r_reset_adapter(struct esas2r_adapter *a);
1029*4882a593Smuzhiyun void esas2r_timer_tick(struct esas2r_adapter *a);
1030*4882a593Smuzhiyun const char *esas2r_get_model_name(struct esas2r_adapter *a);
1031*4882a593Smuzhiyun const char *esas2r_get_model_name_short(struct esas2r_adapter *a);
1032*4882a593Smuzhiyun u32 esas2r_stall_execution(struct esas2r_adapter *a, u32 start_time,
1033*4882a593Smuzhiyun u32 *delay);
1034*4882a593Smuzhiyun void esas2r_build_flash_req(struct esas2r_adapter *a,
1035*4882a593Smuzhiyun struct esas2r_request *rq,
1036*4882a593Smuzhiyun u8 sub_func,
1037*4882a593Smuzhiyun u8 cksum,
1038*4882a593Smuzhiyun u32 addr,
1039*4882a593Smuzhiyun u32 length);
1040*4882a593Smuzhiyun void esas2r_build_mgt_req(struct esas2r_adapter *a,
1041*4882a593Smuzhiyun struct esas2r_request *rq,
1042*4882a593Smuzhiyun u8 sub_func,
1043*4882a593Smuzhiyun u8 scan_gen,
1044*4882a593Smuzhiyun u16 dev_index,
1045*4882a593Smuzhiyun u32 length,
1046*4882a593Smuzhiyun void *data);
1047*4882a593Smuzhiyun void esas2r_build_ae_req(struct esas2r_adapter *a, struct esas2r_request *rq);
1048*4882a593Smuzhiyun void esas2r_build_cli_req(struct esas2r_adapter *a,
1049*4882a593Smuzhiyun struct esas2r_request *rq,
1050*4882a593Smuzhiyun u32 length,
1051*4882a593Smuzhiyun u32 cmd_rsp_len);
1052*4882a593Smuzhiyun void esas2r_build_ioctl_req(struct esas2r_adapter *a,
1053*4882a593Smuzhiyun struct esas2r_request *rq,
1054*4882a593Smuzhiyun u32 length,
1055*4882a593Smuzhiyun u8 sub_func);
1056*4882a593Smuzhiyun void esas2r_build_cfg_req(struct esas2r_adapter *a,
1057*4882a593Smuzhiyun struct esas2r_request *rq,
1058*4882a593Smuzhiyun u8 sub_func,
1059*4882a593Smuzhiyun u32 length,
1060*4882a593Smuzhiyun void *data);
1061*4882a593Smuzhiyun void esas2r_power_down(struct esas2r_adapter *a);
1062*4882a593Smuzhiyun bool esas2r_power_up(struct esas2r_adapter *a, bool init_poll);
1063*4882a593Smuzhiyun void esas2r_wait_request(struct esas2r_adapter *a, struct esas2r_request *rq);
1064*4882a593Smuzhiyun u32 esas2r_map_data_window(struct esas2r_adapter *a, u32 addr_lo);
1065*4882a593Smuzhiyun bool esas2r_process_fs_ioctl(struct esas2r_adapter *a,
1066*4882a593Smuzhiyun struct esas2r_ioctl_fs *fs,
1067*4882a593Smuzhiyun struct esas2r_request *rq,
1068*4882a593Smuzhiyun struct esas2r_sg_context *sgc);
1069*4882a593Smuzhiyun bool esas2r_read_flash_block(struct esas2r_adapter *a, void *to, u32 from,
1070*4882a593Smuzhiyun u32 size);
1071*4882a593Smuzhiyun bool esas2r_read_mem_block(struct esas2r_adapter *a, void *to, u32 from,
1072*4882a593Smuzhiyun u32 size);
1073*4882a593Smuzhiyun bool esas2r_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi,
1074*4882a593Smuzhiyun struct esas2r_request *rq, struct esas2r_sg_context *sgc);
1075*4882a593Smuzhiyun void esas2r_force_interrupt(struct esas2r_adapter *a);
1076*4882a593Smuzhiyun void esas2r_local_start_request(struct esas2r_adapter *a,
1077*4882a593Smuzhiyun struct esas2r_request *rq);
1078*4882a593Smuzhiyun void esas2r_process_adapter_reset(struct esas2r_adapter *a);
1079*4882a593Smuzhiyun void esas2r_complete_request(struct esas2r_adapter *a,
1080*4882a593Smuzhiyun struct esas2r_request *rq);
1081*4882a593Smuzhiyun void esas2r_dummy_complete(struct esas2r_adapter *a,
1082*4882a593Smuzhiyun struct esas2r_request *rq);
1083*4882a593Smuzhiyun void esas2r_ae_complete(struct esas2r_adapter *a, struct esas2r_request *rq);
1084*4882a593Smuzhiyun void esas2r_start_vda_request(struct esas2r_adapter *a,
1085*4882a593Smuzhiyun struct esas2r_request *rq);
1086*4882a593Smuzhiyun bool esas2r_read_flash_rev(struct esas2r_adapter *a);
1087*4882a593Smuzhiyun bool esas2r_read_image_type(struct esas2r_adapter *a);
1088*4882a593Smuzhiyun bool esas2r_nvram_read_direct(struct esas2r_adapter *a);
1089*4882a593Smuzhiyun bool esas2r_nvram_validate(struct esas2r_adapter *a);
1090*4882a593Smuzhiyun void esas2r_nvram_set_defaults(struct esas2r_adapter *a);
1091*4882a593Smuzhiyun bool esas2r_print_flash_rev(struct esas2r_adapter *a);
1092*4882a593Smuzhiyun void esas2r_send_reset_ae(struct esas2r_adapter *a, bool pwr_mgt);
1093*4882a593Smuzhiyun bool esas2r_init_msgs(struct esas2r_adapter *a);
1094*4882a593Smuzhiyun bool esas2r_is_adapter_present(struct esas2r_adapter *a);
1095*4882a593Smuzhiyun void esas2r_nuxi_mgt_data(u8 function, void *data);
1096*4882a593Smuzhiyun void esas2r_nuxi_cfg_data(u8 function, void *data);
1097*4882a593Smuzhiyun void esas2r_nuxi_ae_data(union atto_vda_ae *ae);
1098*4882a593Smuzhiyun void esas2r_reset_chip(struct esas2r_adapter *a);
1099*4882a593Smuzhiyun void esas2r_log_request_failure(struct esas2r_adapter *a,
1100*4882a593Smuzhiyun struct esas2r_request *rq);
1101*4882a593Smuzhiyun void esas2r_polled_interrupt(struct esas2r_adapter *a);
1102*4882a593Smuzhiyun bool esas2r_ioreq_aborted(struct esas2r_adapter *a, struct esas2r_request *rq,
1103*4882a593Smuzhiyun u8 status);
1104*4882a593Smuzhiyun bool esas2r_build_sg_list_sge(struct esas2r_adapter *a,
1105*4882a593Smuzhiyun struct esas2r_sg_context *sgc);
1106*4882a593Smuzhiyun bool esas2r_build_sg_list_prd(struct esas2r_adapter *a,
1107*4882a593Smuzhiyun struct esas2r_sg_context *sgc);
1108*4882a593Smuzhiyun void esas2r_targ_db_initialize(struct esas2r_adapter *a);
1109*4882a593Smuzhiyun void esas2r_targ_db_remove_all(struct esas2r_adapter *a, bool notify);
1110*4882a593Smuzhiyun void esas2r_targ_db_report_changes(struct esas2r_adapter *a);
1111*4882a593Smuzhiyun struct esas2r_target *esas2r_targ_db_add_raid(struct esas2r_adapter *a,
1112*4882a593Smuzhiyun struct esas2r_disc_context *dc);
1113*4882a593Smuzhiyun struct esas2r_target *esas2r_targ_db_add_pthru(struct esas2r_adapter *a,
1114*4882a593Smuzhiyun struct esas2r_disc_context *dc,
1115*4882a593Smuzhiyun u8 *ident,
1116*4882a593Smuzhiyun u8 ident_len);
1117*4882a593Smuzhiyun void esas2r_targ_db_remove(struct esas2r_adapter *a, struct esas2r_target *t);
1118*4882a593Smuzhiyun struct esas2r_target *esas2r_targ_db_find_by_sas_addr(struct esas2r_adapter *a,
1119*4882a593Smuzhiyun u64 *sas_addr);
1120*4882a593Smuzhiyun struct esas2r_target *esas2r_targ_db_find_by_ident(struct esas2r_adapter *a,
1121*4882a593Smuzhiyun void *identifier,
1122*4882a593Smuzhiyun u8 ident_len);
1123*4882a593Smuzhiyun u16 esas2r_targ_db_find_next_present(struct esas2r_adapter *a, u16 target_id);
1124*4882a593Smuzhiyun struct esas2r_target *esas2r_targ_db_find_by_virt_id(struct esas2r_adapter *a,
1125*4882a593Smuzhiyun u16 virt_id);
1126*4882a593Smuzhiyun u16 esas2r_targ_db_get_tgt_cnt(struct esas2r_adapter *a);
1127*4882a593Smuzhiyun void esas2r_disc_initialize(struct esas2r_adapter *a);
1128*4882a593Smuzhiyun void esas2r_disc_start_waiting(struct esas2r_adapter *a);
1129*4882a593Smuzhiyun void esas2r_disc_check_for_work(struct esas2r_adapter *a);
1130*4882a593Smuzhiyun void esas2r_disc_check_complete(struct esas2r_adapter *a);
1131*4882a593Smuzhiyun void esas2r_disc_queue_event(struct esas2r_adapter *a, u8 disc_evt);
1132*4882a593Smuzhiyun bool esas2r_disc_start_port(struct esas2r_adapter *a);
1133*4882a593Smuzhiyun void esas2r_disc_local_start_request(struct esas2r_adapter *a,
1134*4882a593Smuzhiyun struct esas2r_request *rq);
1135*4882a593Smuzhiyun bool esas2r_set_degraded_mode(struct esas2r_adapter *a, char *error_str);
1136*4882a593Smuzhiyun bool esas2r_process_vda_ioctl(struct esas2r_adapter *a,
1137*4882a593Smuzhiyun struct atto_ioctl_vda *vi,
1138*4882a593Smuzhiyun struct esas2r_request *rq,
1139*4882a593Smuzhiyun struct esas2r_sg_context *sgc);
1140*4882a593Smuzhiyun void esas2r_queue_fw_event(struct esas2r_adapter *a,
1141*4882a593Smuzhiyun enum fw_event_type type,
1142*4882a593Smuzhiyun void *data,
1143*4882a593Smuzhiyun int data_sz);
1144*4882a593Smuzhiyun
1145*4882a593Smuzhiyun /* Inline functions */
1146*4882a593Smuzhiyun
1147*4882a593Smuzhiyun /* Allocate a chip scatter/gather list entry */
esas2r_alloc_sgl(struct esas2r_adapter * a)1148*4882a593Smuzhiyun static inline struct esas2r_mem_desc *esas2r_alloc_sgl(struct esas2r_adapter *a)
1149*4882a593Smuzhiyun {
1150*4882a593Smuzhiyun unsigned long flags;
1151*4882a593Smuzhiyun struct list_head *sgl;
1152*4882a593Smuzhiyun struct esas2r_mem_desc *result = NULL;
1153*4882a593Smuzhiyun
1154*4882a593Smuzhiyun spin_lock_irqsave(&a->sg_list_lock, flags);
1155*4882a593Smuzhiyun if (likely(!list_empty(&a->free_sg_list_head))) {
1156*4882a593Smuzhiyun sgl = a->free_sg_list_head.next;
1157*4882a593Smuzhiyun result = list_entry(sgl, struct esas2r_mem_desc, next_desc);
1158*4882a593Smuzhiyun list_del_init(sgl);
1159*4882a593Smuzhiyun }
1160*4882a593Smuzhiyun spin_unlock_irqrestore(&a->sg_list_lock, flags);
1161*4882a593Smuzhiyun
1162*4882a593Smuzhiyun return result;
1163*4882a593Smuzhiyun }
1164*4882a593Smuzhiyun
1165*4882a593Smuzhiyun /* Initialize a scatter/gather context */
esas2r_sgc_init(struct esas2r_sg_context * sgc,struct esas2r_adapter * a,struct esas2r_request * rq,struct atto_vda_sge * first)1166*4882a593Smuzhiyun static inline void esas2r_sgc_init(struct esas2r_sg_context *sgc,
1167*4882a593Smuzhiyun struct esas2r_adapter *a,
1168*4882a593Smuzhiyun struct esas2r_request *rq,
1169*4882a593Smuzhiyun struct atto_vda_sge *first)
1170*4882a593Smuzhiyun {
1171*4882a593Smuzhiyun sgc->adapter = a;
1172*4882a593Smuzhiyun sgc->first_req = rq;
1173*4882a593Smuzhiyun
1174*4882a593Smuzhiyun /*
1175*4882a593Smuzhiyun * set the limit pointer such that an SGE pointer above this value
1176*4882a593Smuzhiyun * would be the first one to overflow the SGL.
1177*4882a593Smuzhiyun */
1178*4882a593Smuzhiyun sgc->sge.a64.limit = (struct atto_vda_sge *)((u8 *)rq->vrq
1179*4882a593Smuzhiyun + (sizeof(union
1180*4882a593Smuzhiyun atto_vda_req) /
1181*4882a593Smuzhiyun 8)
1182*4882a593Smuzhiyun - sizeof(struct
1183*4882a593Smuzhiyun atto_vda_sge));
1184*4882a593Smuzhiyun if (first) {
1185*4882a593Smuzhiyun sgc->sge.a64.last =
1186*4882a593Smuzhiyun sgc->sge.a64.curr = first;
1187*4882a593Smuzhiyun rq->vrq->scsi.sg_list_offset = (u8)
1188*4882a593Smuzhiyun ((u8 *)first -
1189*4882a593Smuzhiyun (u8 *)rq->vrq);
1190*4882a593Smuzhiyun } else {
1191*4882a593Smuzhiyun sgc->sge.a64.last =
1192*4882a593Smuzhiyun sgc->sge.a64.curr = &rq->vrq->scsi.u.sge[0];
1193*4882a593Smuzhiyun rq->vrq->scsi.sg_list_offset =
1194*4882a593Smuzhiyun (u8)offsetof(struct atto_vda_scsi_req, u.sge);
1195*4882a593Smuzhiyun }
1196*4882a593Smuzhiyun sgc->sge.a64.chain = NULL;
1197*4882a593Smuzhiyun }
1198*4882a593Smuzhiyun
esas2r_rq_init_request(struct esas2r_request * rq,struct esas2r_adapter * a)1199*4882a593Smuzhiyun static inline void esas2r_rq_init_request(struct esas2r_request *rq,
1200*4882a593Smuzhiyun struct esas2r_adapter *a)
1201*4882a593Smuzhiyun {
1202*4882a593Smuzhiyun union atto_vda_req *vrq = rq->vrq;
1203*4882a593Smuzhiyun
1204*4882a593Smuzhiyun INIT_LIST_HEAD(&rq->sg_table_head);
1205*4882a593Smuzhiyun rq->data_buf = (void *)(vrq + 1);
1206*4882a593Smuzhiyun rq->interrupt_cb = NULL;
1207*4882a593Smuzhiyun rq->comp_cb = esas2r_complete_request_cb;
1208*4882a593Smuzhiyun rq->flags = 0;
1209*4882a593Smuzhiyun rq->timeout = 0;
1210*4882a593Smuzhiyun rq->req_stat = RS_PENDING;
1211*4882a593Smuzhiyun rq->req_type = RT_INI_REQ;
1212*4882a593Smuzhiyun
1213*4882a593Smuzhiyun /* clear the outbound response */
1214*4882a593Smuzhiyun rq->func_rsp.dwords[0] = 0;
1215*4882a593Smuzhiyun rq->func_rsp.dwords[1] = 0;
1216*4882a593Smuzhiyun
1217*4882a593Smuzhiyun /*
1218*4882a593Smuzhiyun * clear the size of the VDA request. esas2r_build_sg_list() will
1219*4882a593Smuzhiyun * only allow the size of the request to grow. there are some
1220*4882a593Smuzhiyun * management requests that go through there twice and the second
1221*4882a593Smuzhiyun * time through sets a smaller request size. if this is not modified
1222*4882a593Smuzhiyun * at all we'll set it to the size of the entire VDA request.
1223*4882a593Smuzhiyun */
1224*4882a593Smuzhiyun rq->vda_req_sz = RQ_SIZE_DEFAULT;
1225*4882a593Smuzhiyun
1226*4882a593Smuzhiyun /* req_table entry should be NULL at this point - if not, halt */
1227*4882a593Smuzhiyun
1228*4882a593Smuzhiyun if (a->req_table[LOWORD(vrq->scsi.handle)]) {
1229*4882a593Smuzhiyun esas2r_bugon();
1230*4882a593Smuzhiyun }
1231*4882a593Smuzhiyun
1232*4882a593Smuzhiyun /* fill in the table for this handle so we can get back to the
1233*4882a593Smuzhiyun * request.
1234*4882a593Smuzhiyun */
1235*4882a593Smuzhiyun a->req_table[LOWORD(vrq->scsi.handle)] = rq;
1236*4882a593Smuzhiyun
1237*4882a593Smuzhiyun /*
1238*4882a593Smuzhiyun * add a reference number to the handle to make it unique (until it
1239*4882a593Smuzhiyun * wraps of course) while preserving the least significant word
1240*4882a593Smuzhiyun */
1241*4882a593Smuzhiyun vrq->scsi.handle = (a->cmd_ref_no++ << 16) | (u16)vrq->scsi.handle;
1242*4882a593Smuzhiyun
1243*4882a593Smuzhiyun /*
1244*4882a593Smuzhiyun * the following formats a SCSI request. the caller can override as
1245*4882a593Smuzhiyun * necessary. clear_vda_request can be called to clear the VDA
1246*4882a593Smuzhiyun * request for another type of request.
1247*4882a593Smuzhiyun */
1248*4882a593Smuzhiyun vrq->scsi.function = VDA_FUNC_SCSI;
1249*4882a593Smuzhiyun vrq->scsi.sense_len = SENSE_DATA_SZ;
1250*4882a593Smuzhiyun
1251*4882a593Smuzhiyun /* clear out sg_list_offset and chain_offset */
1252*4882a593Smuzhiyun vrq->scsi.sg_list_offset = 0;
1253*4882a593Smuzhiyun vrq->scsi.chain_offset = 0;
1254*4882a593Smuzhiyun vrq->scsi.flags = 0;
1255*4882a593Smuzhiyun vrq->scsi.reserved = 0;
1256*4882a593Smuzhiyun
1257*4882a593Smuzhiyun /* set the sense buffer to be the data payload buffer */
1258*4882a593Smuzhiyun vrq->scsi.ppsense_buf
1259*4882a593Smuzhiyun = cpu_to_le64(rq->vrq_md->phys_addr +
1260*4882a593Smuzhiyun sizeof(union atto_vda_req));
1261*4882a593Smuzhiyun }
1262*4882a593Smuzhiyun
esas2r_rq_free_sg_lists(struct esas2r_request * rq,struct esas2r_adapter * a)1263*4882a593Smuzhiyun static inline void esas2r_rq_free_sg_lists(struct esas2r_request *rq,
1264*4882a593Smuzhiyun struct esas2r_adapter *a)
1265*4882a593Smuzhiyun {
1266*4882a593Smuzhiyun unsigned long flags;
1267*4882a593Smuzhiyun
1268*4882a593Smuzhiyun if (list_empty(&rq->sg_table_head))
1269*4882a593Smuzhiyun return;
1270*4882a593Smuzhiyun
1271*4882a593Smuzhiyun spin_lock_irqsave(&a->sg_list_lock, flags);
1272*4882a593Smuzhiyun list_splice_tail_init(&rq->sg_table_head, &a->free_sg_list_head);
1273*4882a593Smuzhiyun spin_unlock_irqrestore(&a->sg_list_lock, flags);
1274*4882a593Smuzhiyun }
1275*4882a593Smuzhiyun
esas2r_rq_destroy_request(struct esas2r_request * rq,struct esas2r_adapter * a)1276*4882a593Smuzhiyun static inline void esas2r_rq_destroy_request(struct esas2r_request *rq,
1277*4882a593Smuzhiyun struct esas2r_adapter *a)
1278*4882a593Smuzhiyun
1279*4882a593Smuzhiyun {
1280*4882a593Smuzhiyun esas2r_rq_free_sg_lists(rq, a);
1281*4882a593Smuzhiyun a->req_table[LOWORD(rq->vrq->scsi.handle)] = NULL;
1282*4882a593Smuzhiyun rq->data_buf = NULL;
1283*4882a593Smuzhiyun }
1284*4882a593Smuzhiyun
esas2r_is_tasklet_pending(struct esas2r_adapter * a)1285*4882a593Smuzhiyun static inline bool esas2r_is_tasklet_pending(struct esas2r_adapter *a)
1286*4882a593Smuzhiyun {
1287*4882a593Smuzhiyun
1288*4882a593Smuzhiyun return test_bit(AF_BUSRST_NEEDED, &a->flags) ||
1289*4882a593Smuzhiyun test_bit(AF_BUSRST_DETECTED, &a->flags) ||
1290*4882a593Smuzhiyun test_bit(AF_CHPRST_NEEDED, &a->flags) ||
1291*4882a593Smuzhiyun test_bit(AF_CHPRST_DETECTED, &a->flags) ||
1292*4882a593Smuzhiyun test_bit(AF_PORT_CHANGE, &a->flags);
1293*4882a593Smuzhiyun
1294*4882a593Smuzhiyun }
1295*4882a593Smuzhiyun
1296*4882a593Smuzhiyun /*
1297*4882a593Smuzhiyun * Build the scatter/gather list for an I/O request according to the
1298*4882a593Smuzhiyun * specifications placed in the esas2r_sg_context. The caller must initialize
1299*4882a593Smuzhiyun * struct esas2r_sg_context prior to the initial call by calling
1300*4882a593Smuzhiyun * esas2r_sgc_init()
1301*4882a593Smuzhiyun */
esas2r_build_sg_list(struct esas2r_adapter * a,struct esas2r_request * rq,struct esas2r_sg_context * sgc)1302*4882a593Smuzhiyun static inline bool esas2r_build_sg_list(struct esas2r_adapter *a,
1303*4882a593Smuzhiyun struct esas2r_request *rq,
1304*4882a593Smuzhiyun struct esas2r_sg_context *sgc)
1305*4882a593Smuzhiyun {
1306*4882a593Smuzhiyun if (unlikely(le32_to_cpu(rq->vrq->scsi.length) == 0))
1307*4882a593Smuzhiyun return true;
1308*4882a593Smuzhiyun
1309*4882a593Smuzhiyun return (*a->build_sgl)(a, sgc);
1310*4882a593Smuzhiyun }
1311*4882a593Smuzhiyun
esas2r_disable_chip_interrupts(struct esas2r_adapter * a)1312*4882a593Smuzhiyun static inline void esas2r_disable_chip_interrupts(struct esas2r_adapter *a)
1313*4882a593Smuzhiyun {
1314*4882a593Smuzhiyun if (atomic_inc_return(&a->dis_ints_cnt) == 1)
1315*4882a593Smuzhiyun esas2r_write_register_dword(a, MU_INT_MASK_OUT,
1316*4882a593Smuzhiyun ESAS2R_INT_DIS_MASK);
1317*4882a593Smuzhiyun }
1318*4882a593Smuzhiyun
esas2r_enable_chip_interrupts(struct esas2r_adapter * a)1319*4882a593Smuzhiyun static inline void esas2r_enable_chip_interrupts(struct esas2r_adapter *a)
1320*4882a593Smuzhiyun {
1321*4882a593Smuzhiyun if (atomic_dec_return(&a->dis_ints_cnt) == 0)
1322*4882a593Smuzhiyun esas2r_write_register_dword(a, MU_INT_MASK_OUT,
1323*4882a593Smuzhiyun ESAS2R_INT_ENB_MASK);
1324*4882a593Smuzhiyun }
1325*4882a593Smuzhiyun
1326*4882a593Smuzhiyun /* Schedule a TASKLET to perform non-interrupt tasks that may require delays
1327*4882a593Smuzhiyun * or long completion times.
1328*4882a593Smuzhiyun */
esas2r_schedule_tasklet(struct esas2r_adapter * a)1329*4882a593Smuzhiyun static inline void esas2r_schedule_tasklet(struct esas2r_adapter *a)
1330*4882a593Smuzhiyun {
1331*4882a593Smuzhiyun /* make sure we don't schedule twice */
1332*4882a593Smuzhiyun if (!test_and_set_bit(AF_TASKLET_SCHEDULED, &a->flags))
1333*4882a593Smuzhiyun tasklet_hi_schedule(&a->tasklet);
1334*4882a593Smuzhiyun }
1335*4882a593Smuzhiyun
esas2r_enable_heartbeat(struct esas2r_adapter * a)1336*4882a593Smuzhiyun static inline void esas2r_enable_heartbeat(struct esas2r_adapter *a)
1337*4882a593Smuzhiyun {
1338*4882a593Smuzhiyun if (!test_bit(AF_DEGRADED_MODE, &a->flags) &&
1339*4882a593Smuzhiyun !test_bit(AF_CHPRST_PENDING, &a->flags) &&
1340*4882a593Smuzhiyun (a->nvram->options2 & SASNVR2_HEARTBEAT))
1341*4882a593Smuzhiyun set_bit(AF_HEARTBEAT_ENB, &a->flags);
1342*4882a593Smuzhiyun else
1343*4882a593Smuzhiyun clear_bit(AF_HEARTBEAT_ENB, &a->flags);
1344*4882a593Smuzhiyun }
1345*4882a593Smuzhiyun
esas2r_disable_heartbeat(struct esas2r_adapter * a)1346*4882a593Smuzhiyun static inline void esas2r_disable_heartbeat(struct esas2r_adapter *a)
1347*4882a593Smuzhiyun {
1348*4882a593Smuzhiyun clear_bit(AF_HEARTBEAT_ENB, &a->flags);
1349*4882a593Smuzhiyun clear_bit(AF_HEARTBEAT, &a->flags);
1350*4882a593Smuzhiyun }
1351*4882a593Smuzhiyun
1352*4882a593Smuzhiyun /* Set the initial state for resetting the adapter on the next pass through
1353*4882a593Smuzhiyun * esas2r_do_deferred.
1354*4882a593Smuzhiyun */
esas2r_local_reset_adapter(struct esas2r_adapter * a)1355*4882a593Smuzhiyun static inline void esas2r_local_reset_adapter(struct esas2r_adapter *a)
1356*4882a593Smuzhiyun {
1357*4882a593Smuzhiyun esas2r_disable_heartbeat(a);
1358*4882a593Smuzhiyun
1359*4882a593Smuzhiyun set_bit(AF_CHPRST_NEEDED, &a->flags);
1360*4882a593Smuzhiyun set_bit(AF_CHPRST_PENDING, &a->flags);
1361*4882a593Smuzhiyun set_bit(AF_DISC_PENDING, &a->flags);
1362*4882a593Smuzhiyun }
1363*4882a593Smuzhiyun
1364*4882a593Smuzhiyun /* See if an interrupt is pending on the adapter. */
esas2r_adapter_interrupt_pending(struct esas2r_adapter * a)1365*4882a593Smuzhiyun static inline bool esas2r_adapter_interrupt_pending(struct esas2r_adapter *a)
1366*4882a593Smuzhiyun {
1367*4882a593Smuzhiyun u32 intstat;
1368*4882a593Smuzhiyun
1369*4882a593Smuzhiyun if (a->int_mask == 0)
1370*4882a593Smuzhiyun return false;
1371*4882a593Smuzhiyun
1372*4882a593Smuzhiyun intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT);
1373*4882a593Smuzhiyun
1374*4882a593Smuzhiyun if ((intstat & a->int_mask) == 0)
1375*4882a593Smuzhiyun return false;
1376*4882a593Smuzhiyun
1377*4882a593Smuzhiyun esas2r_disable_chip_interrupts(a);
1378*4882a593Smuzhiyun
1379*4882a593Smuzhiyun a->int_stat = intstat;
1380*4882a593Smuzhiyun a->int_mask = 0;
1381*4882a593Smuzhiyun
1382*4882a593Smuzhiyun return true;
1383*4882a593Smuzhiyun }
1384*4882a593Smuzhiyun
esas2r_targ_get_id(struct esas2r_target * t,struct esas2r_adapter * a)1385*4882a593Smuzhiyun static inline u16 esas2r_targ_get_id(struct esas2r_target *t,
1386*4882a593Smuzhiyun struct esas2r_adapter *a)
1387*4882a593Smuzhiyun {
1388*4882a593Smuzhiyun return (u16)(uintptr_t)(t - a->targetdb);
1389*4882a593Smuzhiyun }
1390*4882a593Smuzhiyun
1391*4882a593Smuzhiyun /* Build and start an asynchronous event request */
esas2r_start_ae_request(struct esas2r_adapter * a,struct esas2r_request * rq)1392*4882a593Smuzhiyun static inline void esas2r_start_ae_request(struct esas2r_adapter *a,
1393*4882a593Smuzhiyun struct esas2r_request *rq)
1394*4882a593Smuzhiyun {
1395*4882a593Smuzhiyun unsigned long flags;
1396*4882a593Smuzhiyun
1397*4882a593Smuzhiyun esas2r_build_ae_req(a, rq);
1398*4882a593Smuzhiyun
1399*4882a593Smuzhiyun spin_lock_irqsave(&a->queue_lock, flags);
1400*4882a593Smuzhiyun esas2r_start_vda_request(a, rq);
1401*4882a593Smuzhiyun spin_unlock_irqrestore(&a->queue_lock, flags);
1402*4882a593Smuzhiyun }
1403*4882a593Smuzhiyun
esas2r_comp_list_drain(struct esas2r_adapter * a,struct list_head * comp_list)1404*4882a593Smuzhiyun static inline void esas2r_comp_list_drain(struct esas2r_adapter *a,
1405*4882a593Smuzhiyun struct list_head *comp_list)
1406*4882a593Smuzhiyun {
1407*4882a593Smuzhiyun struct esas2r_request *rq;
1408*4882a593Smuzhiyun struct list_head *element, *next;
1409*4882a593Smuzhiyun
1410*4882a593Smuzhiyun list_for_each_safe(element, next, comp_list) {
1411*4882a593Smuzhiyun rq = list_entry(element, struct esas2r_request, comp_list);
1412*4882a593Smuzhiyun list_del_init(element);
1413*4882a593Smuzhiyun esas2r_complete_request(a, rq);
1414*4882a593Smuzhiyun }
1415*4882a593Smuzhiyun }
1416*4882a593Smuzhiyun
1417*4882a593Smuzhiyun /* sysfs handlers */
1418*4882a593Smuzhiyun extern struct bin_attribute bin_attr_fw;
1419*4882a593Smuzhiyun extern struct bin_attribute bin_attr_fs;
1420*4882a593Smuzhiyun extern struct bin_attribute bin_attr_vda;
1421*4882a593Smuzhiyun extern struct bin_attribute bin_attr_hw;
1422*4882a593Smuzhiyun extern struct bin_attribute bin_attr_live_nvram;
1423*4882a593Smuzhiyun extern struct bin_attribute bin_attr_default_nvram;
1424*4882a593Smuzhiyun
1425*4882a593Smuzhiyun #endif /* ESAS2R_H */
1426