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 2008 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 #include <string.h> 32 #include <strings.h> 33 34 #include "ipmi_impl.h" 35 36 /* 37 * 31.2 Get SEL Info Command. 38 */ 39 ipmi_sel_info_t * 40 ipmi_sel_get_info(ipmi_handle_t *ihp) 41 { 42 ipmi_cmd_t cmd, *rsp; 43 ipmi_sel_info_t *ip; 44 45 cmd.ic_netfn = IPMI_NETFN_STORAGE; 46 cmd.ic_lun = 0; 47 cmd.ic_cmd = IPMI_CMD_GET_SEL_INFO; 48 cmd.ic_dlen = 0; 49 cmd.ic_data = NULL; 50 51 if ((rsp = ipmi_send(ihp, &cmd)) == NULL) 52 return (NULL); 53 54 ip = (ipmi_sel_info_t *)rsp->ic_data; 55 56 ip->isel_entries = LE_IN16(&ip->isel_entries); 57 ip->isel_free = LE_IN16(&ip->isel_free); 58 ip->isel_add_ts = LE_IN32(&ip->isel_add_ts); 59 ip->isel_erase_ts = LE_IN32(&ip->isel_erase_ts); 60 61 return (ip); 62 } 63 64 typedef struct ipmi_cmd_get_sel_entry { 65 uint16_t ic_sel_ent_resid; 66 uint16_t ic_sel_ent_recid; 67 uint8_t ic_sel_ent_offset; 68 uint8_t ic_sel_ent_bytes; 69 } ipmi_cmd_get_sel_entry_t; 70 71 ipmi_sel_event_t * 72 ipmi_sel_get_entry(ipmi_handle_t *ihp, uint16_t id) 73 { 74 ipmi_cmd_t cmd, *rsp; 75 ipmi_sel_event_t *evp; 76 ipmi_cmd_get_sel_entry_t data; 77 78 data.ic_sel_ent_resid = 0; 79 data.ic_sel_ent_recid = LE_16(id); 80 data.ic_sel_ent_offset = 0; 81 data.ic_sel_ent_bytes = 0xFF; 82 83 cmd.ic_netfn = IPMI_NETFN_STORAGE; 84 cmd.ic_lun = 0; 85 cmd.ic_cmd = IPMI_CMD_GET_SEL_ENTRY; 86 cmd.ic_dlen = sizeof (data); 87 cmd.ic_data = &data; 88 89 if ((rsp = ipmi_send(ihp, &cmd)) == NULL) 90 return (NULL); 91 92 if (rsp->ic_dlen < sizeof (ipmi_sel_event_t)) { 93 (void) ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL); 94 return (NULL); 95 } 96 97 evp = (ipmi_sel_event_t *)rsp->ic_data; 98 99 evp->isel_ev_next = LE_IN16(&evp->isel_ev_next); 100 evp->isel_ev_recid = LE_IN16(&evp->isel_ev_recid); 101 if (evp->isel_ev_rectype == IPMI_SEL_SYSTEM || 102 evp->isel_ev_rectype >= IPMI_SEL_OEM_LO) 103 evp->isel_ev_ts = LE_IN32(&evp->isel_ev_ts); 104 105 return (evp); 106 } 107 108 /* 109 * SEL time management. For the purposes of libipmi we assume that the SDR 110 * repository and SEL share the same timebase, even though the spec allows for 111 * separate time sources. Hence no function to set the SDR repository time. 112 */ 113 int 114 ipmi_sel_get_time(ipmi_handle_t *ihp, uint32_t *tp) 115 { 116 ipmi_cmd_t cmd, *rsp; 117 118 cmd.ic_netfn = IPMI_NETFN_STORAGE; 119 cmd.ic_lun = 0; 120 cmd.ic_cmd = IPMI_CMD_GET_SEL_TIME; 121 cmd.ic_dlen = 0; 122 cmd.ic_data = NULL; 123 124 if ((rsp = ipmi_send(ihp, &cmd)) == NULL) 125 return (-1); 126 127 if (rsp->ic_dlen < sizeof (uint32_t)) 128 return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL)); 129 130 *tp = LE_IN32(rsp->ic_data); 131 132 return (0); 133 } 134 135 int 136 ipmi_sel_set_time(ipmi_handle_t *ihp, uint32_t t) 137 { 138 ipmi_cmd_t cmd; 139 140 t = LE_32(t); 141 142 cmd.ic_netfn = IPMI_NETFN_STORAGE; 143 cmd.ic_lun = 0; 144 cmd.ic_cmd = IPMI_CMD_SET_SEL_TIME; 145 cmd.ic_dlen = sizeof (t); 146 cmd.ic_data = &t; 147 148 if (ipmi_send(ihp, &cmd) == NULL) 149 return (-1); 150 151 return (0); 152 } 153 154 int 155 ipmi_sel_get_utc_offset(ipmi_handle_t *ihp, int *offp) 156 { 157 ipmi_cmd_t cmd, *rsp; 158 int16_t off16; 159 160 cmd.ic_netfn = IPMI_NETFN_STORAGE; 161 cmd.ic_lun = 0; 162 cmd.ic_cmd = IPMI_CMD_GET_SEL_UTC_OFFSET; 163 cmd.ic_dlen = 0; 164 cmd.ic_data = NULL; 165 166 if ((rsp = ipmi_send(ihp, &cmd)) == NULL) 167 return (-1); 168 169 if (rsp->ic_dlen < sizeof (uint16_t)) 170 return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL)); 171 172 off16 = LE_IN16(rsp->ic_data); 173 *offp = off16; 174 175 return (0); 176 } 177 178 int 179 ipmi_sel_set_utc_offset(ipmi_handle_t *ihp, int off) 180 { 181 ipmi_cmd_t cmd; 182 int16_t off16 = off; 183 184 off16 = LE_16(off16); 185 186 cmd.ic_netfn = IPMI_NETFN_STORAGE; 187 cmd.ic_lun = 0; 188 cmd.ic_cmd = IPMI_CMD_SET_SEL_UTC_OFFSET; 189 cmd.ic_dlen = sizeof (off16); 190 cmd.ic_data = &off16; 191 192 if (ipmi_send(ihp, &cmd) == NULL) 193 return (-1); 194 195 return (0); 196 } 197