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