Exemple #1
0
/*
 * Cleanup method. If the daemon is stopped, we (re)activate all cpus
 */
void reactivate_cpus()
{
	/*
	 * Only enable the number of cpus which where
	 * available at daemon startup time
	 */
	int cpuid, nc;

	cpuid = 0;
	/* suppress verbose messages on exit */
	debug = 0;
       /*
	* We check for num_cpu_start != 0 because we might want to
	* clean up, before we queried for the number on cpus at
	* startup
	*/
	if (num_cpu_start == 0)
		return;
	while (get_num_online_cpus() != num_cpu_start && cpuid < MAX_CPU) {
		nc = get_num_online_cpus();
		if (nc == num_cpu_start)
			return;
		if (nc > num_cpu_start && is_online(cpuid) == 1)
			hotunplug(cpuid);
		if (nc < num_cpu_start && is_online(cpuid) == 0)
			hotplug(cpuid);
		cpuid++;
	}
}
int monitor_hotplug(int action_ndx)
{
    /* This should probably be serialized - if PM runs in a separate
       context, it would seem possible for someone to "rmmmod usbdmonitor"
       (e.g. via "at") at the same time time PM decides to suspend.
       Unfortunately, there is no airtight way to accomplish that inside
       this module - once PM has called the registered fn, the "race"
       is on :(. */
    int rc;
    if (action_ndx < 0 || action_ndx > MHA_UNLOAD) {
        return(-EINVAL);
    }
    if (monitor_exiting) {
        if (MHA_UNLOAD != action_ndx) {
            return(-EINVAL);
	}
	if (MONITOR_UNLOADED == monitor.status ||
            MONITOR_UNLOADING == monitor.status) {
            /* No need to do it again... */
            return(0);
        }
    }
    printk(KERN_DEBUG "monitor_hotplug: agent: usbd interface: monitor action: %s\n", hotplug_actions[action_ndx]);
#if defined(CONFIG_USBD_PROCFS) && defined(CONFIG_PM)
    /* Sync - fire up the script and wait for it to echo something to
              /proc/usb-monitor (or else PM SUSPEND may not work) */
    init_MUTEX_LOCKED(&hotplug_done);
    /* fire up the script */
    rc = hotplug("usbd", "monitor", hotplug_actions[action_ndx]);
    if (0 == rc) {
        /* wait for the nudge from a write to /proc/usb-monitor */
        init_timer(&hotplug_timeout);
        hotplug_timeout.data = 0;
        hotplug_timeout.function = hotplug_sync_over;
        hotplug_timeout.expires = jiffies + HOTPLUG_SYNC_TIMEOUT;
        add_timer(&hotplug_timeout);
        down_interruptible(&hotplug_done);
        del_timer(&hotplug_timeout);
    }
#else
    /* Async - fire up the script and return */
    rc = hotplug("usbd", "monitor", hotplug_actions[action_ndx]);
#endif
    return(rc);
}
Exemple #3
0
/**
 * usbd_hotplug - call a hotplug script
 * @action: hotplug action
 */
