xref: /titanic_51/usr/src/cmd/luxadm/adm.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte /*
22*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*fcf3ce44SJohn Forte  * Use is subject to license terms.
24*fcf3ce44SJohn Forte  */
25*fcf3ce44SJohn Forte 
26*fcf3ce44SJohn Forte 
27*fcf3ce44SJohn Forte 
28*fcf3ce44SJohn Forte 
29*fcf3ce44SJohn Forte /*LINTLIBRARY*/
30*fcf3ce44SJohn Forte 
31*fcf3ce44SJohn Forte 
32*fcf3ce44SJohn Forte /*
33*fcf3ce44SJohn Forte  * Administration program for SENA
34*fcf3ce44SJohn Forte  * subsystems and individual FC_AL devices.
35*fcf3ce44SJohn Forte  */
36*fcf3ce44SJohn Forte 
37*fcf3ce44SJohn Forte /*
38*fcf3ce44SJohn Forte  * I18N message number ranges
39*fcf3ce44SJohn Forte  *  This file: 2000 - 2999
40*fcf3ce44SJohn Forte  *  Shared common messages: 1 - 1999
41*fcf3ce44SJohn Forte  */
42*fcf3ce44SJohn Forte 
43*fcf3ce44SJohn Forte /* #define		 _POSIX_SOURCE 1 */
44*fcf3ce44SJohn Forte 
45*fcf3ce44SJohn Forte /*
46*fcf3ce44SJohn Forte  * These defines are used to map instance number from sf minor node.
47*fcf3ce44SJohn Forte  * They are copied from SF_INST_SHIFT4MINOR and SF_MINOR2INST in sfvar.h.
48*fcf3ce44SJohn Forte  * sfvar.h is not clean for userland use.
49*fcf3ce44SJohn Forte  * When it is cleaned up, these defines will be removed and sfvar.h
50*fcf3ce44SJohn Forte  * will be included in luxadm.h header file.
51*fcf3ce44SJohn Forte  */
52*fcf3ce44SJohn Forte #define		LUX_SF_INST_SHIFT4MINOR	6
53*fcf3ce44SJohn Forte #define		LUX_SF_MINOR2INST(x)	(x >> LUX_SF_INST_SHIFT4MINOR)
54*fcf3ce44SJohn Forte 
55*fcf3ce44SJohn Forte /*	Includes	*/
56*fcf3ce44SJohn Forte #include	<stdlib.h>
57*fcf3ce44SJohn Forte #include	<stdio.h>
58*fcf3ce44SJohn Forte #include	<sys/file.h>
59*fcf3ce44SJohn Forte #include	<sys/errno.h>
60*fcf3ce44SJohn Forte #include	<sys/types.h>
61*fcf3ce44SJohn Forte #include	<sys/stat.h>
62*fcf3ce44SJohn Forte #include	<sys/param.h>
63*fcf3ce44SJohn Forte #include	<fcntl.h>
64*fcf3ce44SJohn Forte #include	<unistd.h>
65*fcf3ce44SJohn Forte #include	<errno.h>
66*fcf3ce44SJohn Forte #include	<string.h>
67*fcf3ce44SJohn Forte #include	<ctype.h>
68*fcf3ce44SJohn Forte #include	<strings.h>
69*fcf3ce44SJohn Forte #include	<sys/stat.h>
70*fcf3ce44SJohn Forte #include	<dirent.h>
71*fcf3ce44SJohn Forte #include	<limits.h>
72*fcf3ce44SJohn Forte #include	<stdarg.h>
73*fcf3ce44SJohn Forte #include	<termio.h>		/* For password */
74*fcf3ce44SJohn Forte #include	<sys/scsi/scsi.h>
75*fcf3ce44SJohn Forte 
76*fcf3ce44SJohn Forte #include	"common.h"
77*fcf3ce44SJohn Forte #include	"luxadm.h"
78*fcf3ce44SJohn Forte 
79*fcf3ce44SJohn Forte 
80*fcf3ce44SJohn Forte /*	Global variables	*/
81*fcf3ce44SJohn Forte char	*dtype[16]; /* setting a global for later use. */
82*fcf3ce44SJohn Forte char			*whoami;
83*fcf3ce44SJohn Forte int	Options;
84*fcf3ce44SJohn Forte const	int OPTION_A	= 0x00000001;
85*fcf3ce44SJohn Forte const	int OPTION_B	= 0x00000002;
86*fcf3ce44SJohn Forte const	int OPTION_C	= 0x00000004;
87*fcf3ce44SJohn Forte const	int OPTION_D	= 0x00000008;
88*fcf3ce44SJohn Forte const	int OPTION_E	= 0x00000010;
89*fcf3ce44SJohn Forte const	int OPTION_F	= 0x00000020;
90*fcf3ce44SJohn Forte const	int OPTION_L	= 0x00000040;
91*fcf3ce44SJohn Forte const	int OPTION_P	= 0x00000080;
92*fcf3ce44SJohn Forte const	int OPTION_R	= 0x00000100;
93*fcf3ce44SJohn Forte const	int OPTION_T	= 0x00000200;
94*fcf3ce44SJohn Forte const	int OPTION_V	= 0x00000400;
95*fcf3ce44SJohn Forte const	int OPTION_Z	= 0x00001000;
96*fcf3ce44SJohn Forte const	int OPTION_Y	= 0x00002000;
97*fcf3ce44SJohn Forte const	int OPTION_CAPF	= 0x00004000;
98*fcf3ce44SJohn Forte const	int PVERBOSE	= 0x00008000;
99*fcf3ce44SJohn Forte const	int SAVE	= 0x00010000;
100*fcf3ce44SJohn Forte const	int EXPERT	= 0x00020000;
101*fcf3ce44SJohn Forte 
102*fcf3ce44SJohn Forte /*
103*fcf3ce44SJohn Forte  * Given a pointer to a character array, print the character array.
104*fcf3ce44SJohn Forte  * the character array will not necesarily be NULL terminated.
105*fcf3ce44SJohn Forte  *
106*fcf3ce44SJohn Forte  * Inputs:
107*fcf3ce44SJohn Forte  *	size - the max number of characters to print
108*fcf3ce44SJohn Forte  *	fill_flag - flag when set fills all NULL characters with spaces
109*fcf3ce44SJohn Forte  * Returns:
110*fcf3ce44SJohn Forte  *	N/A
111*fcf3ce44SJohn Forte  */
112*fcf3ce44SJohn Forte void
113*fcf3ce44SJohn Forte print_chars(uchar_t *buffer, int size, int fill_flag)
114*fcf3ce44SJohn Forte {
115*fcf3ce44SJohn Forte 
116*fcf3ce44SJohn Forte int i;
117*fcf3ce44SJohn Forte 
118*fcf3ce44SJohn Forte 	for (i = 0; i < size; i++) {
119*fcf3ce44SJohn Forte 		if (buffer[i])
120*fcf3ce44SJohn Forte 			(void) fprintf(stdout, "%c", buffer[i]);
121*fcf3ce44SJohn Forte 		else if (fill_flag)
122*fcf3ce44SJohn Forte 			(void) fprintf(stdout, " ");
123*fcf3ce44SJohn Forte 		else
124*fcf3ce44SJohn Forte 			return;
125*fcf3ce44SJohn Forte 	}
126*fcf3ce44SJohn Forte }
127*fcf3ce44SJohn Forte 
128*fcf3ce44SJohn Forte /*
129*fcf3ce44SJohn Forte  * Name    : memstrstr
130*fcf3ce44SJohn Forte  * Input   : pointer to buf1, pointer to buf2, size of buf1, size of buf2
131*fcf3ce44SJohn Forte  * Returns :
132*fcf3ce44SJohn Forte  *	Pointer to start of contents-of-buf2 in buf1 if it is found
133*fcf3ce44SJohn Forte  *	NULL if buf1 does not contain contents of buf2
134*fcf3ce44SJohn Forte  * Synopsis:
135*fcf3ce44SJohn Forte  * This function works similar to strstr(). The difference is that null
136*fcf3ce44SJohn Forte  * characters in the buffer are treated like any other character. So, buf1
137*fcf3ce44SJohn Forte  * and buf2 can have embedded null characters in them.
138*fcf3ce44SJohn Forte  */
139*fcf3ce44SJohn Forte static char *
140*fcf3ce44SJohn Forte memstrstr(char *s1, char *s2, int size1, int size2)
141*fcf3ce44SJohn Forte {
142*fcf3ce44SJohn Forte 	int count1, count2;
143*fcf3ce44SJohn Forte 	char *s1_ptr, *s2_ptr;
144*fcf3ce44SJohn Forte 
145*fcf3ce44SJohn Forte 	count1 = size1; count2 = size2;
146*fcf3ce44SJohn Forte 	s1_ptr = s1; s2_ptr = s2;
147*fcf3ce44SJohn Forte 
148*fcf3ce44SJohn Forte 	if (size2 == 0)
149*fcf3ce44SJohn Forte 		return (s1);
150*fcf3ce44SJohn Forte 
151*fcf3ce44SJohn Forte 	while (count1--) {
152*fcf3ce44SJohn Forte 		if (*s1_ptr++ == *s2_ptr++) {
153*fcf3ce44SJohn Forte 			if (--count2 == 0)
154*fcf3ce44SJohn Forte 				return (s1_ptr - size2);
155*fcf3ce44SJohn Forte 			continue;
156*fcf3ce44SJohn Forte 		}
157*fcf3ce44SJohn Forte 		count2 = size2;
158*fcf3ce44SJohn Forte 		s2_ptr = s2;
159*fcf3ce44SJohn Forte 	}
160*fcf3ce44SJohn Forte 
161*fcf3ce44SJohn Forte 	return (NULL);
162*fcf3ce44SJohn Forte }
163*fcf3ce44SJohn Forte 
164*fcf3ce44SJohn Forte 
165*fcf3ce44SJohn Forte /*
166*fcf3ce44SJohn Forte  *	Download host bus adapter FCode to all supported cards.
167*fcf3ce44SJohn Forte  *
168*fcf3ce44SJohn Forte  *	Specify a directory that holds the FCode files, or
169*fcf3ce44SJohn Forte  *	it will use the default dir.  Each file is dealt to
170*fcf3ce44SJohn Forte  *	the appropriate function.
171*fcf3ce44SJohn Forte  *
172*fcf3ce44SJohn Forte  *	-p prints current versions only, -d specifies a directory to load
173*fcf3ce44SJohn Forte  */
174*fcf3ce44SJohn Forte static	int
175*fcf3ce44SJohn Forte adm_fcode(int verbose, char *dir)
176*fcf3ce44SJohn Forte {
177*fcf3ce44SJohn Forte 	struct stat statbuf;
178*fcf3ce44SJohn Forte 	struct dirent *dirp;
179*fcf3ce44SJohn Forte 	DIR	*dp;
180*fcf3ce44SJohn Forte 	int	fp;
181*fcf3ce44SJohn Forte 	char	fbuf[BUFSIZ];
182*fcf3ce44SJohn Forte 	char	file[MAXPATHLEN];
183*fcf3ce44SJohn Forte 	int	retval = 0, strfound = 0;
184*fcf3ce44SJohn Forte 	char	manf[BUFSIZ];
185*fcf3ce44SJohn Forte 
186*fcf3ce44SJohn Forte 	/* Find all adapters and print the current FCode version */
187*fcf3ce44SJohn Forte 	if (Options & OPTION_P) {
188*fcf3ce44SJohn Forte 
189*fcf3ce44SJohn Forte /* SOCAL (SBus) adapters are not supported on x86 */
190*fcf3ce44SJohn Forte #ifndef __x86
191*fcf3ce44SJohn Forte 		if (verbose) {
192*fcf3ce44SJohn Forte 			(void) fprintf(stdout,
193*fcf3ce44SJohn Forte 			    MSGSTR(2215, "\n  Searching for FC100/S cards:\n"));
194*fcf3ce44SJohn Forte 		}
195*fcf3ce44SJohn Forte 		retval += fcal_update(Options & PVERBOSE, NULL);
196*fcf3ce44SJohn Forte #endif
197*fcf3ce44SJohn Forte 
198*fcf3ce44SJohn Forte 		if (verbose) {
199*fcf3ce44SJohn Forte 			(void) fprintf(stdout,
200*fcf3ce44SJohn Forte 		MSGSTR(2216, "\n  Searching for FC100/P, FC100/2P cards:\n"));
201*fcf3ce44SJohn Forte 		}
202*fcf3ce44SJohn Forte 		retval += q_qlgc_update(Options & PVERBOSE, NULL);
203*fcf3ce44SJohn Forte 		if (verbose) {
204*fcf3ce44SJohn Forte 			(void) fprintf(stdout,
205*fcf3ce44SJohn Forte 			    MSGSTR(2503, "\n  Searching for Emulex cards:\n"));
206*fcf3ce44SJohn Forte 		}
207*fcf3ce44SJohn Forte 		retval += emulex_update(NULL);
208*fcf3ce44SJohn Forte 
209*fcf3ce44SJohn Forte 	/* Send files to the correct function for loading to the HBA */
210*fcf3ce44SJohn Forte 	} else {
211*fcf3ce44SJohn Forte 
212*fcf3ce44SJohn Forte 		if (!dir) {
213*fcf3ce44SJohn Forte 			(void) fprintf(stdout, MSGSTR(2251,
214*fcf3ce44SJohn Forte 			    "  Location of Fcode not specified.\n"));
215*fcf3ce44SJohn Forte 			return (1);
216*fcf3ce44SJohn Forte 
217*fcf3ce44SJohn Forte 		} else if (verbose) {
218*fcf3ce44SJohn Forte 			(void) fprintf(stdout, MSGSTR(2217,
219*fcf3ce44SJohn Forte 			    "  Using directory %s"), dir);
220*fcf3ce44SJohn Forte 		}
221*fcf3ce44SJohn Forte 		if (lstat(dir, &statbuf) < 0) {
222*fcf3ce44SJohn Forte 			(void) fprintf(stderr, MSGSTR(134,
223*fcf3ce44SJohn Forte 			    "%s: lstat() failed - %s\n"),
224*fcf3ce44SJohn Forte 			    dir, strerror(errno));
225*fcf3ce44SJohn Forte 			return (1);
226*fcf3ce44SJohn Forte 		}
227*fcf3ce44SJohn Forte 		if (S_ISDIR(statbuf.st_mode) == 0) {
228*fcf3ce44SJohn Forte 		(void) fprintf(stderr,
229*fcf3ce44SJohn Forte 		    MSGSTR(2218, "Error: %s is not a directory.\n"), dir);
230*fcf3ce44SJohn Forte 			return (1);
231*fcf3ce44SJohn Forte 		}
232*fcf3ce44SJohn Forte 		if ((dp = opendir(dir)) == NULL) {
233*fcf3ce44SJohn Forte 			(void) fprintf(stderr, MSGSTR(2219,
234*fcf3ce44SJohn Forte 			    "  Error Cannot open directory %s\n"), dir);
235*fcf3ce44SJohn Forte 			return (1);
236*fcf3ce44SJohn Forte 		}
237*fcf3ce44SJohn Forte 
238*fcf3ce44SJohn Forte 		while ((dirp = readdir(dp)) != NULL) {
239*fcf3ce44SJohn Forte 			if (strcmp(dirp->d_name, ".") == 0 ||
240*fcf3ce44SJohn Forte 			    strcmp(dirp->d_name, "..") == 0) {
241*fcf3ce44SJohn Forte 				continue;
242*fcf3ce44SJohn Forte 			}
243*fcf3ce44SJohn Forte 			sprintf(file, "%s/%s", dir, dirp->d_name);
244*fcf3ce44SJohn Forte 
245*fcf3ce44SJohn Forte 			if ((fp = open(file, O_RDONLY)) < 0) {
246*fcf3ce44SJohn Forte 				(void) fprintf(stderr,
247*fcf3ce44SJohn Forte 				    MSGSTR(2220,
248*fcf3ce44SJohn Forte 					"Error: open() failed to open file "
249*fcf3ce44SJohn Forte 					"%s\n"), file);
250*fcf3ce44SJohn Forte 				/*
251*fcf3ce44SJohn Forte 				 * We should just issue an error message and
252*fcf3ce44SJohn Forte 				 * make an attempt on the next file,
253*fcf3ce44SJohn Forte 				 * and the open error is still an error
254*fcf3ce44SJohn Forte 				 * so the retval should be incremented
255*fcf3ce44SJohn Forte 				 */
256*fcf3ce44SJohn Forte 				retval++;
257*fcf3ce44SJohn Forte 				continue;
258*fcf3ce44SJohn Forte 			}
259*fcf3ce44SJohn Forte 			while ((read(fp, fbuf, BUFSIZ)) > 0) {
260*fcf3ce44SJohn Forte 				if (memstrstr(fbuf, "SUNW,socal",
261*fcf3ce44SJohn Forte 					BUFSIZ, strlen("SUNW,socal"))
262*fcf3ce44SJohn Forte 								!= NULL) {
263*fcf3ce44SJohn Forte 					(void) fprintf(stdout, MSGSTR(2221,
264*fcf3ce44SJohn Forte 					    "\n  Using file: %s\n"), file);
265*fcf3ce44SJohn Forte 					retval += fcal_update(
266*fcf3ce44SJohn Forte 						Options & PVERBOSE, file);
267*fcf3ce44SJohn Forte 					strfound++;
268*fcf3ce44SJohn Forte 					break;
269*fcf3ce44SJohn Forte 				} else if ((memstrstr(fbuf, "SUNW,ifp",
270*fcf3ce44SJohn Forte 						BUFSIZ, strlen("SUNW,ifp"))
271*fcf3ce44SJohn Forte 								!= NULL) ||
272*fcf3ce44SJohn Forte 				    (memstrstr(fbuf, "SUNW,qlc",
273*fcf3ce44SJohn Forte 					    BUFSIZ, strlen("SUNW,qlc"))
274*fcf3ce44SJohn Forte 								    != NULL)) {
275*fcf3ce44SJohn Forte 					(void) fprintf(stdout, MSGSTR(2221,
276*fcf3ce44SJohn Forte 					    "\n  Using file: %s\n"), file);
277*fcf3ce44SJohn Forte 					retval += q_qlgc_update(
278*fcf3ce44SJohn Forte 						Options & PVERBOSE, file);
279*fcf3ce44SJohn Forte 					strfound++;
280*fcf3ce44SJohn Forte 					break;
281*fcf3ce44SJohn Forte 				}
282*fcf3ce44SJohn Forte 			}
283*fcf3ce44SJohn Forte 			if (!strfound) {
284*fcf3ce44SJohn Forte 				/* check to see if this is an emulex fcode */
285*fcf3ce44SJohn Forte 				memset(manf, 0, sizeof (manf));
286*fcf3ce44SJohn Forte 				if ((emulex_fcode_reader(fp, "manufacturer",
287*fcf3ce44SJohn Forte 						    manf,
288*fcf3ce44SJohn Forte 						    sizeof (manf)) == 0) &&
289*fcf3ce44SJohn Forte 				    (strncmp(manf, "Emulex", sizeof (manf))
290*fcf3ce44SJohn Forte 									== 0)) {
291*fcf3ce44SJohn Forte 					retval += emulex_update(file);
292*fcf3ce44SJohn Forte 					strfound = 0;
293*fcf3ce44SJohn Forte 				} else {
294*fcf3ce44SJohn Forte 					(void) fprintf(stderr, MSGSTR(2222,
295*fcf3ce44SJohn Forte 					    "\nError: %s is not a valid Fcode "
296*fcf3ce44SJohn Forte 					    "file.\n"), file);
297*fcf3ce44SJohn Forte 					retval++;
298*fcf3ce44SJohn Forte 				}
299*fcf3ce44SJohn Forte 			} else {
300*fcf3ce44SJohn Forte 				strfound = 0;
301*fcf3ce44SJohn Forte 			}
302*fcf3ce44SJohn Forte 			close(fp);
303*fcf3ce44SJohn Forte 		}
304*fcf3ce44SJohn Forte 		closedir(dp);
305*fcf3ce44SJohn Forte 	}
306*fcf3ce44SJohn Forte 	return (retval);
307*fcf3ce44SJohn Forte }
308*fcf3ce44SJohn Forte 
309*fcf3ce44SJohn Forte /*
310*fcf3ce44SJohn Forte  * Definition of getaction() routine which does keyword parsing
311*fcf3ce44SJohn Forte  *
312*fcf3ce44SJohn Forte  * Operation: A character string containing the ascii cmd to be
313*fcf3ce44SJohn Forte  * parsed is passed in along with an array of structures.
314*fcf3ce44SJohn Forte  * The 1st struct element is a recognizable cmd string, the second
315*fcf3ce44SJohn Forte  * is the minimum number of characters from the start of this string
316*fcf3ce44SJohn Forte  * to succeed on a match. For example, { "offline", 3, ONLINE }
317*fcf3ce44SJohn Forte  * will match "off", "offli", "offline", but not "of" nor "offlinebarf"
318*fcf3ce44SJohn Forte  * The third element is the {usually but not necessarily unique}
319*fcf3ce44SJohn Forte  * integer to return on a successful match. Note: compares are cAsE insensitive.
320*fcf3ce44SJohn Forte  *
321*fcf3ce44SJohn Forte  * To change, extend or use this utility, just add or remove appropriate
322*fcf3ce44SJohn Forte  * lines in the structure initializer below and in the #define	s for the
323*fcf3ce44SJohn Forte  * return values.
324*fcf3ce44SJohn Forte  *
325*fcf3ce44SJohn Forte  *                              N O T E
326*fcf3ce44SJohn Forte  * Do not change the minimum number of characters to produce
327*fcf3ce44SJohn Forte  * a match as someone may be building scripts that use this
328*fcf3ce44SJohn Forte  * feature.
329*fcf3ce44SJohn Forte  */
330*fcf3ce44SJohn Forte struct keyword {
331*fcf3ce44SJohn Forte 	char *match;		/* Character String to match against */
332*fcf3ce44SJohn Forte 	int  num_match;		/* Minimum chars to produce a match */
333*fcf3ce44SJohn Forte 	int  ret_code;		/* Value to return on a match */
334*fcf3ce44SJohn Forte };
335*fcf3ce44SJohn Forte 
336*fcf3ce44SJohn Forte static  struct keyword Keywords[] = {
337*fcf3ce44SJohn Forte 	{"display",		2, DISPLAY},
338*fcf3ce44SJohn Forte 	{"download",		3, DOWNLOAD},
339*fcf3ce44SJohn Forte 	{"enclosure_names",	2, ENCLOSURE_NAMES},
340*fcf3ce44SJohn Forte 	{"failover",		3, FAILOVER},
341*fcf3ce44SJohn Forte 	{"fcal_s_download",	4, FCAL_UPDATE},
342*fcf3ce44SJohn Forte 	{"fcode_download",	4, FCODE_UPDATE},
343*fcf3ce44SJohn Forte 	{"inquiry",		2, INQUIRY},
344*fcf3ce44SJohn Forte 	{"insert_device",	3, INSERT_DEVICE},
345*fcf3ce44SJohn Forte 	{"led",			3, LED},
346*fcf3ce44SJohn Forte 	{"led_on",		5, LED_ON},
347*fcf3ce44SJohn Forte 	{"led_off",		5, LED_OFF},
348*fcf3ce44SJohn Forte 	{"led_blink",		5, LED_BLINK},
349*fcf3ce44SJohn Forte 	{"password",		2, PASSWORD},
350*fcf3ce44SJohn Forte 	{"power_on",		8, POWER_ON},
351*fcf3ce44SJohn Forte 	{"power_off",		9, POWER_OFF},
352*fcf3ce44SJohn Forte 	{"probe",		2, PROBE},
353*fcf3ce44SJohn Forte 	{"qlgc_s_download",	4, QLGC_UPDATE},
354*fcf3ce44SJohn Forte 	{"remove_device",	3, REMOVE_DEVICE},
355*fcf3ce44SJohn Forte 	{"reserve",		5, RESERVE},
356*fcf3ce44SJohn Forte 	{"release",		3, RELEASE},
357*fcf3ce44SJohn Forte 	{"set_boot_dev",	5, SET_BOOT_DEV},
358*fcf3ce44SJohn Forte 	{"start",		3, START},
359*fcf3ce44SJohn Forte 	{"stop",		3, STOP},
360*fcf3ce44SJohn Forte 	{"rdls",		2, RDLS},
361*fcf3ce44SJohn Forte 	{"bypass",		3, BYPASS},
362*fcf3ce44SJohn Forte 	{"enable",		3, ENABLE},
363*fcf3ce44SJohn Forte 	{"p_offline",		4, LUX_P_OFFLINE},
364*fcf3ce44SJohn Forte 	{"p_online",		4, LUX_P_ONLINE},
365*fcf3ce44SJohn Forte 	{"forcelip",		2, FORCELIP},
366*fcf3ce44SJohn Forte 	{"dump",		2, DUMP},
367*fcf3ce44SJohn Forte 	{"check_file",		2, CHECK_FILE},
368*fcf3ce44SJohn Forte 	{"dump_map",		2, DUMP_MAP},
369*fcf3ce44SJohn Forte 	{"sysdump",		5, SYSDUMP},
370*fcf3ce44SJohn Forte 	{"port",		4, PORT},
371*fcf3ce44SJohn Forte 	{"external_loopback",	12, EXT_LOOPBACK},
372*fcf3ce44SJohn Forte 	{"internal_loopback",	12, INT_LOOPBACK},
373*fcf3ce44SJohn Forte 	{"no_loopback",		11, NO_LOOPBACK},
374*fcf3ce44SJohn Forte 	{"version",		2, VERSION},
375*fcf3ce44SJohn Forte 	{"create_fabric_device",	2,	CREATE_FAB},
376*fcf3ce44SJohn Forte 	/* hotplugging device operations */
377*fcf3ce44SJohn Forte 	{"online",		2, DEV_ONLINE},
378*fcf3ce44SJohn Forte 	{"offline",		2, DEV_OFFLINE},
379*fcf3ce44SJohn Forte 	{"dev_getstate",	5, DEV_GETSTATE},
380*fcf3ce44SJohn Forte 	{"dev_reset",		5, DEV_RESET},
381*fcf3ce44SJohn Forte 	/* hotplugging bus operations */
382*fcf3ce44SJohn Forte 	{"bus_quiesce",		5, BUS_QUIESCE},
383*fcf3ce44SJohn Forte 	{"bus_unquiesce",	5, BUS_UNQUIESCE},
384*fcf3ce44SJohn Forte 	{"bus_getstate",	5, BUS_GETSTATE},
385*fcf3ce44SJohn Forte 	{"bus_reset",		9, BUS_RESET},
386*fcf3ce44SJohn Forte 	{"bus_resetall",	12, BUS_RESETALL},
387*fcf3ce44SJohn Forte 	/* hotplugging "helper" subcommands */
388*fcf3ce44SJohn Forte 	{ NULL,			0, 0}
389*fcf3ce44SJohn Forte };
390*fcf3ce44SJohn Forte 
391*fcf3ce44SJohn Forte #ifndef	EOK
392*fcf3ce44SJohn Forte static	const	int EOK	= 0;	/* errno.h type success return code */
393*fcf3ce44SJohn Forte #endif
394*fcf3ce44SJohn Forte 
395*fcf3ce44SJohn Forte 
396*fcf3ce44SJohn Forte /*
397*fcf3ce44SJohn Forte  * function getaction() takes a character string, cmd, and
398*fcf3ce44SJohn Forte  * tries to match it against a passed structure of known cmd
399*fcf3ce44SJohn Forte  * character strings. If a match is found, corresponding code
400*fcf3ce44SJohn Forte  * is returned in retval. Status returns as follows:
401*fcf3ce44SJohn Forte  *   EOK	= Match found, look for cmd's code in retval
402*fcf3ce44SJohn Forte  *   EFAULT = One of passed parameters was bad
403*fcf3ce44SJohn Forte  *   EINVAL = cmd did not match any in list
404*fcf3ce44SJohn Forte  */
405*fcf3ce44SJohn Forte static int
406*fcf3ce44SJohn Forte getaction(char *cmd, struct keyword *matches, int  *retval)
407*fcf3ce44SJohn Forte {
408*fcf3ce44SJohn Forte int actlen;
409*fcf3ce44SJohn Forte 
410*fcf3ce44SJohn Forte 	/* Idiot checking of pointers */
411*fcf3ce44SJohn Forte 	if (! cmd || ! matches || ! retval ||
412*fcf3ce44SJohn Forte 	    ! (actlen = strlen(cmd)))	/* Is there an cmd ? */
413*fcf3ce44SJohn Forte 	    return (EFAULT);
414*fcf3ce44SJohn Forte 
415*fcf3ce44SJohn Forte 	    /* Keep looping until NULL match string (end of list) */
416*fcf3ce44SJohn Forte 	    while (matches->match) {
417*fcf3ce44SJohn Forte 		/*
418*fcf3ce44SJohn Forte 		 * Precedence: Make sure target is no longer than
419*fcf3ce44SJohn Forte 		 * current match string
420*fcf3ce44SJohn Forte 		 * and target is at least as long as
421*fcf3ce44SJohn Forte 		 * minimum # match chars,
422*fcf3ce44SJohn Forte 		 * then do case insensitive match
423*fcf3ce44SJohn Forte 		 * based on actual target size
424*fcf3ce44SJohn Forte 		 */
425*fcf3ce44SJohn Forte 		if ((((int)strlen(matches->match)) >= actlen) &&
426*fcf3ce44SJohn Forte 		    (actlen >= matches->num_match) &&
427*fcf3ce44SJohn Forte 		    /* can't get strncasecmp to work on SCR4 */
428*fcf3ce44SJohn Forte 		    /* (strncasecmp(matches->match, cmd, actlen) == 0) */
429*fcf3ce44SJohn Forte 		    (strncmp(matches->match, cmd, actlen) == 0)) {
430*fcf3ce44SJohn Forte 		    *retval = matches->ret_code;	/* Found our match */
431*fcf3ce44SJohn Forte 		    return (EOK);
432*fcf3ce44SJohn Forte 		} else {
433*fcf3ce44SJohn Forte 		    matches++;		/* Next match string/struct */
434*fcf3ce44SJohn Forte 		}
435*fcf3ce44SJohn Forte 	    }	/* End of matches loop */
436*fcf3ce44SJohn Forte 	return (EINVAL);
437*fcf3ce44SJohn Forte 
438*fcf3ce44SJohn Forte }	/* End of getaction() */
439*fcf3ce44SJohn Forte 
440*fcf3ce44SJohn Forte /* main functions. */
441*fcf3ce44SJohn Forte int
442*fcf3ce44SJohn Forte main(int argc, char **argv)
443*fcf3ce44SJohn Forte {
444*fcf3ce44SJohn Forte register int 	c;
445*fcf3ce44SJohn Forte /* getopt varbs */
446*fcf3ce44SJohn Forte extern char *optarg;
447*fcf3ce44SJohn Forte char		*optstring = NULL;
448*fcf3ce44SJohn Forte int		path_index, err = 0;
449*fcf3ce44SJohn Forte int		cmd = 0;		/* Cmd verb from cmd line */
450*fcf3ce44SJohn Forte int		exit_code = 0;		/* exit code for program */
451*fcf3ce44SJohn Forte int		temp_fd;		/* For -f option */
452*fcf3ce44SJohn Forte char		*file_name = NULL;
453*fcf3ce44SJohn Forte int		option_t_input;
454*fcf3ce44SJohn Forte char		*path_phys = NULL;
455*fcf3ce44SJohn Forte int		USE_FCHBA = 0;
456*fcf3ce44SJohn Forte 
457*fcf3ce44SJohn Forte 	whoami = argv[0];
458*fcf3ce44SJohn Forte 
459*fcf3ce44SJohn Forte 
460*fcf3ce44SJohn Forte 	/*
461*fcf3ce44SJohn Forte 	 * Enable locale announcement
462*fcf3ce44SJohn Forte 	 */
463*fcf3ce44SJohn Forte 	i18n_catopen();
464*fcf3ce44SJohn Forte 
465*fcf3ce44SJohn Forte 	while ((c = getopt(argc, argv, "ve"))
466*fcf3ce44SJohn Forte 	    != EOF) {
467*fcf3ce44SJohn Forte 	    switch (c) {
468*fcf3ce44SJohn Forte 		case 'v':
469*fcf3ce44SJohn Forte 		    Options |= PVERBOSE;
470*fcf3ce44SJohn Forte 		    break;
471*fcf3ce44SJohn Forte 		case 'e':
472*fcf3ce44SJohn Forte 		    Options |= EXPERT;
473*fcf3ce44SJohn Forte 		    break;
474*fcf3ce44SJohn Forte 		default:
475*fcf3ce44SJohn Forte 		    /* Note: getopt prints an error if invalid option */
476*fcf3ce44SJohn Forte 		    USEAGE()
477*fcf3ce44SJohn Forte 		    exit(-1);
478*fcf3ce44SJohn Forte 	    } /* End of switch(c) */
479*fcf3ce44SJohn Forte 	}
480*fcf3ce44SJohn Forte 	setbuf(stdout, NULL);	/* set stdout unbuffered. */
481*fcf3ce44SJohn Forte 
482*fcf3ce44SJohn Forte 	/*
483*fcf3ce44SJohn Forte 	 * Build any i18n global variables
484*fcf3ce44SJohn Forte 	 */
485*fcf3ce44SJohn Forte 	dtype[0] = MSGSTR(2192, "Disk device");
486*fcf3ce44SJohn Forte 	dtype[1] = MSGSTR(2193, "Tape device");
487*fcf3ce44SJohn Forte 	dtype[2] = MSGSTR(2194, "Printer device");
488*fcf3ce44SJohn Forte 	dtype[3] = MSGSTR(2195, "Processor device");
489*fcf3ce44SJohn Forte 	dtype[4] = MSGSTR(2196, "WORM device");
490*fcf3ce44SJohn Forte 	dtype[5] = MSGSTR(2197, "CD-ROM device");
491*fcf3ce44SJohn Forte 	dtype[6] = MSGSTR(2198, "Scanner device");
492*fcf3ce44SJohn Forte 	dtype[7] = MSGSTR(2199, "Optical memory device");
493*fcf3ce44SJohn Forte 	dtype[8] = MSGSTR(2200, "Medium changer device");
494*fcf3ce44SJohn Forte 	dtype[9] = MSGSTR(2201, "Communications device");
495*fcf3ce44SJohn Forte 	dtype[10] = MSGSTR(107, "Graphic arts device");
496*fcf3ce44SJohn Forte 	dtype[11] = MSGSTR(107, "Graphic arts device");
497*fcf3ce44SJohn Forte 	dtype[12] = MSGSTR(2202, "Array controller device");
498*fcf3ce44SJohn Forte 	dtype[13] = MSGSTR(2203, "SES device");
499*fcf3ce44SJohn Forte 	dtype[14] = MSGSTR(71, "Reserved");
500*fcf3ce44SJohn Forte 	dtype[15] = MSGSTR(71, "Reserved");
501*fcf3ce44SJohn Forte 
502*fcf3ce44SJohn Forte 
503*fcf3ce44SJohn Forte 
504*fcf3ce44SJohn Forte 	/*
505*fcf3ce44SJohn Forte 	 * Get subcommand.
506*fcf3ce44SJohn Forte 	 */
507*fcf3ce44SJohn Forte 	if ((getaction(argv[optind], Keywords, &cmd)) == EOK) {
508*fcf3ce44SJohn Forte 		optind++;
509*fcf3ce44SJohn Forte 		if ((cmd != PROBE) && (cmd != FCAL_UPDATE) &&
510*fcf3ce44SJohn Forte 		(cmd != QLGC_UPDATE) && (cmd != FCODE_UPDATE) &&
511*fcf3ce44SJohn Forte 		(cmd != INSERT_DEVICE) && (cmd != SYSDUMP) && (cmd != AU) &&
512*fcf3ce44SJohn Forte 		(cmd != PORT) && (cmd != CREATE_FAB) && (optind >= argc)) {
513*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
514*fcf3ce44SJohn Forte 			MSGSTR(2204,
515*fcf3ce44SJohn Forte 			"Error: enclosure or pathname not specified.\n"));
516*fcf3ce44SJohn Forte 			USEAGE();
517*fcf3ce44SJohn Forte 			exit(-1);
518*fcf3ce44SJohn Forte 		}
519*fcf3ce44SJohn Forte 	} else {
520*fcf3ce44SJohn Forte 		(void) fprintf(stderr,
521*fcf3ce44SJohn Forte 		MSGSTR(2205, "%s: subcommand not specified.\n"),
522*fcf3ce44SJohn Forte 		whoami);
523*fcf3ce44SJohn Forte 		USEAGE();
524*fcf3ce44SJohn Forte 		exit(-1);
525*fcf3ce44SJohn Forte 	}
526*fcf3ce44SJohn Forte 
527*fcf3ce44SJohn Forte 	/* Extract & Save subcommand options */
528*fcf3ce44SJohn Forte 	if ((cmd == ENABLE) || (cmd == BYPASS)) {
529*fcf3ce44SJohn Forte 		optstring = "Ffrab";
530*fcf3ce44SJohn Forte 	} else if (cmd == FCODE_UPDATE) {
531*fcf3ce44SJohn Forte 		optstring = "pd:";
532*fcf3ce44SJohn Forte 	} else if (cmd == REMOVE_DEVICE) {
533*fcf3ce44SJohn Forte 		optstring = "F";
534*fcf3ce44SJohn Forte 	} else if (cmd == CREATE_FAB) {
535*fcf3ce44SJohn Forte 		optstring = "f:";
536*fcf3ce44SJohn Forte 	} else {
537*fcf3ce44SJohn Forte 		optstring = "Fryszabepcdlvt:f:w:";
538*fcf3ce44SJohn Forte 	}
539*fcf3ce44SJohn Forte 	while ((c = getopt(argc, argv, optstring)) != EOF) {
540*fcf3ce44SJohn Forte 	    switch (c) {
541*fcf3ce44SJohn Forte 		case 'a':
542*fcf3ce44SJohn Forte 			Options |= OPTION_A;
543*fcf3ce44SJohn Forte 			break;
544*fcf3ce44SJohn Forte 	    case 'b':
545*fcf3ce44SJohn Forte 			Options |= OPTION_B;
546*fcf3ce44SJohn Forte 			break;
547*fcf3ce44SJohn Forte 		case 'c':
548*fcf3ce44SJohn Forte 			Options |= OPTION_C;
549*fcf3ce44SJohn Forte 			break;
550*fcf3ce44SJohn Forte 		case 'd':
551*fcf3ce44SJohn Forte 			Options |= OPTION_D;
552*fcf3ce44SJohn Forte 			if (cmd == FCODE_UPDATE) {
553*fcf3ce44SJohn Forte 			    file_name = optarg;
554*fcf3ce44SJohn Forte 			}
555*fcf3ce44SJohn Forte 			break;
556*fcf3ce44SJohn Forte 		case 'e':
557*fcf3ce44SJohn Forte 			Options |= OPTION_E;
558*fcf3ce44SJohn Forte 			break;
559*fcf3ce44SJohn Forte 		case 'f':
560*fcf3ce44SJohn Forte 			Options |= OPTION_F;
561*fcf3ce44SJohn Forte 			if (!((cmd == ENABLE) || (cmd == BYPASS))) {
562*fcf3ce44SJohn Forte 				file_name = optarg;
563*fcf3ce44SJohn Forte 			}
564*fcf3ce44SJohn Forte 			break;
565*fcf3ce44SJohn Forte 		case 'F':
566*fcf3ce44SJohn Forte 			Options |= OPTION_CAPF;
567*fcf3ce44SJohn Forte 			break;
568*fcf3ce44SJohn Forte 		case 'l':
569*fcf3ce44SJohn Forte 		    Options |= OPTION_L;
570*fcf3ce44SJohn Forte 		    break;
571*fcf3ce44SJohn Forte 		case 'p':
572*fcf3ce44SJohn Forte 		    Options |= OPTION_P;
573*fcf3ce44SJohn Forte 		    break;
574*fcf3ce44SJohn Forte 		case 'r':
575*fcf3ce44SJohn Forte 		    Options |= OPTION_R;
576*fcf3ce44SJohn Forte 		    break;
577*fcf3ce44SJohn Forte 		case 's':
578*fcf3ce44SJohn Forte 		    Options |= SAVE;
579*fcf3ce44SJohn Forte 		    break;
580*fcf3ce44SJohn Forte 		case 't':
581*fcf3ce44SJohn Forte 		    Options |= OPTION_T;
582*fcf3ce44SJohn Forte 		    option_t_input = atoi(optarg);
583*fcf3ce44SJohn Forte 		    break;
584*fcf3ce44SJohn Forte 		case 'v':
585*fcf3ce44SJohn Forte 		    Options |= OPTION_V;
586*fcf3ce44SJohn Forte 		    break;
587*fcf3ce44SJohn Forte 		case 'z':
588*fcf3ce44SJohn Forte 		    Options |= OPTION_Z;
589*fcf3ce44SJohn Forte 		    break;
590*fcf3ce44SJohn Forte 		case 'y':
591*fcf3ce44SJohn Forte 		    Options |= OPTION_Y;
592*fcf3ce44SJohn Forte 		    break;
593*fcf3ce44SJohn Forte 		default:
594*fcf3ce44SJohn Forte 		    /* Note: getopt prints an error if invalid option */
595*fcf3ce44SJohn Forte 		    USEAGE()
596*fcf3ce44SJohn Forte 		    exit(-1);
597*fcf3ce44SJohn Forte 	    } /* End of switch(c) */
598*fcf3ce44SJohn Forte 	}
599*fcf3ce44SJohn Forte 	if ((cmd != PROBE) && (cmd != FCAL_UPDATE) &&
600*fcf3ce44SJohn Forte 	    (cmd != QLGC_UPDATE) && (cmd != FCODE_UPDATE) &&
601*fcf3ce44SJohn Forte 	    (cmd != INSERT_DEVICE) && (cmd != SYSDUMP) &&
602*fcf3ce44SJohn Forte 	    (cmd != AU) && (cmd != PORT) &&
603*fcf3ce44SJohn Forte 	    (cmd != CREATE_FAB) && (optind >= argc)) {
604*fcf3ce44SJohn Forte 	    (void) fprintf(stderr,
605*fcf3ce44SJohn Forte 		MSGSTR(2206,
606*fcf3ce44SJohn Forte 		"Error: enclosure or pathname not specified.\n"));
607*fcf3ce44SJohn Forte 	    USEAGE();
608*fcf3ce44SJohn Forte 	    exit(-1);
609*fcf3ce44SJohn Forte 	}
610*fcf3ce44SJohn Forte 	path_index = optind;
611*fcf3ce44SJohn Forte 
612*fcf3ce44SJohn Forte 	/*
613*fcf3ce44SJohn Forte 	 * Check if the file supplied with the -f option is valid
614*fcf3ce44SJohn Forte 	 * Some sub commands (bypass for example) use the -f option
615*fcf3ce44SJohn Forte 	 * for other reasons. In such cases, "file_name" should be
616*fcf3ce44SJohn Forte 	 * NULL.
617*fcf3ce44SJohn Forte 	 */
618*fcf3ce44SJohn Forte 	if ((file_name != NULL) && (Options & OPTION_F)) {
619*fcf3ce44SJohn Forte 		if ((temp_fd = open(file_name, O_RDONLY)) == -1) {
620*fcf3ce44SJohn Forte 			perror(file_name);
621*fcf3ce44SJohn Forte 			exit(-1);
622*fcf3ce44SJohn Forte 		} else {
623*fcf3ce44SJohn Forte 			close(temp_fd);
624*fcf3ce44SJohn Forte 		}
625*fcf3ce44SJohn Forte 	}
626*fcf3ce44SJohn Forte 
627*fcf3ce44SJohn Forte 	/* Determine which mode to operate in (FC-HBA or original) */
628*fcf3ce44SJohn Forte 	USE_FCHBA = use_fchba();
629*fcf3ce44SJohn Forte 
630*fcf3ce44SJohn Forte 	switch (cmd)	{
631*fcf3ce44SJohn Forte 	    case	DISPLAY:
632*fcf3ce44SJohn Forte 		if (Options &
633*fcf3ce44SJohn Forte 		    ~(PVERBOSE | OPTION_A | OPTION_Z | OPTION_R |
634*fcf3ce44SJohn Forte 		    OPTION_P | OPTION_V | OPTION_L | OPTION_E | OPTION_T)) {
635*fcf3ce44SJohn Forte 		    USEAGE();
636*fcf3ce44SJohn Forte 		    exit(-1);
637*fcf3ce44SJohn Forte 		}
638*fcf3ce44SJohn Forte 		/* Display object(s) */
639*fcf3ce44SJohn Forte 		if (USE_FCHBA) {
640*fcf3ce44SJohn Forte 		    exit_code = fchba_display_config(&argv[path_index],
641*fcf3ce44SJohn Forte 			    option_t_input, argc - path_index);
642*fcf3ce44SJohn Forte 		} else {
643*fcf3ce44SJohn Forte 		    exit_code = adm_display_config(&argv[path_index]);
644*fcf3ce44SJohn Forte 		}
645*fcf3ce44SJohn Forte 		break;
646*fcf3ce44SJohn Forte 
647*fcf3ce44SJohn Forte 	    case	DOWNLOAD:
648*fcf3ce44SJohn Forte 		    if (Options &
649*fcf3ce44SJohn Forte 			~(PVERBOSE | OPTION_F | SAVE)) {
650*fcf3ce44SJohn Forte 			USEAGE();
651*fcf3ce44SJohn Forte 			exit(-1);
652*fcf3ce44SJohn Forte 		    }
653*fcf3ce44SJohn Forte 		    adm_download(&argv[path_index], file_name);
654*fcf3ce44SJohn Forte 		    break;
655*fcf3ce44SJohn Forte 
656*fcf3ce44SJohn Forte 	    case	ENCLOSURE_NAMES:
657*fcf3ce44SJohn Forte 		    if (Options & ~PVERBOSE) {
658*fcf3ce44SJohn Forte 			USEAGE();
659*fcf3ce44SJohn Forte 			exit(-1);
660*fcf3ce44SJohn Forte 		    }
661*fcf3ce44SJohn Forte 		    up_encl_name(&argv[path_index], argc);
662*fcf3ce44SJohn Forte 		    break;
663*fcf3ce44SJohn Forte 
664*fcf3ce44SJohn Forte 	    case	FAILOVER:
665*fcf3ce44SJohn Forte 		    if (Options & ~PVERBOSE) {
666*fcf3ce44SJohn Forte 			USEAGE();
667*fcf3ce44SJohn Forte 			exit(-1);
668*fcf3ce44SJohn Forte 		    }
669*fcf3ce44SJohn Forte 		    adm_failover(&argv[path_index]);
670*fcf3ce44SJohn Forte 		    break;
671*fcf3ce44SJohn Forte 
672*fcf3ce44SJohn Forte 	    case	INQUIRY:
673*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE)) {
674*fcf3ce44SJohn Forte 			USEAGE();
675*fcf3ce44SJohn Forte 			exit(-1);
676*fcf3ce44SJohn Forte 		}
677*fcf3ce44SJohn Forte 		if (USE_FCHBA) {
678*fcf3ce44SJohn Forte 		    exit_code = fchba_inquiry(&argv[path_index]);
679*fcf3ce44SJohn Forte 		} else {
680*fcf3ce44SJohn Forte 		    exit_code = adm_inquiry(&argv[path_index]);
681*fcf3ce44SJohn Forte 		}
682*fcf3ce44SJohn Forte 		break;
683*fcf3ce44SJohn Forte 
684*fcf3ce44SJohn Forte 	    case	PROBE:
685*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE | OPTION_P)) {
686*fcf3ce44SJohn Forte 			USEAGE();
687*fcf3ce44SJohn Forte 			exit(-1);
688*fcf3ce44SJohn Forte 		}
689*fcf3ce44SJohn Forte 		/*
690*fcf3ce44SJohn Forte 		 * A special check just in case someone entered
691*fcf3ce44SJohn Forte 		 * any characters after the -p or the probe.
692*fcf3ce44SJohn Forte 		 *
693*fcf3ce44SJohn Forte 		 * (I know, a nit.)
694*fcf3ce44SJohn Forte 		 */
695*fcf3ce44SJohn Forte 		if (((Options & PVERBOSE) && (Options & OPTION_P) &&
696*fcf3ce44SJohn Forte 			(argc != 4)) ||
697*fcf3ce44SJohn Forte 			(!(Options & PVERBOSE) && (Options & OPTION_P) &&
698*fcf3ce44SJohn Forte 			(argc != 3)) ||
699*fcf3ce44SJohn Forte 			((Options & PVERBOSE) && (!(Options & OPTION_P)) &&
700*fcf3ce44SJohn Forte 			(argc != 3)) ||
701*fcf3ce44SJohn Forte 			(!(Options & PVERBOSE) && (!(Options & OPTION_P)) &&
702*fcf3ce44SJohn Forte 			(argc != 2))) {
703*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
704*fcf3ce44SJohn Forte 			MSGSTR(114, "Error: Incorrect number of arguments.\n"));
705*fcf3ce44SJohn Forte 			(void) fprintf(stderr,  MSGSTR(2208,
706*fcf3ce44SJohn Forte 			"Usage: %s [-v] subcommand [option]\n"), whoami);
707*fcf3ce44SJohn Forte 			exit(-1);
708*fcf3ce44SJohn Forte 		}
709*fcf3ce44SJohn Forte 		if (USE_FCHBA) {
710*fcf3ce44SJohn Forte 		    exit_code = fchba_non_encl_probe();
711*fcf3ce44SJohn Forte 		} else {
712*fcf3ce44SJohn Forte 		    pho_probe();
713*fcf3ce44SJohn Forte 		    non_encl_probe();
714*fcf3ce44SJohn Forte 		}
715*fcf3ce44SJohn Forte 		break;
716*fcf3ce44SJohn Forte 
717*fcf3ce44SJohn Forte 	    case	FCODE_UPDATE:	/* Update Fcode in all cards */
718*fcf3ce44SJohn Forte 			if ((Options & ~(PVERBOSE)) &
719*fcf3ce44SJohn Forte 			    ~(OPTION_P | OPTION_D) || argv[path_index]) {
720*fcf3ce44SJohn Forte 				USEAGE();
721*fcf3ce44SJohn Forte 				exit(-1);
722*fcf3ce44SJohn Forte 			}
723*fcf3ce44SJohn Forte 			if (!((Options & (OPTION_P | OPTION_D)) &&
724*fcf3ce44SJohn Forte 			    !((Options & OPTION_P) && (Options & OPTION_D)))) {
725*fcf3ce44SJohn Forte 				USEAGE();
726*fcf3ce44SJohn Forte 				exit(-1);
727*fcf3ce44SJohn Forte 			}
728*fcf3ce44SJohn Forte 			if (adm_fcode(Options & PVERBOSE, file_name) != 0) {
729*fcf3ce44SJohn Forte 				exit(-1);
730*fcf3ce44SJohn Forte 			}
731*fcf3ce44SJohn Forte 			break;
732*fcf3ce44SJohn Forte 
733*fcf3ce44SJohn Forte 	    case	QLGC_UPDATE:	/* Update Fcode in PCI HBA card(s) */
734*fcf3ce44SJohn Forte 			if ((Options & ~(PVERBOSE)) & ~(OPTION_F) ||
735*fcf3ce44SJohn Forte 			    argv[path_index]) {
736*fcf3ce44SJohn Forte 				USEAGE();
737*fcf3ce44SJohn Forte 				exit(-1);
738*fcf3ce44SJohn Forte 			}
739*fcf3ce44SJohn Forte 			if (q_qlgc_update(Options & PVERBOSE, file_name) != 0) {
740*fcf3ce44SJohn Forte 				exit(-1);
741*fcf3ce44SJohn Forte 			}
742*fcf3ce44SJohn Forte 			break;
743*fcf3ce44SJohn Forte 
744*fcf3ce44SJohn Forte 	    case	FCAL_UPDATE:	/* Update Fcode in Sbus soc+ card */
745*fcf3ce44SJohn Forte 			if ((Options & ~(PVERBOSE)) & ~(OPTION_F) ||
746*fcf3ce44SJohn Forte 			    argv[path_index]) {
747*fcf3ce44SJohn Forte 				USEAGE();
748*fcf3ce44SJohn Forte 				exit(-1);
749*fcf3ce44SJohn Forte 			}
750*fcf3ce44SJohn Forte 			exit_code = fcal_update(Options & PVERBOSE, file_name);
751*fcf3ce44SJohn Forte 			break;
752*fcf3ce44SJohn Forte 
753*fcf3ce44SJohn Forte 	    case	SET_BOOT_DEV:   /* Set boot-device variable in nvram */
754*fcf3ce44SJohn Forte 			exit_code = setboot(Options & OPTION_Y,
755*fcf3ce44SJohn Forte 				Options & PVERBOSE, argv[path_index]);
756*fcf3ce44SJohn Forte 		break;
757*fcf3ce44SJohn Forte 
758*fcf3ce44SJohn Forte 	    case	LED:
759*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE)) {
760*fcf3ce44SJohn Forte 			USEAGE();
761*fcf3ce44SJohn Forte 			exit(-1);
762*fcf3ce44SJohn Forte 		}
763*fcf3ce44SJohn Forte 		adm_led(&argv[path_index], L_LED_STATUS);
764*fcf3ce44SJohn Forte 		break;
765*fcf3ce44SJohn Forte 	    case	LED_ON:
766*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE)) {
767*fcf3ce44SJohn Forte 			USEAGE();
768*fcf3ce44SJohn Forte 			exit(-1);
769*fcf3ce44SJohn Forte 		}
770*fcf3ce44SJohn Forte 		adm_led(&argv[path_index], L_LED_ON);
771*fcf3ce44SJohn Forte 		break;
772*fcf3ce44SJohn Forte 	    case	LED_OFF:
773*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE)) {
774*fcf3ce44SJohn Forte 			USEAGE();
775*fcf3ce44SJohn Forte 			exit(-1);
776*fcf3ce44SJohn Forte 		}
777*fcf3ce44SJohn Forte 		adm_led(&argv[path_index], L_LED_OFF);
778*fcf3ce44SJohn Forte 		break;
779*fcf3ce44SJohn Forte 	    case	LED_BLINK:
780*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE)) {
781*fcf3ce44SJohn Forte 			USEAGE();
782*fcf3ce44SJohn Forte 			exit(-1);
783*fcf3ce44SJohn Forte 		}
784*fcf3ce44SJohn Forte 		adm_led(&argv[path_index], L_LED_RQST_IDENTIFY);
785*fcf3ce44SJohn Forte 		break;
786*fcf3ce44SJohn Forte 	    case	PASSWORD:
787*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE))  {
788*fcf3ce44SJohn Forte 			USEAGE();
789*fcf3ce44SJohn Forte 			exit(-1);
790*fcf3ce44SJohn Forte 		}
791*fcf3ce44SJohn Forte 		up_password(&argv[path_index]);
792*fcf3ce44SJohn Forte 		break;
793*fcf3ce44SJohn Forte 
794*fcf3ce44SJohn Forte 	    case	RESERVE:
795*fcf3ce44SJohn Forte 
796*fcf3ce44SJohn Forte 		if (Options & (~PVERBOSE)) {
797*fcf3ce44SJohn Forte 			USEAGE();
798*fcf3ce44SJohn Forte 			exit(-1);
799*fcf3ce44SJohn Forte 		}
800*fcf3ce44SJohn Forte 		VERBPRINT(MSGSTR(2209,
801*fcf3ce44SJohn Forte 			"  Reserving: \n %s\n"), argv[path_index]);
802*fcf3ce44SJohn Forte 		if (USE_FCHBA) {
803*fcf3ce44SJohn Forte 		    struct stat sbuf;
804*fcf3ce44SJohn Forte 		    /* Just stat the argument and make sure it exists */
805*fcf3ce44SJohn Forte 		    if (stat(argv[path_index], &sbuf) < 0) {
806*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "%s: ", whoami);
807*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
808*fcf3ce44SJohn Forte 				MSGSTR(112, "Error: Invalid pathname (%s)"),
809*fcf3ce44SJohn Forte 				argv[path_index]);
810*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "\n");
811*fcf3ce44SJohn Forte 			exit(-1);
812*fcf3ce44SJohn Forte 		    }
813*fcf3ce44SJohn Forte 		    path_phys = argv[path_index];
814*fcf3ce44SJohn Forte 		    if (err = scsi_reserve(path_phys)) {
815*fcf3ce44SJohn Forte 			(void) print_errString(err, argv[path_index]);
816*fcf3ce44SJohn Forte 			exit(-1);
817*fcf3ce44SJohn Forte 		    }
818*fcf3ce44SJohn Forte 		} else {
819*fcf3ce44SJohn Forte 		    exit_code = adm_reserve(argv[path_index]);
820*fcf3ce44SJohn Forte 		}
821*fcf3ce44SJohn Forte 		break;
822*fcf3ce44SJohn Forte 
823*fcf3ce44SJohn Forte 	    case	RELEASE:
824*fcf3ce44SJohn Forte 		if (Options & (~PVERBOSE)) {
825*fcf3ce44SJohn Forte 			USEAGE();
826*fcf3ce44SJohn Forte 			exit(-1);
827*fcf3ce44SJohn Forte 		}
828*fcf3ce44SJohn Forte 		VERBPRINT(MSGSTR(2210, "  Canceling Reservation for:\n %s\n"),
829*fcf3ce44SJohn Forte 		    argv[path_index]);
830*fcf3ce44SJohn Forte 		if (USE_FCHBA) {
831*fcf3ce44SJohn Forte 		    struct stat sbuf;
832*fcf3ce44SJohn Forte 		    /* Just stat the argument and make sure it exists */
833*fcf3ce44SJohn Forte 		    if (stat(argv[path_index], &sbuf) < 0) {
834*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "%s: ", whoami);
835*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
836*fcf3ce44SJohn Forte 				MSGSTR(112, "Error: Invalid pathname (%s)"),
837*fcf3ce44SJohn Forte 				argv[path_index]);
838*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "\n");
839*fcf3ce44SJohn Forte 			exit(-1);
840*fcf3ce44SJohn Forte 		    }
841*fcf3ce44SJohn Forte 		    path_phys = argv[path_index];
842*fcf3ce44SJohn Forte 		    if (err = scsi_release(path_phys)) {
843*fcf3ce44SJohn Forte 			(void) print_errString(err, argv[path_index]);
844*fcf3ce44SJohn Forte 			exit(-1);
845*fcf3ce44SJohn Forte 		    }
846*fcf3ce44SJohn Forte 		} else {
847*fcf3ce44SJohn Forte 		    exit_code = adm_release(argv[path_index]);
848*fcf3ce44SJohn Forte 		}
849*fcf3ce44SJohn Forte 		break;
850*fcf3ce44SJohn Forte 
851*fcf3ce44SJohn Forte 	    case	START:
852*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE)) {
853*fcf3ce44SJohn Forte 			USEAGE();
854*fcf3ce44SJohn Forte 			exit(-1);
855*fcf3ce44SJohn Forte 		}
856*fcf3ce44SJohn Forte 		exit_code = adm_start(&argv[path_index]);
857*fcf3ce44SJohn Forte 		break;
858*fcf3ce44SJohn Forte 
859*fcf3ce44SJohn Forte 	    case	STOP:
860*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE)) {
861*fcf3ce44SJohn Forte 			USEAGE();
862*fcf3ce44SJohn Forte 			exit(-1);
863*fcf3ce44SJohn Forte 		}
864*fcf3ce44SJohn Forte 		exit_code = adm_stop(&argv[path_index]);
865*fcf3ce44SJohn Forte 		break;
866*fcf3ce44SJohn Forte 
867*fcf3ce44SJohn Forte 	    case	POWER_OFF:
868*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE | OPTION_CAPF)) {
869*fcf3ce44SJohn Forte 			USEAGE();
870*fcf3ce44SJohn Forte 			exit(-1);
871*fcf3ce44SJohn Forte 		}
872*fcf3ce44SJohn Forte 		exit_code = adm_power_off(&argv[path_index], 1);
873*fcf3ce44SJohn Forte 		break;
874*fcf3ce44SJohn Forte 
875*fcf3ce44SJohn Forte 	    case	POWER_ON:
876*fcf3ce44SJohn Forte 		if (Options & (~PVERBOSE)) {
877*fcf3ce44SJohn Forte 			USEAGE();
878*fcf3ce44SJohn Forte 			exit(-1);
879*fcf3ce44SJohn Forte 		}
880*fcf3ce44SJohn Forte 		exit_code = adm_power_off(&argv[path_index], 0);
881*fcf3ce44SJohn Forte 		break;
882*fcf3ce44SJohn Forte 
883*fcf3ce44SJohn Forte 	/*
884*fcf3ce44SJohn Forte 	 * EXPERT commands.
885*fcf3ce44SJohn Forte 	 */
886*fcf3ce44SJohn Forte 
887*fcf3ce44SJohn Forte 	    case	FORCELIP:
888*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
889*fcf3ce44SJohn Forte 			E_USEAGE();
890*fcf3ce44SJohn Forte 			exit(-1);
891*fcf3ce44SJohn Forte 		}
892*fcf3ce44SJohn Forte 		exit_code = adm_forcelip(&argv[path_index]);
893*fcf3ce44SJohn Forte 		break;
894*fcf3ce44SJohn Forte 
895*fcf3ce44SJohn Forte 	    case	BYPASS:
896*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT |
897*fcf3ce44SJohn Forte 			OPTION_CAPF | OPTION_A | OPTION_B | OPTION_F |
898*fcf3ce44SJohn Forte 			OPTION_R)) || !(Options & (OPTION_A | OPTION_B)) ||
899*fcf3ce44SJohn Forte 			((Options & OPTION_A) && (Options & OPTION_B))) {
900*fcf3ce44SJohn Forte 			E_USEAGE();
901*fcf3ce44SJohn Forte 			exit(-1);
902*fcf3ce44SJohn Forte 		}
903*fcf3ce44SJohn Forte 		adm_bypass_enable(&argv[path_index], 1);
904*fcf3ce44SJohn Forte 		break;
905*fcf3ce44SJohn Forte 
906*fcf3ce44SJohn Forte 	    case	ENABLE:
907*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT |
908*fcf3ce44SJohn Forte 			OPTION_CAPF | OPTION_A | OPTION_B | OPTION_F |
909*fcf3ce44SJohn Forte 			OPTION_R)) || !(Options & (OPTION_A | OPTION_B)) ||
910*fcf3ce44SJohn Forte 			((Options & OPTION_A) && (Options & OPTION_B))) {
911*fcf3ce44SJohn Forte 			E_USEAGE();
912*fcf3ce44SJohn Forte 			exit(-1);
913*fcf3ce44SJohn Forte 		}
914*fcf3ce44SJohn Forte 		adm_bypass_enable(&argv[path_index], 0);
915*fcf3ce44SJohn Forte 		break;
916*fcf3ce44SJohn Forte 	    case	LUX_P_OFFLINE:	/* Offline a port */
917*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
918*fcf3ce44SJohn Forte 			E_USEAGE();
919*fcf3ce44SJohn Forte 			exit(-1);
920*fcf3ce44SJohn Forte 		}
921*fcf3ce44SJohn Forte 		exit_code = adm_port_offline_online(&argv[path_index],
922*fcf3ce44SJohn Forte 		    LUX_P_OFFLINE);
923*fcf3ce44SJohn Forte 		break;
924*fcf3ce44SJohn Forte 
925*fcf3ce44SJohn Forte 	    case	LUX_P_ONLINE:	/* Online a port */
926*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
927*fcf3ce44SJohn Forte 			E_USEAGE();
928*fcf3ce44SJohn Forte 			exit(-1);
929*fcf3ce44SJohn Forte 		}
930*fcf3ce44SJohn Forte 		exit_code = adm_port_offline_online(&argv[path_index],
931*fcf3ce44SJohn Forte 		    LUX_P_ONLINE);
932*fcf3ce44SJohn Forte 		break;
933*fcf3ce44SJohn Forte 
934*fcf3ce44SJohn Forte 	    case	RDLS:
935*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
936*fcf3ce44SJohn Forte 			E_USEAGE();
937*fcf3ce44SJohn Forte 			exit(-1);
938*fcf3ce44SJohn Forte 		}
939*fcf3ce44SJohn Forte 		if (USE_FCHBA) {
940*fcf3ce44SJohn Forte 		    exit_code = fchba_display_link_status(&argv[path_index]);
941*fcf3ce44SJohn Forte 		} else {
942*fcf3ce44SJohn Forte 		    display_link_status(&argv[path_index]);
943*fcf3ce44SJohn Forte 		}
944*fcf3ce44SJohn Forte 		break;
945*fcf3ce44SJohn Forte 
946*fcf3ce44SJohn Forte 	    case	CREATE_FAB:
947*fcf3ce44SJohn Forte 		if (!(Options & (EXPERT | OPTION_F)) ||
948*fcf3ce44SJohn Forte 			(Options & ~(PVERBOSE | EXPERT | OPTION_F))) {
949*fcf3ce44SJohn Forte 			E_USEAGE();
950*fcf3ce44SJohn Forte 			exit(-1);
951*fcf3ce44SJohn Forte 		}
952*fcf3ce44SJohn Forte 		if (read_repos_file(file_name) != 0) {
953*fcf3ce44SJohn Forte 			exit(-1);
954*fcf3ce44SJohn Forte 		}
955*fcf3ce44SJohn Forte 		break;
956*fcf3ce44SJohn Forte 
957*fcf3ce44SJohn Forte 	/*
958*fcf3ce44SJohn Forte 	 * Undocumented commands.
959*fcf3ce44SJohn Forte 	 */
960*fcf3ce44SJohn Forte 
961*fcf3ce44SJohn Forte 	    case	CHECK_FILE:	/* Undocumented Cmd */
962*fcf3ce44SJohn Forte 		if (Options & ~(PVERBOSE)) {
963*fcf3ce44SJohn Forte 			USEAGE();
964*fcf3ce44SJohn Forte 			exit(-1);
965*fcf3ce44SJohn Forte 		}
966*fcf3ce44SJohn Forte 		exit_code = adm_check_file(&argv[path_index],
967*fcf3ce44SJohn Forte 		    (Options & PVERBOSE));
968*fcf3ce44SJohn Forte 		break;
969*fcf3ce44SJohn Forte 
970*fcf3ce44SJohn Forte 	    case	DUMP:		/* Undocumented Cmd */
971*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
972*fcf3ce44SJohn Forte 			USEAGE();
973*fcf3ce44SJohn Forte 			exit(-1);
974*fcf3ce44SJohn Forte 		}
975*fcf3ce44SJohn Forte 		dump(&argv[path_index]);
976*fcf3ce44SJohn Forte 		break;
977*fcf3ce44SJohn Forte 
978*fcf3ce44SJohn Forte 	    case	DUMP_MAP:	/* Undocumented Cmd */
979*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
980*fcf3ce44SJohn Forte 			USEAGE();
981*fcf3ce44SJohn Forte 			exit(-1);
982*fcf3ce44SJohn Forte 		}
983*fcf3ce44SJohn Forte 		if (USE_FCHBA) {
984*fcf3ce44SJohn Forte 		    exit_code = fchba_dump_map(&argv[path_index]);
985*fcf3ce44SJohn Forte 		} else {
986*fcf3ce44SJohn Forte 		    dump_map(&argv[path_index]);
987*fcf3ce44SJohn Forte 		}
988*fcf3ce44SJohn Forte 		break;
989*fcf3ce44SJohn Forte 
990*fcf3ce44SJohn Forte 	    case	SYSDUMP:
991*fcf3ce44SJohn Forte 			if (Options & ~(PVERBOSE)) {
992*fcf3ce44SJohn Forte 			USEAGE();
993*fcf3ce44SJohn Forte 			exit(-1);
994*fcf3ce44SJohn Forte 		}
995*fcf3ce44SJohn Forte 		if (err = sysdump(Options & PVERBOSE)) {
996*fcf3ce44SJohn Forte 		    (void) print_errString(err, NULL);
997*fcf3ce44SJohn Forte 		    exit(-1);
998*fcf3ce44SJohn Forte 		}
999*fcf3ce44SJohn Forte 		break;
1000*fcf3ce44SJohn Forte 
1001*fcf3ce44SJohn Forte 	    case	PORT: /* Undocumented command */
1002*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
1003*fcf3ce44SJohn Forte 			USEAGE();
1004*fcf3ce44SJohn Forte 			exit(-1);
1005*fcf3ce44SJohn Forte 		}
1006*fcf3ce44SJohn Forte 		if (USE_FCHBA) {
1007*fcf3ce44SJohn Forte 		    exit_code = fchba_display_port(Options & PVERBOSE);
1008*fcf3ce44SJohn Forte 		} else {
1009*fcf3ce44SJohn Forte 		    exit_code = adm_display_port(Options & PVERBOSE);
1010*fcf3ce44SJohn Forte 		}
1011*fcf3ce44SJohn Forte 		break;
1012*fcf3ce44SJohn Forte 
1013*fcf3ce44SJohn Forte 	    case	EXT_LOOPBACK:
1014*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
1015*fcf3ce44SJohn Forte 			USEAGE();
1016*fcf3ce44SJohn Forte 			exit(-1);
1017*fcf3ce44SJohn Forte 		}
1018*fcf3ce44SJohn Forte 		if (adm_port_loopback(argv[path_index], EXT_LOOPBACK) < 0) {
1019*fcf3ce44SJohn Forte 			exit(-1);
1020*fcf3ce44SJohn Forte 		}
1021*fcf3ce44SJohn Forte 		break;
1022*fcf3ce44SJohn Forte 
1023*fcf3ce44SJohn Forte 	    case	INT_LOOPBACK:
1024*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
1025*fcf3ce44SJohn Forte 			USEAGE();
1026*fcf3ce44SJohn Forte 			exit(-1);
1027*fcf3ce44SJohn Forte 		}
1028*fcf3ce44SJohn Forte 		if (adm_port_loopback(argv[path_index], INT_LOOPBACK) < 0) {
1029*fcf3ce44SJohn Forte 			exit(-1);
1030*fcf3ce44SJohn Forte 		}
1031*fcf3ce44SJohn Forte 		break;
1032*fcf3ce44SJohn Forte 
1033*fcf3ce44SJohn Forte 	    case	NO_LOOPBACK:
1034*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
1035*fcf3ce44SJohn Forte 			USEAGE();
1036*fcf3ce44SJohn Forte 			exit(-1);
1037*fcf3ce44SJohn Forte 		}
1038*fcf3ce44SJohn Forte 		if (adm_port_loopback(argv[path_index], NO_LOOPBACK) < 0) {
1039*fcf3ce44SJohn Forte 			exit(-1);
1040*fcf3ce44SJohn Forte 		}
1041*fcf3ce44SJohn Forte 		break;
1042*fcf3ce44SJohn Forte 
1043*fcf3ce44SJohn Forte 	    case	VERSION:
1044*fcf3ce44SJohn Forte 		break;
1045*fcf3ce44SJohn Forte 
1046*fcf3ce44SJohn Forte 
1047*fcf3ce44SJohn Forte 	    case	INSERT_DEVICE:
1048*fcf3ce44SJohn Forte 			if (argv[path_index] == NULL) {
1049*fcf3ce44SJohn Forte 				if ((err = h_insertSena_fcdev()) != 0) {
1050*fcf3ce44SJohn Forte 					(void) print_errString(err, NULL);
1051*fcf3ce44SJohn Forte 					exit(-1);
1052*fcf3ce44SJohn Forte 				}
1053*fcf3ce44SJohn Forte 			} else if ((err = hotplug(INSERT_DEVICE,
1054*fcf3ce44SJohn Forte 					&argv[path_index],
1055*fcf3ce44SJohn Forte 					Options & PVERBOSE,
1056*fcf3ce44SJohn Forte 					Options & OPTION_CAPF)) != 0) {
1057*fcf3ce44SJohn Forte 				(void) print_errString(err, argv[path_index]);
1058*fcf3ce44SJohn Forte 				exit(-1);
1059*fcf3ce44SJohn Forte 			}
1060*fcf3ce44SJohn Forte 			break;
1061*fcf3ce44SJohn Forte 	    case	REMOVE_DEVICE:
1062*fcf3ce44SJohn Forte 			if (err = hotplug(REMOVE_DEVICE, &argv[path_index],
1063*fcf3ce44SJohn Forte 			    Options & PVERBOSE, Options & OPTION_CAPF)) {
1064*fcf3ce44SJohn Forte 			    (void) print_errString(err, argv[path_index]);
1065*fcf3ce44SJohn Forte 			    exit(-1);
1066*fcf3ce44SJohn Forte 			}
1067*fcf3ce44SJohn Forte 			break;
1068*fcf3ce44SJohn Forte 
1069*fcf3ce44SJohn Forte 	/* for hotplug device operations */
1070*fcf3ce44SJohn Forte 	    case	DEV_ONLINE:
1071*fcf3ce44SJohn Forte 	    case	DEV_OFFLINE:
1072*fcf3ce44SJohn Forte 	    case	DEV_GETSTATE:
1073*fcf3ce44SJohn Forte 	    case	DEV_RESET:
1074*fcf3ce44SJohn Forte 	    case	BUS_QUIESCE:
1075*fcf3ce44SJohn Forte 	    case	BUS_UNQUIESCE:
1076*fcf3ce44SJohn Forte 	    case	BUS_GETSTATE:
1077*fcf3ce44SJohn Forte 	    case	BUS_RESET:
1078*fcf3ce44SJohn Forte 	    case	BUS_RESETALL:
1079*fcf3ce44SJohn Forte 		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
1080*fcf3ce44SJohn Forte 			E_USEAGE();
1081*fcf3ce44SJohn Forte 			exit(-1);
1082*fcf3ce44SJohn Forte 		}
1083*fcf3ce44SJohn Forte 		if (USE_FCHBA) {
1084*fcf3ce44SJohn Forte 		    if (fchba_hotplug_e(cmd, &argv[path_index],
1085*fcf3ce44SJohn Forte 			    Options & PVERBOSE, Options & OPTION_CAPF) != 0) {
1086*fcf3ce44SJohn Forte 			exit(-1);
1087*fcf3ce44SJohn Forte 		    }
1088*fcf3ce44SJohn Forte 		} else {
1089*fcf3ce44SJohn Forte 		    if (hotplug_e(cmd, &argv[path_index],
1090*fcf3ce44SJohn Forte 			    Options & PVERBOSE, Options & OPTION_CAPF) != 0) {
1091*fcf3ce44SJohn Forte 			exit(-1);
1092*fcf3ce44SJohn Forte 		    }
1093*fcf3ce44SJohn Forte 		}
1094*fcf3ce44SJohn Forte 		break;
1095*fcf3ce44SJohn Forte 
1096*fcf3ce44SJohn Forte 	    default:
1097*fcf3ce44SJohn Forte 		(void) fprintf(stderr,
1098*fcf3ce44SJohn Forte 		    MSGSTR(2213, "%s: subcommand decode failed.\n"),
1099*fcf3ce44SJohn Forte 		    whoami);
1100*fcf3ce44SJohn Forte 		USEAGE();
1101*fcf3ce44SJohn Forte 		exit(-1);
1102*fcf3ce44SJohn Forte 	}
1103*fcf3ce44SJohn Forte 	return (exit_code);
1104*fcf3ce44SJohn Forte }
1105