예제 #1
0
static int
drd_rcm_remove_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc)
{
	char		**rlist;
	int		rv = 0;
	rcm_info_t	*rinfo;

	drd_dbg("drd_rcm_remove_cpu_notify...");

	if ((rlist = drd_rcm_cpu_rlist_init(rsrcs, nrsrc,
	    DRCTL_STATUS_CONFIG_SUCCESS)) == NULL) {
		drd_dbg("  no CPUs in the success state, nothing to do");
		return (0);
	}

	rv = rcm_notify_remove_list(rcm_hdl, rlist, 0, &rinfo);
	if (rv != RCM_SUCCESS) {
		drd_info("rcm_notify_remove_list failed: %d", rv);
		rcm_free_info(rinfo);
		rv = -1;
	}

	drd_rcm_cpu_rlist_fini(rlist);

	return (rv);
}
예제 #2
0
static int
drd_rcm_io_unconfig_request(drctl_rsrc_t *rsrc, int nrsrc)
{
	int		rv;
	char		*dev = rsrc->res_dev_path;
	rcm_info_t	*rinfo = NULL;

	if (nrsrc != 1) {
		drd_dbg("drd_io_unconfig_request: only 1 resource "
		    "allowed for I/O requests, passed %d resources\n", nrsrc);
		rsrc->status = DRCTL_STATUS_DENY;

		return (-1);
	}

	if ((rv = rcm_request_offline(rcm_hdl, dev, 0, &rinfo)) == RCM_SUCCESS)
		rsrc->status = DRCTL_STATUS_ALLOW;
	else {
		rcm_notify_online(rcm_hdl, dev, 0, NULL);
		rsrc->status = DRCTL_STATUS_DENY;
		rsrc->offset = (uintptr_t)rcm_info_table(rinfo);

	}

	rcm_free_info(rinfo);
	drd_dbg("drd_rcm_io_unconfig_request(%s) = %d", dev, rv);

	return (rv);
}
예제 #3
0
파일: cfga_rcm.c 프로젝트: andreiw/polaris
/*
 * sata_rcm_offline:
 *      Offline SATA resource consumers.
 */
cfga_sata_ret_t
sata_rcm_offline(const char *rsrc, char **errstring, char *rsrc_fixed,
		cfga_flags_t flags)
{
	int		rret;
	uint_t		rflags = 0;
	rcm_info_t	*rinfo = NULL;
	cfga_sata_ret_t	ret = CFGA_SATA_OK;

	if ((ret = sata_rcm_init(rsrc, flags, errstring, &rflags)) !=
	    CFGA_SATA_OK) {

		return (ret);
	}

	if ((rret = rcm_request_offline(rcm_handle, rsrc_fixed, rflags,
	    &rinfo)) != RCM_SUCCESS) {
		if (rinfo) {
			(void) sata_rcm_info_table(rinfo, errstring);
			rcm_free_info(rinfo);
			rinfo = NULL;
		}

		if (rret == RCM_FAILURE) {
			(void) sata_rcm_online(rsrc, errstring,
					rsrc_fixed, flags);
		}
		ret = CFGA_SATA_RCM_OFFLINE;
	}
	return (ret);
}
예제 #4
0
파일: cfga_rcm.c 프로젝트: andreiw/polaris
/*
 * sata_rcm_online:
 *      Online SATA resource consumers that were previously offlined.
 */