int usbd_hotplug (char *interface, char *action)
{
#ifdef CONFIG_HOTPLUG
	dbg_init (1, "agent: usbd interface: %s action: %s", interface, action);
	return hotplug ("usbd", interface, action);
#else
	return (0);
#endif
}
Exemple #4
0
static void state_enter(void)
{

	switch (state) {
	case STATE_EARLY:
		LOG("- early -\n");
		watchdog_init(0);
		hotplug("/etc/hotplug.json");
		procd_coldplug();
		break;

	case STATE_INIT:
		// try to reopen incase the wdt was not available before coldplug
		watchdog_init(0);
		LOG("- init -\n");
		log_init();
		procd_connect_ubus();
		procd_inittab();
		procd_inittab_run("respawn");
		procd_inittab_run("askconsole");
		procd_inittab_run("askfirst");
		procd_inittab_run("sysinit");
		break;

	case STATE_RUNNING:
		LOG("- init complete -\n");
		break;

	case STATE_SHUTDOWN:
		LOG("- shutdown -\n");
		procd_inittab_run("shutdown");
		sync();
		break;

	case STATE_HALT:
		LOG("- reboot -\n");
		reboot(reboot_event);
		break;

	default:
		ERROR("Unhandled state %d\n", state);
		return;
	};
}
Exemple #5
0
static int video_wake_up(struct uterm_video *video)
{
	int ret;

	if (video_is_awake(video))
		return 0;

	ret = drmSetMaster(video->dumb.fd);
	if (ret) {
		log_err("cannot set DRM-master");
		return -EACCES;
	}

	video->flags |= VIDEO_AWAKE;
	ret = hotplug(video);
	if (ret) {
		video->flags &= ~VIDEO_AWAKE;
		drmDropMaster(video->dumb.fd);
		return ret;
	}

	show_displays(video);
	return 0;
}
Exemple #6
0
static void eval_cpu_rules(void)
{
	double diffs[CPUSTATS], diffs_total, percent_factor;
	char *procinfo_current, *procinfo_prev;
	int cpu, nr_cpus, on_off;

	nr_cpus = get_numcpus();
	procinfo_current = cpustat + history_current * cpustat_size;
	procinfo_prev = cpustat + history_prev * cpustat_size;

	diffs[0] = get_proc_value(procinfo_current, "user", ' ') -
		   get_proc_value(procinfo_prev, "user", ' ');
	diffs[1] = get_proc_value(procinfo_current, "nice", ' ') -
		   get_proc_value(procinfo_prev, "nice", ' ');
	diffs[2] = get_proc_value(procinfo_current, "system", ' ') -
		   get_proc_value(procinfo_prev, "system", ' ');
	diffs[3] = get_proc_value(procinfo_current, "idle", ' ') -
		   get_proc_value(procinfo_prev, "idle", ' ');
	diffs[4] = get_proc_value(procinfo_current, "iowait", ' ') -
		   get_proc_value(procinfo_prev, "iowait", ' ');
	diffs[5] = get_proc_value(procinfo_current, "irq", ' ') -
		   get_proc_value(procinfo_prev, "irq", ' ');
	diffs[6] = get_proc_value(procinfo_current, "softirq", ' ') -
		   get_proc_value(procinfo_prev, "softirq", ' ');
	diffs[7] = get_proc_value(procinfo_current, "steal", ' ') -
		   get_proc_value(procinfo_prev, "steal", ' ');
	diffs[8] = get_proc_value(procinfo_current, "guest", ' ') -
		   get_proc_value(procinfo_prev, "guest", ' ');
	diffs[9] = get_proc_value(procinfo_current, "guest_nice", ' ') -
		   get_proc_value(procinfo_prev, "guest_nice", ' ');

	diffs_total = get_proc_value(procinfo_current, "total_ticks", ' ') -
		      get_proc_value(procinfo_prev, "total_ticks", ' ');
	if (diffs_total == 0)
		diffs_total = 1;

	symbols.loadavg = get_proc_value(procinfo_current, "loadavg", ' ');
	symbols.runnable_proc = get_proc_value(procinfo_current,
					       "runnable_proc", ' ');
	symbols.onumcpus = get_proc_value(procinfo_current, "onumcpus", ' ');

	percent_factor = 100 * symbols.onumcpus;
	symbols.user = (diffs[0] / diffs_total) * percent_factor;
	symbols.nice = (diffs[1] / diffs_total) * percent_factor;
	symbols.system = (diffs[2] / diffs_total) * percent_factor;
	symbols.idle = (diffs[3] / diffs_total) * percent_factor;
	symbols.iowait = (diffs[4] / diffs_total) * percent_factor;
	symbols.irq = (diffs[5] / diffs_total) * percent_factor;
	symbols.softirq = (diffs[6] / diffs_total) * percent_factor;
	symbols.steal = (diffs[7] / diffs_total) * percent_factor;
	symbols.guest = (diffs[8] / diffs_total) * percent_factor;
	symbols.guest_nice = (diffs[9] / diffs_total) * percent_factor;

	/* only use this for development and testing */
	cpuplugd_debug("cpustat values:\n%s", cpustat + history_current *
		       cpustat_size);
	if (debug && foreground == 1) {
		printf("-------------------- CPU --------------------\n");
		printf("cpu_min: %ld\n", cfg.cpu_min);
		printf("cpu_max: %ld\n", cfg.cpu_max);
		printf("loadavg: %f \n", symbols.loadavg);
		printf("user percent = %f\n", symbols.user);
		printf("nice percent = %f\n", symbols.nice);
		printf("system percent = %f\n", symbols.system);
		printf("idle percent = %f\n", symbols.idle);
		printf("iowait percent = %f\n", symbols.iowait);
		printf("irq percent = %f\n", symbols.irq);
		printf("softirq percent = %f\n", symbols.softirq);
		printf("steal percent = %f\n", symbols.steal);
		printf("guest percent = %f\n", symbols.guest);
		printf("guest_nice percent = %f\n", symbols.guest_nice);
		printf("numcpus %d\n", nr_cpus);
		printf("runnable_proc: %d\n", (int) symbols.runnable_proc);
		printf("---------------------------------------------\n");
		printf("onumcpus:   %d\n", (int) symbols.onumcpus);
		printf("---------------------------------------------\n");
		printf("hotplug: ");
		print_term(cfg.hotplug);
		printf("\n");
		printf("hotunplug: ");
		print_term(cfg.hotunplug);
		printf("\n");
		printf("---------------------------------------------\n");
	}

	on_off = 0;
	/* Evaluate the hotplug rule */
	if (eval_term(cfg.hotplug, &symbols))
		on_off++;
	/* Evaluate the hotunplug rule only if hotplug did not match */
	else if (eval_term(cfg.hotunplug, &symbols))
		on_off--;
	if (on_off > 0) {
		/* check the cpu nr limit */
		if (symbols.onumcpus + 1 > cfg.cpu_max) {
			/* cpu limit reached */
			cpuplugd_debug("maximum cpu limit is reached\n");
			return;
		}
		/* try to find a offline cpu */
		for (cpu = 0; cpu < nr_cpus; cpu++)
			if (is_online(cpu) == 0 && cpu_is_configured(cpu) != 0)
				break;
		if (cpu < nr_cpus) {
			cpuplugd_debug("cpu with id %d is currently offline "
				       "and will be enabled\n", cpu);
			if (hotplug(cpu) == -1)
				cpuplugd_debug("unable to find a cpu which "
					       "can be enabled\n");
		} else {
			/*
			 * In case we tried to enable a cpu but this failed.
			 * This is the case if a cpu is deconfigured
			 */
			cpuplugd_debug("unable to find a cpu which can "
				       "be enabled\n");
		}
	} else if (on_off < 0) {
		/* check cpu nr limit */
		if (symbols.onumcpus <= cfg.cpu_min) {
			cpuplugd_debug("minimum cpu limit is reached\n");
			return;
		}
		/* try to find a online cpu */
		for (cpu = get_numcpus() - 1; cpu >= 0; cpu--) {
			if (is_online(cpu) != 0)
				break;
		}
		if (cpu > 0) {
			cpuplugd_debug("cpu with id %d is currently online "
				       "and will be disabled\n", cpu);
			hotunplug(cpu);
		}
	}
}
Exemple #7
0
static int video_poll(struct uterm_video *video)
{
	video->flags |= VIDEO_HOTPLUG;
	return hotplug(video);
}
Exemple #8
0
int main(int argc, char **argv)
{
	char *busid = NULL;
	char *remote_host = NULL;

	enum {
		cmd_unknown = 0,
		cmd_use_by_usbip,
		cmd_use_by_other,
		cmd_list,
		cmd_scriptlist,
		cmd_autobind,
		cmd_export_to,
		cmd_unexport,
		cmd_help,
		cmd_hotplug
	} cmd = cmd_unknown;

	if (geteuid() != 0)
		g_warning("running non-root?");

	for (;;) {
		int c;
		int index = 0;

		c = getopt_long(argc, argv, "u:o:hlsae:x:b:H", longopts, &index);
		if (c == -1)
			break;

		switch (c) {
			case 'u':
				cmd = cmd_use_by_usbip;
				busid = optarg;
				break;
			case 'o' :
				cmd = cmd_use_by_other;
				busid = optarg;
				break;
			case 'l' :
				cmd = cmd_list;
				break;
			case 's' :
				cmd = cmd_scriptlist;
				break;
			case 'a' :
				cmd = cmd_autobind;
				break;
			case 'b':
				busid = optarg;
				break;
			case 'e':
				cmd = cmd_export_to;
				remote_host = optarg;
				break;
			case 'x':
				cmd = cmd_unexport;
				remote_host = optarg;
				break;
			case 'H':
				cmd = cmd_hotplug;
				break;
			case 'h': /* fallthrough */
			case '?':
				cmd = cmd_help;
				break;
			default:
				g_error("getopt");
		}

		//if (cmd)
		//	break;
	}

	switch (cmd) {
		case cmd_use_by_usbip:
			use_device_by_usbip(busid);
			break;
		case cmd_use_by_other:
			use_device_by_other(busid);
			break;
		case cmd_list:
			show_devices();
			break;
		case cmd_scriptlist:
			show_devices_script();
			break;
		case cmd_autobind:
			auto_bind();
			break;
		case cmd_export_to:
			export_to(remote_host, busid);
			break;
		case cmd_unexport:
			unexport_from(remote_host, busid);
			break;
		case cmd_hotplug:
			hotplug();
			break;
		case cmd_help: /* fallthrough */
		case cmd_unknown:
			show_help();
			break;
		default:
			g_error("NOT REACHED");
	}

	return 0;
}
Exemple #9
0
static void set_console(void)
{
	const char* tty;
	char* split;
	char line[ 20 ];
	const char* try[] = { "tty0", "console", NULL }; /* Try the most common outputs */
	int f, i = 0;

	tty = get_cmdline_val("console",line,sizeof(line));
	if (tty != NULL) {
		split = strchr(tty, ',');
		if ( split != NULL )
			*split = '\0';
	} else {
		// Try a default
		tty=try[i];
		i++;
	}

	if (chdir("/dev")) {
		ERROR("failed to change dir to /dev\n");
		return;
	}
	while (tty!=NULL) {
		f = open(tty, O_RDONLY);
		if (f >= 0) {
			close(f);
			break;
		}

		tty=try[i];
		i++;
	}
	if (chdir("/"))
		ERROR("failed to change dir to /\n");

	if (tty != NULL)
		set_stdio(tty);
}

