xref: /onnv-gate/usr/src/lib/libipmi/common/ipmi_sel.c (revision 6726:d01b10854a9d)
16070Srobj /*
26070Srobj  * CDDL HEADER START
36070Srobj  *
46070Srobj  * The contents of this file are subject to the terms of the
56070Srobj  * Common Development and Distribution License (the "License").
66070Srobj  * You may not use this file except in compliance with the License.
76070Srobj  *
86070Srobj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96070Srobj  * or http://www.opensolaris.org/os/licensing.
106070Srobj  * See the License for the specific language governing permissions
116070Srobj  * and limitations under the License.
126070Srobj  *
136070Srobj  * When distributing Covered Code, include this CDDL HEADER in each
146070Srobj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156070Srobj  * If applicable, add the following below this CDDL HEADER, with the
166070Srobj  * fields enclosed by brackets "[]" replaced with your own identifying
176070Srobj  * information: Portions Copyright [yyyy] [name of copyright owner]
186070Srobj  *
196070Srobj  * CDDL HEADER END
206070Srobj  */
216070Srobj 
226070Srobj /*
236070Srobj  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
246070Srobj  * Use is subject to license terms.
256070Srobj  */
266070Srobj 
276070Srobj #pragma ident	"%Z%%M%	%I%	%E% SMI"
286070Srobj 
296070Srobj #include <libipmi.h>
306070Srobj #include <stddef.h>
316070Srobj #include <string.h>
326070Srobj #include <strings.h>
336070Srobj 
346070Srobj #include "ipmi_impl.h"
356070Srobj 
366070Srobj /*
376070Srobj  * 31.2 Get SEL Info Command.
386070Srobj  */
396070Srobj ipmi_sel_info_t *
ipmi_sel_get_info(ipmi_handle_t * ihp)406070Srobj ipmi_sel_get_info(ipmi_handle_t *ihp)
416070Srobj {
426070Srobj 	ipmi_cmd_t cmd, *rsp;
436070Srobj 	ipmi_sel_info_t *ip;
44*6726Srobj 	uint16_t tmp16;
45*6726Srobj 	uint32_t tmp32;
466070Srobj 
476070Srobj 	cmd.ic_netfn = IPMI_NETFN_STORAGE;
486070Srobj 	cmd.ic_lun = 0;
496070Srobj 	cmd.ic_cmd = IPMI_CMD_GET_SEL_INFO;
506070Srobj 	cmd.ic_dlen = 0;
516070Srobj 	cmd.ic_data = NULL;
526070Srobj 
536070Srobj 	if ((rsp = ipmi_send(ihp, &cmd)) == NULL)
546070Srobj 		return (NULL);
556070Srobj 
566070Srobj 	ip = (ipmi_sel_info_t *)rsp->ic_data;
576070Srobj 
58*6726Srobj 	tmp16 = LE_IN16(&ip->isel_entries);
59*6726Srobj 	(void) memcpy(&ip->isel_entries, &tmp16, sizeof (tmp16));
60*6726Srobj 	tmp16 = LE_IN16(&ip->isel_free);
61*6726Srobj 	(void) memcpy(&ip->isel_free, &tmp16, sizeof (tmp16));
62*6726Srobj 	tmp32 = LE_IN32(&ip->isel_add_ts);
63*6726Srobj 	(void) memcpy(&ip->isel_add_ts, &tmp32, sizeof (tmp32));
64*6726Srobj 	tmp32 = LE_IN32(&ip->isel_erase_ts);
65*6726Srobj 	(void) memcpy(&ip->isel_erase_ts, &tmp32, sizeof (tmp32));
666070Srobj 
676070Srobj 	return (ip);
686070Srobj }
696070Srobj 
706070Srobj typedef struct ipmi_cmd_get_sel_entry {
716070Srobj 	uint16_t	ic_sel_ent_resid;
726070Srobj 	uint16_t	ic_sel_ent_recid;
736070Srobj 	uint8_t		ic_sel_ent_offset;
746070Srobj 	uint8_t		ic_sel_ent_bytes;
756070Srobj } ipmi_cmd_get_sel_entry_t;
766070Srobj 
776070Srobj ipmi_sel_event_t *
ipmi_sel_get_entry(ipmi_handle_t * ihp,uint16_t id)786070Srobj ipmi_sel_get_entry(ipmi_handle_t *ihp, uint16_t id)
796070Srobj {
806070Srobj 	ipmi_cmd_t cmd, *rsp;
816070Srobj 	ipmi_sel_event_t *evp;
826070Srobj 	ipmi_cmd_get_sel_entry_t data;
83*6726Srobj 	uint32_t tmp;
846070Srobj 
856070Srobj 	data.ic_sel_ent_resid = 0;
866070Srobj 	data.ic_sel_ent_recid = LE_16(id);
876070Srobj 	data.ic_sel_ent_offset = 0;
886070Srobj 	data.ic_sel_ent_bytes = 0xFF;
896070Srobj 
906070Srobj 	cmd.ic_netfn = IPMI_NETFN_STORAGE;
916070Srobj 	cmd.ic_lun = 0;
926070Srobj 	cmd.ic_cmd = IPMI_CMD_GET_SEL_ENTRY;
936070Srobj 	cmd.ic_dlen = sizeof (data);
946070Srobj 	cmd.ic_data = &data;
956070Srobj 
966070Srobj 	if ((rsp = ipmi_send(ihp, &cmd)) == NULL)
976070Srobj 		return (NULL);
986070Srobj 
996070Srobj 	if (rsp->ic_dlen < sizeof (ipmi_sel_event_t)) {
1006070Srobj 		(void) ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL);
1016070Srobj 		return (NULL);
1026070Srobj 	}
1036070Srobj 
1046070Srobj 	evp = (ipmi_sel_event_t *)rsp->ic_data;
1056070Srobj 
1066360Srobj 	evp->isel_ev_next = LE_IN16(&evp->isel_ev_next);
1076360Srobj 	evp->isel_ev_recid = LE_IN16(&evp->isel_ev_recid);
1086070Srobj 	if (evp->isel_ev_rectype == IPMI_SEL_SYSTEM ||
109*6726Srobj 	    evp->isel_ev_rectype >= IPMI_SEL_OEM_LO) {
1106070Srobj 
111*6726Srobj 		tmp = LE_IN32(&evp->isel_ev_ts);
112*6726Srobj 		(void) memcpy(&evp->isel_ev_ts, &tmp, sizeof (tmp));
113*6726Srobj 	}
1146070Srobj 	return (evp);
1156070Srobj }
1166070Srobj 
1176070Srobj /*
1186070Srobj  * SEL time management.  For the purposes of libipmi we assume that the SDR
1196070Srobj  * repository and SEL share the same timebase, even though the spec allows for
1206070Srobj  * separate time sources.  Hence no function to set the SDR repository time.
1216070Srobj  */
1226070Srobj int
ipmi_sel_get_time(ipmi_handle_t * ihp,uint32_t * tp)1236070Srobj ipmi_sel_get_time(ipmi_handle_t *ihp, uint32_t *tp)
1246070Srobj {
1256070Srobj 	ipmi_cmd_t cmd, *rsp;
1266070Srobj 
1276070Srobj 	cmd.ic_netfn = IPMI_NETFN_STORAGE;
1286070Srobj 	cmd.ic_lun = 0;
1296070Srobj 	cmd.ic_cmd = IPMI_CMD_GET_SEL_TIME;
1306070Srobj 	cmd.ic_dlen = 0;
1316070Srobj 	cmd.ic_data = NULL;
1326070Srobj 
1336070Srobj 	if ((rsp = ipmi_send(ihp, &cmd)) == NULL)
1346070Srobj 		return (-1);
1356070Srobj 
1366070Srobj 	if (rsp->ic_dlen < sizeof (uint32_t))
1376070Srobj 		return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL));
1386070Srobj 
1396360Srobj 	*tp = LE_IN32(rsp->ic_data);
1406070Srobj 
1416070Srobj 	return (0);
1426070Srobj }
1436070Srobj 
1446070Srobj int
ipmi_sel_set_time(ipmi_handle_t * ihp,uint32_t t)1456070Srobj ipmi_sel_set_time(ipmi_handle_t *ihp, uint32_t t)
1466070Srobj {
1476070Srobj 	ipmi_cmd_t cmd;
1486070Srobj 
1496070Srobj 	t = LE_32(t);
1506070Srobj 
1516070Srobj 	cmd.ic_netfn = IPMI_NETFN_STORAGE;
1526070Srobj 	cmd.ic_lun = 0;
1536070Srobj 	cmd.ic_cmd = IPMI_CMD_SET_SEL_TIME;
1546070Srobj 	cmd.ic_dlen = sizeof (t);
1556070Srobj 	cmd.ic_data = &t;
1566070Srobj 
1576070Srobj 	if (ipmi_send(ihp, &cmd) == NULL)
1586070Srobj 		return (-1);
1596070Srobj 
1606070Srobj 	return (0);
1616070Srobj }
1626070Srobj 
1636070Srobj int
ipmi_sel_get_utc_offset(ipmi_handle_t * ihp,int * offp)1646070Srobj ipmi_sel_get_utc_offset(ipmi_handle_t *ihp, int *offp)
1656070Srobj {
1666070Srobj 	ipmi_cmd_t cmd, *rsp;
1676070Srobj 	int16_t off16;
1686070Srobj 
1696070Srobj 	cmd.ic_netfn = IPMI_NETFN_STORAGE;
1706070Srobj 	cmd.ic_lun = 0;
1716070Srobj 	cmd.ic_cmd = IPMI_CMD_GET_SEL_UTC_OFFSET;
1726070Srobj 	cmd.ic_dlen = 0;
1736070Srobj 	cmd.ic_data = NULL;
1746070Srobj 
1756070Srobj 	if ((rsp = ipmi_send(ihp, &cmd)) == NULL)
1766070Srobj 		return (-1);
1776070Srobj 
1786070Srobj 	if (rsp->ic_dlen < sizeof (uint16_t))
1796070Srobj 		return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL));
1806070Srobj 
1816360Srobj 	off16 = LE_IN16(rsp->ic_data);
1826070Srobj 	*offp = off16;
1836070Srobj 
1846070Srobj 	return (0);
1856070Srobj }
1866070Srobj 
1876070Srobj int
ipmi_sel_set_utc_offset(ipmi_handle_t * ihp,int off)1886070Srobj ipmi_sel_set_utc_offset(ipmi_handle_t *ihp, int off)
1896070Srobj {
1906070Srobj 	ipmi_cmd_t cmd;
1916070Srobj 	int16_t off16 = off;
1926070Srobj 
1936070Srobj 	off16 = LE_16(off16);
1946070Srobj 
1956070Srobj 	cmd.ic_netfn = IPMI_NETFN_STORAGE;
1966070Srobj 	cmd.ic_lun = 0;
1976070Srobj 	cmd.ic_cmd = IPMI_CMD_SET_SEL_UTC_OFFSET;
1986070Srobj 	cmd.ic_dlen = sizeof (off16);
1996070Srobj 	cmd.ic_data = &off16;
2006070Srobj 
2016070Srobj 	if (ipmi_send(ihp, &cmd) == NULL)
2026070Srobj 		return (-1);
2036070Srobj 
2046070Srobj 	return (0);
2056070Srobj }
206