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