1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright 2021 RackTop Systems, Inc.
24  */
25 
26 #ifndef _SYS_SCSI_ADAPTERS_MPAPI_IMPL_H
27 #define	_SYS_SCSI_ADAPTERS_MPAPI_IMPL_H
28 
29 #include <sys/sunmdi.h>
30 #include <sys/sunddi.h>
31 #include <sys/mdi_impldefs.h>
32 #include <sys/debug.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
39 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
40 #endif  /* _BIT_FIELDS_LTOH */
41 
42 /*
43  * All the structures (except mp_iocdata_t) are 64-bit aligned (padded,
44  * where necessary) to facilitate the use of the same structure for
45  * handling ioctl calls made by both 32-bit and 64-bit applications.
46  * There are no pointers to other structures inside these structures
47  * as copyout to user land may not produce desired result.
48  * The caddr_t structure is kept at the end due to the undeterminstic
49  * size it could accrue to its parent structure.
50  */
51 
52 /* Structure for MP_PLUGIN_PROPERTIES */
53 
54 typedef struct mp_driver_prop {
55 	char		driverVersion[256];
56 	uint32_t	supportedLoadBalanceTypes;
57 	boolean_t	canSetTPGAccess;
58 	boolean_t	canOverridePaths;
59 	boolean_t	exposesPathDeviceFiles;
60 	char		deviceFileNamespace[256];
61 	uint32_t	onlySupportsSpecifiedProducts;
62 	uint32_t	maximumWeight;
63 	uint32_t	failbackPollingRateMax;
64 	uint32_t	currentFailbackPollingRate;
65 	uint32_t	autoFailbackSupport;
66 	uint32_t	autoFailbackEnabled;
67 	uint32_t	defaultLoadBalanceType;
68 	uint32_t	probingPollingRateMax;
69 	uint32_t	currentProbingPollingRate;
70 	uint32_t	autoProbingSupport;
71 	uint32_t	autoProbingEnabled;
72 	uint32_t	proprietaryPropSize;
73 	caddr_t		proprietaryProp;
74 #ifdef _ILP32
75 	uint32_t	pad;
76 #endif
77 } mp_driver_prop_t;
78 CTASSERT(sizeof (mp_driver_prop_t) == 0x248);
79 
80 
81 /* Size of "proprietaryProp" field */
82 
83 #define	MP_MAX_PROP_BUF_SIZE				1024
84 
85 
86 /* Constants for autoFailbackSupport */
87 
88 /*
89  * Both MP_DRVR_AUTO_FAILBACK_SUPPORT and
90  * MP_DRVR_AUTO_FAILBACK_SUPPORT_LU
91  * can be supported at the same time.
92  */
93 
94 #define	MP_DRVR_AUTO_FAILBACK_SUPPORT_NONE		0
95 #define	MP_DRVR_AUTO_FAILBACK_SUPPORT			(1<<0)
96 #define	MP_DRVR_AUTO_FAILBACK_SUPPORT_LU		(1<<1)
97 
98 
99 
100 /*
101  * Declaration of the MP_LOAD_BALANCE_TYPE constants - should be
102  * the same defines as in mpapi.h
103  */
104 #define	MP_DRVR_LOAD_BALANCE_TYPE_NONE			0
105 #define	MP_DRVR_LOAD_BALANCE_TYPE_UNKNOWN		(1<<0)
106 #define	MP_DRVR_LOAD_BALANCE_TYPE_ROUNDROBIN		(1<<1)
107 #define	MP_DRVR_LOAD_BALANCE_TYPE_LEASTBLOCKS		(1<<2)
108 #define	MP_DRVR_LOAD_BALANCE_TYPE_LEASTIO		(1<<3)
109 #define	MP_DRVR_LOAD_BALANCE_TYPE_DEVICE_PRODUCT	(1<<4)
110 #define	MP_DRVR_LOAD_BALANCE_TYPE_LBA_REGION		(1<<5)
111 #define	MP_DRVR_LOAD_BALANCE_TYPE_FAILOVER_ONLY		(1<<6)
112 /*
113  * Proprietary load balance type should start from 0x10000(1<<16) or greater.
114  * It is exposed through API MP_GetProprietaryLoadBalanceProperties if exists.
115  */
116 #define	MP_DRVR_LOAD_BALANCE_TYPE_PROPRIETARY1		(1<<16)
117 #define	MP_DRVR_LOAD_BALANCE_TYPE_PROPRIETARY2		(1<<17)
118 
119 /* Constants for autoProbingSupport */
120 
121 /*
122  * Both MP_DRVR_AUTO_PROBING_SUPPORT and
123  * MP_DRVR_AUTO_PROBING_SUPPORT_LU
124  * can be supported at the same time.
125  */
126 
127 #define	MP_DRVR_AUTO_PROBING_SUPPORT_NONE		0
128 #define	MP_DRVR_AUTO_PROBING_SUPPORT			(1<<0)
129 #define	MP_DRVR_AUTO_PROBING_SUPPORT_LU			(1<<1)
130 
131 
132 /* Structures for MP_DEVICE_PRODUCT_PROPERTIES */
133 
134 typedef struct mp_vendor_prod_info {
135 	char	vendor[8];
136 	char	product[16];
137 	char	revision[4];
138 	char	reserved[4]; /* padding for 64bit alignment */
139 } mp_vendor_prod_info_t;
140 
141 typedef struct mp_dev_prod_prop {
142 	struct mp_vendor_prod_info	prodInfo;
143 	uint32_t			supportedLoadBalanceTypes;
144 	uint32_t			reserved; /* 64bit alignment padding */
145 	uint64_t			id;
146 } mp_dev_prod_prop_t;
147 
148 
149 /* Structure for MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES */
150 
151 typedef struct mp_logical_unit_prop {
152 	struct mp_vendor_prod_info	prodInfo;
153 	char				name[256];  /* guid */
154 	uint32_t			nameType;
155 	uint32_t			luGroupID;
156 	char				deviceFileName[256];
157 	uint64_t			id;
158 	boolean_t			asymmetric;
159 	uint32_t			currentLoadBalanceType;
160 	boolean_t			autoFailbackEnabled;
161 	uint32_t			failbackPollingRateMax;
162 	uint32_t			currentFailBackPollingRate;
163 	uint32_t			autoProbingEnabled;
164 	uint32_t			probingPollingRateMax;
165 	uint32_t			currentProbingPollingRate;
166 	uint64_t			overridePathID;
167 	boolean_t			overridePathInUse;
168 	uint32_t			proprietaryPropSize;
169 	caddr_t				proprietaryProp;
170 #ifdef _ILP32
171 	uint32_t			pad;
172 #endif
173 } mp_logical_unit_prop_t;
174 CTASSERT(sizeof (mp_logical_unit_prop_t) == 0x268);
175 
176 
177 /* Constants for nameType */
178 
179 #define	MP_DRVR_NAME_TYPE_UNKNOWN		0
180 #define	MP_DRVR_NAME_TYPE_VPD83_TYPE1		1
181 #define	MP_DRVR_NAME_TYPE_VPD83_TYPE2		2
182 #define	MP_DRVR_NAME_TYPE_VPD83_TYPE3		3
183 #define	MP_DRVR_NAME_TYPE_DEVICE_SPECIFIC	4
184 
185 
186 /* Structure for MP_INITIATOR_PORT_PROPERTIES */
187 
188 typedef struct mp_init_port_prop {
189 	char		portID[256];
190 	char		osDeviceFile[256];
191 	uint32_t	portType;
192 	uint32_t	reserved; /* padding for 64bit alignment */
193 	uint64_t	id;
194 } mp_init_port_prop_t;
195 
196 
197 /* Constants for portType */
198 
199 #define	MP_DRVR_TRANSPORT_TYPE_UNKNOWN	0
200 #define	MP_DRVR_TRANSPORT_TYPE_FC	2
201 #define	MP_DRVR_TRANSPORT_TYPE_SPI	3
202 #define	MP_DRVR_TRANSPORT_TYPE_ISCSI	4
203 #define	MP_DRVR_TRANSPORT_TYPE_IFB	5
204 
205 
206 /* Structure for MP_TARGET_PORT_PROPERTIES */
207 
208 typedef struct mp_target_port_prop {
209 	char		portName[256];
210 	uint32_t	relativePortID;
211 	uint32_t	reserved; /* padding for 64bit alignment */
212 	uint64_t	id;
213 } mp_target_port_prop_t;
214 
215 
216 /* Structure for MP_TARGET_PORT_GROUP_PROPERTIES */
217 
218 typedef struct mp_tpg_prop {
219 	uint32_t	accessState;
220 	boolean_t	explicitFailover;
221 	uint32_t	tpgId; /* T10 defined id in report/set TPG */
222 	boolean_t	preferredLuPath;
223 	boolean_t	supportsLuAssignment;
224 	uint32_t	reserved; /* padding for 64bit alignment */
225 	uint64_t	id;
226 } mp_tpg_prop_t;
227 
228 
229 /* Constants for accessState */
230 
231 #define	MP_DRVR_ACCESS_STATE_ACTIVE_OPTIMIZED		0
232 #define	MP_DRVR_ACCESS_STATE_ACTIVE_NONOPTIMIZED	0x1
233 #define	MP_DRVR_ACCESS_STATE_STANDBY			0x2
234 #define	MP_DRVR_ACCESS_STATE_UNAVAILABLE		0x3
235 #define	MP_DRVR_ACCESS_STATE_TRANSITIONING		0xf
236 #define	MP_DRVR_ACCESS_STATE_ACTIVE			0x10
237 
238 
239 /* Structure for MP_PATH_LOGICAL_UNIT_PROPERTIES */
240 
241 typedef struct mp_path_prop {
242 	uint32_t			weight;
243 	uint32_t			pathState;
244 	boolean_t			disabled;
245 	uint32_t			reserved; /* 64bit alignment padding */
246 	uint64_t			id;
247 	struct mp_init_port_prop	initPort;
248 	struct mp_target_port_prop	targetPort;
249 	struct mp_logical_unit_prop	logicalUnit;
250 } mp_path_prop_t;
251 
252 
253 /* Constants for pathState */
254 
255 #define	MP_DRVR_PATH_STATE_ACTIVE		0
256 #define	MP_DRVR_PATH_STATE_PASSIVE		1
257 #define	MP_DRVR_PATH_STATE_PATH_ERR		2
258 #define	MP_DRVR_PATH_STATE_LU_ERR		3
259 #define	MP_DRVR_PATH_STATE_RESERVED		4
260 #define	MP_DRVR_PATH_STATE_REMOVED		5
261 #define	MP_DRVR_PATH_STATE_TRANSITIONING	6
262 #define	MP_DRVR_PATH_STATE_UNKNOWN		7
263 #define	MP_DRVR_PATH_STATE_UNINIT		8
264 
265 
266 /* Structure for MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES */
267 
268 typedef struct mp_proprietary_loadbalance_prop {
269 	char		name[256];
270 	char		vendorName[256];
271 	uint64_t	id;
272 	uint32_t	typeIndex;
273 	uint32_t	proprietaryPropSize;
274 	caddr_t		proprietaryProp;
275 #ifdef _ILP32
276 	uint32_t	pad;
277 #endif
278 } mp_proprietary_loadbalance_prop_t;
279 CTASSERT(sizeof (mp_proprietary_loadbalance_prop_t) == 0x218);
280 
281 
282 /*
283  * Structure used as input to
284  * MP_ASSIGN_LU_TO_TPG subcmd.
285  */
286 
287 typedef struct mp_lu_tpg_pair {
288 	uint64_t	luId;
289 	uint64_t	tpgId;
290 } mp_lu_tpg_pair_t;
291 
292 /* used for uscsi commmands */
293 typedef struct mp_uscsi_cmd {
294 	struct scsi_address	*ap;		/* address of the path */
295 	struct uscsi_cmd	*uscmdp;	/* uscsi command */
296 	struct buf		*cmdbp;		/* original buffer */
297 	struct buf		*rqbp;		/* auto-rqsense packet */
298 	mdi_pathinfo_t		*pip;		/* path information */
299 	int			arq_enabled;	/* auto-rqsense enable flag */
300 } mp_uscsi_cmd_t;
301 
302 /*
303  * Structure used as input to
304  * MP_SET_TPG_ACCESS_STATE subcmd.
305  */
306 
307 typedef struct mp_set_tpg_state_req {
308 	struct mp_lu_tpg_pair	luTpgPair;
309 	uint32_t		desiredState;
310 	uint32_t		reserved; /* padding for 64bit boundary */
311 } mp_set_tpg_state_req_t;
312 
313 
314 /*
315  * Structure for ioctl data
316  */
317 typedef struct mp_iocdata {
318 	uint16_t	mp_xfer;	/* direction */
319 	uint16_t	mp_cmd;		/* sub command */
320 	uint16_t	mp_flags;	/* flags */
321 	uint16_t	mp_cmd_flags;	/* command specific flags */
322 	size_t		mp_ilen;	/* Input buffer length */
323 	caddr_t		mp_ibuf;	/* Input buffer */
324 	size_t		mp_olen;	/* Output buffer length */
325 	caddr_t		mp_obuf;	/* Output buffer */
326 	size_t		mp_alen;	/* Auxiliary buffer length */
327 	caddr_t		mp_abuf;	/* Auxiliary buffer */
328 	int		mp_errno;	/* MPAPI driver internal error code */
329 } mp_iocdata_t;
330 
331 
332 #ifdef _KERNEL
333 
334 #if defined(_SYSCALL32)
335 
336 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
337 #pragma pack(4)
338 #endif
339 
340 /*
341  * Structure for 32-bit ioctl data
342  */
343 
344 typedef struct mp_iocdata32 {
345 	uint16_t	mp_xfer;	/* direction */
346 	uint16_t	mp_cmd;		/* sub command */
347 	uint16_t	mp_flags;	/* flags */
348 	uint16_t	mp_cmd_flags;	/* command specific flags */
349 	uint32_t	mp_ilen;	/* Input buffer length */
350 	caddr32_t	mp_ibuf;	/* Input buffer */
351 	uint32_t	mp_olen;	/* Output buffer length */
352 	caddr32_t	mp_obuf;	/* Output buffer */
353 	uint32_t	mp_alen;	/* Auxiliary buffer length */
354 	caddr32_t	mp_abuf;	/* Auxiliary buffer */
355 	int32_t		mp_errno;	/* MPAPI driver internal error code */
356 } mp_iocdata32_t;
357 
358 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
359 #pragma pack()
360 #endif
361 
362 #endif  /* _SYSCALL32 */
363 
364 #endif /* _KERNEL */
365 
366 
367 /* Constants for MP_XFER */
368 
369 #define	MP_XFER_NONE	0x00
370 #define	MP_XFER_READ	0x01
371 #define	MP_XFER_WRITE	0x02
372 #define	MP_XFER_RW	(MP_XFER_READ | MP_XFER_WRITE)
373 
374 
375 /* Constants for MP_OBJECT_TYPE */
376 
377 #define	MP_OBJECT_TYPE_UNKNOWN			0
378 #define	MP_OBJECT_TYPE_PLUGIN			1
379 #define	MP_OBJECT_TYPE_INITIATOR_PORT		2
380 #define	MP_OBJECT_TYPE_TARGET_PORT		3
381 #define	MP_OBJECT_TYPE_MULTIPATH_LU		4
382 #define	MP_OBJECT_TYPE_PATH_LU			5
383 #define	MP_OBJECT_TYPE_DEVICE_PRODUCT		6
384 #define	MP_OBJECT_TYPE_TARGET_PORT_GROUP	7
385 #define	MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE	8
386 #define	MP_OBJECT_TYPE_LAST_ENTRY	MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE
387 #define	MP_MAX_OBJECT_TYPE	(MP_OBJECT_TYPE_LAST_ENTRY + 1)
388 
389 
390 /* Constants for MP_CMD */
391 
392 #define	MPAPI_CTL				('m'<<8)
393 #define	MP_CMD					(MPAPI_CTL | 2005)
394 #define	MP_SUB_CMD				('M'<<8)
395 
396 #define	MP_API_SUBCMD_MIN			(MP_SUB_CMD + 0x01)
397 #define	MP_GET_DRIVER_PROP			(MP_SUB_CMD + 0x01)
398 #define	MP_GET_DEV_PROD_LIST			(MP_SUB_CMD + 0x02)
399 #define	MP_GET_DEV_PROD_PROP			(MP_SUB_CMD + 0x03)
400 #define	MP_GET_LU_LIST				(MP_SUB_CMD + 0x04)
401 #define	MP_GET_LU_LIST_FROM_TPG			(MP_SUB_CMD + 0x05)
402 #define	MP_GET_LU_PROP				(MP_SUB_CMD + 0x06)
403 #define	MP_GET_PATH_LIST_FOR_MP_LU		(MP_SUB_CMD + 0x07)
404 #define	MP_GET_PATH_LIST_FOR_INIT_PORT		(MP_SUB_CMD + 0x08)
405 #define	MP_GET_PATH_LIST_FOR_TARGET_PORT	(MP_SUB_CMD + 0x09)
406 #define	MP_GET_PATH_PROP			(MP_SUB_CMD + 0x0a)
407 #define	MP_GET_INIT_PORT_LIST			(MP_SUB_CMD + 0x0b)
408 #define	MP_GET_INIT_PORT_PROP			(MP_SUB_CMD + 0x0c)
409 #define	MP_GET_TARGET_PORT_PROP			(MP_SUB_CMD + 0x0d)
410 #define	MP_GET_TPG_LIST				(MP_SUB_CMD + 0x0e)
411 #define	MP_GET_TPG_PROP				(MP_SUB_CMD + 0x0f)
412 #define	MP_GET_TPG_LIST_FOR_LU			(MP_SUB_CMD + 0x10)
413 #define	MP_GET_TARGET_PORT_LIST_FOR_TPG		(MP_SUB_CMD + 0x11)
414 #define	MP_SET_TPG_ACCESS_STATE			(MP_SUB_CMD + 0x12)
415 #define	MP_ENABLE_AUTO_FAILBACK			(MP_SUB_CMD + 0x13)
416 #define	MP_DISABLE_AUTO_FAILBACK		(MP_SUB_CMD + 0x14)
417 #define	MP_ENABLE_PATH				(MP_SUB_CMD + 0x15)
418 #define	MP_DISABLE_PATH				(MP_SUB_CMD + 0x16)
419 #define	MP_GET_PROPRIETARY_LOADBALANCE_LIST	(MP_SUB_CMD + 0x17)
420 #define	MP_GET_PROPRIETARY_LOADBALANCE_PROP	(MP_SUB_CMD + 0x18)
421 #define	MP_ASSIGN_LU_TO_TPG			(MP_SUB_CMD + 0x19)
422 #define	MP_SEND_SCSI_CMD			(MP_SUB_CMD + 0x1a)
423 #define	MP_API_SUBCMD_MAX			(MP_SEND_SCSI_CMD)
424 
425 
426 /*
427  * Typical MP API ioctl interface specific Return Values
428  */
429 
430 #define	MP_IOCTL_ERROR_START			0x5533
431 #define	MP_MORE_DATA				(MP_IOCTL_ERROR_START + 1)
432 #define	MP_DRVR_INVALID_ID			(MP_IOCTL_ERROR_START + 2)
433 #define	MP_DRVR_ID_OBSOLETE			(MP_IOCTL_ERROR_START + 3)
434 #define	MP_DRVR_ACCESS_SYMMETRIC		(MP_IOCTL_ERROR_START + 4)
435 #define	MP_DRVR_PATH_UNAVAILABLE		(MP_IOCTL_ERROR_START + 5)
436 #define	MP_DRVR_IDS_NOT_ASSOCIATED		(MP_IOCTL_ERROR_START + 6)
437 #define	MP_DRVR_ILLEGAL_ACCESS_STATE_REQUEST	(MP_IOCTL_ERROR_START + 7)
438 #define	MP_DRVR_IO_ERROR			(MP_IOCTL_ERROR_START + 8)
439 
440 /*
441  * Macros for OID operations
442  */
443 #define	MP_ID_SHIFT4MAJOR		32
444 #define	MP_GET_MAJOR_FROM_ID(id)	((id) >> MP_ID_SHIFT4MAJOR)
445 #define	MP_GET_INST_FROM_ID(id)		((id) & 0x00000000ffffffff)
446 #define	MP_STORE_INST_TO_ID(inst, id)	(((uint64_t)(inst)) | id)
447 #define	MP_STORE_MAJOR_TO_ID(major, id)	\
448 	((((uint64_t)(major)) << MP_ID_SHIFT4MAJOR) | id)
449 
450 /*
451  * Event Class and Sub-Class definitions
452  */
453 #define	EC_SUN_MP			"EC_sun_mp"
454 
455 #define	ESC_SUN_MP_PLUGIN_CHANGE	"ESC_sun_mp_plugin_change"
456 
457 #define	ESC_SUN_MP_LU_CHANGE		"ESC_sun_mp_lu_change"
458 #define	ESC_SUN_MP_LU_ADD		"ESC_sun_mp_lu_add"
459 #define	ESC_SUN_MP_LU_REMOVE		"ESC_sun_mp_lu_remove"
460 
461 #define	ESC_SUN_MP_PATH_CHANGE		"ESC_sun_mp_path_change"
462 #define	ESC_SUN_MP_PATH_ADD		"ESC_sun_mp_path_add"
463 #define	ESC_SUN_MP_PATH_REMOVE		"ESC_sun_mp_path_remove"
464 
465 #define	ESC_SUN_MP_INIT_PORT_CHANGE	"ESC_sun_mp_init_port_change"
466 
467 #define	ESC_SUN_MP_TPG_CHANGE		"ESC_sun_mp_tpg_change"
468 #define	ESC_SUN_MP_TPG_ADD		"ESC_sun_mp_tpg_add"
469 #define	ESC_SUN_MP_TPG_REMOVE		"ESC_sun_mp_tpg_remove"
470 
471 #define	ESC_SUN_MP_TARGET_PORT_CHANGE	"ESC_sun_mp_target_port_change"
472 #define	ESC_SUN_MP_TARGET_PORT_ADD	"ESC_sun_mp_target_port_add"
473 #define	ESC_SUN_MP_TARGET_PORT_REMOVE	"ESC_sun_mp_target_port_remove"
474 
475 #define	ESC_SUN_MP_DEV_PROD_CHANGE	"ESC_sun_mp_dev_prod_change"
476 #define	ESC_SUN_MP_DEV_PROD_ADD		"ESC_sun_mp_dev_prod_add"
477 #define	ESC_SUN_MP_DEV_PROD_REMOVE	"ESC_sun_mp_dev_prod_remove"
478 
479 #ifdef __cplusplus
480 }
481 #endif
482 
483 #endif /* _SYS_SCSI_ADAPTERS_MPAPI_IMPL_H */
484