1e4b86885SCheng Sean Ye /*
2e4b86885SCheng Sean Ye * CDDL HEADER START
3e4b86885SCheng Sean Ye *
4e4b86885SCheng Sean Ye * The contents of this file are subject to the terms of the
5e4b86885SCheng Sean Ye * Common Development and Distribution License (the "License").
6e4b86885SCheng Sean Ye * You may not use this file except in compliance with the License.
7e4b86885SCheng Sean Ye *
8e4b86885SCheng Sean Ye * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e4b86885SCheng Sean Ye * or http://www.opensolaris.org/os/licensing.
10e4b86885SCheng Sean Ye * See the License for the specific language governing permissions
11e4b86885SCheng Sean Ye * and limitations under the License.
12e4b86885SCheng Sean Ye *
13e4b86885SCheng Sean Ye * When distributing Covered Code, include this CDDL HEADER in each
14e4b86885SCheng Sean Ye * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15e4b86885SCheng Sean Ye * If applicable, add the following below this CDDL HEADER, with the
16e4b86885SCheng Sean Ye * fields enclosed by brackets "[]" replaced with your own identifying
17e4b86885SCheng Sean Ye * information: Portions Copyright [yyyy] [name of copyright owner]
18e4b86885SCheng Sean Ye *
19e4b86885SCheng Sean Ye * CDDL HEADER END
20e4b86885SCheng Sean Ye */
21e4b86885SCheng Sean Ye
22e4b86885SCheng Sean Ye /*
23e4b86885SCheng Sean Ye * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24e4b86885SCheng Sean Ye * Use is subject to license terms.
25e4b86885SCheng Sean Ye */
26e4b86885SCheng Sean Ye
27e4b86885SCheng Sean Ye #include <stdlib.h>
28e4b86885SCheng Sean Ye #include <errno.h>
29e4b86885SCheng Sean Ye #include <sys/types.h>
30e4b86885SCheng Sean Ye #include <libnvpair.h>
31e4b86885SCheng Sean Ye #include <sys/fcntl.h>
32e4b86885SCheng Sean Ye #include <sys/devfm.h>
33e4b86885SCheng Sean Ye #include <fmd_agent_impl.h>
34e4b86885SCheng Sean Ye
35e4b86885SCheng Sean Ye static int
cleanup_set_errno(fmd_agent_hdl_t * hdl,nvlist_t * innvl,nvlist_t * outnvl,int err)36e4b86885SCheng Sean Ye cleanup_set_errno(fmd_agent_hdl_t *hdl, nvlist_t *innvl, nvlist_t *outnvl,
37e4b86885SCheng Sean Ye int err)
38e4b86885SCheng Sean Ye {
39*aab83bb8SJosef 'Jeff' Sipek nvlist_free(innvl);
40*aab83bb8SJosef 'Jeff' Sipek nvlist_free(outnvl);
41e4b86885SCheng Sean Ye return (fmd_agent_seterrno(hdl, err));
42e4b86885SCheng Sean Ye }
43e4b86885SCheng Sean Ye
44e4b86885SCheng Sean Ye static int
fmd_agent_physcpu_info_v1(fmd_agent_hdl_t * hdl,nvlist_t *** cpusp,uint_t * ncpup)45e4b86885SCheng Sean Ye fmd_agent_physcpu_info_v1(fmd_agent_hdl_t *hdl, nvlist_t ***cpusp,
46e4b86885SCheng Sean Ye uint_t *ncpup)
47e4b86885SCheng Sean Ye {
48e4b86885SCheng Sean Ye int err;
49e4b86885SCheng Sean Ye nvlist_t *nvl, **nvl_array, **cpus;
50e4b86885SCheng Sean Ye uint_t i, n;
51e4b86885SCheng Sean Ye
52e4b86885SCheng Sean Ye if ((err = fmd_agent_nvl_ioctl(hdl, FM_IOC_PHYSCPU_INFO, 1,
53e4b86885SCheng Sean Ye NULL, &nvl)) != 0)
54e4b86885SCheng Sean Ye return (cleanup_set_errno(hdl, NULL, NULL, err));
55e4b86885SCheng Sean Ye if ((err = nvlist_lookup_nvlist_array(nvl, FM_PHYSCPU_INFO_CPUS,
56e4b86885SCheng Sean Ye &cpus, &n)) != 0)
57e4b86885SCheng Sean Ye return (cleanup_set_errno(hdl, NULL, nvl, err));
58e4b86885SCheng Sean Ye
59e4b86885SCheng Sean Ye if ((nvl_array = umem_alloc(sizeof (nvlist_t *) * n, UMEM_DEFAULT))
60e4b86885SCheng Sean Ye == NULL)
61e4b86885SCheng Sean Ye return (cleanup_set_errno(hdl, NULL, nvl, errno));
62e4b86885SCheng Sean Ye for (i = 0; i < n; i++) {
63e4b86885SCheng Sean Ye if ((err = nvlist_dup(cpus[i], nvl_array + i, 0)) != 0) {
64e4b86885SCheng Sean Ye while (i > 0)
65e4b86885SCheng Sean Ye nvlist_free(nvl_array[--i]);
66e4b86885SCheng Sean Ye umem_free(nvl_array, sizeof (nvlist_t *) * n);
67e4b86885SCheng Sean Ye return (cleanup_set_errno(hdl, NULL, nvl, err));
68e4b86885SCheng Sean Ye }
69e4b86885SCheng Sean Ye }
70e4b86885SCheng Sean Ye
71e4b86885SCheng Sean Ye nvlist_free(nvl);
72e4b86885SCheng Sean Ye *cpusp = nvl_array;
73e4b86885SCheng Sean Ye *ncpup = n;
74e4b86885SCheng Sean Ye return (0);
75e4b86885SCheng Sean Ye }
76e4b86885SCheng Sean Ye
77e4b86885SCheng Sean Ye int
fmd_agent_physcpu_info(fmd_agent_hdl_t * hdl,nvlist_t *** cpusp,uint_t * ncpu)78e4b86885SCheng Sean Ye fmd_agent_physcpu_info(fmd_agent_hdl_t *hdl, nvlist_t ***cpusp, uint_t *ncpu)
79e4b86885SCheng Sean Ye {
80e4b86885SCheng Sean Ye uint32_t ver;
81e4b86885SCheng Sean Ye
82e4b86885SCheng Sean Ye if (fmd_agent_version(hdl, FM_CPU_INFO_VERSION, &ver) == -1)
83e4b86885SCheng Sean Ye return (fmd_agent_seterrno(hdl, errno));
84e4b86885SCheng Sean Ye
85e4b86885SCheng Sean Ye switch (ver) {
86e4b86885SCheng Sean Ye case 1:
87e4b86885SCheng Sean Ye return (fmd_agent_physcpu_info_v1(hdl, cpusp, ncpu));
88e4b86885SCheng Sean Ye
89e4b86885SCheng Sean Ye default:
90e4b86885SCheng Sean Ye return (fmd_agent_seterrno(hdl, ENOTSUP));
91e4b86885SCheng Sean Ye }
92e4b86885SCheng Sean Ye }
93e4b86885SCheng Sean Ye
94e4b86885SCheng Sean Ye static int
fmd_agent_cpuop_v1(fmd_agent_hdl_t * hdl,int cmd,int chipid,int coreid,int strandid,int * old_status)95e4b86885SCheng Sean Ye fmd_agent_cpuop_v1(fmd_agent_hdl_t *hdl, int cmd, int chipid, int coreid,
96e4b86885SCheng Sean Ye int strandid, int *old_status)
97e4b86885SCheng Sean Ye {
98e4b86885SCheng Sean Ye int err;
99e4b86885SCheng Sean Ye nvlist_t *nvl = NULL, *outnvl = NULL;
100e4b86885SCheng Sean Ye int32_t status;
101e4b86885SCheng Sean Ye
102e4b86885SCheng Sean Ye if ((err = nvlist_alloc(&nvl, NV_UNIQUE_NAME_TYPE, 0)) != 0 ||
103e4b86885SCheng Sean Ye (err = nvlist_add_int32(nvl, FM_CPU_RETIRE_CHIP_ID, chipid)) != 0 ||
104e4b86885SCheng Sean Ye (err = nvlist_add_int32(nvl, FM_CPU_RETIRE_CORE_ID, coreid)) != 0 ||
105e4b86885SCheng Sean Ye (err = nvlist_add_int32(nvl, FM_CPU_RETIRE_STRAND_ID, strandid))
106e4b86885SCheng Sean Ye != 0 || (err = fmd_agent_nvl_ioctl(hdl, cmd, 1, nvl, &outnvl)) != 0)
107e4b86885SCheng Sean Ye return (cleanup_set_errno(hdl, nvl, NULL, err));
108e4b86885SCheng Sean Ye
109e4b86885SCheng Sean Ye nvlist_free(nvl);
110e4b86885SCheng Sean Ye if (outnvl != NULL) {
111e4b86885SCheng Sean Ye if (old_status != NULL) {
112e4b86885SCheng Sean Ye (void) nvlist_lookup_int32(outnvl,
113e4b86885SCheng Sean Ye FM_CPU_RETIRE_OLDSTATUS, &status);
114e4b86885SCheng Sean Ye *old_status = status;
115e4b86885SCheng Sean Ye }
116e4b86885SCheng Sean Ye nvlist_free(outnvl);
117e4b86885SCheng Sean Ye }
118e4b86885SCheng Sean Ye
119e4b86885SCheng Sean Ye return (0);
120e4b86885SCheng Sean Ye }
121e4b86885SCheng Sean Ye
122e4b86885SCheng Sean Ye static int
fmd_agent_cpuop(fmd_agent_hdl_t * hdl,int cmd,int chipid,int coreid,int strandid,int * old_status)123e4b86885SCheng Sean Ye fmd_agent_cpuop(fmd_agent_hdl_t *hdl, int cmd, int chipid, int coreid,
124e4b86885SCheng Sean Ye int strandid, int *old_status)
125e4b86885SCheng Sean Ye {
126e4b86885SCheng Sean Ye uint32_t ver;
127e4b86885SCheng Sean Ye
128e4b86885SCheng Sean Ye if (fmd_agent_version(hdl, FM_CPU_OP_VERSION, &ver) == -1)
129e4b86885SCheng Sean Ye return (cleanup_set_errno(hdl, NULL, NULL, errno));
130e4b86885SCheng Sean Ye
131e4b86885SCheng Sean Ye switch (ver) {
132e4b86885SCheng Sean Ye case 1:
133e4b86885SCheng Sean Ye return (fmd_agent_cpuop_v1(hdl, cmd, chipid, coreid, strandid,
134e4b86885SCheng Sean Ye old_status));
135e4b86885SCheng Sean Ye
136e4b86885SCheng Sean Ye default:
137e4b86885SCheng Sean Ye return (fmd_agent_seterrno(hdl, ENOTSUP));
138e4b86885SCheng Sean Ye }
139e4b86885SCheng Sean Ye }
140e4b86885SCheng Sean Ye
141e4b86885SCheng Sean Ye int
fmd_agent_cpu_retire(fmd_agent_hdl_t * hdl,int chipid,int coreid,int strandid)142e4b86885SCheng Sean Ye fmd_agent_cpu_retire(fmd_agent_hdl_t *hdl, int chipid, int coreid, int strandid)
143e4b86885SCheng Sean Ye {
144e4b86885SCheng Sean Ye int ret;
145e4b86885SCheng Sean Ye
146e4b86885SCheng Sean Ye ret = fmd_agent_cpuop(hdl, FM_IOC_CPU_RETIRE, chipid, coreid, strandid,
147e4b86885SCheng Sean Ye NULL);
148e4b86885SCheng Sean Ye
149e4b86885SCheng Sean Ye return (ret == 0 ? FMD_AGENT_RETIRE_DONE : FMD_AGENT_RETIRE_FAIL);
150e4b86885SCheng Sean Ye }
151e4b86885SCheng Sean Ye
152e4b86885SCheng Sean Ye int
fmd_agent_cpu_isretired(fmd_agent_hdl_t * hdl,int chipid,int coreid,int strandid)153e4b86885SCheng Sean Ye fmd_agent_cpu_isretired(fmd_agent_hdl_t *hdl, int chipid, int coreid,
154e4b86885SCheng Sean Ye int strandid)
155e4b86885SCheng Sean Ye {
156e4b86885SCheng Sean Ye int ret, status;
157e4b86885SCheng Sean Ye
158e4b86885SCheng Sean Ye ret = fmd_agent_cpuop(hdl, FM_IOC_CPU_STATUS, chipid, coreid, strandid,
159e4b86885SCheng Sean Ye &status);
160e4b86885SCheng Sean Ye
161e4b86885SCheng Sean Ye return (ret == 0 && status != P_ONLINE ?
162e4b86885SCheng Sean Ye FMD_AGENT_RETIRE_DONE : FMD_AGENT_RETIRE_FAIL);
163e4b86885SCheng Sean Ye }
164e4b86885SCheng Sean Ye
165e4b86885SCheng Sean Ye int
fmd_agent_cpu_unretire(fmd_agent_hdl_t * hdl,int chipid,int coreid,int strandid)166e4b86885SCheng Sean Ye fmd_agent_cpu_unretire(fmd_agent_hdl_t *hdl, int chipid, int coreid,
167e4b86885SCheng Sean Ye int strandid)
168e4b86885SCheng Sean Ye {
169e4b86885SCheng Sean Ye int ret;
170e4b86885SCheng Sean Ye
171e4b86885SCheng Sean Ye ret = fmd_agent_cpuop(hdl, FM_IOC_CPU_UNRETIRE, chipid, coreid,
172e4b86885SCheng Sean Ye strandid, NULL);
173e4b86885SCheng Sean Ye
174e4b86885SCheng Sean Ye return (ret == 0 ? FMD_AGENT_RETIRE_DONE : FMD_AGENT_RETIRE_FAIL);
175e4b86885SCheng Sean Ye }
176