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