xref: /freebsd/sys/dev/mfi/mfireg.h (revision 7bd6fde3)
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 /* Firmware flashing can take 40s */
283 #define MFI_POLL_TIMEOUT_SECS	50
284 
285 /* Allow for speedier math calculations */
286 #define MFI_SECTOR_LEN		512
287 
288 /* Scatter Gather elements */
289 struct mfi_sg32 {
290 	uint32_t	addr;
291 	uint32_t	len;
292 } __packed;
293 
294 struct mfi_sg64 {
295 	uint64_t	addr;
296 	uint32_t	len;
297 } __packed;
298 
299 union mfi_sgl {
300 	struct mfi_sg32	sg32[1];
301 	struct mfi_sg64	sg64[1];
302 } __packed;
303 
304 /* Message frames.  All messages have a common header */
305 struct mfi_frame_header {
306 	uint8_t		cmd;
307 	uint8_t		sense_len;
308 	uint8_t		cmd_status;
309 	uint8_t		scsi_status;
310 	uint8_t		target_id;
311 	uint8_t		lun_id;
312 	uint8_t		cdb_len;
313 	uint8_t		sg_count;
314 	uint32_t	context;
315 	uint32_t	pad0;
316 	uint16_t	flags;
317 	uint16_t	timeout;
318 	uint32_t	data_len;
319 } __packed;
320 
321 struct mfi_init_frame {
322 	struct mfi_frame_header	header;
323 	uint32_t	qinfo_new_addr_lo;
324 	uint32_t	qinfo_new_addr_hi;
325 	uint32_t	qinfo_old_addr_lo;
326 	uint32_t	qinfo_old_addr_hi;
327 	uint32_t	reserved[6];
328 } __packed;
329 
330 #define MFI_IO_FRAME_SIZE 40
331 struct mfi_io_frame {
332 	struct mfi_frame_header	header;
333 	uint32_t	sense_addr_lo;
334 	uint32_t	sense_addr_hi;
335 	uint32_t	lba_lo;
336 	uint32_t	lba_hi;
337 	union mfi_sgl	sgl;
338 } __packed;
339 
340 #define MFI_PASS_FRAME_SIZE 48
341 struct mfi_pass_frame {
342 	struct mfi_frame_header header;
343 	uint32_t	sense_addr_lo;
344 	uint32_t	sense_addr_hi;
345 	uint8_t		cdb[16];
346 	union mfi_sgl	sgl;
347 } __packed;
348 
349 #define MFI_DCMD_FRAME_SIZE 40
350 struct mfi_dcmd_frame {
351 	struct mfi_frame_header header;
352 	uint32_t	opcode;
353 	uint8_t		mbox[MFI_MBOX_SIZE];
354 	union mfi_sgl	sgl;
355 } __packed;
356 
357 struct mfi_abort_frame {
358 	struct mfi_frame_header header;
359 	uint32_t	abort_context;
360 	uint32_t	pad;
361 	uint32_t	abort_mfi_addr_lo;
362 	uint32_t	abort_mfi_addr_hi;
363 	uint32_t	reserved[6];
364 } __packed;
365 
366 struct mfi_smp_frame {
367 	struct mfi_frame_header header;
368 	uint64_t	sas_addr;
369 	union {
370 		struct mfi_sg32 sg32[2];
371 		struct mfi_sg64 sg64[2];
372 	} sgl;
373 } __packed;
374 
375 struct mfi_stp_frame {
376 	struct mfi_frame_header header;
377 	uint16_t	fis[10];
378 	uint32_t	stp_flags;
379 	union {
380 		struct mfi_sg32 sg32[2];
381 		struct mfi_sg64 sg64[2];
382 	} sgl;
383 } __packed;
384 
385 union mfi_frame {
386 	struct mfi_frame_header header;
387 	struct mfi_init_frame	init;
388 	struct mfi_io_frame	io;
389 	struct mfi_pass_frame	pass;
390 	struct mfi_dcmd_frame	dcmd;
391 	struct mfi_abort_frame	abort;
392 	struct mfi_smp_frame	smp;
393 	struct mfi_stp_frame	stp;
394 	uint8_t			bytes[MFI_FRAME_SIZE];
395 };
396 
397 #define MFI_SENSE_LEN 128
398 struct mfi_sense {
399 	uint8_t		data[MFI_SENSE_LEN];
400 };
401 
402 /* The queue init structure that is passed with the init message */
403 struct mfi_init_qinfo {
404 	uint32_t	flags;
405 	uint32_t	rq_entries;
406 	uint32_t	rq_addr_lo;
407 	uint32_t	rq_addr_hi;
408 	uint32_t	pi_addr_lo;
409 	uint32_t	pi_addr_hi;
410 	uint32_t	ci_addr_lo;
411 	uint32_t	ci_addr_hi;
412 } __packed;
413 
414 /* SAS (?) controller properties, part of mfi_ctrl_info */
415 struct mfi_ctrl_props {
416 	uint16_t	seq_num;
417 	uint16_t	pred_fail_poll_interval;
418 	uint16_t	intr_throttle_cnt;
419 	uint16_t	intr_throttle_timeout;
420 	uint8_t		rebuild_rate;
421 	uint8_t		patrol_read_rate;
422 	uint8_t		bgi_rate;
423 	uint8_t		cc_rate;
424 	uint8_t		recon_rate;
425 	uint8_t		cache_flush_interval;
426 	uint8_t		spinup_drv_cnt;
427 	uint8_t		spinup_delay;
428 	uint8_t		cluster_enable;
429 	uint8_t		coercion_mode;
430 	uint8_t		alarm_enable;
431 	uint8_t		disable_auto_rebuild;
432 	uint8_t		disable_battery_warn;
433 	uint8_t		ecc_bucket_size;
434 	uint16_t	ecc_bucket_leak_rate;
435 	uint8_t		restore_hotspare_on_insertion;
436 	uint8_t		expose_encl_devices;
437 	uint8_t		reserved[38];
438 } __packed;
439 
440 /* PCI information about the card. */
441 struct mfi_info_pci {
442 	uint16_t	vendor;
443 	uint16_t	device;
444 	uint16_t	subvendor;
445 	uint16_t	subdevice;
446 	uint8_t		reserved[24];
447 } __packed;
448 
449 /* Host (front end) interface information */
450 struct mfi_info_host {
451 	uint8_t		type;
452 #define MFI_INFO_HOST_PCIX	0x01
453 #define MFI_INFO_HOST_PCIE	0x02
454 #define MFI_INFO_HOST_ISCSI	0x04
455 #define MFI_INFO_HOST_SAS3G	0x08
456 	uint8_t		reserved[6];
457 	uint8_t		port_count;
458 	uint64_t	port_addr[8];
459 } __packed;
460 
461 /* Device (back end) interface information */
462 struct mfi_info_device {
463 	uint8_t		type;
464 #define MFI_INFO_DEV_SPI	0x01
465 #define MFI_INFO_DEV_SAS3G	0x02
466 #define MFI_INFO_DEV_SATA1	0x04
467 #define MFI_INFO_DEV_SATA3G	0x08
468 	uint8_t		reserved[6];
469 	uint8_t		port_count;
470 	uint64_t	port_addr[8];
471 } __packed;
472 
473 /* Firmware component information */
474 struct mfi_info_component {
475 	char		 name[8];
476 	char		 version[32];
477 	char		 build_date[16];
478 	char		 build_time[16];
479 } __packed;
480 
481 /* Controller default settings */
482 struct mfi_defaults {
483 	uint64_t	sas_addr;
484 	uint8_t		phy_polarity;
485 	uint8_t		background_rate;
486 	uint8_t		stripe_size;
487 	uint8_t		flush_time;
488 	uint8_t		write_back;
489 	uint8_t		read_ahead;
490 	uint8_t		cache_when_bbu_bad;
491 	uint8_t		cached_io;
492 	uint8_t		smart_mode;
493 	uint8_t		alarm_disable;
494 	uint8_t		coercion;
495 	uint8_t		zrc_config;
496 	uint8_t		dirty_led_shows_drive_activity;
497 	uint8_t		bios_continue_on_error;
498 	uint8_t		spindown_mode;
499 	uint8_t		allowed_device_types;
500 	uint8_t		allow_mix_in_enclosure;
501 	uint8_t		allow_mix_in_ld;
502 	uint8_t		allow_sata_in_cluster;
503 	uint8_t		max_chained_enclosures;
504 	uint8_t		disable_ctrl_r;
505 	uint8_t		enabel_web_bios;
506 	uint8_t		phy_polarity_split;
507 	uint8_t		direct_pd_mapping;
508 	uint8_t		bios_enumerate_lds;
509 	uint8_t		restored_hot_spare_on_insertion;
510 	uint8_t		expose_enclosure_devices;
511 	uint8_t		maintain_pd_fail_history;
512 	uint8_t		resv[28];
513 } __packed;
514 
515 /* Controller default settings */
516 struct mfi_bios_data {
517 	uint16_t	boot_target_id;
518 	uint8_t		do_not_int_13;
519 	uint8_t		continue_on_error;
520 	uint8_t		verbose;
521 	uint8_t		geometry;
522 	uint8_t		expose_all_drives;
523 	uint8_t		reserved[56];
524 	uint8_t		check_sum;
525 } __packed;
526 
527 /* SAS (?) controller info, returned from MFI_DCMD_CTRL_GETINFO. */
528 struct mfi_ctrl_info {
529 	struct mfi_info_pci	pci;
530 	struct mfi_info_host	host;
531 	struct mfi_info_device	device;
532 
533 	/* Firmware components that are present and active. */
534 	uint32_t		image_check_word;
535 	uint32_t		image_component_count;
536 	struct mfi_info_component image_component[8];
537 
538 	/* Firmware components that have been flashed but are inactive */
539 	uint32_t		pending_image_component_count;
540 	struct mfi_info_component pending_image_component[8];
541 
542 	uint8_t			max_arms;
543 	uint8_t			max_spans;
544 	uint8_t			max_arrays;
545 	uint8_t			max_lds;
546 	char			product_name[80];
547 	char			serial_number[32];
548 	uint32_t		hw_present;
549 #define MFI_INFO_HW_BBU		0x01
550 #define MFI_INFO_HW_ALARM	0x02
551 #define MFI_INFO_HW_NVRAM	0x04
552 #define MFI_INFO_HW_UART	0x08
553 	uint32_t		current_fw_time;
554 	uint16_t		max_cmds;
555 	uint16_t		max_sg_elements;
556 	uint32_t		max_request_size;
557 	uint16_t		lds_present;
558 	uint16_t		lds_degraded;
559 	uint16_t		lds_offline;
560 	uint16_t		pd_present;
561 	uint16_t		pd_disks_present;
562 	uint16_t		pd_disks_pred_failure;
563 	uint16_t		pd_disks_failed;
564 	uint16_t		nvram_size;
565 	uint16_t		memory_size;
566 	uint16_t		flash_size;
567 	uint16_t		ram_correctable_errors;
568 	uint16_t		ram_uncorrectable_errors;
569 	uint8_t			cluster_allowed;
570 	uint8_t			cluster_active;
571 	uint16_t		max_strips_per_io;
572 
573 	uint32_t		raid_levels;
574 #define MFI_INFO_RAID_0		0x01
575 #define MFI_INFO_RAID_1		0x02
576 #define MFI_INFO_RAID_5		0x04
577 #define MFI_INFO_RAID_1E	0x08
578 #define MFI_INFO_RAID_6		0x10
579 
580 	uint32_t		adapter_ops;
581 #define MFI_INFO_AOPS_RBLD_RATE		0x0001
582 #define MFI_INFO_AOPS_CC_RATE		0x0002
583 #define MFI_INFO_AOPS_BGI_RATE		0x0004
584 #define MFI_INFO_AOPS_RECON_RATE	0x0008
585 #define MFI_INFO_AOPS_PATROL_RATE	0x0010
586 #define MFI_INFO_AOPS_ALARM_CONTROL	0x0020
587 #define MFI_INFO_AOPS_CLUSTER_SUPPORTED	0x0040
588 #define MFI_INFO_AOPS_BBU		0x0080
589 #define MFI_INFO_AOPS_SPANNING_ALLOWED	0x0100
590 #define MFI_INFO_AOPS_DEDICATED_SPARES	0x0200
591 #define MFI_INFO_AOPS_REVERTIBLE_SPARES	0x0400
592 #define MFI_INFO_AOPS_FOREIGN_IMPORT	0x0800
593 #define MFI_INFO_AOPS_SELF_DIAGNOSTIC	0x1000
594 #define MFI_INFO_AOPS_MIXED_ARRAY	0x2000
595 #define MFI_INFO_AOPS_GLOBAL_SPARES	0x4000
596 
597 	uint32_t		ld_ops;
598 #define MFI_INFO_LDOPS_READ_POLICY	0x01
599 #define MFI_INFO_LDOPS_WRITE_POLICY	0x02
600 #define MFI_INFO_LDOPS_IO_POLICY	0x04
601 #define MFI_INFO_LDOPS_ACCESS_POLICY	0x08
602 #define MFI_INFO_LDOPS_DISK_CACHE_POLICY 0x10
603 
604 	struct {
605 		uint8_t		min;
606 		uint8_t		max;
607 		uint8_t		reserved[2];
608 	} __packed stripe_sz_ops;
609 
610 	uint32_t		pd_ops;
611 #define MFI_INFO_PDOPS_FORCE_ONLINE	0x01
612 #define MFI_INFO_PDOPS_FORCE_OFFLINE	0x02
613 #define MFI_INFO_PDOPS_FORCE_REBUILD	0x04
614 
615 	uint32_t		pd_mix_support;
616 #define MFI_INFO_PDMIX_SAS		0x01
617 #define MFI_INFO_PDMIX_SATA		0x02
618 #define MFI_INFO_PDMIX_ENCL		0x04
619 #define MFI_INFO_PDMIX_LD		0x08
620 #define MFI_INFO_PDMIX_SATA_CLUSTER	0x10
621 
622 	uint8_t			ecc_bucket_count;
623 	uint8_t			reserved2[11];
624 	struct mfi_ctrl_props	properties;
625 	char			package_version[0x60];
626 	uint8_t			pad[0x800 - 0x6a0];
627 } __packed;
628 
629 /* keep track of an event. */
630 union mfi_evt {
631 	struct {
632 		uint16_t	locale;
633 		uint8_t		reserved;
634 		int8_t		class;
635 	} members;
636 	uint32_t		word;
637 } __packed;
638 
639 /* event log state. */
640 struct mfi_evt_log_state {
641 	uint32_t		newest_seq_num;
642 	uint32_t		oldest_seq_num;
643 	uint32_t		clear_seq_num;
644 	uint32_t		shutdown_seq_num;
645 	uint32_t		boot_seq_num;
646 } __packed;
647 
648 struct mfi_progress {
649 	uint16_t		progress;
650 	uint16_t		elapsed_seconds;
651 } __packed;
652 
653 struct mfi_evt_ld {
654 	uint16_t		target_id;
655 	uint8_t			ld_index;
656 	uint8_t			reserved;
657 } __packed;
658 
659 struct mfi_evt_pd {
660 	uint16_t		device_id;
661 	uint8_t			enclosure_index;
662 	uint8_t			slot_number;
663 } __packed;
664 
665 /* SAS (?) event detail, returned from MFI_DCMD_CTRL_EVENT_WAIT. */
666 struct mfi_evt_detail {
667 	uint32_t		seq;
668 	uint32_t		time;
669 	uint32_t		code;
670 	union mfi_evt		class;
671 	uint8_t			arg_type;
672 	uint8_t			reserved1[15];
673 
674 	union {
675 		struct {
676 			struct mfi_evt_pd	pd;
677 			uint8_t			cdb_len;
678 			uint8_t			sense_len;
679 			uint8_t			reserved[2];
680 			uint8_t			cdb[16];
681 			uint8_t			sense[64];
682 		} cdb_sense;
683 
684 		struct mfi_evt_ld		ld;
685 
686 		struct {
687 			struct mfi_evt_ld	ld;
688 			uint64_t		count;
689 		} ld_count;
690 
691 		struct {
692 			uint64_t		lba;
693 			struct mfi_evt_ld	ld;
694 		} ld_lba;
695 
696 		struct {
697 			struct mfi_evt_ld	ld;
698 			uint32_t		pre_owner;
699 			uint32_t		new_owner;
700 		} ld_owner;
701 
702 		struct {
703 			uint64_t		ld_lba;
704 			uint64_t		pd_lba;
705 			struct mfi_evt_ld	ld;
706 			struct mfi_evt_pd	pd;
707 		} ld_lba_pd_lba;
708 
709 		struct {
710 			struct mfi_evt_ld	ld;
711 			struct mfi_progress	prog;
712 		} ld_prog;
713 
714 		struct {
715 			struct mfi_evt_ld	ld;
716 			uint32_t		prev_state;
717 			uint32_t		new_state;
718 		} ld_state;
719 
720 		struct {
721 			uint64_t		strip;
722 			struct mfi_evt_ld	ld;
723 		} ld_strip;
724 
725 		struct mfi_evt_pd		pd;
726 
727 		struct {
728 			struct mfi_evt_pd	pd;
729 			uint32_t		err;
730 		} pd_err;
731 
732 		struct {
733 			uint64_t		lba;
734 			struct mfi_evt_pd	pd;
735 		} pd_lba;
736 
737 		struct {
738 			uint64_t		lba;
739 			struct mfi_evt_pd	pd;
740 			struct mfi_evt_ld	ld;
741 		} pd_lba_ld;
742 
743 		struct {
744 			struct mfi_evt_pd	pd;
745 			struct mfi_progress	prog;
746 		} pd_prog;
747 
748 		struct {
749 			struct mfi_evt_pd	ld;
750 			uint32_t		prev_state;
751 			uint32_t		new_state;
752 		} pd_state;
753 
754 		struct {
755 			uint16_t		venderId;
756 			uint16_t		deviceId;
757 			uint16_t		subVenderId;
758 			uint16_t		subDeviceId;
759 		} pci;
760 
761 		uint32_t			rate;
762 
763 		char				str[96];
764 
765 		struct {
766 			uint32_t		rtc;
767 			uint16_t		elapsedSeconds;
768 		} time;
769 
770 		struct {
771 			uint32_t		ecar;
772 			uint32_t		elog;
773 			char			str[64];
774 		} ecc;
775 
776 		uint8_t		b[96];
777 		uint16_t	s[48];
778 		uint32_t	w[24];
779 		uint64_t	d[12];
780 	} args;
781 
782 	char description[128];
783 } __packed;
784 
785 struct mfi_evt_list {
786 	uint32_t		count;
787 	uint32_t		reserved;
788 	struct mfi_evt_detail	event[1];
789 } __packed;
790 
791 union mfi_pd_ref {
792 	struct {
793 		uint16_t	device_id;
794 		uint16_t	seq_num;
795 	} v;
796 	uint32_t	ref;
797 } __packed;
798 
799 union mfi_pd_ddf_type {
800 	struct {
801 		union {
802 			struct {
803 				uint16_t	forced_pd_guid	: 1;
804 				uint16_t	in_vd		: 1;
805 				uint16_t	is_global_spare	: 1;
806 				uint16_t	is_spare	: 1;
807 				uint16_t	is_foreign	: 1;
808 				uint16_t	reserved	: 7;
809 				uint16_t	intf		: 4;
810 			} pd_type;
811 			uint16_t	type;
812 		} v;
813 		uint16_t		reserved;
814 	} ddf;
815 	struct {
816 		uint32_t		reserved;
817 	} non_disk;
818 	uint32_t			type;
819 } __packed;
820 
821 struct mfi_pd_progress {
822 	struct {
823 		uint32_t		rbld	: 1;
824 		uint32_t		patrol	: 1;
825 		uint32_t		clear	: 1;
826 		uint32_t		reserved: 29;
827 	} active;
828 	struct mfi_progress		rbld;
829 	struct mfi_progress		patrol;
830 	struct mfi_progress		clear;
831 	struct mfi_progress		reserved[4];
832 } __packed;
833 
834 struct mfi_pd_info {
835 	union mfi_pd_ref		ref;
836 	uint8_t				inquiry_data[96];
837 	uint8_t				vpd_page83[64];
838 	uint8_t				not_supported;
839 	uint8_t				scsi_dev_type;
840 	uint8_t				connected_port_bitmap;
841 	uint8_t				device_speed;
842 	uint32_t			media_err_count;
843 	uint32_t			other_err_count;
844 	uint32_t			pred_fail_count;
845 	uint32_t			last_pred_fail_event_seq_num;
846 	uint16_t			fw_state;
847 	uint8_t				disable_for_removal;
848 	uint8_t				link_speed;
849 	union mfi_pd_ddf_type		state;
850 	struct {
851 		uint8_t			count;
852 		uint8_t			is_path_broken;
853 		uint8_t			reserved[6];
854 		uint64_t		sas_addr[4];
855 	} path_info;
856 	uint64_t			raw_size;
857 	uint64_t			non_coerced_size;
858 	uint64_t			coerced_size;
859 	uint16_t			encl_device_id;
860 	uint8_t				encl_index;
861 	uint8_t				slot_number;
862 	struct mfi_pd_progress		prog_info;
863 	uint8_t				bad_block_table_full;
864 	uint8_t				unusable_in_current_config;
865 	uint8_t				vpd_page83_ext[64];
866 	uint8_t				reserved[512-358];
867 } __packed;
868 
869 struct mfi_pd_address {
870 	uint16_t		device_id;
871 	uint16_t		encl_device_id;
872 	uint8_t			encl_index;
873 	uint8_t			slot_number;
874 	uint8_t			scsi_dev_type;
875 	uint8_t			connect_port_bitmap;
876 	uint64_t		sas_addr[2];
877 } __packed;
878 
879 struct mfi_pd_list {
880 	uint32_t		size;
881 	uint32_t		count;
882 	uint8_t			data;
883 	/*
884 	struct mfi_pd_address	addr[];
885 	*/
886 } __packed;
887 
888 union mfi_ld_ref {
889 	struct {
890 		uint8_t		target_id;
891 		uint8_t		reserved;
892 		uint16_t	seq;
893 	} v;
894 	uint32_t		ref;
895 } __packed;
896 
897 struct mfi_ld_list {
898 	uint32_t		ld_count;
899 	uint32_t		reserved1;
900 	struct {
901 		union mfi_ld_ref	ld;
902 		uint8_t		state;
903 		uint8_t		reserved2[3];
904 		uint64_t	size;
905 	} ld_list[MFI_MAX_LD];
906 } __packed;
907 
908 enum mfi_ld_access {
909 	MFI_LD_ACCESS_RW =	0,
910 	MFI_LD_ACCSSS_RO = 	2,
911 	MFI_LD_ACCESS_BLOCKED =	3,
912 };
913 #define MFI_LD_ACCESS_MASK	3
914 
915 enum mfi_ld_state {
916 	MFI_LD_STATE_OFFLINE =			0,
917 	MFI_LD_STATE_PARTIALLY_DEGRADED =	1,
918 	MFI_LD_STATE_DEGRADED =			2,
919 	MFI_LD_STATE_OPTIMAL =			3
920 };
921 
922 struct mfi_ld_props {
923 	union mfi_ld_ref	ld;
924 	char			name[16];
925 	uint8_t			default_cache_policy;
926 	uint8_t			access_policy;
927 	uint8_t			disk_cache_policy;
928 	uint8_t			current_cache_policy;
929 	uint8_t			no_bgi;
930 	uint8_t			reserved[7];
931 } __packed;
932 
933 struct mfi_ld_params {
934 	uint8_t			primary_raid_level;
935 	uint8_t			raid_level_qualifier;
936 	uint8_t			secondary_raid_level;
937 	uint8_t			stripe_size;
938 	uint8_t			num_drives;
939 	uint8_t			span_depth;
940 	uint8_t			state;
941 	uint8_t			init_state;
942 	uint8_t			is_consistent;
943 	uint8_t			reserved[23];
944 } __packed;
945 
946 struct mfi_ld_progress {
947 	uint32_t		active;
948 #define	MFI_LD_PROGRESS_CC	(1<<0)
949 #define	MFI_LD_PROGRESS_BGI	(1<<1)
950 #define	MFI_LD_PROGRESS_FGI	(1<<2)
951 #define	MFI_LD_PORGRESS_RECON	(1<<3)
952 	struct mfi_progress	cc;
953 	struct mfi_progress	bgi;
954 	struct mfi_progress	fgi;
955 	struct mfi_progress	recon;
956 	struct mfi_progress	reserved[4];
957 } __packed;
958 
959 struct mfi_span {
960 	uint64_t		start_block;
961 	uint64_t		num_blocks;
962 	uint16_t		array_ref;
963 	uint8_t			reserved[6];
964 } __packed;
965 
966 #define	MFI_MAX_SPAN_DEPTH	8
967 struct mfi_ld_config {
968 	struct mfi_ld_props	properties;
969 	struct mfi_ld_params	params;
970 	struct mfi_span		span[MFI_MAX_SPAN_DEPTH];
971 } __packed;
972 
973 struct mfi_ld_info {
974 	struct mfi_ld_config	ld_config;
975 	uint64_t		size;
976 	struct mfi_ld_progress	progress;
977 	uint16_t		cluster_owner;
978 	uint8_t			reconstruct_active;
979 	uint8_t			reserved1[1];
980 	uint8_t			vpd_page83[64];
981 	uint8_t			reserved2[16];
982 } __packed;
983 
984 union mfi_spare_type {
985 	struct {
986 		uint8_t		is_dedicate		:1;
987 		uint8_t		is_revertable		:1;
988 		uint8_t		is_encl_affinity	:1;
989 		uint8_t		reserved		:5;
990 	} v;
991 	uint8_t		type;
992 } __packed;
993 
994 #define MAX_ARRAYS 16
995 struct mfi_spare {
996 	union mfi_pd_ref	ref;
997 	union mfi_spare_type	spare_type;
998 	uint8_t			reserved[2];
999 	uint8_t			array_count;
1000 	uint16_t		array_refd[MAX_ARRAYS];
1001 } __packed;
1002 
1003 #define MAX_ROW_SIZE 32
1004 struct mfi_array {
1005 	uint64_t			size;
1006 	uint8_t				num_drives;
1007 	uint8_t				reserved;
1008 	uint16_t			array_ref;
1009 	uint8_t				pad[20];
1010 	struct {
1011 		union mfi_pd_ref	ref;
1012 		uint16_t		fw_state;
1013 		struct {
1014 			uint8_t		pd;
1015 			uint8_t		slot;
1016 		} encl;
1017 	} pd[MAX_ROW_SIZE];
1018 } __packed;
1019 
1020 struct mfi_config_data {
1021 	uint32_t		size;
1022 	uint16_t		array_count;
1023 	uint16_t		array_size;
1024 	uint16_t		log_drv_count;
1025 	uint16_t		log_drv_size;
1026 	uint16_t		spares_count;
1027 	uint16_t		spares_size;
1028 	uint8_t			reserved[16];
1029 	uint8_t			data;
1030 	/*
1031 	struct mfi_array	array[];
1032 	struct mfi_ld_config	ld[];
1033 	struct mfi_spare	spare[];
1034 	*/
1035 } __packed;
1036 
1037 #endif /* _MFIREG_H */
1038