xref: /freebsd/sys/dev/mfi/mfireg.h (revision 84ee9401a3fc8d3c22424266f421a928989cd692)
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 #ifndef _MFIREG_H
28 #define _MFIREG_H
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 /*
34  * MegaRAID SAS MFI firmware definitions
35  *
36  * Calling this driver 'MegaRAID SAS' is a bit misleading.  It's a completely
37  * new firmware interface from the old AMI MegaRAID one, and there is no
38  * reason why this interface should be limited to just SAS.  In any case, LSI
39  * seems to also call this interface 'MFI', so that will be used here.
40  */
41 
42 /*
43  * Start with the register set.  All registers are 32 bits wide.
44  * The usual Intel IOP style setup.
45  */
46 #define MFI_IMSG0	0x10	/* Inbound message 0 */
47 #define MFI_IMSG1	0x14	/* Inbound message 1 */
48 #define MFI_OMSG0	0x18	/* Outbound message 0 */
49 #define MFI_OMSG1	0x1c	/* Outbound message 1 */
50 #define MFI_IDB		0x20	/* Inbound doorbell */
51 #define MFI_ISTS	0x24	/* Inbound interrupt status */
52 #define MFI_IMSK	0x28	/* Inbound interrupt mask */
53 #define MFI_ODB		0x2c	/* Outbound doorbell */
54 #define MFI_OSTS	0x30	/* Outbound interrupt status */
55 #define MFI_OMSK	0x34	/* Outbound interrupt mask */
56 #define MFI_IQP		0x40	/* Inbound queue port */
57 #define MFI_OQP		0x44	/* Outbound queue port */
58 
59 /* Bits for MFI_OSTS */
60 #define MFI_OSTS_INTR_VALID	0x00000002
61 
62 /*
63  * Firmware state values.  Found in OMSG0 during initialization.
64  */
65 #define MFI_FWSTATE_MASK		0xf0000000
66 #define MFI_FWSTATE_UNDEFINED		0x00000000
67 #define MFI_FWSTATE_BB_INIT		0x10000000
68 #define MFI_FWSTATE_FW_INIT		0x40000000
69 #define MFI_FWSTATE_WAIT_HANDSHAKE	0x60000000
70 #define MFI_FWSTATE_FW_INIT_2		0x70000000
71 #define MFI_FWSTATE_DEVICE_SCAN		0x80000000
72 #define MFI_FWSTATE_FLUSH_CACHE		0xa0000000
73 #define MFI_FWSTATE_READY		0xb0000000
74 #define MFI_FWSTATE_OPERATIONAL		0xc0000000
75 #define MFI_FWSTATE_FAULT		0xf0000000
76 #define MFI_FWSTATE_MAXSGL_MASK		0x00ff0000
77 #define MFI_FWSTATE_MAXCMD_MASK		0x0000ffff
78 
79 /*
80  * Control bits to drive the card to ready state.  These go into the IDB
81  * register.
82  */
83 #define MFI_FWINIT_ABORT	0x00000000 /* Abort all pending commands */
84 #define MFI_FWINIT_READY	0x00000002 /* Move from operational to ready */
85 #define MFI_FWINIT_MFIMODE	0x00000004 /* unknown */
86 #define MFI_FWINIT_CLEAR_HANDSHAKE 0x00000008 /* Respond to WAIT_HANDSHAKE */
87 
88 /* MFI Commands */
89 typedef enum {
90 	MFI_CMD_INIT =		0x00,
91 	MFI_CMD_LD_READ,
92 	MFI_CMD_LD_WRITE,
93 	MFI_CMD_LD_SCSI_IO,
94 	MFI_CMD_PD_SCSI_IO,
95 	MFI_CMD_DCMD,
96 	MFI_CMD_ABORT,
97 	MFI_CMD_SMP,
98 	MFI_CMD_STP
99 } mfi_cmd_t;
100 
101 /* Direct commands */
102 typedef enum {
103 	MFI_DCMD_CTRL_GETINFO =		0x01010000,
104 	MFI_DCMD_CTRL_MFC_DEFAULTS_GET =0x010e0201,
105 	MFI_DCMD_CTRL_MFC_DEFAULTS_SET =0x010e0202,
106 	MFI_DCMD_CTRL_FLUSHCACHE =	0x01101000,
107 	MFI_DCMD_CTRL_SHUTDOWN =	0x01050000,
108 	MFI_DCMD_CTRL_EVENT_GETINFO =	0x01040100,
109 	MFI_DCMD_CTRL_EVENT_GET =	0x01040300,
110 	MFI_DCMD_CTRL_EVENT_WAIT =	0x01040500,
111 	MFI_DCMD_LD_GET_LIST =		0x03010000,
112 	MFI_DCMD_LD_GET_INFO =		0x03020000,
113 	MFI_DCMD_LD_GET_PROP =		0x03030000,
114 	MFI_DCMD_LD_SET_PROP =		0x03040000,
115 	MFI_DCMD_CFG_READ =		0x04010000,
116 	MFI_DCMD_CFG_ADD =		0x04020000,
117 	MFI_DCMD_CFG_CLEAR =		0x04030000,
118 	MFI_DCMD_CLUSTER =		0x08000000,
119 	MFI_DCMD_CLUSTER_RESET_ALL =	0x08010100,
120 	MFI_DCMD_CLUSTER_RESET_LD =	0x08010200
121 } mfi_dcmd_t;
122 
123 /* Modifiers for MFI_DCMD_CTRL_FLUSHCACHE */
124 #define MFI_FLUSHCACHE_CTRL	0x01
125 #define MFI_FLUSHCACHE_DISK	0x02
126 
127 /* Modifiers for MFI_DCMD_CTRL_SHUTDOWN */
128 #define MFI_SHUTDOWN_SPINDOWN	0x01
129 
130 /*
131  * MFI Frame flags
132  */
133 #define MFI_FRAME_POST_IN_REPLY_QUEUE		0x0000
134 #define MFI_FRAME_DONT_POST_IN_REPLY_QUEUE	0x0001
135 #define MFI_FRAME_SGL32				0x0000
136 #define MFI_FRAME_SGL64				0x0002
137 #define MFI_FRAME_SENSE32			0x0000
138 #define MFI_FRAME_SENSE64			0x0004
139 #define MFI_FRAME_DIR_NONE			0x0000
140 #define MFI_FRAME_DIR_WRITE			0x0008
141 #define MFI_FRAME_DIR_READ			0x0010
142 #define MFI_FRAME_DIR_BOTH			0x0018
143 
144 /* MFI Status codes */
145 typedef enum {
146 	MFI_STAT_OK =			0x00,
147 	MFI_STAT_INVALID_CMD,
148 	MFI_STAT_INVALID_DCMD,
149 	MFI_STAT_INVALID_PARAMETER,
150 	MFI_STAT_INVALID_SEQUENCE_NUMBER,
151 	MFI_STAT_ABORT_NOT_POSSIBLE,
152 	MFI_STAT_APP_HOST_CODE_NOT_FOUND,
153 	MFI_STAT_APP_IN_USE,
154 	MFI_STAT_APP_NOT_INITIALIZED,
155 	MFI_STAT_ARRAY_INDEX_INVALID,
156 	MFI_STAT_ARRAY_ROW_NOT_EMPTY,
157 	MFI_STAT_CONFIG_RESOURCE_CONFLICT,
158 	MFI_STAT_DEVICE_NOT_FOUND,
159 	MFI_STAT_DRIVE_TOO_SMALL,
160 	MFI_STAT_FLASH_ALLOC_FAIL,
161 	MFI_STAT_FLASH_BUSY,
162 	MFI_STAT_FLASH_ERROR =		0x10,
163 	MFI_STAT_FLASH_IMAGE_BAD,
164 	MFI_STAT_FLASH_IMAGE_INCOMPLETE,
165 	MFI_STAT_FLASH_NOT_OPEN,
166 	MFI_STAT_FLASH_NOT_STARTED,
167 	MFI_STAT_FLUSH_FAILED,
168 	MFI_STAT_HOST_CODE_NOT_FOUNT,
169 	MFI_STAT_LD_CC_IN_PROGRESS,
170 	MFI_STAT_LD_INIT_IN_PROGRESS,
171 	MFI_STAT_LD_LBA_OUT_OF_RANGE,
172 	MFI_STAT_LD_MAX_CONFIGURED,
173 	MFI_STAT_LD_NOT_OPTIMAL,
174 	MFI_STAT_LD_RBLD_IN_PROGRESS,
175 	MFI_STAT_LD_RECON_IN_PROGRESS,
176 	MFI_STAT_LD_WRONG_RAID_LEVEL,
177 	MFI_STAT_MAX_SPARES_EXCEEDED,
178 	MFI_STAT_MEMORY_NOT_AVAILABLE =	0x20,
179 	MFI_STAT_MFC_HW_ERROR,
180 	MFI_STAT_NO_HW_PRESENT,
181 	MFI_STAT_NOT_FOUND,
182 	MFI_STAT_NOT_IN_ENCL,
183 	MFI_STAT_PD_CLEAR_IN_PROGRESS,
184 	MFI_STAT_PD_TYPE_WRONG,
185 	MFI_STAT_PR_DISABLED,
186 	MFI_STAT_ROW_INDEX_INVALID,
187 	MFI_STAT_SAS_CONFIG_INVALID_ACTION,
188 	MFI_STAT_SAS_CONFIG_INVALID_DATA,
189 	MFI_STAT_SAS_CONFIG_INVALID_PAGE,
190 	MFI_STAT_SAS_CONFIG_INVALID_TYPE,
191 	MFI_STAT_SCSI_DONE_WITH_ERROR,
192 	MFI_STAT_SCSI_IO_FAILED,
193 	MFI_STAT_SCSI_RESERVATION_CONFLICT,
194 	MFI_STAT_SHUTDOWN_FAILED =	0x30,
195 	MFI_STAT_TIME_NOT_SET,
196 	MFI_STAT_WRONG_STATE,
197 	MFI_STAT_LD_OFFLINE,
198 	MFI_STAT_PEER_NOTIFICATION_REJECTED,
199 	MFI_STAT_PEER_NOTIFICATION_FAILED,
200 	MFI_STAT_RESERVATION_IN_PROGRESS,
201 	MFI_STAT_I2C_ERRORS_DETECTED,
202 	MFI_STAT_PCI_ERRORS_DETECTED,
203 	MFI_STAT_INVALID_STATUS =	0xFF
204 } mfi_status_t;
205 
206 typedef enum {
207 	MFI_EVT_CLASS_DEBUG =		-2,
208 	MFI_EVT_CLASS_PROGRESS =	-1,
209 	MFI_EVT_CLASS_INFO =		0,
210 	MFI_EVT_CLASS_WARNING =		1,
211 	MFI_EVT_CLASS_CRITICAL =	2,
212 	MFI_EVT_CLASS_FATAL =		3,
213 	MFI_EVT_CLASS_DEAD =		4
214 } mfi_evt_class_t;
215 
216 typedef enum {
217 	MFI_EVT_LOCALE_LD =		0x0001,
218 	MFI_EVT_LOCALE_PD =		0x0002,
219 	MFI_EVT_LOCALE_ENCL =		0x0004,
220 	MFI_EVT_LOCALE_BBU =		0x0008,
221 	MFI_EVT_LOCALE_SAS =		0x0010,
222 	MFI_EVT_LOCALE_CTRL =		0x0020,
223 	MFI_EVT_LOCALE_CONFIG =		0x0040,
224 	MFI_EVT_LOCALE_CLUSTER =	0x0080,
225 	MFI_EVT_LOCALE_ALL =		0xffff
226 } mfi_evt_locale_t;
227 
228 typedef enum {
229 	MR_EVT_ARGS_NONE =		0x00,
230 	MR_EVT_ARGS_CDB_SENSE,
231 	MR_EVT_ARGS_LD,
232 	MR_EVT_ARGS_LD_COUNT,
233 	MR_EVT_ARGS_LD_LBA,
234 	MR_EVT_ARGS_LD_OWNER,
235 	MR_EVT_ARGS_LD_LBA_PD_LBA,
236 	MR_EVT_ARGS_LD_PROG,
237 	MR_EVT_ARGS_LD_STATE,
238 	MR_EVT_ARGS_LD_STRIP,
239 	MR_EVT_ARGS_PD,
240 	MR_EVT_ARGS_PD_ERR,
241 	MR_EVT_ARGS_PD_LBA,
242 	MR_EVT_ARGS_PD_LBA_LD,
243 	MR_EVT_ARGS_PD_PROG,
244 	MR_EVT_ARGS_PD_STATE,
245 	MR_EVT_ARGS_PCI,
246 	MR_EVT_ARGS_RATE,
247 	MR_EVT_ARGS_STR,
248 	MR_EVT_ARGS_TIME,
249 	MR_EVT_ARGS_ECC
250 } mfi_evt_args;
251 
252 typedef enum {
253 	MR_LD_CACHE_WRITE_BACK =	0x01,
254 	MR_LD_CACHE_WRITE_ADAPTIVE =	0x02,
255 	MR_LD_CACHE_READ_AHEAD =	0x04,
256 	MR_LD_CACHE_READ_ADAPTIVE =	0x08,
257 	MR_LD_CACHE_WRITE_CACHE_BAD_BBU=0x10,
258 	MR_LD_CACHE_ALLOW_WRITE_CACHE =	0x20,
259 	MR_LD_CACHE_ALLOW_READ_CACHE =	0x40
260 } mfi_ld_cache;
261 
262 typedef enum {
263 	MR_PD_CACHE_UNCHANGED  =	0,
264 	MR_PD_CACHE_ENABLE =		1,
265 	MR_PD_CACHE_DISABLE =		2
266 } mfi_pd_cache;
267 
268 /*
269  * Other propertities and definitions
270  */
271 #define MFI_MAX_PD_CHANNELS	2
272 #define MFI_MAX_LD_CHANNELS	2
273 #define MFI_MAX_CHANNELS	(MFI_MAX_PD_CHANNELS + MFI_MAX_LD_CHANNELS)
274 #define MFI_MAX_CHANNEL_DEVS	128
275 #define MFI_DEFAULT_ID		-1
276 #define MFI_MAX_LUN		8
277 #define MFI_MAX_LD		64
278 
279 #define MFI_FRAME_SIZE		64
280 #define MFI_MBOX_SIZE		12
281 
282 #define MFI_POLL_TIMEOUT_SECS	10
283 
284 /* Allow for speedier math calculations */
285 #define MFI_SECTOR_LEN		512
286 
287 /* Scatter Gather elements */
288 struct mfi_sg32 {
289 	uint32_t	addr;
290 	uint32_t	len;
291 } __packed;
292 
293 struct mfi_sg64 {
294 	uint64_t	addr;
295 	uint32_t	len;
296 } __packed;
297 
298 union mfi_sgl {
299 	struct mfi_sg32	sg32[1];
300 	struct mfi_sg64	sg64[1];
301 } __packed;
302 
303 /* Message frames.  All messages have a common header */
304 struct mfi_frame_header {
305 	uint8_t		cmd;
306 	uint8_t		sense_len;
307 	uint8_t		cmd_status;
308 	uint8_t		scsi_status;
309 	uint8_t		target_id;
310 	uint8_t		lun_id;
311 	uint8_t		cdb_len;
312 	uint8_t		sg_count;
313 	uint32_t	context;
314 	uint32_t	pad0;
315 	uint16_t	flags;
316 	uint16_t	timeout;
317 	uint32_t	data_len;
318 } __packed;
319 
320 struct mfi_init_frame {
321 	struct mfi_frame_header	header;
322 	uint32_t	qinfo_new_addr_lo;
323 	uint32_t	qinfo_new_addr_hi;
324 	uint32_t	qinfo_old_addr_lo;
325 	uint32_t	qinfo_old_addr_hi;
326 	uint32_t	reserved[6];
327 } __packed;
328 
329 #define MFI_IO_FRAME_SIZE 40
330 struct mfi_io_frame {
331 	struct mfi_frame_header	header;
332 	uint32_t	sense_addr_lo;
333 	uint32_t	sense_addr_hi;
334 	uint32_t	lba_lo;
335 	uint32_t	lba_hi;
336 	union mfi_sgl	sgl;
337 } __packed;
338 
339 #define MFI_PASS_FRAME_SIZE 48
340 struct mfi_pass_frame {
341 	struct mfi_frame_header header;
342 	uint32_t	sense_addr_lo;
343 	uint32_t	sense_addr_hi;
344 	uint8_t		cdb[16];
345 	union mfi_sgl	sgl;
346 } __packed;
347 
348 #define MFI_DCMD_FRAME_SIZE 40
349 struct mfi_dcmd_frame {
350 	struct mfi_frame_header header;
351 	uint32_t	opcode;
352 	uint8_t		mbox[MFI_MBOX_SIZE];
353 	union mfi_sgl	sgl;
354 } __packed;
355 
356 struct mfi_abort_frame {
357 	struct mfi_frame_header header;
358 	uint32_t	abort_context;
359 	uint32_t	pad;
360 	uint32_t	abort_mfi_addr_lo;
361 	uint32_t	abort_mfi_addr_hi;
362 	uint32_t	reserved[6];
363 } __packed;
364 
365 struct mfi_smp_frame {
366 	struct mfi_frame_header header;
367 	uint64_t	sas_addr;
368 	union {
369 		struct mfi_sg32 sg32[2];
370 		struct mfi_sg64 sg64[2];
371 	} sgl;
372 } __packed;
373 
374 struct mfi_stp_frame {
375 	struct mfi_frame_header header;
376 	uint16_t	fis[10];
377 	uint32_t	stp_flags;
378 	union {
379 		struct mfi_sg32 sg32[2];
380 		struct mfi_sg64 sg64[2];
381 	} sgl;
382 } __packed;
383 
384 union mfi_frame {
385 	struct mfi_frame_header header;
386 	struct mfi_init_frame	init;
387 	struct mfi_io_frame	io;
388 	struct mfi_pass_frame	pass;
389 	struct mfi_dcmd_frame	dcmd;
390 	struct mfi_abort_frame	abort;
391 	struct mfi_smp_frame	smp;
392 	struct mfi_stp_frame	stp;
393 	uint8_t			bytes[MFI_FRAME_SIZE];
394 };
395 
396 #define MFI_SENSE_LEN 128
397 struct mfi_sense {
398 	uint8_t		data[MFI_SENSE_LEN];
399 };
400 
401 /* The queue init structure that is passed with the init message */
402 struct mfi_init_qinfo {
403 	uint32_t	flags;
404 	uint32_t	rq_entries;
405 	uint32_t	rq_addr_lo;
406 	uint32_t	rq_addr_hi;
407 	uint32_t	pi_addr_lo;
408 	uint32_t	pi_addr_hi;
409 	uint32_t	ci_addr_lo;
410 	uint32_t	ci_addr_hi;
411 } __packed;
412 
413 /* SAS (?) controller properties, part of mfi_ctrl_info */
414 struct mfi_ctrl_props {
415 	uint16_t	seq_num;
416 	uint16_t	pred_fail_poll_interval;
417 	uint16_t	intr_throttle_cnt;
418 	uint16_t	intr_throttle_timeout;
419 	uint8_t		rebuild_rate;
420 	uint8_t		patrol_read_rate;
421 	uint8_t		bgi_rate;
422 	uint8_t		cc_rate;
423 	uint8_t		recon_rate;
424 	uint8_t		cache_flush_interval;
425 	uint8_t		spinup_drv_cnt;
426 	uint8_t		spinup_delay;
427 	uint8_t		cluster_enable;
428 	uint8_t		coercion_mode;
429 	uint8_t		alarm_enable;
430 	uint8_t		disable_auto_rebuild;
431 	uint8_t		disable_battery_warn;
432 	uint8_t		ecc_bucket_size;
433 	uint16_t	ecc_bucket_leak_rate;
434 	uint8_t		restore_hotspare_on_insertion;
435 	uint8_t		expose_encl_devices;
436 	uint8_t		reserved[38];
437 } __packed;
438 
439 /* PCI information about the card. */
440 struct mfi_info_pci {
441 	uint16_t	vendor;
442 	uint16_t	device;
443 	uint16_t	subvendor;
444 	uint16_t	subdevice;
445 	uint8_t		reserved[24];
446 } __packed;
447 
448 /* Host (front end) interface information */
449 struct mfi_info_host {
450 	uint8_t		type;
451 #define MFI_INFO_HOST_PCIX	0x01
452 #define MFI_INFO_HOST_PCIE	0x02
453 #define MFI_INFO_HOST_ISCSI	0x04
454 #define MFI_INFO_HOST_SAS3G	0x08
455 	uint8_t		reserved[6];
456 	uint8_t		port_count;
457 	uint64_t	port_addr[8];
458 } __packed;
459 
460 /* Device (back end) interface information */
461 struct mfi_info_device {
462 	uint8_t		type;
463 #define MFI_INFO_DEV_SPI	0x01
464 #define MFI_INFO_DEV_SAS3G	0x02
465 #define MFI_INFO_DEV_SATA1	0x04
466 #define MFI_INFO_DEV_SATA3G	0x08
467 	uint8_t		reserved[6];
468 	uint8_t		port_count;
469 	uint64_t	port_addr[8];
470 } __packed;
471 
472 /* Firmware component information */
473 struct mfi_info_component {
474 	char		 name[8];
475 	char		 version[32];
476 	char		 build_date[16];
477 	char		 build_time[16];
478 } __packed;
479 
480 /* Controller default settings */
481 struct mfi_defaults {
482 	uint64_t	sas_addr;
483 	uint8_t		phy_polarity;
484 	uint8_t		background_rate;
485 	uint8_t		stripe_size;
486 	uint8_t		flush_time;
487 	uint8_t		write_back;
488 	uint8_t		read_ahead;
489 	uint8_t		cache_when_bbu_bad;
490 	uint8_t		cached_io;
491 	uint8_t		smart_mode;
492 	uint8_t		alarm_disable;
493 	uint8_t		coercion;
494 	uint8_t		zrc_config;
495 	uint8_t		dirty_led_shows_drive_activity;
496 	uint8_t		bios_continue_on_error;
497 	uint8_t		spindown_mode;
498 	uint8_t		allowed_device_types;
499 	uint8_t		allow_mix_in_enclosure;
500 	uint8_t		allow_mix_in_ld;
501 	uint8_t		allow_sata_in_cluster;
502 	uint8_t		max_chained_enclosures;
503 	uint8_t		disable_ctrl_r;
504 	uint8_t		enabel_web_bios;
505 	uint8_t		phy_polarity_split;
506 	uint8_t		direct_pd_mapping;
507 	uint8_t		bios_enumerate_lds;
508 	uint8_t		restored_hot_spare_on_insertion;
509 	uint8_t		expose_enclosure_devices;
510 	uint8_t		maintain_pd_fail_history;
511 	uint8_t		resv[28];
512 } __packed;
513 
514 /* Controller default settings */
515 struct mfi_bios_data {
516 	uint16_t	boot_target_id;
517 	uint8_t		do_not_int_13;
518 	uint8_t		continue_on_error;
519 	uint8_t		verbose;
520 	uint8_t		geometry;
521 	uint8_t		expose_all_drives;
522 	uint8_t		reserved[56];
523 	uint8_t		check_sum;
524 } __packed;
525 
526 /* SAS (?) controller info, returned from MFI_DCMD_CTRL_GETINFO. */
527 struct mfi_ctrl_info {
528 	struct mfi_info_pci	pci;
529 	struct mfi_info_host	host;
530 	struct mfi_info_device	device;
531 
532 	/* Firmware components that are present and active. */
533 	uint32_t		image_check_word;
534 	uint32_t		image_component_count;
535 	struct mfi_info_component image_component[8];
536 
537 	/* Firmware components that have been flashed but are inactive */
538 	uint32_t		pending_image_component_count;
539 	struct mfi_info_component pending_image_component[8];
540 
541 	uint8_t			max_arms;
542 	uint8_t			max_spans;
543 	uint8_t			max_arrays;
544 	uint8_t			max_lds;
545 	char			product_name[80];
546 	char			serial_number[32];
547 	uint32_t		hw_present;
548 #define MFI_INFO_HW_BBU		0x01
549 #define MFI_INFO_HW_ALARM	0x02
550 #define MFI_INFO_HW_NVRAM	0x04
551 #define MFI_INFO_HW_UART	0x08
552 	uint32_t		current_fw_time;
553 	uint16_t		max_cmds;
554 	uint16_t		max_sg_elements;
555 	uint32_t		max_request_size;
556 	uint16_t		lds_present;
557 	uint16_t		lds_degraded;
558 	uint16_t		lds_offline;
559 	uint16_t		pd_present;
560 	uint16_t		pd_disks_present;
561 	uint16_t		pd_disks_pred_failure;
562 	uint16_t		pd_disks_failed;
563 	uint16_t		nvram_size;
564 	uint16_t		memory_size;
565 	uint16_t		flash_size;
566 	uint16_t		ram_correctable_errors;
567 	uint16_t		ram_uncorrectable_errors;
568 	uint8_t			cluster_allowed;
569 	uint8_t			cluster_active;
570 	uint16_t		max_strips_per_io;
571 
572 	uint32_t		raid_levels;
573 #define MFI_INFO_RAID_0		0x01
574 #define MFI_INFO_RAID_1		0x02
575 #define MFI_INFO_RAID_5		0x04
576 #define MFI_INFO_RAID_1E	0x08
577 #define MFI_INFO_RAID_6		0x10
578 
579 	uint32_t		adapter_ops;
580 #define MFI_INFO_AOPS_RBLD_RATE		0x0001
581 #define MFI_INFO_AOPS_CC_RATE		0x0002
582 #define MFI_INFO_AOPS_BGI_RATE		0x0004
583 #define MFI_INFO_AOPS_RECON_RATE	0x0008
584 #define MFI_INFO_AOPS_PATROL_RATE	0x0010
585 #define MFI_INFO_AOPS_ALARM_CONTROL	0x0020
586 #define MFI_INFO_AOPS_CLUSTER_SUPPORTED	0x0040
587 #define MFI_INFO_AOPS_BBU		0x0080
588 #define MFI_INFO_AOPS_SPANNING_ALLOWED	0x0100
589 #define MFI_INFO_AOPS_DEDICATED_SPARES	0x0200
590 #define MFI_INFO_AOPS_REVERTIBLE_SPARES	0x0400
591 #define MFI_INFO_AOPS_FOREIGN_IMPORT	0x0800
592 #define MFI_INFO_AOPS_SELF_DIAGNOSTIC	0x1000
593 #define MFI_INFO_AOPS_MIXED_ARRAY	0x2000
594 #define MFI_INFO_AOPS_GLOBAL_SPARES	0x4000
595 
596 	uint32_t		ld_ops;
597 #define MFI_INFO_LDOPS_READ_POLICY	0x01
598 #define MFI_INFO_LDOPS_WRITE_POLICY	0x02
599 #define MFI_INFO_LDOPS_IO_POLICY	0x04
600 #define MFI_INFO_LDOPS_ACCESS_POLICY	0x08
601 #define MFI_INFO_LDOPS_DISK_CACHE_POLICY 0x10
602 
603 	struct {
604 		uint8_t		min;
605 		uint8_t		max;
606 		uint8_t		reserved[2];
607 	} __packed stripe_sz_ops;
608 
609 	uint32_t		pd_ops;
610 #define MFI_INFO_PDOPS_FORCE_ONLINE	0x01
611 #define MFI_INFO_PDOPS_FORCE_OFFLINE	0x02
612 #define MFI_INFO_PDOPS_FORCE_REBUILD	0x04
613 
614 	uint32_t		pd_mix_support;
615 #define MFI_INFO_PDMIX_SAS		0x01
616 #define MFI_INFO_PDMIX_SATA		0x02
617 #define MFI_INFO_PDMIX_ENCL		0x04
618 #define MFI_INFO_PDMIX_LD		0x08
619 #define MFI_INFO_PDMIX_SATA_CLUSTER	0x10
620 
621 	uint8_t			ecc_bucket_count;
622 	uint8_t			reserved2[11];
623 	struct mfi_ctrl_props	properties;
624 	char			package_version[0x60];
625 	uint8_t			pad[0x800 - 0x6a0];
626 } __packed;
627 
628 /* keep track of an event. */
629 union mfi_evt {
630 	struct {
631 		uint16_t	locale;
632 		uint8_t		reserved;
633 		int8_t		class;
634 	} members;
635 	uint32_t		word;
636 } __packed;
637 
638 /* event log state. */
639 struct mfi_evt_log_state {
640 	uint32_t		newest_seq_num;
641 	uint32_t		oldest_seq_num;
642 	uint32_t		clear_seq_num;
643 	uint32_t		shutdown_seq_num;
644 	uint32_t		boot_seq_num;
645 } __packed;
646 
647 struct mfi_progress {
648 	uint16_t		progress;
649 	uint16_t		elapsed_seconds;
650 } __packed;
651 
652 struct mfi_evt_ld {
653 	uint16_t		target_id;
654 	uint8_t			ld_index;
655 	uint8_t			reserved;
656 } __packed;
657 
658 struct mfi_evt_pd {
659 	uint16_t		device_id;
660 	uint8_t			enclosure_index;
661 	uint8_t			slot_number;
662 } __packed;
663 
664 /* SAS (?) event detail, returned from MFI_DCMD_CTRL_EVENT_WAIT. */
665 struct mfi_evt_detail {
666 	uint32_t		seq;
667 	uint32_t		time;
668 	uint32_t		code;
669 	union mfi_evt		class;
670 	uint8_t			arg_type;
671 	uint8_t			reserved1[15];
672 
673 	union {
674 		struct {
675 			struct mfi_evt_pd	pd;
676 			uint8_t			cdb_len;
677 			uint8_t			sense_len;
678 			uint8_t			reserved[2];
679 			uint8_t			cdb[16];
680 			uint8_t			sense[64];
681 		} cdb_sense;
682 
683 		struct mfi_evt_ld		ld;
684 
685 		struct {
686 			struct mfi_evt_ld	ld;
687 			uint64_t		count;
688 		} ld_count;
689 
690 		struct {
691 			uint64_t		lba;
692 			struct mfi_evt_ld	ld;
693 		} ld_lba;
694 
695 		struct {
696 			struct mfi_evt_ld	ld;
697 			uint32_t		pre_owner;
698 			uint32_t		new_owner;
699 		} ld_owner;
700 
701 		struct {
702 			uint64_t		ld_lba;
703 			uint64_t		pd_lba;
704 			struct mfi_evt_ld	ld;
705 			struct mfi_evt_pd	pd;
706 		} ld_lba_pd_lba;
707 
708 		struct {
709 			struct mfi_evt_ld	ld;
710 			struct mfi_progress	prog;
711 		} ld_prog;
712 
713 		struct {
714 			struct mfi_evt_ld	ld;
715 			uint32_t		prev_state;
716 			uint32_t		new_state;
717 		} ld_state;
718 
719 		struct {
720 			uint64_t		strip;
721 			struct mfi_evt_ld	ld;
722 		} ld_strip;
723 
724 		struct mfi_evt_pd		pd;
725 
726 		struct {
727 			struct mfi_evt_pd	pd;
728 			uint32_t		err;
729 		} pd_err;
730 
731 		struct {
732 			uint64_t		lba;
733 			struct mfi_evt_pd	pd;
734 		} pd_lba;
735 
736 		struct {
737 			uint64_t		lba;
738 			struct mfi_evt_pd	pd;
739 			struct mfi_evt_ld	ld;
740 		} pd_lba_ld;
741 
742 		struct {
743 			struct mfi_evt_pd	pd;
744 			struct mfi_progress	prog;
745 		} pd_prog;
746 
747 		struct {
748 			struct mfi_evt_pd	ld;
749 			uint32_t		prev_state;
750 			uint32_t		new_state;
751 		} pd_state;
752 
753 		struct {
754 			uint16_t		venderId;
755 			uint16_t		deviceId;
756 			uint16_t		subVenderId;
757 			uint16_t		subDeviceId;
758 		} pci;
759 
760 		uint32_t			rate;
761 
762 		char				str[96];
763 
764 		struct {
765 			uint32_t		rtc;
766 			uint16_t		elapsedSeconds;
767 		} time;
768 
769 		struct {
770 			uint32_t		ecar;
771 			uint32_t		elog;
772 			char			str[64];
773 		} ecc;
774 
775 		uint8_t		b[96];
776 		uint16_t	s[48];
777 		uint32_t	w[24];
778 		uint64_t	d[12];
779 	} args;
780 
781 	char description[128];
782 } __packed;
783 
784 struct mfi_evt_list {
785 	uint32_t		count;
786 	uint32_t		reserved;
787 	struct mfi_evt_detail	event[1];
788 } __packed;
789 
790 union mfi_pd_ref {
791 	struct {
792 		uint16_t	device_id;
793 		uint16_t	seq_num;
794 	} v;
795 	uint32_t	ref;
796 } __packed;
797 
798 union mfi_pd_ddf_type {
799 	struct {
800 		union {
801 			struct {
802 				uint16_t	forced_pd_guid	: 1;
803 				uint16_t	in_vd		: 1;
804 				uint16_t	is_global_spare	: 1;
805 				uint16_t	is_spare	: 1;
806 				uint16_t	is_foreign	: 1;
807 				uint16_t	reserved	: 7;
808 				uint16_t	intf		: 4;
809 			} pd_type;
810 			uint16_t	type;
811 		} v;
812 		uint16_t		reserved;
813 	} ddf;
814 	struct {
815 		uint32_t		reserved;
816 	} non_disk;
817 	uint32_t			type;
818 } __packed;
819 
820 struct mfi_pd_progress {
821 	struct {
822 		uint32_t		rbld	: 1;
823 		uint32_t		patrol	: 1;
824 		uint32_t		clear	: 1;
825 		uint32_t		reserved: 29;
826 	} active;
827 	struct mfi_progress		rbld;
828 	struct mfi_progress		patrol;
829 	struct mfi_progress		clear;
830 	struct mfi_progress		reserved[4];
831 } __packed;
832 
833 struct mfi_pd_info {
834 	union mfi_pd_ref		ref;
835 	uint8_t				inquiry_data[96];
836 	uint8_t				vpd_page83[64];
837 	uint8_t				not_supported;
838 	uint8_t				scsi_dev_type;
839 	uint8_t				connected_port_bitmap;
840 	uint8_t				device_speed;
841 	uint32_t			media_err_count;
842 	uint32_t			other_err_count;
843 	uint32_t			pred_fail_count;
844 	uint32_t			last_pred_fail_event_seq_num;
845 	uint16_t			fw_state;
846 	uint8_t				disable_for_removal;
847 	uint8_t				link_speed;
848 	union mfi_pd_ddf_type		state;
849 	struct {
850 		uint8_t			count;
851 		uint8_t			is_path_broken;
852 		uint8_t			reserved[6];
853 		uint64_t		sas_addr[4];
854 	} path_info;
855 	uint64_t			raw_size;
856 	uint64_t			non_coerced_size;
857 	uint64_t			coerced_size;
858 	uint16_t			encl_device_id;
859 	uint8_t				encl_index;
860 	uint8_t				slot_number;
861 	struct mfi_pd_progress		prog_info;
862 	uint8_t				bad_block_table_full;
863 	uint8_t				unusable_in_current_config;
864 	uint8_t				vpd_page83_ext[64];
865 	uint8_t				reserved[512-358];
866 } __packed;
867 
868 struct mfi_pd_address {
869 	uint16_t		device_id;
870 	uint16_t		encl_device_id;
871 	uint8_t			encl_index;
872 	uint8_t			slot_number;
873 	uint8_t			scsi_dev_type;
874 	uint8_t			connect_port_bitmap;
875 	uint64_t		sas_addr[2];
876 } __packed;
877 
878 struct mfi_pd_list {
879 	uint32_t		size;
880 	uint32_t		count;
881 	uint8_t			data;
882 	/*
883 	struct mfi_pd_address	addr[];
884 	*/
885 } __packed;
886 
887 union mfi_ld_ref {
888 	struct {
889 		uint8_t		target_id;
890 		uint8_t		reserved;
891 		uint16_t	seq;
892 	} v;
893 	uint32_t		ref;
894 } __packed;
895 
896 struct mfi_ld_list {
897 	uint32_t		ld_count;
898 	uint32_t		reserved1;
899 	struct {
900 		union mfi_ld_ref	ld;
901 		uint8_t		state;
902 		uint8_t		reserved2[3];
903 		uint64_t	size;
904 	} ld_list[MFI_MAX_LD];
905 } __packed;
906 
907 enum mfi_ld_access {
908 	MFI_LD_ACCESS_RW =	0,
909 	MFI_LD_ACCSSS_RO = 	2,
910 	MFI_LD_ACCESS_BLOCKED =	3,
911 };
912 #define MFI_LD_ACCESS_MASK	3
913 
914 enum mfi_ld_state {
915 	MFI_LD_STATE_OFFLINE =			0,
916 	MFI_LD_STATE_PARTIALLY_DEGRADED =	1,
917 	MFI_LD_STATE_DEGRADED =			2,
918 	MFI_LD_STATE_OPTIMAL =			3
919 };
920 
921 struct mfi_ld_props {
922 	union mfi_ld_ref	ld;
923 	char			name[16];
924 	uint8_t			default_cache_policy;
925 	uint8_t			access_policy;
926 	uint8_t			disk_cache_policy;
927 	uint8_t			current_cache_policy;
928 	uint8_t			no_bgi;
929 	uint8_t			reserved[7];
930 } __packed;
931 
932 struct mfi_ld_params {
933 	uint8_t			primary_raid_level;
934 	uint8_t			raid_level_qualifier;
935 	uint8_t			secondary_raid_level;
936 	uint8_t			stripe_size;
937 	uint8_t			num_drives;
938 	uint8_t			span_depth;
939 	uint8_t			state;
940 	uint8_t			init_state;
941 	uint8_t			is_consistent;
942 	uint8_t			reserved[23];
943 } __packed;
944 
945 struct mfi_ld_progress {
946 	uint32_t		active;
947 #define	MFI_LD_PROGRESS_CC	(1<<0)
948 #define	MFI_LD_PROGRESS_BGI	(1<<1)
949 #define	MFI_LD_PROGRESS_FGI	(1<<2)
950 #define	MFI_LD_PORGRESS_RECON	(1<<3)
951 	struct mfi_progress	cc;
952 	struct mfi_progress	bgi;
953 	struct mfi_progress	fgi;
954 	struct mfi_progress	recon;
955 	struct mfi_progress	reserved[4];
956 } __packed;
957 
958 struct mfi_span {
959 	uint64_t		start_block;
960 	uint64_t		num_blocks;
961 	uint16_t		array_ref;
962 	uint8_t			reserved[6];
963 } __packed;
964 
965 #define	MFI_MAX_SPAN_DEPTH	8
966 struct mfi_ld_config {
967 	struct mfi_ld_props	properties;
968 	struct mfi_ld_params	params;
969 	struct mfi_span		span[MFI_MAX_SPAN_DEPTH];
970 } __packed;
971 
972 struct mfi_ld_info {
973 	struct mfi_ld_config	ld_config;
974 	uint64_t		size;
975 	struct mfi_ld_progress	progress;
976 	uint16_t		cluster_owner;
977 	uint8_t			reconstruct_active;
978 	uint8_t			reserved1[1];
979 	uint8_t			vpd_page83[64];
980 	uint8_t			reserved2[16];
981 } __packed;
982 
983 union mfi_spare_type {
984 	struct {
985 		uint8_t		is_dedicate		:1;
986 		uint8_t		is_revertable		:1;
987 		uint8_t		is_encl_affinity	:1;
988 		uint8_t		reserved		:5;
989 	} v;
990 	uint8_t		type;
991 } __packed;
992 
993 #define MAX_ARRAYS 16
994 struct mfi_spare {
995 	union mfi_pd_ref	ref;
996 	union mfi_spare_type	spare_type;
997 	uint8_t			reserved[2];
998 	uint8_t			array_count;
999 	uint16_t		array_refd[MAX_ARRAYS];
1000 } __packed;
1001 
1002 #define MAX_ROW_SIZE 32
1003 struct mfi_array {
1004 	uint64_t			size;
1005 	uint8_t				num_drives;
1006 	uint8_t				reserved;
1007 	uint16_t			array_ref;
1008 	uint8_t				pad[20];
1009 	struct {
1010 		union mfi_pd_ref	ref;
1011 		uint16_t		fw_state;
1012 		struct {
1013 			uint8_t		pd;
1014 			uint8_t		slot;
1015 		} encl;
1016 	} pd[MAX_ROW_SIZE];
1017 } __packed;
1018 
1019 struct mfi_config_data {
1020 	uint32_t		size;
1021 	uint16_t		array_count;
1022 	uint16_t		array_size;
1023 	uint16_t		log_drv_count;
1024 	uint16_t		log_drv_size;
1025 	uint16_t		spares_count;
1026 	uint16_t		spares_size;
1027 	uint8_t			reserved[16];
1028 	uint8_t			data;
1029 	/*
1030 	struct mfi_array	array[];
1031 	struct mfi_ld_config	ld[];
1032 	struct mfi_spare	spare[];
1033 	*/
1034 } __packed;
1035 
1036 #endif /* _MFIREG_H */
1037