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