cfga_sata_ret_t
sata_rcm_online(const char *rsrc, char **errstring, char *rsrc_fixed,
		cfga_flags_t flags)
{
	rcm_info_t	*rinfo = NULL;
	cfga_sata_ret_t	ret = CFGA_SATA_OK;

	if ((ret = sata_rcm_init(rsrc, flags, errstring, NULL)) !=
	    CFGA_SATA_OK) {

		return (ret);
	}

	if (rcm_notify_online(rcm_handle, rsrc_fixed, 0, &rinfo) !=
	    RCM_SUCCESS && (rinfo != NULL)) {
		(void) sata_rcm_info_table(rinfo, errstring);
		rcm_free_info(rinfo);
		rinfo = NULL;
		ret = CFGA_SATA_RCM_ONLINE;
	}

	return (ret);
}
예제 #5
0
static int
drd_rcm_restore_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc)
{
	char		**rlist;
	char		**full_rlist;
	int		idx;
	int		ridx;
	int		state;
	int		rv = 0;
	rcm_info_t	*rinfo;

	drd_dbg("drd_rcm_restore_cpu_notify...");

	if ((full_rlist = drd_rcm_cpu_rlist_init(rsrcs, nrsrc,
	    DRCTL_STATUS_CONFIG_FAILURE)) == NULL) {
		drd_dbg("  no CPUs in the failed state, nothing to do");
		return (0);
	}

	/*
	 * Since the desired result of this operation is to
	 * restore resources to the online state, filter out
	 * the resources already in the online state before
	 * passing the list to RCM.
	 */

	/* allocate a zero filled array to ensure NULL terminated list */
	rlist = (char **)calloc((nrsrc + 1), sizeof (char *));
	if (rlist == NULL) {
		drd_err("calloc failed: %s", strerror(errno));
		rv = -1;
		goto done;
	}

	for (idx = 0, ridx = 0; full_rlist[idx] != NULL; idx++) {
		state = 0;
		rcm_get_rsrcstate(rcm_hdl, full_rlist[idx], &state);
		if (state != RCM_STATE_ONLINE) {
			rlist[ridx] = full_rlist[idx];
			ridx++;
		}
	}

	/* check if everything got filtered out */
	if (ridx == 0) {
		drd_dbg("  all CPUs already online, nothing to do");
		goto done;
	}

	rv = rcm_notify_online_list(rcm_hdl, rlist, 0, &rinfo);
	if (rv != RCM_SUCCESS) {
		drd_info("rcm_notify_online_list failed: %d", rv);
		rcm_free_info(rinfo);
		rv = -1;
	}

done:
	drd_rcm_cpu_rlist_fini(full_rlist);
	s_free(rlist);

	return (rv);
}
예제 #6
0
static int
drd_rcm_offline_cpu_request(drctl_rsrc_t *rsrcs, int nrsrc)
{
	char		**rlist;
	drctl_rsrc_t	*rsrc;
	int		idx;
	int		state;
	int		rv = 0;
	rcm_info_t	*rinfo = NULL;
	rcm_info_tuple_t *tuple = NULL;
	const char	*rsrcstr;
	const char	*errstr;

	drd_dbg("drd_rcm_offline_cpu_request...");

	if ((rlist = drd_rcm_cpu_rlist_init(rsrcs, nrsrc,
	    DRCTL_STATUS_INIT)) == NULL) {
		drd_err("unable to generate resource list");
		return (-1);
	}

	rv = rcm_request_offline_list(rcm_hdl, rlist, 0, &rinfo);
	if (rv == RCM_SUCCESS) {
		drd_dbg("RCM success, rinfo=%p", rinfo);
		goto done;
	}

	drd_dbg("RCM call failed (%d):", rv);

	/*
	 * Loop through the result of the operation and add
	 * any error messages to the resource structure.
	 */
	while ((tuple = rcm_info_next(rinfo, tuple)) != NULL) {

		/* find the resource of interest */
		rsrcstr = rcm_info_rsrc(tuple);
		rsrc = cpu_rsrcstr_to_rsrc(rsrcstr, rsrcs, nrsrc);

		if (rsrc == NULL) {
			drd_dbg("unable to find resource for %s", rsrcstr);
			continue;
		}

		errstr = rcm_info_error(tuple);

		if (errstr) {
			drd_dbg("  %s: '%s'", rsrcstr, errstr);
			rsrc->offset = (uintptr_t)strdup(errstr);
		}
	}

	rcm_free_info(rinfo);
	rv = 0;

done:
	/*
	 * Set the state of the resource based on the RCM
	 * state. CPUs in the offline state have the ok to
	 * proceed. All others have been blocked.
	 */
	for (idx = 0; rlist[idx] != NULL; idx++) {

		state = 0;
		rcm_get_rsrcstate(rcm_hdl, rlist[idx], &state);

		/* find the resource of interest */
		rsrc = cpu_rsrcstr_to_rsrc(rlist[idx], rsrcs, nrsrc);

		if (rsrc == NULL) {
			drd_dbg("unable to find resource for %s", rlist[idx]);
			continue;
		}

		rsrc->status = ((state == RCM_STATE_OFFLINE) ?
		    DRCTL_STATUS_ALLOW : DRCTL_STATUS_DENY);
	}

	drd_rcm_cpu_rlist_fini(rlist);

	return (rv);
}