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