xref: /illumos-gate/usr/src/uts/common/io/mr_sas/mr_sas.h (revision 71531557)
1 /*
2  * mr_sas.h: header for mr_sas
3  *
4  * Solaris MegaRAID driver for SAS2.0 controllers
5  * Copyright (c) 2008-2012, LSI Logic Corporation.
6  * All rights reserved.
7  *
8  * Version:
9  * Author:
10  *		Swaminathan K S
11  *		Arun Chandrashekhar
12  *		Manju R
13  *		Rasheed
14  *		Shakeel Bukhari
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions are met:
18  *
19  * 1. Redistributions of source code must retain the above copyright notice,
20  *    this list of conditions and the following disclaimer.
21  *
22  * 2. Redistributions in binary form must reproduce the above copyright notice,
23  *    this list of conditions and the following disclaimer in the documentation
24  *    and/or other materials provided with the distribution.
25  *
26  * 3. Neither the name of the author nor the names of its contributors may be
27  *    used to endorse or promote products derived from this software without
28  *    specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
37  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
38  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
40  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
41  * DAMAGE.
42  */
43 
44 /*
45  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
46  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
47  * Copyright 2015 Garrett D'Amore <garrett@damore.org>
48  * Copyright 2017 Citrus IT Limited. All rights reserved.
49  */
50 
51 #ifndef	_MR_SAS_H_
52 #define	_MR_SAS_H_
53 
54 #ifdef	__cplusplus
55 extern "C" {
56 #endif
57 
58 #include <sys/scsi/scsi.h>
59 #include "mr_sas_list.h"
60 #include "ld_pd_map.h"
61 
62 /*
63  * MegaRAID SAS2.0 Driver meta data
64  */
65 #define	MRSAS_VERSION				"6.503.00.00ILLUMOS-20170421"
66 #define	MRSAS_RELDATE				"April 21, 2017"
67 
68 #define	MRSAS_TRUE				1
69 #define	MRSAS_FALSE				0
70 
71 #define	ADAPTER_RESET_NOT_REQUIRED		0
72 #define	ADAPTER_RESET_REQUIRED			1
73 
74 #define	PDSUPPORT	1
75 
76 /*
77  * MegaRAID SAS2.0 device id conversion definitions.
78  */
79 #define	INST2LSIRDCTL(x)		((x) << INST_MINOR_SHIFT)
80 #define	MRSAS_GET_BOUNDARY_ALIGNED_LEN(len, new_len, boundary_len)  { \
81 	int rem; \
82 	rem = (len / boundary_len); \
83 	if ((rem * boundary_len) != len) { \
84 		new_len = len + ((rem + 1) * boundary_len - len); \
85 	} else { \
86 		new_len = len; \
87 	} \
88 }
89 
90 
91 /*
92  * MegaRAID SAS2.0 supported controllers
93  */
94 
95 /* Skinny */
96 #define	PCI_DEVICE_ID_LSI_SKINNY		0x0071
97 #define	PCI_DEVICE_ID_LSI_SKINNY_NEW		0x0073
98 /* Liberator series (Gen2) */
99 #define	PCI_DEVICE_ID_LSI_2108VDE		0x0078
100 #define	PCI_DEVICE_ID_LSI_2108V			0x0079
101 /* Thunderbolt series */
102 #define	PCI_DEVICE_ID_LSI_TBOLT			0x005b
103 /* Invader series (Gen3) */
104 #define	PCI_DEVICE_ID_LSI_INVADER		0x005d
105 #define	PCI_DEVICE_ID_LSI_FURY			0x005f
106 #define	PCI_DEVICE_ID_LSI_INTRUDER		0x00ce
107 #define	PCI_DEVICE_ID_LSI_INTRUDER_24		0x00cf
108 #define	PCI_DEVICE_ID_LSI_CUTLASS_52		0x0052
109 #define	PCI_DEVICE_ID_LSI_CUTLASS_53		0x0053
110 /* Ventura series not yet supported */
111 
112 /*
113  * Register Index for 2108 Controllers.
114  */
115 #define	REGISTER_SET_IO_2108			(2)
116 
117 #define	MRSAS_MAX_SGE_CNT			0x50
118 #define	MRSAS_APP_RESERVED_CMDS			32
119 #define	MRSAS_APP_MIN_RESERVED_CMDS		4
120 
121 #define	MRSAS_IOCTL_DRIVER			0x12341234
122 #define	MRSAS_IOCTL_FIRMWARE			0x12345678
123 #define	MRSAS_IOCTL_AEN				0x87654321
124 
125 #define	MRSAS_1_SECOND				1000000
126 
127 #ifdef PDSUPPORT
128 
129 #define	UNCONFIGURED_GOOD			0x0
130 #define	PD_SYSTEM				0x40
131 #define	MR_EVT_PD_STATE_CHANGE			0x0072
132 #define	MR_EVT_PD_REMOVED_EXT		0x00f8
133 #define	MR_EVT_PD_INSERTED_EXT		0x00f7
134 #define	MR_DCMD_PD_GET_INFO			0x02020000
135 #define	MRSAS_TBOLT_PD_LUN		1
136 #define	MRSAS_TBOLT_PD_TGT_MAX	255
137 #define	MRSAS_TBOLT_GET_PD_MAX(s)	((s)->mr_tbolt_pd_max)
138 
139 #endif
140 
141 /* Raid Context Flags */
142 #define	MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT 0x4
143 #define	MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_MASK 0x30
144 typedef enum MR_RAID_FLAGS_IO_SUB_TYPE {
145 	MR_RAID_FLAGS_IO_SUB_TYPE_NONE = 0,
146 	MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD = 1
147 } MR_RAID_FLAGS_IO_SUB_TYPE;
148 
149 /* Dynamic Enumeration Flags */
150 #define	MRSAS_LD_LUN		0
151 #define	WWN_STRLEN		17
152 #define	LD_SYNC_BIT	1
153 #define	LD_SYNC_SHIFT	14
154 /* ThunderBolt (TB) specific */
155 #define	MRSAS_THUNDERBOLT_MSG_SIZE		256
156 #define	MRSAS_THUNDERBOLT_MAX_COMMANDS		1024
157 #define	MRSAS_THUNDERBOLT_MAX_REPLY_COUNT	1024
158 #define	MRSAS_THUNDERBOLT_REPLY_SIZE		8
159 #define	MRSAS_THUNDERBOLT_MAX_CHAIN_COUNT	1
160 
161 #define	MPI2_FUNCTION_PASSTHRU_IO_REQUEST	0xF0
162 #define	MPI2_FUNCTION_LD_IO_REQUEST		0xF1
163 
164 #define	MR_EVT_LD_FAST_PATH_IO_STATUS_CHANGED	(0xFFFF)
165 
166 #define	MR_INTERNAL_MFI_FRAMES_SMID		1
167 #define	MR_CTRL_EVENT_WAIT_SMID			2
168 #define	MR_INTERNAL_DRIVER_RESET_SMID		3
169 
170 
171 /*
172  * =====================================
173  * MegaRAID SAS2.0 MFI firmware definitions
174  * =====================================
175  */
176 /*
177  * MFI stands for  MegaRAID SAS2.0 FW Interface. This is just a moniker for
178  * protocol between the software and firmware. Commands are issued using
179  * "message frames"
180  */
181 
182 /*
183  * FW posts its state in upper 4 bits of outbound_msg_0 register
184  */
185 #define	MFI_STATE_MASK				0xF0000000
186 #define	MFI_STATE_UNDEFINED			0x00000000
187 #define	MFI_STATE_BB_INIT			0x10000000
188 #define	MFI_STATE_FW_INIT			0x40000000
189 #define	MFI_STATE_WAIT_HANDSHAKE		0x60000000
190 #define	MFI_STATE_FW_INIT_2			0x70000000
191 #define	MFI_STATE_DEVICE_SCAN			0x80000000
192 #define	MFI_STATE_BOOT_MESSAGE_PENDING		0x90000000
193 #define	MFI_STATE_FLUSH_CACHE			0xA0000000
194 #define	MFI_STATE_READY				0xB0000000
195 #define	MFI_STATE_OPERATIONAL			0xC0000000
196 #define	MFI_STATE_FAULT				0xF0000000
197 
198 #define	MRMFI_FRAME_SIZE			64
199 
200 /*
201  * During FW init, clear pending cmds & reset state using inbound_msg_0
202  *
203  * ABORT	: Abort all pending cmds
204  * READY	: Move from OPERATIONAL to READY state; discard queue info
205  * MFIMODE	: Discard (possible) low MFA posted in 64-bit mode (??)
206  * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver
207  */
208 #define	MFI_INIT_ABORT				0x00000001
209 #define	MFI_INIT_READY				0x00000002
210 #define	MFI_INIT_MFIMODE			0x00000004
211 #define	MFI_INIT_CLEAR_HANDSHAKE		0x00000008
212 #define	MFI_INIT_HOTPLUG			0x00000010
213 #define	MFI_STOP_ADP				0x00000020
214 #define	MFI_RESET_FLAGS		MFI_INIT_READY|MFI_INIT_MFIMODE|MFI_INIT_ABORT
215 
216 /*
217  * MFI frame flags
218  */
219 #define	MFI_FRAME_POST_IN_REPLY_QUEUE		0x0000
220 #define	MFI_FRAME_DONT_POST_IN_REPLY_QUEUE	0x0001
221 #define	MFI_FRAME_SGL32				0x0000
222 #define	MFI_FRAME_SGL64				0x0002
223 #define	MFI_FRAME_SENSE32			0x0000
224 #define	MFI_FRAME_SENSE64			0x0004
225 #define	MFI_FRAME_DIR_NONE			0x0000
226 #define	MFI_FRAME_DIR_WRITE			0x0008
227 #define	MFI_FRAME_DIR_READ			0x0010
228 #define	MFI_FRAME_DIR_BOTH			0x0018
229 #define	MFI_FRAME_IEEE				0x0020
230 
231 /*
232  * Definition for cmd_status
233  */
234 #define	MFI_CMD_STATUS_POLL_MODE		0xFF
235 #define	MFI_CMD_STATUS_SYNC_MODE		0xFF
236 
237 /*
238  * MFI command opcodes
239  */
240 #define	MFI_CMD_OP_INIT				0x00
241 #define	MFI_CMD_OP_LD_READ			0x01
242 #define	MFI_CMD_OP_LD_WRITE			0x02
243 #define	MFI_CMD_OP_LD_SCSI			0x03
244 #define	MFI_CMD_OP_PD_SCSI			0x04
245 #define	MFI_CMD_OP_DCMD				0x05
246 #define	MFI_CMD_OP_ABORT			0x06
247 #define	MFI_CMD_OP_SMP				0x07
248 #define	MFI_CMD_OP_STP				0x08
249 
250 #define	MR_DCMD_CTRL_GET_INFO			0x01010000
251 
252 #define	MR_DCMD_CTRL_CACHE_FLUSH		0x01101000
253 #define	MR_FLUSH_CTRL_CACHE			0x01
254 #define	MR_FLUSH_DISK_CACHE			0x02
255 
256 #define	MR_DCMD_CTRL_SHUTDOWN			0x01050000
257 #define	MRSAS_ENABLE_DRIVE_SPINDOWN		0x01
258 
259 #define	MR_DCMD_CTRL_EVENT_GET_INFO		0x01040100
260 #define	MR_DCMD_CTRL_EVENT_GET			0x01040300
261 #define	MR_DCMD_CTRL_EVENT_WAIT			0x01040500
262 #define	MR_DCMD_LD_GET_PROPERTIES		0x03030000
263 
264 /*
265  * Solaris Specific MAX values
266  */
267 #define	MAX_SGL					24
268 
269 /*
270  * MFI command completion codes
271  */
272 enum MFI_STAT {
273 	MFI_STAT_OK				= 0x00,
274 	MFI_STAT_INVALID_CMD			= 0x01,
275 	MFI_STAT_INVALID_DCMD			= 0x02,
276 	MFI_STAT_INVALID_PARAMETER		= 0x03,
277 	MFI_STAT_INVALID_SEQUENCE_NUMBER	= 0x04,
278 	MFI_STAT_ABORT_NOT_POSSIBLE		= 0x05,
279 	MFI_STAT_APP_HOST_CODE_NOT_FOUND	= 0x06,
280 	MFI_STAT_APP_IN_USE			= 0x07,
281 	MFI_STAT_APP_NOT_INITIALIZED		= 0x08,
282 	MFI_STAT_ARRAY_INDEX_INVALID		= 0x09,
283 	MFI_STAT_ARRAY_ROW_NOT_EMPTY		= 0x0a,
284 	MFI_STAT_CONFIG_RESOURCE_CONFLICT	= 0x0b,
285 	MFI_STAT_DEVICE_NOT_FOUND		= 0x0c,
286 	MFI_STAT_DRIVE_TOO_SMALL		= 0x0d,
287 	MFI_STAT_FLASH_ALLOC_FAIL		= 0x0e,
288 	MFI_STAT_FLASH_BUSY			= 0x0f,
289 	MFI_STAT_FLASH_ERROR			= 0x10,
290 	MFI_STAT_FLASH_IMAGE_BAD		= 0x11,
291 	MFI_STAT_FLASH_IMAGE_INCOMPLETE		= 0x12,
292 	MFI_STAT_FLASH_NOT_OPEN			= 0x13,
293 	MFI_STAT_FLASH_NOT_STARTED		= 0x14,
294 	MFI_STAT_FLUSH_FAILED			= 0x15,
295 	MFI_STAT_HOST_CODE_NOT_FOUNT		= 0x16,
296 	MFI_STAT_LD_CC_IN_PROGRESS		= 0x17,
297 	MFI_STAT_LD_INIT_IN_PROGRESS		= 0x18,
298 	MFI_STAT_LD_LBA_OUT_OF_RANGE		= 0x19,
299 	MFI_STAT_LD_MAX_CONFIGURED		= 0x1a,
300 	MFI_STAT_LD_NOT_OPTIMAL			= 0x1b,
301 	MFI_STAT_LD_RBLD_IN_PROGRESS		= 0x1c,
302 	MFI_STAT_LD_RECON_IN_PROGRESS		= 0x1d,
303 	MFI_STAT_LD_WRONG_RAID_LEVEL		= 0x1e,
304 	MFI_STAT_MAX_SPARES_EXCEEDED		= 0x1f,
305 	MFI_STAT_MEMORY_NOT_AVAILABLE		= 0x20,
306 	MFI_STAT_MFC_HW_ERROR			= 0x21,
307 	MFI_STAT_NO_HW_PRESENT			= 0x22,
308 	MFI_STAT_NOT_FOUND			= 0x23,
309 	MFI_STAT_NOT_IN_ENCL			= 0x24,
310 	MFI_STAT_PD_CLEAR_IN_PROGRESS		= 0x25,
311 	MFI_STAT_PD_TYPE_WRONG			= 0x26,
312 	MFI_STAT_PR_DISABLED			= 0x27,
313 	MFI_STAT_ROW_INDEX_INVALID		= 0x28,
314 	MFI_STAT_SAS_CONFIG_INVALID_ACTION	= 0x29,
315 	MFI_STAT_SAS_CONFIG_INVALID_DATA	= 0x2a,
316 	MFI_STAT_SAS_CONFIG_INVALID_PAGE	= 0x2b,
317 	MFI_STAT_SAS_CONFIG_INVALID_TYPE	= 0x2c,
318 	MFI_STAT_SCSI_DONE_WITH_ERROR		= 0x2d,
319 	MFI_STAT_SCSI_IO_FAILED			= 0x2e,
320 	MFI_STAT_SCSI_RESERVATION_CONFLICT	= 0x2f,
321 	MFI_STAT_SHUTDOWN_FAILED		= 0x30,
322 	MFI_STAT_TIME_NOT_SET			= 0x31,
323 	MFI_STAT_WRONG_STATE			= 0x32,
324 	MFI_STAT_LD_OFFLINE			= 0x33,
325 	MFI_STAT_INVALID_STATUS			= 0xFF
326 };
327 
328 enum MR_EVT_CLASS {
329 	MR_EVT_CLASS_DEBUG		= -2,
330 	MR_EVT_CLASS_PROGRESS		= -1,
331 	MR_EVT_CLASS_INFO		=  0,
332 	MR_EVT_CLASS_WARNING		=  1,
333 	MR_EVT_CLASS_CRITICAL		=  2,
334 	MR_EVT_CLASS_FATAL		=  3,
335 	MR_EVT_CLASS_DEAD		=  4
336 };
337 
338 enum MR_EVT_LOCALE {
339 	MR_EVT_LOCALE_LD		= 0x0001,
340 	MR_EVT_LOCALE_PD		= 0x0002,
341 	MR_EVT_LOCALE_ENCL		= 0x0004,
342 	MR_EVT_LOCALE_BBU		= 0x0008,
343 	MR_EVT_LOCALE_SAS		= 0x0010,
344 	MR_EVT_LOCALE_CTRL		= 0x0020,
345 	MR_EVT_LOCALE_CONFIG		= 0x0040,
346 	MR_EVT_LOCALE_CLUSTER		= 0x0080,
347 	MR_EVT_LOCALE_ALL		= 0xffff
348 };
349 
350 enum MR_EVT_ARGS {
351 	MR_EVT_ARGS_NONE,
352 	MR_EVT_ARGS_CDB_SENSE,
353 	MR_EVT_ARGS_LD,
354 	MR_EVT_ARGS_LD_COUNT,
355 	MR_EVT_ARGS_LD_LBA,
356 	MR_EVT_ARGS_LD_OWNER,
357 	MR_EVT_ARGS_LD_LBA_PD_LBA,
358 	MR_EVT_ARGS_LD_PROG,
359 	MR_EVT_ARGS_LD_STATE,
360 	MR_EVT_ARGS_LD_STRIP,
361 	MR_EVT_ARGS_PD,
362 	MR_EVT_ARGS_PD_ERR,
363 	MR_EVT_ARGS_PD_LBA,
364 	MR_EVT_ARGS_PD_LBA_LD,
365 	MR_EVT_ARGS_PD_PROG,
366 	MR_EVT_ARGS_PD_STATE,
367 	MR_EVT_ARGS_PCI,
368 	MR_EVT_ARGS_RATE,
369 	MR_EVT_ARGS_STR,
370 	MR_EVT_ARGS_TIME,
371 	MR_EVT_ARGS_ECC
372 };
373 
374 #define	MR_EVT_CFG_CLEARED		0x0004
375 #define	MR_EVT_LD_CREATED		0x008a
376 #define	MR_EVT_LD_DELETED		0x008b
377 #define	MR_EVT_CFG_FP_CHANGE		0x017B
378 
379 enum LD_STATE {
380 	LD_OFFLINE		= 0,
381 	LD_PARTIALLY_DEGRADED	= 1,
382 	LD_DEGRADED		= 2,
383 	LD_OPTIMAL		= 3,
384 	LD_INVALID		= 0xFF
385 };
386 
387 enum MRSAS_EVT {
388 	MRSAS_EVT_CONFIG_TGT	= 0,
389 	MRSAS_EVT_UNCONFIG_TGT	= 1,
390 	MRSAS_EVT_UNCONFIG_SMP	= 2
391 };
392 
393 #define	DMA_OBJ_ALLOCATED	1
394 #define	DMA_OBJ_REALLOCATED	2
395 #define	DMA_OBJ_FREED		3
396 
397 /*
398  * dma_obj_t	- Our DMA object
399  * @param buffer	: kernel virtual address
400  * @param size		: size of the data to be allocated
401  * @param acc_handle	: access handle
402  * @param dma_handle	: dma handle
403  * @param dma_cookie	: scatter-gather list
404  * @param dma_attr	: dma attributes for this buffer
405  *
406  * Our DMA object. The caller must initialize the size and dma attributes
407  * (dma_attr) fields before allocating the resources.
408  */
409 typedef struct {
410 	caddr_t			buffer;
411 	uint32_t		size;
412 	ddi_acc_handle_t	acc_handle;
413 	ddi_dma_handle_t	dma_handle;
414 	ddi_dma_cookie_t	dma_cookie[MRSAS_MAX_SGE_CNT];
415 	ddi_dma_attr_t		dma_attr;
416 	uint8_t			status;
417 	uint8_t			reserved[3];
418 } dma_obj_t;
419 
420 struct mrsas_eventinfo {
421 	struct mrsas_instance	*instance;
422 	int 			tgt;
423 	int 			lun;
424 	int 			event;
425 	uint64_t		wwn;
426 };
427 
428 struct mrsas_ld {
429 	dev_info_t		*dip;
430 	uint8_t 		lun_type;
431 	uint8_t			flag;
432 	uint8_t 		reserved[2];
433 };
434 
435 
436 #ifdef PDSUPPORT
437 struct mrsas_tbolt_pd {
438 	dev_info_t		*dip;
439 	uint8_t 		lun_type;
440 	uint8_t 		dev_id;
441 	uint8_t 		flag;
442 	uint8_t 		reserved;
443 };
444 struct mrsas_tbolt_pd_info {
445 	uint16_t	deviceId;
446 	uint16_t	seqNum;
447 	uint8_t		inquiryData[96];
448 	uint8_t		vpdPage83[64];
449 	uint8_t		notSupported;
450 	uint8_t		scsiDevType;
451 	uint8_t		a;
452 	uint8_t		device_speed;
453 	uint32_t	mediaerrcnt;
454 	uint32_t	other;
455 	uint32_t	pred;
456 	uint32_t	lastpred;
457 	uint16_t	fwState;
458 	uint8_t		disabled;
459 	uint8_t		linkspwwd;
460 	uint32_t	ddfType;
461 	struct {
462 		uint8_t	count;
463 		uint8_t	isPathBroken;
464 		uint8_t	connectorIndex[2];
465 		uint8_t	reserved[4];
466 		uint64_t sasAddr[2];
467 		uint8_t	reserved2[16];
468 	} pathInfo;
469 };
470 #endif
471 
472 typedef struct mrsas_instance {
473 	uint32_t	*producer;
474 	uint32_t	*consumer;
475 
476 	uint32_t	*reply_queue;
477 	dma_obj_t	mfi_internal_dma_obj;
478 	uint16_t	adapterresetinprogress;
479 	uint16_t	deadadapter;
480 	/* ThunderBolt (TB) specific */
481 	dma_obj_t	mpi2_frame_pool_dma_obj;
482 	dma_obj_t	request_desc_dma_obj;
483 	dma_obj_t	reply_desc_dma_obj;
484 	dma_obj_t	ld_map_obj[2];
485 
486 	uint8_t		init_id;
487 	uint8_t		flag_ieee;
488 	uint8_t		disable_online_ctrl_reset;
489 	uint8_t		fw_fault_count_after_ocr;
490 
491 	uint16_t	max_num_sge;
492 	uint16_t	max_fw_cmds;
493 	uint32_t	max_sectors_per_req;
494 
495 	struct mrsas_cmd **cmd_list;
496 
497 	mlist_t		cmd_pool_list;
498 	kmutex_t	cmd_pool_mtx;
499 	kmutex_t	sync_map_mtx;
500 
501 	mlist_t		app_cmd_pool_list;
502 	kmutex_t	app_cmd_pool_mtx;
503 	mlist_t		cmd_app_pool_list;
504 	kmutex_t	cmd_app_pool_mtx;
505 
506 
507 	mlist_t		cmd_pend_list;
508 	kmutex_t	cmd_pend_mtx;
509 
510 	dma_obj_t	mfi_evt_detail_obj;
511 	struct mrsas_cmd *aen_cmd;
512 
513 	uint32_t	aen_seq_num;
514 	uint32_t	aen_class_locale_word;
515 
516 	scsi_hba_tran_t		*tran;
517 
518 	kcondvar_t	int_cmd_cv;
519 	kmutex_t	int_cmd_mtx;
520 
521 	kcondvar_t	aen_cmd_cv;
522 	kmutex_t	aen_cmd_mtx;
523 
524 	kcondvar_t	abort_cmd_cv;
525 	kmutex_t	abort_cmd_mtx;
526 
527 	kmutex_t	reg_write_mtx;
528 	kmutex_t	chip_mtx;
529 
530 	dev_info_t		*dip;
531 	ddi_acc_handle_t	pci_handle;
532 
533 	timeout_id_t	timeout_id;
534 	uint32_t	unique_id;
535 	uint16_t	fw_outstanding;
536 	caddr_t		regmap;
537 	ddi_acc_handle_t	regmap_handle;
538 	uint8_t		isr_level;
539 	ddi_iblock_cookie_t	iblock_cookie;
540 	ddi_iblock_cookie_t	soft_iblock_cookie;
541 	ddi_softintr_t		soft_intr_id;
542 	uint8_t		softint_running;
543 	uint8_t		tbolt_softint_running;
544 	kmutex_t	completed_pool_mtx;
545 	mlist_t		completed_pool_list;
546 
547 	caddr_t		internal_buf;
548 	uint32_t	internal_buf_dmac_add;
549 	uint32_t	internal_buf_size;
550 
551 	uint16_t	vendor_id;
552 	uint16_t	device_id;
553 	uint16_t	subsysvid;
554 	uint16_t	subsysid;
555 	int		instance;
556 	int		baseaddress;
557 	char		iocnode[16];
558 
559 	int		fm_capabilities;
560 	/*
561 	 * Driver resources unroll flags.  The flag is set for resources that
562 	 * are needed to be free'd at detach() time.
563 	 */
564 	struct _unroll {
565 		uint8_t softs;		/* The software state was allocated. */
566 		uint8_t regs;		/* Controller registers mapped. */
567 		uint8_t intr;		/* Interrupt handler added. */
568 		uint8_t reqs;		/* Request structs allocated. */
569 		uint8_t mutexs;		/* Mutex's allocated. */
570 		uint8_t taskq;		/* Task q's created. */
571 		uint8_t tran;		/* Tran struct allocated */
572 		uint8_t tranSetup;	/* Tran attached to the ddi. */
573 		uint8_t devctl;		/* Device nodes for cfgadm created. */
574 		uint8_t scsictl;	/* Device nodes for cfgadm created. */
575 		uint8_t ioctl;		/* Device nodes for ioctl's created. */
576 		uint8_t timer;		/* Timer started. */
577 		uint8_t aenPend;	/* AEN cmd pending f/w. */
578 		uint8_t mapUpdate_pend; /* LD MAP update cmd pending f/w. */
579 		uint8_t soft_isr;	/* Soft interrupt handler allocated. */
580 		uint8_t ldlist_buff;	/* Logical disk list allocated. */
581 		uint8_t pdlist_buff;	/* Physical disk list allocated. */
582 		uint8_t syncCmd;	/* Sync map command allocated. */
583 		uint8_t verBuff;	/* 2108 MFI buffer allocated. */
584 		uint8_t alloc_space_mfi;  /* Allocated space for 2108 MFI. */
585 		uint8_t alloc_space_mpi2; /* Allocated space for 2208 MPI2. */
586 	} unroll;
587 
588 
589 	/* function template pointer */
590 	struct mrsas_function_template *func_ptr;
591 
592 
593 	/* MSI interrupts specific */
594 	ddi_intr_handle_t *intr_htable;		/* Interrupt handle array */
595 	size_t		intr_htable_size;	/* Int. handle array size */
596 	int		intr_type;
597 	int		intr_cnt;
598 	uint_t		intr_pri;
599 	int		intr_cap;
600 
601 	ddi_taskq_t	*taskq;
602 	struct mrsas_ld	*mr_ld_list;
603 	kmutex_t	config_dev_mtx;
604 	/* ThunderBolt (TB) specific */
605 	ddi_softintr_t	tbolt_soft_intr_id;
606 
607 #ifdef PDSUPPORT
608 	uint32_t	mr_tbolt_pd_max;
609 	struct mrsas_tbolt_pd *mr_tbolt_pd_list;
610 #endif
611 
612 	uint8_t		fast_path_io;
613 
614 	uint8_t		skinny;
615 	uint8_t		tbolt;
616 	uint8_t		gen3;
617 	uint16_t	reply_read_index;
618 	uint16_t	reply_size; 		/* Single Reply struct size */
619 	uint16_t	raid_io_msg_size; 	/* Single message size */
620 	uint32_t	io_request_frames_phy;
621 	uint8_t 	*io_request_frames;
622 	/* Virtual address of request desc frame pool */
623 	MRSAS_REQUEST_DESCRIPTOR_UNION	*request_message_pool;
624 	/* Physical address of request desc frame pool */
625 	uint32_t	request_message_pool_phy;
626 	/* Virtual address of reply Frame */
627 	MPI2_REPLY_DESCRIPTORS_UNION	*reply_frame_pool;
628 	/* Physical address of reply Frame */
629 	uint32_t	reply_frame_pool_phy;
630 	uint8_t		*reply_pool_limit;	/* Last reply frame address */
631 	/* Physical address of Last reply frame */
632 	uint32_t	reply_pool_limit_phy;
633 	uint32_t	reply_q_depth;		/* Reply Queue Depth */
634 	uint8_t		max_sge_in_main_msg;
635 	uint8_t		max_sge_in_chain;
636 	uint8_t    	chain_offset_io_req;
637 	uint8_t		chain_offset_mpt_msg;
638 	MR_FW_RAID_MAP_ALL *ld_map[2];
639 	uint32_t 	ld_map_phy[2];
640 	uint32_t	size_map_info;
641 	uint64_t 	map_id;
642 	LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES];
643 	struct mrsas_cmd *map_update_cmd;
644 	uint32_t	SyncRequired;
645 	kmutex_t	ocr_flags_mtx;
646 	dma_obj_t	drv_ver_dma_obj;
647 } mrsas_t;
648 
649 
650 /*
651  * Function templates for various controller specific functions
652  */
653 struct mrsas_function_template {
654 	uint32_t (*read_fw_status_reg)(struct mrsas_instance *);
655 	void (*issue_cmd)(struct mrsas_cmd *, struct mrsas_instance *);
656 	int (*issue_cmd_in_sync_mode)(struct mrsas_instance *,
657 	    struct mrsas_cmd *);
658 	int (*issue_cmd_in_poll_mode)(struct mrsas_instance *,
659 	    struct mrsas_cmd *);
660 	void (*enable_intr)(struct mrsas_instance *);
661 	void (*disable_intr)(struct mrsas_instance *);
662 	int (*intr_ack)(struct mrsas_instance *);
663 	int (*init_adapter)(struct mrsas_instance *);
664 /*	int (*reset_adapter)(struct mrsas_instance *); */
665 };
666 
667 /*
668  * ### Helper routines ###
669  */
670 
671 /*
672  * con_log() - console log routine
673  * @param level		: indicates the severity of the message.
674  * @fparam mt		: format string
675  *
676  * con_log displays the error messages on the console based on the current
677  * debug level. Also it attaches the appropriate kernel severity level with
678  * the message.
679  *
680  *
681  * console messages debug levels
682  */
683 #define	CL_NONE		0	/* No debug information */
684 #define	CL_ANN		1	/* print unconditionally, announcements */
685 #define	CL_ANN1		2	/* No-op  */
686 #define	CL_DLEVEL1	3	/* debug level 1, informative */
687 #define	CL_DLEVEL2	4	/* debug level 2, verbose */
688 #define	CL_DLEVEL3	5	/* debug level 3, very verbose */
689 
690 #ifdef __SUNPRO_C
691 #define	__func__ ""
692 #endif
693 
694 #define	con_log(level, fmt) { if (debug_level_g >= level) cmn_err fmt; }
695 
696 /*
697  * ### SCSA definitions ###
698  */
699 #define	PKT2TGT(pkt)	((pkt)->pkt_address.a_target)
700 #define	PKT2LUN(pkt)	((pkt)->pkt_address.a_lun)
701 #define	PKT2TRAN(pkt)	((pkt)->pkt_adress.a_hba_tran)
702 #define	ADDR2TRAN(ap)	((ap)->a_hba_tran)
703 
704 #define	TRAN2MR(tran)	(struct mrsas_instance *)(tran)->tran_hba_private)
705 #define	ADDR2MR(ap)	(TRAN2MR(ADDR2TRAN(ap))
706 
707 #define	PKT2CMD(pkt)	((struct scsa_cmd *)(pkt)->pkt_ha_private)
708 #define	CMD2PKT(sp)	((sp)->cmd_pkt)
709 #define	PKT2REQ(pkt)	(&(PKT2CMD(pkt)->request))
710 
711 #define	CMD2ADDR(cmd)	(&CMD2PKT(cmd)->pkt_address)
712 #define	CMD2TRAN(cmd)	(CMD2PKT(cmd)->pkt_address.a_hba_tran)
713 #define	CMD2MR(cmd)	(TRAN2MR(CMD2TRAN(cmd)))
714 
715 #define	CFLAG_DMAVALID		0x0001	/* requires a dma operation */
716 #define	CFLAG_DMASEND		0x0002	/* Transfer from the device */
717 #define	CFLAG_CONSISTENT	0x0040	/* consistent data transfer */
718 
719 /*
720  * ### Data structures for ioctl inteface and internal commands ###
721  */
722 
723 /*
724  * Data direction flags
725  */
726 #define	UIOC_RD		0x00001
727 #define	UIOC_WR		0x00002
728 
729 #define	SCP2HOST(scp)		(scp)->device->host	/* to host */
730 #define	SCP2HOSTDATA(scp)	SCP2HOST(scp)->hostdata	/* to soft state */
731 #define	SCP2CHANNEL(scp)	(scp)->device->channel	/* to channel */
732 #define	SCP2TARGET(scp)		(scp)->device->id	/* to target */
733 #define	SCP2LUN(scp)		(scp)->device->lun	/* to LUN */
734 
735 #define	SCSIHOST2ADAP(host)	(((caddr_t *)(host->hostdata))[0])
736 #define	SCP2ADAPTER(scp)				\
737 	(struct mrsas_instance *)SCSIHOST2ADAP(SCP2HOST(scp))
738 
739 #define	MRDRV_IS_LOGICAL_SCSA(instance, acmd)		\
740 	(acmd->device_id < MRDRV_MAX_LD) ? 1 : 0
741 #define	MRDRV_IS_LOGICAL(ap)				\
742 	((ap->a_target < MRDRV_MAX_LD) && (ap->a_lun == 0)) ? 1 : 0
743 #define	MAP_DEVICE_ID(instance, ap)			\
744 	(ap->a_target)
745 
746 #define	HIGH_LEVEL_INTR			1
747 #define	NORMAL_LEVEL_INTR		0
748 
749 #define		IO_TIMEOUT_VAL		0
750 #define		IO_RETRY_COUNT		3
751 #define		MAX_FW_RESET_COUNT	3
752 /*
753  * scsa_cmd  - Per-command mr private data
754  * @param cmd_dmahandle		:  dma handle
755  * @param cmd_dmacookies	:  current dma cookies
756  * @param cmd_pkt		:  scsi_pkt reference
757  * @param cmd_dmacount		:  dma count
758  * @param cmd_cookie		:  next cookie
759  * @param cmd_ncookies		:  cookies per window
760  * @param cmd_cookiecnt		:  cookies per sub-win
761  * @param cmd_nwin		:  number of dma windows
762  * @param cmd_curwin		:  current dma window
763  * @param cmd_dma_offset	:  current window offset
764  * @param cmd_dma_len		:  current window length
765  * @param cmd_flags		:  private flags
766  * @param cmd_cdblen		:  length of cdb
767  * @param cmd_scblen		:  length of scb
768  * @param cmd_buf		:  command buffer
769  * @param channel		:  channel for scsi sub-system
770  * @param target		:  target for scsi sub-system
771  * @param lun			:  LUN for scsi sub-system
772  *
773  * - Allocated at same time as scsi_pkt by scsi_hba_pkt_alloc(9E)
774  * - Pointed to by pkt_ha_private field in scsi_pkt
775  */
776 struct scsa_cmd {
777 	ddi_dma_handle_t	cmd_dmahandle;
778 	ddi_dma_cookie_t	cmd_dmacookies[MRSAS_MAX_SGE_CNT];
779 	struct scsi_pkt		*cmd_pkt;
780 	ulong_t			cmd_dmacount;
781 	uint_t			cmd_cookie;
782 	uint_t			cmd_ncookies;
783 	uint_t			cmd_cookiecnt;
784 	uint_t			cmd_nwin;
785 	uint_t			cmd_curwin;
786 	off_t			cmd_dma_offset;
787 	ulong_t			cmd_dma_len;
788 	ulong_t			cmd_flags;
789 	uint_t			cmd_cdblen;
790 	uint_t			cmd_scblen;
791 	struct buf		*cmd_buf;
792 	ushort_t		device_id;
793 	uchar_t			islogical;
794 	uchar_t			lun;
795 	struct mrsas_device	*mrsas_dev;
796 };
797 
798 
799 struct mrsas_cmd {
800 	/*
801 	 * ThunderBolt(TB) We would be needing to have a placeholder
802 	 * for RAID_MSG_IO_REQUEST inside this structure. We are
803 	 * supposed to embed the mr_frame inside the RAID_MSG and post
804 	 * it down to the firmware.
805 	 */
806 	union mrsas_frame	*frame;
807 	uint32_t		frame_phys_addr;
808 	uint8_t			*sense;
809 	uint8_t			*sense1;
810 	uint32_t		sense_phys_addr;
811 	uint32_t		sense_phys_addr1;
812 	dma_obj_t		frame_dma_obj;
813 	uint8_t			frame_dma_obj_status;
814 	uint32_t		index;
815 	uint8_t			sync_cmd;
816 	uint8_t			cmd_status;
817 	uint16_t		abort_aen;
818 	mlist_t			list;
819 	uint32_t		frame_count;
820 	struct scsa_cmd		*cmd;
821 	struct scsi_pkt		*pkt;
822 	Mpi2RaidSCSIIORequest_t *scsi_io_request;
823 	Mpi2SGEIOUnion_t	*sgl;
824 	uint32_t		sgl_phys_addr;
825 	uint32_t		scsi_io_request_phys_addr;
826 	MRSAS_REQUEST_DESCRIPTOR_UNION	*request_desc;
827 	uint16_t		SMID;
828 	uint16_t		retry_count_for_ocr;
829 	uint16_t		drv_pkt_time;
830 	uint16_t		load_balance_flag;
831 
832 };
833 
834 #define	MAX_MGMT_ADAPTERS			1024
835 #define	IOC_SIGNATURE				"MR-SAS"
836 
837 #define	IOC_CMD_FIRMWARE			0x0
838 #define	MRSAS_DRIVER_IOCTL_COMMON		0xF0010000
839 #define	MRSAS_DRIVER_IOCTL_DRIVER_VERSION	0xF0010100
840 #define	MRSAS_DRIVER_IOCTL_PCI_INFORMATION	0xF0010200
841 #define	MRSAS_DRIVER_IOCTL_MRRAID_STATISTICS	0xF0010300
842 
843 
844 #define	MRSAS_MAX_SENSE_LENGTH			32
845 
846 struct mrsas_mgmt_info {
847 
848 	uint16_t			count;
849 	struct mrsas_instance		*instance[MAX_MGMT_ADAPTERS];
850 	uint16_t			map[MAX_MGMT_ADAPTERS];
851 	int				max_index;
852 };
853 
854 
855 #pragma pack(1)
856 /*
857  * SAS controller properties
858  */
859 struct mrsas_ctrl_prop {
860 	uint16_t	seq_num;
861 	uint16_t	pred_fail_poll_interval;
862 	uint16_t	intr_throttle_count;
863 	uint16_t	intr_throttle_timeouts;
864 
865 	uint8_t		rebuild_rate;
866 	uint8_t		patrol_read_rate;
867 	uint8_t		bgi_rate;
868 	uint8_t		cc_rate;
869 	uint8_t		recon_rate;
870 
871 	uint8_t		cache_flush_interval;
872 
873 	uint8_t		spinup_drv_count;
874 	uint8_t		spinup_delay;
875 
876 	uint8_t		cluster_enable;
877 	uint8_t		coercion_mode;
878 	uint8_t		alarm_enable;
879 
880 	uint8_t		reserved_1[13];
881 	uint32_t	on_off_properties;
882 	uint8_t		reserved_4[28];
883 };
884 
885 
886 /*
887  * SAS controller information
888  */
889 struct mrsas_ctrl_info {
890 	/* PCI device information */
891 	struct {
892 		uint16_t	vendor_id;
893 		uint16_t	device_id;
894 		uint16_t	sub_vendor_id;
895 		uint16_t	sub_device_id;
896 		uint8_t	reserved[24];
897 	} pci;
898 
899 	/* Host interface information */
900 	struct {
901 		uint8_t	PCIX		: 1;
902 		uint8_t	PCIE		: 1;
903 		uint8_t	iSCSI		: 1;
904 		uint8_t	SAS_3G		: 1;
905 		uint8_t	reserved_0	: 4;
906 		uint8_t	reserved_1[6];
907 		uint8_t	port_count;
908 		uint64_t	port_addr[8];
909 	} host_interface;
910 
911 	/* Device (backend) interface information */
912 	struct {
913 		uint8_t	SPI		: 1;
914 		uint8_t	SAS_3G		: 1;
915 		uint8_t	SATA_1_5G	: 1;
916 		uint8_t	SATA_3G		: 1;
917 		uint8_t	reserved_0	: 4;
918 		uint8_t	reserved_1[6];
919 		uint8_t	port_count;
920 		uint64_t	port_addr[8];
921 	} device_interface;
922 
923 	/* List of components residing in flash. All str are null terminated */
924 	uint32_t	image_check_word;
925 	uint32_t	image_component_count;
926 
927 	struct {
928 		char	name[8];
929 		char	version[32];
930 		char	build_date[16];
931 		char	built_time[16];
932 	} image_component[8];
933 
934 	/*
935 	 * List of flash components that have been flashed on the card, but
936 	 * are not in use, pending reset of the adapter. This list will be
937 	 * empty if a flash operation has not occurred. All stings are null
938 	 * terminated
939 	 */
940 	uint32_t	pending_image_component_count;
941 
942 	struct {
943 		char	name[8];
944 		char	version[32];
945 		char	build_date[16];
946 		char	build_time[16];
947 	} pending_image_component[8];
948 
949 	uint8_t		max_arms;
950 	uint8_t		max_spans;
951 	uint8_t		max_arrays;
952 	uint8_t		max_lds;
953 
954 	char		product_name[80];
955 	char		serial_no[32];
956 
957 	/*
958 	 * Other physical/controller/operation information. Indicates the
959 	 * presence of the hardware
960 	 */
961 	struct {
962 		uint32_t	bbu		: 1;
963 		uint32_t	alarm		: 1;
964 		uint32_t	nvram		: 1;
965 		uint32_t	uart		: 1;
966 		uint32_t	reserved	: 28;
967 	} hw_present;
968 
969 	uint32_t	current_fw_time;
970 
971 	/* Maximum data transfer sizes */
972 	uint16_t		max_concurrent_cmds;
973 	uint16_t		max_sge_count;
974 	uint32_t		max_request_size;
975 
976 	/* Logical and physical device counts */
977 	uint16_t		ld_present_count;
978 	uint16_t		ld_degraded_count;
979 	uint16_t		ld_offline_count;
980 
981 	uint16_t		pd_present_count;
982 	uint16_t		pd_disk_present_count;
983 	uint16_t		pd_disk_pred_failure_count;
984 	uint16_t		pd_disk_failed_count;
985 
986 	/* Memory size information */
987 	uint16_t		nvram_size;
988 	uint16_t		memory_size;
989 	uint16_t		flash_size;
990 
991 	/* Error counters */
992 	uint16_t		mem_correctable_error_count;
993 	uint16_t		mem_uncorrectable_error_count;
994 
995 	/* Cluster information */
996 	uint8_t		cluster_permitted;
997 	uint8_t		cluster_active;
998 	uint8_t		reserved_1[2];
999 
1000 	/* Controller capabilities structures */
1001 	struct {
1002 		uint32_t	raid_level_0	: 1;
1003 		uint32_t	raid_level_1	: 1;
1004 		uint32_t	raid_level_5	: 1;
1005 		uint32_t	raid_level_1E	: 1;
1006 		uint32_t	reserved	: 28;
1007 	} raid_levels;
1008 
1009 	struct {
1010 		uint32_t	rbld_rate		: 1;
1011 		uint32_t	cc_rate			: 1;
1012 		uint32_t	bgi_rate		: 1;
1013 		uint32_t	recon_rate		: 1;
1014 		uint32_t	patrol_rate		: 1;
1015 		uint32_t	alarm_control		: 1;
1016 		uint32_t	cluster_supported	: 1;
1017 		uint32_t	bbu			: 1;
1018 		uint32_t	spanning_allowed	: 1;
1019 		uint32_t	dedicated_hotspares	: 1;
1020 		uint32_t	revertible_hotspares	: 1;
1021 		uint32_t	foreign_config_import	: 1;
1022 		uint32_t	self_diagnostic		: 1;
1023 		uint32_t	reserved		: 19;
1024 	} adapter_operations;
1025 
1026 	struct {
1027 		uint32_t	read_policy	: 1;
1028 		uint32_t	write_policy	: 1;
1029 		uint32_t	io_policy	: 1;
1030 		uint32_t	access_policy	: 1;
1031 		uint32_t	reserved	: 28;
1032 	} ld_operations;
1033 
1034 	struct {
1035 		uint8_t	min;
1036 		uint8_t	max;
1037 		uint8_t	reserved[2];
1038 	} stripe_size_operations;
1039 
1040 	struct {
1041 		uint32_t	force_online	: 1;
1042 		uint32_t	force_offline	: 1;
1043 		uint32_t	force_rebuild	: 1;
1044 		uint32_t	reserved	: 29;
1045 	} pd_operations;
1046 
1047 	struct {
1048 		uint32_t	ctrl_supports_sas	: 1;
1049 		uint32_t	ctrl_supports_sata	: 1;
1050 		uint32_t	allow_mix_in_encl	: 1;
1051 		uint32_t	allow_mix_in_ld		: 1;
1052 		uint32_t	allow_sata_in_cluster	: 1;
1053 		uint32_t	reserved		: 27;
1054 	} pd_mix_support;
1055 
1056 	/* Include the controller properties (changeable items) */
1057 	uint8_t				reserved_2[12];
1058 	struct mrsas_ctrl_prop		properties;
1059 
1060 	uint8_t				pad[0x800 - 0x640];
1061 };
1062 
1063 /*
1064  * ==================================
1065  * MegaRAID SAS2.0 driver definitions
1066  * ==================================
1067  */
1068 #define	MRDRV_MAX_NUM_CMD			1024
1069 
1070 #define	MRDRV_MAX_PD_CHANNELS			2
1071 #define	MRDRV_MAX_LD_CHANNELS			2
1072 #define	MRDRV_MAX_CHANNELS			(MRDRV_MAX_PD_CHANNELS + \
1073 						MRDRV_MAX_LD_CHANNELS)
1074 #define	MRDRV_MAX_DEV_PER_CHANNEL		128
1075 #define	MRDRV_DEFAULT_INIT_ID			-1
1076 #define	MRDRV_MAX_CMD_PER_LUN			1000
1077 #define	MRDRV_MAX_LUN				1
1078 #define	MRDRV_MAX_LD				64
1079 
1080 #define	MRDRV_RESET_WAIT_TIME			300
1081 #define	MRDRV_RESET_NOTICE_INTERVAL		5
1082 
1083 #define	MRSAS_IOCTL_CMD				0
1084 
1085 #define	MRDRV_TGT_VALID				1
1086 
1087 /*
1088  * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
1089  * SGLs based on the size of dma_addr_t
1090  */
1091 #define	IS_DMA64		(sizeof (dma_addr_t) == 8)
1092 
1093 #define	RESERVED0_REGISTER		0x00	/* XScale */
1094 #define	IB_MSG_0_OFF			0x10	/* XScale */
1095 #define	OB_MSG_0_OFF			0x18	/* XScale */
1096 #define	IB_DOORBELL_OFF			0x20	/* XScale & ROC */
1097 #define	OB_INTR_STATUS_OFF		0x30	/* XScale & ROC */
1098 #define	OB_INTR_MASK_OFF		0x34	/* XScale & ROC */
1099 #define	IB_QPORT_OFF			0x40	/* XScale & ROC */
1100 #define	OB_DOORBELL_CLEAR_OFF		0xA0	/* ROC */
1101 #define	OB_SCRATCH_PAD_0_OFF		0xB0	/* ROC */
1102 #define	OB_INTR_MASK			0xFFFFFFFF
1103 #define	OB_DOORBELL_CLEAR_MASK		0xFFFFFFFF
1104 #define	SYSTOIOP_INTERRUPT_MASK		0x80000000
1105 #define	OB_SCRATCH_PAD_2_OFF		0xB4
1106 #define	WRITE_TBOLT_SEQ_OFF		0x00000004
1107 #define	DIAG_TBOLT_RESET_ADAPTER	0x00000004
1108 #define	HOST_TBOLT_DIAG_OFF		0x00000008
1109 #define	RESET_TBOLT_STATUS_OFF		0x000003C3
1110 #define	WRITE_SEQ_OFF			0x000000FC
1111 #define	HOST_DIAG_OFF			0x000000F8
1112 #define	DIAG_RESET_ADAPTER		0x00000004
1113 #define	DIAG_WRITE_ENABLE		0x00000080
1114 #define	SYSTOIOP_INTERRUPT_MASK		0x80000000
1115 
1116 #define	WR_IB_WRITE_SEQ(v, instance) 	ddi_put32((instance)->regmap_handle, \
1117 	(uint32_t *)((uintptr_t)(instance)->regmap + WRITE_SEQ_OFF), (v))
1118 
1119 #define	RD_OB_DRWE(instance) 		ddi_get32((instance)->regmap_handle, \
1120 	(uint32_t *)((uintptr_t)(instance)->regmap + HOST_DIAG_OFF))
1121 
1122 #define	WR_IB_DRWE(v, instance) 	ddi_put32((instance)->regmap_handle, \
1123 	(uint32_t *)((uintptr_t)(instance)->regmap + HOST_DIAG_OFF), (v))
1124 
1125 #define	IB_LOW_QPORT			0xC0
1126 #define	IB_HIGH_QPORT			0xC4
1127 #define	OB_DOORBELL_REGISTER		0x9C	/* 1078 implementation */
1128 
1129 /*
1130  * All MFI register set macros accept mrsas_register_set*
1131  */
1132 #define	WR_IB_MSG_0(v, instance) 	ddi_put32((instance)->regmap_handle, \
1133 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_MSG_0_OFF), (v))
1134 
1135 #define	RD_OB_MSG_0(instance) 		ddi_get32((instance)->regmap_handle, \
1136 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_MSG_0_OFF))
1137 
1138 #define	WR_IB_DOORBELL(v, instance)	ddi_put32((instance)->regmap_handle, \
1139 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_DOORBELL_OFF), (v))
1140 
1141 #define	RD_IB_DOORBELL(instance)	ddi_get32((instance)->regmap_handle, \
1142 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_DOORBELL_OFF))
1143 
1144 #define	WR_OB_INTR_STATUS(v, instance) 	ddi_put32((instance)->regmap_handle, \
1145 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_STATUS_OFF), (v))
1146 
1147 #define	RD_OB_INTR_STATUS(instance) 	ddi_get32((instance)->regmap_handle, \
1148 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_STATUS_OFF))
1149 
1150 #define	WR_OB_INTR_MASK(v, instance) 	ddi_put32((instance)->regmap_handle, \
1151 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF), (v))
1152 
1153 #define	RD_OB_INTR_MASK(instance) 	ddi_get32((instance)->regmap_handle, \
1154 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF))
1155 
1156 #define	WR_IB_QPORT(v, instance) 	ddi_put32((instance)->regmap_handle, \
1157 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_QPORT_OFF), (v))
1158 
1159 #define	WR_OB_DOORBELL_CLEAR(v, instance) ddi_put32((instance)->regmap_handle, \
1160 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_DOORBELL_CLEAR_OFF), \
1161 	(v))
1162 
1163 #define	RD_OB_SCRATCH_PAD_0(instance) 	ddi_get32((instance)->regmap_handle, \
1164 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_SCRATCH_PAD_0_OFF))
1165 
1166 /* Thunderbolt specific registers */
1167 #define	RD_OB_SCRATCH_PAD_2(instance)	ddi_get32((instance)->regmap_handle, \
1168 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_SCRATCH_PAD_2_OFF))
1169 
1170 #define	WR_TBOLT_IB_WRITE_SEQ(v, instance) \
1171 	ddi_put32((instance)->regmap_handle, \
1172 	(uint32_t *)((uintptr_t)(instance)->regmap + WRITE_TBOLT_SEQ_OFF), (v))
1173 
1174 #define	RD_TBOLT_HOST_DIAG(instance)	ddi_get32((instance)->regmap_handle, \
1175 	(uint32_t *)((uintptr_t)(instance)->regmap + HOST_TBOLT_DIAG_OFF))
1176 
1177 #define	WR_TBOLT_HOST_DIAG(v, instance)	ddi_put32((instance)->regmap_handle, \
1178 	(uint32_t *)((uintptr_t)(instance)->regmap + HOST_TBOLT_DIAG_OFF), (v))
1179 
1180 #define	RD_TBOLT_RESET_STAT(instance)	ddi_get32((instance)->regmap_handle, \
1181 	(uint32_t *)((uintptr_t)(instance)->regmap + RESET_TBOLT_STATUS_OFF))
1182 
1183 
1184 #define	WR_MPI2_REPLY_POST_INDEX(v, instance)\
1185 	ddi_put32((instance)->regmap_handle,\
1186 	(uint32_t *)\
1187 	((uintptr_t)(instance)->regmap + MPI2_REPLY_POST_HOST_INDEX_OFFSET),\
1188 	(v))
1189 
1190 
1191 #define	RD_MPI2_REPLY_POST_INDEX(instance)\
1192 	ddi_get32((instance)->regmap_handle,\
1193 	(uint32_t *)\
1194 	((uintptr_t)(instance)->regmap + MPI2_REPLY_POST_HOST_INDEX_OFFSET))
1195 
1196 #define	WR_IB_LOW_QPORT(v, instance) 	ddi_put32((instance)->regmap_handle, \
1197 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_LOW_QPORT), (v))
1198 
1199 #define	WR_IB_HIGH_QPORT(v, instance) 	ddi_put32((instance)->regmap_handle, \
1200 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_HIGH_QPORT), (v))
1201 
1202 #define	WR_OB_DOORBELL_REGISTER_CLEAR(v, instance)\
1203 	ddi_put32((instance)->regmap_handle,\
1204 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_DOORBELL_REGISTER), \
1205 	(v))
1206 
1207 #define	WR_RESERVED0_REGISTER(v, instance) ddi_put32((instance)->regmap_handle,\
1208 	(uint32_t *)((uintptr_t)(instance)->regmap + RESERVED0_REGISTER), \
1209 	(v))
1210 
1211 #define	RD_RESERVED0_REGISTER(instance) ddi_get32((instance)->regmap_handle, \
1212 	(uint32_t *)((uintptr_t)(instance)->regmap + RESERVED0_REGISTER))
1213 
1214 
1215 
1216 /*
1217  * When FW is in MFI_STATE_READY or MFI_STATE_OPERATIONAL, the state data
1218  * of Outbound Msg Reg 0 indicates max concurrent cmds supported, max SGEs
1219  * supported per cmd and if 64-bit MFAs (M64) is enabled or disabled.
1220  */
1221 #define	MFI_OB_INTR_STATUS_MASK		0x00000002
1222 
1223 /*
1224  * This MFI_REPLY_2108_MESSAGE_INTR flag is used also
1225  * in enable_intr_ppc also. Hence bit 2, i.e. 0x4 has
1226  * been set in this flag along with bit 1.
1227  */
1228 #define	MFI_REPLY_2108_MESSAGE_INTR		0x00000001
1229 #define	MFI_REPLY_2108_MESSAGE_INTR_MASK	0x00000005
1230 
1231 /* Fusion interrupt mask */
1232 #define	MFI_FUSION_ENABLE_INTERRUPT_MASK	(0x00000008)
1233 
1234 #define	MFI_POLL_TIMEOUT_SECS		60
1235 
1236 #define	MFI_ENABLE_INTR(instance)  ddi_put32((instance)->regmap_handle, \
1237 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF), 1)
1238 #define	MFI_DISABLE_INTR(instance)					\
1239 {									\
1240 	uint32_t disable = 1;						\
1241 	uint32_t mask =  ddi_get32((instance)->regmap_handle, 		\
1242 	    (uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF));\
1243 	mask &= ~disable;						\
1244 	ddi_put32((instance)->regmap_handle, (uint32_t *)		\
1245 	    (uintptr_t)((instance)->regmap + OB_INTR_MASK_OFF), mask);	\
1246 }
1247 
1248 /* By default, the firmware programs for 8 Kbytes of memory */
1249 #define	DEFAULT_MFI_MEM_SZ	8192
1250 #define	MINIMUM_MFI_MEM_SZ	4096
1251 
1252 /* DCMD Message Frame MAILBOX0-11 */
1253 #define	DCMD_MBOX_SZ		12
1254 
1255 /*
1256  * on_off_property of mrsas_ctrl_prop
1257  * bit0-9, 11-31 are reserved
1258  */
1259 #define	DISABLE_OCR_PROP_FLAG   0x00000400 /* bit 10 */
1260 
1261 struct mrsas_register_set {
1262 	uint32_t	reserved_0[4];			/* 0000h */
1263 
1264 	uint32_t	inbound_msg_0;			/* 0010h */
1265 	uint32_t	inbound_msg_1;			/* 0014h */
1266 	uint32_t	outbound_msg_0;			/* 0018h */
1267 	uint32_t	outbound_msg_1;			/* 001Ch */
1268 
1269 	uint32_t	inbound_doorbell;		/* 0020h */
1270 	uint32_t	inbound_intr_status;		/* 0024h */
1271 	uint32_t	inbound_intr_mask;		/* 0028h */
1272 
1273 	uint32_t	outbound_doorbell;		/* 002Ch */
1274 	uint32_t	outbound_intr_status;		/* 0030h */
1275 	uint32_t	outbound_intr_mask;		/* 0034h */
1276 
1277 	uint32_t	reserved_1[2];			/* 0038h */
1278 
1279 	uint32_t	inbound_queue_port;		/* 0040h */
1280 	uint32_t	outbound_queue_port;		/* 0044h */
1281 
1282 	uint32_t 	reserved_2[22];			/* 0048h */
1283 
1284 	uint32_t 	outbound_doorbell_clear;	/* 00A0h */
1285 
1286 	uint32_t 	reserved_3[3];			/* 00A4h */
1287 
1288 	uint32_t 	outbound_scratch_pad;		/* 00B0h */
1289 
1290 	uint32_t 	reserved_4[3];			/* 00B4h */
1291 
1292 	uint32_t 	inbound_low_queue_port;		/* 00C0h */
1293 
1294 	uint32_t 	inbound_high_queue_port;	/* 00C4h */
1295 
1296 	uint32_t 	reserved_5;			/* 00C8h */
1297 	uint32_t 	index_registers[820];		/* 00CCh */
1298 };
1299 
1300 struct mrsas_sge32 {
1301 	uint32_t	phys_addr;
1302 	uint32_t	length;
1303 };
1304 
1305 struct mrsas_sge64 {
1306 	uint64_t	phys_addr;
1307 	uint32_t	length;
1308 };
1309 
1310 struct mrsas_sge_ieee {
1311 	uint64_t 	phys_addr;
1312 	uint32_t	length;
1313 	uint32_t	flag;
1314 };
1315 
1316 union mrsas_sgl {
1317 	struct mrsas_sge32	sge32[1];
1318 	struct mrsas_sge64	sge64[1];
1319 	struct mrsas_sge_ieee	sge_ieee[1];
1320 };
1321 
1322 struct mrsas_header {
1323 	uint8_t		cmd;				/* 00h */
1324 	uint8_t		sense_len;			/* 01h */
1325 	uint8_t		cmd_status;			/* 02h */
1326 	uint8_t		scsi_status;			/* 03h */
1327 
1328 	uint8_t		target_id;			/* 04h */
1329 	uint8_t		lun;				/* 05h */
1330 	uint8_t		cdb_len;			/* 06h */
1331 	uint8_t		sge_count;			/* 07h */
1332 
1333 	uint32_t	context;			/* 08h */
1334 	uint8_t		req_id;				/* 0Ch */
1335 	uint8_t		msgvector;			/* 0Dh */
1336 	uint16_t	pad_0;				/* 0Eh */
1337 
1338 	uint16_t	flags;				/* 10h */
1339 	uint16_t	timeout;			/* 12h */
1340 	uint32_t	data_xferlen;			/* 14h */
1341 };
1342 
1343 union mrsas_sgl_frame {
1344 	struct mrsas_sge32	sge32[8];
1345 	struct mrsas_sge64	sge64[5];
1346 };
1347 
1348 struct mrsas_init_frame {
1349 	uint8_t		cmd;				/* 00h */
1350 	uint8_t		reserved_0;			/* 01h */
1351 	uint8_t		cmd_status;			/* 02h */
1352 
1353 	uint8_t		reserved_1;			/* 03h */
1354 	uint32_t	reserved_2;			/* 04h */
1355 
1356 	uint32_t	context;			/* 08h */
1357 	uint8_t		req_id;				/* 0Ch */
1358 	uint8_t		msgvector;			/* 0Dh */
1359 	uint16_t	pad_0;				/* 0Eh */
1360 
1361 	uint16_t	flags;				/* 10h */
1362 	uint16_t	reserved_3;			/* 12h */
1363 	uint32_t	data_xfer_len;			/* 14h */
1364 
1365 	uint32_t	queue_info_new_phys_addr_lo;	/* 18h */
1366 	uint32_t	queue_info_new_phys_addr_hi;	/* 1Ch */
1367 	uint32_t	queue_info_old_phys_addr_lo;	/* 20h */
1368 	uint32_t	queue_info_old_phys_addr_hi;	/* 24h */
1369 	uint64_t 	driverversion;			/* 28h */
1370 	uint32_t	reserved_4[4];			/* 30h */
1371 };
1372 
1373 struct mrsas_init_queue_info {
1374 	uint32_t		init_flags;			/* 00h */
1375 	uint32_t		reply_queue_entries;		/* 04h */
1376 
1377 	uint32_t		reply_queue_start_phys_addr_lo;	/* 08h */
1378 	uint32_t		reply_queue_start_phys_addr_hi;	/* 0Ch */
1379 	uint32_t		producer_index_phys_addr_lo;	/* 10h */
1380 	uint32_t		producer_index_phys_addr_hi;	/* 14h */
1381 	uint32_t		consumer_index_phys_addr_lo;	/* 18h */
1382 	uint32_t		consumer_index_phys_addr_hi;	/* 1Ch */
1383 };
1384 
1385 struct mrsas_io_frame {
1386 	uint8_t			cmd;			/* 00h */
1387 	uint8_t			sense_len;		/* 01h */
1388 	uint8_t			cmd_status;		/* 02h */
1389 	uint8_t			scsi_status;		/* 03h */
1390 
1391 	uint8_t			target_id;		/* 04h */
1392 	uint8_t			access_byte;		/* 05h */
1393 	uint8_t			reserved_0;		/* 06h */
1394 	uint8_t			sge_count;		/* 07h */
1395 
1396 	uint32_t		context;		/* 08h */
1397 	uint8_t			req_id;			/* 0Ch */
1398 	uint8_t			msgvector;		/* 0Dh */
1399 	uint16_t		pad_0;			/* 0Eh */
1400 
1401 	uint16_t		flags;			/* 10h */
1402 	uint16_t		timeout;		/* 12h */
1403 	uint32_t		lba_count;		/* 14h */
1404 
1405 	uint32_t		sense_buf_phys_addr_lo;	/* 18h */
1406 	uint32_t		sense_buf_phys_addr_hi;	/* 1Ch */
1407 
1408 	uint32_t		start_lba_lo;		/* 20h */
1409 	uint32_t		start_lba_hi;		/* 24h */
1410 
1411 	union mrsas_sgl		sgl;			/* 28h */
1412 };
1413 
1414 struct mrsas_pthru_frame {
1415 	uint8_t			cmd;			/* 00h */
1416 	uint8_t			sense_len;		/* 01h */
1417 	uint8_t			cmd_status;		/* 02h */
1418 	uint8_t			scsi_status;		/* 03h */
1419 
1420 	uint8_t			target_id;		/* 04h */
1421 	uint8_t			lun;			/* 05h */
1422 	uint8_t			cdb_len;		/* 06h */
1423 	uint8_t			sge_count;		/* 07h */
1424 
1425 	uint32_t		context;		/* 08h */
1426 	uint8_t			req_id;			/* 0Ch */
1427 	uint8_t			msgvector;		/* 0Dh */
1428 	uint16_t		pad_0;			/* 0Eh */
1429 
1430 	uint16_t		flags;			/* 10h */
1431 	uint16_t		timeout;		/* 12h */
1432 	uint32_t		data_xfer_len;		/* 14h */
1433 
1434 	uint32_t		sense_buf_phys_addr_lo;	/* 18h */
1435 	uint32_t		sense_buf_phys_addr_hi;	/* 1Ch */
1436 
1437 	uint8_t			cdb[16];		/* 20h */
1438 	union mrsas_sgl		sgl;			/* 30h */
1439 };
1440 
1441 struct mrsas_dcmd_frame {
1442 	uint8_t			cmd;			/* 00h */
1443 	uint8_t			reserved_0;		/* 01h */
1444 	uint8_t			cmd_status;		/* 02h */
1445 	uint8_t			reserved_1[4];		/* 03h */
1446 	uint8_t			sge_count;		/* 07h */
1447 
1448 	uint32_t		context;		/* 08h */
1449 	uint8_t			req_id;			/* 0Ch */
1450 	uint8_t			msgvector;		/* 0Dh */
1451 	uint16_t		pad_0;			/* 0Eh */
1452 
1453 	uint16_t		flags;			/* 10h */
1454 	uint16_t		timeout;		/* 12h */
1455 
1456 	uint32_t		data_xfer_len;		/* 14h */
1457 	uint32_t		opcode;			/* 18h */
1458 
1459 	/* uint8_t		mbox[DCMD_MBOX_SZ]; */	/* 1Ch */
1460 	union {						/* 1Ch */
1461 		uint8_t b[DCMD_MBOX_SZ];
1462 		uint16_t s[6];
1463 		uint32_t w[3];
1464 	} mbox;
1465 
1466 	union mrsas_sgl		sgl;			/* 28h */
1467 };
1468 
1469 struct mrsas_abort_frame {
1470 	uint8_t		cmd;				/* 00h */
1471 	uint8_t		reserved_0;			/* 01h */
1472 	uint8_t		cmd_status;			/* 02h */
1473 
1474 	uint8_t		reserved_1;			/* 03h */
1475 	uint32_t	reserved_2;			/* 04h */
1476 
1477 	uint32_t	context;			/* 08h */
1478 	uint8_t		req_id;				/* 0Ch */
1479 	uint8_t		msgvector;			/* 0Dh */
1480 	uint16_t	pad_0;				/* 0Eh */
1481 
1482 	uint16_t	flags;				/* 10h */
1483 	uint16_t	reserved_3;			/* 12h */
1484 	uint32_t	reserved_4;			/* 14h */
1485 
1486 	uint32_t	abort_context;			/* 18h */
1487 	uint32_t	pad_1;				/* 1Ch */
1488 
1489 	uint32_t	abort_mfi_phys_addr_lo;		/* 20h */
1490 	uint32_t	abort_mfi_phys_addr_hi;		/* 24h */
1491 
1492 	uint32_t	reserved_5[6];			/* 28h */
1493 };
1494 
1495 struct mrsas_smp_frame {
1496 	uint8_t		cmd;				/* 00h */
1497 	uint8_t		reserved_1;			/* 01h */
1498 	uint8_t		cmd_status;			/* 02h */
1499 	uint8_t		connection_status;		/* 03h */
1500 
1501 	uint8_t		reserved_2[3];			/* 04h */
1502 	uint8_t		sge_count;			/* 07h */
1503 
1504 	uint32_t	context;			/* 08h */
1505 	uint8_t		req_id;				/* 0Ch */
1506 	uint8_t		msgvector;			/* 0Dh */
1507 	uint16_t	pad_0;				/* 0Eh */
1508 
1509 	uint16_t	flags;				/* 10h */
1510 	uint16_t	timeout;			/* 12h */
1511 
1512 	uint32_t	data_xfer_len;			/* 14h */
1513 
1514 	uint64_t	sas_addr;			/* 20h */
1515 
1516 	union mrsas_sgl	sgl[2];				/* 28h */
1517 };
1518 
1519 struct mrsas_stp_frame {
1520 	uint8_t		cmd;				/* 00h */
1521 	uint8_t		reserved_1;			/* 01h */
1522 	uint8_t		cmd_status;			/* 02h */
1523 	uint8_t		connection_status;		/* 03h */
1524 
1525 	uint8_t		target_id;			/* 04h */
1526 	uint8_t		reserved_2[2];			/* 04h */
1527 	uint8_t		sge_count;			/* 07h */
1528 
1529 	uint32_t	context;			/* 08h */
1530 	uint8_t		req_id;				/* 0Ch */
1531 	uint8_t		msgvector;			/* 0Dh */
1532 	uint16_t	pad_0;				/* 0Eh */
1533 
1534 	uint16_t	flags;				/* 10h */
1535 	uint16_t	timeout;			/* 12h */
1536 
1537 	uint32_t	data_xfer_len;			/* 14h */
1538 
1539 	uint16_t	fis[10];			/* 28h */
1540 	uint32_t	stp_flags;			/* 3C */
1541 	union mrsas_sgl	sgl;				/* 40 */
1542 };
1543 
1544 union mrsas_frame {
1545 	struct mrsas_header		hdr;
1546 	struct mrsas_init_frame		init;
1547 	struct mrsas_io_frame		io;
1548 	struct mrsas_pthru_frame	pthru;
1549 	struct mrsas_dcmd_frame		dcmd;
1550 	struct mrsas_abort_frame	abort;
1551 	struct mrsas_smp_frame		smp;
1552 	struct mrsas_stp_frame		stp;
1553 
1554 	uint8_t			raw_bytes[64];
1555 };
1556 
1557 typedef struct mrsas_pd_address {
1558 	uint16_t	device_id;
1559 	uint16_t	encl_id;
1560 
1561 	union {
1562 		struct {
1563 			uint8_t encl_index;
1564 			uint8_t slot_number;
1565 		} pd_address;
1566 		struct {
1567 			uint8_t	encl_position;
1568 			uint8_t	encl_connector_index;
1569 		} encl_address;
1570 	}address;
1571 
1572 	uint8_t	scsi_dev_type;
1573 
1574 	union {
1575 		uint8_t		port_bitmap;
1576 		uint8_t		port_numbers;
1577 	} connected;
1578 
1579 	uint64_t		sas_addr[2];
1580 } mrsas_pd_address_t;
1581 
1582 union mrsas_evt_class_locale {
1583 	struct {
1584 		uint16_t	locale;
1585 		uint8_t		reserved;
1586 		int8_t		class;
1587 	} members;
1588 
1589 	uint32_t	word;
1590 };
1591 
1592 struct mrsas_evt_log_info {
1593 	uint32_t	newest_seq_num;
1594 	uint32_t	oldest_seq_num;
1595 	uint32_t	clear_seq_num;
1596 	uint32_t	shutdown_seq_num;
1597 	uint32_t	boot_seq_num;
1598 };
1599 
1600 struct mrsas_progress {
1601 	uint16_t	progress;
1602 	uint16_t	elapsed_seconds;
1603 };
1604 
1605 struct mrsas_evtarg_ld {
1606 	uint16_t	target_id;
1607 	uint8_t		ld_index;
1608 	uint8_t		reserved;
1609 };
1610 
1611 struct mrsas_evtarg_pd {
1612 	uint16_t	device_id;
1613 	uint8_t		encl_index;
1614 	uint8_t		slot_number;
1615 };
1616 
1617 struct mrsas_evt_detail {
1618 	uint32_t	seq_num;
1619 	uint32_t	time_stamp;
1620 	uint32_t	code;
1621 	union mrsas_evt_class_locale	cl;
1622 	uint8_t		arg_type;
1623 	uint8_t		reserved1[15];
1624 
1625 	union {
1626 		struct {
1627 			struct mrsas_evtarg_pd	pd;
1628 			uint8_t			cdb_length;
1629 			uint8_t			sense_length;
1630 			uint8_t			reserved[2];
1631 			uint8_t			cdb[16];
1632 			uint8_t			sense[64];
1633 		} cdbSense;
1634 
1635 		struct mrsas_evtarg_ld		ld;
1636 
1637 		struct {
1638 			struct mrsas_evtarg_ld	ld;
1639 			uint64_t		count;
1640 		} ld_count;
1641 
1642 		struct {
1643 			uint64_t		lba;
1644 			struct mrsas_evtarg_ld	ld;
1645 		} ld_lba;
1646 
1647 		struct {
1648 			struct mrsas_evtarg_ld	ld;
1649 			uint32_t		prevOwner;
1650 			uint32_t		newOwner;
1651 		} ld_owner;
1652 
1653 		struct {
1654 			uint64_t		ld_lba;
1655 			uint64_t		pd_lba;
1656 			struct mrsas_evtarg_ld	ld;
1657 			struct mrsas_evtarg_pd	pd;
1658 		} ld_lba_pd_lba;
1659 
1660 		struct {
1661 			struct mrsas_evtarg_ld	ld;
1662 			struct mrsas_progress	prog;
1663 		} ld_prog;
1664 
1665 		struct {
1666 			struct mrsas_evtarg_ld	ld;
1667 			uint32_t		prev_state;
1668 			uint32_t		new_state;
1669 		} ld_state;
1670 
1671 		struct {
1672 			uint64_t		strip;
1673 			struct mrsas_evtarg_ld	ld;
1674 		} ld_strip;
1675 
1676 		struct mrsas_evtarg_pd		pd;
1677 
1678 		struct {
1679 			struct mrsas_evtarg_pd	pd;
1680 			uint32_t		err;
1681 		} pd_err;
1682 
1683 		struct {
1684 			uint64_t		lba;
1685 			struct mrsas_evtarg_pd	pd;
1686 		} pd_lba;
1687 
1688 		struct {
1689 			uint64_t		lba;
1690 			struct mrsas_evtarg_pd	pd;
1691 			struct mrsas_evtarg_ld	ld;
1692 		} pd_lba_ld;
1693 
1694 		struct {
1695 			struct mrsas_evtarg_pd	pd;
1696 			struct mrsas_progress	prog;
1697 		} pd_prog;
1698 
1699 		struct {
1700 			struct mrsas_evtarg_pd	pd;
1701 			uint32_t		prevState;
1702 			uint32_t		newState;
1703 		} pd_state;
1704 
1705 		struct {
1706 			uint16_t	vendorId;
1707 			uint16_t	deviceId;
1708 			uint16_t	subVendorId;
1709 			uint16_t	subDeviceId;
1710 		} pci;
1711 
1712 		uint32_t	rate;
1713 		char		str[96];
1714 
1715 		struct {
1716 			uint32_t	rtc;
1717 			uint32_t	elapsedSeconds;
1718 		} time;
1719 
1720 		struct {
1721 			uint32_t	ecar;
1722 			uint32_t	elog;
1723 			char		str[64];
1724 		} ecc;
1725 
1726 		mrsas_pd_address_t	pd_addr;
1727 
1728 		uint8_t		b[96];
1729 		uint16_t	s[48];
1730 		uint32_t	w[24];
1731 		uint64_t	d[12];
1732 	} args;
1733 
1734 	char	description[128];
1735 
1736 };
1737 
1738 /* only 63 are usable by the application */
1739 #define	MAX_LOGICAL_DRIVES			64
1740 /* only 255 physical devices may be used */
1741 #define	MAX_PHYSICAL_DEVICES			256
1742 #define	MAX_PD_PER_ENCLOSURE			64
1743 /* maximum disks per array */
1744 #define	MAX_ROW_SIZE				32
1745 /* maximum spans per logical drive */
1746 #define	MAX_SPAN_DEPTH				8
1747 /* maximum number of arrays a hot spare may be dedicated to */
1748 #define	MAX_ARRAYS_DEDICATED			16
1749 /* maximum number of arrays which may exist */
1750 #define	MAX_ARRAYS				128
1751 /* maximum number of foreign configs that may ha managed at once */
1752 #define	MAX_FOREIGN_CONFIGS			8
1753 /* maximum spares (global and dedicated combined) */
1754 #define	MAX_SPARES_FOR_THE_CONTROLLER		MAX_PHYSICAL_DEVICES
1755 /* maximum possible Target IDs (i.e. 0 to 63) */
1756 #define	MAX_TARGET_ID				63
1757 /* maximum number of supported enclosures */
1758 #define	MAX_ENCLOSURES				32
1759 /* maximum number of PHYs per controller */
1760 #define	MAX_PHYS_PER_CONTROLLER			16
1761 /* maximum number of LDs per array (due to DDF limitations) */
1762 #define	MAX_LDS_PER_ARRAY			16
1763 
1764 /*
1765  * -----------------------------------------------------------------------------
1766  * -----------------------------------------------------------------------------
1767  *
1768  * Logical Drive commands
1769  *
1770  * -----------------------------------------------------------------------------
1771  * -----------------------------------------------------------------------------
1772  */
1773 #define	MR_DCMD_LD	0x03000000,	/* Logical Device (LD) opcodes */
1774 
1775 /*
1776  * Input:	dcmd.opcode	- MR_DCMD_LD_GET_LIST
1777  *		dcmd.mbox	- reserved
1778  *		dcmd.sge IN	- ptr to returned MR_LD_LIST structure
1779  * Desc:	Return the logical drive list structure
1780  * Status:	No error
1781  */
1782 
1783 /*
1784  * defines the logical drive reference structure
1785  */
1786 typedef	union _MR_LD_REF {	/* LD reference structure */
1787 	struct {
1788 		uint8_t	targetId; /* LD target id (0 to MAX_TARGET_ID) */
1789 		uint8_t	reserved; /* reserved for in line with MR_PD_REF */
1790 		uint16_t seqNum;  /* Sequence Number */
1791 	} ld_ref;
1792 	uint32_t ref;		/* shorthand reference to full 32-bits */
1793 } MR_LD_REF;			/* 4 bytes */
1794 
1795 /*
1796  * defines the logical drive list structure
1797  */
1798 typedef struct _MR_LD_LIST {
1799 	uint32_t	ldCount;	/* number of LDs */
1800 	uint32_t	reserved;	/* pad to 8-byte boundary */
1801 	struct {
1802 		MR_LD_REF ref;	/* LD reference */
1803 		uint8_t	state;		/* current LD state (MR_LD_STATE) */
1804 		uint8_t	reserved[3];	/* pad to 8-byte boundary */
1805 		uint64_t size;		/* LD size */
1806 	} ldList[MAX_LOGICAL_DRIVES];
1807 } MR_LD_LIST;
1808 
1809 struct mrsas_drv_ver {
1810 	uint8_t	signature[12];
1811 	uint8_t	os_name[16];
1812 	uint8_t	os_ver[12];
1813 	uint8_t	drv_name[20];
1814 	uint8_t	drv_ver[32];
1815 	uint8_t	drv_rel_date[20];
1816 };
1817 
1818 #define	PCI_TYPE0_ADDRESSES		6
1819 #define	PCI_TYPE1_ADDRESSES		2
1820 #define	PCI_TYPE2_ADDRESSES		5
1821 
1822 struct mrsas_pci_common_header {
1823 	uint16_t	vendorID;		/* (ro) */
1824 	uint16_t	deviceID;		/* (ro) */
1825 	uint16_t	command;		/* Device control */
1826 	uint16_t	status;
1827 	uint8_t		revisionID;		/* (ro) */
1828 	uint8_t		progIf;			/* (ro) */
1829 	uint8_t		subClass;		/* (ro) */
1830 	uint8_t		baseClass;		/* (ro) */
1831 	uint8_t		cacheLineSize;		/* (ro+) */
1832 	uint8_t		latencyTimer;		/* (ro+) */
1833 	uint8_t		headerType;		/* (ro) */
1834 	uint8_t		bist;			/* Built in self test */
1835 
1836 	union {
1837 	    struct {
1838 		uint32_t	baseAddresses[PCI_TYPE0_ADDRESSES];
1839 		uint32_t	cis;
1840 		uint16_t	subVendorID;
1841 		uint16_t	subSystemID;
1842 		uint32_t	romBaseAddress;
1843 		uint8_t		capabilitiesPtr;
1844 		uint8_t		reserved1[3];
1845 		uint32_t	reserved2;
1846 		uint8_t		interruptLine;
1847 		uint8_t		interruptPin;	/* (ro) */
1848 		uint8_t		minimumGrant;	/* (ro) */
1849 		uint8_t		maximumLatency;	/* (ro) */
1850 	    } type_0;
1851 
1852 	    struct {
1853 		uint32_t	baseAddresses[PCI_TYPE1_ADDRESSES];
1854 		uint8_t		primaryBus;
1855 		uint8_t		secondaryBus;
1856 		uint8_t		subordinateBus;
1857 		uint8_t		secondaryLatency;
1858 		uint8_t		ioBase;
1859 		uint8_t		ioLimit;
1860 		uint16_t	secondaryStatus;
1861 		uint16_t	memoryBase;
1862 		uint16_t	memoryLimit;
1863 		uint16_t	prefetchBase;
1864 		uint16_t	prefetchLimit;
1865 		uint32_t	prefetchBaseUpper32;
1866 		uint32_t	prefetchLimitUpper32;
1867 		uint16_t	ioBaseUpper16;
1868 		uint16_t	ioLimitUpper16;
1869 		uint8_t		capabilitiesPtr;
1870 		uint8_t		reserved1[3];
1871 		uint32_t	romBaseAddress;
1872 		uint8_t		interruptLine;
1873 		uint8_t		interruptPin;
1874 		uint16_t	bridgeControl;
1875 	    } type_1;
1876 
1877 	    struct {
1878 		uint32_t	socketRegistersBaseAddress;
1879 		uint8_t		capabilitiesPtr;
1880 		uint8_t		reserved;
1881 		uint16_t	secondaryStatus;
1882 		uint8_t		primaryBus;
1883 		uint8_t		secondaryBus;
1884 		uint8_t		subordinateBus;
1885 		uint8_t		secondaryLatency;
1886 		struct {
1887 			uint32_t	base;
1888 			uint32_t	limit;
1889 		} range[PCI_TYPE2_ADDRESSES-1];
1890 		uint8_t		interruptLine;
1891 		uint8_t		interruptPin;
1892 		uint16_t	bridgeControl;
1893 	    } type_2;
1894 	} header;
1895 };
1896 
1897 struct mrsas_pci_link_capability {
1898 	union {
1899 	    struct {
1900 		uint32_t linkSpeed		:4;
1901 		uint32_t linkWidth		:6;
1902 		uint32_t aspmSupport		:2;
1903 		uint32_t losExitLatency		:3;
1904 		uint32_t l1ExitLatency		:3;
1905 		uint32_t rsvdp			:6;
1906 		uint32_t portNumber		:8;
1907 	    } bits;
1908 
1909 	    uint32_t asUlong;
1910 	} cap;
1911 
1912 };
1913 
1914 struct mrsas_pci_link_status_capability {
1915 	union {
1916 	    struct {
1917 		uint16_t linkSpeed		:4;
1918 		uint16_t negotiatedLinkWidth	:6;
1919 		uint16_t linkTrainingError	:1;
1920 		uint16_t linkTraning		:1;
1921 		uint16_t slotClockConfig	:1;
1922 		uint16_t rsvdZ			:3;
1923 	    } bits;
1924 
1925 	    uint16_t asUshort;
1926 	} stat_cap;
1927 
1928 	uint16_t reserved;
1929 
1930 };
1931 
1932 struct mrsas_pci_capabilities {
1933 	struct mrsas_pci_link_capability	linkCapability;
1934 	struct mrsas_pci_link_status_capability linkStatusCapability;
1935 };
1936 
1937 struct mrsas_pci_information
1938 {
1939 	uint32_t		busNumber;
1940 	uint8_t			deviceNumber;
1941 	uint8_t			functionNumber;
1942 	uint8_t			interruptVector;
1943 	uint8_t			reserved;
1944 	struct mrsas_pci_common_header pciHeaderInfo;
1945 	struct mrsas_pci_capabilities capability;
1946 	uint8_t			reserved2[32];
1947 };
1948 
1949 struct mrsas_ioctl {
1950 	uint16_t	version;
1951 	uint16_t	controller_id;
1952 	uint8_t		signature[8];
1953 	uint32_t	reserved_1;
1954 	uint32_t	control_code;
1955 	uint32_t	reserved_2[2];
1956 	uint8_t		frame[64];
1957 	union mrsas_sgl_frame sgl_frame;
1958 	uint8_t		sense_buff[MRSAS_MAX_SENSE_LENGTH];
1959 	uint8_t		data[1];
1960 };
1961 
1962 struct mrsas_aen {
1963 	uint16_t	host_no;
1964 	uint16_t	cmd_status;
1965 	uint32_t	seq_num;
1966 	uint32_t	class_locale_word;
1967 };
1968 
1969 #pragma pack()
1970 
1971 #ifndef	DDI_VENDOR_LSI
1972 #define	DDI_VENDOR_LSI		"LSI"
1973 #endif /* DDI_VENDOR_LSI */
1974 
1975 int mrsas_config_scsi_device(struct mrsas_instance *,
1976     struct scsi_device *, dev_info_t **);
1977 
1978 #ifdef PDSUPPORT
1979 int mrsas_tbolt_config_pd(struct mrsas_instance *, uint16_t,
1980     uint8_t, dev_info_t **);
1981 #endif
1982 
1983 dev_info_t *mrsas_find_child(struct mrsas_instance *, uint16_t, uint8_t);
1984 int mrsas_service_evt(struct mrsas_instance *, int, int, int, uint64_t);
1985 void return_raid_msg_pkt(struct mrsas_instance *, struct mrsas_cmd *);
1986 struct mrsas_cmd *get_raid_msg_mfi_pkt(struct mrsas_instance *);
1987 void return_raid_msg_mfi_pkt(struct mrsas_instance *, struct mrsas_cmd *);
1988 
1989 int	alloc_space_for_mpi2(struct mrsas_instance *);
1990 void	fill_up_drv_ver(struct mrsas_drv_ver *dv);
1991 
1992 int	mrsas_issue_init_mpi2(struct mrsas_instance *);
1993 struct scsi_pkt *mrsas_tbolt_tran_init_pkt(struct scsi_address *, register
1994 		    struct scsi_pkt *, struct buf *, int, int, int, int,
1995 		    int (*)(), caddr_t);
1996 int	mrsas_tbolt_tran_start(struct scsi_address *,
1997 		    register struct scsi_pkt *);
1998 uint32_t tbolt_read_fw_status_reg(struct mrsas_instance *);
1999 void 	tbolt_issue_cmd(struct mrsas_cmd *, struct mrsas_instance *);
2000 int	tbolt_issue_cmd_in_poll_mode(struct mrsas_instance *,
2001 		    struct mrsas_cmd *);
2002 int	tbolt_issue_cmd_in_sync_mode(struct mrsas_instance *,
2003 		    struct mrsas_cmd *);
2004 void	tbolt_enable_intr(struct mrsas_instance *);
2005 void	tbolt_disable_intr(struct mrsas_instance *);
2006 int	tbolt_intr_ack(struct mrsas_instance *);
2007 uint_t	mr_sas_tbolt_process_outstanding_cmd(struct mrsas_instance *);
2008     uint_t tbolt_softintr();
2009 int 	mrsas_tbolt_dma(struct mrsas_instance *, uint32_t, int, int (*)());
2010 int	mrsas_check_dma_handle(ddi_dma_handle_t handle);
2011 int	mrsas_check_acc_handle(ddi_acc_handle_t handle);
2012 int	mrsas_dma_alloc(struct mrsas_instance *, struct scsi_pkt *,
2013 		    struct buf *, int, int (*)());
2014 int	mrsas_dma_move(struct mrsas_instance *,
2015 			struct scsi_pkt *, struct buf *);
2016 int	mrsas_alloc_dma_obj(struct mrsas_instance *, dma_obj_t *,
2017 		    uchar_t);
2018 void 	mr_sas_tbolt_build_mfi_cmd(struct mrsas_instance *, struct mrsas_cmd *);
2019 int 	mrsas_dma_alloc_dmd(struct mrsas_instance *, dma_obj_t *);
2020 void 	tbolt_complete_cmd_in_sync_mode(struct mrsas_instance *,
2021 	struct mrsas_cmd *);
2022 int 	alloc_req_rep_desc(struct mrsas_instance *);
2023 int		mrsas_mode_sense_build(struct scsi_pkt *);
2024 void		push_pending_mfi_pkt(struct mrsas_instance *,
2025 			struct mrsas_cmd *);
2026 int	mrsas_issue_pending_cmds(struct mrsas_instance *);
2027 int 	mrsas_print_pending_cmds(struct mrsas_instance *);
2028 int  	mrsas_complete_pending_cmds(struct mrsas_instance *);
2029 
2030 int	create_mfi_frame_pool(struct mrsas_instance *);
2031 void	destroy_mfi_frame_pool(struct mrsas_instance *);
2032 int 	create_mfi_mpi_frame_pool(struct mrsas_instance *);
2033 void 	destroy_mfi_mpi_frame_pool(struct mrsas_instance *);
2034 int 	create_mpi2_frame_pool(struct mrsas_instance *);
2035 void 	destroy_mpi2_frame_pool(struct mrsas_instance *);
2036 int	mrsas_free_dma_obj(struct mrsas_instance *, dma_obj_t);
2037 void 	mrsas_tbolt_free_additional_dma_buffer(struct mrsas_instance *);
2038 void 	free_req_desc_pool(struct mrsas_instance *);
2039 void 	free_space_for_mpi2(struct mrsas_instance *);
2040 void 	mrsas_dump_reply_desc(struct mrsas_instance *);
2041 void 	tbolt_complete_cmd(struct mrsas_instance *, struct mrsas_cmd *);
2042 void	display_scsi_inquiry(caddr_t);
2043 void	service_mfi_aen(struct mrsas_instance *, struct mrsas_cmd *);
2044 int	mrsas_mode_sense_build(struct scsi_pkt *);
2045 int 	mrsas_tbolt_get_ld_map_info(struct mrsas_instance *);
2046 struct mrsas_cmd *mrsas_tbolt_build_poll_cmd(struct mrsas_instance *,
2047 	struct scsi_address *, struct scsi_pkt *, uchar_t *);
2048 int	mrsas_tbolt_reset_ppc(struct mrsas_instance *instance);
2049 void	mrsas_tbolt_kill_adapter(struct mrsas_instance *instance);
2050 int 	abort_syncmap_cmd(struct mrsas_instance *, struct mrsas_cmd *);
2051 void	mrsas_tbolt_prepare_cdb(struct mrsas_instance *instance, U8 cdb[],
2052     struct IO_REQUEST_INFO *, Mpi2RaidSCSIIORequest_t *, U32);
2053 
2054 
2055 int mrsas_init_adapter_ppc(struct mrsas_instance *instance);
2056 int mrsas_init_adapter_tbolt(struct mrsas_instance *instance);
2057 int mrsas_init_adapter(struct mrsas_instance *instance);
2058 
2059 int mrsas_alloc_cmd_pool(struct mrsas_instance *instance);
2060 void mrsas_free_cmd_pool(struct mrsas_instance *instance);
2061 
2062 void mrsas_print_cmd_details(struct mrsas_instance *, struct mrsas_cmd *, int);
2063 struct mrsas_cmd *get_raid_msg_pkt(struct mrsas_instance *);
2064 
2065 int mfi_state_transition_to_ready(struct mrsas_instance *);
2066 
2067 struct mrsas_cmd *mrsas_get_mfi_pkt(struct mrsas_instance *);
2068 void mrsas_return_mfi_pkt(struct mrsas_instance *, struct mrsas_cmd *);
2069 
2070 
2071 /* FMA functions. */
2072 int mrsas_common_check(struct mrsas_instance *, struct  mrsas_cmd *);
2073 void mrsas_fm_ereport(struct mrsas_instance *, char *);
2074 
2075 
2076 #ifdef	__cplusplus
2077 }
2078 #endif
2079 
2080 #endif /* _MR_SAS_H_ */
2081