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