1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * CDDL HEADER START
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda *
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * The contents of this file are subject to the terms of the
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Common Development and Distribution License (the "License").
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * You may not use this file except in compliance with the License.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda *
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * or http://www.opensolaris.org/os/licensing.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * See the License for the specific language governing permissions
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * and limitations under the License.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda *
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * When distributing Covered Code, include this CDDL HEADER in each
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * If applicable, add the following below this CDDL HEADER, with the
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * fields enclosed by brackets "[]" replaced with your own identifying
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * information: Portions Copyright [yyyy] [name of copyright owner]
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda *
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * CDDL HEADER END
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Use is subject to license terms.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * RCM backend for the DR Daemon
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#include <unistd.h>
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#include <strings.h>
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#include <errno.h>
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#include <kstat.h>
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#include <libnvpair.h>
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#include <librcm.h>
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm#include <locale.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <assert.h>
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#include "drd.h"
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * RCM Backend Support
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_init(void);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_fini(void);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_cpu_config_request(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_cpu_config_notify(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_cpu_unconfig_request(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_cpu_unconfig_notify(drctl_rsrc_t *rsrcs, int nrsrc);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmstatic int drd_rcm_io_config_request(drctl_rsrc_t *rsrc, int nrsrc);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmstatic int drd_rcm_io_config_notify(drctl_rsrc_t *rsrc, int nrsrc);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmstatic int drd_rcm_io_unconfig_request(drctl_rsrc_t *rsrc, int nrsrc);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmstatic int drd_rcm_io_unconfig_notify(drctl_rsrc_t *rsrc, int nrsrc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int drd_rcm_mem_config_request(drctl_rsrc_t *rsrcs, int nrsrc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int drd_rcm_mem_config_notify(drctl_rsrc_t *rsrcs, int nrsrc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int drd_rcm_mem_unconfig_request(drctl_rsrc_t *rsrcs, int nrsrc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int drd_rcm_mem_unconfig_notify(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_backend_t drd_rcm_backend = {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_rcm_init, /* init */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_rcm_fini, /* fini */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_rcm_cpu_config_request, /* cpu_config_request */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_rcm_cpu_config_notify, /* cpu_config_notify */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_rcm_cpu_unconfig_request, /* cpu_unconfig_request */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_rcm_cpu_unconfig_notify, /* cpu_unconfig_notify */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_rcm_io_config_request, /* io_config_request */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_rcm_io_config_notify, /* io_config_notify */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_rcm_io_unconfig_request, /* io_unconfig_request */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_rcm_io_unconfig_notify, /* io_unconfig_notify */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_rcm_mem_config_request, /* mem_config_request */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_rcm_mem_config_notify, /* mem_config_notify */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_rcm_mem_unconfig_request, /* mem_unconfig_request */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_rcm_mem_unconfig_notify /* mem_unconfig_notify */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda};
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorotypedef int (*rcm_op_t)(rcm_handle_t *, char *, uint_t, nvlist_t *,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rcm_info_t **);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#define RCM_MEM_ALL "SUNW_memory"
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#define RCM_CPU_ALL "SUNW_cpu"
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#define RCM_CPU RCM_CPU_ALL"/cpu"
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#define RCM_CPU_MAX_LEN (32)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/* global RCM handle used in all RCM operations */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic rcm_handle_t *rcm_hdl;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/* functions that call into RCM */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_online_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_add_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_del_cpu_request(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_offline_cpu_request(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_remove_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_restore_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int drd_rcm_del_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/* utility functions */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic char **drd_rcm_cpu_rlist_init(drctl_rsrc_t *, int nrsrc, int status);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic void drd_rcm_cpu_rlist_fini(char **rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic drctl_rsrc_t *cpu_rsrcstr_to_rsrc(const char *, drctl_rsrc_t *, int);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int get_sys_cpuids(cpuid_t **cpuids, int *ncpuids);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic boolean_t is_cpu_in_list(cpuid_t cpuid, cpuid_t *list, int len);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmstatic char *rcm_info_table(rcm_info_t *rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/* debugging utility functions */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic void dump_cpu_list(char *prefix, cpuid_t *cpuids, int ncpuids);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic void dump_cpu_rsrc_list(char *prefix, drctl_rsrc_t *, int nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic void dump_cpu_rlist(char **rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_init(void)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_init...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = rcm_alloc_handle(NULL, 0, NULL, &rcm_hdl);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rv == RCM_FAILURE) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_err("unable to allocate RCM handle: %s", strerror(errno));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (-1);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (0);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_fini(void)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_fini...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rcm_hdl != NULL)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_free_handle(rcm_hdl);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (0);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_cpu_config_request(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_cpu_config_request...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_rsrc_list(NULL, rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * There is no RCM operation to request the addition
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm * of resources. So, by definition, the operation for
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * all the CPUs is allowed.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < nrsrc; idx++)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrcs[idx].status = DRCTL_STATUS_ALLOW;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_rsrc_list("returning:", rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (0);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_cpu_config_notify(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_cpu_config_notify...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_rsrc_list(NULL, rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* notify RCM about the newly added CPUs */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (drd_rcm_online_cpu_notify(rsrcs, nrsrc) != 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* notify RCM about the increased CPU capacity */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (drd_rcm_add_cpu_notify(rsrcs, nrsrc) != 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadone:
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_rsrc_list("returning:", rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_cpu_unconfig_request(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_cpu_unconfig_request...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_rsrc_list(NULL, rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* contact RCM to request a decrease in CPU capacity */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (drd_rcm_del_cpu_request(rsrcs, nrsrc) != 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* contact RCM to request the removal of CPUs */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (drd_rcm_offline_cpu_request(rsrcs, nrsrc) != 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadone:
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * If any errors occurred, the status field for
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * a CPU may still be in the INIT state. Set the
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * status for any such CPU to DENY to ensure it
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * gets processed properly.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < nrsrc; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rsrcs[idx].status == DRCTL_STATUS_INIT)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrcs[idx].status = DRCTL_STATUS_DENY;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_rsrc_list("returning:", rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_cpu_unconfig_notify(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_cpu_unconfig_notify...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_rsrc_list(NULL, rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Notify RCM about the CPUs that were removed.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Failures are ignored so that CPUs that could
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * not be unconfigured can be processed by RCM.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda (void) drd_rcm_remove_cpu_notify(rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Notify RCM about any CPUs that did not make it
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * in to the unconfigured state.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (drd_rcm_restore_cpu_notify(rsrcs, nrsrc) != 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* notify RCM about the decreased CPU capacity */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (drd_rcm_del_cpu_notify(rsrcs, nrsrc) != 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadone:
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_rsrc_list("returning:", rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_online_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char **rlist;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_info_t *rinfo;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_online_cpu_notify...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((rlist = drd_rcm_cpu_rlist_init(rsrcs, nrsrc,
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda DRCTL_STATUS_CONFIG_SUCCESS)) == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" no CPUs were successfully added, nothing to do");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (0);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_notify_online_list(rcm_hdl, rlist, 0, &rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rv != RCM_SUCCESS) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_info("rcm_notify_online_list failed: %d", rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_free_info(rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_rcm_cpu_rlist_fini(rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_add_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t *cpus = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int ncpus;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t *oldcpus = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t *newcpus = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int oldncpus = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int newncpus = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_t *nvl = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_info_t *rinfo;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_add_cpu_notify...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((rsrcs == NULL) || (nrsrc == 0)) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_err("add_cpu_notify: cpu list empty");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda ncpus = nrsrc;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpus = (cpuid_t *)malloc(nrsrc * sizeof (cpuid_t));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < nrsrc; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" cpu[%d] = %d", idx, rsrcs[idx].res_cpu_id);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpus[idx] = rsrcs[idx].res_cpu_id;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* allocate an nvlist for the RCM call */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Added CPU capacity, so newcpus is the current list
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * of CPUs in the system.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (get_sys_cpuids(&newcpus, &newncpus) == -1)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Since the operation added CPU capacity, the old CPU
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * list is the new CPU list with the CPUs involved in
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * the operation removed.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda oldcpus = (cpuid_t *)calloc(newncpus, sizeof (cpuid_t));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (oldcpus == NULL)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < newncpus; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (!is_cpu_in_list(newcpus[idx], cpus, ncpus))
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda oldcpus[oldncpus++] = newcpus[idx];
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* dump pre and post lists */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_list("oldcpus: ", oldcpus, oldncpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_list("newcpus: ", newcpus, newncpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_list("delta: ", cpus, ncpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* setup the nvlist for the RCM call */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (nvlist_add_string(nvl, "state", "capacity") ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32(nvl, "old_total", oldncpus) ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32(nvl, "new_total", newncpus) ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32_array(nvl, "old_cpu_list", oldcpus, oldncpus) ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32_array(nvl, "new_cpu_list", newcpus, newncpus)) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = rcm_notify_capacity_change(rcm_hdl, RCM_CPU_ALL, 0, nvl, &rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = (rv == RCM_SUCCESS) ? 0 : -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadone:
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_nvfree(nvl);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(cpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(oldcpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(newcpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_del_cpu_request(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t *cpus = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int ncpus;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t *oldcpus = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t *newcpus = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int oldncpus = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int newncpus = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_t *nvl = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_info_t *rinfo;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_del_cpu_request...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((rsrcs == NULL) || (nrsrc == 0)) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_err("del_cpu_request: cpu list empty");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda ncpus = nrsrc;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpus = (cpuid_t *)malloc(nrsrc * sizeof (cpuid_t));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < nrsrc; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpus[idx] = rsrcs[idx].res_cpu_id;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* allocate an nvlist for the RCM call */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Removing CPU capacity, so oldcpus is the current
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * list of CPUs in the system.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (get_sys_cpuids(&oldcpus, &oldncpus) == -1) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Since this is a request to remove CPU capacity,
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * the new CPU list is the old CPU list with the CPUs
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * involved in the operation removed.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda newcpus = (cpuid_t *)calloc(oldncpus, sizeof (cpuid_t));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (newcpus == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < oldncpus; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (!is_cpu_in_list(oldcpus[idx], cpus, ncpus))
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda newcpus[newncpus++] = oldcpus[idx];
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* dump pre and post lists */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_list("oldcpus: ", oldcpus, oldncpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_list("newcpus: ", newcpus, newncpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_list("delta: ", cpus, ncpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* setup the nvlist for the RCM call */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (nvlist_add_string(nvl, "state", "capacity") ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32(nvl, "old_total", oldncpus) ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32(nvl, "new_total", newncpus) ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32_array(nvl, "old_cpu_list", oldcpus, oldncpus) ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32_array(nvl, "new_cpu_list", newcpus, newncpus)) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = rcm_request_capacity_change(rcm_hdl, RCM_CPU_ALL, 0, nvl, &rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rv != RCM_SUCCESS) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("RCM call failed: %d", rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Since the capacity change was blocked, we
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * mark all CPUs as blocked. It is up to the
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * user to reframe the query so that it can
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * succeed.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < nrsrc; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrcs[idx].status = DRCTL_STATUS_DENY;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* tack on message to first resource */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrcs[0].offset = (uintptr_t)strdup("unable to remove "
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda "specified number of CPUs");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" unable to remove specified number of CPUs");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadone:
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_nvfree(nvl);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(cpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(oldcpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(newcpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_offline_cpu_request(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char **rlist;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drctl_rsrc_t *rsrc;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int state;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_info_t *rinfo = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_info_tuple_t *tuple = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda const char *rsrcstr;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda const char *errstr;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_offline_cpu_request...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((rlist = drd_rcm_cpu_rlist_init(rsrcs, nrsrc,
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda DRCTL_STATUS_INIT)) == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_err("unable to generate resource list");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (-1);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = rcm_request_offline_list(rcm_hdl, rlist, 0, &rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rv == RCM_SUCCESS) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("RCM success, rinfo=%p", rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("RCM call failed (%d):", rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Loop through the result of the operation and add
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * any error messages to the resource structure.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda while ((tuple = rcm_info_next(rinfo, tuple)) != NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* find the resource of interest */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrcstr = rcm_info_rsrc(tuple);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrc = cpu_rsrcstr_to_rsrc(rsrcstr, rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rsrc == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("unable to find resource for %s", rsrcstr);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda continue;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda errstr = rcm_info_error(tuple);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (errstr) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" %s: '%s'", rsrcstr, errstr);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrc->offset = (uintptr_t)strdup(errstr);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_free_info(rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadone:
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Set the state of the resource based on the RCM
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * state. CPUs in the offline state have the ok to
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * proceed. All others have been blocked.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; rlist[idx] != NULL; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda state = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_get_rsrcstate(rcm_hdl, rlist[idx], &state);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* find the resource of interest */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrc = cpu_rsrcstr_to_rsrc(rlist[idx], rsrcs, nrsrc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rsrc == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("unable to find resource for %s", rlist[idx]);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda continue;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrc->status = ((state == RCM_STATE_OFFLINE) ?
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda DRCTL_STATUS_ALLOW : DRCTL_STATUS_DENY);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_rcm_cpu_rlist_fini(rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_remove_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char **rlist;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_info_t *rinfo;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_remove_cpu_notify...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((rlist = drd_rcm_cpu_rlist_init(rsrcs, nrsrc,
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda DRCTL_STATUS_CONFIG_SUCCESS)) == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" no CPUs in the success state, nothing to do");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (0);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = rcm_notify_remove_list(rcm_hdl, rlist, 0, &rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rv != RCM_SUCCESS) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_info("rcm_notify_remove_list failed: %d", rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_free_info(rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_rcm_cpu_rlist_fini(rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_restore_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char **rlist;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char **full_rlist;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int ridx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int state;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_info_t *rinfo;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_restore_cpu_notify...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((full_rlist = drd_rcm_cpu_rlist_init(rsrcs, nrsrc,
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda DRCTL_STATUS_CONFIG_FAILURE)) == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" no CPUs in the failed state, nothing to do");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (0);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Since the desired result of this operation is to
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * restore resources to the online state, filter out
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * the resources already in the online state before
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * passing the list to RCM.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* allocate a zero filled array to ensure NULL terminated list */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rlist = (char **)calloc((nrsrc + 1), sizeof (char *));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rlist == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_err("calloc failed: %s", strerror(errno));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0, ridx = 0; full_rlist[idx] != NULL; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda state = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_get_rsrcstate(rcm_hdl, full_rlist[idx], &state);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (state != RCM_STATE_ONLINE) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rlist[ridx] = full_rlist[idx];
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda ridx++;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* check if everything got filtered out */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (ridx == 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" all CPUs already online, nothing to do");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = rcm_notify_online_list(rcm_hdl, rlist, 0, &rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rv != RCM_SUCCESS) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_info("rcm_notify_online_list failed: %d", rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_free_info(rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadone:
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_rcm_cpu_rlist_fini(full_rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_del_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t *cpus = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int rv = -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t *oldcpus = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t *newcpus = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int oldncpus = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int newncpus = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_t *nvl = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int cidx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_info_t *rinfo;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_del_cpu_notify...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((rsrcs == NULL) || (nrsrc == 0)) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_err("del_cpu_notify: cpu list empty");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpus = (cpuid_t *)malloc(nrsrc * sizeof (cpuid_t));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Filter out the CPUs that could not be unconfigured.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0, cidx = 0; idx < nrsrc; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rsrcs[idx].status != DRCTL_STATUS_CONFIG_SUCCESS)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda continue;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" cpu[%d] = %d", idx, rsrcs[idx].res_cpu_id);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpus[cidx] = rsrcs[idx].res_cpu_id;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cidx++;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" ncpus = %d", cidx);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* nothing to do */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (cidx == 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* allocate an nvlist for the RCM call */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Removed CPU capacity, so newcpus is the current list
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * of CPUs in the system.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (get_sys_cpuids(&newcpus, &newncpus) == -1) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Since the operation removed CPU capacity, the old CPU
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * list is the new CPU list with the CPUs involved in
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * the operation added.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda oldcpus = (cpuid_t *)calloc(newncpus + cidx, sizeof (cpuid_t));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (oldcpus == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < newncpus; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (!is_cpu_in_list(newcpus[idx], cpus, cidx))
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda oldcpus[oldncpus++] = newcpus[idx];
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < cidx; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda oldcpus[oldncpus++] = cpus[idx];
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* dump pre and post lists */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_list("oldcpus: ", oldcpus, oldncpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_list("newcpus: ", newcpus, newncpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_list("delta: ", cpus, cidx);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* setup the nvlist for the RCM call */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (nvlist_add_string(nvl, "state", "capacity") ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32(nvl, "old_total", oldncpus) ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32(nvl, "new_total", newncpus) ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32_array(nvl, "old_cpu_list", oldcpus, oldncpus) ||
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda nvlist_add_int32_array(nvl, "new_cpu_list", newcpus, newncpus)) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda goto done;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = rcm_notify_capacity_change(rcm_hdl, RCM_CPU_ALL, 0, nvl, &rinfo);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rv = (rv == RCM_SUCCESS) ? 0 : -1;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadone:
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_nvfree(nvl);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(cpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(oldcpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(newcpus);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rv);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Given a list of resource structures, create a list of CPU
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * resource strings formatted as expected by RCM. Only resources
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * that are in the state specified by the status argument are
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * included in the resulting list.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic char **
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_cpu_rlist_init(drctl_rsrc_t *rsrcs, int nrsrc, int status)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char rbuf[RCM_CPU_MAX_LEN];
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char **rlist;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int ridx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_cpu_rlist_init...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((rsrcs == NULL) || (nrsrc == 0)) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("cpu list is empty");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (NULL);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* allocate a zero filled array to ensure NULL terminated list */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rlist = (char **)calloc((nrsrc + 1), sizeof (char *));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rlist == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_err("calloc failed: %s", strerror(errno));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (NULL);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0, ridx = 0; idx < nrsrc; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" checking cpu %d, status=%d, expected status=%d",
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrcs[idx].res_cpu_id, rsrcs[idx].status, status);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Filter out the CPUs that are not in
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * the requested state.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rsrcs[idx].status != status)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda continue;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* generate the resource string */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda (void) sprintf(rbuf, "%s%d", RCM_CPU, rsrcs[idx].res_cpu_id);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rlist[ridx] = strdup(rbuf);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rlist[ridx] == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_err("strdup failed: %s", strerror(errno));
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_rcm_cpu_rlist_fini(rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (NULL);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda ridx++;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* cleanup if the list is empty */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (ridx == 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("final rlist:");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_rlist(rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic void
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadrd_rcm_cpu_rlist_fini(char **rlist)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("drd_rcm_cpu_rlist_fini...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_rlist(rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; rlist[idx] != NULL; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(rlist[idx]);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda s_free(rlist);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Convert an RCM CPU resource string into a numerical cpuid.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Assumes the resource string has the form: "SUNW_cpu/cpu<C>"
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * where "<C>" is the numerical cpuid of interest.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic cpuid_t
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedacpu_rsrcstr_to_cpuid(const char *rsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char *cpuid_off;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t cpuid;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Search for the last occurrance of 'u' in the
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * expected RCM resource string "SUNW_cpu/cpu<C>".
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * This will give a pointer to the cpuid portion.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_off = strrchr(rsrc, 'u');
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_off++;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid = atoi(cpuid_off);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (cpuid);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda/*
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * Given an RCM CPU resource string, return a pointer to the
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * corresponding resource structure from the given resource list.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * NULL is returned if no matching resource structure can be
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda * found.
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic drctl_rsrc_t *
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedacpu_rsrcstr_to_rsrc(const char *rsrcstr, drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t cpuid;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid = cpu_rsrcstr_to_cpuid(rsrcstr);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < nrsrc; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rsrcs[idx].res_cpu_id == cpuid)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (&rsrcs[idx]);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (NULL);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic int
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedaget_sys_cpuids(cpuid_t **cpuids, int *ncpuids)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int ncpu = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int maxncpu;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda kstat_t *ksp;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda kstat_ctl_t *kc = NULL;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cpuid_t *cp;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("get_sys_cpuids...");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((maxncpu = sysconf(_SC_NPROCESSORS_MAX)) == -1)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (-1);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((kc = kstat_open()) == NULL)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (-1);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if ((cp = (cpuid_t *)calloc(maxncpu, sizeof (cpuid_t))) == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda (void) kstat_close(kc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (-1);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (strcmp(ksp->ks_module, "cpu_info") == 0)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda cp[ncpu++] = ksp->ks_instance;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda dump_cpu_list("syscpus: ", cp, ncpu);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda (void) kstat_close(kc);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda *cpuids = cp;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda *ncpuids = ncpu;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (0);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic boolean_t
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedais_cpu_in_list(cpuid_t cpuid, cpuid_t *list, int len)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (list == NULL)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (B_FALSE);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < len; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (list[idx] == cpuid)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (B_TRUE);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return (B_FALSE);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#define CPUIDS_PER_LINE 16
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda#define LINEWIDTH (2 * (CPUIDS_PER_LINE * 4))
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic void
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadump_cpu_list(char *prefix, cpuid_t *cpuids, int ncpuids)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char line[LINEWIDTH];
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char *curr;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int i, j;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* return if not debugging */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (drd_debug == 0)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* print just the prefix if CPU list is empty */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (ncpuids == 0) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (prefix)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("%s", prefix);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (i = 0; i < ncpuids; i += CPUIDS_PER_LINE) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda bzero(line, LINEWIDTH);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda curr = line;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* start with the prefix */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda (void) sprintf(curr, "%s", (prefix) ? prefix : "");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda curr = line + strlen(line);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* format the CPUs for this line */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (j = 0; (j < CPUIDS_PER_LINE) && ((i + j) < ncpuids); j++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda (void) sprintf(curr, "%3d ", cpuids[i + j]);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda curr = line + strlen(line);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("%s", line);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic void
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadump_cpu_rsrc_list(char *prefix, drctl_rsrc_t *rsrcs, int nrsrc)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda char *errstr;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* just return if not debugging */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (drd_debug == 0)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (prefix)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg("%s", prefix);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; idx < nrsrc; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* get a pointer to the error string */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda errstr = (char *)(uintptr_t)rsrcs[idx].offset;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" cpu[%d]: cpuid=%d, status=%d, errstr='%s'", idx,
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rsrcs[idx].res_cpu_id, rsrcs[idx].status,
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda (errstr != NULL) ? errstr : "");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedastatic void
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaedadump_cpu_rlist(char **rlist)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda{
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int idx;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda int state;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda static char *rcm_state_str[] = {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda "UNKNOWN", "ONLINE", "ONLINING",
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda "OFFLINE_FAIL", "OFFLINING", "OFFLINE",
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda "REMOVING", "INVALID_7", "INVALID_8",
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda "INVALID_9", "RESUMING", "SUSPEND_FAIL",
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda "SUSPENDING", "SUSPEND", "REMOVE",
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda "OFFLINE_QUERYING", "OFFLINE_QUERY_FAIL", "OFFLINE_QUERY",
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda "SUSPEND_QUERYING", "SUSPEND_QUERY_FAIL", "SUSPEND_QUERY"
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda };
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda /* just return if not debugging */
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (drd_debug == 0)
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda if (rlist == NULL) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" empty rlist");
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda return;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda for (idx = 0; rlist[idx] != NULL; idx++) {
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda state = 0;
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rcm_get_rsrcstate(rcm_hdl, rlist[idx], &state);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda drd_dbg(" rlist[%d]: rsrc=%s, state=%-2d (%s)", idx,
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda rlist[idx], state, rcm_state_str[state]);
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda }
1d4b38e0077763e7c9b20768eacb841957e787bcrsmaeda}
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmstatic int
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmdrd_rcm_io_config_request(drctl_rsrc_t *rsrc, int nrsrc)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm{
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_dbg("drd_rcm_io_config_request...");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if (nrsrc != 1) {
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_dbg("drd_rcm_cpu_config_request: only 1 resource "
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm "allowed for I/O requests, passed %d resources\n", nrsrc);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rsrc->status = DRCTL_STATUS_DENY;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (-1);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm }
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /*
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm * There is no RCM operation to request the addition
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm * of resources. So, by definition, the operation for
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm * the current resource is allowed.
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rsrc->status = DRCTL_STATUS_ALLOW;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (0);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm}
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm/*ARGSUSED*/
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmstatic int
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmdrd_rcm_io_config_notify(drctl_rsrc_t *rsrcs, int nrsrc)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm{
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_dbg("drd_rcm_io_config_notify...");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if (nrsrc != 1) {
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_dbg("drd_rcm_cpu_config_notify: only 1 resource "
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm "allowed for I/O requests, passed %d resources\n", nrsrc);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (-1);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm }
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (0);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm}
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmstatic int
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmdrd_rcm_io_unconfig_request(drctl_rsrc_t *rsrc, int nrsrc)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm{
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm int rv;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm char *dev = rsrc->res_dev_path;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rcm_info_t *rinfo = NULL;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if (nrsrc != 1) {
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_dbg("drd_io_unconfig_request: only 1 resource "
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm "allowed for I/O requests, passed %d resources\n", nrsrc);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rsrc->status = DRCTL_STATUS_DENY;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (-1);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm }
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if ((rv = rcm_request_offline(rcm_hdl, dev, 0, &rinfo)) == RCM_SUCCESS)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rsrc->status = DRCTL_STATUS_ALLOW;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm else {
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rcm_notify_online(rcm_hdl, dev, 0, NULL);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rsrc->status = DRCTL_STATUS_DENY;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rsrc->offset = (uintptr_t)rcm_info_table(rinfo);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm }
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rcm_free_info(rinfo);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_dbg("drd_rcm_io_unconfig_request(%s) = %d", dev, rv);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (rv);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm}
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmstatic int
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmdrd_rcm_io_unconfig_notify(drctl_rsrc_t *rsrc, int nrsrc)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm{
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_dbg("drd_rcm_io_unconfig_notify...");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if (nrsrc != 1) {
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_dbg("drd_io_cpu_unconfig_notify: only 1 resource "
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm "allowed for I/O requests, passed %d resources\n", nrsrc);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (-1);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm }
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (rcm_notify_remove(rcm_hdl, rsrc->res_dev_path, 0, NULL));
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm}
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm#define MAX_FORMAT 80
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm/*
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm * Convert rcm_info_t data into a printable table.
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmstatic char *
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jmrcm_info_table(rcm_info_t *rinfo)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm{
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm int i;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm size_t w;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm size_t width = 0;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm size_t w_rsrc = 0;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm size_t w_info = 0;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm size_t table_size = 0;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm uint_t tuples = 0;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rcm_info_tuple_t *tuple = NULL;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm char *rsrc;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm char *info;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm char *table;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm static char format[MAX_FORMAT];
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm const char *infostr;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* Protect against invalid arguments */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if (rinfo == NULL)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (NULL);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* Set localized table header strings */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm rsrc = dgettext(TEXT_DOMAIN, "Resource");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm info = dgettext(TEXT_DOMAIN, "Information");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* A first pass, to size up the RCM information */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm while (tuple = rcm_info_next(rinfo, tuple)) {
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if ((infostr = rcm_info_info(tuple)) != NULL) {
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm tuples++;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if ((w = strlen(rcm_info_rsrc(tuple))) > w_rsrc)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm w_rsrc = w;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if ((w = strlen(infostr)) > w_info)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm w_info = w;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm }
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm }
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* If nothing was sized up above, stop early */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if (tuples == 0)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (NULL);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* Adjust column widths for column headings */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if ((w = strlen(rsrc)) > w_rsrc)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm w_rsrc = w;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm else if ((w_rsrc - w) % 2)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm w_rsrc++;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if ((w = strlen(info)) > w_info)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm w_info = w;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm else if ((w_info - w) % 2)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm w_info++;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /*
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm * Compute the total line width of each line,
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm * accounting for intercolumn spacing.
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm width = w_info + w_rsrc + 4;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* Allocate space for the table */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm table_size = (2 + tuples) * (width + 1) + 2;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* zero fill for the strcat() call below */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm table = calloc(table_size, sizeof (char));
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if (table == NULL)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (NULL);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* Place a table header into the string */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* The resource header */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, "\n");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm w = strlen(rsrc);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm for (i = 0; i < ((w_rsrc - w) / 2); i++)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, " ");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, rsrc);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm for (i = 0; i < ((w_rsrc - w) / 2); i++)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, " ");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* The information header */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, " ");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm w = strlen(info);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm for (i = 0; i < ((w_info - w) / 2); i++)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, " ");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, info);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm for (i = 0; i < ((w_info - w) / 2); i++)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, " ");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* Underline the headers */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, "\n");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm for (i = 0; i < w_rsrc; i++)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, "-");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, " ");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm for (i = 0; i < w_info; i++)
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, "-");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* Construct the format string */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) snprintf(format, MAX_FORMAT, "%%-%ds %%-%ds",
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (int)w_rsrc, (int)w_info);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm /* Add the tuples to the table string */
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm tuple = NULL;
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm while ((tuple = rcm_info_next(rinfo, tuple)) != NULL) {
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm if ((infostr = rcm_info_info(tuple)) != NULL) {
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) strcat(table, "\n");
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm (void) sprintf(&((table)[strlen(table)]),
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm format, rcm_info_rsrc(tuple),
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm infostr);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm }
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm }
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm drd_dbg("rcm_info_table: %s\n", table);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm return (table);
8fea755a86ff6c596183a4366bfbd59f1bfdfe55jm}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodump_mem_rsrc_list(char *prefix, drctl_rsrc_t *rsrcs, int nrsrc)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro char *errstr;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* just return if not debugging */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (drd_debug == 0)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (prefix)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg("%s", prefix);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nrsrc; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* get a pointer to the error string */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro errstr = (char *)(uintptr_t)rsrcs[idx].offset;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg(" mem[%d]: addr=0x%llx, size=0x%llx"
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro " status=%d, errstr='%s'", idx,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rsrcs[idx].res_mem_addr, rsrcs[idx].res_mem_size,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rsrcs[idx].status, (errstr != NULL) ? errstr : "");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodrd_rcm_mem_op(rcm_op_t op, uint64_t change)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv = -1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int pgsize;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro long oldpages;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro long newpages;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro nvlist_t *nvl = NULL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rcm_info_t *rinfo;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* allocate an nvlist for the RCM call */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((pgsize = sysconf(_SC_PAGE_SIZE)) == -1 ||
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (newpages = sysconf(_SC_PHYS_PAGES)) == -1)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * If this is a notify add, the capacity change
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * was positive and the current page count reflects
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * the new capacity level.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * If this is a request del, the capacity change
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * is negative and the current page count will
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * reflect the old capacity level.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro assert(change % pgsize == 0);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (change > 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro oldpages = newpages - (long)(change / pgsize);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro assert(newpages >= change / pgsize);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro oldpages = newpages;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro newpages = oldpages + (long)(change / pgsize);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg("oldpages=%lld newpages=%lld delta=%lld",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro oldpages, newpages, newpages - oldpages);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* setup the nvlist for the RCM call */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (nvlist_add_string(nvl, "state", "capacity") != 0 ||
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro nvlist_add_int32(nvl, "page_size", pgsize) != 0 ||
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro nvlist_add_int32(nvl, "old_pages", oldpages) != 0 ||
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro nvlist_add_int32(nvl, "new_pages", newpages) != 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = (*op)(rcm_hdl, RCM_MEM_ALL, 0, nvl, &rinfo);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = (rv == RCM_SUCCESS) ? 0 : -1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodone:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro s_nvfree(nvl);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * RCM clients can interpose only on removal of resources.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodrd_rcm_mem_config_request(drctl_rsrc_t *rsrcs, int nrsrc)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg("drd_rcm_mem_config_request...");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rsrcs == NULL) || (nrsrc == 0))
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (0);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dump_mem_rsrc_list(NULL, rsrcs, nrsrc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * There is no RCM operation to request the addition
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * of resources. So, by definition, the operation for
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * all the memory is allowed.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nrsrc; idx++)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rsrcs[idx].status = DRCTL_STATUS_ALLOW;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dump_mem_rsrc_list("returning:", rsrcs, nrsrc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (0);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodrd_rcm_mem_config_notify(drctl_rsrc_t *rsrcs, int nrsrc)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv = -1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro uint64_t change = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg("drd_rcm_mem_config_notify...");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rsrcs == NULL) || (nrsrc == 0)) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_err("mem_config_notify: mem list empty");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dump_mem_rsrc_list(NULL, rsrcs, nrsrc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nrsrc; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rsrcs[idx].status == DRCTL_STATUS_CONFIG_SUCCESS)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro change += rsrcs[idx].res_mem_size;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg(" idx=%d addr=0x%llx size=0x%llx",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro idx, rsrcs[idx].res_mem_addr, rsrcs[idx].res_mem_size);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = drd_rcm_mem_op(rcm_notify_capacity_change, change);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodone:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodrd_rcm_mem_unconfig_request(drctl_rsrc_t *rsrcs, int nrsrc)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv = -1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro uint64_t change = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg("drd_rcm_del_mem_request...");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rsrcs == NULL) || (nrsrc == 0)) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_err("mem_unconfig_request: mem list empty");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dump_mem_rsrc_list(NULL, rsrcs, nrsrc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nrsrc; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg(" idx=%d addr=0x%llx size=0x%llx",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro idx, rsrcs[idx].res_mem_addr, rsrcs[idx].res_mem_size);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro change += rsrcs[idx].res_mem_size;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = drd_rcm_mem_op(rcm_request_capacity_change, -change);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rv != RCM_SUCCESS) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg("RCM call failed: %d", rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Since the capacity change was blocked, we
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * mark all mblocks as blocked. It is up to the
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * user to reframe the query so that it can
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * succeed.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nrsrc; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rsrcs[idx].status = DRCTL_STATUS_DENY;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* tack on message to first resource */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rsrcs[0].offset = (uintptr_t)strdup("unable to remove "
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "specified amount of memory");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg(" unable to remove specified amount of memory");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nrsrc; idx++)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rsrcs[idx].status = DRCTL_STATUS_ALLOW;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodone:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dump_mem_rsrc_list("returning:", rsrcs, nrsrc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodrd_rcm_mem_unconfig_notify(drctl_rsrc_t *rsrcs, int nrsrc)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv = -1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro uint64_t change = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg("drd_rcm_mem_unconfig_notify...");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rsrcs == NULL) || (nrsrc == 0)) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_err("unconfig_mem_notify: mem list empty");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dump_mem_rsrc_list(NULL, rsrcs, nrsrc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Filter out the memory that was configured.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * We need to notify RCM about a memory capacity change
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * only if the memory unconfigure request wasn't successful
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * because if both the RCM capacity delete request and the
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * memory unconfigure succeed, this notify would give a
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * memory capacity identical to the delete request.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nrsrc; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rsrcs[idx].status != DRCTL_STATUS_CONFIG_SUCCESS)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro change += rsrcs[idx].res_mem_size;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drd_dbg(" idx=%d addr=0x%llx size=0x%llx",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro idx, rsrcs[idx].res_mem_addr, rsrcs[idx].res_mem_size);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = drd_rcm_mem_op(rcm_notify_capacity_change, change);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodone:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}