static void state_enter(void)
{
	char ubus_cmd[] = "/sbin/ubusd";

	switch (state) {
	case STATE_EARLY:
		LOG("- early -\n");
		watchdog_init(0);
		hotplug("/etc/hotplug.json");
		procd_coldplug();
		break;

	case STATE_UBUS:
		// try to reopen incase the wdt was not available before coldplug
		watchdog_init(0);
		set_stdio("console");
		LOG("- ubus -\n");
		procd_connect_ubus();
		service_start_early("ubus", ubus_cmd);
		break;

	case STATE_INIT:
		LOG("- init -\n");
		procd_inittab();
		procd_inittab_run("respawn");
		procd_inittab_run("askconsole");
		procd_inittab_run("askfirst");
		procd_inittab_run("sysinit");

		// switch to syslog log channel
		ulog_open(ULOG_SYSLOG, LOG_DAEMON, "procd");
		break;

	case STATE_RUNNING:
		LOG("- init complete -\n");
		break;

	case STATE_SHUTDOWN:
		/* Redirect output to the console for the users' benefit */
		set_console();
		LOG("- shutdown -\n");
		procd_inittab_run("shutdown");
		sync();
		break;

	case STATE_HALT:
		// To prevent killed processes from interrupting the sleep
		signal(SIGCHLD, SIG_IGN);
		LOG("- SIGTERM processes -\n");
		kill(-1, SIGTERM);
		sync();
		sleep(1);
		LOG("- SIGKILL processes -\n");
		kill(-1, SIGKILL);
		sync();
		sleep(1);
#ifndef DISABLE_INIT
		if (reboot_event == RB_POWER_OFF)
			LOG("- power down -\n");
		else
			LOG("- reboot -\n");

		/* Allow time for last message to reach serial console, etc */
		sleep(1);

		/* We have to fork here, since the kernel calls do_exit(EXIT_SUCCESS)
		 * in linux/kernel/sys.c, which can cause the machine to panic when
		 * the init process exits... */
		if (!vfork( )) { /* child */
			reboot(reboot_event);
			_exit(EXIT_SUCCESS);
		}
		while (1)
			sleep(1);
#else
		exit(0);
#endif
		break;

	default:
		ERROR("Unhandled state %d\n", state);
		return;
	};
}

