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