#define LUX_SF_INST_SHIFT4MINOR 6
#define LUX_SF_MINOR2INST(x) (x >> LUX_SF_INST_SHIFT4MINOR)
#include <stdlib.h>
#include <stdio.h>
#include <sys/file.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <strings.h>
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <stdarg.h>
#include <termio.h>
#include <sys/scsi/scsi.h>
#include "common.h"
#include "luxadm.h"
char *dtype[16];
char *whoami;
int Options;
const int OPTION_A = 0x00000001;
const int OPTION_B = 0x00000002;
const int OPTION_C = 0x00000004;
const int OPTION_D = 0x00000008;
const int OPTION_E = 0x00000010;
const int OPTION_F = 0x00000020;
const int OPTION_L = 0x00000040;
const int OPTION_P = 0x00000080;
const int OPTION_R = 0x00000100;
const int OPTION_T = 0x00000200;
const int OPTION_V = 0x00000400;
const int OPTION_Z = 0x00001000;
const int OPTION_Y = 0x00002000;
const int OPTION_CAPF = 0x00004000;
const int PVERBOSE = 0x00008000;
const int SAVE = 0x00010000;
const int EXPERT = 0x00020000;
void
print_chars(uchar_t *buffer, int size, int fill_flag)
{
int i;
for (i = 0; i < size; i++) {
if (buffer[i])
(void) fprintf(stdout, "%c", buffer[i]);
else if (fill_flag)
(void) fprintf(stdout, " ");
else
return;
}
}
static char *
memstrstr(char *s1, char *s2, int size1, int size2)
{
int count1, count2;
char *s1_ptr, *s2_ptr;
count1 = size1; count2 = size2;
s1_ptr = s1; s2_ptr = s2;
if (size2 == 0)
return (s1);
while (count1--) {
if (*s1_ptr++ == *s2_ptr++) {
if (--count2 == 0)
return (s1_ptr - size2);
continue;
}
count2 = size2;
s2_ptr = s2;
}
return (NULL);
}
static int
adm_fcode(int verbose, char *dir)
{
struct stat statbuf;
struct dirent *dirp;
DIR *dp;
int fp;
char fbuf[BUFSIZ];
char file[MAXPATHLEN];
int retval = 0, strfound = 0;
char manf[BUFSIZ];
if (Options & OPTION_P) {
#ifndef __x86
if (verbose) {
(void) fprintf(stdout,
MSGSTR(2215, "\n Searching for FC100/S cards:\n"));
}
retval += fcal_update(Options & PVERBOSE, NULL);
#endif
if (verbose) {
(void) fprintf(stdout,
MSGSTR(2216, "\n Searching for FC100/P, FC100/2P cards:\n"));
}
retval += q_qlgc_update(Options & PVERBOSE, NULL);
if (verbose) {
(void) fprintf(stdout,
MSGSTR(2503, "\n Searching for Emulex cards:\n"));
}
retval += emulex_update(NULL);
} else {
if (!dir) {
(void) fprintf(stdout, MSGSTR(2251,
" Location of Fcode not specified.\n"));
return (1);
} else if (verbose) {
(void) fprintf(stdout, MSGSTR(2217,
" Using directory %s"), dir);
}
if (lstat(dir, &statbuf) < 0) {
(void) fprintf(stderr, MSGSTR(134,
"%s: lstat() failed - %s\n"),
dir, strerror(errno));
return (1);
}
if (S_ISDIR(statbuf.st_mode) == 0) {
(void) fprintf(stderr,
MSGSTR(2218, "Error: %s is not a directory.\n"), dir);
return (1);
}
if ((dp = opendir(dir)) == NULL) {
(void) fprintf(stderr, MSGSTR(2219,
" Error Cannot open directory %s\n"), dir);
return (1);
}
while ((dirp = readdir(dp)) != NULL) {
if (strcmp(dirp->d_name, ".") == 0 ||
strcmp(dirp->d_name, "..") == 0) {
continue;
}
sprintf(file, "%s/%s", dir, dirp->d_name);
if ((fp = open(file, O_RDONLY)) < 0) {
(void) fprintf(stderr,
MSGSTR(2220,
"Error: open() failed to open file "
"%s\n"), file);
retval++;
continue;
}
while ((read(fp, fbuf, BUFSIZ)) > 0) {
if (memstrstr(fbuf, "SUNW,socal",
BUFSIZ, strlen("SUNW,socal"))
!= NULL) {
(void) fprintf(stdout, MSGSTR(2221,
"\n Using file: %s\n"), file);
retval += fcal_update(
Options & PVERBOSE, file);
strfound++;
break;
} else if ((memstrstr(fbuf, "SUNW,ifp",
BUFSIZ, strlen("SUNW,ifp"))
!= NULL) ||
(memstrstr(fbuf, "SUNW,qlc",
BUFSIZ, strlen("SUNW,qlc"))
!= NULL)) {
(void) fprintf(stdout, MSGSTR(2221,
"\n Using file: %s\n"), file);
retval += q_qlgc_update(
Options & PVERBOSE, file);
strfound++;
break;
}
}
if (!strfound) {
memset(manf, 0, sizeof (manf));
if ((emulex_fcode_reader(fp, "manufacturer",
manf,
sizeof (manf)) == 0) &&
(strncmp(manf, "Emulex", sizeof (manf))
== 0)) {
retval += emulex_update(file);
strfound = 0;
} else {
(void) fprintf(stderr, MSGSTR(2222,
"\nError: %s is not a valid Fcode "
"file.\n"), file);
retval++;
}
} else {
strfound = 0;
}
close(fp);
}
closedir(dp);
}
return (retval);
}
struct keyword {
char *match;
int num_match;
int ret_code;
};
static struct keyword Keywords[] = {
{"display", 2, DISPLAY},
{"download", 3, DOWNLOAD},
{"enclosure_names", 2, ENCLOSURE_NAMES},
{"failover", 3, FAILOVER},
{"fcal_s_download", 4, FCAL_UPDATE},
{"fcode_download", 4, FCODE_UPDATE},
{"inquiry", 2, INQUIRY},
{"insert_device", 3, INSERT_DEVICE},
{"led", 3, LED},
{"led_on", 5, LED_ON},
{"led_off", 5, LED_OFF},
{"led_blink", 5, LED_BLINK},
{"password", 2, PASSWORD},
{"power_on", 8, POWER_ON},
{"power_off", 9, POWER_OFF},
{"probe", 2, PROBE},
{"qlgc_s_download", 4, QLGC_UPDATE},
{"remove_device", 3, REMOVE_DEVICE},
{"reserve", 5, RESERVE},
{"release", 3, RELEASE},
{"set_boot_dev", 5, SET_BOOT_DEV},
{"start", 3, START},
{"stop", 3, STOP},
{"rdls", 2, RDLS},
{"bypass", 3, BYPASS},
{"enable", 3, ENABLE},
{"p_offline", 4, LUX_P_OFFLINE},
{"p_online", 4, LUX_P_ONLINE},
{"forcelip", 2, FORCELIP},
{"dump", 2, DUMP},
{"check_file", 2, CHECK_FILE},
{"dump_map", 2, DUMP_MAP},
{"sysdump", 5, SYSDUMP},
{"port", 4, PORT},
{"external_loopback", 12, EXT_LOOPBACK},
{"internal_loopback", 12, INT_LOOPBACK},
{"no_loopback", 11, NO_LOOPBACK},
{"version", 2, VERSION},
{"create_fabric_device", 2, CREATE_FAB},
{"online", 2, DEV_ONLINE},
{"offline", 2, DEV_OFFLINE},
{"dev_getstate", 5, DEV_GETSTATE},
{"dev_reset", 5, DEV_RESET},
{"bus_quiesce", 5, BUS_QUIESCE},
{"bus_unquiesce", 5, BUS_UNQUIESCE},
{"bus_getstate", 5, BUS_GETSTATE},
{"bus_reset", 9, BUS_RESET},
{"bus_resetall", 12, BUS_RESETALL},
{ NULL, 0, 0}
};
#ifndef EOK
static const int EOK = 0;
#endif
static int
getaction(char *cmd, struct keyword *matches, int *retval)
{
int actlen;
if (! cmd || ! matches || ! retval ||
! (actlen = strlen(cmd)))
return (EFAULT);
while (matches->match) {
if ((((int)strlen(matches->match)) >= actlen) &&
(actlen >= matches->num_match) &&
(strncmp(matches->match, cmd, actlen) == 0)) {
*retval = matches->ret_code;
return (EOK);
} else {
matches++;
}
}
return (EINVAL);
}
int
main(int argc, char **argv)
{
register int c;
extern char *optarg;
char *optstring = NULL;
int path_index, err = 0;
int cmd = 0;
int exit_code = 0;
int temp_fd;
char *file_name = NULL;
int option_t_input = 0;
char *path_phys = NULL;
int USE_FCHBA = 0;
whoami = argv[0];
i18n_catopen();
while ((c = getopt(argc, argv, "ve"))
!= EOF) {
switch (c) {
case 'v':
Options |= PVERBOSE;
break;
case 'e':
Options |= EXPERT;
break;
default:
USEAGE()
exit(-1);
}
}
setbuf(stdout, NULL);
dtype[0] = MSGSTR(2192, "Disk device");
dtype[1] = MSGSTR(2193, "Tape device");
dtype[2] = MSGSTR(2194, "Printer device");
dtype[3] = MSGSTR(2195, "Processor device");
dtype[4] = MSGSTR(2196, "WORM device");
dtype[5] = MSGSTR(2197, "CD-ROM device");
dtype[6] = MSGSTR(2198, "Scanner device");
dtype[7] = MSGSTR(2199, "Optical memory device");
dtype[8] = MSGSTR(2200, "Medium changer device");
dtype[9] = MSGSTR(2201, "Communications device");
dtype[10] = MSGSTR(107, "Graphic arts device");
dtype[11] = MSGSTR(107, "Graphic arts device");
dtype[12] = MSGSTR(2202, "Array controller device");
dtype[13] = MSGSTR(2203, "SES device");
dtype[14] = MSGSTR(71, "Reserved");
dtype[15] = MSGSTR(71, "Reserved");
if ((getaction(argv[optind], Keywords, &cmd)) == EOK) {
optind++;
if ((cmd != PROBE) && (cmd != FCAL_UPDATE) &&
(cmd != QLGC_UPDATE) && (cmd != FCODE_UPDATE) &&
(cmd != INSERT_DEVICE) && (cmd != SYSDUMP) && (cmd != AU) &&
(cmd != PORT) && (cmd != CREATE_FAB) && (optind >= argc)) {
(void) fprintf(stderr,
MSGSTR(2204,
"Error: enclosure or pathname not specified.\n"));
USEAGE();
exit(-1);
}
} else {
(void) fprintf(stderr,
MSGSTR(2205, "%s: subcommand not specified.\n"),
whoami);
USEAGE();
exit(-1);
}
if ((cmd == ENABLE) || (cmd == BYPASS)) {
optstring = "Ffrab";
} else if (cmd == FCODE_UPDATE) {
optstring = "pd:";
} else if (cmd == REMOVE_DEVICE) {
optstring = "F";
} else if (cmd == CREATE_FAB) {
optstring = "f:";
} else {
optstring = "Fryszabepcdlvt:f:w:";
}
while ((c = getopt(argc, argv, optstring)) != EOF) {
switch (c) {
case 'a':
Options |= OPTION_A;
break;
case 'b':
Options |= OPTION_B;
break;
case 'c':
Options |= OPTION_C;
break;
case 'd':
Options |= OPTION_D;
if (cmd == FCODE_UPDATE) {
file_name = optarg;
}
break;
case 'e':
Options |= OPTION_E;
break;
case 'f':
Options |= OPTION_F;
if (!((cmd == ENABLE) || (cmd == BYPASS))) {
file_name = optarg;
}
break;
case 'F':
Options |= OPTION_CAPF;
break;
case 'l':
Options |= OPTION_L;
break;
case 'p':
Options |= OPTION_P;
break;
case 'r':
Options |= OPTION_R;
break;
case 's':
Options |= SAVE;
break;
case 't':
Options |= OPTION_T;
option_t_input = atoi(optarg);
break;
case 'v':
Options |= OPTION_V;
break;
case 'z':
Options |= OPTION_Z;
break;
case 'y':
Options |= OPTION_Y;
break;
default:
USEAGE()
exit(-1);
}
}
if ((cmd != PROBE) && (cmd != FCAL_UPDATE) &&
(cmd != QLGC_UPDATE) && (cmd != FCODE_UPDATE) &&
(cmd != INSERT_DEVICE) && (cmd != SYSDUMP) &&
(cmd != AU) && (cmd != PORT) &&
(cmd != CREATE_FAB) && (optind >= argc)) {
(void) fprintf(stderr,
MSGSTR(2206,
"Error: enclosure or pathname not specified.\n"));
USEAGE();
exit(-1);
}
path_index = optind;
if ((file_name != NULL) && (Options & OPTION_F)) {
if ((temp_fd = open(file_name, O_RDONLY)) == -1) {
perror(file_name);
exit(-1);
} else {
close(temp_fd);
}
}
USE_FCHBA = use_fchba();
switch (cmd) {
case DISPLAY:
if (Options &
~(PVERBOSE | OPTION_A | OPTION_Z | OPTION_R |
OPTION_P | OPTION_V | OPTION_L | OPTION_E | OPTION_T)) {
USEAGE();
exit(-1);
}
if (USE_FCHBA) {
exit_code = fchba_display_config(&argv[path_index],
option_t_input, argc - path_index);
} else {
exit_code = adm_display_config(&argv[path_index]);
}
break;
case DOWNLOAD:
if (Options &
~(PVERBOSE | OPTION_F | SAVE)) {
USEAGE();
exit(-1);
}
adm_download(&argv[path_index], file_name);
break;
case ENCLOSURE_NAMES:
if (Options & ~PVERBOSE) {
USEAGE();
exit(-1);
}
up_encl_name(&argv[path_index], argc);
break;
case FAILOVER:
if (Options & ~PVERBOSE) {
USEAGE();
exit(-1);
}
adm_failover(&argv[path_index]);
break;
case INQUIRY:
if (Options & ~(PVERBOSE)) {
USEAGE();
exit(-1);
}
if (USE_FCHBA) {
exit_code = fchba_inquiry(&argv[path_index]);
} else {
exit_code = adm_inquiry(&argv[path_index]);
}
break;
case PROBE:
if (Options & ~(PVERBOSE | OPTION_P)) {
USEAGE();
exit(-1);
}
if (((Options & PVERBOSE) && (Options & OPTION_P) &&
(argc != 4)) ||
(!(Options & PVERBOSE) && (Options & OPTION_P) &&
(argc != 3)) ||
((Options & PVERBOSE) && (!(Options & OPTION_P)) &&
(argc != 3)) ||
(!(Options & PVERBOSE) && (!(Options & OPTION_P)) &&
(argc != 2))) {
(void) fprintf(stderr,
MSGSTR(114, "Error: Incorrect number of arguments.\n"));
(void) fprintf(stderr, MSGSTR(2208,
"Usage: %s [-v] subcommand [option]\n"), whoami);
exit(-1);
}
if (USE_FCHBA) {
exit_code = fchba_non_encl_probe();
} else {
pho_probe();
non_encl_probe();
}
break;
case FCODE_UPDATE:
if ((Options & ~(PVERBOSE)) &
~(OPTION_P | OPTION_D) || argv[path_index]) {
USEAGE();
exit(-1);
}
if (!((Options & (OPTION_P | OPTION_D)) &&
!((Options & OPTION_P) && (Options & OPTION_D)))) {
USEAGE();
exit(-1);
}
if (adm_fcode(Options & PVERBOSE, file_name) != 0) {
exit(-1);
}
break;
case QLGC_UPDATE:
if ((Options & ~(PVERBOSE)) & ~(OPTION_F) ||
argv[path_index]) {
USEAGE();
exit(-1);
}
if (q_qlgc_update(Options & PVERBOSE, file_name) != 0) {
exit(-1);
}
break;
case FCAL_UPDATE:
if ((Options & ~(PVERBOSE)) & ~(OPTION_F) ||
argv[path_index]) {
USEAGE();
exit(-1);
}
exit_code = fcal_update(Options & PVERBOSE, file_name);
break;
case SET_BOOT_DEV:
exit_code = setboot(Options & OPTION_Y,
Options & PVERBOSE, argv[path_index]);
break;
case LED:
if (Options & ~(PVERBOSE)) {
USEAGE();
exit(-1);
}
adm_led(&argv[path_index], L_LED_STATUS);
break;
case LED_ON:
if (Options & ~(PVERBOSE)) {
USEAGE();
exit(-1);
}
adm_led(&argv[path_index], L_LED_ON);
break;
case LED_OFF:
if (Options & ~(PVERBOSE)) {
USEAGE();
exit(-1);
}
adm_led(&argv[path_index], L_LED_OFF);
break;
case LED_BLINK:
if (Options & ~(PVERBOSE)) {
USEAGE();
exit(-1);
}
adm_led(&argv[path_index], L_LED_RQST_IDENTIFY);
break;
case PASSWORD:
if (Options & ~(PVERBOSE)) {
USEAGE();
exit(-1);
}
up_password(&argv[path_index]);
break;
case RESERVE:
if (Options & (~PVERBOSE)) {
USEAGE();
exit(-1);
}
VERBPRINT(MSGSTR(2209,
" Reserving: \n %s\n"), argv[path_index]);
if (USE_FCHBA) {
struct stat sbuf;
if (stat(argv[path_index], &sbuf) < 0) {
(void) fprintf(stderr, "%s: ", whoami);
(void) fprintf(stderr,
MSGSTR(112, "Error: Invalid pathname (%s)"),
argv[path_index]);
(void) fprintf(stderr, "\n");
exit(-1);
}
path_phys = argv[path_index];
if (err = scsi_reserve(path_phys)) {
(void) print_errString(err, argv[path_index]);
exit(-1);
}
} else {
exit_code = adm_reserve(argv[path_index]);
}
break;
case RELEASE:
if (Options & (~PVERBOSE)) {
USEAGE();
exit(-1);
}
VERBPRINT(MSGSTR(2210, " Canceling Reservation for:\n %s\n"),
argv[path_index]);
if (USE_FCHBA) {
struct stat sbuf;
if (stat(argv[path_index], &sbuf) < 0) {
(void) fprintf(stderr, "%s: ", whoami);
(void) fprintf(stderr,
MSGSTR(112, "Error: Invalid pathname (%s)"),
argv[path_index]);
(void) fprintf(stderr, "\n");
exit(-1);
}
path_phys = argv[path_index];
if (err = scsi_release(path_phys)) {
(void) print_errString(err, argv[path_index]);
exit(-1);
}
} else {
exit_code = adm_release(argv[path_index]);
}
break;
case START:
if (Options & ~(PVERBOSE)) {
USEAGE();
exit(-1);
}
exit_code = adm_start(&argv[path_index]);
break;
case STOP:
if (Options & ~(PVERBOSE)) {
USEAGE();
exit(-1);
}
exit_code = adm_stop(&argv[path_index]);
break;
case POWER_OFF:
if (Options & ~(PVERBOSE | OPTION_CAPF)) {
USEAGE();
exit(-1);
}
exit_code = adm_power_off(&argv[path_index], 1);
break;
case POWER_ON:
if (Options & (~PVERBOSE)) {
USEAGE();
exit(-1);
}
exit_code = adm_power_off(&argv[path_index], 0);
break;
case FORCELIP:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
E_USEAGE();
exit(-1);
}
exit_code = adm_forcelip(&argv[path_index]);
break;
case BYPASS:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT |
OPTION_CAPF | OPTION_A | OPTION_B | OPTION_F |
OPTION_R)) || !(Options & (OPTION_A | OPTION_B)) ||
((Options & OPTION_A) && (Options & OPTION_B))) {
E_USEAGE();
exit(-1);
}
adm_bypass_enable(&argv[path_index], 1);
break;
case ENABLE:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT |
OPTION_CAPF | OPTION_A | OPTION_B | OPTION_F |
OPTION_R)) || !(Options & (OPTION_A | OPTION_B)) ||
((Options & OPTION_A) && (Options & OPTION_B))) {
E_USEAGE();
exit(-1);
}
adm_bypass_enable(&argv[path_index], 0);
break;
case LUX_P_OFFLINE:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
E_USEAGE();
exit(-1);
}
exit_code = adm_port_offline_online(&argv[path_index],
LUX_P_OFFLINE);
break;
case LUX_P_ONLINE:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
E_USEAGE();
exit(-1);
}
exit_code = adm_port_offline_online(&argv[path_index],
LUX_P_ONLINE);
break;
case RDLS:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
E_USEAGE();
exit(-1);
}
if (USE_FCHBA) {
exit_code = fchba_display_link_status(&argv[path_index]);
} else {
display_link_status(&argv[path_index]);
}
break;
case CREATE_FAB:
if (!(Options & (EXPERT | OPTION_F)) ||
(Options & ~(PVERBOSE | EXPERT | OPTION_F))) {
E_USEAGE();
exit(-1);
}
if (read_repos_file(file_name) != 0) {
exit(-1);
}
break;
case CHECK_FILE:
if (Options & ~(PVERBOSE)) {
USEAGE();
exit(-1);
}
exit_code = adm_check_file(&argv[path_index],
(Options & PVERBOSE));
break;
case DUMP:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
USEAGE();
exit(-1);
}
dump(&argv[path_index]);
break;
case DUMP_MAP:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
USEAGE();
exit(-1);
}
if (USE_FCHBA) {
exit_code = fchba_dump_map(&argv[path_index]);
} else {
dump_map(&argv[path_index]);
}
break;
case SYSDUMP:
if (Options & ~(PVERBOSE)) {
USEAGE();
exit(-1);
}
if (err = sysdump(Options & PVERBOSE)) {
(void) print_errString(err, NULL);
exit(-1);
}
break;
case PORT:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
USEAGE();
exit(-1);
}
if (USE_FCHBA) {
exit_code = fchba_display_port(Options & PVERBOSE);
} else {
exit_code = adm_display_port(Options & PVERBOSE);
}
break;
case EXT_LOOPBACK:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
USEAGE();
exit(-1);
}
if (adm_port_loopback(argv[path_index], EXT_LOOPBACK) < 0) {
exit(-1);
}
break;
case INT_LOOPBACK:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
USEAGE();
exit(-1);
}
if (adm_port_loopback(argv[path_index], INT_LOOPBACK) < 0) {
exit(-1);
}
break;
case NO_LOOPBACK:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
USEAGE();
exit(-1);
}
if (adm_port_loopback(argv[path_index], NO_LOOPBACK) < 0) {
exit(-1);
}
break;
case VERSION:
break;
case INSERT_DEVICE:
if (argv[path_index] == NULL) {
if ((err = h_insertSena_fcdev()) != 0) {
(void) print_errString(err, NULL);
exit(-1);
}
} else if ((err = hotplug(INSERT_DEVICE,
&argv[path_index],
Options & PVERBOSE,
Options & OPTION_CAPF)) != 0) {
(void) print_errString(err, argv[path_index]);
exit(-1);
}
break;
case REMOVE_DEVICE:
if (err = hotplug(REMOVE_DEVICE, &argv[path_index],
Options & PVERBOSE, Options & OPTION_CAPF)) {
(void) print_errString(err, argv[path_index]);
exit(-1);
}
break;
case DEV_ONLINE:
case DEV_OFFLINE:
case DEV_GETSTATE:
case DEV_RESET:
case BUS_QUIESCE:
case BUS_UNQUIESCE:
case BUS_GETSTATE:
case BUS_RESET:
case BUS_RESETALL:
if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
E_USEAGE();
exit(-1);
}
if (USE_FCHBA) {
if (fchba_hotplug_e(cmd, &argv[path_index],
Options & PVERBOSE, Options & OPTION_CAPF) != 0) {
exit(-1);
}
} else {
if (hotplug_e(cmd, &argv[path_index],
Options & PVERBOSE, Options & OPTION_CAPF) != 0) {
exit(-1);
}
}
break;
default:
(void) fprintf(stderr,
MSGSTR(2213, "%s: subcommand decode failed.\n"),
whoami);
USEAGE();
exit(-1);
}
return (exit_code);
}