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 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _CFGA_SCSI_H 28 #define _CFGA_SCSI_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #include <stddef.h> 35 #include <locale.h> 36 #include <ctype.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <fcntl.h> 41 #include <unistd.h> 42 #include <errno.h> 43 #include <locale.h> 44 #include <langinfo.h> 45 #include <time.h> 46 #include <stdarg.h> 47 #include <sys/types.h> 48 #include <sys/ioctl.h> 49 #include <sys/dditypes.h> 50 #include <sys/modctl.h> 51 #include <libdevinfo.h> 52 #include <libdevice.h> 53 #include <librcm.h> 54 #include <dirent.h> 55 #include <strings.h> 56 57 #include <sys/ioctl.h> 58 #include <sys/byteorder.h> 59 #include <sys/scsi/scsi.h> 60 #include <strings.h> 61 #include <sys/vfstab.h> 62 #include <sys/stat.h> 63 #include <sys/mnttab.h> 64 #include <sys/wait.h> 65 #include <signal.h> 66 67 #include <sys/uio.h> 68 #include <sys/param.h> 69 70 #include <synch.h> 71 #include <thread.h> 72 73 #include <limits.h> 74 #include <ftw.h> 75 76 #define CFGA_PLUGIN_LIB 77 #include <config_admin.h> 78 79 #if !defined(DEBUG) 80 #define NDEBUG 1 81 #else 82 #undef NDEBUG 83 #endif 84 85 #include <assert.h> 86 87 /* Return/error codes */ 88 typedef enum { 89 SCFGA_ERR = -1, 90 SCFGA_LIB_ERR = 0, 91 SCFGA_OK, 92 SCFGA_NACK, 93 SCFGA_BUSY, 94 SCFGA_SYSTEM_BUSY, 95 SCFGA_APID_NOEXIST, 96 SCFGA_OPNOTSUPP, 97 SCFGA_PRIV, 98 SCFGA_UNLOCKED, 99 SCFGA_NO_REC, 100 SCFGA_OP_INTR, 101 SCFGA_DB_INVAL, 102 SCFGA_UNKNOWN_ERR 103 } scfga_ret_t; 104 105 /* Commands used internally */ 106 typedef enum { 107 SCFGA_INVAL_CMD = -1, 108 SCFGA_DEV_OP = 0, 109 SCFGA_BUS_OP, 110 SCFGA_STAT_DEV, 111 SCFGA_STAT_BUS, 112 SCFGA_STAT_ALL, 113 SCFGA_GET_DEVPATH, 114 SCFGA_INSERT_DEV, 115 SCFGA_REMOVE_DEV, 116 SCFGA_REPLACE_DEV, 117 SCFGA_WALK_NODE, 118 SCFGA_WALK_MINOR, 119 SCFGA_WALK_PATH, 120 SCFGA_BUS_QUIESCE, 121 SCFGA_BUS_UNQUIESCE, 122 SCFGA_BUS_GETSTATE, 123 SCFGA_DEV_GETSTATE, 124 SCFGA_BUS_CONFIGURE, 125 SCFGA_BUS_UNCONFIGURE, 126 SCFGA_DEV_CONFIGURE, 127 SCFGA_DEV_UNCONFIGURE, 128 SCFGA_DEV_REMOVE, 129 SCFGA_LED_DEV, 130 SCFGA_LOCATOR_DEV, 131 SCFGA_RESET_DEV, 132 SCFGA_RESET_BUS, 133 SCFGA_RESET_ALL, 134 SCFGA_READ, 135 SCFGA_WRITE 136 } scfga_cmd_t; 137 138 typedef enum { 139 SCFGA_TERMINATE = 0, 140 SCFGA_CONTINUE 141 } scfga_recur_t; 142 143 typedef enum { 144 NODYNCOMP = 1, 145 DEV_APID, 146 PATH_APID 147 } dyncomp_t; 148 149 150 /* Structures for tree walking code */ 151 152 typedef struct { 153 uint_t flags; 154 int (*fcn)(di_node_t node, void *argp); 155 } walk_node_t; 156 157 typedef struct { 158 const char *nodetype; 159 int (*fcn)(di_node_t node, di_minor_t minor, void *argp); 160 } walk_minor_t; 161 162 typedef union { 163 walk_node_t node_args; 164 walk_minor_t minor_args; 165 } walkarg_t; 166 167 typedef struct { 168 char *phys; 169 char *log; 170 scfga_ret_t ret; 171 int match_minor; 172 int l_errno; 173 } pathm_t; 174 175 typedef struct ldata_list { 176 cfga_list_data_t ldata; 177 struct ldata_list *next; 178 } ldata_list_t; 179 180 typedef struct { 181 struct cfga_confirm *confp; 182 struct cfga_msg *msgp; 183 } prompt_t; 184 185 typedef struct { 186 char *hba_phys; 187 char *dyncomp; 188 dyncomp_t dyntype; /* is pathinfo or dev apid? */ 189 char *path; /* for apid with device dyn comp. */ 190 uint_t flags; 191 } apid_t; 192 193 /* Private hardware options */ 194 #define OPT_DISABLE_RCM "disable_rcm" 195 #define OPT_USE_DIFORCE "use_diforce" 196 197 /* apid_t flags */ 198 #define FLAG_DISABLE_RCM 0x01 199 #define FLAG_USE_DIFORCE 0x02 200 201 /* internal use for handling pathinfo */ 202 #define FLAG_CLIENT_DEV 0x04 203 204 /* Message ids */ 205 typedef enum { 206 207 /* ERRORS */ 208 ERR_UNKNOWN = -1, 209 ERR_OP_FAILED, 210 ERR_CMD_INVAL, 211 ERR_NOT_BUSAPID, 212 ERR_APID_INVAL, 213 ERR_NOT_BUSOP, 214 ERR_NOT_DEVOP, 215 ERR_UNAVAILABLE, 216 ERR_CTRLR_CRIT, 217 ERR_BUS_GETSTATE, 218 ERR_BUS_NOTCONNECTED, 219 ERR_BUS_CONNECTED, 220 ERR_BUS_QUIESCE, 221 ERR_BUS_UNQUIESCE, 222 ERR_BUS_CONFIGURE, 223 ERR_BUS_UNCONFIGURE, 224 ERR_DEV_CONFIGURE, 225 ERR_DEV_RECONFIGURE, 226 ERR_DEV_UNCONFIGURE, 227 ERR_DEV_REMOVE, 228 ERR_DEV_REPLACE, 229 ERR_DEV_INSERT, 230 ERR_DEV_GETSTATE, 231 ERR_RESET, 232 ERR_LIST, 233 ERR_MAYBE_BUSY, 234 ERR_BUS_DEV_MISMATCH, 235 ERR_VAR_RUN, 236 ERR_FORK, 237 238 /* Errors with arguments */ 239 ERRARG_OPT_INVAL, 240 ERRARG_HWCMD_INVAL, 241 ERRARG_DEVINFO, 242 ERRARG_OPEN, 243 ERRARG_LOCK, 244 ERRARG_QUIESCE_LOCK, 245 246 /* RCM Errors */ 247 ERR_RCM_HANDLE, 248 ERRARG_RCM_SUSPEND, 249 ERRARG_RCM_RESUME, 250 ERRARG_RCM_OFFLINE, 251 ERRARG_RCM_CLIENT_OFFLINE, 252 ERRARG_RCM_ONLINE, 253 ERRARG_RCM_REMOVE, 254 255 /* Commands */ 256 CMD_INSERT_DEV, 257 CMD_REMOVE_DEV, 258 CMD_REPLACE_DEV, 259 CMD_LED_DEV, 260 CMD_LOCATOR_DEV, 261 CMD_RESET_DEV, 262 CMD_RESET_BUS, 263 CMD_RESET_ALL, 264 265 /* help messages */ 266 MSG_HELP_HDR, 267 MSG_HELP_USAGE, 268 269 /* Hotplug messages */ 270 MSG_INSDEV, 271 MSG_RMDEV, 272 MSG_REPLDEV, 273 MSG_WAIT_LOCK, 274 275 /* Hotplugging confirmation prompts */ 276 CONF_QUIESCE_1, 277 CONF_QUIESCE_2, 278 CONF_UNQUIESCE, 279 CONF_NO_QUIESCE, 280 281 /* Misc. */ 282 WARN_DISCONNECT, 283 284 /* HDD led/locator messages */ 285 MSG_LED_HDR, 286 MSG_MISSING_LED_NAME, 287 MSG_MISSING_LED_MODE 288 } msgid_t; 289 290 typedef enum { 291 LED_STR_FAULT, 292 LED_STR_POWER, 293 LED_STR_ATTN, 294 LED_STR_ACTIVE, 295 LED_STR_LOCATOR 296 } led_strid_t; 297 298 typedef enum { 299 LED_MODE_OFF, 300 LED_MODE_ON, 301 LED_MODE_BLINK, 302 LED_MODE_FAULTED, 303 LED_MODE_UNK 304 } led_modeid_t; 305 306 307 typedef struct { 308 msgid_t str_id; 309 scfga_cmd_t cmd; 310 scfga_ret_t (*fcn)(const char *, scfga_cmd_t, apid_t *, prompt_t *, 311 cfga_flags_t, char **); 312 } hw_cmd_t; 313 314 typedef struct { 315 msgid_t msgid; 316 int nargs; /* Number of arguments following msgid */ 317 int intl; /* Flag: if 1, internationalize */ 318 const char *msgstr; 319 } msgcvt_t; 320 321 322 #define SLASH "/" 323 #define CFGA_DEV_DIR "/dev/cfg" 324 #define DEV_DIR "/dev" 325 #define DEVICES_DIR "/devices" 326 #define DEV_DSK "/dev/dsk" 327 #define DEV_RDSK "/dev/rdsk" 328 #define DEV_RMT "/dev/rmt" 329 #define DSK_DIR "dsk" 330 #define RDSK_DIR "rdsk" 331 #define RMT_DIR "rmt" 332 333 334 #define DYN_SEP "::" 335 #define MINOR_SEP ":" 336 #define PATH_APID_DYN_SEP "," 337 338 #define S_FREE(x) (((x) != NULL) ? (free(x), (x) = NULL) : (void *)0) 339 #define S_STR(x) (((x) == NULL) ? "" : (x)) 340 341 342 #define IS_STUB_NODE(s) (di_instance(s) == -1 && \ 343 di_nodeid(s) == (DI_PROM_NODEID)) 344 345 #define GET_MSG_STR(i) (str_tbl[msg_idx(i)].msgstr) 346 347 #define GET_DYN(a) (((a) != NULL) ? strstr((a), DYN_SEP) : (void *)0) 348 349 /* 350 * The following macro removes the separator from the dynamic component. 351 */ 352 #define DYN_TO_DYNCOMP(a) ((a) + strlen(DYN_SEP)) 353 354 extern int _scfga_debug; 355 356 /* 357 * Tracing/debugging macros 358 */ 359 #define CFGA_TRACE1(args) (void) ((_scfga_debug >= 1) ? fprintf args : 0) 360 #define CFGA_TRACE2(args) (void) ((_scfga_debug >= 2) ? fprintf args : 0) 361 #define CFGA_TRACE3(args) (void) ((_scfga_debug >= 3) ? fprintf args : 0) 362 363 /* Function prototypes */ 364 365 /* bus/device ctl routines */ 366 scfga_ret_t bus_change_state(cfga_cmd_t state_change_cmd, 367 apid_t *apidp, struct cfga_confirm *confp, cfga_flags_t flags, 368 char **errstring); 369 scfga_ret_t dev_change_state(cfga_cmd_t state_change_cmd, 370 apid_t *apidp, cfga_flags_t flags, char **errstring); 371 scfga_ret_t dev_insert(const char *func, scfga_cmd_t cmd, apid_t *apidp, 372 prompt_t *argsp, cfga_flags_t flags, char **errstring); 373 scfga_ret_t dev_replace(const char *func, scfga_cmd_t cmd, apid_t *apidp, 374 prompt_t *argsp, cfga_flags_t flags, char **errstring); 375 scfga_ret_t dev_remove(const char *func, scfga_cmd_t cmd, apid_t *apidp, 376 prompt_t *argsp, cfga_flags_t flags, char **errstring); 377 scfga_ret_t reset_common(const char *func, scfga_cmd_t cmd, apid_t *apidp, 378 prompt_t *argsp, cfga_flags_t flags, char **errstring); 379 scfga_ret_t dev_led(const char *func, scfga_cmd_t cmd, apid_t *apidp, 380 prompt_t *argsp, cfga_flags_t flags, char **errstring); 381 scfga_ret_t plat_dev_led(const char *func, scfga_cmd_t cmd, apid_t *apidp, 382 prompt_t *argsp, cfga_flags_t flags, char **errstring); 383 384 385 /* List related routines */ 386 scfga_ret_t do_list(apid_t *apidp, scfga_cmd_t cmd, 387 ldata_list_t **llpp, int *nelem, char **errstring); 388 scfga_ret_t list_ext_postprocess(ldata_list_t **llpp, int nelem, 389 cfga_list_data_t **ap_id_list, int *nlistp, char **errstring); 390 int stat_path_info(di_node_t root, void *arg, int *l_errnop); 391 392 393 /* Conversion routines */ 394 scfga_ret_t make_hba_logid(const char *hba_phys, char **hba_logpp, 395 int *l_errnop); 396 scfga_ret_t apid_to_path(const char *hba_phys, const char *dyncomp, 397 char **pathpp, int *l_errnop); 398 scfga_ret_t make_dyncomp(di_node_t node, const char *physpath, 399 char **dyncompp, int *l_errnop); 400 scfga_ret_t make_path_dyncomp(di_path_t path, char **dyncomp, int *l_errnop); 401 402 403 /* RCM routines */ 404 scfga_ret_t scsi_rcm_suspend(char **rsrclist, char **errstring, 405 cfga_flags_t flags, int pflag); 406 scfga_ret_t scsi_rcm_resume(char **rsrclist, char **errstring, 407 cfga_flags_t flags, int pflag); 408 scfga_ret_t scsi_rcm_offline(char **rsrclist, char **errstring, 409 cfga_flags_t flags); 410 scfga_ret_t scsi_rcm_online(char **rsrclist, char **errstring, 411 cfga_flags_t flags); 412 scfga_ret_t scsi_rcm_remove(char **rsrclist, char **errstring, 413 cfga_flags_t flags); 414 415 416 /* Utility routines */ 417 scfga_ret_t physpath_to_devlink(char *physpath, char **linkpp, int *l_errnop, 418 int match_minor); 419 scfga_ret_t apidt_create(const char *ap_id, apid_t *apidp, 420 char **errstring); 421 void apidt_free(apid_t *apidp); 422 cfga_err_t err_cvt(scfga_ret_t err); 423 void list_free(ldata_list_t **llpp); 424 int known_state(di_node_t node); 425 scfga_ret_t devctl_cmd(const char *ap_id, scfga_cmd_t cmd, 426 uint_t *statep, int *l_errnop); 427 scfga_ret_t path_apid_state_change(apid_t *apidp, scfga_cmd_t cmd, 428 cfga_flags_t flags, char **errstring, int *l_errnop, msgid_t errid); 429 scfga_ret_t invoke_cmd(const char *func, apid_t *apidt, prompt_t *prp, 430 cfga_flags_t flags, char **errstring); 431 432 void cfga_err(char **errstring, int use_errno, ...); 433 void cfga_msg(struct cfga_msg *msgp, ...); 434 void cfga_led_msg(struct cfga_msg *msgp, apid_t *apidp, led_strid_t, 435 led_modeid_t); 436 char *cfga_str(int append_newline, ...); 437 int msg_idx(msgid_t msgid); 438 scfga_ret_t walk_tree(const char *physpath, void *arg, uint_t init_flags, 439 walkarg_t *up, scfga_cmd_t cmd, int *l_errnop); 440 int hba_dev_cmp(const char *hba, const char *dev); 441 int dev_cmp(const char *dev1, const char *dev2, int match_minor); 442 443 extern msgcvt_t str_tbl[]; 444 445 #ifdef __cplusplus 446 } 447 #endif 448 449 #endif /* _CFGA_SCSI_H */ 450