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