4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
33 * Administration program for SENA
34 * subsystems and individual FC_AL devices.
38 * I18N message number ranges
39 * This file: 2000 - 2999
40 * Shared common messages: 1 - 1999
43 /* #define _POSIX_SOURCE 1 */
46 * These defines are used to map instance number from sf minor node.
47 * They are copied from SF_INST_SHIFT4MINOR and SF_MINOR2INST in sfvar.h.
48 * sfvar.h is not clean for userland use.
49 * When it is cleaned up, these defines will be removed and sfvar.h
50 * will be included in luxadm.h header file.
52 #define LUX_SF_INST_SHIFT4MINOR 6
53 #define LUX_SF_MINOR2INST(x) (x >> LUX_SF_INST_SHIFT4MINOR)
59 #include <sys/errno.h>
60 #include <sys/types.h>
62 #include <sys/param.h>
73 #include <termio.h> /* For password */
74 #include <sys/scsi/scsi.h>
80 /* Global variables */
81 char *dtype
[16]; /* setting a global for later use. */
84 const int OPTION_A
= 0x00000001;
85 const int OPTION_B
= 0x00000002;
86 const int OPTION_C
= 0x00000004;
87 const int OPTION_D
= 0x00000008;
88 const int OPTION_E
= 0x00000010;
89 const int OPTION_F
= 0x00000020;
90 const int OPTION_L
= 0x00000040;
91 const int OPTION_P
= 0x00000080;
92 const int OPTION_R
= 0x00000100;
93 const int OPTION_T
= 0x00000200;
94 const int OPTION_V
= 0x00000400;
95 const int OPTION_Z
= 0x00001000;
96 const int OPTION_Y
= 0x00002000;
97 const int OPTION_CAPF
= 0x00004000;
98 const int PVERBOSE
= 0x00008000;
99 const int SAVE
= 0x00010000;
100 const int EXPERT
= 0x00020000;
103 * Given a pointer to a character array, print the character array.
104 * the character array will not necesarily be NULL terminated.
107 * size - the max number of characters to print
108 * fill_flag - flag when set fills all NULL characters with spaces
113 print_chars(uchar_t
*buffer
, int size
, int fill_flag
)
118 for (i
= 0; i
< size
; i
++) {
120 (void) fprintf(stdout
, "%c", buffer
[i
]);
122 (void) fprintf(stdout
, " ");
130 * Input : pointer to buf1, pointer to buf2, size of buf1, size of buf2
132 * Pointer to start of contents-of-buf2 in buf1 if it is found
133 * NULL if buf1 does not contain contents of buf2
135 * This function works similar to strstr(). The difference is that null
136 * characters in the buffer are treated like any other character. So, buf1
137 * and buf2 can have embedded null characters in them.
140 memstrstr(char *s1
, char *s2
, int size1
, int size2
)
143 char *s1_ptr
, *s2_ptr
;
145 count1
= size1
; count2
= size2
;
146 s1_ptr
= s1
; s2_ptr
= s2
;
152 if (*s1_ptr
++ == *s2_ptr
++) {
154 return (s1_ptr
- size2
);
166 * Download host bus adapter FCode to all supported cards.
168 * Specify a directory that holds the FCode files, or
169 * it will use the default dir. Each file is dealt to
170 * the appropriate function.
172 * -p prints current versions only, -d specifies a directory to load
175 adm_fcode(int verbose
, char *dir
)
182 char file
[MAXPATHLEN
];
183 int retval
= 0, strfound
= 0;
186 /* Find all adapters and print the current FCode version */
187 if (Options
& OPTION_P
) {
189 /* SOCAL (SBus) adapters are not supported on x86 */
192 (void) fprintf(stdout
,
193 MSGSTR(2215, "\n Searching for FC100/S cards:\n"));
195 retval
+= fcal_update(Options
& PVERBOSE
, NULL
);
199 (void) fprintf(stdout
,
200 MSGSTR(2216, "\n Searching for FC100/P, FC100/2P cards:\n"));
202 retval
+= q_qlgc_update(Options
& PVERBOSE
, NULL
);
204 (void) fprintf(stdout
,
205 MSGSTR(2503, "\n Searching for Emulex cards:\n"));
207 retval
+= emulex_update(NULL
);
209 /* Send files to the correct function for loading to the HBA */
213 (void) fprintf(stdout
, MSGSTR(2251,
214 " Location of Fcode not specified.\n"));
217 } else if (verbose
) {
218 (void) fprintf(stdout
, MSGSTR(2217,
219 " Using directory %s"), dir
);
221 if (lstat(dir
, &statbuf
) < 0) {
222 (void) fprintf(stderr
, MSGSTR(134,
223 "%s: lstat() failed - %s\n"),
224 dir
, strerror(errno
));
227 if (S_ISDIR(statbuf
.st_mode
) == 0) {
228 (void) fprintf(stderr
,
229 MSGSTR(2218, "Error: %s is not a directory.\n"), dir
);
232 if ((dp
= opendir(dir
)) == NULL
) {
233 (void) fprintf(stderr
, MSGSTR(2219,
234 " Error Cannot open directory %s\n"), dir
);
238 while ((dirp
= readdir(dp
)) != NULL
) {
239 if (strcmp(dirp
->d_name
, ".") == 0 ||
240 strcmp(dirp
->d_name
, "..") == 0) {
243 sprintf(file
, "%s/%s", dir
, dirp
->d_name
);
245 if ((fp
= open(file
, O_RDONLY
)) < 0) {
246 (void) fprintf(stderr
,
248 "Error: open() failed to open file "
251 * We should just issue an error message and
252 * make an attempt on the next file,
253 * and the open error is still an error
254 * so the retval should be incremented
259 while ((read(fp
, fbuf
, BUFSIZ
)) > 0) {
260 if (memstrstr(fbuf
, "SUNW,socal",
261 BUFSIZ
, strlen("SUNW,socal"))
263 (void) fprintf(stdout
, MSGSTR(2221,
264 "\n Using file: %s\n"), file
);
265 retval
+= fcal_update(
266 Options
& PVERBOSE
, file
);
269 } else if ((memstrstr(fbuf
, "SUNW,ifp",
270 BUFSIZ
, strlen("SUNW,ifp"))
272 (memstrstr(fbuf
, "SUNW,qlc",
273 BUFSIZ
, strlen("SUNW,qlc"))
275 (void) fprintf(stdout
, MSGSTR(2221,
276 "\n Using file: %s\n"), file
);
277 retval
+= q_qlgc_update(
278 Options
& PVERBOSE
, file
);
284 /* check to see if this is an emulex fcode */
285 memset(manf
, 0, sizeof (manf
));
286 if ((emulex_fcode_reader(fp
, "manufacturer",
288 sizeof (manf
)) == 0) &&
289 (strncmp(manf
, "Emulex", sizeof (manf
))
291 retval
+= emulex_update(file
);
294 (void) fprintf(stderr
, MSGSTR(2222,
295 "\nError: %s is not a valid Fcode "
310 * Definition of getaction() routine which does keyword parsing
312 * Operation: A character string containing the ascii cmd to be
313 * parsed is passed in along with an array of structures.
314 * The 1st struct element is a recognizable cmd string, the second
315 * is the minimum number of characters from the start of this string
316 * to succeed on a match. For example, { "offline", 3, ONLINE }
317 * will match "off", "offli", "offline", but not "of" nor "offlinebarf"
318 * The third element is the {usually but not necessarily unique}
319 * integer to return on a successful match. Note: compares are cAsE insensitive.
321 * To change, extend or use this utility, just add or remove appropriate
322 * lines in the structure initializer below and in the #define s for the
326 * Do not change the minimum number of characters to produce
327 * a match as someone may be building scripts that use this
331 char *match
; /* Character String to match against */
332 int num_match
; /* Minimum chars to produce a match */
333 int ret_code
; /* Value to return on a match */
336 static struct keyword Keywords
[] = {
337 {"display", 2, DISPLAY
},
338 {"download", 3, DOWNLOAD
},
339 {"enclosure_names", 2, ENCLOSURE_NAMES
},
340 {"failover", 3, FAILOVER
},
341 {"fcal_s_download", 4, FCAL_UPDATE
},
342 {"fcode_download", 4, FCODE_UPDATE
},
343 {"inquiry", 2, INQUIRY
},
344 {"insert_device", 3, INSERT_DEVICE
},
346 {"led_on", 5, LED_ON
},
347 {"led_off", 5, LED_OFF
},
348 {"led_blink", 5, LED_BLINK
},
349 {"password", 2, PASSWORD
},
350 {"power_on", 8, POWER_ON
},
351 {"power_off", 9, POWER_OFF
},
353 {"qlgc_s_download", 4, QLGC_UPDATE
},
354 {"remove_device", 3, REMOVE_DEVICE
},
355 {"reserve", 5, RESERVE
},
356 {"release", 3, RELEASE
},
357 {"set_boot_dev", 5, SET_BOOT_DEV
},
361 {"bypass", 3, BYPASS
},
362 {"enable", 3, ENABLE
},
363 {"p_offline", 4, LUX_P_OFFLINE
},
364 {"p_online", 4, LUX_P_ONLINE
},
365 {"forcelip", 2, FORCELIP
},
367 {"check_file", 2, CHECK_FILE
},
368 {"dump_map", 2, DUMP_MAP
},
369 {"sysdump", 5, SYSDUMP
},
371 {"external_loopback", 12, EXT_LOOPBACK
},
372 {"internal_loopback", 12, INT_LOOPBACK
},
373 {"no_loopback", 11, NO_LOOPBACK
},
374 {"version", 2, VERSION
},
375 {"create_fabric_device", 2, CREATE_FAB
},
376 /* hotplugging device operations */
377 {"online", 2, DEV_ONLINE
},
378 {"offline", 2, DEV_OFFLINE
},
379 {"dev_getstate", 5, DEV_GETSTATE
},
380 {"dev_reset", 5, DEV_RESET
},
381 /* hotplugging bus operations */
382 {"bus_quiesce", 5, BUS_QUIESCE
},
383 {"bus_unquiesce", 5, BUS_UNQUIESCE
},
384 {"bus_getstate", 5, BUS_GETSTATE
},
385 {"bus_reset", 9, BUS_RESET
},
386 {"bus_resetall", 12, BUS_RESETALL
},
387 /* hotplugging "helper" subcommands */
392 static const int EOK
= 0; /* errno.h type success return code */
397 * function getaction() takes a character string, cmd, and
398 * tries to match it against a passed structure of known cmd
399 * character strings. If a match is found, corresponding code
400 * is returned in retval. Status returns as follows:
401 * EOK = Match found, look for cmd's code in retval
402 * EFAULT = One of passed parameters was bad
403 * EINVAL = cmd did not match any in list
406 getaction(char *cmd
, struct keyword
*matches
, int *retval
)
410 /* Idiot checking of pointers */
411 if (! cmd
|| ! matches
|| ! retval
||
412 ! (actlen
= strlen(cmd
))) /* Is there an cmd ? */
415 /* Keep looping until NULL match string (end of list) */
416 while (matches
->match
) {
418 * Precedence: Make sure target is no longer than
419 * current match string
420 * and target is at least as long as
421 * minimum # match chars,
422 * then do case insensitive match
423 * based on actual target size
425 if ((((int)strlen(matches
->match
)) >= actlen
) &&
426 (actlen
>= matches
->num_match
) &&
427 /* can't get strncasecmp to work on SCR4 */
428 /* (strncasecmp(matches->match, cmd, actlen) == 0) */
429 (strncmp(matches
->match
, cmd
, actlen
) == 0)) {
430 *retval
= matches
->ret_code
; /* Found our match */
433 matches
++; /* Next match string/struct */
435 } /* End of matches loop */
438 } /* End of getaction() */
440 /* main functions. */
442 main(int argc
, char **argv
)
447 char *optstring
= NULL
;
448 int path_index
, err
= 0;
449 int cmd
= 0; /* Cmd verb from cmd line */
450 int exit_code
= 0; /* exit code for program */
451 int temp_fd
; /* For -f option */
452 char *file_name
= NULL
;
454 char *path_phys
= NULL
;
461 * Enable locale announcement
465 while ((c
= getopt(argc
, argv
, "ve"))
475 /* Note: getopt prints an error if invalid option */
478 } /* End of switch(c) */
480 setbuf(stdout
, NULL
); /* set stdout unbuffered. */
483 * Build any i18n global variables
485 dtype
[0] = MSGSTR(2192, "Disk device");
486 dtype
[1] = MSGSTR(2193, "Tape device");
487 dtype
[2] = MSGSTR(2194, "Printer device");
488 dtype
[3] = MSGSTR(2195, "Processor device");
489 dtype
[4] = MSGSTR(2196, "WORM device");
490 dtype
[5] = MSGSTR(2197, "CD-ROM device");
491 dtype
[6] = MSGSTR(2198, "Scanner device");
492 dtype
[7] = MSGSTR(2199, "Optical memory device");
493 dtype
[8] = MSGSTR(2200, "Medium changer device");
494 dtype
[9] = MSGSTR(2201, "Communications device");
495 dtype
[10] = MSGSTR(107, "Graphic arts device");
496 dtype
[11] = MSGSTR(107, "Graphic arts device");
497 dtype
[12] = MSGSTR(2202, "Array controller device");
498 dtype
[13] = MSGSTR(2203, "SES device");
499 dtype
[14] = MSGSTR(71, "Reserved");
500 dtype
[15] = MSGSTR(71, "Reserved");
507 if ((getaction(argv
[optind
], Keywords
, &cmd
)) == EOK
) {
509 if ((cmd
!= PROBE
) && (cmd
!= FCAL_UPDATE
) &&
510 (cmd
!= QLGC_UPDATE
) && (cmd
!= FCODE_UPDATE
) &&
511 (cmd
!= INSERT_DEVICE
) && (cmd
!= SYSDUMP
) && (cmd
!= AU
) &&
512 (cmd
!= PORT
) && (cmd
!= CREATE_FAB
) && (optind
>= argc
)) {
513 (void) fprintf(stderr
,
515 "Error: enclosure or pathname not specified.\n"));
520 (void) fprintf(stderr
,
521 MSGSTR(2205, "%s: subcommand not specified.\n"),
527 /* Extract & Save subcommand options */
528 if ((cmd
== ENABLE
) || (cmd
== BYPASS
)) {
530 } else if (cmd
== FCODE_UPDATE
) {
532 } else if (cmd
== REMOVE_DEVICE
) {
534 } else if (cmd
== CREATE_FAB
) {
537 optstring
= "Fryszabepcdlvt:f:w:";
539 while ((c
= getopt(argc
, argv
, optstring
)) != EOF
) {
552 if (cmd
== FCODE_UPDATE
) {
561 if (!((cmd
== ENABLE
) || (cmd
== BYPASS
))) {
566 Options
|= OPTION_CAPF
;
582 option_t_input
= atoi(optarg
);
594 /* Note: getopt prints an error if invalid option */
597 } /* End of switch(c) */
599 if ((cmd
!= PROBE
) && (cmd
!= FCAL_UPDATE
) &&
600 (cmd
!= QLGC_UPDATE
) && (cmd
!= FCODE_UPDATE
) &&
601 (cmd
!= INSERT_DEVICE
) && (cmd
!= SYSDUMP
) &&
602 (cmd
!= AU
) && (cmd
!= PORT
) &&
603 (cmd
!= CREATE_FAB
) && (optind
>= argc
)) {
604 (void) fprintf(stderr
,
606 "Error: enclosure or pathname not specified.\n"));
613 * Check if the file supplied with the -f option is valid
614 * Some sub commands (bypass for example) use the -f option
615 * for other reasons. In such cases, "file_name" should be
618 if ((file_name
!= NULL
) && (Options
& OPTION_F
)) {
619 if ((temp_fd
= open(file_name
, O_RDONLY
)) == -1) {
627 /* Determine which mode to operate in (FC-HBA or original) */
628 USE_FCHBA
= use_fchba();
633 ~(PVERBOSE
| OPTION_A
| OPTION_Z
| OPTION_R
|
634 OPTION_P
| OPTION_V
| OPTION_L
| OPTION_E
| OPTION_T
)) {
638 /* Display object(s) */
640 exit_code
= fchba_display_config(&argv
[path_index
],
641 option_t_input
, argc
- path_index
);
643 exit_code
= adm_display_config(&argv
[path_index
]);
649 ~(PVERBOSE
| OPTION_F
| SAVE
)) {
653 adm_download(&argv
[path_index
], file_name
);
656 case ENCLOSURE_NAMES
:
657 if (Options
& ~PVERBOSE
) {
661 up_encl_name(&argv
[path_index
], argc
);
665 if (Options
& ~PVERBOSE
) {
669 adm_failover(&argv
[path_index
]);
673 if (Options
& ~(PVERBOSE
)) {
678 exit_code
= fchba_inquiry(&argv
[path_index
]);
680 exit_code
= adm_inquiry(&argv
[path_index
]);
685 if (Options
& ~(PVERBOSE
| OPTION_P
)) {
690 * A special check just in case someone entered
691 * any characters after the -p or the probe.
695 if (((Options
& PVERBOSE
) && (Options
& OPTION_P
) &&
697 (!(Options
& PVERBOSE
) && (Options
& OPTION_P
) &&
699 ((Options
& PVERBOSE
) && (!(Options
& OPTION_P
)) &&
701 (!(Options
& PVERBOSE
) && (!(Options
& OPTION_P
)) &&
703 (void) fprintf(stderr
,
704 MSGSTR(114, "Error: Incorrect number of arguments.\n"));
705 (void) fprintf(stderr
, MSGSTR(2208,
706 "Usage: %s [-v] subcommand [option]\n"), whoami
);
710 exit_code
= fchba_non_encl_probe();
717 case FCODE_UPDATE
: /* Update Fcode in all cards */
718 if ((Options
& ~(PVERBOSE
)) &
719 ~(OPTION_P
| OPTION_D
) || argv
[path_index
]) {
723 if (!((Options
& (OPTION_P
| OPTION_D
)) &&
724 !((Options
& OPTION_P
) && (Options
& OPTION_D
)))) {
728 if (adm_fcode(Options
& PVERBOSE
, file_name
) != 0) {
733 case QLGC_UPDATE
: /* Update Fcode in PCI HBA card(s) */
734 if ((Options
& ~(PVERBOSE
)) & ~(OPTION_F
) ||
739 if (q_qlgc_update(Options
& PVERBOSE
, file_name
) != 0) {
744 case FCAL_UPDATE
: /* Update Fcode in Sbus soc+ card */
745 if ((Options
& ~(PVERBOSE
)) & ~(OPTION_F
) ||
750 exit_code
= fcal_update(Options
& PVERBOSE
, file_name
);
753 case SET_BOOT_DEV
: /* Set boot-device variable in nvram */
754 exit_code
= setboot(Options
& OPTION_Y
,
755 Options
& PVERBOSE
, argv
[path_index
]);
759 if (Options
& ~(PVERBOSE
)) {
763 adm_led(&argv
[path_index
], L_LED_STATUS
);
766 if (Options
& ~(PVERBOSE
)) {
770 adm_led(&argv
[path_index
], L_LED_ON
);
773 if (Options
& ~(PVERBOSE
)) {
777 adm_led(&argv
[path_index
], L_LED_OFF
);
780 if (Options
& ~(PVERBOSE
)) {
784 adm_led(&argv
[path_index
], L_LED_RQST_IDENTIFY
);
787 if (Options
& ~(PVERBOSE
)) {
791 up_password(&argv
[path_index
]);
796 if (Options
& (~PVERBOSE
)) {
800 VERBPRINT(MSGSTR(2209,
801 " Reserving: \n %s\n"), argv
[path_index
]);
804 /* Just stat the argument and make sure it exists */
805 if (stat(argv
[path_index
], &sbuf
) < 0) {
806 (void) fprintf(stderr
, "%s: ", whoami
);
807 (void) fprintf(stderr
,
808 MSGSTR(112, "Error: Invalid pathname (%s)"),
810 (void) fprintf(stderr
, "\n");
813 path_phys
= argv
[path_index
];
814 if (err
= scsi_reserve(path_phys
)) {
815 (void) print_errString(err
, argv
[path_index
]);
819 exit_code
= adm_reserve(argv
[path_index
]);
824 if (Options
& (~PVERBOSE
)) {
828 VERBPRINT(MSGSTR(2210, " Canceling Reservation for:\n %s\n"),
832 /* Just stat the argument and make sure it exists */
833 if (stat(argv
[path_index
], &sbuf
) < 0) {
834 (void) fprintf(stderr
, "%s: ", whoami
);
835 (void) fprintf(stderr
,
836 MSGSTR(112, "Error: Invalid pathname (%s)"),
838 (void) fprintf(stderr
, "\n");
841 path_phys
= argv
[path_index
];
842 if (err
= scsi_release(path_phys
)) {
843 (void) print_errString(err
, argv
[path_index
]);
847 exit_code
= adm_release(argv
[path_index
]);
852 if (Options
& ~(PVERBOSE
)) {
856 exit_code
= adm_start(&argv
[path_index
]);
860 if (Options
& ~(PVERBOSE
)) {
864 exit_code
= adm_stop(&argv
[path_index
]);
868 if (Options
& ~(PVERBOSE
| OPTION_CAPF
)) {
872 exit_code
= adm_power_off(&argv
[path_index
], 1);
876 if (Options
& (~PVERBOSE
)) {
880 exit_code
= adm_power_off(&argv
[path_index
], 0);
888 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
892 exit_code
= adm_forcelip(&argv
[path_index
]);
896 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
|
897 OPTION_CAPF
| OPTION_A
| OPTION_B
| OPTION_F
|
898 OPTION_R
)) || !(Options
& (OPTION_A
| OPTION_B
)) ||
899 ((Options
& OPTION_A
) && (Options
& OPTION_B
))) {
903 adm_bypass_enable(&argv
[path_index
], 1);
907 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
|
908 OPTION_CAPF
| OPTION_A
| OPTION_B
| OPTION_F
|
909 OPTION_R
)) || !(Options
& (OPTION_A
| OPTION_B
)) ||
910 ((Options
& OPTION_A
) && (Options
& OPTION_B
))) {
914 adm_bypass_enable(&argv
[path_index
], 0);
916 case LUX_P_OFFLINE
: /* Offline a port */
917 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
921 exit_code
= adm_port_offline_online(&argv
[path_index
],
925 case LUX_P_ONLINE
: /* Online a port */
926 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
930 exit_code
= adm_port_offline_online(&argv
[path_index
],
935 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
940 exit_code
= fchba_display_link_status(&argv
[path_index
]);
942 display_link_status(&argv
[path_index
]);
947 if (!(Options
& (EXPERT
| OPTION_F
)) ||
948 (Options
& ~(PVERBOSE
| EXPERT
| OPTION_F
))) {
952 if (read_repos_file(file_name
) != 0) {
958 * Undocumented commands.
961 case CHECK_FILE
: /* Undocumented Cmd */
962 if (Options
& ~(PVERBOSE
)) {
966 exit_code
= adm_check_file(&argv
[path_index
],
967 (Options
& PVERBOSE
));
970 case DUMP
: /* Undocumented Cmd */
971 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
975 dump(&argv
[path_index
]);
978 case DUMP_MAP
: /* Undocumented Cmd */
979 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
984 exit_code
= fchba_dump_map(&argv
[path_index
]);
986 dump_map(&argv
[path_index
]);
991 if (Options
& ~(PVERBOSE
)) {
995 if (err
= sysdump(Options
& PVERBOSE
)) {
996 (void) print_errString(err
, NULL
);
1001 case PORT
: /* Undocumented command */
1002 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
1007 exit_code
= fchba_display_port(Options
& PVERBOSE
);
1009 exit_code
= adm_display_port(Options
& PVERBOSE
);
1014 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
1018 if (adm_port_loopback(argv
[path_index
], EXT_LOOPBACK
) < 0) {
1024 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
1028 if (adm_port_loopback(argv
[path_index
], INT_LOOPBACK
) < 0) {
1034 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
1038 if (adm_port_loopback(argv
[path_index
], NO_LOOPBACK
) < 0) {
1048 if (argv
[path_index
] == NULL
) {
1049 if ((err
= h_insertSena_fcdev()) != 0) {
1050 (void) print_errString(err
, NULL
);
1053 } else if ((err
= hotplug(INSERT_DEVICE
,
1056 Options
& OPTION_CAPF
)) != 0) {
1057 (void) print_errString(err
, argv
[path_index
]);
1062 if (err
= hotplug(REMOVE_DEVICE
, &argv
[path_index
],
1063 Options
& PVERBOSE
, Options
& OPTION_CAPF
)) {
1064 (void) print_errString(err
, argv
[path_index
]);
1069 /* for hotplug device operations */
1079 if (!(Options
& EXPERT
) || (Options
& ~(PVERBOSE
| EXPERT
))) {
1084 if (fchba_hotplug_e(cmd
, &argv
[path_index
],
1085 Options
& PVERBOSE
, Options
& OPTION_CAPF
) != 0) {
1089 if (hotplug_e(cmd
, &argv
[path_index
],
1090 Options
& PVERBOSE
, Options
& OPTION_CAPF
) != 0) {
1097 (void) fprintf(stderr
,
1098 MSGSTR(2213, "%s: subcommand decode failed.\n"),