1 /*
2  * ld_pd_map.h
3  *
4  * Solaris MegaRAID device 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 
17 #ifndef _LD_PD_MAP
18 #define	_LD_PD_MAP
19 #include <sys/scsi/scsi.h>
20 #include "fusion.h"
21 
22 struct mrsas_instance;	/* This will be defined in mr_sas.h */
23 
24 /* raid->write_mode; raid->read_ahead; dcmd->state */
25 /* Write through */
26 #define	WRITE_THROUGH				0
27 /* Delayed Write */
28 #define	WRITE_BACK				1
29 
30 /* SCSI CDB definitions */
31 #define	READ_6		0x08
32 #define	READ_16		0x88
33 #define	READ_10		0x28
34 #define	READ_12		0xA8
35 #define	WRITE_16	0x8A
36 #define	WRITE_10	0x2A
37 
38 /* maximum disks per array */
39 #define	MAX_ROW_SIZE				32
40 /* maximum spans per logical drive */
41 #define	MAX_SPAN_DEPTH				8
42 #define	MEGASAS_LOAD_BALANCE_FLAG		0x1
43 #define	MR_DEFAULT_IO_TIMEOUT	20
44 
45 
46 union desc_value {
47 	U64 word;
48 	struct {
49 		U32 low;
50 		U32 high;
51 	} u1;
52 };
53 
54 typedef struct _LD_LOAD_BALANCE_INFO
55 {
56     U8	    loadBalanceFlag;
57     U8	    reserved1;
58     U16	    raid1DevHandle[2];
59     U16	    scsi_pending_cmds[2];
60     U64	    last_accessed_block[2];
61 } LD_LOAD_BALANCE_INFO, *PLD_LOAD_BALANCE_INFO;
62 
63 #pragma pack(1)
64 typedef struct _MR_FW_RAID_MAP_ALL {
65 	MR_FW_RAID_MAP raidMap;
66 	MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES - 1];
67 } MR_FW_RAID_MAP_ALL;
68 
69 /*
70  * Raid Context structure which describes MegaRAID specific IO Parameters
71  * This resides at offset 0x60 where the SGL normally starts in MPT IO Frames
72  */
73 typedef struct _MPI2_SCSI_IO_VENDOR_UNIQUE {
74 	U8 nsegType;		/* 0x00 nseg[7:4], Type[3:0] */
75 	U8 resvd0;		/* 0x01 */
76 	U16 timeoutValue;	/* 0x02 -0x03 */
77 	U8 regLockFlags;	/* 0x04 */
78 	U8 reservedForHw1;	/* 0x05 */
79 	U16 ldTargetId;		/* 0x06 - 0x07 */
80 	U64 regLockRowLBA;	/* 0x08 - 0x0F */
81 	U32 regLockLength;	/* 0x10 - 0x13 */
82 	U16 nextLMId;		/* 0x14 - 0x15 */
83 	U8 extStatus;		/* 0x16 */
84 	U8 status;		/* 0x17 status */
85 	U8 RAIDFlags;		/* 0x18 resvd[7:6], ioSubType[5:4], */
86 				/* resvd[3:1], preferredCpu[0] */
87 	U8 numSGE;		/* 0x19 numSge; not including chain entries */
88 	U16 configSeqNum;	/* 0x1A -0x1B */
89 	U8 spanArm;		/* 0x1C span[7:5], arm[4:0] */
90 	U8 resvd2[3];		/* 0x1D-0x1f */
91 } MPI2_SCSI_IO_VENDOR_UNIQUE, MPI25_SCSI_IO_VENDOR_UNIQUE;
92 
93 #define	RAID_CTX_SPANARM_ARM_SHIFT	(0)
94 #define	RAID_CTX_SPANARM_ARM_MASK	(0x1f)
95 
96 #define	RAID_CTX_SPANARM_SPAN_SHIFT	(5)
97 #define	RAID_CTX_SPANARM_SPAN_MASK	(0xE0)
98 
99 
100 /*
101  * RAID SCSI IO Request Message
102  * Total SGE count will be one less
103  * than	 _MPI2_SCSI_IO_REQUEST
104  */
105 typedef struct _MPI2_RAID_SCSI_IO_REQUEST
106 {
107 	uint16_t		DevHandle;			/* 0x00 */
108 	uint8_t			ChainOffset;			/* 0x02 */
109 	uint8_t			Function;			/* 0x03 */
110 	uint16_t		Reserved1;			/* 0x04 */
111 	uint8_t			Reserved2;			/* 0x06 */
112 	uint8_t			MsgFlags;			/* 0x07 */
113 	uint8_t			VP_ID;				/* 0x08 */
114 	uint8_t			VF_ID;				/* 0x09 */
115 	uint16_t		Reserved3;			/* 0x0A */
116 	uint32_t		SenseBufferLowAddress;		/* 0x0C */
117 	uint16_t		SGLFlags;			/* 0x10 */
118 	uint8_t			SenseBufferLength;		/* 0x12 */
119 	uint8_t			Reserved4;			/* 0x13 */
120 	uint8_t			SGLOffset0;			/* 0x14 */
121 	uint8_t			SGLOffset1;			/* 0x15 */
122 	uint8_t			SGLOffset2;			/* 0x16 */
123 	uint8_t			SGLOffset3;			/* 0x17 */
124 	uint32_t		SkipCount;			/* 0x18 */
125 	uint32_t		DataLength;			/* 0x1C */
126 	uint32_t		BidirectionalDataLength;	/* 0x20 */
127 	uint16_t		IoFlags;			/* 0x24 */
128 	uint16_t		EEDPFlags;			/* 0x26 */
129 	uint32_t		EEDPBlockSize;			/* 0x28 */
130 	uint32_t		SecondaryReferenceTag;		/* 0x2C */
131 	uint16_t		SecondaryApplicationTag;	/* 0x30 */
132 	uint16_t		ApplicationTagTranslationMask;	/* 0x32 */
133 	uint8_t			LUN[8];				/* 0x34 */
134 	uint32_t		Control;			/* 0x3C */
135 	Mpi2ScsiIoCdb_t		CDB;				/* 0x40 */
136 	MPI2_SCSI_IO_VENDOR_UNIQUE RaidContext;			/* 0x60 */
137 	Mpi2SGEIOUnion_t	SGL; /* 0x80 */
138 } MPI2_RAID_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_RAID_SCSI_IO_REQUEST,
139 Mpi2RaidSCSIIORequest_t, MPI2_POINTER pMpi2RaidSCSIIORequest_t;
140 
141 /*
142  * define region lock types
143  */
144 typedef enum	_REGION_TYPE {
145 	REGION_TYPE_UNUSED	= 0,	/* lock is currently not active */
146 	REGION_TYPE_SHARED_READ	= 1,	/* shared lock (for reads) */
147 	REGION_TYPE_SHARED_WRITE = 2,
148 	REGION_TYPE_EXCLUSIVE	= 3	/* exclusive lock (for writes) */
149 } REGION_TYPE;
150 
151 
152 #define	DM_PATH_MAXPATH		2
153 #define	DM_PATH_FIRSTPATH	0
154 #define	DM_PATH_SECONDPATH	1
155 
156 /* declare valid Region locking values */
157 typedef enum _REGION_LOCK {
158 	REGION_LOCK_BYPASS		= 0,
159 	/* for RAID 6 single-drive failure */
160 	REGION_LOCK_UNCOND_SHARED_READ	= 1,
161 	REGION_LOCK_UNCOND_SHARED_WRITE	= 2,
162 	REGION_LOCK_UNCOND_SHARED_OTHER	= 3,
163 	REGION_LOCK_UNCOND_SHARED_EXCLUSIVE = 0xFF
164 } REGION_LOCK;
165 
166 
167 struct mrsas_init_frame2 {
168 	uint8_t	cmd;				/* 00h */
169 	uint8_t reserved_0;			/* 01h */
170 	uint8_t cmd_status;			/* 02h */
171 
172 	uint8_t reserved_1;			/* 03h */
173 	uint32_t reserved_2;			/* 04h */
174 
175 	uint32_t context;			/* 08h */
176 	uint32_t pad_0;				/* 0Ch */
177 
178 	uint16_t flags;				/* 10h */
179 	uint16_t reserved_3;			/* 12h */
180 	uint32_t data_xfer_len;			/* 14h */
181 
182 	uint32_t queue_info_new_phys_addr_lo;	/* 18h */
183 	uint32_t queue_info_new_phys_addr_hi;	/* 1Ch */
184 	uint32_t queue_info_old_phys_addr_lo;	/* 20h */
185 	uint32_t queue_info_old_phys_addr_hi;	/* 24h */
186 	uint64_t	driverversion;		/* 28h */
187 	uint32_t reserved_4[4];			/* 30h */
188 };
189 
190 
191 /*
192  * Request descriptor types
193  */
194 #define	MPI2_REQ_DESCRIPT_FLAGS_LD_IO		0x7
195 #define	MPI2_REQ_DESCRIPT_FLAGS_MFA		0x1
196 #define	MPI2_REQ_DESCRIPT_FLAGS_NO_LOCK		0x2
197 
198 #define	MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT	1
199 
200 
201 /*
202  * MPT RAID MFA IO Descriptor.
203  */
204 typedef struct _MR_RAID_MFA_IO_DESCRIPTOR {
205 	uint32_t	RequestFlags : 8;
206 	uint32_t	MessageAddress1 : 24;	/* bits 31:8 */
207 	uint32_t	MessageAddress2;	/* bits 61:32 */
208 } MR_RAID_MFA_IO_REQUEST_DESCRIPTOR,
209 *PMR_RAID_MFA_IO_REQUEST_DESCRIPTOR;
210 
211 /* union of Request Descriptors */
212 typedef union _MRSAS_REQUEST_DESCRIPTOR_UNION
213 {
214 	MPI2_DEFAULT_REQUEST_DESCRIPTOR		Default;
215 	MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR	HighPriority;
216 	MPI2_SCSI_IO_REQUEST_DESCRIPTOR		SCSIIO;
217 	MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR	SCSITarget;
218 	MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR	RAIDAccelerator;
219 	MR_RAID_MFA_IO_REQUEST_DESCRIPTOR	MFAIo;
220 	U64 Words;
221 } MRSAS_REQUEST_DESCRIPTOR_UNION;
222 
223 #pragma pack()
224 
225 enum {
226 	MRSAS_SCSI_VARIABLE_LENGTH_CMD		= 0x7F,
227 	MRSAS_SCSI_SERVICE_ACTION_READ32	= 0x9,
228 	MRSAS_SCSI_SERVICE_ACTION_WRITE32	= 0xB,
229 	MRSAS_SCSI_ADDL_CDB_LEN			= 0x18,
230 	MRSAS_RD_WR_PROTECT			= 0x20,
231 	MRSAS_EEDPBLOCKSIZE			= 512
232 };
233 
234 
235 #define	IEEE_SGE_FLAGS_ADDR_MASK	(0x03)
236 #define	IEEE_SGE_FLAGS_SYSTEM_ADDR	(0x00)
237 #define	IEEE_SGE_FLAGS_IOCDDR_ADDR	(0x01)
238 #define	IEEE_SGE_FLAGS_IOCPLB_ADDR	(0x02)
239 #define	IEEE_SGE_FLAGS_IOCPLBNTA_ADDR	(0x03)
240 #define	IEEE_SGE_FLAGS_CHAIN_ELEMENT	(0x80)
241 #define	IEEE_SGE_FLAGS_END_OF_LIST	(0x40)
242 
243 
244 U8 MR_ValidateMapInfo(MR_FW_RAID_MAP_ALL *map, PLD_LOAD_BALANCE_INFO lbInfo);
245 U16 MR_CheckDIF(U32, MR_FW_RAID_MAP_ALL *);
246 U8 MR_BuildRaidContext(struct mrsas_instance *, struct IO_REQUEST_INFO *,
247     MPI2_SCSI_IO_VENDOR_UNIQUE *, MR_FW_RAID_MAP_ALL *);
248 
249 #endif /* _LD_PD_MAP */
250