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