xref: /illumos-gate/usr/src/lib/cfgadm_plugins/scsi/common/cfga_scsi.h (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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