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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _CFGA_FP_H 27 #define _CFGA_FP_H 28 29 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #include <sys/types.h> 36 #include <sys/mkdev.h> 37 #include <stddef.h> 38 #include <locale.h> 39 #include <ctype.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <fcntl.h> 44 #include <unistd.h> 45 #include <errno.h> 46 #include <locale.h> 47 #include <langinfo.h> 48 #include <time.h> 49 #include <stdarg.h> 50 #include <sys/mman.h> 51 #include <sys/ioctl.h> 52 #include <sys/dditypes.h> 53 #include <sys/modctl.h> 54 #include <libdevinfo.h> 55 #include <libdevice.h> 56 #include <librcm.h> 57 #include <dirent.h> 58 #include <strings.h> 59 60 61 #include <sys/ioctl.h> 62 #include <sys/byteorder.h> 63 #include <sys/scsi/scsi.h> 64 #include <strings.h> 65 #include <sys/vfstab.h> 66 #include <sys/stat.h> 67 #include <setjmp.h> 68 #include <signal.h> 69 #include <hbaapi.h> 70 #include <sys/fibre-channel/fcio.h> 71 #include <sys/fibre-channel/ulp/fcp_util.h> 72 73 #include <sys/uio.h> 74 #include <sys/param.h> 75 76 #include <synch.h> 77 #include <thread.h> 78 79 #include <limits.h> 80 #include <ftw.h> 81 82 #define CFGA_PLUGIN_LIB 83 #include <config_admin.h> 84 85 #if !defined(DEBUG) 86 #define NDEBUG 1 87 #else 88 #undef NDEBUG 89 #endif 90 91 #include <assert.h> 92 93 /* Return/error codes */ 94 typedef enum { 95 FPCFGA_ERR = -2, 96 FPCFGA_LIB_ERR = -1, 97 FPCFGA_OK = 0, 98 FPCFGA_ACCESS_OK, 99 FPCFGA_NACK, 100 FPCFGA_BUSY, 101 FPCFGA_SYSTEM_BUSY, 102 FPCFGA_APID_NOCONFIGURE, 103 FPCFGA_APID_NOACCESS, 104 FPCFGA_APID_NOEXIST, 105 FPCFGA_OPNOTSUPP, 106 FPCFGA_PRIV, 107 FPCFGA_UNLOCKED, 108 FPCFGA_NO_REC, 109 FPCFGA_OP_INTR, 110 FPCFGA_DB_INVAL, 111 FPCFGA_CONF_OK_UPD_REP_FAILED, 112 FPCFGA_UNCONF_OK_UPD_REP_FAILED, 113 FPCFGA_INVALID_PATH, 114 FPCFGA_VHCI_GET_PATHLIST_FAILED, 115 FPCFGA_XPORT_NOT_IN_PHCI_LIST, 116 FPCFGA_UNKNOWN_ERR, 117 FPCFGA_FCP_TGT_SEND_SCSI_FAILED, 118 FPCFGA_FCP_SEND_SCSI_DEV_NOT_TGT 119 } fpcfga_ret_t; 120 121 /* Commands used internally */ 122 typedef enum { 123 FPCFGA_INVAL_CMD = -1, 124 FPCFGA_DEV_OP = 0, 125 FPCFGA_BUS_OP, 126 FPCFGA_STAT_FC_DEV, 127 FPCFGA_STAT_FCA_PORT, 128 FPCFGA_STAT_ALL, 129 FPCFGA_GET_DEVPATH, 130 FPCFGA_INSERT_DEV, 131 FPCFGA_REMOVE_DEV, 132 FPCFGA_REPLACE_DEV, 133 FPCFGA_WALK_NODE, 134 FPCFGA_WALK_MINOR, 135 FPCFGA_BUS_QUIESCE, 136 FPCFGA_BUS_UNQUIESCE, 137 FPCFGA_BUS_GETSTATE, 138 FPCFGA_DEV_GETSTATE, 139 FPCFGA_BUS_CONFIGURE, 140 FPCFGA_BUS_UNCONFIGURE, 141 FPCFGA_DEV_CONFIGURE, 142 FPCFGA_DEV_UNCONFIGURE, 143 FPCFGA_DEV_REMOVE, 144 FPCFGA_RESET_DEV, 145 FPCFGA_RESET_BUS, 146 FPCFGA_RESET_ALL, 147 FPCFGA_READ, 148 FPCFGA_WRITE 149 } fpcfga_cmd_t; 150 151 typedef enum { 152 FPCFGA_TERMINATE = 0, 153 FPCFGA_CONTINUE 154 } fpcfga_recur_t; 155 156 157 /* Structures for tree walking code */ 158 159 typedef struct { 160 uint_t flags; 161 int (*fcn)(di_node_t node, void *argp); 162 } walk_node_t; 163 164 typedef struct { 165 const char *nodetype; 166 int (*fcn)(di_node_t node, di_minor_t minor, void *argp); 167 } walk_minor_t; 168 169 typedef union { 170 walk_node_t node_args; 171 walk_minor_t minor_args; 172 } walkmode_t; 173 174 typedef struct { 175 uint_t flags; 176 walkmode_t walkmode; 177 } walkarg_t; 178 179 typedef struct { 180 char *phys; 181 char *log; 182 fpcfga_ret_t ret; 183 int match_minor; 184 int l_errno; 185 } pathm_t; 186 187 typedef struct ldata_list { 188 cfga_list_data_t ldata; 189 struct ldata_list *next; 190 } ldata_list_t; 191 192 typedef struct { 193 struct cfga_confirm *confp; 194 struct cfga_msg *msgp; 195 } prompt_t; 196 197 typedef struct luninfo_list { 198 int lunnum; 199 uint_t node_state; 200 uint_t lun_flag; 201 char *path; 202 struct luninfo_list *next; 203 } luninfo_list_t; 204 205 typedef struct { 206 char *xport_phys; 207 char *dyncomp; 208 uint_t flags; 209 luninfo_list_t *lunlist; /* Singly linked list */ 210 } apid_t; 211 212 /* Report luns names */ 213 #define FP_SCMD_REPORT_LUN 0xA0 214 #define DEFAULT_NUM_LUN 1024 215 #define REPORT_LUN_HDR_SIZE 8 216 #define SAM_LUN_SIZE 8 217 218 #ifdef _BIG_ENDIAN 219 #define htonll(x) (x) 220 #define ntohll(x) (x) 221 #else 222 #define htonll(x) ((((unsigned long long)htonl(x)) << 32) + htonl(x >> 32)) 223 #define ntohll(x) ((((unsigned long long)ntohl(x)) << 32) + ntohl(x >> 32)) 224 #endif 225 226 typedef struct report_lun_resp { 227 uint32_t num_lun; 228 uint32_t reserved; 229 longlong_t lun_string[DEFAULT_NUM_LUN]; 230 } report_lun_resp_t; 231 232 /* 233 * Hardware options acceptable for fp plugin. 234 * list related options are handled by getsupopts() and set to 235 * index of array. 236 */ 237 #define OPT_DEVINFO_FORCE 0 238 #define OPT_SHOW_SCSI_LUN 1 239 #define OPT_FCP_DEV 2 240 #define OPT_DISABLE_RCM 0 241 #define OPT_FORCE_UPDATE_REP 1 242 #define OPT_NO_UPDATE_REP 2 243 #define OPT_REMOVE_UNUSABLE_SCSI_LUN 3 244 #define OPT_REMOVE_UNUSABLE_FCP_DEV 4 245 246 /* walk tree flag */ 247 #define FLAG_PATH_INFO_WALK 0x00000001 248 249 /* apid_t flags */ 250 #define FLAG_DISABLE_RCM 0x00000001 251 #define FLAG_FORCE_UPDATE_REP 0x00000010 252 #define FLAG_NO_UPDATE_REP 0x00000100 253 #define FLAG_DYN_AP_CONFIGURED 0x00001000 254 #define FLAG_DEVINFO_FORCE 0x00010000 255 #define FLAG_FCP_DEV 0x00100000 256 #define FLAG_REMOVE_UNUSABLE_FCP_DEV 0x01000000 257 258 /* apid_t lun flags */ 259 #define FLAG_SKIP_RCMOFFLINE 0x00000001 260 #define FLAG_SKIP_RCMREMOVE 0x00000010 261 #define FLAG_SKIP_ONLINEOTHERS 0x00000100 262 263 /* define for peripheral qualifier mask */ 264 #define FP_PERI_QUAL_MASK 0xE0 265 266 /* Message ids */ 267 typedef enum { 268 269 /* ERRORS */ 270 ERR_UNKNOWN = -1, 271 ERR_OP_FAILED, 272 ERR_CMD_INVAL, 273 ERR_NOT_BUSAPID, 274 ERR_APID_INVAL, 275 ERR_NOT_BUSOP, 276 ERR_NOT_DEVOP, 277 ERR_UNAVAILABLE, 278 ERR_CTRLR_CRIT, 279 ERR_BUS_GETSTATE, 280 ERR_BUS_NOTCONNECTED, 281 ERR_BUS_CONNECTED, 282 ERR_BUS_QUIESCE, 283 ERR_BUS_UNQUIESCE, 284 ERR_BUS_CONFIGURE, 285 ERR_BUS_UNCONFIGURE, 286 ERR_DEV_CONFIGURE, 287 ERR_DEV_UNCONFIGURE, 288 ERR_FCA_CONFIGURE, 289 ERR_FCA_UNCONFIGURE, 290 ERR_DEV_REPLACE, 291 ERR_DEV_INSERT, 292 ERR_DEV_GETSTATE, 293 ERR_RESET, 294 ERR_LIST, 295 ERR_FC, 296 ERR_FC_GET_DEVLIST, 297 ERR_FC_GET_FIRST_DEV, 298 ERR_FC_GET_NEXT_DEV, 299 ERRARG_FC_DEV_MAP_INIT, 300 ERRARG_FC_PROP_LOOKUP_BYTES, 301 ERRARG_FC_INQUIRY, 302 ERRARG_FC_REP_LUNS, 303 ERRARG_FC_TOPOLOGY, 304 ERRARG_PATH_TOO_LONG, 305 ERRARG_INVALID_PATH, 306 ERRARG_OPENDIR, 307 ERRARG_VHCI_GET_PATHLIST, 308 ERRARG_XPORT_NOT_IN_PHCI_LIST, 309 ERR_SIG_STATE, 310 ERR_MAYBE_BUSY, 311 ERR_BUS_DEV_MISMATCH, 312 ERR_GET_DEVLIST, 313 ERR_MEM_ALLOC, 314 ERR_DEVCTL_OFFLINE, 315 ERR_UPD_REP, 316 ERR_CONF_OK_UPD_REP, 317 ERR_UNCONF_OK_UPD_REP, 318 ERR_PARTIAL_SUCCESS, 319 ERR_HBA_LOAD_LIBRARY, 320 ERR_MATCHING_HBA_PORT, 321 ERR_NO_ADAPTER_FOUND, 322 323 /* Errors with arguments */ 324 ERRARG_OPT_INVAL, 325 ERRARG_HWCMD_INVAL, 326 ERRARG_DEVINFO, 327 ERRARG_NOT_IN_DEVLIST, 328 ERRARG_NOT_IN_DEVINFO, 329 ERRARG_DI_GET_PROP, 330 ERRARG_DC_DDEF_ALLOC, 331 ERRARG_DC_BYTE_ARRAY, 332 ERRARG_DC_BUS_ACQUIRE, 333 ERRARG_BUS_DEV_CREATE, 334 ERRARG_BUS_DEV_CREATE_UNKNOWN, 335 ERRARG_DEV_ACQUIRE, 336 ERRARG_DEV_REMOVE, 337 338 /* RCM Errors */ 339 ERR_RCM_HANDLE, 340 ERRARG_RCM_SUSPEND, 341 ERRARG_RCM_RESUME, 342 ERRARG_RCM_OFFLINE, 343 ERRARG_RCM_ONLINE, 344 ERRARG_RCM_REMOVE, 345 ERRARG_RCM_INFO, 346 347 /* Commands */ 348 CMD_INSERT_DEV, 349 CMD_REMOVE_DEV, 350 CMD_REPLACE_DEV, 351 CMD_RESET_DEV, 352 CMD_RESET_BUS, 353 CMD_RESET_ALL, 354 355 /* help messages */ 356 MSG_HELP_HDR, 357 MSG_HELP_USAGE, 358 359 /* Hotplug messages */ 360 MSG_INSDEV, 361 MSG_RMDEV, 362 MSG_REPLDEV, 363 364 /* Hotplugging confirmation prompts */ 365 CONF_QUIESCE_1, 366 CONF_QUIESCE_2, 367 CONF_UNQUIESCE, 368 369 /* Misc. */ 370 WARN_DISCONNECT 371 } msgid_t; 372 373 typedef struct { 374 msgid_t str_id; 375 fpcfga_cmd_t cmd; 376 fpcfga_ret_t (*fcn)(fpcfga_cmd_t, apid_t *, prompt_t *, char **); 377 } hw_cmd_t; 378 379 typedef struct { 380 msgid_t msgid; 381 int nargs; /* Number of arguments following msgid */ 382 int intl; /* Flag: if 1, internationalize */ 383 const char *msgstr; 384 } msgcvt_t; 385 386 387 #define SLASH "/" 388 #define CFGA_DEV_DIR "/dev/cfg" 389 #define DEV_DIR "/dev" 390 #define DEVICES_DIR "/devices" 391 #define DEV_DSK "/dev/dsk" 392 #define DEV_RDSK "/dev/rdsk" 393 #define DEV_RMT "/dev/rmt" 394 #define DSK_DIR "dsk" 395 #define RDSK_DIR "rdsk" 396 #define RMT_DIR "rmt" 397 398 399 #define DYN_SEP "::" 400 #define LUN_COMP_SEP "," 401 #define MINOR_SEP ":" 402 403 #define S_FREE(x) (((x) != NULL) ? (free(x), (x) = NULL) : (void *)0) 404 #define S_STR(x) (((x) == NULL) ? "" : (x)) 405 406 407 #define IS_STUB_NODE(s) (di_instance(s) == -1 && \ 408 di_nodeid(s) == (DI_PROM_NODEID)) 409 410 #define GET_MSG_STR(i) (str_tbl[msg_idx(i)].msgstr) 411 412 #define GET_DYN(a) (((a) != NULL) ? strstr((a), DYN_SEP) : (void *)0) 413 #define GET_LUN_DYN(a) (((a) != NULL) ? strstr((a), LUN_COMP_SEP) : (void *)0) 414 415 /* 416 * The following macro removes the separator from the dynamic component. 417 */ 418 #define DYN_TO_DYNCOMP(a) ((a) + strlen(DYN_SEP)) 419 #define LUN_DYN_TO_LUNCOMP(a) ((a) + strlen(LUN_COMP_SEP)) 420 421 /* 422 * Property names 423 */ 424 #define PORT_WWN_PROP "port-wwn" 425 #define LUN_GUID_PROP "client-guid" 426 #define LUN_PROP "lun" 427 428 #define WWN_S_LEN 17 /* NULL terminated string */ 429 #define WWN_SIZE 8 430 /* Constants used for repository updates */ 431 #define ADD_ENTRY 0 432 #define REMOVE_ENTRY 1 433 434 #define FAB_REPOSITORY_DIR "/etc/cfg/fp" 435 #define FAB_REPOSITORY "/etc/cfg/fp/fabric_WWN_map" 436 #define TMP_FAB_REPOSITORY "/etc/cfg/fp/fabric_WWN_map.tmp" 437 #define OLD_FAB_REPOSITORY "/etc/cfg/fp/fabric_WWN_map.old" 438 439 /* MPXIO VHCI root dir */ 440 #define SCSI_VHCI_ROOT "/devices/scsi_vhci/" 441 #define SCSI_VHCI_DRVR "scsi_vhci" 442 #define HBA_MAX_RETRIES 10 443 444 /* Function prototypes */ 445 446 fpcfga_ret_t get_report_lun_data(const char *xport_phys, 447 const char *dyncomp, int *num_luns, report_lun_resp_t **resp_buf, 448 struct scsi_extended_sense *sense, int *l_errnop); 449 /* Functions in cfga_cs.c */ 450 fpcfga_ret_t 451 dev_change_state(cfga_cmd_t, apid_t *, la_wwn_t *, cfga_flags_t, char **, 452 HBA_HANDLE handle, HBA_PORTATTRIBUTES portAttrs); 453 fpcfga_ret_t 454 fca_change_state(cfga_cmd_t, apid_t *, cfga_flags_t, char **); 455 456 /* Functions in cfga_rep.c */ 457 int update_fabric_wwn_list(int, const char *, char **); 458 459 fpcfga_ret_t dev_insert(fpcfga_cmd_t cmd, apid_t *apidp, prompt_t *argsp, 460 char **errstring); 461 fpcfga_ret_t dev_replace(fpcfga_cmd_t cmd, apid_t *apidp, prompt_t *argsp, 462 char **errstring); 463 fpcfga_ret_t dev_remove(fpcfga_cmd_t cmd, apid_t *apidp, prompt_t *argsp, 464 char **errstring); 465 fpcfga_ret_t reset_common(fpcfga_cmd_t cmd, apid_t *apidp, prompt_t *argsp, 466 char **errstring); 467 468 469 /* List related routines */ 470 fpcfga_ret_t do_list(apid_t *apidp, fpcfga_cmd_t cmd, 471 ldata_list_t **ldatalistp, int *nelem, char **errstring); 472 fpcfga_ret_t do_list_FCP_dev(const char *ap_id, uint_t flags, fpcfga_cmd_t cmd, 473 ldata_list_t **llpp, int *nelemp, char **errstring); 474 fpcfga_ret_t list_ext_postprocess(ldata_list_t **ldatalistp, int nelem, 475 cfga_list_data_t **ap_id_list, int *nlistp, char **errstring); 476 int stat_path_info_node(di_node_t root, void *arg, int *l_errnop); 477 478 /* Conversion routines */ 479 fpcfga_ret_t make_xport_logid(const char *xport_phys, char **xport_logpp, 480 int *l_errnop); 481 fpcfga_ret_t dyn_apid_to_path(const char *xport_phys, const char *dyncomp, 482 struct luninfo_list **lunlistpp, int *l_errnop); 483 void cvt_lawwn_to_dyncomp(const la_wwn_t *pwwn, char **dyncomp, int *l_errnop); 484 int cvt_dyncomp_to_lawwn(const char *dyncomp, la_wwn_t *port_wwn); 485 fpcfga_ret_t make_dyncomp_from_dinode(const di_node_t node, char **dyncompp, 486 int *l_errnop); 487 fpcfga_ret_t make_portwwn_luncomp_from_dinode(const di_node_t node, 488 char **dyncompp, int **luncompp, int *l_errnop); 489 fpcfga_ret_t make_portwwn_luncomp_from_pinode(const di_path_t pinode, 490 char **dyncompp, int **luncompp, int *l_errnop); 491 fpcfga_ret_t construct_nodepath_from_dinode(const di_node_t node, 492 char **node_pathp, int *l_errnop); 493 u_longlong_t wwnConversion(uchar_t *wwn); 494 495 496 /* Functions in cfga_rcm.c */ 497 fpcfga_ret_t fp_rcm_offline(char *, char **, cfga_flags_t); 498 fpcfga_ret_t fp_rcm_online(char *, char **, cfga_flags_t); 499 fpcfga_ret_t fp_rcm_remove(char *, char **, cfga_flags_t); 500 fpcfga_ret_t fp_rcm_suspend(char *, char *, char **, cfga_flags_t); 501 fpcfga_ret_t fp_rcm_resume(char *, char *, char **, cfga_flags_t); 502 fpcfga_ret_t fp_rcm_info(char *, char **, char **); 503 504 /* Utility routines */ 505 fpcfga_ret_t physpath_to_devlink(const char *basedir, char *xport_phys, 506 char **xport_logpp, int *l_errnop, int match_minor); 507 fpcfga_ret_t recurse_dev(const char *basedir, void *arg, 508 fpcfga_recur_t (*fcn)(const char *lpath, void *arg)); 509 fpcfga_ret_t apidt_create(const char *ap_id, apid_t *apidp, 510 char **errstring); 511 void apidt_free(apid_t *apidp); 512 cfga_err_t err_cvt(fpcfga_ret_t err); 513 void list_free(ldata_list_t **llpp); 514 int known_state(di_node_t node); 515 516 fpcfga_ret_t devctl_cmd(const char *ap_id, fpcfga_cmd_t cmd, 517 uint_t *statep, int *l_errnop); 518 fpcfga_ret_t invoke_cmd(const char *func, apid_t *apidt, prompt_t *prp, 519 char **errstring); 520 521 void cfga_err(char **errstring, int use_errno, ...); 522 void cfga_msg(struct cfga_msg *msgp, ...); 523 char *cfga_str(int append_newline, ...); 524 int msg_idx(msgid_t msgid); 525 fpcfga_ret_t walk_tree(const char *physpath, void *arg, uint_t init_flags, 526 walkarg_t *up, fpcfga_cmd_t cmd, int *l_errnop); 527 int hba_dev_cmp(const char *hba, const char *dev); 528 int dev_cmp(const char *dev1, const char *dev2, int match_minor); 529 char *pathdup(const char *path, int *l_errnop); 530 int getPortAttrsByWWN(HBA_HANDLE handle, HBA_WWN wwn, 531 HBA_PORTATTRIBUTES *attrs); 532 int getDiscPortAttrs(HBA_HANDLE handle, int portIndex, 533 int discIndex, HBA_PORTATTRIBUTES *attrs); 534 int getAdapterPortAttrs(HBA_HANDLE handle, int portIndex, 535 HBA_PORTATTRIBUTES *attrs); 536 int getAdapterAttrs(HBA_HANDLE handle, HBA_ADAPTERATTRIBUTES *attrs); 537 fpcfga_ret_t findMatchingAdapterPort(char *portPath, 538 HBA_HANDLE *matchingHandle, int *matchingPortIndex, 539 HBA_PORTATTRIBUTES *matchingPortAttrs, char **errstring); 540 541 extern msgcvt_t str_tbl[]; 542 543 #ifdef __cplusplus 544 } 545 #endif 546 547 #endif /* _CFGA_FP_H */ 548