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