12eeaed14Srobj /* 22eeaed14Srobj * CDDL HEADER START 32eeaed14Srobj * 42eeaed14Srobj * The contents of this file are subject to the terms of the 52eeaed14Srobj * Common Development and Distribution License (the "License"). 62eeaed14Srobj * You may not use this file except in compliance with the License. 72eeaed14Srobj * 82eeaed14Srobj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92eeaed14Srobj * or http://www.opensolaris.org/os/licensing. 102eeaed14Srobj * See the License for the specific language governing permissions 112eeaed14Srobj * and limitations under the License. 122eeaed14Srobj * 132eeaed14Srobj * When distributing Covered Code, include this CDDL HEADER in each 142eeaed14Srobj * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152eeaed14Srobj * If applicable, add the following below this CDDL HEADER, with the 162eeaed14Srobj * fields enclosed by brackets "[]" replaced with your own identifying 172eeaed14Srobj * information: Portions Copyright [yyyy] [name of copyright owner] 182eeaed14Srobj * 192eeaed14Srobj * CDDL HEADER END 202eeaed14Srobj */ 212eeaed14Srobj 222eeaed14Srobj /* 232eeaed14Srobj * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 242eeaed14Srobj * Use is subject to license terms. 252eeaed14Srobj */ 262eeaed14Srobj 272eeaed14Srobj #pragma ident "%Z%%M% %I% %E% SMI" 282eeaed14Srobj 292eeaed14Srobj #include <libipmi.h> 302eeaed14Srobj #include <stddef.h> 312eeaed14Srobj #include <string.h> 322eeaed14Srobj #include <strings.h> 332eeaed14Srobj 342eeaed14Srobj #include "ipmi_impl.h" 352eeaed14Srobj 362eeaed14Srobj /* 372eeaed14Srobj * 31.2 Get SEL Info Command. 382eeaed14Srobj */ 392eeaed14Srobj ipmi_sel_info_t * 402eeaed14Srobj ipmi_sel_get_info(ipmi_handle_t *ihp) 412eeaed14Srobj { 422eeaed14Srobj ipmi_cmd_t cmd, *rsp; 432eeaed14Srobj ipmi_sel_info_t *ip; 44*e1a24155Srobj uint16_t tmp16; 45*e1a24155Srobj uint32_t tmp32; 462eeaed14Srobj 472eeaed14Srobj cmd.ic_netfn = IPMI_NETFN_STORAGE; 482eeaed14Srobj cmd.ic_lun = 0; 492eeaed14Srobj cmd.ic_cmd = IPMI_CMD_GET_SEL_INFO; 502eeaed14Srobj cmd.ic_dlen = 0; 512eeaed14Srobj cmd.ic_data = NULL; 522eeaed14Srobj 532eeaed14Srobj if ((rsp = ipmi_send(ihp, &cmd)) == NULL) 542eeaed14Srobj return (NULL); 552eeaed14Srobj 562eeaed14Srobj ip = (ipmi_sel_info_t *)rsp->ic_data; 572eeaed14Srobj 58*e1a24155Srobj tmp16 = LE_IN16(&ip->isel_entries); 59*e1a24155Srobj (void) memcpy(&ip->isel_entries, &tmp16, sizeof (tmp16)); 60*e1a24155Srobj tmp16 = LE_IN16(&ip->isel_free); 61*e1a24155Srobj (void) memcpy(&ip->isel_free, &tmp16, sizeof (tmp16)); 62*e1a24155Srobj tmp32 = LE_IN32(&ip->isel_add_ts); 63*e1a24155Srobj (void) memcpy(&ip->isel_add_ts, &tmp32, sizeof (tmp32)); 64*e1a24155Srobj tmp32 = LE_IN32(&ip->isel_erase_ts); 65*e1a24155Srobj (void) memcpy(&ip->isel_erase_ts, &tmp32, sizeof (tmp32)); 662eeaed14Srobj 672eeaed14Srobj return (ip); 682eeaed14Srobj } 692eeaed14Srobj 702eeaed14Srobj typedef struct ipmi_cmd_get_sel_entry { 712eeaed14Srobj uint16_t ic_sel_ent_resid; 722eeaed14Srobj uint16_t ic_sel_ent_recid; 732eeaed14Srobj uint8_t ic_sel_ent_offset; 742eeaed14Srobj uint8_t ic_sel_ent_bytes; 752eeaed14Srobj } ipmi_cmd_get_sel_entry_t; 762eeaed14Srobj 772eeaed14Srobj ipmi_sel_event_t * 782eeaed14Srobj ipmi_sel_get_entry(ipmi_handle_t *ihp, uint16_t id) 792eeaed14Srobj { 802eeaed14Srobj ipmi_cmd_t cmd, *rsp; 812eeaed14Srobj ipmi_sel_event_t *evp; 822eeaed14Srobj ipmi_cmd_get_sel_entry_t data; 83*e1a24155Srobj uint32_t tmp; 842eeaed14Srobj 852eeaed14Srobj data.ic_sel_ent_resid = 0; 862eeaed14Srobj data.ic_sel_ent_recid = LE_16(id); 872eeaed14Srobj data.ic_sel_ent_offset = 0; 882eeaed14Srobj data.ic_sel_ent_bytes = 0xFF; 892eeaed14Srobj 902eeaed14Srobj cmd.ic_netfn = IPMI_NETFN_STORAGE; 912eeaed14Srobj cmd.ic_lun = 0; 922eeaed14Srobj cmd.ic_cmd = IPMI_CMD_GET_SEL_ENTRY; 932eeaed14Srobj cmd.ic_dlen = sizeof (data); 942eeaed14Srobj cmd.ic_data = &data; 952eeaed14Srobj 962eeaed14Srobj if ((rsp = ipmi_send(ihp, &cmd)) == NULL) 972eeaed14Srobj return (NULL); 982eeaed14Srobj 992eeaed14Srobj if (rsp->ic_dlen < sizeof (ipmi_sel_event_t)) { 1002eeaed14Srobj (void) ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL); 1012eeaed14Srobj return (NULL); 1022eeaed14Srobj } 1032eeaed14Srobj 1042eeaed14Srobj evp = (ipmi_sel_event_t *)rsp->ic_data; 1052eeaed14Srobj 106918a0d8aSrobj evp->isel_ev_next = LE_IN16(&evp->isel_ev_next); 107918a0d8aSrobj evp->isel_ev_recid = LE_IN16(&evp->isel_ev_recid); 1082eeaed14Srobj if (evp->isel_ev_rectype == IPMI_SEL_SYSTEM || 109*e1a24155Srobj evp->isel_ev_rectype >= IPMI_SEL_OEM_LO) { 1102eeaed14Srobj 111*e1a24155Srobj tmp = LE_IN32(&evp->isel_ev_ts); 112*e1a24155Srobj (void) memcpy(&evp->isel_ev_ts, &tmp, sizeof (tmp)); 113*e1a24155Srobj } 1142eeaed14Srobj return (evp); 1152eeaed14Srobj } 1162eeaed14Srobj 1172eeaed14Srobj /* 1182eeaed14Srobj * SEL time management. For the purposes of libipmi we assume that the SDR 1192eeaed14Srobj * repository and SEL share the same timebase, even though the spec allows for 1202eeaed14Srobj * separate time sources. Hence no function to set the SDR repository time. 1212eeaed14Srobj */ 1222eeaed14Srobj int 1232eeaed14Srobj ipmi_sel_get_time(ipmi_handle_t *ihp, uint32_t *tp) 1242eeaed14Srobj { 1252eeaed14Srobj ipmi_cmd_t cmd, *rsp; 1262eeaed14Srobj 1272eeaed14Srobj cmd.ic_netfn = IPMI_NETFN_STORAGE; 1282eeaed14Srobj cmd.ic_lun = 0; 1292eeaed14Srobj cmd.ic_cmd = IPMI_CMD_GET_SEL_TIME; 1302eeaed14Srobj cmd.ic_dlen = 0; 1312eeaed14Srobj cmd.ic_data = NULL; 1322eeaed14Srobj 1332eeaed14Srobj if ((rsp = ipmi_send(ihp, &cmd)) == NULL) 1342eeaed14Srobj return (-1); 1352eeaed14Srobj 1362eeaed14Srobj if (rsp->ic_dlen < sizeof (uint32_t)) 1372eeaed14Srobj return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL)); 1382eeaed14Srobj 139918a0d8aSrobj *tp = LE_IN32(rsp->ic_data); 1402eeaed14Srobj 1412eeaed14Srobj return (0); 1422eeaed14Srobj } 1432eeaed14Srobj 1442eeaed14Srobj int 1452eeaed14Srobj ipmi_sel_set_time(ipmi_handle_t *ihp, uint32_t t) 1462eeaed14Srobj { 1472eeaed14Srobj ipmi_cmd_t cmd; 1482eeaed14Srobj 1492eeaed14Srobj t = LE_32(t); 1502eeaed14Srobj 1512eeaed14Srobj cmd.ic_netfn = IPMI_NETFN_STORAGE; 1522eeaed14Srobj cmd.ic_lun = 0; 1532eeaed14Srobj cmd.ic_cmd = IPMI_CMD_SET_SEL_TIME; 1542eeaed14Srobj cmd.ic_dlen = sizeof (t); 1552eeaed14Srobj cmd.ic_data = &t; 1562eeaed14Srobj 1572eeaed14Srobj if (ipmi_send(ihp, &cmd) == NULL) 1582eeaed14Srobj return (-1); 1592eeaed14Srobj 1602eeaed14Srobj return (0); 1612eeaed14Srobj } 1622eeaed14Srobj 1632eeaed14Srobj int 1642eeaed14Srobj ipmi_sel_get_utc_offset(ipmi_handle_t *ihp, int *offp) 1652eeaed14Srobj { 1662eeaed14Srobj ipmi_cmd_t cmd, *rsp; 1672eeaed14Srobj int16_t off16; 1682eeaed14Srobj 1692eeaed14Srobj cmd.ic_netfn = IPMI_NETFN_STORAGE; 1702eeaed14Srobj cmd.ic_lun = 0; 1712eeaed14Srobj cmd.ic_cmd = IPMI_CMD_GET_SEL_UTC_OFFSET; 1722eeaed14Srobj cmd.ic_dlen = 0; 1732eeaed14Srobj cmd.ic_data = NULL; 1742eeaed14Srobj 1752eeaed14Srobj if ((rsp = ipmi_send(ihp, &cmd)) == NULL) 1762eeaed14Srobj return (-1); 1772eeaed14Srobj 1782eeaed14Srobj if (rsp->ic_dlen < sizeof (uint16_t)) 1792eeaed14Srobj return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL)); 1802eeaed14Srobj 181918a0d8aSrobj off16 = LE_IN16(rsp->ic_data); 1822eeaed14Srobj *offp = off16; 1832eeaed14Srobj 1842eeaed14Srobj return (0); 1852eeaed14Srobj } 1862eeaed14Srobj 1872eeaed14Srobj int 1882eeaed14Srobj ipmi_sel_set_utc_offset(ipmi_handle_t *ihp, int off) 1892eeaed14Srobj { 1902eeaed14Srobj ipmi_cmd_t cmd; 1912eeaed14Srobj int16_t off16 = off; 1922eeaed14Srobj 1932eeaed14Srobj off16 = LE_16(off16); 1942eeaed14Srobj 1952eeaed14Srobj cmd.ic_netfn = IPMI_NETFN_STORAGE; 1962eeaed14Srobj cmd.ic_lun = 0; 1972eeaed14Srobj cmd.ic_cmd = IPMI_CMD_SET_SEL_UTC_OFFSET; 1982eeaed14Srobj cmd.ic_dlen = sizeof (off16); 1992eeaed14Srobj cmd.ic_data = &off16; 2002eeaed14Srobj 2012eeaed14Srobj if (ipmi_send(ihp, &cmd) == NULL) 2022eeaed14Srobj return (-1); 2032eeaed14Srobj 2042eeaed14Srobj return (0); 2052eeaed14Srobj } 206