xref: /illumos-gate/usr/src/lib/libipmi/common/ipmi_sunoem.c (revision cb6207858a9fcc2feaee22e626912fba281ac969)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <libipmi.h>
30 #include <stddef.h>
31 
32 #include "ipmi_impl.h"
33 
34 static int
35 check_sunoem(ipmi_handle_t *ihp)
36 {
37 	ipmi_deviceid_t *devid;
38 
39 	if ((devid = ipmi_get_deviceid(ihp)) == NULL)
40 		return (-1);
41 
42 	if (ipmi_devid_manufacturer(devid) != IPMI_OEM_SUN)
43 		return (ipmi_set_error(ihp, EIPMI_INVALID_COMMAND, NULL));
44 
45 	return (0);
46 }
47 
48 static int
49 ipmi_send_sunoem_led_set(ipmi_handle_t *ihp, ipmi_cmd_sunoem_led_set_t *req)
50 {
51 	ipmi_cmd_t cmd, *resp;
52 
53 	cmd.ic_netfn = IPMI_NETFN_OEM;
54 	cmd.ic_cmd = IPMI_CMD_SUNOEM_LED_SET;
55 	cmd.ic_lun = 0;
56 	cmd.ic_data = req;
57 	cmd.ic_dlen = sizeof (*req);
58 
59 	if ((resp = ipmi_send(ihp, &cmd)) == NULL)
60 		return (-1);
61 
62 	if (resp->ic_dlen != 0)
63 		return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL));
64 
65 	return (0);
66 }
67 
68 static int
69 ipmi_send_sunoem_led_get(ipmi_handle_t *ihp, ipmi_cmd_sunoem_led_get_t *req,
70     uint8_t *result)
71 {
72 	ipmi_cmd_t cmd, *resp;
73 
74 	cmd.ic_netfn = IPMI_NETFN_OEM;
75 	cmd.ic_cmd = IPMI_CMD_SUNOEM_LED_GET;
76 	cmd.ic_lun = 0;
77 	cmd.ic_data = req;
78 	cmd.ic_dlen = sizeof (*req);
79 
80 	if ((resp = ipmi_send(ihp, &cmd)) == NULL)
81 		return (-1);
82 
83 	if (resp->ic_dlen != 1)
84 		return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL));
85 
86 	*result = *((uint8_t *)resp->ic_data);
87 	return (0);
88 }
89 
90 int
91 ipmi_sunoem_led_set(ipmi_handle_t *ihp, ipmi_sdr_generic_locator_t *dev,
92     uint8_t mode)
93 {
94 	ipmi_cmd_sunoem_led_set_t cmd = { 0 };
95 
96 	if (check_sunoem(ihp) != 0)
97 		return (-1);
98 
99 	cmd.ic_sls_devaddr = dev->is_gl_slaveaddr;
100 	cmd.ic_sls_type = dev->is_gl_oem;
101 	cmd.ic_sls_ctladdr = dev->is_gl_accessaddr;
102 	cmd.ic_sls_hwinfo = dev->is_gl_oem;
103 	cmd.ic_sls_mode = mode;
104 
105 	return (ipmi_send_sunoem_led_set(ihp, &cmd));
106 }
107 
108 int
109 ipmi_sunoem_led_get(ipmi_handle_t *ihp, ipmi_sdr_generic_locator_t *dev,
110     uint8_t *mode)
111 {
112 	ipmi_cmd_sunoem_led_get_t cmd = { 0 };
113 
114 	if (check_sunoem(ihp) != 0)
115 		return (-1);
116 
117 	cmd.ic_slg_devaddr = dev->is_gl_slaveaddr;
118 	cmd.ic_slg_type = dev->is_gl_oem;
119 	cmd.ic_slg_ctladdr = dev->is_gl_accessaddr;
120 	cmd.ic_slg_hwinfo = dev->is_gl_oem;
121 
122 	return (ipmi_send_sunoem_led_get(ihp, &cmd, mode));
123 }
124 
125 int
126 ipmi_sunoem_uptime(ipmi_handle_t *ihp, uint32_t *uptime, uint32_t *gen)
127 {
128 	ipmi_cmd_t cmd, *resp;
129 	uint8_t unused;
130 
131 	if (check_sunoem(ihp) != 0)
132 		return (-1);
133 
134 	cmd.ic_netfn = IPMI_NETFN_OEM;
135 	cmd.ic_lun = 0;
136 	cmd.ic_cmd = IPMI_CMD_SUNOEM_UPTIME;
137 	cmd.ic_dlen = sizeof (unused);
138 	cmd.ic_data = &unused;
139 
140 	if ((resp = ipmi_send(ihp, &cmd)) == NULL)
141 		return (-1);
142 
143 	if (resp->ic_dlen != 2 * sizeof (uint32_t))
144 		return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL));
145 
146 	if (uptime)
147 		*uptime = BE_32(((uint32_t *)resp->ic_data)[0]);
148 	if (gen)
149 		*gen = BE_32(((uint32_t *)resp->ic_data)[1]);
150 
151 	return (0);
152 }
153 
154 int
155 ipmi_sunoem_update_fru(ipmi_handle_t *ihp, ipmi_sunoem_fru_t *req)
156 {
157 	ipmi_cmd_t cmd, *resp;
158 
159 	if (check_sunoem(ihp) != 0)
160 		return (-1);
161 
162 	switch (req->isf_type) {
163 	case IPMI_SUNOEM_FRU_DIMM:
164 		req->isf_datalen = sizeof (req->isf_data.dimm);
165 		break;
166 
167 	case IPMI_SUNOEM_FRU_CPU:
168 		req->isf_datalen = sizeof (req->isf_data.cpu);
169 		break;
170 
171 	case IPMI_SUNOEM_FRU_BIOS:
172 		req->isf_datalen = sizeof (req->isf_data.bios);
173 		break;
174 
175 	case IPMI_SUNOEM_FRU_DISK:
176 		req->isf_datalen = sizeof (req->isf_data.disk);
177 		break;
178 	}
179 
180 	cmd.ic_netfn = IPMI_NETFN_OEM;
181 	cmd.ic_cmd = IPMI_CMD_SUNOEM_FRU_UPDATE;
182 	cmd.ic_lun = 0;
183 	cmd.ic_dlen = offsetof(ipmi_sunoem_fru_t, isf_data) +
184 	    req->isf_datalen;
185 	cmd.ic_data = req;
186 
187 	if ((resp = ipmi_send(ihp, &cmd)) == NULL)
188 		return (-1);
189 
190 	if (resp->ic_dlen != 0)
191 		return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL));
192 
193 	return (0);
194 }
195