xref: /freebsd/sys/dev/mfi/mfireg.h (revision b2db760808f74bb53c232900091c9da801ebbfcc)
1 /*-
2  * Copyright (c) 2006 IronPort Systems
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 /*-
27  * Copyright (c) 2007 LSI Corp.
28  * Copyright (c) 2007 Rajesh Prabhakaran.
29  * All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  * 1. Redistributions of source code must retain the above copyright
35  *    notice, this list of conditions and the following disclaimer.
36  * 2. Redistributions in binary form must reproduce the above copyright
37  *    notice, this list of conditions and the following disclaimer in the
38  *    documentation and/or other materials provided with the distribution.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  */
52 
53 #ifndef _MFIREG_H
54 #define _MFIREG_H
55 
56 #include <sys/cdefs.h>
57 __FBSDID("$FreeBSD$");
58 
59 /*
60  * MegaRAID SAS MFI firmware definitions
61  *
62  * Calling this driver 'MegaRAID SAS' is a bit misleading.  It's a completely
63  * new firmware interface from the old AMI MegaRAID one, and there is no
64  * reason why this interface should be limited to just SAS.  In any case, LSI
65  * seems to also call this interface 'MFI', so that will be used here.
66  */
67 
68 /*
69  * Start with the register set.  All registers are 32 bits wide.
70  * The usual Intel IOP style setup.
71  */
72 #define MFI_IMSG0	0x10	/* Inbound message 0 */
73 #define MFI_IMSG1	0x14	/* Inbound message 1 */
74 #define MFI_OMSG0	0x18	/* Outbound message 0 */
75 #define MFI_OMSG1	0x1c	/* Outbound message 1 */
76 #define MFI_IDB		0x20	/* Inbound doorbell */
77 #define MFI_ISTS	0x24	/* Inbound interrupt status */
78 #define MFI_IMSK	0x28	/* Inbound interrupt mask */
79 #define MFI_ODB		0x2c	/* Outbound doorbell */
80 #define MFI_OSTS	0x30	/* Outbound interrupt status */
81 #define MFI_OMSK	0x34	/* Outbound interrupt mask */
82 #define MFI_IQP		0x40	/* Inbound queue port */
83 #define MFI_OQP		0x44	/* Outbound queue port */
84 
85 /*
86  * 1078 specific related register
87  */
88 #define MFI_ODR0	0x9c 		/* outbound doorbell register0 */
89 #define MFI_ODCR0	0xa0 		/* outbound doorbell clear register0  */
90 #define MFI_OSP0	0xb0 		/* outbound scratch pad0  */
91 #define MFI_1078_EIM	0x80000004 	/* 1078 enable intrrupt mask  */
92 #define MFI_RMI		0x2 		/* reply message interrupt  */
93 #define MFI_1078_RM	0x80000000 	/* reply 1078 message interrupt  */
94 #define MFI_ODC		0x4 		/* outbound doorbell change interrupt */
95 
96 /*
97  * GEN2 specific changes
98  */
99 #define MFI_GEN2_EIM	0x00000005	/* GEN2 enable interrupt mask */
100 #define MFI_GEN2_RM	0x00000001	/* reply GEN2 message interrupt */
101 
102 /* Bits for MFI_OSTS */
103 #define MFI_OSTS_INTR_VALID	0x00000002
104 
105 /*
106  * Firmware state values.  Found in OMSG0 during initialization.
107  */
108 #define MFI_FWSTATE_MASK		0xf0000000
109 #define MFI_FWSTATE_UNDEFINED		0x00000000
110 #define MFI_FWSTATE_BB_INIT		0x10000000
111 #define MFI_FWSTATE_FW_INIT		0x40000000
112 #define MFI_FWSTATE_WAIT_HANDSHAKE	0x60000000
113 #define MFI_FWSTATE_FW_INIT_2		0x70000000
114 #define MFI_FWSTATE_DEVICE_SCAN		0x80000000
115 #define MFI_FWSTATE_FLUSH_CACHE		0xa0000000
116 #define MFI_FWSTATE_READY		0xb0000000
117 #define MFI_FWSTATE_OPERATIONAL		0xc0000000
118 #define MFI_FWSTATE_FAULT		0xf0000000
119 #define MFI_FWSTATE_MAXSGL_MASK		0x00ff0000
120 #define MFI_FWSTATE_MAXCMD_MASK		0x0000ffff
121 
122 /*
123  * Control bits to drive the card to ready state.  These go into the IDB
124  * register.
125  */
126 #define MFI_FWINIT_ABORT	0x00000000 /* Abort all pending commands */
127 #define MFI_FWINIT_READY	0x00000002 /* Move from operational to ready */
128 #define MFI_FWINIT_MFIMODE	0x00000004 /* unknown */
129 #define MFI_FWINIT_CLEAR_HANDSHAKE 0x00000008 /* Respond to WAIT_HANDSHAKE */
130 
131 /* MFI Commands */
132 typedef enum {
133 	MFI_CMD_INIT =		0x00,
134 	MFI_CMD_LD_READ,
135 	MFI_CMD_LD_WRITE,
136 	MFI_CMD_LD_SCSI_IO,
137 	MFI_CMD_PD_SCSI_IO,
138 	MFI_CMD_DCMD,
139 	MFI_CMD_ABORT,
140 	MFI_CMD_SMP,
141 	MFI_CMD_STP
142 } mfi_cmd_t;
143 
144 /* Direct commands */
145 typedef enum {
146 	MFI_DCMD_CTRL_GETINFO =		0x01010000,
147 	MFI_DCMD_CTRL_MFC_DEFAULTS_GET =0x010e0201,
148 	MFI_DCMD_CTRL_MFC_DEFAULTS_SET =0x010e0202,
149 	MFI_DCMD_CTRL_FLUSHCACHE =	0x01101000,
150 	MFI_DCMD_CTRL_SHUTDOWN =	0x01050000,
151 	MFI_DCMD_CTRL_EVENT_GETINFO =	0x01040100,
152 	MFI_DCMD_CTRL_EVENT_GET =	0x01040300,
153 	MFI_DCMD_CTRL_EVENT_WAIT =	0x01040500,
154 	MFI_DCMD_PR_GET_STATUS =	0x01070100,
155 	MFI_DCMD_PR_GET_PROPERTIES =	0x01070200,
156 	MFI_DCMD_PR_SET_PROPERTIES =	0x01070300,
157 	MFI_DCMD_PR_START =		0x01070400,
158 	MFI_DCMD_PR_STOP =		0x01070500,
159 	MFI_DCMD_TIME_SECS_GET =	0x01080201,
160 	MFI_DCMD_FLASH_FW_OPEN =	0x010f0100,
161 	MFI_DCMD_FLASH_FW_DOWNLOAD =	0x010f0200,
162 	MFI_DCMD_FLASH_FW_FLASH =	0x010f0300,
163 	MFI_DCMD_FLASH_FW_CLOSE =	0x010f0400,
164 	MFI_DCMD_PD_GET_LIST =		0x02010000,
165 	MFI_DCMD_PD_GET_INFO = 		0x02020000,
166 	MFI_DCMD_PD_STATE_SET =		0x02030100,
167 	MFI_DCMD_PD_REBUILD_START =	0x02040100,
168 	MFI_DCMD_PD_REBUILD_ABORT =	0x02040200,
169 	MFI_DCMD_PD_CLEAR_START =	0x02050100,
170 	MFI_DCMD_PD_CLEAR_ABORT =	0x02050200,
171 	MFI_DCMD_PD_GET_PROGRESS =	0x02060000,
172 	MFI_DCMD_PD_LOCATE_START =	0x02070100,
173 	MFI_DCMD_PD_LOCATE_STOP =	0x02070200,
174 	MFI_DCMD_LD_GET_LIST =		0x03010000,
175 	MFI_DCMD_LD_GET_INFO =		0x03020000,
176 	MFI_DCMD_LD_GET_PROP =		0x03030000,
177 	MFI_DCMD_LD_SET_PROP =		0x03040000,
178 	MFI_DCMD_LD_INIT_START =	0x03060100,
179 	MFI_DCMD_LD_DELETE =		0x03090000,
180 	MFI_DCMD_CFG_READ =		0x04010000,
181 	MFI_DCMD_CFG_ADD =		0x04020000,
182 	MFI_DCMD_CFG_CLEAR =		0x04030000,
183 	MFI_DCMD_CFG_MAKE_SPARE =	0x04040000,
184 	MFI_DCMD_CFG_REMOVE_SPARE =	0x04050000,
185 	MFI_DCMD_CFG_FOREIGN_IMPORT =	0x04060400,
186 	MFI_DCMD_BBU_GET_STATUS =	0x05010000,
187 	MFI_DCMD_BBU_GET_CAPACITY_INFO =0x05020000,
188 	MFI_DCMD_BBU_GET_DESIGN_INFO =	0x05030000,
189 	MFI_DCMD_CLUSTER =		0x08000000,
190 	MFI_DCMD_CLUSTER_RESET_ALL =	0x08010100,
191 	MFI_DCMD_CLUSTER_RESET_LD =	0x08010200
192 } mfi_dcmd_t;
193 
194 /* Modifiers for MFI_DCMD_CTRL_FLUSHCACHE */
195 #define MFI_FLUSHCACHE_CTRL	0x01
196 #define MFI_FLUSHCACHE_DISK	0x02
197 
198 /* Modifiers for MFI_DCMD_CTRL_SHUTDOWN */
199 #define MFI_SHUTDOWN_SPINDOWN	0x01
200 
201 /*
202  * MFI Frame flags
203  */
204 #define MFI_FRAME_POST_IN_REPLY_QUEUE		0x0000
205 #define MFI_FRAME_DONT_POST_IN_REPLY_QUEUE	0x0001
206 #define MFI_FRAME_SGL32				0x0000
207 #define MFI_FRAME_SGL64				0x0002
208 #define MFI_FRAME_SENSE32			0x0000
209 #define MFI_FRAME_SENSE64			0x0004
210 #define MFI_FRAME_DIR_NONE			0x0000
211 #define MFI_FRAME_DIR_WRITE			0x0008
212 #define MFI_FRAME_DIR_READ			0x0010
213 #define MFI_FRAME_DIR_BOTH			0x0018
214 
215 /* MFI Status codes */
216 typedef enum {
217 	MFI_STAT_OK =			0x00,
218 	MFI_STAT_INVALID_CMD,
219 	MFI_STAT_INVALID_DCMD,
220 	MFI_STAT_INVALID_PARAMETER,
221 	MFI_STAT_INVALID_SEQUENCE_NUMBER,
222 	MFI_STAT_ABORT_NOT_POSSIBLE,
223 	MFI_STAT_APP_HOST_CODE_NOT_FOUND,
224 	MFI_STAT_APP_IN_USE,
225 	MFI_STAT_APP_NOT_INITIALIZED,
226 	MFI_STAT_ARRAY_INDEX_INVALID,
227 	MFI_STAT_ARRAY_ROW_NOT_EMPTY,
228 	MFI_STAT_CONFIG_RESOURCE_CONFLICT,
229 	MFI_STAT_DEVICE_NOT_FOUND,
230 	MFI_STAT_DRIVE_TOO_SMALL,
231 	MFI_STAT_FLASH_ALLOC_FAIL,
232 	MFI_STAT_FLASH_BUSY,
233 	MFI_STAT_FLASH_ERROR =		0x10,
234 	MFI_STAT_FLASH_IMAGE_BAD,
235 	MFI_STAT_FLASH_IMAGE_INCOMPLETE,
236 	MFI_STAT_FLASH_NOT_OPEN,
237 	MFI_STAT_FLASH_NOT_STARTED,
238 	MFI_STAT_FLUSH_FAILED,
239 	MFI_STAT_HOST_CODE_NOT_FOUNT,
240 	MFI_STAT_LD_CC_IN_PROGRESS,
241 	MFI_STAT_LD_INIT_IN_PROGRESS,
242 	MFI_STAT_LD_LBA_OUT_OF_RANGE,
243 	MFI_STAT_LD_MAX_CONFIGURED,
244 	MFI_STAT_LD_NOT_OPTIMAL,
245 	MFI_STAT_LD_RBLD_IN_PROGRESS,
246 	MFI_STAT_LD_RECON_IN_PROGRESS,
247 	MFI_STAT_LD_WRONG_RAID_LEVEL,
248 	MFI_STAT_MAX_SPARES_EXCEEDED,
249 	MFI_STAT_MEMORY_NOT_AVAILABLE =	0x20,
250 	MFI_STAT_MFC_HW_ERROR,
251 	MFI_STAT_NO_HW_PRESENT,
252 	MFI_STAT_NOT_FOUND,
253 	MFI_STAT_NOT_IN_ENCL,
254 	MFI_STAT_PD_CLEAR_IN_PROGRESS,
255 	MFI_STAT_PD_TYPE_WRONG,
256 	MFI_STAT_PR_DISABLED,
257 	MFI_STAT_ROW_INDEX_INVALID,
258 	MFI_STAT_SAS_CONFIG_INVALID_ACTION,
259 	MFI_STAT_SAS_CONFIG_INVALID_DATA,
260 	MFI_STAT_SAS_CONFIG_INVALID_PAGE,
261 	MFI_STAT_SAS_CONFIG_INVALID_TYPE,
262 	MFI_STAT_SCSI_DONE_WITH_ERROR,
263 	MFI_STAT_SCSI_IO_FAILED,
264 	MFI_STAT_SCSI_RESERVATION_CONFLICT,
265 	MFI_STAT_SHUTDOWN_FAILED =	0x30,
266 	MFI_STAT_TIME_NOT_SET,
267 	MFI_STAT_WRONG_STATE,
268 	MFI_STAT_LD_OFFLINE,
269 	MFI_STAT_PEER_NOTIFICATION_REJECTED,
270 	MFI_STAT_PEER_NOTIFICATION_FAILED,
271 	MFI_STAT_RESERVATION_IN_PROGRESS,
272 	MFI_STAT_I2C_ERRORS_DETECTED,
273 	MFI_STAT_PCI_ERRORS_DETECTED,
274 	MFI_STAT_DIAG_FAILED,
275 	MFI_STAT_BOOT_MSG_PENDING,
276 	MFI_STAT_FOREIGN_CONFIG_INCOMPLETE,
277 	MFI_STAT_INVALID_STATUS =	0xFF
278 } mfi_status_t;
279 
280 typedef enum {
281 	MFI_EVT_CLASS_DEBUG =		-2,
282 	MFI_EVT_CLASS_PROGRESS =	-1,
283 	MFI_EVT_CLASS_INFO =		0,
284 	MFI_EVT_CLASS_WARNING =		1,
285 	MFI_EVT_CLASS_CRITICAL =	2,
286 	MFI_EVT_CLASS_FATAL =		3,
287 	MFI_EVT_CLASS_DEAD =		4
288 } mfi_evt_class_t;
289 
290 typedef enum {
291 	MFI_EVT_LOCALE_LD =		0x0001,
292 	MFI_EVT_LOCALE_PD =		0x0002,
293 	MFI_EVT_LOCALE_ENCL =		0x0004,
294 	MFI_EVT_LOCALE_BBU =		0x0008,
295 	MFI_EVT_LOCALE_SAS =		0x0010,
296 	MFI_EVT_LOCALE_CTRL =		0x0020,
297 	MFI_EVT_LOCALE_CONFIG =		0x0040,
298 	MFI_EVT_LOCALE_CLUSTER =	0x0080,
299 	MFI_EVT_LOCALE_ALL =		0xffff
300 } mfi_evt_locale_t;
301 
302 typedef enum {
303 	MR_EVT_ARGS_NONE =		0x00,
304 	MR_EVT_ARGS_CDB_SENSE,
305 	MR_EVT_ARGS_LD,
306 	MR_EVT_ARGS_LD_COUNT,
307 	MR_EVT_ARGS_LD_LBA,
308 	MR_EVT_ARGS_LD_OWNER,
309 	MR_EVT_ARGS_LD_LBA_PD_LBA,
310 	MR_EVT_ARGS_LD_PROG,
311 	MR_EVT_ARGS_LD_STATE,
312 	MR_EVT_ARGS_LD_STRIP,
313 	MR_EVT_ARGS_PD,
314 	MR_EVT_ARGS_PD_ERR,
315 	MR_EVT_ARGS_PD_LBA,
316 	MR_EVT_ARGS_PD_LBA_LD,
317 	MR_EVT_ARGS_PD_PROG,
318 	MR_EVT_ARGS_PD_STATE,
319 	MR_EVT_ARGS_PCI,
320 	MR_EVT_ARGS_RATE,
321 	MR_EVT_ARGS_STR,
322 	MR_EVT_ARGS_TIME,
323 	MR_EVT_ARGS_ECC
324 } mfi_evt_args;
325 
326 typedef enum {
327 	MR_LD_CACHE_WRITE_BACK =	0x01,
328 	MR_LD_CACHE_WRITE_ADAPTIVE =	0x02,
329 	MR_LD_CACHE_READ_AHEAD =	0x04,
330 	MR_LD_CACHE_READ_ADAPTIVE =	0x08,
331 	MR_LD_CACHE_WRITE_CACHE_BAD_BBU=0x10,
332 	MR_LD_CACHE_ALLOW_WRITE_CACHE =	0x20,
333 	MR_LD_CACHE_ALLOW_READ_CACHE =	0x40
334 } mfi_ld_cache;
335 #define	MR_LD_CACHE_MASK	0x7f
336 
337 #define	MR_LD_CACHE_POLICY_READ_AHEAD_NONE		0
338 #define	MR_LD_CACHE_POLICY_READ_AHEAD_ALWAYS		MR_LD_CACHE_READ_AHEAD
339 #define	MR_LD_CACHE_POLICY_READ_AHEAD_ADAPTIVE		\
340 	(MR_LD_CACHE_READ_AHEAD | MR_LD_CACHE_READ_ADAPTIVE)
341 #define	MR_LD_CACHE_POLICY_WRITE_THROUGH		0
342 #define	MR_LD_CACHE_POLICY_WRITE_BACK			MR_LD_CACHE_WRITE_BACK
343 #define	MR_LD_CACHE_POLICY_IO_CACHED			\
344 	(MR_LD_CACHE_ALLOW_WRITE_CACHE | MR_LD_CACHE_ALLOW_READ_CACHE)
345 #define	MR_LD_CACHE_POLICY_IO_DIRECT			0
346 
347 typedef enum {
348 	MR_PD_CACHE_UNCHANGED  =	0,
349 	MR_PD_CACHE_ENABLE =		1,
350 	MR_PD_CACHE_DISABLE =		2
351 } mfi_pd_cache;
352 
353 /*
354  * Other propertities and definitions
355  */
356 #define MFI_MAX_PD_CHANNELS	2
357 #define MFI_MAX_LD_CHANNELS	2
358 #define MFI_MAX_CHANNELS	(MFI_MAX_PD_CHANNELS + MFI_MAX_LD_CHANNELS)
359 #define MFI_MAX_CHANNEL_DEVS	128
360 #define MFI_DEFAULT_ID		-1
361 #define MFI_MAX_LUN		8
362 #define MFI_MAX_LD		64
363 #define	MFI_MAX_PD		256
364 
365 #define MFI_FRAME_SIZE		64
366 #define MFI_MBOX_SIZE		12
367 
368 /* Firmware flashing can take 40s */
369 #define MFI_POLL_TIMEOUT_SECS	50
370 
371 /* Allow for speedier math calculations */
372 #define MFI_SECTOR_LEN		512
373 
374 /* Scatter Gather elements */
375 struct mfi_sg32 {
376 	uint32_t	addr;
377 	uint32_t	len;
378 } __packed;
379 
380 struct mfi_sg64 {
381 	uint64_t	addr;
382 	uint32_t	len;
383 } __packed;
384 
385 union mfi_sgl {
386 	struct mfi_sg32	sg32[1];
387 	struct mfi_sg64	sg64[1];
388 } __packed;
389 
390 /* Message frames.  All messages have a common header */
391 struct mfi_frame_header {
392 	uint8_t		cmd;
393 	uint8_t		sense_len;
394 	uint8_t		cmd_status;
395 	uint8_t		scsi_status;
396 	uint8_t		target_id;
397 	uint8_t		lun_id;
398 	uint8_t		cdb_len;
399 	uint8_t		sg_count;
400 	uint32_t	context;
401 	uint32_t	pad0;
402 	uint16_t	flags;
403 #define MFI_FRAME_DATAOUT	0x08
404 #define MFI_FRAME_DATAIN	0x10
405 	uint16_t	timeout;
406 	uint32_t	data_len;
407 } __packed;
408 
409 struct mfi_init_frame {
410 	struct mfi_frame_header	header;
411 	uint32_t	qinfo_new_addr_lo;
412 	uint32_t	qinfo_new_addr_hi;
413 	uint32_t	qinfo_old_addr_lo;
414 	uint32_t	qinfo_old_addr_hi;
415 	uint32_t	reserved[6];
416 } __packed;
417 
418 #define MFI_IO_FRAME_SIZE 40
419 struct mfi_io_frame {
420 	struct mfi_frame_header	header;
421 	uint32_t	sense_addr_lo;
422 	uint32_t	sense_addr_hi;
423 	uint32_t	lba_lo;
424 	uint32_t	lba_hi;
425 	union mfi_sgl	sgl;
426 } __packed;
427 
428 #define MFI_PASS_FRAME_SIZE 48
429 struct mfi_pass_frame {
430 	struct mfi_frame_header header;
431 	uint32_t	sense_addr_lo;
432 	uint32_t	sense_addr_hi;
433 	uint8_t		cdb[16];
434 	union mfi_sgl	sgl;
435 } __packed;
436 
437 #define MFI_DCMD_FRAME_SIZE 40
438 struct mfi_dcmd_frame {
439 	struct mfi_frame_header header;
440 	uint32_t	opcode;
441 	uint8_t		mbox[MFI_MBOX_SIZE];
442 	union mfi_sgl	sgl;
443 } __packed;
444 
445 struct mfi_abort_frame {
446 	struct mfi_frame_header header;
447 	uint32_t	abort_context;
448 	uint32_t	pad;
449 	uint32_t	abort_mfi_addr_lo;
450 	uint32_t	abort_mfi_addr_hi;
451 	uint32_t	reserved[6];
452 } __packed;
453 
454 struct mfi_smp_frame {
455 	struct mfi_frame_header header;
456 	uint64_t	sas_addr;
457 	union {
458 		struct mfi_sg32 sg32[2];
459 		struct mfi_sg64 sg64[2];
460 	} sgl;
461 } __packed;
462 
463 struct mfi_stp_frame {
464 	struct mfi_frame_header header;
465 	uint16_t	fis[10];
466 	uint32_t	stp_flags;
467 	union {
468 		struct mfi_sg32 sg32[2];
469 		struct mfi_sg64 sg64[2];
470 	} sgl;
471 } __packed;
472 
473 union mfi_frame {
474 	struct mfi_frame_header header;
475 	struct mfi_init_frame	init;
476 	struct mfi_io_frame	io;
477 	struct mfi_pass_frame	pass;
478 	struct mfi_dcmd_frame	dcmd;
479 	struct mfi_abort_frame	abort;
480 	struct mfi_smp_frame	smp;
481 	struct mfi_stp_frame	stp;
482 	uint8_t			bytes[MFI_FRAME_SIZE];
483 };
484 
485 #define MFI_SENSE_LEN 128
486 struct mfi_sense {
487 	uint8_t		data[MFI_SENSE_LEN];
488 };
489 
490 /* The queue init structure that is passed with the init message */
491 struct mfi_init_qinfo {
492 	uint32_t	flags;
493 	uint32_t	rq_entries;
494 	uint32_t	rq_addr_lo;
495 	uint32_t	rq_addr_hi;
496 	uint32_t	pi_addr_lo;
497 	uint32_t	pi_addr_hi;
498 	uint32_t	ci_addr_lo;
499 	uint32_t	ci_addr_hi;
500 } __packed;
501 
502 /* SAS (?) controller properties, part of mfi_ctrl_info */
503 struct mfi_ctrl_props {
504 	uint16_t	seq_num;
505 	uint16_t	pred_fail_poll_interval;
506 	uint16_t	intr_throttle_cnt;
507 	uint16_t	intr_throttle_timeout;
508 	uint8_t		rebuild_rate;
509 	uint8_t		patrol_read_rate;
510 	uint8_t		bgi_rate;
511 	uint8_t		cc_rate;
512 	uint8_t		recon_rate;
513 	uint8_t		cache_flush_interval;
514 	uint8_t		spinup_drv_cnt;
515 	uint8_t		spinup_delay;
516 	uint8_t		cluster_enable;
517 	uint8_t		coercion_mode;
518 	uint8_t		alarm_enable;
519 	uint8_t		disable_auto_rebuild;
520 	uint8_t		disable_battery_warn;
521 	uint8_t		ecc_bucket_size;
522 	uint16_t	ecc_bucket_leak_rate;
523 	uint8_t		restore_hotspare_on_insertion;
524 	uint8_t		expose_encl_devices;
525 	uint8_t		reserved[38];
526 } __packed;
527 
528 /* PCI information about the card. */
529 struct mfi_info_pci {
530 	uint16_t	vendor;
531 	uint16_t	device;
532 	uint16_t	subvendor;
533 	uint16_t	subdevice;
534 	uint8_t		reserved[24];
535 } __packed;
536 
537 /* Host (front end) interface information */
538 struct mfi_info_host {
539 	uint8_t		type;
540 #define MFI_INFO_HOST_PCIX	0x01
541 #define MFI_INFO_HOST_PCIE	0x02
542 #define MFI_INFO_HOST_ISCSI	0x04
543 #define MFI_INFO_HOST_SAS3G	0x08
544 	uint8_t		reserved[6];
545 	uint8_t		port_count;
546 	uint64_t	port_addr[8];
547 } __packed;
548 
549 /* Device (back end) interface information */
550 struct mfi_info_device {
551 	uint8_t		type;
552 #define MFI_INFO_DEV_SPI	0x01
553 #define MFI_INFO_DEV_SAS3G	0x02
554 #define MFI_INFO_DEV_SATA1	0x04
555 #define MFI_INFO_DEV_SATA3G	0x08
556 	uint8_t		reserved[6];
557 	uint8_t		port_count;
558 	uint64_t	port_addr[8];
559 } __packed;
560 
561 /* Firmware component information */
562 struct mfi_info_component {
563 	char		 name[8];
564 	char		 version[32];
565 	char		 build_date[16];
566 	char		 build_time[16];
567 } __packed;
568 
569 /* Controller default settings */
570 struct mfi_defaults {
571 	uint64_t	sas_addr;
572 	uint8_t		phy_polarity;
573 	uint8_t		background_rate;
574 	uint8_t		stripe_size;
575 	uint8_t		flush_time;
576 	uint8_t		write_back;
577 	uint8_t		read_ahead;
578 	uint8_t		cache_when_bbu_bad;
579 	uint8_t		cached_io;
580 	uint8_t		smart_mode;
581 	uint8_t		alarm_disable;
582 	uint8_t		coercion;
583 	uint8_t		zrc_config;
584 	uint8_t		dirty_led_shows_drive_activity;
585 	uint8_t		bios_continue_on_error;
586 	uint8_t		spindown_mode;
587 	uint8_t		allowed_device_types;
588 	uint8_t		allow_mix_in_enclosure;
589 	uint8_t		allow_mix_in_ld;
590 	uint8_t		allow_sata_in_cluster;
591 	uint8_t		max_chained_enclosures;
592 	uint8_t		disable_ctrl_r;
593 	uint8_t		enabel_web_bios;
594 	uint8_t		phy_polarity_split;
595 	uint8_t		direct_pd_mapping;
596 	uint8_t		bios_enumerate_lds;
597 	uint8_t		restored_hot_spare_on_insertion;
598 	uint8_t		expose_enclosure_devices;
599 	uint8_t		maintain_pd_fail_history;
600 	uint8_t		resv[28];
601 } __packed;
602 
603 /* Controller default settings */
604 struct mfi_bios_data {
605 	uint16_t	boot_target_id;
606 	uint8_t		do_not_int_13;
607 	uint8_t		continue_on_error;
608 	uint8_t		verbose;
609 	uint8_t		geometry;
610 	uint8_t		expose_all_drives;
611 	uint8_t		reserved[56];
612 	uint8_t		check_sum;
613 } __packed;
614 
615 /* SAS (?) controller info, returned from MFI_DCMD_CTRL_GETINFO. */
616 struct mfi_ctrl_info {
617 	struct mfi_info_pci	pci;
618 	struct mfi_info_host	host;
619 	struct mfi_info_device	device;
620 
621 	/* Firmware components that are present and active. */
622 	uint32_t		image_check_word;
623 	uint32_t		image_component_count;
624 	struct mfi_info_component image_component[8];
625 
626 	/* Firmware components that have been flashed but are inactive */
627 	uint32_t		pending_image_component_count;
628 	struct mfi_info_component pending_image_component[8];
629 
630 	uint8_t			max_arms;
631 	uint8_t			max_spans;
632 	uint8_t			max_arrays;
633 	uint8_t			max_lds;
634 	char			product_name[80];
635 	char			serial_number[32];
636 	uint32_t		hw_present;
637 #define MFI_INFO_HW_BBU		0x01
638 #define MFI_INFO_HW_ALARM	0x02
639 #define MFI_INFO_HW_NVRAM	0x04
640 #define MFI_INFO_HW_UART	0x08
641 	uint32_t		current_fw_time;
642 	uint16_t		max_cmds;
643 	uint16_t		max_sg_elements;
644 	uint32_t		max_request_size;
645 	uint16_t		lds_present;
646 	uint16_t		lds_degraded;
647 	uint16_t		lds_offline;
648 	uint16_t		pd_present;
649 	uint16_t		pd_disks_present;
650 	uint16_t		pd_disks_pred_failure;
651 	uint16_t		pd_disks_failed;
652 	uint16_t		nvram_size;
653 	uint16_t		memory_size;
654 	uint16_t		flash_size;
655 	uint16_t		ram_correctable_errors;
656 	uint16_t		ram_uncorrectable_errors;
657 	uint8_t			cluster_allowed;
658 	uint8_t			cluster_active;
659 	uint16_t		max_strips_per_io;
660 
661 	uint32_t		raid_levels;
662 #define MFI_INFO_RAID_0		0x01
663 #define MFI_INFO_RAID_1		0x02
664 #define MFI_INFO_RAID_5		0x04
665 #define MFI_INFO_RAID_1E	0x08
666 #define MFI_INFO_RAID_6		0x10
667 
668 	uint32_t		adapter_ops;
669 #define MFI_INFO_AOPS_RBLD_RATE		0x0001
670 #define MFI_INFO_AOPS_CC_RATE		0x0002
671 #define MFI_INFO_AOPS_BGI_RATE		0x0004
672 #define MFI_INFO_AOPS_RECON_RATE	0x0008
673 #define MFI_INFO_AOPS_PATROL_RATE	0x0010
674 #define MFI_INFO_AOPS_ALARM_CONTROL	0x0020
675 #define MFI_INFO_AOPS_CLUSTER_SUPPORTED	0x0040
676 #define MFI_INFO_AOPS_BBU		0x0080
677 #define MFI_INFO_AOPS_SPANNING_ALLOWED	0x0100
678 #define MFI_INFO_AOPS_DEDICATED_SPARES	0x0200
679 #define MFI_INFO_AOPS_REVERTIBLE_SPARES	0x0400
680 #define MFI_INFO_AOPS_FOREIGN_IMPORT	0x0800
681 #define MFI_INFO_AOPS_SELF_DIAGNOSTIC	0x1000
682 #define MFI_INFO_AOPS_MIXED_ARRAY	0x2000
683 #define MFI_INFO_AOPS_GLOBAL_SPARES	0x4000
684 
685 	uint32_t		ld_ops;
686 #define MFI_INFO_LDOPS_READ_POLICY	0x01
687 #define MFI_INFO_LDOPS_WRITE_POLICY	0x02
688 #define MFI_INFO_LDOPS_IO_POLICY	0x04
689 #define MFI_INFO_LDOPS_ACCESS_POLICY	0x08
690 #define MFI_INFO_LDOPS_DISK_CACHE_POLICY 0x10
691 
692 	struct {
693 		uint8_t		min;
694 		uint8_t		max;
695 		uint8_t		reserved[2];
696 	} __packed stripe_sz_ops;
697 
698 	uint32_t		pd_ops;
699 #define MFI_INFO_PDOPS_FORCE_ONLINE	0x01
700 #define MFI_INFO_PDOPS_FORCE_OFFLINE	0x02
701 #define MFI_INFO_PDOPS_FORCE_REBUILD	0x04
702 
703 	uint32_t		pd_mix_support;
704 #define MFI_INFO_PDMIX_SAS		0x01
705 #define MFI_INFO_PDMIX_SATA		0x02
706 #define MFI_INFO_PDMIX_ENCL		0x04
707 #define MFI_INFO_PDMIX_LD		0x08
708 #define MFI_INFO_PDMIX_SATA_CLUSTER	0x10
709 
710 	uint8_t			ecc_bucket_count;
711 	uint8_t			reserved2[11];
712 	struct mfi_ctrl_props	properties;
713 	char			package_version[0x60];
714 	uint8_t			pad[0x800 - 0x6a0];
715 } __packed;
716 
717 /* keep track of an event. */
718 union mfi_evt {
719 	struct {
720 		uint16_t	locale;
721 		uint8_t		reserved;
722 		int8_t		class;
723 	} members;
724 	uint32_t		word;
725 } __packed;
726 
727 /* event log state. */
728 struct mfi_evt_log_state {
729 	uint32_t		newest_seq_num;
730 	uint32_t		oldest_seq_num;
731 	uint32_t		clear_seq_num;
732 	uint32_t		shutdown_seq_num;
733 	uint32_t		boot_seq_num;
734 } __packed;
735 
736 struct mfi_progress {
737 	uint16_t		progress;
738 	uint16_t		elapsed_seconds;
739 } __packed;
740 
741 struct mfi_evt_ld {
742 	uint16_t		target_id;
743 	uint8_t			ld_index;
744 	uint8_t			reserved;
745 } __packed;
746 
747 struct mfi_evt_pd {
748 	uint16_t		device_id;
749 	uint8_t			enclosure_index;
750 	uint8_t			slot_number;
751 } __packed;
752 
753 /* SAS (?) event detail, returned from MFI_DCMD_CTRL_EVENT_WAIT. */
754 struct mfi_evt_detail {
755 	uint32_t		seq;
756 	uint32_t		time;
757 	uint32_t		code;
758 	union mfi_evt		class;
759 	uint8_t			arg_type;
760 	uint8_t			reserved1[15];
761 
762 	union {
763 		struct {
764 			struct mfi_evt_pd	pd;
765 			uint8_t			cdb_len;
766 			uint8_t			sense_len;
767 			uint8_t			reserved[2];
768 			uint8_t			cdb[16];
769 			uint8_t			sense[64];
770 		} cdb_sense;
771 
772 		struct mfi_evt_ld		ld;
773 
774 		struct {
775 			struct mfi_evt_ld	ld;
776 			uint64_t		count;
777 		} ld_count;
778 
779 		struct {
780 			uint64_t		lba;
781 			struct mfi_evt_ld	ld;
782 		} ld_lba;
783 
784 		struct {
785 			struct mfi_evt_ld	ld;
786 			uint32_t		pre_owner;
787 			uint32_t		new_owner;
788 		} ld_owner;
789 
790 		struct {
791 			uint64_t		ld_lba;
792 			uint64_t		pd_lba;
793 			struct mfi_evt_ld	ld;
794 			struct mfi_evt_pd	pd;
795 		} ld_lba_pd_lba;
796 
797 		struct {
798 			struct mfi_evt_ld	ld;
799 			struct mfi_progress	prog;
800 		} ld_prog;
801 
802 		struct {
803 			struct mfi_evt_ld	ld;
804 			uint32_t		prev_state;
805 			uint32_t		new_state;
806 		} ld_state;
807 
808 		struct {
809 			uint64_t		strip;
810 			struct mfi_evt_ld	ld;
811 		} ld_strip;
812 
813 		struct mfi_evt_pd		pd;
814 
815 		struct {
816 			struct mfi_evt_pd	pd;
817 			uint32_t		err;
818 		} pd_err;
819 
820 		struct {
821 			uint64_t		lba;
822 			struct mfi_evt_pd	pd;
823 		} pd_lba;
824 
825 		struct {
826 			uint64_t		lba;
827 			struct mfi_evt_pd	pd;
828 			struct mfi_evt_ld	ld;
829 		} pd_lba_ld;
830 
831 		struct {
832 			struct mfi_evt_pd	pd;
833 			struct mfi_progress	prog;
834 		} pd_prog;
835 
836 		struct {
837 			struct mfi_evt_pd	ld;
838 			uint32_t		prev_state;
839 			uint32_t		new_state;
840 		} pd_state;
841 
842 		struct {
843 			uint16_t		venderId;
844 			uint16_t		deviceId;
845 			uint16_t		subVenderId;
846 			uint16_t		subDeviceId;
847 		} pci;
848 
849 		uint32_t			rate;
850 
851 		char				str[96];
852 
853 		struct {
854 			uint32_t		rtc;
855 			uint16_t		elapsedSeconds;
856 		} time;
857 
858 		struct {
859 			uint32_t		ecar;
860 			uint32_t		elog;
861 			char			str[64];
862 		} ecc;
863 
864 		uint8_t		b[96];
865 		uint16_t	s[48];
866 		uint32_t	w[24];
867 		uint64_t	d[12];
868 	} args;
869 
870 	char description[128];
871 } __packed;
872 
873 struct mfi_evt_list {
874 	uint32_t		count;
875 	uint32_t		reserved;
876 	struct mfi_evt_detail	event[1];
877 } __packed;
878 
879 union mfi_pd_ref {
880 	struct {
881 		uint16_t	device_id;
882 		uint16_t	seq_num;
883 	} v;
884 	uint32_t	ref;
885 } __packed;
886 
887 union mfi_pd_ddf_type {
888 	struct {
889 		union {
890 			struct {
891 				uint16_t	forced_pd_guid	: 1;
892 				uint16_t	in_vd		: 1;
893 				uint16_t	is_global_spare	: 1;
894 				uint16_t	is_spare	: 1;
895 				uint16_t	is_foreign	: 1;
896 				uint16_t	reserved	: 7;
897 				uint16_t	intf		: 4;
898 			} pd_type;
899 			uint16_t	type;
900 		} v;
901 		uint16_t		reserved;
902 	} ddf;
903 	struct {
904 		uint32_t		reserved;
905 	} non_disk;
906 	uint32_t			type;
907 } __packed;
908 
909 struct mfi_pd_progress {
910 	uint32_t			active;
911 #define	MFI_PD_PROGRESS_REBUILD	(1<<0)
912 #define	MFI_PD_PROGRESS_PATROL	(1<<1)
913 #define	MFI_PD_PROGRESS_CLEAR	(1<<2)
914 	struct mfi_progress		rbld;
915 	struct mfi_progress		patrol;
916 	struct mfi_progress		clear;
917 	struct mfi_progress		reserved[4];
918 } __packed;
919 
920 struct mfi_pd_info {
921 	union mfi_pd_ref		ref;
922 	uint8_t				inquiry_data[96];
923 	uint8_t				vpd_page83[64];
924 	uint8_t				not_supported;
925 	uint8_t				scsi_dev_type;
926 	uint8_t				connected_port_bitmap;
927 	uint8_t				device_speed;
928 	uint32_t			media_err_count;
929 	uint32_t			other_err_count;
930 	uint32_t			pred_fail_count;
931 	uint32_t			last_pred_fail_event_seq_num;
932 	uint16_t			fw_state;	/* MFI_PD_STATE_* */
933 	uint8_t				disabled_for_removal;
934 	uint8_t				link_speed;
935 	union mfi_pd_ddf_type		state;
936 	struct {
937 		uint8_t			count;
938 		uint8_t			is_path_broken;
939 		uint8_t			reserved[6];
940 		uint64_t		sas_addr[4];
941 	} path_info;
942 	uint64_t			raw_size;
943 	uint64_t			non_coerced_size;
944 	uint64_t			coerced_size;
945 	uint16_t			encl_device_id;
946 	uint8_t				encl_index;
947 	uint8_t				slot_number;
948 	struct mfi_pd_progress		prog_info;
949 	uint8_t				bad_block_table_full;
950 	uint8_t				unusable_in_current_config;
951 	uint8_t				vpd_page83_ext[64];
952 	uint8_t				reserved[512-358];
953 } __packed;
954 
955 struct mfi_pd_address {
956 	uint16_t		device_id;
957 	uint16_t		encl_device_id;
958 	uint8_t			encl_index;
959 	uint8_t			slot_number;
960 	uint8_t			scsi_dev_type;	/* 0 = disk */
961 	uint8_t			connect_port_bitmap;
962 	uint64_t		sas_addr[2];
963 } __packed;
964 
965 struct mfi_pd_list {
966 	uint32_t		size;
967 	uint32_t		count;
968 	struct mfi_pd_address	addr[0];
969 } __packed;
970 
971 enum mfi_pd_state {
972 	MFI_PD_STATE_UNCONFIGURED_GOOD = 0x00,
973 	MFI_PD_STATE_UNCONFIGURED_BAD = 0x01,
974 	MFI_PD_STATE_HOT_SPARE = 0x02,
975 	MFI_PD_STATE_OFFLINE = 0x10,
976 	MFI_PD_STATE_FAILED = 0x11,
977 	MFI_PD_STATE_REBUILD = 0x14,
978 	MFI_PD_STATE_ONLINE = 0x18
979 };
980 
981 union mfi_ld_ref {
982 	struct {
983 		uint8_t		target_id;
984 		uint8_t		reserved;
985 		uint16_t	seq;
986 	} v;
987 	uint32_t		ref;
988 } __packed;
989 
990 struct mfi_ld_list {
991 	uint32_t		ld_count;
992 	uint32_t		reserved1;
993 	struct {
994 		union mfi_ld_ref	ld;
995 		uint8_t		state;
996 		uint8_t		reserved2[3];
997 		uint64_t	size;
998 	} ld_list[MFI_MAX_LD];
999 } __packed;
1000 
1001 enum mfi_ld_access {
1002 	MFI_LD_ACCESS_RW =	0,
1003 	MFI_LD_ACCSSS_RO = 	2,
1004 	MFI_LD_ACCESS_BLOCKED =	3,
1005 };
1006 #define MFI_LD_ACCESS_MASK	3
1007 
1008 enum mfi_ld_state {
1009 	MFI_LD_STATE_OFFLINE =			0,
1010 	MFI_LD_STATE_PARTIALLY_DEGRADED =	1,
1011 	MFI_LD_STATE_DEGRADED =			2,
1012 	MFI_LD_STATE_OPTIMAL =			3
1013 };
1014 
1015 struct mfi_ld_props {
1016 	union mfi_ld_ref	ld;
1017 	char			name[16];
1018 	uint8_t			default_cache_policy;
1019 	uint8_t			access_policy;
1020 	uint8_t			disk_cache_policy;
1021 	uint8_t			current_cache_policy;
1022 	uint8_t			no_bgi;
1023 	uint8_t			reserved[7];
1024 } __packed;
1025 
1026 struct mfi_ld_params {
1027 	uint8_t			primary_raid_level;
1028 	uint8_t			raid_level_qualifier;
1029 	uint8_t			secondary_raid_level;
1030 	uint8_t			stripe_size;
1031 	uint8_t			num_drives;
1032 	uint8_t			span_depth;
1033 	uint8_t			state;
1034 	uint8_t			init_state;
1035 #define	MFI_LD_PARAMS_INIT_NO		0
1036 #define	MFI_LD_PARAMS_INIT_QUICK	1
1037 #define	MFI_LD_PARAMS_INIT_FULL		2
1038 	uint8_t			is_consistent;
1039 	uint8_t			reserved[23];
1040 } __packed;
1041 
1042 struct mfi_ld_progress {
1043 	uint32_t		active;
1044 #define	MFI_LD_PROGRESS_CC	(1<<0)
1045 #define	MFI_LD_PROGRESS_BGI	(1<<1)
1046 #define	MFI_LD_PROGRESS_FGI	(1<<2)
1047 #define	MFI_LD_PROGRESS_RECON	(1<<3)
1048 	struct mfi_progress	cc;
1049 	struct mfi_progress	bgi;
1050 	struct mfi_progress	fgi;
1051 	struct mfi_progress	recon;
1052 	struct mfi_progress	reserved[4];
1053 } __packed;
1054 
1055 struct mfi_span {
1056 	uint64_t		start_block;
1057 	uint64_t		num_blocks;
1058 	uint16_t		array_ref;
1059 	uint8_t			reserved[6];
1060 } __packed;
1061 
1062 #define	MFI_MAX_SPAN_DEPTH	8
1063 struct mfi_ld_config {
1064 	struct mfi_ld_props	properties;
1065 	struct mfi_ld_params	params;
1066 	struct mfi_span		span[MFI_MAX_SPAN_DEPTH];
1067 } __packed;
1068 
1069 struct mfi_ld_info {
1070 	struct mfi_ld_config	ld_config;
1071 	uint64_t		size;
1072 	struct mfi_ld_progress	progress;
1073 	uint16_t		cluster_owner;
1074 	uint8_t			reconstruct_active;
1075 	uint8_t			reserved1[1];
1076 	uint8_t			vpd_page83[64];
1077 	uint8_t			reserved2[16];
1078 } __packed;
1079 
1080 #define MAX_ARRAYS 16
1081 struct mfi_spare {
1082 	union mfi_pd_ref	ref;
1083 	uint8_t			spare_type;
1084 #define	MFI_SPARE_DEDICATED	(1 << 0)
1085 #define	MFI_SPARE_REVERTIBLE	(1 << 1)
1086 #define	MFI_SPARE_ENCL_AFFINITY	(1 << 2)
1087 	uint8_t			reserved[2];
1088 	uint8_t			array_count;
1089 	uint16_t		array_ref[MAX_ARRAYS];
1090 } __packed;
1091 
1092 struct mfi_array {
1093 	uint64_t			size;
1094 	uint8_t				num_drives;
1095 	uint8_t				reserved;
1096 	uint16_t			array_ref;
1097 	uint8_t				pad[20];
1098 	struct {
1099 		union mfi_pd_ref	ref;	/* 0xffff == missing drive */
1100 		uint16_t		fw_state;	/* MFI_PD_STATE_* */
1101 		struct {
1102 			uint8_t		pd;
1103 			uint8_t		slot;
1104 		} encl;
1105 	} pd[0];
1106 } __packed;
1107 
1108 struct mfi_config_data {
1109 	uint32_t		size;
1110 	uint16_t		array_count;
1111 	uint16_t		array_size;
1112 	uint16_t		log_drv_count;
1113 	uint16_t		log_drv_size;
1114 	uint16_t		spares_count;
1115 	uint16_t		spares_size;
1116 	uint8_t			reserved[16];
1117 	struct mfi_array	array[0];
1118 	struct mfi_ld_config	ld[0];
1119 	struct mfi_spare	spare[0];
1120 } __packed;
1121 
1122 struct mfi_bbu_capacity_info {
1123 	uint16_t		relative_charge;
1124 	uint16_t		absolute_charge;
1125 	uint16_t		remaining_capacity;
1126 	uint16_t		full_charge_capacity;
1127 	uint16_t		run_time_to_empty;
1128 	uint16_t		average_time_to_empty;
1129 	uint16_t		average_time_to_full;
1130 	uint16_t		cycle_count;
1131 	uint16_t		max_error;
1132 	uint16_t		remaining_capacity_alarm;
1133 	uint16_t		remaining_time_alarm;
1134 	uint8_t			reserved[26];
1135 } __packed;
1136 
1137 struct mfi_bbu_design_info {
1138 	uint32_t		mfg_date;
1139 	uint16_t		design_capacity;
1140 	uint16_t		design_voltage;
1141 	uint16_t		spec_info;
1142 	uint16_t		serial_number;
1143 	uint16_t		pack_stat_config;
1144 	uint8_t			mfg_name[12];
1145 	uint8_t			device_name[8];
1146 	uint8_t			device_chemistry[8];
1147 	uint8_t			mfg_data[8];
1148 	uint8_t			reserved[17];
1149 } __packed;
1150 
1151 struct mfi_ibbu_state {
1152 	uint16_t		gas_guage_status;
1153 	uint16_t		relative_charge;
1154 	uint16_t		charger_system_state;
1155 	uint16_t		charger_system_ctrl;
1156 	uint16_t		charging_current;
1157 	uint16_t		absolute_charge;
1158 	uint16_t		max_error;
1159 	uint8_t			reserved[18];
1160 } __packed;
1161 
1162 struct mfi_bbu_state {
1163 	uint16_t		gas_guage_status;
1164 	uint16_t		relative_charge;
1165 	uint16_t		charger_status;
1166 	uint16_t		remaining_capacity;
1167 	uint16_t		full_charge_capacity;
1168 	uint8_t			is_SOH_good;
1169 	uint8_t			reserved[21];
1170 } __packed;
1171 
1172 union mfi_bbu_status_detail {
1173 	struct mfi_ibbu_state	ibbu;
1174 	struct mfi_bbu_state	bbu;
1175 };
1176 
1177 struct mfi_bbu_status {
1178 	uint8_t			battery_type;
1179 #define	MFI_BBU_TYPE_NONE	0
1180 #define	MFI_BBU_TYPE_IBBU	1
1181 #define	MFI_BBU_TYPE_BBU	2
1182 	uint8_t			reserved;
1183 	uint16_t		voltage;
1184 	int16_t			current;
1185 	uint16_t		temperature;
1186 	uint32_t		fw_status;
1187 #define	MFI_BBU_STATE_PACK_MISSING	(1 << 0)
1188 #define	MFI_BBU_STATE_VOLTAGE_LOW	(1 << 1)
1189 #define	MFI_BBU_STATE_TEMPERATURE_HIGH	(1 << 2)
1190 #define	MFI_BBU_STATE_CHARGE_ACTIVE	(1 << 0)
1191 #define	MFI_BBU_STATE_DISCHARGE_ACTIVE	(1 << 0)
1192 	uint8_t			pad[20];
1193 	union mfi_bbu_status_detail detail;
1194 } __packed;
1195 
1196 enum mfi_pr_state {
1197 	MFI_PR_STATE_STOPPED = 0,
1198 	MFI_PR_STATE_READY = 1,
1199 	MFI_PR_STATE_ACTIVE = 2,
1200 	MFI_PR_STATE_ABORTED = 0xff
1201 };
1202 
1203 struct mfi_pr_status {
1204 	uint32_t		num_iteration;
1205 	uint8_t			state;
1206 	uint8_t			num_pd_done;
1207 	uint8_t			reserved[10];
1208 };
1209 
1210 enum mfi_pr_opmode {
1211 	MFI_PR_OPMODE_AUTO = 0,
1212 	MFI_PR_OPMODE_MANUAL = 1,
1213 	MFI_PR_OPMODE_DISABLED = 2
1214 };
1215 
1216 struct mfi_pr_properties {
1217 	uint8_t			op_mode;
1218 	uint8_t			max_pd;
1219 	uint8_t			reserved;
1220 	uint8_t			exclude_ld_count;
1221 	uint16_t		excluded_ld[MFI_MAX_LD];
1222 	uint8_t			cur_pd_map[MFI_MAX_PD / 8];
1223 	uint8_t			last_pd_map[MFI_MAX_PD / 8];
1224 	uint32_t		next_exec;
1225 	uint32_t		exec_freq;
1226 	uint32_t		clear_freq;
1227 };
1228 
1229 #define MFI_SCSI_MAX_TARGETS	128
1230 #define MFI_SCSI_MAX_LUNS	8
1231 #define MFI_SCSI_INITIATOR_ID	255
1232 #define MFI_SCSI_MAX_CMDS	8
1233 #define MFI_SCSI_MAX_CDB_LEN	16
1234 
1235 #endif /* _MFIREG_H */
1236