void procd_state_next(void)
{
	DEBUG(4, "Change state %d -> %d\n", state, state + 1);
	state++;
	state_enter();
}

void procd_state_ubus_connect(void)
{
	if (state == STATE_UBUS)
		procd_state_next();
}

void procd_shutdown(int event)
{
	if (state >= STATE_SHUTDOWN)
		return;
	DEBUG(2, "Shutting down system with event %x\n", event);
	reboot_event = event;
	state = STATE_SHUTDOWN;
	state_enter();
}
Exemple #10
0
/* main functions. */
int
main(int argc, char **argv)
{
register int 	c;
/* getopt varbs */
extern char *optarg;
char		*optstring = NULL;
int		path_index, err = 0;
int		cmd = 0;		/* Cmd verb from cmd line */
int		exit_code = 0;		/* exit code for program */
int		temp_fd;		/* For -f option */
char		*file_name = NULL;
int		option_t_input;
char		*path_phys = NULL;
int		USE_FCHBA = 0;

	whoami = argv[0];


	/*
	 * Enable locale announcement
	 */
	i18n_catopen();

	while ((c = getopt(argc, argv, "ve"))
	    != EOF) {
	    switch (c) {
		case 'v':
		    Options |= PVERBOSE;
		    break;
		case 'e':
		    Options |= EXPERT;
		    break;
		default:
		    /* Note: getopt prints an error if invalid option */
		    USEAGE()
		    exit(-1);
	    } /* End of switch(c) */
	}
	setbuf(stdout, NULL);	/* set stdout unbuffered. */

	/*
	 * Build any i18n global variables
	 */
	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");



	/*
	 * Get subcommand.
	 */
	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);
	}

	/* Extract & Save subcommand options */
	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:
		    /* Note: getopt prints an error if invalid option */
		    USEAGE()
		    exit(-1);
	    } /* End of switch(c) */
	}
	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;

	/*
	 * Check if the file supplied with the -f option is valid
	 * Some sub commands (bypass for example) use the -f option
	 * for other reasons. In such cases, "file_name" should be
	 * NULL.
	 */
	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);
		}
	}

	/* Determine which mode to operate in (FC-HBA or original) */
	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);
		}
		/* Display object(s) */
		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);
		}
		/*
		 * A special check just in case someone entered
		 * any characters after the -p or the probe.
		 *
		 * (I know, a nit.)
		 */
		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:	/* Update Fcode in all cards */
			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:	/* Update Fcode in PCI HBA card(s) */
			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:	/* Update Fcode in Sbus soc+ card */
			if ((Options & ~(PVERBOSE)) & ~(OPTION_F) ||
			    argv[path_index]) {
				USEAGE();
				exit(-1);
			}
			exit_code = fcal_update(Options & PVERBOSE, file_name);
			break;

	    case	SET_BOOT_DEV:   /* Set boot-device variable in nvram */
			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;
		    /* Just stat the argument and make sure it exists */
		    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;
		    /* Just stat the argument and make sure it exists */
		    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;

	/*
	 * EXPERT commands.
	 */

	    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:	/* Offline a port */
		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:	/* Online a port */
		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;

	/*
	 * Undocumented commands.
	 */

	    case	CHECK_FILE:	/* Undocumented Cmd */
		if (Options & ~(PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		exit_code = adm_check_file(&argv[path_index],
		    (Options & PVERBOSE));
		break;

	    case	DUMP:		/* Undocumented Cmd */
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			USEAGE();
			exit(-1);
		}
		dump(&argv[path_index]);
		break;

	    case	DUMP_MAP:	/* Undocumented Cmd */
		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: /* Undocumented command */
		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;

	/* for hotplug device operations */
	    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);
}