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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 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_RESET_DEV, 131 SCFGA_RESET_BUS, 132 SCFGA_RESET_ALL, 133 SCFGA_READ, 134 SCFGA_WRITE 135 } scfga_cmd_t; 136 137 typedef enum { 138 SCFGA_TERMINATE = 0, 139 SCFGA_CONTINUE 140 } scfga_recur_t; 141 142 143 /* Structures for tree walking code */ 144 145 typedef struct { 146 uint_t flags; 147 int (*fcn)(di_node_t node, void *argp); 148 } walk_node_t; 149 150 typedef struct { 151 const char *nodetype; 152 int (*fcn)(di_node_t node, di_minor_t minor, void *argp); 153 } walk_minor_t; 154 155 typedef union { 156 walk_node_t node_args; 157 walk_minor_t minor_args; 158 } walkarg_t; 159 160 typedef struct { 161 char *phys; 162 char *log; 163 scfga_ret_t ret; 164 int match_minor; 165 int l_errno; 166 } pathm_t; 167 168 typedef struct ldata_list { 169 cfga_list_data_t ldata; 170 struct ldata_list *next; 171 } ldata_list_t; 172 173 typedef struct { 174 struct cfga_confirm *confp; 175 struct cfga_msg *msgp; 176 } prompt_t; 177 178 typedef struct { 179 char *hba_phys; 180 char *dyncomp; 181 char *path; 182 uint_t flags; 183 } apid_t; 184 185 /* Private hardware options */ 186 #define OPT_DISABLE_RCM "disable_rcm" 187 #define OPT_USE_DIFORCE "use_diforce" 188 189 /* apid_t flags */ 190 #define FLAG_DISABLE_RCM 0x01 191 #define FLAG_USE_DIFORCE 0x02 192 193 /* Message ids */ 194 typedef enum { 195 196 /* ERRORS */ 197 ERR_UNKNOWN = -1, 198 ERR_OP_FAILED, 199 ERR_CMD_INVAL, 200 ERR_NOT_BUSAPID, 201 ERR_APID_INVAL, 202 ERR_NOT_BUSOP, 203 ERR_NOT_DEVOP, 204 ERR_UNAVAILABLE, 205 ERR_CTRLR_CRIT, 206 ERR_BUS_GETSTATE, 207 ERR_BUS_NOTCONNECTED, 208 ERR_BUS_CONNECTED, 209 ERR_BUS_QUIESCE, 210 ERR_BUS_UNQUIESCE, 211 ERR_BUS_CONFIGURE, 212 ERR_BUS_UNCONFIGURE, 213 ERR_DEV_CONFIGURE, 214 ERR_DEV_RECONFIGURE, 215 ERR_DEV_UNCONFIGURE, 216 ERR_DEV_REMOVE, 217 ERR_DEV_REPLACE, 218 ERR_DEV_INSERT, 219 ERR_DEV_GETSTATE, 220 ERR_RESET, 221 ERR_LIST, 222 ERR_MAYBE_BUSY, 223 ERR_BUS_DEV_MISMATCH, 224 ERR_VAR_RUN, 225 ERR_FORK, 226 227 /* Errors with arguments */ 228 ERRARG_OPT_INVAL, 229 ERRARG_HWCMD_INVAL, 230 ERRARG_DEVINFO, 231 ERRARG_OPEN, 232 ERRARG_LOCK, 233 ERRARG_QUIESCE_LOCK, 234 235 /* RCM Errors */ 236 ERR_RCM_HANDLE, 237 ERRARG_RCM_SUSPEND, 238 ERRARG_RCM_RESUME, 239 ERRARG_RCM_OFFLINE, 240 ERRARG_RCM_ONLINE, 241 ERRARG_RCM_REMOVE, 242 243 /* Commands */ 244 CMD_INSERT_DEV, 245 CMD_REMOVE_DEV, 246 CMD_REPLACE_DEV, 247 CMD_RESET_DEV, 248 CMD_RESET_BUS, 249 CMD_RESET_ALL, 250 251 /* help messages */ 252 MSG_HELP_HDR, 253 MSG_HELP_USAGE, 254 255 /* Hotplug messages */ 256 MSG_INSDEV, 257 MSG_RMDEV, 258 MSG_REPLDEV, 259 MSG_WAIT_LOCK, 260 261 /* Hotplugging confirmation prompts */ 262 CONF_QUIESCE_1, 263 CONF_QUIESCE_2, 264 CONF_UNQUIESCE, 265 CONF_NO_QUIESCE, 266 267 /* Misc. */ 268 WARN_DISCONNECT 269 } msgid_t; 270 271 typedef struct { 272 msgid_t str_id; 273 scfga_cmd_t cmd; 274 scfga_ret_t (*fcn)(scfga_cmd_t, apid_t *, prompt_t *, cfga_flags_t, 275 char **); 276 } hw_cmd_t; 277 278 typedef struct { 279 msgid_t msgid; 280 int nargs; /* Number of arguments following msgid */ 281 int intl; /* Flag: if 1, internationalize */ 282 const char *msgstr; 283 } msgcvt_t; 284 285 286 #define SLASH "/" 287 #define CFGA_DEV_DIR "/dev/cfg" 288 #define DEV_DIR "/dev" 289 #define DEVICES_DIR "/devices" 290 #define DEV_DSK "/dev/dsk" 291 #define DEV_RDSK "/dev/rdsk" 292 #define DEV_RMT "/dev/rmt" 293 #define DSK_DIR "dsk" 294 #define RDSK_DIR "rdsk" 295 #define RMT_DIR "rmt" 296 297 298 #define DYN_SEP "::" 299 #define MINOR_SEP ":" 300 301 #define S_FREE(x) (((x) != NULL) ? (free(x), (x) = NULL) : (void *)0) 302 #define S_STR(x) (((x) == NULL) ? "" : (x)) 303 304 305 #define IS_STUB_NODE(s) (di_instance(s) == -1 && \ 306 di_nodeid(s) == (DI_PROM_NODEID)) 307 308 #define GET_MSG_STR(i) (str_tbl[msg_idx(i)].msgstr) 309 310 #define GET_DYN(a) (((a) != NULL) ? strstr((a), DYN_SEP) : (void *)0) 311 312 /* 313 * The following macro removes the separator from the dynamic component. 314 */ 315 #define DYN_TO_DYNCOMP(a) ((a) + strlen(DYN_SEP)) 316 317 extern int _scfga_debug; 318 319 /* 320 * Tracing/debugging macros 321 */ 322 #define CFGA_TRACE1(args) (void) ((_scfga_debug >= 1) ? fprintf args : 0) 323 #define CFGA_TRACE2(args) (void) ((_scfga_debug >= 2) ? fprintf args : 0) 324 #define CFGA_TRACE3(args) (void) ((_scfga_debug >= 3) ? fprintf args : 0) 325 326 /* Function prototypes */ 327 328 /* bus/device ctl routines */ 329 scfga_ret_t bus_change_state(cfga_cmd_t state_change_cmd, 330 apid_t *apidp, struct cfga_confirm *confp, cfga_flags_t flags, 331 char **errstring); 332 scfga_ret_t dev_change_state(cfga_cmd_t state_change_cmd, 333 apid_t *apidp, cfga_flags_t flags, char **errstring); 334 scfga_ret_t dev_insert(scfga_cmd_t cmd, apid_t *apidp, prompt_t *argsp, 335 cfga_flags_t flags, char **errstring); 336 scfga_ret_t dev_replace(scfga_cmd_t cmd, apid_t *apidp, prompt_t *argsp, 337 cfga_flags_t flags, char **errstring); 338 scfga_ret_t dev_remove(scfga_cmd_t cmd, apid_t *apidp, prompt_t *argsp, 339 cfga_flags_t flags, char **errstring); 340 scfga_ret_t reset_common(scfga_cmd_t cmd, apid_t *apidp, prompt_t *argsp, 341 cfga_flags_t flags, char **errstring); 342 343 344 /* List related routines */ 345 scfga_ret_t do_list(apid_t *apidp, scfga_cmd_t cmd, 346 ldata_list_t **llpp, int *nelem, char **errstring); 347 scfga_ret_t list_ext_postprocess(ldata_list_t **llpp, int nelem, 348 cfga_list_data_t **ap_id_list, int *nlistp, char **errstring); 349 350 351 /* Conversion routines */ 352 scfga_ret_t make_hba_logid(const char *hba_phys, char **hba_logpp, 353 int *l_errnop); 354 scfga_ret_t apid_to_path(const char *hba_phys, const char *dyncomp, 355 char **pathpp, int *l_errnop); 356 scfga_ret_t make_dyncomp(di_node_t node, const char *physpath, 357 char **dyncompp, int *l_errnop); 358 359 360 /* RCM routines */ 361 scfga_ret_t scsi_rcm_suspend(char **rsrclist, char **errstring, 362 cfga_flags_t flags, int pflag); 363 scfga_ret_t scsi_rcm_resume(char **rsrclist, char **errstring, 364 cfga_flags_t flags, int pflag); 365 scfga_ret_t scsi_rcm_offline(char **rsrclist, char **errstring, 366 cfga_flags_t flags); 367 scfga_ret_t scsi_rcm_online(char **rsrclist, char **errstring, 368 cfga_flags_t flags); 369 scfga_ret_t scsi_rcm_remove(char **rsrclist, char **errstring, 370 cfga_flags_t flags); 371 372 373 /* Utility routines */ 374 scfga_ret_t physpath_to_devlink(char *physpath, char **linkpp, int *l_errnop, 375 int match_minor); 376 scfga_ret_t apidt_create(const char *ap_id, apid_t *apidp, 377 char **errstring); 378 void apidt_free(apid_t *apidp); 379 cfga_err_t err_cvt(scfga_ret_t err); 380 void list_free(ldata_list_t **llpp); 381 int known_state(di_node_t node); 382 scfga_ret_t devctl_cmd(const char *ap_id, scfga_cmd_t cmd, 383 uint_t *statep, int *l_errnop); 384 scfga_ret_t invoke_cmd(const char *func, apid_t *apidt, prompt_t *prp, 385 cfga_flags_t flags, char **errstring); 386 387 void cfga_err(char **errstring, int use_errno, ...); 388 void cfga_msg(struct cfga_msg *msgp, ...); 389 char *cfga_str(int append_newline, ...); 390 int msg_idx(msgid_t msgid); 391 scfga_ret_t walk_tree(const char *physpath, void *arg, uint_t init_flags, 392 walkarg_t *up, scfga_cmd_t cmd, int *l_errnop); 393 int hba_dev_cmp(const char *hba, const char *dev); 394 int dev_cmp(const char *dev1, const char *dev2, int match_minor); 395 396 extern msgcvt_t str_tbl[]; 397 398 #ifdef __cplusplus 399 } 400 #endif 401 402 #endif /* _CFGA_SCSI_H */ 403