1c18ec02fSPetter Reinholdtsen /* -*-mode: C; indent-tabs-mode: t; -*-
2c18ec02fSPetter Reinholdtsen * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
3c18ec02fSPetter Reinholdtsen *
4c18ec02fSPetter Reinholdtsen * Redistribution and use in source and binary forms, with or without
5c18ec02fSPetter Reinholdtsen * modification, are permitted provided that the following conditions
6c18ec02fSPetter Reinholdtsen * are met:
7c18ec02fSPetter Reinholdtsen *
8c18ec02fSPetter Reinholdtsen * Redistribution of source code must retain the above copyright
9c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer.
10c18ec02fSPetter Reinholdtsen *
11c18ec02fSPetter Reinholdtsen * Redistribution in binary form must reproduce the above copyright
12c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer in the
13c18ec02fSPetter Reinholdtsen * documentation and/or other materials provided with the distribution.
14c18ec02fSPetter Reinholdtsen *
15c18ec02fSPetter Reinholdtsen * Neither the name of Sun Microsystems, Inc. or the names of
16c18ec02fSPetter Reinholdtsen * contributors may be used to endorse or promote products derived
17c18ec02fSPetter Reinholdtsen * from this software without specific prior written permission.
18c18ec02fSPetter Reinholdtsen *
19c18ec02fSPetter Reinholdtsen * This software is provided "AS IS," without a warranty of any kind.
20c18ec02fSPetter Reinholdtsen * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21c18ec02fSPetter Reinholdtsen * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22c18ec02fSPetter Reinholdtsen * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23c18ec02fSPetter Reinholdtsen * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24c18ec02fSPetter Reinholdtsen * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25c18ec02fSPetter Reinholdtsen * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
26c18ec02fSPetter Reinholdtsen * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27c18ec02fSPetter Reinholdtsen * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28c18ec02fSPetter Reinholdtsen * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29c18ec02fSPetter Reinholdtsen * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30c18ec02fSPetter Reinholdtsen * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31c18ec02fSPetter Reinholdtsen */
32c18ec02fSPetter Reinholdtsen
33c18ec02fSPetter Reinholdtsen #include <string.h>
34c18ec02fSPetter Reinholdtsen #include <math.h>
35c18ec02fSPetter Reinholdtsen #define __USE_XOPEN /* glibc2 needs this for strptime */
36c18ec02fSPetter Reinholdtsen #include <time.h>
37c18ec02fSPetter Reinholdtsen #include <ctype.h>
38c18ec02fSPetter Reinholdtsen #include <errno.h>
39c18ec02fSPetter Reinholdtsen
40c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
41c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
42c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
43c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_mc.h>
44c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
45c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sel.h>
46c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sdr.h>
47c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_fru.h>
48c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sensor.h>
49c18ec02fSPetter Reinholdtsen
50c18ec02fSPetter Reinholdtsen extern int verbose;
51c18ec02fSPetter Reinholdtsen static int sel_extended = 0;
52c18ec02fSPetter Reinholdtsen static int sel_oem_nrecs = 0;
53c18ec02fSPetter Reinholdtsen
54c18ec02fSPetter Reinholdtsen static IPMI_OEM sel_iana = IPMI_OEM_UNKNOWN;
55c18ec02fSPetter Reinholdtsen
56c18ec02fSPetter Reinholdtsen struct ipmi_sel_oem_msg_rec {
57c18ec02fSPetter Reinholdtsen int value[14];
58c18ec02fSPetter Reinholdtsen char *string[14];
59c18ec02fSPetter Reinholdtsen char *text;
60c18ec02fSPetter Reinholdtsen } *sel_oem_msg;
61c18ec02fSPetter Reinholdtsen
62c18ec02fSPetter Reinholdtsen #define SEL_BYTE(n) (n-3) /* So we can refer to byte positions in log entries (byte 3 is at index 0, etc) */
63c18ec02fSPetter Reinholdtsen
64c18ec02fSPetter Reinholdtsen // Definiation for the Decoding the SEL OEM Bytes for DELL Platfoms
65c18ec02fSPetter Reinholdtsen #define BIT(x) (1 << x) /* Select the Bit */
66c18ec02fSPetter Reinholdtsen #define SIZE_OF_DESC 128 /* Max Size of the description String to be displyed for the Each sel entry */
67c18ec02fSPetter Reinholdtsen #define MAX_CARDNO_STR 32 /* Max Size of Card number string */
68c18ec02fSPetter Reinholdtsen #define MAX_DIMM_STR 32 /* Max Size of DIMM string */
69c18ec02fSPetter Reinholdtsen #define MAX_CARD_STR 32 /* Max Size of Card string */
70c18ec02fSPetter Reinholdtsen /*
71c18ec02fSPetter Reinholdtsen * Reads values found in message translation file. XX is a wildcard, R means reserved.
72c18ec02fSPetter Reinholdtsen * Returns -1 for XX, -2 for R, -3 for non-hex (string), or positive integer from a hex value.
73c18ec02fSPetter Reinholdtsen */
ipmi_sel_oem_readval(char * str)74c18ec02fSPetter Reinholdtsen static int ipmi_sel_oem_readval(char *str)
75c18ec02fSPetter Reinholdtsen {
76c18ec02fSPetter Reinholdtsen int ret;
77c18ec02fSPetter Reinholdtsen if (!strcmp(str, "XX")) {
78c18ec02fSPetter Reinholdtsen return -1;
79c18ec02fSPetter Reinholdtsen }
80c18ec02fSPetter Reinholdtsen if (!strcmp(str, "R")) {
81c18ec02fSPetter Reinholdtsen return -2;
82c18ec02fSPetter Reinholdtsen }
83c18ec02fSPetter Reinholdtsen if (sscanf(str, "0x%x", &ret) != 1) {
84c18ec02fSPetter Reinholdtsen return -3;
85c18ec02fSPetter Reinholdtsen }
86c18ec02fSPetter Reinholdtsen return ret;
87c18ec02fSPetter Reinholdtsen }
88c18ec02fSPetter Reinholdtsen
89c18ec02fSPetter Reinholdtsen /*
90c18ec02fSPetter Reinholdtsen * This is where the magic happens. SEL_BYTE is a bit ugly, but it allows
91c18ec02fSPetter Reinholdtsen * reference to byte positions instead of array indexes which (hopefully)
92c18ec02fSPetter Reinholdtsen * helps make the code easier to read.
93c18ec02fSPetter Reinholdtsen */
9482a0caa3SZdenek Styblik static int
ipmi_sel_oem_match(uint8_t * evt,const struct ipmi_sel_oem_msg_rec * rec)95*88891f69SZdenek Styblik ipmi_sel_oem_match(uint8_t *evt, const struct ipmi_sel_oem_msg_rec *rec)
96c18ec02fSPetter Reinholdtsen {
97*88891f69SZdenek Styblik if (evt[2] == rec->value[SEL_BYTE(3)]
98*88891f69SZdenek Styblik && ((rec->value[SEL_BYTE(4)] < 0)
99*88891f69SZdenek Styblik || (evt[3] == rec->value[SEL_BYTE(4)]))
100*88891f69SZdenek Styblik && ((rec->value[SEL_BYTE(5)] < 0)
101*88891f69SZdenek Styblik || (evt[4] == rec->value[SEL_BYTE(5)]))
102*88891f69SZdenek Styblik && ((rec->value[SEL_BYTE(6)] < 0)
103*88891f69SZdenek Styblik || (evt[5] == rec->value[SEL_BYTE(6)]))
104*88891f69SZdenek Styblik && ((rec->value[SEL_BYTE(7)] < 0)
105*88891f69SZdenek Styblik || (evt[6] == rec->value[SEL_BYTE(7)]))
106*88891f69SZdenek Styblik && ((rec->value[SEL_BYTE(11)] < 0)
107*88891f69SZdenek Styblik || (evt[10] == rec->value[SEL_BYTE(11)]))
108*88891f69SZdenek Styblik && ((rec->value[SEL_BYTE(12)] < 0)
109*88891f69SZdenek Styblik || (evt[11] == rec->value[SEL_BYTE(12)]))) {
110c18ec02fSPetter Reinholdtsen return 1;
111c18ec02fSPetter Reinholdtsen } else {
112c18ec02fSPetter Reinholdtsen return 0;
113c18ec02fSPetter Reinholdtsen }
114c18ec02fSPetter Reinholdtsen }
115c18ec02fSPetter Reinholdtsen
ipmi_sel_oem_init(const char * filename)116c18ec02fSPetter Reinholdtsen int ipmi_sel_oem_init(const char * filename)
117c18ec02fSPetter Reinholdtsen {
118c18ec02fSPetter Reinholdtsen FILE * fp;
119c18ec02fSPetter Reinholdtsen int i, j, k, n, byte;
120c18ec02fSPetter Reinholdtsen char buf[15][150];
121c18ec02fSPetter Reinholdtsen
122c18ec02fSPetter Reinholdtsen if (filename == NULL) {
123c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "No SEL OEM filename provided");
124c18ec02fSPetter Reinholdtsen return -1;
125c18ec02fSPetter Reinholdtsen }
126c18ec02fSPetter Reinholdtsen
127c18ec02fSPetter Reinholdtsen fp = ipmi_open_file_read(filename);
128c18ec02fSPetter Reinholdtsen if (fp == NULL) {
129c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Could not open %s file", filename);
130c18ec02fSPetter Reinholdtsen return -1;
131c18ec02fSPetter Reinholdtsen }
132c18ec02fSPetter Reinholdtsen
133c18ec02fSPetter Reinholdtsen /* count number of records (lines) in input file */
134c18ec02fSPetter Reinholdtsen sel_oem_nrecs = 0;
135c18ec02fSPetter Reinholdtsen while (fscanf(fp, "%*[^\n]\n") == 0) {
136c18ec02fSPetter Reinholdtsen sel_oem_nrecs++;
137c18ec02fSPetter Reinholdtsen }
138c18ec02fSPetter Reinholdtsen
139c18ec02fSPetter Reinholdtsen printf("nrecs=%d\n", sel_oem_nrecs);
140c18ec02fSPetter Reinholdtsen
141c18ec02fSPetter Reinholdtsen rewind(fp);
142c18ec02fSPetter Reinholdtsen sel_oem_msg = (struct ipmi_sel_oem_msg_rec *)calloc(sel_oem_nrecs,
143c18ec02fSPetter Reinholdtsen sizeof(struct ipmi_sel_oem_msg_rec));
144c18ec02fSPetter Reinholdtsen
145c18ec02fSPetter Reinholdtsen for (i=0; i < sel_oem_nrecs; i++) {
146c18ec02fSPetter Reinholdtsen n=fscanf(fp, "\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\""
147c18ec02fSPetter Reinholdtsen "%[^\"]\",\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\""
148c18ec02fSPetter Reinholdtsen "%[^\"]\",\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\""
149c18ec02fSPetter Reinholdtsen "%[^\"]\",\"%[^\"]\",\"%[^\"]\"\n",
150c18ec02fSPetter Reinholdtsen buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
151c18ec02fSPetter Reinholdtsen buf[6], buf[7], buf[8], buf[9], buf[10], buf[11],
152c18ec02fSPetter Reinholdtsen buf[12], buf[13], buf[14]);
153c18ec02fSPetter Reinholdtsen
154c18ec02fSPetter Reinholdtsen if (n != 15) {
155c18ec02fSPetter Reinholdtsen lprintf (LOG_ERR, "Encountered problems reading line %d of %s",
156c18ec02fSPetter Reinholdtsen i+1, filename);
157c18ec02fSPetter Reinholdtsen fclose(fp);
158c18ec02fSPetter Reinholdtsen fp = NULL;
159c18ec02fSPetter Reinholdtsen sel_oem_nrecs = 0;
160c18ec02fSPetter Reinholdtsen /* free all the memory allocated so far */
161c18ec02fSPetter Reinholdtsen for (j=0; j<i ; j++) {
162c18ec02fSPetter Reinholdtsen for (k=3; k<17; k++) {
163c18ec02fSPetter Reinholdtsen if (sel_oem_msg[j].value[SEL_BYTE(k)] == -3) {
164c18ec02fSPetter Reinholdtsen free(sel_oem_msg[j].string[SEL_BYTE(k)]);
165c18ec02fSPetter Reinholdtsen sel_oem_msg[j].string[SEL_BYTE(k)] = NULL;
166c18ec02fSPetter Reinholdtsen }
167c18ec02fSPetter Reinholdtsen }
168c18ec02fSPetter Reinholdtsen }
169c18ec02fSPetter Reinholdtsen free(sel_oem_msg);
170c18ec02fSPetter Reinholdtsen sel_oem_msg = NULL;
171c18ec02fSPetter Reinholdtsen return -1;
172c18ec02fSPetter Reinholdtsen }
173c18ec02fSPetter Reinholdtsen
174c18ec02fSPetter Reinholdtsen for (byte = 3; byte < 17; byte++) {
175c18ec02fSPetter Reinholdtsen if ((sel_oem_msg[i].value[SEL_BYTE(byte)] =
176c18ec02fSPetter Reinholdtsen ipmi_sel_oem_readval(buf[SEL_BYTE(byte)])) == -3) {
177c18ec02fSPetter Reinholdtsen sel_oem_msg[i].string[SEL_BYTE(byte)] =
178c18ec02fSPetter Reinholdtsen (char *)malloc(strlen(buf[SEL_BYTE(byte)]) + 1);
179c18ec02fSPetter Reinholdtsen strcpy(sel_oem_msg[i].string[SEL_BYTE(byte)],
180c18ec02fSPetter Reinholdtsen buf[SEL_BYTE(byte)]);
181c18ec02fSPetter Reinholdtsen }
182c18ec02fSPetter Reinholdtsen }
183c18ec02fSPetter Reinholdtsen sel_oem_msg[i].text = (char *)malloc(strlen(buf[SEL_BYTE(17)]) + 1);
184c18ec02fSPetter Reinholdtsen strcpy(sel_oem_msg[i].text, buf[SEL_BYTE(17)]);
185c18ec02fSPetter Reinholdtsen }
186c18ec02fSPetter Reinholdtsen
187c18ec02fSPetter Reinholdtsen fclose(fp);
188c18ec02fSPetter Reinholdtsen fp = NULL;
189c18ec02fSPetter Reinholdtsen return 0;
190c18ec02fSPetter Reinholdtsen }
191c18ec02fSPetter Reinholdtsen
ipmi_sel_oem_message(struct sel_event_record * evt,int verbose)192c18ec02fSPetter Reinholdtsen static void ipmi_sel_oem_message(struct sel_event_record * evt, int verbose)
193c18ec02fSPetter Reinholdtsen {
194c18ec02fSPetter Reinholdtsen /*
195c18ec02fSPetter Reinholdtsen * Note: although we have a verbose argument, currently the output
196c18ec02fSPetter Reinholdtsen * isn't affected by it.
197c18ec02fSPetter Reinholdtsen */
198c18ec02fSPetter Reinholdtsen int i, j;
199c18ec02fSPetter Reinholdtsen
200c18ec02fSPetter Reinholdtsen for (i=0; i < sel_oem_nrecs; i++) {
201*88891f69SZdenek Styblik if (ipmi_sel_oem_match((uint8_t *)evt, &sel_oem_msg[i])) {
202c18ec02fSPetter Reinholdtsen printf (csv_output ? ",\"%s\"" : " | %s", sel_oem_msg[i].text);
203c18ec02fSPetter Reinholdtsen for (j=4; j<17; j++) {
204c18ec02fSPetter Reinholdtsen if (sel_oem_msg[i].value[SEL_BYTE(j)] == -3) {
205c18ec02fSPetter Reinholdtsen printf (csv_output ? ",%s=0x%x" : " %s = 0x%x",
206c18ec02fSPetter Reinholdtsen sel_oem_msg[i].string[SEL_BYTE(j)],
207c18ec02fSPetter Reinholdtsen ((uint8_t *)evt)[SEL_BYTE(j)]);
208c18ec02fSPetter Reinholdtsen }
209c18ec02fSPetter Reinholdtsen }
210c18ec02fSPetter Reinholdtsen }
211c18ec02fSPetter Reinholdtsen }
212c18ec02fSPetter Reinholdtsen }
213c18ec02fSPetter Reinholdtsen
214c18ec02fSPetter Reinholdtsen static const struct valstr event_dir_vals[] = {
215c18ec02fSPetter Reinholdtsen { 0, "Assertion Event" },
216c18ec02fSPetter Reinholdtsen { 1, "Deassertion Event" },
217c18ec02fSPetter Reinholdtsen { 0, NULL },
218c18ec02fSPetter Reinholdtsen };
219c18ec02fSPetter Reinholdtsen
220c18ec02fSPetter Reinholdtsen static const char *
ipmi_get_event_type(uint8_t code)221c18ec02fSPetter Reinholdtsen ipmi_get_event_type(uint8_t code)
222c18ec02fSPetter Reinholdtsen {
223c18ec02fSPetter Reinholdtsen if (code == 0)
224c18ec02fSPetter Reinholdtsen return "Unspecified";
225c18ec02fSPetter Reinholdtsen if (code == 1)
226c18ec02fSPetter Reinholdtsen return "Threshold";
227c18ec02fSPetter Reinholdtsen if (code >= 0x02 && code <= 0x0b)
228c18ec02fSPetter Reinholdtsen return "Generic Discrete";
229c18ec02fSPetter Reinholdtsen if (code == 0x6f)
230c18ec02fSPetter Reinholdtsen return "Sensor-specific Discrete";
231c18ec02fSPetter Reinholdtsen if (code >= 0x70 && code <= 0x7f)
232c18ec02fSPetter Reinholdtsen return "OEM";
233c18ec02fSPetter Reinholdtsen return "Reserved";
234c18ec02fSPetter Reinholdtsen }
235c18ec02fSPetter Reinholdtsen
236c18ec02fSPetter Reinholdtsen static char *
ipmi_sel_timestamp(uint32_t stamp)237c18ec02fSPetter Reinholdtsen ipmi_sel_timestamp(uint32_t stamp)
238c18ec02fSPetter Reinholdtsen {
239c18ec02fSPetter Reinholdtsen static char tbuf[40];
240c18ec02fSPetter Reinholdtsen time_t s = (time_t)stamp;
241c18ec02fSPetter Reinholdtsen memset(tbuf, 0, 40);
242c18ec02fSPetter Reinholdtsen strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", gmtime(&s));
243c18ec02fSPetter Reinholdtsen return tbuf;
244c18ec02fSPetter Reinholdtsen }
245c18ec02fSPetter Reinholdtsen
246c18ec02fSPetter Reinholdtsen static char *
ipmi_sel_timestamp_date(uint32_t stamp)247c18ec02fSPetter Reinholdtsen ipmi_sel_timestamp_date(uint32_t stamp)
248c18ec02fSPetter Reinholdtsen {
249c18ec02fSPetter Reinholdtsen static char tbuf[11];
250c18ec02fSPetter Reinholdtsen time_t s = (time_t)stamp;
251c18ec02fSPetter Reinholdtsen strftime(tbuf, sizeof(tbuf), "%m/%d/%Y", gmtime(&s));
252c18ec02fSPetter Reinholdtsen return tbuf;
253c18ec02fSPetter Reinholdtsen }
254c18ec02fSPetter Reinholdtsen
255c18ec02fSPetter Reinholdtsen static char *
ipmi_sel_timestamp_time(uint32_t stamp)256c18ec02fSPetter Reinholdtsen ipmi_sel_timestamp_time(uint32_t stamp)
257c18ec02fSPetter Reinholdtsen {
258c18ec02fSPetter Reinholdtsen static char tbuf[9];
259c18ec02fSPetter Reinholdtsen time_t s = (time_t)stamp;
260c18ec02fSPetter Reinholdtsen strftime(tbuf, sizeof(tbuf), "%H:%M:%S", gmtime(&s));
261c18ec02fSPetter Reinholdtsen return tbuf;
262c18ec02fSPetter Reinholdtsen }
263c18ec02fSPetter Reinholdtsen
264c18ec02fSPetter Reinholdtsen static char *
hex2ascii(uint8_t * hexChars,uint8_t numBytes)265c18ec02fSPetter Reinholdtsen hex2ascii (uint8_t * hexChars, uint8_t numBytes)
266c18ec02fSPetter Reinholdtsen {
267c18ec02fSPetter Reinholdtsen int count;
268c18ec02fSPetter Reinholdtsen static char hexString[SEL_OEM_NOTS_DATA_LEN+1]; /*Max Size*/
269c18ec02fSPetter Reinholdtsen
270c18ec02fSPetter Reinholdtsen if(numBytes > SEL_OEM_NOTS_DATA_LEN)
271c18ec02fSPetter Reinholdtsen numBytes = SEL_OEM_NOTS_DATA_LEN;
272c18ec02fSPetter Reinholdtsen
273c18ec02fSPetter Reinholdtsen for(count=0;count < numBytes;count++)
274c18ec02fSPetter Reinholdtsen {
275c18ec02fSPetter Reinholdtsen if((hexChars[count]<0x40)||(hexChars[count]>0x7e))
276c18ec02fSPetter Reinholdtsen hexString[count]='.';
277c18ec02fSPetter Reinholdtsen else
278c18ec02fSPetter Reinholdtsen hexString[count]=hexChars[count];
279c18ec02fSPetter Reinholdtsen }
280c18ec02fSPetter Reinholdtsen hexString[numBytes]='\0';
281c18ec02fSPetter Reinholdtsen return hexString;
282c18ec02fSPetter Reinholdtsen }
283c18ec02fSPetter Reinholdtsen
284c18ec02fSPetter Reinholdtsen IPMI_OEM
ipmi_get_oem(struct ipmi_intf * intf)285c18ec02fSPetter Reinholdtsen ipmi_get_oem(struct ipmi_intf * intf)
286c18ec02fSPetter Reinholdtsen {
287c18ec02fSPetter Reinholdtsen /* Execute a Get Device ID command to determine the OEM */
288c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
289c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
290c18ec02fSPetter Reinholdtsen struct ipm_devid_rsp *devid;
291c18ec02fSPetter Reinholdtsen
292c18ec02fSPetter Reinholdtsen if (intf->fd == 0) {
293c18ec02fSPetter Reinholdtsen if( sel_iana != IPMI_OEM_UNKNOWN ){
294c18ec02fSPetter Reinholdtsen return sel_iana;
295c18ec02fSPetter Reinholdtsen }
296c18ec02fSPetter Reinholdtsen return IPMI_OEM_UNKNOWN;
297c18ec02fSPetter Reinholdtsen }
298c18ec02fSPetter Reinholdtsen
299c18ec02fSPetter Reinholdtsen /*
300c18ec02fSPetter Reinholdtsen * Return the cached manufacturer id if the device is open and
301c18ec02fSPetter Reinholdtsen * we got an identified OEM owner. Otherwise just attempt to read
302c18ec02fSPetter Reinholdtsen * it.
303c18ec02fSPetter Reinholdtsen */
304c18ec02fSPetter Reinholdtsen if (intf->opened && intf->manufacturer_id != IPMI_OEM_UNKNOWN) {
305c18ec02fSPetter Reinholdtsen return intf->manufacturer_id;
306c18ec02fSPetter Reinholdtsen }
307c18ec02fSPetter Reinholdtsen
308c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
309c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
310c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_GET_DEVICE_ID;
311c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
312c18ec02fSPetter Reinholdtsen
313c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
314c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
315c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Device ID command failed");
316c18ec02fSPetter Reinholdtsen return IPMI_OEM_UNKNOWN;
317c18ec02fSPetter Reinholdtsen }
318c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
319c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Device ID command failed: %#x %s",
320c18ec02fSPetter Reinholdtsen rsp->ccode, val2str(rsp->ccode, completion_code_vals));
321c18ec02fSPetter Reinholdtsen return IPMI_OEM_UNKNOWN;
322c18ec02fSPetter Reinholdtsen }
323c18ec02fSPetter Reinholdtsen
324c18ec02fSPetter Reinholdtsen devid = (struct ipm_devid_rsp *) rsp->data;
325c18ec02fSPetter Reinholdtsen
326c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG,"Iana: %u",
327c18ec02fSPetter Reinholdtsen IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id));
328c18ec02fSPetter Reinholdtsen
329c18ec02fSPetter Reinholdtsen return IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id);
330c18ec02fSPetter Reinholdtsen }
331c18ec02fSPetter Reinholdtsen
332c18ec02fSPetter Reinholdtsen static int
ipmi_sel_add_entry(struct ipmi_intf * intf,struct sel_event_record * rec)333c18ec02fSPetter Reinholdtsen ipmi_sel_add_entry(struct ipmi_intf * intf, struct sel_event_record * rec)
334c18ec02fSPetter Reinholdtsen {
335c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
336c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
337c18ec02fSPetter Reinholdtsen
338c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
339c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
340c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_CMD_ADD_SEL_ENTRY;
341c18ec02fSPetter Reinholdtsen req.msg.data = (unsigned char *)rec;
342c18ec02fSPetter Reinholdtsen req.msg.data_len = 16;
343c18ec02fSPetter Reinholdtsen
344c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry(intf, rec);
345c18ec02fSPetter Reinholdtsen
346c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
347c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
348c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Add SEL Entry failed");
349c18ec02fSPetter Reinholdtsen return -1;
350c18ec02fSPetter Reinholdtsen }
351c18ec02fSPetter Reinholdtsen else if (rsp->ccode > 0) {
352c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Add SEL Entry failed: %s",
353c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
354c18ec02fSPetter Reinholdtsen return -1;
355c18ec02fSPetter Reinholdtsen }
356c18ec02fSPetter Reinholdtsen
357c18ec02fSPetter Reinholdtsen return 0;
358c18ec02fSPetter Reinholdtsen }
359c18ec02fSPetter Reinholdtsen
360c18ec02fSPetter Reinholdtsen
361c18ec02fSPetter Reinholdtsen static int
ipmi_sel_add_entries_fromfile(struct ipmi_intf * intf,const char * filename)362c18ec02fSPetter Reinholdtsen ipmi_sel_add_entries_fromfile(struct ipmi_intf * intf, const char * filename)
363c18ec02fSPetter Reinholdtsen {
364c18ec02fSPetter Reinholdtsen FILE * fp;
365c18ec02fSPetter Reinholdtsen char buf[1024];
366c18ec02fSPetter Reinholdtsen char * ptr, * tok;
367c18ec02fSPetter Reinholdtsen int i, j;
368c18ec02fSPetter Reinholdtsen int rc = 0;
369c18ec02fSPetter Reinholdtsen uint8_t rqdata[8];
370c18ec02fSPetter Reinholdtsen struct sel_event_record sel_event;
371c18ec02fSPetter Reinholdtsen
372c18ec02fSPetter Reinholdtsen if (filename == NULL)
373c18ec02fSPetter Reinholdtsen return -1;
374c18ec02fSPetter Reinholdtsen
375c18ec02fSPetter Reinholdtsen fp = ipmi_open_file_read(filename);
376c18ec02fSPetter Reinholdtsen if (fp == NULL)
377c18ec02fSPetter Reinholdtsen return -1;
378c18ec02fSPetter Reinholdtsen
379c18ec02fSPetter Reinholdtsen while (feof(fp) == 0) {
380c18ec02fSPetter Reinholdtsen if (fgets(buf, 1024, fp) == NULL)
381c18ec02fSPetter Reinholdtsen continue;
382c18ec02fSPetter Reinholdtsen
383c18ec02fSPetter Reinholdtsen /* clip off optional comment tail indicated by # */
384c18ec02fSPetter Reinholdtsen ptr = strchr(buf, '#');
385c18ec02fSPetter Reinholdtsen if (ptr)
386c18ec02fSPetter Reinholdtsen *ptr = '\0';
387c18ec02fSPetter Reinholdtsen else
388c18ec02fSPetter Reinholdtsen ptr = buf + strlen(buf);
389c18ec02fSPetter Reinholdtsen
390c18ec02fSPetter Reinholdtsen /* clip off trailing and leading whitespace */
391c18ec02fSPetter Reinholdtsen ptr--;
392c18ec02fSPetter Reinholdtsen while (isspace((int)*ptr) && ptr >= buf)
393c18ec02fSPetter Reinholdtsen *ptr-- = '\0';
394c18ec02fSPetter Reinholdtsen ptr = buf;
395c18ec02fSPetter Reinholdtsen while (isspace((int)*ptr))
396c18ec02fSPetter Reinholdtsen ptr++;
397c18ec02fSPetter Reinholdtsen if (strlen(ptr) == 0)
398c18ec02fSPetter Reinholdtsen continue;
399c18ec02fSPetter Reinholdtsen
400c18ec02fSPetter Reinholdtsen /* parse the event, 7 bytes with optional comment */
401c18ec02fSPetter Reinholdtsen /* 0x00 0x00 0x00 0x00 0x00 0x00 0x00 # event */
402c18ec02fSPetter Reinholdtsen i = 0;
403c18ec02fSPetter Reinholdtsen tok = strtok(ptr, " ");
404c18ec02fSPetter Reinholdtsen while (tok) {
405c18ec02fSPetter Reinholdtsen if (i == 7)
406c18ec02fSPetter Reinholdtsen break;
407c18ec02fSPetter Reinholdtsen j = i++;
408c18ec02fSPetter Reinholdtsen if (str2uchar(tok, &rqdata[j]) != 0) {
409c18ec02fSPetter Reinholdtsen break;
410c18ec02fSPetter Reinholdtsen }
411c18ec02fSPetter Reinholdtsen tok = strtok(NULL, " ");
412c18ec02fSPetter Reinholdtsen }
413c18ec02fSPetter Reinholdtsen if (i < 7) {
414c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Event: %s",
415c18ec02fSPetter Reinholdtsen buf2str(rqdata, sizeof(rqdata)));
416c18ec02fSPetter Reinholdtsen continue;
417c18ec02fSPetter Reinholdtsen }
418c18ec02fSPetter Reinholdtsen
419c18ec02fSPetter Reinholdtsen memset(&sel_event, 0, sizeof(struct sel_event_record));
420c18ec02fSPetter Reinholdtsen sel_event.record_id = 0x0000;
421c18ec02fSPetter Reinholdtsen sel_event.record_type = 0x02;
422c18ec02fSPetter Reinholdtsen sel_event.sel_type.standard_type.gen_id = 0x00;
423c18ec02fSPetter Reinholdtsen sel_event.sel_type.standard_type.evm_rev = rqdata[0];
424c18ec02fSPetter Reinholdtsen sel_event.sel_type.standard_type.sensor_type = rqdata[1];
425c18ec02fSPetter Reinholdtsen sel_event.sel_type.standard_type.sensor_num = rqdata[2];
426c18ec02fSPetter Reinholdtsen sel_event.sel_type.standard_type.event_type = rqdata[3] & 0x7f;
427c18ec02fSPetter Reinholdtsen sel_event.sel_type.standard_type.event_dir = (rqdata[3] & 0x80) >> 7;
428c18ec02fSPetter Reinholdtsen sel_event.sel_type.standard_type.event_data[0] = rqdata[4];
429c18ec02fSPetter Reinholdtsen sel_event.sel_type.standard_type.event_data[1] = rqdata[5];
430c18ec02fSPetter Reinholdtsen sel_event.sel_type.standard_type.event_data[2] = rqdata[6];
431c18ec02fSPetter Reinholdtsen
432c18ec02fSPetter Reinholdtsen rc = ipmi_sel_add_entry(intf, &sel_event);
433c18ec02fSPetter Reinholdtsen if (rc < 0)
434c18ec02fSPetter Reinholdtsen break;
435c18ec02fSPetter Reinholdtsen }
436c18ec02fSPetter Reinholdtsen
437c18ec02fSPetter Reinholdtsen fclose(fp);
438c18ec02fSPetter Reinholdtsen return rc;
439c18ec02fSPetter Reinholdtsen }
440c18ec02fSPetter Reinholdtsen
441c18ec02fSPetter Reinholdtsen static struct ipmi_event_sensor_types oem_kontron_event_reading_types[] __attribute__((unused)) = {
442c18ec02fSPetter Reinholdtsen { 0x70 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info 1", "Code Assert" },
443c18ec02fSPetter Reinholdtsen { 0x71 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info 2", "Code Assert" },
444c18ec02fSPetter Reinholdtsen };
445c18ec02fSPetter Reinholdtsen
446c18ec02fSPetter Reinholdtsen char *
get_kontron_evt_desc(struct ipmi_intf * intf,struct sel_event_record * rec)447c18ec02fSPetter Reinholdtsen get_kontron_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
448c18ec02fSPetter Reinholdtsen {
449c18ec02fSPetter Reinholdtsen char * description = NULL;
450c18ec02fSPetter Reinholdtsen /*
451c18ec02fSPetter Reinholdtsen * Kontron OEM events are described in the product's user manual, but are limited in favor of
452c18ec02fSPetter Reinholdtsen * sensor specific
453c18ec02fSPetter Reinholdtsen */
454c18ec02fSPetter Reinholdtsen
455c18ec02fSPetter Reinholdtsen /* Only standard records are defined so far */
456c18ec02fSPetter Reinholdtsen if( rec->record_type < 0xC0 ){
457c18ec02fSPetter Reinholdtsen struct ipmi_event_sensor_types *st=NULL;
458c18ec02fSPetter Reinholdtsen for ( st=oem_kontron_event_reading_types ; st->type != NULL; st++){
459c18ec02fSPetter Reinholdtsen if (st->code == rec->sel_type.standard_type.event_type ){
460c18ec02fSPetter Reinholdtsen size_t len =strlen(st->desc);
461c18ec02fSPetter Reinholdtsen description = (char*)malloc( len + 1 );
462c18ec02fSPetter Reinholdtsen memcpy(description, st->desc , len);
463c18ec02fSPetter Reinholdtsen description[len] = 0;;
464c18ec02fSPetter Reinholdtsen return description;
465c18ec02fSPetter Reinholdtsen }
466c18ec02fSPetter Reinholdtsen }
467c18ec02fSPetter Reinholdtsen }
468c18ec02fSPetter Reinholdtsen
469c18ec02fSPetter Reinholdtsen return NULL;
470c18ec02fSPetter Reinholdtsen }
471c18ec02fSPetter Reinholdtsen
472c18ec02fSPetter Reinholdtsen char *
get_newisys_evt_desc(struct ipmi_intf * intf,struct sel_event_record * rec)473c18ec02fSPetter Reinholdtsen get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
474c18ec02fSPetter Reinholdtsen {
475c18ec02fSPetter Reinholdtsen /*
476c18ec02fSPetter Reinholdtsen * Newisys OEM event descriptions can be retrieved through an
477c18ec02fSPetter Reinholdtsen * OEM IPMI command.
478c18ec02fSPetter Reinholdtsen */
479c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
480c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
481c18ec02fSPetter Reinholdtsen uint8_t msg_data[6];
482c18ec02fSPetter Reinholdtsen char * description = NULL;
483c18ec02fSPetter Reinholdtsen
484c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
485c18ec02fSPetter Reinholdtsen req.msg.netfn = 0x2E;
486c18ec02fSPetter Reinholdtsen req.msg.cmd = 0x01;
487c18ec02fSPetter Reinholdtsen req.msg.data_len = sizeof(msg_data);
488c18ec02fSPetter Reinholdtsen
489c18ec02fSPetter Reinholdtsen msg_data[0] = 0x15; /* IANA LSB */
490c18ec02fSPetter Reinholdtsen msg_data[1] = 0x24; /* IANA */
491c18ec02fSPetter Reinholdtsen msg_data[2] = 0x00; /* IANA MSB */
492c18ec02fSPetter Reinholdtsen msg_data[3] = 0x01; /* Subcommand */
493c18ec02fSPetter Reinholdtsen msg_data[4] = rec->record_id & 0x00FF; /* SEL Record ID LSB */
494c18ec02fSPetter Reinholdtsen msg_data[5] = (rec->record_id & 0xFF00) >> 8; /* SEL Record ID MSB */
495c18ec02fSPetter Reinholdtsen
496c18ec02fSPetter Reinholdtsen req.msg.data = msg_data;
497c18ec02fSPetter Reinholdtsen
498c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
499c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
500c18ec02fSPetter Reinholdtsen if (verbose)
501c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Error issuing OEM command");
502c18ec02fSPetter Reinholdtsen return NULL;
503c18ec02fSPetter Reinholdtsen }
504c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
505c18ec02fSPetter Reinholdtsen if (verbose)
506c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "OEM command returned error code: %s",
507c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
508c18ec02fSPetter Reinholdtsen return NULL;
509c18ec02fSPetter Reinholdtsen }
510c18ec02fSPetter Reinholdtsen
511c18ec02fSPetter Reinholdtsen /* Verify our response before we use it */
512c18ec02fSPetter Reinholdtsen if (rsp->data_len < 5)
513c18ec02fSPetter Reinholdtsen {
514c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Newisys OEM response too short");
515c18ec02fSPetter Reinholdtsen return NULL;
516c18ec02fSPetter Reinholdtsen }
517c18ec02fSPetter Reinholdtsen else if (rsp->data_len != (4 + rsp->data[3]))
518c18ec02fSPetter Reinholdtsen {
519c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Newisys OEM response has unexpected length");
520c18ec02fSPetter Reinholdtsen return NULL;
521c18ec02fSPetter Reinholdtsen }
522c18ec02fSPetter Reinholdtsen else if (IPM_DEV_MANUFACTURER_ID(rsp->data) != IPMI_OEM_NEWISYS)
523c18ec02fSPetter Reinholdtsen {
524c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Newisys OEM response has unexpected length");
525c18ec02fSPetter Reinholdtsen return NULL;
526c18ec02fSPetter Reinholdtsen }
527c18ec02fSPetter Reinholdtsen
528c18ec02fSPetter Reinholdtsen description = (char*)malloc(rsp->data[3] + 1);
529c18ec02fSPetter Reinholdtsen memcpy(description, rsp->data + 4, rsp->data[3]);
530c18ec02fSPetter Reinholdtsen description[rsp->data[3]] = 0;;
531c18ec02fSPetter Reinholdtsen
532c18ec02fSPetter Reinholdtsen return description;
533c18ec02fSPetter Reinholdtsen }
534c18ec02fSPetter Reinholdtsen
535c18ec02fSPetter Reinholdtsen char *
get_supermicro_evt_desc(struct ipmi_intf * intf,struct sel_event_record * rec)536c18ec02fSPetter Reinholdtsen get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec)
537c18ec02fSPetter Reinholdtsen {
538c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp;
539c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
540c18ec02fSPetter Reinholdtsen char *desc = NULL;
541c18ec02fSPetter Reinholdtsen int chipset_type = 1;
542c18ec02fSPetter Reinholdtsen int data1;
543c18ec02fSPetter Reinholdtsen int data2;
544c18ec02fSPetter Reinholdtsen int data3;
545c18ec02fSPetter Reinholdtsen int sensor_type;
546c18ec02fSPetter Reinholdtsen uint8_t i = 0;
547c18ec02fSPetter Reinholdtsen uint16_t oem_id = 0;
548c18ec02fSPetter Reinholdtsen /* Get the OEM event Bytes of the SEL Records byte 13, 14, 15 to
549c18ec02fSPetter Reinholdtsen * data1,data2,data3
550c18ec02fSPetter Reinholdtsen */
551c18ec02fSPetter Reinholdtsen data1 = rec->sel_type.standard_type.event_data[0];
552c18ec02fSPetter Reinholdtsen data2 = rec->sel_type.standard_type.event_data[1];
553c18ec02fSPetter Reinholdtsen data3 = rec->sel_type.standard_type.event_data[2];
554c18ec02fSPetter Reinholdtsen /* Check for the Standard Event type == 0x6F */
555c18ec02fSPetter Reinholdtsen if (rec->sel_type.standard_type.event_type != 0x6F) {
556c18ec02fSPetter Reinholdtsen return NULL;
557c18ec02fSPetter Reinholdtsen }
558c18ec02fSPetter Reinholdtsen /* Allocate mem for te Description string */
559aabd9eb1SZdenek Styblik desc = malloc(sizeof(char) * SIZE_OF_DESC);
560c18ec02fSPetter Reinholdtsen if (desc == NULL) {
561c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: malloc failure");
562c18ec02fSPetter Reinholdtsen return NULL;
563c18ec02fSPetter Reinholdtsen }
564aabd9eb1SZdenek Styblik memset(desc, '\0', SIZE_OF_DESC);
565c18ec02fSPetter Reinholdtsen sensor_type = rec->sel_type.standard_type.sensor_type;
566c18ec02fSPetter Reinholdtsen switch (sensor_type) {
567c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_MEMORY:
568c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof (req));
569c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
570c18ec02fSPetter Reinholdtsen req.msg.lun = 0;
571c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_GET_DEVICE_ID;
572c18ec02fSPetter Reinholdtsen req.msg.data = NULL;
573c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
574c18ec02fSPetter Reinholdtsen
575c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
576c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
577c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, " Error getting system info");
578c18ec02fSPetter Reinholdtsen if (desc != NULL) {
579c18ec02fSPetter Reinholdtsen free(desc);
580c18ec02fSPetter Reinholdtsen desc = NULL;
581c18ec02fSPetter Reinholdtsen }
582c18ec02fSPetter Reinholdtsen return NULL;
583c18ec02fSPetter Reinholdtsen } else if (rsp->ccode > 0) {
584c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, " Error getting system info: %s",
585c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
586c18ec02fSPetter Reinholdtsen if (desc != NULL) {
587c18ec02fSPetter Reinholdtsen free(desc);
588c18ec02fSPetter Reinholdtsen desc = NULL;
589c18ec02fSPetter Reinholdtsen }
590c18ec02fSPetter Reinholdtsen return NULL;
591c18ec02fSPetter Reinholdtsen }
592c18ec02fSPetter Reinholdtsen /* check the chipset type */
593c18ec02fSPetter Reinholdtsen oem_id = ipmi_get_oem_id(intf);
594c18ec02fSPetter Reinholdtsen if (oem_id == 0) {
595e37e3ab7SZdenek Styblik if (desc != NULL) {
596e37e3ab7SZdenek Styblik free(desc);
597e37e3ab7SZdenek Styblik desc = NULL;
598e37e3ab7SZdenek Styblik }
599c18ec02fSPetter Reinholdtsen return NULL;
600c18ec02fSPetter Reinholdtsen }
601b6ec5072SZdenek Styblik for (i = 0; supermicro_X8[i] != 0xFFFF; i++) {
602c18ec02fSPetter Reinholdtsen if (oem_id == supermicro_X8[i]) {
603c18ec02fSPetter Reinholdtsen chipset_type = 0;
604c18ec02fSPetter Reinholdtsen break;
605c18ec02fSPetter Reinholdtsen }
606c18ec02fSPetter Reinholdtsen }
607b6ec5072SZdenek Styblik for (i = 0; supermicro_x9[i] != 0xFFFF; i++) {
608c18ec02fSPetter Reinholdtsen if (oem_id == supermicro_x9[i]) {
609c18ec02fSPetter Reinholdtsen chipset_type = 2;
610c18ec02fSPetter Reinholdtsen break;
611c18ec02fSPetter Reinholdtsen }
612c18ec02fSPetter Reinholdtsen }
613c18ec02fSPetter Reinholdtsen if (chipset_type == 0) {
614c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "@DIMM%2X(CPU%x)",
615c18ec02fSPetter Reinholdtsen data2,
616c18ec02fSPetter Reinholdtsen (data3 & 0x03) + 1);
617c18ec02fSPetter Reinholdtsen } else if (chipset_type == 1) {
618c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
619c18ec02fSPetter Reinholdtsen (data2 >> 4) + 0x40 + (data3 & 0x3) * 4,
620c18ec02fSPetter Reinholdtsen (data2 & 0xf) + 0x27, (data3 & 0x03) + 1);
621c18ec02fSPetter Reinholdtsen } else if (chipset_type == 2) {
622c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
623c18ec02fSPetter Reinholdtsen (data2 >> 4) + 0x40 + (data3 & 0x3) * 3,
624c18ec02fSPetter Reinholdtsen (data2 & 0xf) + 0x27, (data3 & 0x03) + 1);
625c18ec02fSPetter Reinholdtsen } else {
626aabd9eb1SZdenek Styblik /* No description. */
627aabd9eb1SZdenek Styblik desc[0] = '\0';
628c18ec02fSPetter Reinholdtsen }
629c18ec02fSPetter Reinholdtsen break;
630c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_SUPERMICRO_OEM:
631c18ec02fSPetter Reinholdtsen if (data1 == 0x80 && data3 == 0xFF) {
632c18ec02fSPetter Reinholdtsen if (data2 == 0x0) {
633c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "BMC unexpected reset");
634c18ec02fSPetter Reinholdtsen } else if (data2 == 0x1) {
635c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "BMC cold reset");
636c18ec02fSPetter Reinholdtsen } else if (data2 == 0x2) {
637c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "BMC warm reset");
638c18ec02fSPetter Reinholdtsen }
639c18ec02fSPetter Reinholdtsen }
640c18ec02fSPetter Reinholdtsen break;
641c18ec02fSPetter Reinholdtsen }
642c18ec02fSPetter Reinholdtsen return desc;
643c18ec02fSPetter Reinholdtsen }
644c18ec02fSPetter Reinholdtsen
645c18ec02fSPetter Reinholdtsen /*
646c18ec02fSPetter Reinholdtsen * Function : Decoding the SEL OEM Bytes for the DELL Platforms.
647c18ec02fSPetter Reinholdtsen * Description : The below fucntion will decode the SEL Events OEM Bytes for the Dell specific Sensors only.
648c18ec02fSPetter Reinholdtsen * The below function will append the additional information Strings/description to the normal sel desc.
649c18ec02fSPetter Reinholdtsen * With this the SEL will display additional information sent via OEM Bytes of the SEL Record.
650c18ec02fSPetter Reinholdtsen * NOTE : Specific to DELL Platforms only.
651c18ec02fSPetter Reinholdtsen * Returns : Pointer to the char string.
652c18ec02fSPetter Reinholdtsen */
get_dell_evt_desc(struct ipmi_intf * intf,struct sel_event_record * rec)653c18ec02fSPetter Reinholdtsen char * get_dell_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
654c18ec02fSPetter Reinholdtsen {
655c18ec02fSPetter Reinholdtsen int data1, data2, data3;
656c18ec02fSPetter Reinholdtsen int sensor_type;
657c18ec02fSPetter Reinholdtsen char *desc = NULL;
658c18ec02fSPetter Reinholdtsen
659c18ec02fSPetter Reinholdtsen unsigned char count;
660c18ec02fSPetter Reinholdtsen unsigned char node;
661c18ec02fSPetter Reinholdtsen unsigned char dimmNum;
662c18ec02fSPetter Reinholdtsen unsigned char dimmsPerNode;
663c18ec02fSPetter Reinholdtsen char dimmStr[MAX_DIMM_STR];
664c18ec02fSPetter Reinholdtsen char tmpdesc[SIZE_OF_DESC];
665c18ec02fSPetter Reinholdtsen char* str;
666c18ec02fSPetter Reinholdtsen unsigned char incr = 0;
667c18ec02fSPetter Reinholdtsen unsigned char i=0,j = 0;
668c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp;
669c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
670c18ec02fSPetter Reinholdtsen char tmpData;
671c18ec02fSPetter Reinholdtsen int version;
672c18ec02fSPetter Reinholdtsen /* Get the OEM event Bytes of the SEL Records byte 13, 14, 15 to Data1,data2,data3 */
673c18ec02fSPetter Reinholdtsen data1 = rec->sel_type.standard_type.event_data[0];
674c18ec02fSPetter Reinholdtsen data2 = rec->sel_type.standard_type.event_data[1];
675c18ec02fSPetter Reinholdtsen data3 = rec->sel_type.standard_type.event_data[2];
676c18ec02fSPetter Reinholdtsen /* Check for the Standard Event type == 0x6F */
677c18ec02fSPetter Reinholdtsen if (0x6F == rec->sel_type.standard_type.event_type)
678c18ec02fSPetter Reinholdtsen {
679c18ec02fSPetter Reinholdtsen sensor_type = rec->sel_type.standard_type.sensor_type;
680c18ec02fSPetter Reinholdtsen /* Allocate mem for te Description string */
681c18ec02fSPetter Reinholdtsen desc = (char*)malloc(SIZE_OF_DESC);
682c18ec02fSPetter Reinholdtsen if(NULL == desc)
683c18ec02fSPetter Reinholdtsen return NULL;
684c18ec02fSPetter Reinholdtsen memset(desc,0,SIZE_OF_DESC);
685c18ec02fSPetter Reinholdtsen memset(tmpdesc,0,SIZE_OF_DESC);
686c18ec02fSPetter Reinholdtsen switch (sensor_type) {
687c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_PROCESSOR: /* Processor/CPU related OEM Sel Byte Decoding for DELL Platforms only */
688c18ec02fSPetter Reinholdtsen if((OEM_CODE_IN_BYTE2 == (data1 & DATA_BYTE2_SPECIFIED_MASK)))
689c18ec02fSPetter Reinholdtsen {
690c18ec02fSPetter Reinholdtsen if(0x00 == (data1 & MASK_LOWER_NIBBLE))
691c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"CPU Internal Err | ");
692c18ec02fSPetter Reinholdtsen if(0x06 == (data1 & MASK_LOWER_NIBBLE))
693c18ec02fSPetter Reinholdtsen {
694c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"CPU Protocol Err | ");
695c18ec02fSPetter Reinholdtsen
696c18ec02fSPetter Reinholdtsen }
697c18ec02fSPetter Reinholdtsen
698c18ec02fSPetter Reinholdtsen /* change bit location to a number */
699c18ec02fSPetter Reinholdtsen for (count= 0; count < 8; count++)
700c18ec02fSPetter Reinholdtsen {
701c18ec02fSPetter Reinholdtsen if (BIT(count)& data2)
702c18ec02fSPetter Reinholdtsen {
703c18ec02fSPetter Reinholdtsen count++;
704c18ec02fSPetter Reinholdtsen /* 0x0A - CPU sensor number */
705c18ec02fSPetter Reinholdtsen if((0x06 == (data1 & MASK_LOWER_NIBBLE)) && (0x0A == rec->sel_type.standard_type.sensor_num))
706c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"FSB %d ",count); // Which CPU Has generated the FSB
707c18ec02fSPetter Reinholdtsen else
708c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"CPU %d | APIC ID %d ",count,data3); /* Specific CPU related info */
709c18ec02fSPetter Reinholdtsen break;
710c18ec02fSPetter Reinholdtsen }
711c18ec02fSPetter Reinholdtsen }
712c18ec02fSPetter Reinholdtsen }
713c18ec02fSPetter Reinholdtsen break;
714c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_MEMORY: /* Memory or DIMM related OEM Sel Byte Decoding for DELL Platforms only */
715c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_EVT_LOG: /* Events Logging for Memory or DIMM related OEM Sel Byte Decoding for DELL Platforms only */
716c18ec02fSPetter Reinholdtsen
717c18ec02fSPetter Reinholdtsen /* Get the current version of the IPMI Spec Based on that Decoding of memory info is done.*/
718c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof (req));
719c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
720c18ec02fSPetter Reinholdtsen req.msg.lun = 0;
721c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_GET_DEVICE_ID;
722c18ec02fSPetter Reinholdtsen req.msg.data = NULL;
723c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
724c18ec02fSPetter Reinholdtsen
725c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
726c18ec02fSPetter Reinholdtsen if (NULL == rsp)
727c18ec02fSPetter Reinholdtsen {
728c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, " Error getting system info");
729c18ec02fSPetter Reinholdtsen if (desc != NULL) {
730c18ec02fSPetter Reinholdtsen free(desc);
731c18ec02fSPetter Reinholdtsen desc = NULL;
732c18ec02fSPetter Reinholdtsen }
733c18ec02fSPetter Reinholdtsen return NULL;
734c18ec02fSPetter Reinholdtsen }
735c18ec02fSPetter Reinholdtsen else if (rsp->ccode > 0)
736c18ec02fSPetter Reinholdtsen {
737c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, " Error getting system info: %s",
738c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
739c18ec02fSPetter Reinholdtsen if (desc != NULL) {
740c18ec02fSPetter Reinholdtsen free(desc);
741c18ec02fSPetter Reinholdtsen desc = NULL;
742c18ec02fSPetter Reinholdtsen }
743c18ec02fSPetter Reinholdtsen return NULL;
744c18ec02fSPetter Reinholdtsen }
745c18ec02fSPetter Reinholdtsen version = rsp->data[4];
746c18ec02fSPetter Reinholdtsen /* Memory DIMMS */
747c18ec02fSPetter Reinholdtsen if( (data1 & OEM_CODE_IN_BYTE2) || (data1 & OEM_CODE_IN_BYTE3 ) )
748c18ec02fSPetter Reinholdtsen {
749c18ec02fSPetter Reinholdtsen /* Memory Redundancy related oem bytes docoding .. */
750c18ec02fSPetter Reinholdtsen if( (SENSOR_TYPE_MEMORY == sensor_type) && (0x0B == rec->sel_type.standard_type.event_type) )
751c18ec02fSPetter Reinholdtsen {
752c18ec02fSPetter Reinholdtsen if(0x00 == (data1 & MASK_LOWER_NIBBLE))
753c18ec02fSPetter Reinholdtsen {
754c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC," Redundancy Regained | ");
755c18ec02fSPetter Reinholdtsen }
756c18ec02fSPetter Reinholdtsen else if(0x01 == (data1 & MASK_LOWER_NIBBLE))
757c18ec02fSPetter Reinholdtsen {
758c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"Redundancy Lost | ");
759c18ec02fSPetter Reinholdtsen }
760c18ec02fSPetter Reinholdtsen } /* Correctable and uncorrectable ECC Error Decoding */
761c18ec02fSPetter Reinholdtsen else if(SENSOR_TYPE_MEMORY == sensor_type)
762c18ec02fSPetter Reinholdtsen {
763c18ec02fSPetter Reinholdtsen if(0x00 == (data1 & MASK_LOWER_NIBBLE))
764c18ec02fSPetter Reinholdtsen {
765c18ec02fSPetter Reinholdtsen /* 0x1C - Memory Sensor Number */
766c18ec02fSPetter Reinholdtsen if(0x1C == rec->sel_type.standard_type.sensor_num)
767c18ec02fSPetter Reinholdtsen {
768c18ec02fSPetter Reinholdtsen /*Add the complete information about the Memory Configs.*/
769c18ec02fSPetter Reinholdtsen if((data1 & OEM_CODE_IN_BYTE2) && (data1 & OEM_CODE_IN_BYTE3 ))
770c18ec02fSPetter Reinholdtsen {
771c18ec02fSPetter Reinholdtsen count = 0;
772c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"CRC Error on:");
773c18ec02fSPetter Reinholdtsen for(i=0;i<4;i++)
774c18ec02fSPetter Reinholdtsen {
775c18ec02fSPetter Reinholdtsen if((BIT(i))&(data2))
776c18ec02fSPetter Reinholdtsen {
777c18ec02fSPetter Reinholdtsen if(count)
778c18ec02fSPetter Reinholdtsen {
779c18ec02fSPetter Reinholdtsen str = desc+strlen(desc);
780c18ec02fSPetter Reinholdtsen *str++ = ',';
781c18ec02fSPetter Reinholdtsen str = '\0';
782c18ec02fSPetter Reinholdtsen count = 0;
783c18ec02fSPetter Reinholdtsen }
784c18ec02fSPetter Reinholdtsen switch(i) /* Which type of memory config is present.. */
785c18ec02fSPetter Reinholdtsen {
786c18ec02fSPetter Reinholdtsen case 0: snprintf(tmpdesc,SIZE_OF_DESC,"South Bound Memory");
787c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
788c18ec02fSPetter Reinholdtsen count++;
789c18ec02fSPetter Reinholdtsen break;
790c18ec02fSPetter Reinholdtsen case 1: snprintf(tmpdesc,SIZE_OF_DESC,"South Bound Config");
791c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
792c18ec02fSPetter Reinholdtsen count++;
793c18ec02fSPetter Reinholdtsen break;
794c18ec02fSPetter Reinholdtsen case 2: snprintf(tmpdesc,SIZE_OF_DESC,"North Bound memory");
795c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
796c18ec02fSPetter Reinholdtsen count++;
797c18ec02fSPetter Reinholdtsen break;
798c18ec02fSPetter Reinholdtsen case 3: snprintf(tmpdesc,SIZE_OF_DESC,"North Bound memory-corr");
799c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
800c18ec02fSPetter Reinholdtsen count++;
801c18ec02fSPetter Reinholdtsen break;
802c18ec02fSPetter Reinholdtsen default:
803c18ec02fSPetter Reinholdtsen break;
804c18ec02fSPetter Reinholdtsen }
805c18ec02fSPetter Reinholdtsen }
806c18ec02fSPetter Reinholdtsen }
807c18ec02fSPetter Reinholdtsen if(data3>=0x00 && data3<0xFF)
808c18ec02fSPetter Reinholdtsen {
809c18ec02fSPetter Reinholdtsen snprintf(tmpdesc,SIZE_OF_DESC,"|Failing_Channel:%d",data3);
810c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
811c18ec02fSPetter Reinholdtsen }
812c18ec02fSPetter Reinholdtsen }
813c18ec02fSPetter Reinholdtsen break;
814c18ec02fSPetter Reinholdtsen }
815c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"Correctable ECC | ");
816c18ec02fSPetter Reinholdtsen }
817c18ec02fSPetter Reinholdtsen else if(0x01 == (data1 & MASK_LOWER_NIBBLE))
818c18ec02fSPetter Reinholdtsen {
819c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"UnCorrectable ECC | ");
820c18ec02fSPetter Reinholdtsen }
821c18ec02fSPetter Reinholdtsen } /* Corr Memory log disabled */
822c18ec02fSPetter Reinholdtsen else if(SENSOR_TYPE_EVT_LOG == sensor_type)
823c18ec02fSPetter Reinholdtsen {
824c18ec02fSPetter Reinholdtsen if(0x00 == (data1 & MASK_LOWER_NIBBLE))
825c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"Corr Memory Log Disabled | ");
826c18ec02fSPetter Reinholdtsen }
827c18ec02fSPetter Reinholdtsen }
828c18ec02fSPetter Reinholdtsen else
829c18ec02fSPetter Reinholdtsen {
830c18ec02fSPetter Reinholdtsen if(SENSOR_TYPE_SYS_EVENT == sensor_type)
831c18ec02fSPetter Reinholdtsen {
832c18ec02fSPetter Reinholdtsen if(0x02 == (data1 & MASK_LOWER_NIBBLE))
833c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"Unknown System Hardware Failure ");
834c18ec02fSPetter Reinholdtsen }
835c18ec02fSPetter Reinholdtsen if(SENSOR_TYPE_EVT_LOG == sensor_type)
836c18ec02fSPetter Reinholdtsen {
837c18ec02fSPetter Reinholdtsen if(0x03 == (data1 & MASK_LOWER_NIBBLE))
838c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"All Even Logging Dissabled");
839c18ec02fSPetter Reinholdtsen }
840c18ec02fSPetter Reinholdtsen }
841c18ec02fSPetter Reinholdtsen /*
842c18ec02fSPetter Reinholdtsen * Based on the above error, we need to find whcih memory slot or
843c18ec02fSPetter Reinholdtsen * Card has got the Errors/Sel Generated.
844c18ec02fSPetter Reinholdtsen */
845c18ec02fSPetter Reinholdtsen if(data1 & OEM_CODE_IN_BYTE2 )
846c18ec02fSPetter Reinholdtsen {
847c18ec02fSPetter Reinholdtsen /* Find the Card Type */
848c18ec02fSPetter Reinholdtsen if((0x0F != (data2 >> 4)) && ((data2 >> 4) < 0x08))
849c18ec02fSPetter Reinholdtsen {
850c18ec02fSPetter Reinholdtsen tmpData = ('A'+ (data2 >> 4));
851c18ec02fSPetter Reinholdtsen if( (SENSOR_TYPE_MEMORY == sensor_type) && (0x0B == rec->sel_type.standard_type.event_type) )
852c18ec02fSPetter Reinholdtsen {
853c18ec02fSPetter Reinholdtsen snprintf(tmpdesc, SIZE_OF_DESC, "Bad Card %c", tmpData);
854c18ec02fSPetter Reinholdtsen }
855c18ec02fSPetter Reinholdtsen else
856c18ec02fSPetter Reinholdtsen {
857c18ec02fSPetter Reinholdtsen snprintf(tmpdesc, SIZE_OF_DESC, "Card %c", tmpData);
858c18ec02fSPetter Reinholdtsen }
859c18ec02fSPetter Reinholdtsen strcat(desc, tmpdesc);
860c18ec02fSPetter Reinholdtsen } /* Find the Bank Number of the DIMM */
861c18ec02fSPetter Reinholdtsen if (0x0F != (data2 & MASK_LOWER_NIBBLE))
862c18ec02fSPetter Reinholdtsen {
863c18ec02fSPetter Reinholdtsen if(0x51 == version)
864c18ec02fSPetter Reinholdtsen {
865c18ec02fSPetter Reinholdtsen snprintf(tmpdesc, SIZE_OF_DESC, "Bank %d", ((data2 & 0x0F)+1));
866c18ec02fSPetter Reinholdtsen strcat(desc, tmpdesc);
867c18ec02fSPetter Reinholdtsen }
868c18ec02fSPetter Reinholdtsen else
869c18ec02fSPetter Reinholdtsen {
870c18ec02fSPetter Reinholdtsen incr = (data2 & 0x0f) << 3;
871c18ec02fSPetter Reinholdtsen }
872c18ec02fSPetter Reinholdtsen }
873c18ec02fSPetter Reinholdtsen
874c18ec02fSPetter Reinholdtsen }
875c18ec02fSPetter Reinholdtsen /* Find the DIMM Number of the Memory which has Generated the Fault or Sel */
876c18ec02fSPetter Reinholdtsen if(data1 & OEM_CODE_IN_BYTE3 )
877c18ec02fSPetter Reinholdtsen {
878c18ec02fSPetter Reinholdtsen // Based on the IPMI Spec Need Identify the DIMM Details.
879c18ec02fSPetter Reinholdtsen // For the SPEC 1.5 Only the DIMM Number is Valid.
880c18ec02fSPetter Reinholdtsen if(0x51 == version)
881c18ec02fSPetter Reinholdtsen {
882c18ec02fSPetter Reinholdtsen snprintf(tmpdesc, SIZE_OF_DESC, "DIMM %c", ('A'+ data3));
883c18ec02fSPetter Reinholdtsen strcat(desc, tmpdesc);
884c18ec02fSPetter Reinholdtsen }
885c18ec02fSPetter Reinholdtsen /* For the SPEC 2.0 Decode the DIMM Number as it supports more.*/
886c18ec02fSPetter Reinholdtsen else if( ((data2 >> 4) > 0x07) && (0x0F != (data2 >> 4) ))
887c18ec02fSPetter Reinholdtsen {
888c18ec02fSPetter Reinholdtsen strcpy(dimmStr, " DIMM");
889c18ec02fSPetter Reinholdtsen str = desc+strlen(desc);
890c18ec02fSPetter Reinholdtsen dimmsPerNode = 4;
891c18ec02fSPetter Reinholdtsen if(0x09 == (data2 >> 4)) dimmsPerNode = 6;
892c18ec02fSPetter Reinholdtsen else if(0x0A == (data2 >> 4)) dimmsPerNode = 8;
893c18ec02fSPetter Reinholdtsen else if(0x0B == (data2 >> 4)) dimmsPerNode = 9;
894c18ec02fSPetter Reinholdtsen else if(0x0C == (data2 >> 4)) dimmsPerNode = 12;
895c18ec02fSPetter Reinholdtsen else if(0x0D == (data2 >> 4)) dimmsPerNode = 24;
896c18ec02fSPetter Reinholdtsen else if(0x0E == (data2 >> 4)) dimmsPerNode = 3;
897c18ec02fSPetter Reinholdtsen count = 0;
898c18ec02fSPetter Reinholdtsen for (i = 0; i < 8; i++)
899c18ec02fSPetter Reinholdtsen {
900c18ec02fSPetter Reinholdtsen if (BIT(i) & data3)
901c18ec02fSPetter Reinholdtsen {
902c18ec02fSPetter Reinholdtsen if(count)
903c18ec02fSPetter Reinholdtsen {
904c18ec02fSPetter Reinholdtsen strcat(str,",");
905c18ec02fSPetter Reinholdtsen count = 0x00;
906c18ec02fSPetter Reinholdtsen }
907c18ec02fSPetter Reinholdtsen node = (incr + i)/dimmsPerNode;
908c18ec02fSPetter Reinholdtsen dimmNum = ((incr + i)%dimmsPerNode)+1;
909c18ec02fSPetter Reinholdtsen dimmStr[5] = node + 'A';
910c18ec02fSPetter Reinholdtsen sprintf(tmpdesc,"%d",dimmNum);
911c18ec02fSPetter Reinholdtsen for(j = 0; j < strlen(tmpdesc);j++)
912c18ec02fSPetter Reinholdtsen dimmStr[6+j] = tmpdesc[j];
913c18ec02fSPetter Reinholdtsen dimmStr[6+j] = '\0';
914c18ec02fSPetter Reinholdtsen strcat(str,dimmStr); // final DIMM Details.
915c18ec02fSPetter Reinholdtsen count++;
916c18ec02fSPetter Reinholdtsen }
917c18ec02fSPetter Reinholdtsen }
918c18ec02fSPetter Reinholdtsen }
919c18ec02fSPetter Reinholdtsen else
920c18ec02fSPetter Reinholdtsen {
921c18ec02fSPetter Reinholdtsen strcpy(dimmStr, " DIMM");
922c18ec02fSPetter Reinholdtsen str = desc+strlen(desc);
923c18ec02fSPetter Reinholdtsen count = 0;
924c18ec02fSPetter Reinholdtsen for (i = 0; i < 8; i++)
925c18ec02fSPetter Reinholdtsen {
926c18ec02fSPetter Reinholdtsen if (BIT(i) & data3)
927c18ec02fSPetter Reinholdtsen {
928c18ec02fSPetter Reinholdtsen // check if more than one DIMM, if so add a comma to the string.
929c18ec02fSPetter Reinholdtsen sprintf(tmpdesc,"%d",(i + incr + 1));
930c18ec02fSPetter Reinholdtsen if(count)
931c18ec02fSPetter Reinholdtsen {
932c18ec02fSPetter Reinholdtsen strcat(str,",");
933c18ec02fSPetter Reinholdtsen count = 0x00;
934c18ec02fSPetter Reinholdtsen }
935c18ec02fSPetter Reinholdtsen for(j = 0; j < strlen(tmpdesc);j++)
936c18ec02fSPetter Reinholdtsen dimmStr[5+j] = tmpdesc[j];
937c18ec02fSPetter Reinholdtsen dimmStr[5+j] = '\0';
938c18ec02fSPetter Reinholdtsen strcat(str, dimmStr);
939c18ec02fSPetter Reinholdtsen count++;
940c18ec02fSPetter Reinholdtsen }
941c18ec02fSPetter Reinholdtsen }
942c18ec02fSPetter Reinholdtsen }
943c18ec02fSPetter Reinholdtsen }
944c18ec02fSPetter Reinholdtsen break;
945c18ec02fSPetter Reinholdtsen /* Sensor In system charectorization Error Decoding.
946c18ec02fSPetter Reinholdtsen Sensor type 0x20*/
947c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_TXT_CMD_ERROR:
948c18ec02fSPetter Reinholdtsen if((0x00 == (data1 & MASK_LOWER_NIBBLE))&&((data1 & OEM_CODE_IN_BYTE2) && (data1 & OEM_CODE_IN_BYTE3)))
949c18ec02fSPetter Reinholdtsen {
950c18ec02fSPetter Reinholdtsen switch(data3)
951c18ec02fSPetter Reinholdtsen {
952c18ec02fSPetter Reinholdtsen case 0x01:
953c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"BIOS TXT Error");
954c18ec02fSPetter Reinholdtsen break;
955c18ec02fSPetter Reinholdtsen case 0x02:
956c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"Processor/FIT TXT");
957c18ec02fSPetter Reinholdtsen break;
958c18ec02fSPetter Reinholdtsen case 0x03:
959c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"BIOS ACM TXT Error");
960c18ec02fSPetter Reinholdtsen break;
961c18ec02fSPetter Reinholdtsen case 0x04:
962c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"SINIT ACM TXT Error");
963c18ec02fSPetter Reinholdtsen break;
964c18ec02fSPetter Reinholdtsen case 0xff:
965c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"Unrecognized TT Error12");
966c18ec02fSPetter Reinholdtsen break;
967c18ec02fSPetter Reinholdtsen default:
968c18ec02fSPetter Reinholdtsen break;
969c18ec02fSPetter Reinholdtsen }
970c18ec02fSPetter Reinholdtsen }
971c18ec02fSPetter Reinholdtsen break;
972c18ec02fSPetter Reinholdtsen /* OS Watch Dog Timer Sel Events */
973c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_WTDOG:
974c18ec02fSPetter Reinholdtsen
975c18ec02fSPetter Reinholdtsen if(SENSOR_TYPE_OEM_SEC_EVENT == data1)
976c18ec02fSPetter Reinholdtsen {
977c18ec02fSPetter Reinholdtsen if(0x04 == data2)
978c18ec02fSPetter Reinholdtsen {
979c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC,"Hard Reset|Interrupt type None,SMS/OS Timer used at expiration");
980c18ec02fSPetter Reinholdtsen }
981c18ec02fSPetter Reinholdtsen }
982c18ec02fSPetter Reinholdtsen
983c18ec02fSPetter Reinholdtsen break;
984c18ec02fSPetter Reinholdtsen /* This Event is for BMC to Othe Hardware or CPU . */
985c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_VER_CHANGE:
986c18ec02fSPetter Reinholdtsen if((0x02 == (data1 & MASK_LOWER_NIBBLE))&&((data1 & OEM_CODE_IN_BYTE2) && (data1 & OEM_CODE_IN_BYTE3)))
987c18ec02fSPetter Reinholdtsen {
988c18ec02fSPetter Reinholdtsen if(0x02 == data2)
989c18ec02fSPetter Reinholdtsen {
990c18ec02fSPetter Reinholdtsen if(0x00 == data3)
991c18ec02fSPetter Reinholdtsen {
992c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "between BMC/iDRAC Firmware and other hardware");
993c18ec02fSPetter Reinholdtsen }
994c18ec02fSPetter Reinholdtsen else if(0x01 == data3)
995c18ec02fSPetter Reinholdtsen {
996c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "between BMC/iDRAC Firmware and CPU");
997c18ec02fSPetter Reinholdtsen }
998c18ec02fSPetter Reinholdtsen }
999c18ec02fSPetter Reinholdtsen }
1000c18ec02fSPetter Reinholdtsen break;
1001c18ec02fSPetter Reinholdtsen /* Flex or Mac tuning OEM Decoding for the DELL. */
1002c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_OEM_SEC_EVENT:
1003c18ec02fSPetter Reinholdtsen /* 0x25 - Virtual MAC sensory number - Dell OEM */
1004c18ec02fSPetter Reinholdtsen if(0x25 == rec->sel_type.standard_type.sensor_num)
1005c18ec02fSPetter Reinholdtsen {
1006c18ec02fSPetter Reinholdtsen if(0x01 == (data1 & MASK_LOWER_NIBBLE))
1007c18ec02fSPetter Reinholdtsen {
1008c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Failed to program Virtual Mac Address");
1009c18ec02fSPetter Reinholdtsen if((data1 & OEM_CODE_IN_BYTE2)&&(data1 & OEM_CODE_IN_BYTE3))
1010c18ec02fSPetter Reinholdtsen {
1011c18ec02fSPetter Reinholdtsen snprintf(tmpdesc, SIZE_OF_DESC, " at bus:%.2x device:%.2x function:%x",
1012c18ec02fSPetter Reinholdtsen data3 &0x7F, (data2 >> 3) & 0x1F,
1013c18ec02fSPetter Reinholdtsen data2 & 0x07);
1014c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
1015c18ec02fSPetter Reinholdtsen }
1016c18ec02fSPetter Reinholdtsen }
1017c18ec02fSPetter Reinholdtsen else if(0x02 == (data1 & MASK_LOWER_NIBBLE))
1018c18ec02fSPetter Reinholdtsen {
1019c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Device option ROM failed to support link tuning or flex address");
1020c18ec02fSPetter Reinholdtsen }
1021c18ec02fSPetter Reinholdtsen else if(0x03 == (data1 & MASK_LOWER_NIBBLE))
1022c18ec02fSPetter Reinholdtsen {
1023c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Failed to get link tuning or flex address data from BMC/iDRAC");
1024c18ec02fSPetter Reinholdtsen }
1025c18ec02fSPetter Reinholdtsen }
1026c18ec02fSPetter Reinholdtsen break;
1027c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_CRIT_INTR:
1028c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_OEM_NFATAL_ERROR: /* Non - Fatal PCIe Express Error Decoding */
1029c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_OEM_FATAL_ERROR: /* Fatal IO Error Decoding */
1030c18ec02fSPetter Reinholdtsen /* 0x29 - QPI Linx Error Sensor Dell OEM */
1031c18ec02fSPetter Reinholdtsen if(0x29 == rec->sel_type.standard_type.sensor_num)
1032c18ec02fSPetter Reinholdtsen {
1033c18ec02fSPetter Reinholdtsen if((0x02 == (data1 & MASK_LOWER_NIBBLE))&&((data1 & OEM_CODE_IN_BYTE2) && (data1 & OEM_CODE_IN_BYTE3)))
1034c18ec02fSPetter Reinholdtsen {
1035c18ec02fSPetter Reinholdtsen snprintf(tmpdesc, SIZE_OF_DESC, "Partner-(LinkId:%d,AgentId:%d)|",(data2 & 0xC0),(data2 & 0x30));
1036c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
1037c18ec02fSPetter Reinholdtsen snprintf(tmpdesc, SIZE_OF_DESC, "ReportingAgent(LinkId:%d,AgentId:%d)|",(data2 & 0x0C),(data2 & 0x03));
1038c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
1039c18ec02fSPetter Reinholdtsen if(0x00 == (data3 & 0xFC))
1040c18ec02fSPetter Reinholdtsen {
1041c18ec02fSPetter Reinholdtsen snprintf(tmpdesc, SIZE_OF_DESC, "LinkWidthDegraded|");
1042c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
1043c18ec02fSPetter Reinholdtsen }
1044c18ec02fSPetter Reinholdtsen if(BIT(1)& data3)
1045c18ec02fSPetter Reinholdtsen {
1046c18ec02fSPetter Reinholdtsen snprintf(tmpdesc,SIZE_OF_DESC,"PA_Type:IOH|");
1047c18ec02fSPetter Reinholdtsen }
1048c18ec02fSPetter Reinholdtsen else
1049c18ec02fSPetter Reinholdtsen {
1050c18ec02fSPetter Reinholdtsen snprintf(tmpdesc,SIZE_OF_DESC,"PA-Type:CPU|");
1051c18ec02fSPetter Reinholdtsen }
1052c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
1053c18ec02fSPetter Reinholdtsen if(BIT(0)& data3)
1054c18ec02fSPetter Reinholdtsen {
1055c18ec02fSPetter Reinholdtsen snprintf(tmpdesc,SIZE_OF_DESC,"RA-Type:IOH");
1056c18ec02fSPetter Reinholdtsen }
1057c18ec02fSPetter Reinholdtsen else
1058c18ec02fSPetter Reinholdtsen {
1059c18ec02fSPetter Reinholdtsen snprintf(tmpdesc,SIZE_OF_DESC,"RA-Type:CPU");
1060c18ec02fSPetter Reinholdtsen }
1061c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
1062c18ec02fSPetter Reinholdtsen }
1063c18ec02fSPetter Reinholdtsen }
1064c18ec02fSPetter Reinholdtsen else
1065c18ec02fSPetter Reinholdtsen {
1066c18ec02fSPetter Reinholdtsen
1067c18ec02fSPetter Reinholdtsen if(0x02 == (data1 & MASK_LOWER_NIBBLE))
1068c18ec02fSPetter Reinholdtsen {
1069c18ec02fSPetter Reinholdtsen sprintf(desc,"%s","IO channel Check NMI");
1070c18ec02fSPetter Reinholdtsen }
1071c18ec02fSPetter Reinholdtsen else
1072c18ec02fSPetter Reinholdtsen {
1073c18ec02fSPetter Reinholdtsen if(0x00 == (data1 & MASK_LOWER_NIBBLE))
1074c18ec02fSPetter Reinholdtsen {
1075c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "%s","PCIe Error |");
1076c18ec02fSPetter Reinholdtsen }
1077c18ec02fSPetter Reinholdtsen else if(0x01 == (data1 & MASK_LOWER_NIBBLE))
1078c18ec02fSPetter Reinholdtsen {
1079c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "%s","I/O Error |");
1080c18ec02fSPetter Reinholdtsen }
1081c18ec02fSPetter Reinholdtsen else if(0x04 == (data1 & MASK_LOWER_NIBBLE))
1082c18ec02fSPetter Reinholdtsen {
1083c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "%s","PCI PERR |");
1084c18ec02fSPetter Reinholdtsen }
1085c18ec02fSPetter Reinholdtsen else if(0x05 == (data1 & MASK_LOWER_NIBBLE))
1086c18ec02fSPetter Reinholdtsen {
1087c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "%s","PCI SERR |");
1088c18ec02fSPetter Reinholdtsen }
1089c18ec02fSPetter Reinholdtsen else
1090c18ec02fSPetter Reinholdtsen {
1091c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "%s"," ");
1092c18ec02fSPetter Reinholdtsen }
1093c18ec02fSPetter Reinholdtsen if (data3 & 0x80)
1094c18ec02fSPetter Reinholdtsen snprintf(tmpdesc, SIZE_OF_DESC, "Slot %d", data3 & 0x7F);
1095c18ec02fSPetter Reinholdtsen else
1096c18ec02fSPetter Reinholdtsen snprintf(tmpdesc, SIZE_OF_DESC, "PCI bus:%.2x device:%.2x function:%x",
1097c18ec02fSPetter Reinholdtsen data3 &0x7F, (data2 >> 3) & 0x1F,
1098c18ec02fSPetter Reinholdtsen data2 & 0x07);
1099c18ec02fSPetter Reinholdtsen
1100c18ec02fSPetter Reinholdtsen strcat(desc,tmpdesc);
1101c18ec02fSPetter Reinholdtsen }
1102c18ec02fSPetter Reinholdtsen }
1103c18ec02fSPetter Reinholdtsen break;
1104c18ec02fSPetter Reinholdtsen /* POST Fatal Errors generated from the Server with much more info*/
1105c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_FRM_PROG:
1106c18ec02fSPetter Reinholdtsen if((0x0F == (data1 & MASK_LOWER_NIBBLE))&&(data1 & OEM_CODE_IN_BYTE2))
1107c18ec02fSPetter Reinholdtsen {
1108c18ec02fSPetter Reinholdtsen switch(data2)
1109c18ec02fSPetter Reinholdtsen {
1110c18ec02fSPetter Reinholdtsen case 0x80:
1111c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "No memory is detected.");break;
1112c18ec02fSPetter Reinholdtsen case 0x81:
1113c18ec02fSPetter Reinholdtsen snprintf(desc,SIZE_OF_DESC, "Memory is detected but is not configurable.");break;
1114c18ec02fSPetter Reinholdtsen case 0x82:
1115c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Memory is configured but not usable.");break;
1116c18ec02fSPetter Reinholdtsen case 0x83:
1117c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "System BIOS shadow failed.");break;
1118c18ec02fSPetter Reinholdtsen case 0x84:
1119c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "CMOS failed.");break;
1120c18ec02fSPetter Reinholdtsen case 0x85:
1121c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "DMA controller failed.");break;
1122c18ec02fSPetter Reinholdtsen case 0x86:
1123c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Interrupt controller failed.");break;
1124c18ec02fSPetter Reinholdtsen case 0x87:
1125c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Timer refresh failed.");break;
1126c18ec02fSPetter Reinholdtsen case 0x88:
1127c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Programmable interval timer error.");break;
1128c18ec02fSPetter Reinholdtsen case 0x89:
1129c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Parity error.");break;
1130c18ec02fSPetter Reinholdtsen case 0x8A:
1131c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "SIO failed.");break;
1132c18ec02fSPetter Reinholdtsen case 0x8B:
1133c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Keyboard controller failed.");break;
1134c18ec02fSPetter Reinholdtsen case 0x8C:
1135c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "System management interrupt initialization failed.");break;
1136c18ec02fSPetter Reinholdtsen case 0x8D:
1137c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "TXT-SX Error.");break;
1138c18ec02fSPetter Reinholdtsen case 0xC0:
1139c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Shutdown test failed.");break;
1140c18ec02fSPetter Reinholdtsen case 0xC1:
1141c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "BIOS POST memory test failed.");break;
1142c18ec02fSPetter Reinholdtsen case 0xC2:
1143c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "RAC configuration failed.");break;
1144c18ec02fSPetter Reinholdtsen case 0xC3:
1145c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "CPU configuration failed.");break;
1146c18ec02fSPetter Reinholdtsen case 0xC4:
1147c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "Incorrect memory configuration.");break;
1148c18ec02fSPetter Reinholdtsen case 0xFE:
1149c18ec02fSPetter Reinholdtsen snprintf(desc, SIZE_OF_DESC, "General failure after video.");
1150c18ec02fSPetter Reinholdtsen break;
1151c18ec02fSPetter Reinholdtsen }
1152c18ec02fSPetter Reinholdtsen }
1153c18ec02fSPetter Reinholdtsen break;
1154c18ec02fSPetter Reinholdtsen
1155c18ec02fSPetter Reinholdtsen default:
1156c18ec02fSPetter Reinholdtsen break;
1157c18ec02fSPetter Reinholdtsen }
1158c18ec02fSPetter Reinholdtsen }
1159c18ec02fSPetter Reinholdtsen else
1160c18ec02fSPetter Reinholdtsen {
1161c18ec02fSPetter Reinholdtsen sensor_type = rec->sel_type.standard_type.event_type;
1162c18ec02fSPetter Reinholdtsen }
1163c18ec02fSPetter Reinholdtsen return desc;
1164c18ec02fSPetter Reinholdtsen }
1165c18ec02fSPetter Reinholdtsen
1166c18ec02fSPetter Reinholdtsen char *
ipmi_get_oem_desc(struct ipmi_intf * intf,struct sel_event_record * rec)1167c18ec02fSPetter Reinholdtsen ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
1168c18ec02fSPetter Reinholdtsen {
1169c18ec02fSPetter Reinholdtsen char * desc = NULL;
1170c18ec02fSPetter Reinholdtsen
1171c18ec02fSPetter Reinholdtsen switch (ipmi_get_oem(intf))
1172c18ec02fSPetter Reinholdtsen {
1173c18ec02fSPetter Reinholdtsen case IPMI_OEM_NEWISYS:
1174c18ec02fSPetter Reinholdtsen desc = get_newisys_evt_desc(intf, rec);
1175c18ec02fSPetter Reinholdtsen break;
1176c18ec02fSPetter Reinholdtsen case IPMI_OEM_KONTRON:
1177c18ec02fSPetter Reinholdtsen desc = get_kontron_evt_desc(intf, rec);
1178c18ec02fSPetter Reinholdtsen break;
1179c18ec02fSPetter Reinholdtsen case IPMI_OEM_DELL: // Dell Decoding of the OEM Bytes from SEL Record.
1180c18ec02fSPetter Reinholdtsen desc = get_dell_evt_desc(intf, rec);
1181c18ec02fSPetter Reinholdtsen break;
1182c18ec02fSPetter Reinholdtsen case IPMI_OEM_SUPERMICRO:
1183c18ec02fSPetter Reinholdtsen case IPMI_OEM_SUPERMICRO_47488:
1184c18ec02fSPetter Reinholdtsen desc = get_supermicro_evt_desc(intf, rec);
1185c18ec02fSPetter Reinholdtsen break;
1186c18ec02fSPetter Reinholdtsen case IPMI_OEM_UNKNOWN:
1187c18ec02fSPetter Reinholdtsen default:
1188c18ec02fSPetter Reinholdtsen break;
1189c18ec02fSPetter Reinholdtsen }
1190c18ec02fSPetter Reinholdtsen
1191c18ec02fSPetter Reinholdtsen return desc;
1192c18ec02fSPetter Reinholdtsen }
1193c18ec02fSPetter Reinholdtsen
1194c18ec02fSPetter Reinholdtsen
1195c18ec02fSPetter Reinholdtsen void
ipmi_get_event_desc(struct ipmi_intf * intf,struct sel_event_record * rec,char ** desc)1196c18ec02fSPetter Reinholdtsen ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char ** desc)
1197c18ec02fSPetter Reinholdtsen {
1198c18ec02fSPetter Reinholdtsen uint8_t code, offset;
1199c18ec02fSPetter Reinholdtsen struct ipmi_event_sensor_types *evt = NULL;
1200c18ec02fSPetter Reinholdtsen char *sfx = NULL; /* This will be assigned if the Platform is DELL,
1201c18ec02fSPetter Reinholdtsen additional info is appended to the current Description */
1202c18ec02fSPetter Reinholdtsen
1203c18ec02fSPetter Reinholdtsen if (desc == NULL)
1204c18ec02fSPetter Reinholdtsen return;
1205c18ec02fSPetter Reinholdtsen *desc = NULL;
1206c18ec02fSPetter Reinholdtsen
1207c18ec02fSPetter Reinholdtsen if ((rec->sel_type.standard_type.event_type >= 0x70) && (rec->sel_type.standard_type.event_type < 0x7F)) {
1208c18ec02fSPetter Reinholdtsen *desc = ipmi_get_oem_desc(intf, rec);
1209c18ec02fSPetter Reinholdtsen return;
1210c18ec02fSPetter Reinholdtsen } else if (rec->sel_type.standard_type.event_type == 0x6f) {
1211c18ec02fSPetter Reinholdtsen if( rec->sel_type.standard_type.sensor_type >= 0xC0 && rec->sel_type.standard_type.sensor_type < 0xF0) {
1212c18ec02fSPetter Reinholdtsen IPMI_OEM iana = ipmi_get_oem(intf);
1213c18ec02fSPetter Reinholdtsen
1214c18ec02fSPetter Reinholdtsen switch(iana){
1215c18ec02fSPetter Reinholdtsen case IPMI_OEM_KONTRON:
1216c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "oem sensor type %x %d using oem type supplied description",
1217c18ec02fSPetter Reinholdtsen rec->sel_type.standard_type.sensor_type , iana);
1218c18ec02fSPetter Reinholdtsen
1219c18ec02fSPetter Reinholdtsen evt = oem_kontron_event_types;
1220c18ec02fSPetter Reinholdtsen code = rec->sel_type.standard_type.sensor_type;
1221c18ec02fSPetter Reinholdtsen break;
1222c18ec02fSPetter Reinholdtsen case IPMI_OEM_DELL: /* OEM Bytes Decoding for DELLi */
1223c18ec02fSPetter Reinholdtsen evt = sensor_specific_types;
1224c18ec02fSPetter Reinholdtsen code = rec->sel_type.standard_type.sensor_type;
1225c18ec02fSPetter Reinholdtsen if ( (OEM_CODE_IN_BYTE2 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)) ||
1226c18ec02fSPetter Reinholdtsen (OEM_CODE_IN_BYTE3 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE3_SPECIFIED_MASK)) )
1227c18ec02fSPetter Reinholdtsen {
1228c18ec02fSPetter Reinholdtsen if(rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)
1229c18ec02fSPetter Reinholdtsen evt->data = rec->sel_type.standard_type.event_data[1];
1230c18ec02fSPetter Reinholdtsen
1231c18ec02fSPetter Reinholdtsen sfx = ipmi_get_oem_desc(intf, rec);
1232c18ec02fSPetter Reinholdtsen }
1233c18ec02fSPetter Reinholdtsen break;
1234c18ec02fSPetter Reinholdtsen case IPMI_OEM_SUPERMICRO:
1235c18ec02fSPetter Reinholdtsen case IPMI_OEM_SUPERMICRO_47488:
1236c18ec02fSPetter Reinholdtsen evt = sensor_specific_types;
1237c18ec02fSPetter Reinholdtsen code = rec->sel_type.standard_type.sensor_type;
1238c18ec02fSPetter Reinholdtsen sfx = ipmi_get_oem_desc(intf, rec);
1239c18ec02fSPetter Reinholdtsen break;
1240c18ec02fSPetter Reinholdtsen /* add your oem sensor assignation here */
124139fb1af2SZdenek Styblik default:
124239fb1af2SZdenek Styblik break;
1243c18ec02fSPetter Reinholdtsen }
1244c18ec02fSPetter Reinholdtsen if( evt == NULL ){
1245c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description",
1246c18ec02fSPetter Reinholdtsen rec->sel_type.standard_type.sensor_type );
1247c18ec02fSPetter Reinholdtsen }
1248c18ec02fSPetter Reinholdtsen } else {
1249c18ec02fSPetter Reinholdtsen switch (ipmi_get_oem(intf)) {
1250c18ec02fSPetter Reinholdtsen case IPMI_OEM_SUPERMICRO:
1251c18ec02fSPetter Reinholdtsen case IPMI_OEM_SUPERMICRO_47488:
1252c18ec02fSPetter Reinholdtsen evt = sensor_specific_types;
1253c18ec02fSPetter Reinholdtsen code = rec->sel_type.standard_type.sensor_type;
1254c18ec02fSPetter Reinholdtsen sfx = ipmi_get_oem_desc(intf, rec);
1255c18ec02fSPetter Reinholdtsen break;
125639fb1af2SZdenek Styblik default:
125739fb1af2SZdenek Styblik break;
1258c18ec02fSPetter Reinholdtsen }
1259c18ec02fSPetter Reinholdtsen }
1260c18ec02fSPetter Reinholdtsen if( evt == NULL ){
1261c18ec02fSPetter Reinholdtsen evt = sensor_specific_types;
1262c18ec02fSPetter Reinholdtsen code = rec->sel_type.standard_type.sensor_type;
1263c18ec02fSPetter Reinholdtsen }
1264c18ec02fSPetter Reinholdtsen /*
1265c18ec02fSPetter Reinholdtsen * Check for the OEM DELL Interface based on the Dell Specific Vendor Code.
1266c18ec02fSPetter Reinholdtsen * If its Dell Platform, do the OEM Byte decode from the SEL Records.
1267c18ec02fSPetter Reinholdtsen * Additional information should be written by the ipmi_get_oem_desc()
1268c18ec02fSPetter Reinholdtsen */
1269c18ec02fSPetter Reinholdtsen if(ipmi_get_oem(intf) == IPMI_OEM_DELL) {
1270c18ec02fSPetter Reinholdtsen code = rec->sel_type.standard_type.sensor_type;
1271c18ec02fSPetter Reinholdtsen if ( (OEM_CODE_IN_BYTE2 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)) ||
1272c18ec02fSPetter Reinholdtsen (OEM_CODE_IN_BYTE3 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE3_SPECIFIED_MASK)) )
1273c18ec02fSPetter Reinholdtsen {
1274c18ec02fSPetter Reinholdtsen if(rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)
1275c18ec02fSPetter Reinholdtsen evt->data = rec->sel_type.standard_type.event_data[1];
1276c18ec02fSPetter Reinholdtsen sfx = ipmi_get_oem_desc(intf, rec);
1277c18ec02fSPetter Reinholdtsen
1278c18ec02fSPetter Reinholdtsen }
1279c18ec02fSPetter Reinholdtsen else if(SENSOR_TYPE_OEM_SEC_EVENT == rec->sel_type.standard_type.event_data[0])
1280c18ec02fSPetter Reinholdtsen {
1281c18ec02fSPetter Reinholdtsen /* 0x23 : Sensor Number.*/
1282c18ec02fSPetter Reinholdtsen if(0x23 == rec->sel_type.standard_type.sensor_num)
1283c18ec02fSPetter Reinholdtsen {
1284c18ec02fSPetter Reinholdtsen evt->data = rec->sel_type.standard_type.event_data[1];
1285c18ec02fSPetter Reinholdtsen sfx = ipmi_get_oem_desc(intf, rec);
1286c18ec02fSPetter Reinholdtsen }
1287c18ec02fSPetter Reinholdtsen }
1288c18ec02fSPetter Reinholdtsen }
1289c18ec02fSPetter Reinholdtsen } else {
1290c18ec02fSPetter Reinholdtsen evt = generic_event_types;
1291c18ec02fSPetter Reinholdtsen code = rec->sel_type.standard_type.event_type;
1292c18ec02fSPetter Reinholdtsen }
1293c18ec02fSPetter Reinholdtsen
1294c18ec02fSPetter Reinholdtsen offset = rec->sel_type.standard_type.event_data[0] & 0xf;
1295c18ec02fSPetter Reinholdtsen
1296c18ec02fSPetter Reinholdtsen while (evt->type) {
1297c18ec02fSPetter Reinholdtsen if ((evt->code == code && evt->offset == offset && evt->desc != NULL) &&
1298c18ec02fSPetter Reinholdtsen ((evt->data == ALL_OFFSETS_SPECIFIED) ||
1299c18ec02fSPetter Reinholdtsen ((rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK) &&
1300c18ec02fSPetter Reinholdtsen (evt->data == rec->sel_type.standard_type.event_data[1]))))
1301c18ec02fSPetter Reinholdtsen {
1302c18ec02fSPetter Reinholdtsen /* Increase the Malloc size to current_size + Dellspecific description size */
1303c18ec02fSPetter Reinholdtsen *desc = (char *)malloc(strlen(evt->desc) + 48 + SIZE_OF_DESC);
1304c18ec02fSPetter Reinholdtsen if (NULL == *desc) {
1305c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: malloc failure");
1306c18ec02fSPetter Reinholdtsen return;
1307c18ec02fSPetter Reinholdtsen }
1308c18ec02fSPetter Reinholdtsen memset(*desc, 0, strlen(evt->desc)+ 48 + SIZE_OF_DESC);
1309c18ec02fSPetter Reinholdtsen /*
1310c18ec02fSPetter Reinholdtsen * Additional info is present for the DELL Platforms.
1311c18ec02fSPetter Reinholdtsen * Append the same to the evt->desc string.
1312c18ec02fSPetter Reinholdtsen */
1313c18ec02fSPetter Reinholdtsen if (sfx) {
1314c18ec02fSPetter Reinholdtsen sprintf(*desc, "%s (%s)", evt->desc, sfx);
1315c18ec02fSPetter Reinholdtsen free(sfx);
1316c18ec02fSPetter Reinholdtsen sfx = NULL;
1317c18ec02fSPetter Reinholdtsen } else {
1318c18ec02fSPetter Reinholdtsen sprintf(*desc, "%s", evt->desc);
1319c18ec02fSPetter Reinholdtsen }
1320c18ec02fSPetter Reinholdtsen return;
1321c18ec02fSPetter Reinholdtsen }
1322c18ec02fSPetter Reinholdtsen evt++;
1323c18ec02fSPetter Reinholdtsen }
1324c18ec02fSPetter Reinholdtsen /* The Above while Condition was not met beacouse the below sensor type were Newly defined OEM
1325c18ec02fSPetter Reinholdtsen Secondary Events. 0xC1, 0xC2, 0xC3. */
1326c18ec02fSPetter Reinholdtsen if((sfx) && (0x6F == rec->sel_type.standard_type.event_type))
1327c18ec02fSPetter Reinholdtsen {
1328c18ec02fSPetter Reinholdtsen uint8_t flag = 0x00;
1329c18ec02fSPetter Reinholdtsen switch(code)
1330c18ec02fSPetter Reinholdtsen {
1331c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_FRM_PROG:
1332c18ec02fSPetter Reinholdtsen if(0x0F == offset)
1333c18ec02fSPetter Reinholdtsen flag = 0x01;
1334c18ec02fSPetter Reinholdtsen break;
1335c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_OEM_SEC_EVENT:
1336c18ec02fSPetter Reinholdtsen if((0x01 == offset) || (0x02 == offset) || (0x03 == offset))
1337c18ec02fSPetter Reinholdtsen flag = 0x01;
1338c18ec02fSPetter Reinholdtsen break;
1339c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_OEM_NFATAL_ERROR:
1340c18ec02fSPetter Reinholdtsen if((0x00 == offset) || (0x02 == offset))
1341c18ec02fSPetter Reinholdtsen flag = 0x01;
1342c18ec02fSPetter Reinholdtsen break;
1343c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_OEM_FATAL_ERROR:
1344c18ec02fSPetter Reinholdtsen if(0x01 == offset)
1345c18ec02fSPetter Reinholdtsen flag = 0x01;
1346c18ec02fSPetter Reinholdtsen break;
1347c18ec02fSPetter Reinholdtsen case SENSOR_TYPE_SUPERMICRO_OEM:
1348c18ec02fSPetter Reinholdtsen flag = 0x02;
1349c18ec02fSPetter Reinholdtsen break;
1350c18ec02fSPetter Reinholdtsen default:
1351c18ec02fSPetter Reinholdtsen break;
1352c18ec02fSPetter Reinholdtsen }
1353c18ec02fSPetter Reinholdtsen if(flag)
1354c18ec02fSPetter Reinholdtsen {
1355c18ec02fSPetter Reinholdtsen *desc = (char *)malloc( 48 + SIZE_OF_DESC);
1356c18ec02fSPetter Reinholdtsen if (NULL == *desc)
1357c18ec02fSPetter Reinholdtsen {
1358c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: malloc failure");
1359c18ec02fSPetter Reinholdtsen return;
1360c18ec02fSPetter Reinholdtsen }
1361c18ec02fSPetter Reinholdtsen memset(*desc, 0, 48 + SIZE_OF_DESC);
1362c18ec02fSPetter Reinholdtsen if (flag == 0x02) {
1363c18ec02fSPetter Reinholdtsen sprintf(*desc, "%s", sfx);
1364c18ec02fSPetter Reinholdtsen return;
1365c18ec02fSPetter Reinholdtsen }
1366c18ec02fSPetter Reinholdtsen sprintf(*desc, "(%s)",sfx);
1367c18ec02fSPetter Reinholdtsen }
1368c18ec02fSPetter Reinholdtsen free(sfx);
1369c18ec02fSPetter Reinholdtsen sfx = NULL;
1370c18ec02fSPetter Reinholdtsen }
1371c18ec02fSPetter Reinholdtsen }
1372c18ec02fSPetter Reinholdtsen
1373c18ec02fSPetter Reinholdtsen
1374c18ec02fSPetter Reinholdtsen const char *
ipmi_sel_get_oem_sensor_type(IPMI_OEM iana,uint8_t code)1375c18ec02fSPetter Reinholdtsen ipmi_sel_get_oem_sensor_type(IPMI_OEM iana, uint8_t code)
1376c18ec02fSPetter Reinholdtsen {
1377c18ec02fSPetter Reinholdtsen struct ipmi_event_sensor_types *st = NULL;
1378c18ec02fSPetter Reinholdtsen
1379c18ec02fSPetter Reinholdtsen switch(iana){
1380c18ec02fSPetter Reinholdtsen case IPMI_OEM_KONTRON:
1381c18ec02fSPetter Reinholdtsen st = oem_kontron_event_types;
1382c18ec02fSPetter Reinholdtsen break;
1383c18ec02fSPetter Reinholdtsen /* add you oem sensor type lookup assignement here */
1384c18ec02fSPetter Reinholdtsen default:
1385c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "ipmitool: missing OEM sensor type for %ul",iana);
1386c18ec02fSPetter Reinholdtsen break;
1387c18ec02fSPetter Reinholdtsen }
1388c18ec02fSPetter Reinholdtsen
1389c18ec02fSPetter Reinholdtsen if( st != NULL )
1390c18ec02fSPetter Reinholdtsen for (; st->type != NULL; st++)
1391c18ec02fSPetter Reinholdtsen if (st->code == code)
1392c18ec02fSPetter Reinholdtsen return st->type;
1393c18ec02fSPetter Reinholdtsen
1394c18ec02fSPetter Reinholdtsen return ipmi_sel_get_sensor_type(code);
1395c18ec02fSPetter Reinholdtsen }
1396c18ec02fSPetter Reinholdtsen
1397c18ec02fSPetter Reinholdtsen const char *
ipmi_sel_get_oem_sensor_type_offset(IPMI_OEM iana,uint8_t code,uint8_t offset)1398c18ec02fSPetter Reinholdtsen ipmi_sel_get_oem_sensor_type_offset(IPMI_OEM iana, uint8_t code, uint8_t offset)
1399c18ec02fSPetter Reinholdtsen {
1400c18ec02fSPetter Reinholdtsen struct ipmi_event_sensor_types *st = NULL;
1401c18ec02fSPetter Reinholdtsen
1402c18ec02fSPetter Reinholdtsen switch(iana){
1403c18ec02fSPetter Reinholdtsen case IPMI_OEM_KONTRON:
1404c18ec02fSPetter Reinholdtsen st = oem_kontron_event_types;
1405c18ec02fSPetter Reinholdtsen break;
1406c18ec02fSPetter Reinholdtsen /* add you oem sensor type lookup assignement here */
1407c18ec02fSPetter Reinholdtsen default:
1408c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG,
1409c18ec02fSPetter Reinholdtsen "ipmitool: missing OEM sensor type offset for %ul",iana);
1410c18ec02fSPetter Reinholdtsen break;
1411c18ec02fSPetter Reinholdtsen }
1412c18ec02fSPetter Reinholdtsen
1413c18ec02fSPetter Reinholdtsen if( st != NULL )
1414c18ec02fSPetter Reinholdtsen for (; st->type != NULL; st++)
1415c18ec02fSPetter Reinholdtsen {
1416c18ec02fSPetter Reinholdtsen if (st->code == code && st->offset == (offset&0xf))
1417c18ec02fSPetter Reinholdtsen return st->type;
1418c18ec02fSPetter Reinholdtsen }
1419c18ec02fSPetter Reinholdtsen
1420c18ec02fSPetter Reinholdtsen return ipmi_sel_get_oem_sensor_type(iana,code);
1421c18ec02fSPetter Reinholdtsen }
1422c18ec02fSPetter Reinholdtsen
1423c18ec02fSPetter Reinholdtsen const char *
ipmi_sel_get_sensor_type(uint8_t code)1424c18ec02fSPetter Reinholdtsen ipmi_sel_get_sensor_type(uint8_t code)
1425c18ec02fSPetter Reinholdtsen {
1426c18ec02fSPetter Reinholdtsen struct ipmi_event_sensor_types *st;
1427c18ec02fSPetter Reinholdtsen for (st = sensor_specific_types; st->type != NULL; st++)
1428c18ec02fSPetter Reinholdtsen if (st->code == code)
1429c18ec02fSPetter Reinholdtsen return st->type;
1430c18ec02fSPetter Reinholdtsen return "Unknown";
1431c18ec02fSPetter Reinholdtsen }
1432c18ec02fSPetter Reinholdtsen
1433c18ec02fSPetter Reinholdtsen const char *
ipmi_sel_get_sensor_type_offset(uint8_t code,uint8_t offset)1434c18ec02fSPetter Reinholdtsen ipmi_sel_get_sensor_type_offset(uint8_t code, uint8_t offset)
1435c18ec02fSPetter Reinholdtsen {
1436c18ec02fSPetter Reinholdtsen struct ipmi_event_sensor_types *st;
1437c18ec02fSPetter Reinholdtsen for (st = sensor_specific_types; st->type != NULL; st++)
1438c18ec02fSPetter Reinholdtsen if (st->code == code && st->offset == (offset&0xf))
1439c18ec02fSPetter Reinholdtsen return st->type;
1440c18ec02fSPetter Reinholdtsen
1441c18ec02fSPetter Reinholdtsen return ipmi_sel_get_sensor_type(code);
1442c18ec02fSPetter Reinholdtsen }
1443c18ec02fSPetter Reinholdtsen
1444c18ec02fSPetter Reinholdtsen static int
ipmi_sel_get_info(struct ipmi_intf * intf)1445c18ec02fSPetter Reinholdtsen ipmi_sel_get_info(struct ipmi_intf * intf)
1446c18ec02fSPetter Reinholdtsen {
1447c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
1448c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
1449c18ec02fSPetter Reinholdtsen uint16_t e, version;
1450c18ec02fSPetter Reinholdtsen uint32_t f;
1451c18ec02fSPetter Reinholdtsen int pctfull = 0;
1452c18ec02fSPetter Reinholdtsen uint32_t fs = 0xffffffff;
1453c18ec02fSPetter Reinholdtsen uint32_t zeros = 0;
1454c18ec02fSPetter Reinholdtsen
1455c18ec02fSPetter Reinholdtsen
1456c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
1457c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
1458c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_CMD_GET_SEL_INFO;
1459c18ec02fSPetter Reinholdtsen
1460c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
1461c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
1462c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Info command failed");
1463c18ec02fSPetter Reinholdtsen return -1;
1464c18ec02fSPetter Reinholdtsen }
1465c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
1466c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Info command failed: %s",
1467c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
1468c18ec02fSPetter Reinholdtsen return -1;
1469c18ec02fSPetter Reinholdtsen }
1470c18ec02fSPetter Reinholdtsen if (verbose > 2)
1471c18ec02fSPetter Reinholdtsen printbuf(rsp->data, rsp->data_len, "sel_info");
1472c18ec02fSPetter Reinholdtsen
1473c18ec02fSPetter Reinholdtsen printf("SEL Information\n");
1474c18ec02fSPetter Reinholdtsen version = rsp->data[0];
1475c18ec02fSPetter Reinholdtsen printf("Version : %d.%d (%s)\n",
1476c18ec02fSPetter Reinholdtsen version & 0xf, (version>>4) & 0xf,
1477c18ec02fSPetter Reinholdtsen (version == 0x51 || version == 0x02) ? "v1.5, v2 compliant" : "Unknown");
1478c18ec02fSPetter Reinholdtsen
1479c18ec02fSPetter Reinholdtsen /* save the entry count and free space to determine percent full */
1480c18ec02fSPetter Reinholdtsen e = buf2short(rsp->data + 1);
1481c18ec02fSPetter Reinholdtsen f = buf2short(rsp->data + 3);
1482c18ec02fSPetter Reinholdtsen printf("Entries : %d\n", e);
1483c18ec02fSPetter Reinholdtsen printf("Free Space : %d bytes %s\n", f ,(f==65535 ? "or more" : "" ));
1484c18ec02fSPetter Reinholdtsen
1485c18ec02fSPetter Reinholdtsen if (e) {
1486c18ec02fSPetter Reinholdtsen e *= 16; /* each entry takes 16 bytes */
1487c18ec02fSPetter Reinholdtsen f += e; /* this is supposed to give the total size ... */
1488c18ec02fSPetter Reinholdtsen pctfull = (int)(100 * ( (double)e / (double)f ));
1489c18ec02fSPetter Reinholdtsen }
1490c18ec02fSPetter Reinholdtsen
1491c18ec02fSPetter Reinholdtsen if( f >= 65535 ) {
1492c18ec02fSPetter Reinholdtsen printf("Percent Used : %s\n", "unknown" );
1493c18ec02fSPetter Reinholdtsen }
1494c18ec02fSPetter Reinholdtsen else {
1495c18ec02fSPetter Reinholdtsen printf("Percent Used : %d%%\n", pctfull);
1496c18ec02fSPetter Reinholdtsen }
1497c18ec02fSPetter Reinholdtsen
1498c18ec02fSPetter Reinholdtsen
1499c18ec02fSPetter Reinholdtsen if ((!memcmp(rsp->data + 5, &fs, 4)) ||
1500c18ec02fSPetter Reinholdtsen (!memcmp(rsp->data + 5, &zeros, 4)))
1501c18ec02fSPetter Reinholdtsen printf("Last Add Time : Not Available\n");
1502c18ec02fSPetter Reinholdtsen else
1503c18ec02fSPetter Reinholdtsen printf("Last Add Time : %s\n",
1504c18ec02fSPetter Reinholdtsen ipmi_sel_timestamp(buf2long(rsp->data + 5)));
1505c18ec02fSPetter Reinholdtsen
1506c18ec02fSPetter Reinholdtsen if ((!memcmp(rsp->data + 9, &fs, 4)) ||
1507c18ec02fSPetter Reinholdtsen (!memcmp(rsp->data + 9, &zeros, 4)))
1508c18ec02fSPetter Reinholdtsen printf("Last Del Time : Not Available\n");
1509c18ec02fSPetter Reinholdtsen else
1510c18ec02fSPetter Reinholdtsen printf("Last Del Time : %s\n",
1511c18ec02fSPetter Reinholdtsen ipmi_sel_timestamp(buf2long(rsp->data + 9)));
1512c18ec02fSPetter Reinholdtsen
1513c18ec02fSPetter Reinholdtsen
1514c18ec02fSPetter Reinholdtsen printf("Overflow : %s\n",
1515c18ec02fSPetter Reinholdtsen rsp->data[13] & 0x80 ? "true" : "false");
1516c18ec02fSPetter Reinholdtsen printf("Supported Cmds : ");
1517c18ec02fSPetter Reinholdtsen if (rsp->data[13] & 0x0f)
1518c18ec02fSPetter Reinholdtsen {
1519c18ec02fSPetter Reinholdtsen if (rsp->data[13] & 0x08)
1520c18ec02fSPetter Reinholdtsen printf("'Delete' ");
1521c18ec02fSPetter Reinholdtsen if (rsp->data[13] & 0x04)
1522c18ec02fSPetter Reinholdtsen printf("'Partial Add' ");
1523c18ec02fSPetter Reinholdtsen if (rsp->data[13] & 0x02)
1524c18ec02fSPetter Reinholdtsen printf("'Reserve' ");
1525c18ec02fSPetter Reinholdtsen if (rsp->data[13] & 0x01)
1526c18ec02fSPetter Reinholdtsen printf("'Get Alloc Info' ");
1527c18ec02fSPetter Reinholdtsen }
1528c18ec02fSPetter Reinholdtsen else
1529c18ec02fSPetter Reinholdtsen printf("None");
1530c18ec02fSPetter Reinholdtsen printf("\n");
1531c18ec02fSPetter Reinholdtsen
1532c18ec02fSPetter Reinholdtsen /* get sel allocation info if supported */
1533c18ec02fSPetter Reinholdtsen if (rsp->data[13] & 1) {
1534c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
1535c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
1536c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_CMD_GET_SEL_ALLOC_INFO;
1537c18ec02fSPetter Reinholdtsen
1538c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
1539c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
1540c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR,
1541c18ec02fSPetter Reinholdtsen "Get SEL Allocation Info command failed");
1542c18ec02fSPetter Reinholdtsen return -1;
1543c18ec02fSPetter Reinholdtsen }
1544c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
1545c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR,
1546c18ec02fSPetter Reinholdtsen "Get SEL Allocation Info command failed: %s",
1547c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
1548c18ec02fSPetter Reinholdtsen return -1;
1549c18ec02fSPetter Reinholdtsen }
1550c18ec02fSPetter Reinholdtsen
1551c18ec02fSPetter Reinholdtsen printf("# of Alloc Units : %d\n", buf2short(rsp->data));
1552c18ec02fSPetter Reinholdtsen printf("Alloc Unit Size : %d\n", buf2short(rsp->data + 2));
1553c18ec02fSPetter Reinholdtsen printf("# Free Units : %d\n", buf2short(rsp->data + 4));
1554c18ec02fSPetter Reinholdtsen printf("Largest Free Blk : %d\n", buf2short(rsp->data + 6));
1555c18ec02fSPetter Reinholdtsen printf("Max Record Size : %d\n", rsp->data[8]);
1556c18ec02fSPetter Reinholdtsen }
1557c18ec02fSPetter Reinholdtsen return 0;
1558c18ec02fSPetter Reinholdtsen }
1559c18ec02fSPetter Reinholdtsen
1560c18ec02fSPetter Reinholdtsen uint16_t
ipmi_sel_get_std_entry(struct ipmi_intf * intf,uint16_t id,struct sel_event_record * evt)1561c18ec02fSPetter Reinholdtsen ipmi_sel_get_std_entry(struct ipmi_intf * intf, uint16_t id,
1562c18ec02fSPetter Reinholdtsen struct sel_event_record * evt)
1563c18ec02fSPetter Reinholdtsen {
1564c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
1565c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
1566c18ec02fSPetter Reinholdtsen uint8_t msg_data[6];
1567c18ec02fSPetter Reinholdtsen uint16_t next;
1568c18ec02fSPetter Reinholdtsen int data_count;
1569c18ec02fSPetter Reinholdtsen
1570c18ec02fSPetter Reinholdtsen memset(msg_data, 0, 6);
1571c18ec02fSPetter Reinholdtsen msg_data[0] = 0x00; /* no reserve id, not partial get */
1572c18ec02fSPetter Reinholdtsen msg_data[1] = 0x00;
1573c18ec02fSPetter Reinholdtsen msg_data[2] = id & 0xff;
1574c18ec02fSPetter Reinholdtsen msg_data[3] = (id >> 8) & 0xff;
1575c18ec02fSPetter Reinholdtsen msg_data[4] = 0x00; /* offset */
1576c18ec02fSPetter Reinholdtsen msg_data[5] = 0xff; /* length */
1577c18ec02fSPetter Reinholdtsen
1578c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
1579c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
1580c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_CMD_GET_SEL_ENTRY;
1581c18ec02fSPetter Reinholdtsen req.msg.data = msg_data;
1582c18ec02fSPetter Reinholdtsen req.msg.data_len = 6;
1583c18ec02fSPetter Reinholdtsen
1584c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
1585c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
1586c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Entry %x command failed", id);
1587c18ec02fSPetter Reinholdtsen return 0;
1588c18ec02fSPetter Reinholdtsen }
1589c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
1590c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Entry %x command failed: %s",
1591c18ec02fSPetter Reinholdtsen id, val2str(rsp->ccode, completion_code_vals));
1592c18ec02fSPetter Reinholdtsen return 0;
1593c18ec02fSPetter Reinholdtsen }
1594c18ec02fSPetter Reinholdtsen
1595c18ec02fSPetter Reinholdtsen /* save next entry id */
1596c18ec02fSPetter Reinholdtsen next = (rsp->data[1] << 8) | rsp->data[0];
1597c18ec02fSPetter Reinholdtsen
1598c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "SEL Entry: %s", buf2str(rsp->data+2, rsp->data_len-2));
1599c18ec02fSPetter Reinholdtsen memset(evt, 0, sizeof(*evt));
1600c18ec02fSPetter Reinholdtsen
1601c18ec02fSPetter Reinholdtsen /*Clear SEL Structure*/
1602c18ec02fSPetter Reinholdtsen evt->record_id = 0;
1603c18ec02fSPetter Reinholdtsen evt->record_type = 0;
1604c18ec02fSPetter Reinholdtsen if (evt->record_type < 0xc0)
1605c18ec02fSPetter Reinholdtsen {
1606c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.timestamp = 0;
1607c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.gen_id = 0;
1608c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.evm_rev = 0;
1609c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_type = 0;
1610c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_num = 0;
1611c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_type = 0;
1612c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_dir = 0;
1613c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[0] = 0;
1614c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[1] = 0;
1615c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[2] = 0;
1616c18ec02fSPetter Reinholdtsen }
1617c18ec02fSPetter Reinholdtsen else if (evt->record_type < 0xe0)
1618c18ec02fSPetter Reinholdtsen {
1619c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.timestamp = 0;
1620c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.manf_id[0] = 0;
1621c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.manf_id[1] = 0;
1622c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.manf_id[2] = 0;
1623c18ec02fSPetter Reinholdtsen for(data_count=0; data_count < SEL_OEM_TS_DATA_LEN ; data_count++)
1624c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.oem_defined[data_count] = 0;
1625c18ec02fSPetter Reinholdtsen }
1626c18ec02fSPetter Reinholdtsen else
1627c18ec02fSPetter Reinholdtsen {
1628c18ec02fSPetter Reinholdtsen for(data_count=0; data_count < SEL_OEM_NOTS_DATA_LEN ; data_count++)
1629c18ec02fSPetter Reinholdtsen evt->sel_type.oem_nots_type.oem_defined[data_count] = 0;
1630c18ec02fSPetter Reinholdtsen }
1631c18ec02fSPetter Reinholdtsen
1632c18ec02fSPetter Reinholdtsen /* save response into SEL event structure */
1633c18ec02fSPetter Reinholdtsen evt->record_id = (rsp->data[3] << 8) | rsp->data[2];
1634c18ec02fSPetter Reinholdtsen evt->record_type = rsp->data[4];
1635c18ec02fSPetter Reinholdtsen if (evt->record_type < 0xc0)
1636c18ec02fSPetter Reinholdtsen {
1637c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.timestamp = (rsp->data[8] << 24) | (rsp->data[7] << 16) |
1638c18ec02fSPetter Reinholdtsen (rsp->data[6] << 8) | rsp->data[5];
1639c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.gen_id = (rsp->data[10] << 8) | rsp->data[9];
1640c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.evm_rev = rsp->data[11];
1641c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_type = rsp->data[12];
1642c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_num = rsp->data[13];
1643c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_type = rsp->data[14] & 0x7f;
1644c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_dir = (rsp->data[14] & 0x80) >> 7;
1645c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[0] = rsp->data[15];
1646c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[1] = rsp->data[16];
1647c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[2] = rsp->data[17];
1648c18ec02fSPetter Reinholdtsen }
1649c18ec02fSPetter Reinholdtsen else if (evt->record_type < 0xe0)
1650c18ec02fSPetter Reinholdtsen {
1651c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.timestamp= (rsp->data[8] << 24) | (rsp->data[7] << 16) |
1652c18ec02fSPetter Reinholdtsen (rsp->data[6] << 8) | rsp->data[5];
1653c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.manf_id[0]= rsp->data[11];
1654c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.manf_id[1]= rsp->data[10];
1655c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.manf_id[2]= rsp->data[9];
1656c18ec02fSPetter Reinholdtsen for(data_count=0; data_count < SEL_OEM_TS_DATA_LEN ; data_count++)
1657c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.oem_defined[data_count] = rsp->data[(data_count+12)];
1658c18ec02fSPetter Reinholdtsen }
1659c18ec02fSPetter Reinholdtsen else
1660c18ec02fSPetter Reinholdtsen {
1661c18ec02fSPetter Reinholdtsen for(data_count=0; data_count < SEL_OEM_NOTS_DATA_LEN ; data_count++)
1662c18ec02fSPetter Reinholdtsen evt->sel_type.oem_nots_type.oem_defined[data_count] = rsp->data[(data_count+5)];
1663c18ec02fSPetter Reinholdtsen }
1664c18ec02fSPetter Reinholdtsen return next;
1665c18ec02fSPetter Reinholdtsen }
1666c18ec02fSPetter Reinholdtsen
1667c18ec02fSPetter Reinholdtsen static void
ipmi_sel_print_event_file(struct ipmi_intf * intf,struct sel_event_record * evt,FILE * fp)1668c18ec02fSPetter Reinholdtsen ipmi_sel_print_event_file(struct ipmi_intf * intf, struct sel_event_record * evt, FILE * fp)
1669c18ec02fSPetter Reinholdtsen {
1670c18ec02fSPetter Reinholdtsen char * description;
1671c18ec02fSPetter Reinholdtsen
1672c18ec02fSPetter Reinholdtsen if (fp == NULL)
1673c18ec02fSPetter Reinholdtsen return;
1674c18ec02fSPetter Reinholdtsen
1675c18ec02fSPetter Reinholdtsen ipmi_get_event_desc(intf, evt, &description);
1676c18ec02fSPetter Reinholdtsen
1677c18ec02fSPetter Reinholdtsen fprintf(fp, "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x # %s #0x%02x %s\n",
1678c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.evm_rev,
1679c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_type,
1680c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_num,
1681c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_type | (evt->sel_type.standard_type.event_dir << 7),
1682c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[0],
1683c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[1],
1684c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[2],
1685c18ec02fSPetter Reinholdtsen (
1686c18ec02fSPetter Reinholdtsen (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
1687c18ec02fSPetter Reinholdtsen ?
1688c18ec02fSPetter Reinholdtsen ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
1689c18ec02fSPetter Reinholdtsen :
1690c18ec02fSPetter Reinholdtsen ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
1691c18ec02fSPetter Reinholdtsen ),
1692c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_num,
1693c18ec02fSPetter Reinholdtsen (description != NULL) ? description : "Unknown");
1694c18ec02fSPetter Reinholdtsen
1695c18ec02fSPetter Reinholdtsen if (description != NULL) {
1696c18ec02fSPetter Reinholdtsen free(description);
1697c18ec02fSPetter Reinholdtsen description = NULL;
1698c18ec02fSPetter Reinholdtsen }
1699c18ec02fSPetter Reinholdtsen }
1700c18ec02fSPetter Reinholdtsen
1701c18ec02fSPetter Reinholdtsen void
ipmi_sel_print_extended_entry(struct ipmi_intf * intf,struct sel_event_record * evt)1702c18ec02fSPetter Reinholdtsen ipmi_sel_print_extended_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
1703c18ec02fSPetter Reinholdtsen {
1704c18ec02fSPetter Reinholdtsen sel_extended++;
1705c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry(intf, evt);
1706c18ec02fSPetter Reinholdtsen sel_extended--;
1707c18ec02fSPetter Reinholdtsen }
1708c18ec02fSPetter Reinholdtsen
1709c18ec02fSPetter Reinholdtsen void
ipmi_sel_print_std_entry(struct ipmi_intf * intf,struct sel_event_record * evt)1710c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
1711c18ec02fSPetter Reinholdtsen {
1712c18ec02fSPetter Reinholdtsen char * description;
1713c18ec02fSPetter Reinholdtsen struct sdr_record_list * sdr = NULL;
1714c18ec02fSPetter Reinholdtsen int data_count;
1715c18ec02fSPetter Reinholdtsen
1716c18ec02fSPetter Reinholdtsen if (sel_extended && (evt->record_type < 0xc0))
1717c18ec02fSPetter Reinholdtsen sdr = ipmi_sdr_find_sdr_bynumtype(intf, evt->sel_type.standard_type.gen_id, evt->sel_type.standard_type.sensor_num, evt->sel_type.standard_type.sensor_type);
1718c18ec02fSPetter Reinholdtsen
1719c18ec02fSPetter Reinholdtsen
1720c18ec02fSPetter Reinholdtsen if (!evt)
1721c18ec02fSPetter Reinholdtsen return;
1722c18ec02fSPetter Reinholdtsen
1723c18ec02fSPetter Reinholdtsen if (csv_output)
1724c18ec02fSPetter Reinholdtsen printf("%x,", evt->record_id);
1725c18ec02fSPetter Reinholdtsen else
1726c18ec02fSPetter Reinholdtsen printf("%4x | ", evt->record_id);
1727c18ec02fSPetter Reinholdtsen
1728c18ec02fSPetter Reinholdtsen if (evt->record_type == 0xf0)
1729c18ec02fSPetter Reinholdtsen {
1730c18ec02fSPetter Reinholdtsen if (csv_output)
1731c18ec02fSPetter Reinholdtsen printf(",,");
1732c18ec02fSPetter Reinholdtsen
1733c18ec02fSPetter Reinholdtsen printf ("Linux kernel panic: %.11s\n", (char *) evt + 5);
1734c18ec02fSPetter Reinholdtsen return;
1735c18ec02fSPetter Reinholdtsen }
1736c18ec02fSPetter Reinholdtsen
1737c18ec02fSPetter Reinholdtsen if (evt->record_type < 0xe0)
1738c18ec02fSPetter Reinholdtsen {
1739c18ec02fSPetter Reinholdtsen if ((evt->sel_type.standard_type.timestamp < 0x20000000)||(evt->sel_type.oem_ts_type.timestamp < 0x20000000)){
1740c18ec02fSPetter Reinholdtsen printf(" Pre-Init ");
1741c18ec02fSPetter Reinholdtsen
1742c18ec02fSPetter Reinholdtsen if (csv_output)
1743c18ec02fSPetter Reinholdtsen printf(",");
1744c18ec02fSPetter Reinholdtsen else
1745c18ec02fSPetter Reinholdtsen printf(" |");
1746c18ec02fSPetter Reinholdtsen
1747c18ec02fSPetter Reinholdtsen printf("%010d", evt->sel_type.standard_type.timestamp );
1748c18ec02fSPetter Reinholdtsen if (csv_output)
1749c18ec02fSPetter Reinholdtsen printf(",");
1750c18ec02fSPetter Reinholdtsen else
1751c18ec02fSPetter Reinholdtsen printf("| ");
1752c18ec02fSPetter Reinholdtsen }
1753c18ec02fSPetter Reinholdtsen else {
1754c18ec02fSPetter Reinholdtsen if (evt->record_type < 0xc0)
1755c18ec02fSPetter Reinholdtsen printf("%s", ipmi_sel_timestamp_date(evt->sel_type.standard_type.timestamp));
1756c18ec02fSPetter Reinholdtsen else
1757c18ec02fSPetter Reinholdtsen printf("%s", ipmi_sel_timestamp_date(evt->sel_type.oem_ts_type.timestamp));
1758c18ec02fSPetter Reinholdtsen if (csv_output)
1759c18ec02fSPetter Reinholdtsen printf(",");
1760c18ec02fSPetter Reinholdtsen else
1761c18ec02fSPetter Reinholdtsen printf(" | ");
1762c18ec02fSPetter Reinholdtsen
1763c18ec02fSPetter Reinholdtsen if (evt->record_type < 0xc0)
1764c18ec02fSPetter Reinholdtsen printf("%s", ipmi_sel_timestamp_time(evt->sel_type.standard_type.timestamp));
1765c18ec02fSPetter Reinholdtsen else
1766c18ec02fSPetter Reinholdtsen printf("%s", ipmi_sel_timestamp_time(evt->sel_type.oem_ts_type.timestamp));
1767c18ec02fSPetter Reinholdtsen
1768c18ec02fSPetter Reinholdtsen if (csv_output)
1769c18ec02fSPetter Reinholdtsen printf(",");
1770c18ec02fSPetter Reinholdtsen else
1771c18ec02fSPetter Reinholdtsen printf(" | ");
1772c18ec02fSPetter Reinholdtsen }
1773c18ec02fSPetter Reinholdtsen
1774c18ec02fSPetter Reinholdtsen }
1775c18ec02fSPetter Reinholdtsen else
1776c18ec02fSPetter Reinholdtsen {
1777c18ec02fSPetter Reinholdtsen if (csv_output)
1778c18ec02fSPetter Reinholdtsen printf(",,");
1779c18ec02fSPetter Reinholdtsen }
1780c18ec02fSPetter Reinholdtsen
1781c18ec02fSPetter Reinholdtsen if (evt->record_type >= 0xc0)
1782c18ec02fSPetter Reinholdtsen {
1783c18ec02fSPetter Reinholdtsen printf ("OEM record %02x", evt->record_type);
1784c18ec02fSPetter Reinholdtsen if (csv_output)
1785c18ec02fSPetter Reinholdtsen printf(",");
1786c18ec02fSPetter Reinholdtsen else
1787c18ec02fSPetter Reinholdtsen printf(" | ");
1788c18ec02fSPetter Reinholdtsen
17898f783736SZdenek Styblik if(evt->record_type <= 0xdf)
1790c18ec02fSPetter Reinholdtsen {
1791c18ec02fSPetter Reinholdtsen printf ("%02x%02x%02x", evt->sel_type.oem_ts_type.manf_id[0], evt->sel_type.oem_ts_type.manf_id[1], evt->sel_type.oem_ts_type.manf_id[2]);
1792c18ec02fSPetter Reinholdtsen if (csv_output)
1793c18ec02fSPetter Reinholdtsen printf(",");
1794c18ec02fSPetter Reinholdtsen else
1795c18ec02fSPetter Reinholdtsen printf(" | ");
1796c18ec02fSPetter Reinholdtsen for(data_count=0;data_count < SEL_OEM_TS_DATA_LEN;data_count++)
1797c18ec02fSPetter Reinholdtsen printf("%02x", evt->sel_type.oem_ts_type.oem_defined[data_count]);
1798c18ec02fSPetter Reinholdtsen }
1799c18ec02fSPetter Reinholdtsen else
1800c18ec02fSPetter Reinholdtsen {
1801c18ec02fSPetter Reinholdtsen for(data_count=0;data_count < SEL_OEM_NOTS_DATA_LEN;data_count++)
1802c18ec02fSPetter Reinholdtsen printf("%02x", evt->sel_type.oem_nots_type.oem_defined[data_count]);
1803c18ec02fSPetter Reinholdtsen }
1804c18ec02fSPetter Reinholdtsen ipmi_sel_oem_message(evt, 0);
1805c18ec02fSPetter Reinholdtsen printf ("\n");
1806c18ec02fSPetter Reinholdtsen return;
1807c18ec02fSPetter Reinholdtsen }
1808c18ec02fSPetter Reinholdtsen
1809c18ec02fSPetter Reinholdtsen /* lookup SDR entry based on sensor number and type */
1810c18ec02fSPetter Reinholdtsen if (sdr != NULL) {
1811c18ec02fSPetter Reinholdtsen printf("%s ",
1812c18ec02fSPetter Reinholdtsen (
1813c18ec02fSPetter Reinholdtsen (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
1814c18ec02fSPetter Reinholdtsen ?
1815c18ec02fSPetter Reinholdtsen ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
1816c18ec02fSPetter Reinholdtsen :
1817c18ec02fSPetter Reinholdtsen ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
1818c18ec02fSPetter Reinholdtsen )
1819c18ec02fSPetter Reinholdtsen );
1820c18ec02fSPetter Reinholdtsen switch (sdr->type) {
1821c18ec02fSPetter Reinholdtsen case SDR_RECORD_TYPE_FULL_SENSOR:
1822c18ec02fSPetter Reinholdtsen printf("%s", sdr->record.full->id_string);
1823c18ec02fSPetter Reinholdtsen break;
1824c18ec02fSPetter Reinholdtsen case SDR_RECORD_TYPE_COMPACT_SENSOR:
1825c18ec02fSPetter Reinholdtsen printf("%s", sdr->record.compact->id_string);
1826c18ec02fSPetter Reinholdtsen break;
1827c18ec02fSPetter Reinholdtsen case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
1828c18ec02fSPetter Reinholdtsen printf("%s", sdr->record.eventonly->id_string);
1829c18ec02fSPetter Reinholdtsen break;
1830c18ec02fSPetter Reinholdtsen case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
1831c18ec02fSPetter Reinholdtsen printf("%s", sdr->record.fruloc->id_string);
1832c18ec02fSPetter Reinholdtsen break;
1833c18ec02fSPetter Reinholdtsen case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
1834c18ec02fSPetter Reinholdtsen printf("%s", sdr->record.mcloc->id_string);
1835c18ec02fSPetter Reinholdtsen break;
1836c18ec02fSPetter Reinholdtsen case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
1837c18ec02fSPetter Reinholdtsen printf("%s", sdr->record.genloc->id_string);
1838c18ec02fSPetter Reinholdtsen break;
1839c18ec02fSPetter Reinholdtsen default:
1840c18ec02fSPetter Reinholdtsen printf("#%02x", evt->sel_type.standard_type.sensor_num);
1841c18ec02fSPetter Reinholdtsen break;
1842c18ec02fSPetter Reinholdtsen }
1843c18ec02fSPetter Reinholdtsen } else {
1844c18ec02fSPetter Reinholdtsen printf("%s",(
1845c18ec02fSPetter Reinholdtsen (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
1846c18ec02fSPetter Reinholdtsen ?
1847c18ec02fSPetter Reinholdtsen ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
1848c18ec02fSPetter Reinholdtsen :
1849c18ec02fSPetter Reinholdtsen ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
1850c18ec02fSPetter Reinholdtsen ));
1851c18ec02fSPetter Reinholdtsen if (evt->sel_type.standard_type.sensor_num != 0)
1852c18ec02fSPetter Reinholdtsen printf(" #0x%02x", evt->sel_type.standard_type.sensor_num);
1853c18ec02fSPetter Reinholdtsen }
1854c18ec02fSPetter Reinholdtsen
1855c18ec02fSPetter Reinholdtsen if (csv_output)
1856c18ec02fSPetter Reinholdtsen printf(",");
1857c18ec02fSPetter Reinholdtsen else
1858c18ec02fSPetter Reinholdtsen printf(" | ");
1859c18ec02fSPetter Reinholdtsen
1860c18ec02fSPetter Reinholdtsen ipmi_get_event_desc(intf, evt, &description);
1861c18ec02fSPetter Reinholdtsen if (description) {
1862c18ec02fSPetter Reinholdtsen printf("%s", description);
1863c18ec02fSPetter Reinholdtsen free(description);
1864c18ec02fSPetter Reinholdtsen description = NULL;
1865c18ec02fSPetter Reinholdtsen }
1866c18ec02fSPetter Reinholdtsen
1867c18ec02fSPetter Reinholdtsen if (csv_output) {
1868c18ec02fSPetter Reinholdtsen printf(",");
1869c18ec02fSPetter Reinholdtsen } else {
1870c18ec02fSPetter Reinholdtsen printf(" | ");
1871c18ec02fSPetter Reinholdtsen }
1872c18ec02fSPetter Reinholdtsen
1873c18ec02fSPetter Reinholdtsen if (evt->sel_type.standard_type.event_dir) {
1874c18ec02fSPetter Reinholdtsen printf("Deasserted");
1875c18ec02fSPetter Reinholdtsen } else {
1876c18ec02fSPetter Reinholdtsen printf("Asserted");
1877c18ec02fSPetter Reinholdtsen }
1878c18ec02fSPetter Reinholdtsen
1879c18ec02fSPetter Reinholdtsen if (sdr != NULL && evt->sel_type.standard_type.event_type == 1) {
1880c18ec02fSPetter Reinholdtsen /*
1881c18ec02fSPetter Reinholdtsen * Threshold Event
1882c18ec02fSPetter Reinholdtsen */
1883c18ec02fSPetter Reinholdtsen float trigger_reading = 0.0;
1884c18ec02fSPetter Reinholdtsen float threshold_reading = 0.0;
1885c18ec02fSPetter Reinholdtsen uint8_t threshold_reading_provided = 0;
1886c18ec02fSPetter Reinholdtsen
1887c18ec02fSPetter Reinholdtsen /* trigger reading in event data byte 2 */
1888c18ec02fSPetter Reinholdtsen if (((evt->sel_type.standard_type.event_data[0] >> 6) & 3) == 1) {
1889c18ec02fSPetter Reinholdtsen trigger_reading = sdr_convert_sensor_reading(
1890c18ec02fSPetter Reinholdtsen sdr->record.full, evt->sel_type.standard_type.event_data[1]);
1891c18ec02fSPetter Reinholdtsen }
1892c18ec02fSPetter Reinholdtsen
1893c18ec02fSPetter Reinholdtsen /* trigger threshold in event data byte 3 */
1894c18ec02fSPetter Reinholdtsen if (((evt->sel_type.standard_type.event_data[0] >> 4) & 3) == 1) {
1895c18ec02fSPetter Reinholdtsen threshold_reading = sdr_convert_sensor_reading(
1896c18ec02fSPetter Reinholdtsen sdr->record.full, evt->sel_type.standard_type.event_data[2]);
1897c18ec02fSPetter Reinholdtsen threshold_reading_provided = 1;
1898c18ec02fSPetter Reinholdtsen }
1899c18ec02fSPetter Reinholdtsen
1900c18ec02fSPetter Reinholdtsen if (csv_output)
1901c18ec02fSPetter Reinholdtsen printf(",");
1902c18ec02fSPetter Reinholdtsen else
1903c18ec02fSPetter Reinholdtsen printf(" | ");
1904c18ec02fSPetter Reinholdtsen
1905c18ec02fSPetter Reinholdtsen printf("Reading %.*f",
1906c18ec02fSPetter Reinholdtsen (trigger_reading==(int)trigger_reading) ? 0 : 2,
1907c18ec02fSPetter Reinholdtsen trigger_reading);
1908c18ec02fSPetter Reinholdtsen if (threshold_reading_provided) {
1909c18ec02fSPetter Reinholdtsen printf(" %s Threshold %.*f %s",
1910c18ec02fSPetter Reinholdtsen ((evt->sel_type.standard_type.event_data[0] & 0xf) % 2) ? ">" : "<",
1911c18ec02fSPetter Reinholdtsen (threshold_reading==(int)threshold_reading) ? 0 : 2,
1912c18ec02fSPetter Reinholdtsen threshold_reading,
1913c18ec02fSPetter Reinholdtsen ipmi_sdr_get_unit_string(sdr->record.common->unit.pct,
1914c18ec02fSPetter Reinholdtsen sdr->record.common->unit.modifier,
1915c18ec02fSPetter Reinholdtsen sdr->record.common->unit.type.base,
1916c18ec02fSPetter Reinholdtsen sdr->record.common->unit.type.modifier));
1917c18ec02fSPetter Reinholdtsen }
1918c18ec02fSPetter Reinholdtsen }
1919c18ec02fSPetter Reinholdtsen else if (evt->sel_type.standard_type.event_type == 0x6f) {
1920c18ec02fSPetter Reinholdtsen int print_sensor = 1;
1921c18ec02fSPetter Reinholdtsen switch (ipmi_get_oem(intf)) {
1922c18ec02fSPetter Reinholdtsen case IPMI_OEM_SUPERMICRO:
1923c18ec02fSPetter Reinholdtsen case IPMI_OEM_SUPERMICRO_47488:
1924c18ec02fSPetter Reinholdtsen print_sensor = 0;
1925c18ec02fSPetter Reinholdtsen break;
192639fb1af2SZdenek Styblik default:
192739fb1af2SZdenek Styblik break;
1928c18ec02fSPetter Reinholdtsen }
1929c18ec02fSPetter Reinholdtsen /*
1930c18ec02fSPetter Reinholdtsen * Sensor-Specific Discrete
1931c18ec02fSPetter Reinholdtsen */
1932c18ec02fSPetter Reinholdtsen if (print_sensor && evt->sel_type.standard_type.sensor_type == 0xC && /*TODO*/
1933c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_num == 0 &&
1934c18ec02fSPetter Reinholdtsen (evt->sel_type.standard_type.event_data[0] & 0x30) == 0x20) {
1935c18ec02fSPetter Reinholdtsen /* break down memory ECC reporting if we can */
1936c18ec02fSPetter Reinholdtsen if (csv_output)
1937c18ec02fSPetter Reinholdtsen printf(",");
1938c18ec02fSPetter Reinholdtsen else
1939c18ec02fSPetter Reinholdtsen printf(" | ");
1940c18ec02fSPetter Reinholdtsen
1941c18ec02fSPetter Reinholdtsen printf("CPU %d DIMM %d",
1942c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[2] & 0x0f,
1943c18ec02fSPetter Reinholdtsen (evt->sel_type.standard_type.event_data[2] & 0xf0) >> 4);
1944c18ec02fSPetter Reinholdtsen }
1945c18ec02fSPetter Reinholdtsen }
1946c18ec02fSPetter Reinholdtsen
1947c18ec02fSPetter Reinholdtsen printf("\n");
1948c18ec02fSPetter Reinholdtsen }
1949c18ec02fSPetter Reinholdtsen
1950c18ec02fSPetter Reinholdtsen void
ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf,struct sel_event_record * evt)1951c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt)
1952c18ec02fSPetter Reinholdtsen {
1953c18ec02fSPetter Reinholdtsen char * description;
1954c18ec02fSPetter Reinholdtsen int data_count;
1955c18ec02fSPetter Reinholdtsen
1956c18ec02fSPetter Reinholdtsen if (!evt)
1957c18ec02fSPetter Reinholdtsen return;
1958c18ec02fSPetter Reinholdtsen
1959c18ec02fSPetter Reinholdtsen printf("SEL Record ID : %04x\n", evt->record_id);
1960c18ec02fSPetter Reinholdtsen
1961c18ec02fSPetter Reinholdtsen if (evt->record_type == 0xf0)
1962c18ec02fSPetter Reinholdtsen {
1963c18ec02fSPetter Reinholdtsen printf (" Record Type : Linux kernel panic (OEM record %02x)\n", evt->record_type);
1964c18ec02fSPetter Reinholdtsen printf (" Panic string : %.11s\n\n", (char *) evt + 5);
1965c18ec02fSPetter Reinholdtsen return;
1966c18ec02fSPetter Reinholdtsen }
1967c18ec02fSPetter Reinholdtsen
1968c18ec02fSPetter Reinholdtsen printf(" Record Type : %02x", evt->record_type);
1969c18ec02fSPetter Reinholdtsen if (evt->record_type >= 0xc0)
1970c18ec02fSPetter Reinholdtsen {
1971c18ec02fSPetter Reinholdtsen if (evt->record_type < 0xe0)
1972c18ec02fSPetter Reinholdtsen printf(" (OEM timestamped)");
1973c18ec02fSPetter Reinholdtsen else
1974c18ec02fSPetter Reinholdtsen printf(" (OEM non-timestamped)");
1975c18ec02fSPetter Reinholdtsen }
1976c18ec02fSPetter Reinholdtsen printf("\n");
1977c18ec02fSPetter Reinholdtsen
1978c18ec02fSPetter Reinholdtsen if (evt->record_type < 0xe0)
1979c18ec02fSPetter Reinholdtsen {
1980c18ec02fSPetter Reinholdtsen printf(" Timestamp : ");
1981c18ec02fSPetter Reinholdtsen if (evt->record_type < 0xc0)
1982c18ec02fSPetter Reinholdtsen printf("%s %s", ipmi_sel_timestamp_date(evt->sel_type.standard_type.timestamp),
1983c18ec02fSPetter Reinholdtsen ipmi_sel_timestamp_time(evt->sel_type.standard_type.timestamp));
1984c18ec02fSPetter Reinholdtsen else
1985c18ec02fSPetter Reinholdtsen printf("%s %s", ipmi_sel_timestamp_date(evt->sel_type.oem_ts_type.timestamp),
1986c18ec02fSPetter Reinholdtsen ipmi_sel_timestamp_time(evt->sel_type.oem_ts_type.timestamp));
1987c18ec02fSPetter Reinholdtsen printf("\n");
1988c18ec02fSPetter Reinholdtsen }
1989c18ec02fSPetter Reinholdtsen
1990c18ec02fSPetter Reinholdtsen if (evt->record_type >= 0xc0)
1991c18ec02fSPetter Reinholdtsen {
19928f783736SZdenek Styblik if(evt->record_type <= 0xdf)
1993c18ec02fSPetter Reinholdtsen {
1994c18ec02fSPetter Reinholdtsen printf (" Manufactacturer ID : %02x%02x%02x\n", evt->sel_type.oem_ts_type.manf_id[0],
1995c18ec02fSPetter Reinholdtsen evt->sel_type.oem_ts_type.manf_id[1], evt->sel_type.oem_ts_type.manf_id[2]);
1996c18ec02fSPetter Reinholdtsen printf (" OEM Defined : ");
1997c18ec02fSPetter Reinholdtsen for(data_count=0;data_count < SEL_OEM_TS_DATA_LEN;data_count++)
1998c18ec02fSPetter Reinholdtsen printf("%02x", evt->sel_type.oem_ts_type.oem_defined[data_count]);
1999c18ec02fSPetter Reinholdtsen printf(" [%s]\n\n",hex2ascii (evt->sel_type.oem_ts_type.oem_defined, SEL_OEM_TS_DATA_LEN));
2000c18ec02fSPetter Reinholdtsen }
2001c18ec02fSPetter Reinholdtsen else
2002c18ec02fSPetter Reinholdtsen {
2003c18ec02fSPetter Reinholdtsen printf (" OEM Defined : ");
2004c18ec02fSPetter Reinholdtsen for(data_count=0;data_count < SEL_OEM_NOTS_DATA_LEN;data_count++)
2005c18ec02fSPetter Reinholdtsen printf("%02x", evt->sel_type.oem_nots_type.oem_defined[data_count]);
2006c18ec02fSPetter Reinholdtsen printf(" [%s]\n\n",hex2ascii (evt->sel_type.oem_nots_type.oem_defined, SEL_OEM_NOTS_DATA_LEN));
2007c18ec02fSPetter Reinholdtsen ipmi_sel_oem_message(evt, 1);
2008c18ec02fSPetter Reinholdtsen }
2009c18ec02fSPetter Reinholdtsen return;
2010c18ec02fSPetter Reinholdtsen }
2011c18ec02fSPetter Reinholdtsen
2012c18ec02fSPetter Reinholdtsen printf(" Generator ID : %04x\n",
2013c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.gen_id);
2014c18ec02fSPetter Reinholdtsen printf(" EvM Revision : %02x\n",
2015c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.evm_rev);
2016c18ec02fSPetter Reinholdtsen printf(" Sensor Type : %s\n",
2017c18ec02fSPetter Reinholdtsen (
2018c18ec02fSPetter Reinholdtsen (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
2019c18ec02fSPetter Reinholdtsen ?
2020c18ec02fSPetter Reinholdtsen ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
2021c18ec02fSPetter Reinholdtsen :
2022c18ec02fSPetter Reinholdtsen ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
2023c18ec02fSPetter Reinholdtsen )
2024c18ec02fSPetter Reinholdtsen );
2025c18ec02fSPetter Reinholdtsen printf(" Sensor Number : %02x\n",
2026c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_num);
2027c18ec02fSPetter Reinholdtsen printf(" Event Type : %s\n",
2028c18ec02fSPetter Reinholdtsen ipmi_get_event_type(evt->sel_type.standard_type.event_type));
2029c18ec02fSPetter Reinholdtsen printf(" Event Direction : %s\n",
2030c18ec02fSPetter Reinholdtsen val2str(evt->sel_type.standard_type.event_dir, event_dir_vals));
2031c18ec02fSPetter Reinholdtsen printf(" Event Data : %02x%02x%02x\n",
2032c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[0], evt->sel_type.standard_type.event_data[1], evt->sel_type.standard_type.event_data[2]);
2033c18ec02fSPetter Reinholdtsen ipmi_get_event_desc(intf, evt, &description);
2034c18ec02fSPetter Reinholdtsen printf(" Description : %s\n",
2035c18ec02fSPetter Reinholdtsen description ? description : "");
2036c18ec02fSPetter Reinholdtsen free(description);
2037c18ec02fSPetter Reinholdtsen description = NULL;
2038c18ec02fSPetter Reinholdtsen
2039c18ec02fSPetter Reinholdtsen printf("\n");
2040c18ec02fSPetter Reinholdtsen }
2041c18ec02fSPetter Reinholdtsen
2042c18ec02fSPetter Reinholdtsen
2043c18ec02fSPetter Reinholdtsen void
ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf,struct sel_event_record * evt)2044c18ec02fSPetter Reinholdtsen ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt)
2045c18ec02fSPetter Reinholdtsen {
2046c18ec02fSPetter Reinholdtsen struct sdr_record_list * sdr;
2047c18ec02fSPetter Reinholdtsen char * description;
2048c18ec02fSPetter Reinholdtsen
2049c18ec02fSPetter Reinholdtsen if (!evt)
2050c18ec02fSPetter Reinholdtsen return;
2051c18ec02fSPetter Reinholdtsen
2052c18ec02fSPetter Reinholdtsen sdr = ipmi_sdr_find_sdr_bynumtype(intf,
2053c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.gen_id,
2054c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_num,
2055c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_type);
2056c18ec02fSPetter Reinholdtsen if (sdr == NULL)
2057c18ec02fSPetter Reinholdtsen {
2058c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry_verbose(intf, evt);
2059c18ec02fSPetter Reinholdtsen return;
2060c18ec02fSPetter Reinholdtsen }
2061c18ec02fSPetter Reinholdtsen
2062c18ec02fSPetter Reinholdtsen printf("SEL Record ID : %04x\n", evt->record_id);
2063c18ec02fSPetter Reinholdtsen
2064c18ec02fSPetter Reinholdtsen if (evt->record_type == 0xf0)
2065c18ec02fSPetter Reinholdtsen {
2066c18ec02fSPetter Reinholdtsen printf (" Record Type : "
2067c18ec02fSPetter Reinholdtsen "Linux kernel panic (OEM record %02x)\n",
2068c18ec02fSPetter Reinholdtsen evt->record_type);
2069c18ec02fSPetter Reinholdtsen printf (" Panic string : %.11s\n\n",
2070c18ec02fSPetter Reinholdtsen (char *) evt + 5);
2071c18ec02fSPetter Reinholdtsen return;
2072c18ec02fSPetter Reinholdtsen }
2073c18ec02fSPetter Reinholdtsen
2074c18ec02fSPetter Reinholdtsen printf(" Record Type : %02x\n", evt->record_type);
2075c18ec02fSPetter Reinholdtsen if (evt->record_type < 0xe0)
2076c18ec02fSPetter Reinholdtsen {
2077c18ec02fSPetter Reinholdtsen printf(" Timestamp : ");
2078c18ec02fSPetter Reinholdtsen printf("%s %s\n", ipmi_sel_timestamp_date(evt->sel_type.standard_type.timestamp),
2079c18ec02fSPetter Reinholdtsen ipmi_sel_timestamp_time(evt->sel_type.standard_type.timestamp));
2080c18ec02fSPetter Reinholdtsen }
2081c18ec02fSPetter Reinholdtsen
2082c18ec02fSPetter Reinholdtsen
2083c18ec02fSPetter Reinholdtsen printf(" Generator ID : %04x\n",
2084c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.gen_id);
2085c18ec02fSPetter Reinholdtsen printf(" EvM Revision : %02x\n",
2086c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.evm_rev);
2087c18ec02fSPetter Reinholdtsen printf(" Sensor Type : %s\n",
2088c18ec02fSPetter Reinholdtsen ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0]));
2089c18ec02fSPetter Reinholdtsen printf(" Sensor Number : %02x\n",
2090c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_num);
2091c18ec02fSPetter Reinholdtsen printf(" Event Type : %s\n",
2092c18ec02fSPetter Reinholdtsen ipmi_get_event_type(evt->sel_type.standard_type.event_type));
2093c18ec02fSPetter Reinholdtsen printf(" Event Direction : %s\n",
2094c18ec02fSPetter Reinholdtsen val2str(evt->sel_type.standard_type.event_dir, event_dir_vals));
2095c18ec02fSPetter Reinholdtsen printf(" Event Data (RAW) : %02x%02x%02x\n",
2096c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[0], evt->sel_type.standard_type.event_data[1], evt->sel_type.standard_type.event_data[2]);
2097c18ec02fSPetter Reinholdtsen
2098c18ec02fSPetter Reinholdtsen /* break down event data field
2099c18ec02fSPetter Reinholdtsen * as per IPMI Spec 2.0 Table 29-6 */
2100c18ec02fSPetter Reinholdtsen if (evt->sel_type.standard_type.event_type == 1 && sdr->type == SDR_RECORD_TYPE_FULL_SENSOR) {
2101c18ec02fSPetter Reinholdtsen /* Threshold */
2102c18ec02fSPetter Reinholdtsen switch ((evt->sel_type.standard_type.event_data[0] >> 6) & 3) { /* EV1[7:6] */
2103c18ec02fSPetter Reinholdtsen case 0:
2104c18ec02fSPetter Reinholdtsen /* unspecified byte 2 */
2105c18ec02fSPetter Reinholdtsen break;
2106c18ec02fSPetter Reinholdtsen case 1:
2107c18ec02fSPetter Reinholdtsen /* trigger reading in byte 2 */
2108c18ec02fSPetter Reinholdtsen printf(" Trigger Reading : %.3f",
2109c18ec02fSPetter Reinholdtsen sdr_convert_sensor_reading(sdr->record.full,
2110c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[1]));
2111c18ec02fSPetter Reinholdtsen /* determine units with possible modifiers */
2112c18ec02fSPetter Reinholdtsen printf ("%s\n", ipmi_sdr_get_unit_string(sdr->record.common->unit.pct,
2113c18ec02fSPetter Reinholdtsen sdr->record.common->unit.modifier,
2114c18ec02fSPetter Reinholdtsen sdr->record.common->unit.type.base,
2115c18ec02fSPetter Reinholdtsen sdr->record.common->unit.type.modifier));
2116c18ec02fSPetter Reinholdtsen break;
2117c18ec02fSPetter Reinholdtsen case 2:
2118c18ec02fSPetter Reinholdtsen /* oem code in byte 2 */
2119c18ec02fSPetter Reinholdtsen printf(" OEM Data : %02x\n",
2120c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[1]);
2121c18ec02fSPetter Reinholdtsen break;
2122c18ec02fSPetter Reinholdtsen case 3:
2123c18ec02fSPetter Reinholdtsen /* sensor-specific extension code in byte 2 */
2124c18ec02fSPetter Reinholdtsen printf(" Sensor Extension Code : %02x\n",
2125c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[1]);
2126c18ec02fSPetter Reinholdtsen break;
2127c18ec02fSPetter Reinholdtsen }
2128c18ec02fSPetter Reinholdtsen switch ((evt->sel_type.standard_type.event_data[0] >> 4) & 3) { /* EV1[5:4] */
2129c18ec02fSPetter Reinholdtsen case 0:
2130c18ec02fSPetter Reinholdtsen /* unspecified byte 3 */
2131c18ec02fSPetter Reinholdtsen break;
2132c18ec02fSPetter Reinholdtsen case 1:
2133c18ec02fSPetter Reinholdtsen /* trigger threshold value in byte 3 */
2134c18ec02fSPetter Reinholdtsen printf(" Trigger Threshold : %.3f",
2135c18ec02fSPetter Reinholdtsen sdr_convert_sensor_reading(sdr->record.full,
2136c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[2]));
2137c18ec02fSPetter Reinholdtsen /* determine units with possible modifiers */
2138c18ec02fSPetter Reinholdtsen printf ("%s\n", ipmi_sdr_get_unit_string(sdr->record.common->unit.pct,
2139c18ec02fSPetter Reinholdtsen sdr->record.common->unit.modifier,
2140c18ec02fSPetter Reinholdtsen sdr->record.common->unit.type.base,
2141c18ec02fSPetter Reinholdtsen sdr->record.common->unit.type.modifier));
2142c18ec02fSPetter Reinholdtsen break;
2143c18ec02fSPetter Reinholdtsen case 2:
2144c18ec02fSPetter Reinholdtsen /* OEM code in byte 3 */
2145c18ec02fSPetter Reinholdtsen printf(" OEM Data : %02x\n",
2146c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[2]);
2147c18ec02fSPetter Reinholdtsen break;
2148c18ec02fSPetter Reinholdtsen case 3:
2149c18ec02fSPetter Reinholdtsen /* sensor-specific extension code in byte 3 */
2150c18ec02fSPetter Reinholdtsen printf(" Sensor Extension Code : %02x\n",
2151c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[2]);
2152c18ec02fSPetter Reinholdtsen break;
2153c18ec02fSPetter Reinholdtsen }
2154c18ec02fSPetter Reinholdtsen } else if (evt->sel_type.standard_type.event_type >= 0x2 && evt->sel_type.standard_type.event_type <= 0xc) {
2155c18ec02fSPetter Reinholdtsen /* Generic Discrete */
2156c18ec02fSPetter Reinholdtsen } else if (evt->sel_type.standard_type.event_type == 0x6f) {
2157c18ec02fSPetter Reinholdtsen
2158c18ec02fSPetter Reinholdtsen /* Sensor-Specific Discrete */
2159c18ec02fSPetter Reinholdtsen if (evt->sel_type.standard_type.sensor_type == 0xC &&
2160c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_num == 0 && /**** THIS LOOK TO BE OEM ****/
2161c18ec02fSPetter Reinholdtsen (evt->sel_type.standard_type.event_data[0] & 0x30) == 0x20)
2162c18ec02fSPetter Reinholdtsen {
2163c18ec02fSPetter Reinholdtsen /* break down memory ECC reporting if we can */
2164c18ec02fSPetter Reinholdtsen printf(" Event Data : CPU %d DIMM %d\n",
2165c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[2] & 0x0f,
2166c18ec02fSPetter Reinholdtsen (evt->sel_type.standard_type.event_data[2] & 0xf0) >> 4);
2167c18ec02fSPetter Reinholdtsen }
2168c18ec02fSPetter Reinholdtsen else if(
2169c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.sensor_type == 0x2b && /* Version change */
2170c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[0] == 0xC1 /* Data in Data 2 */
2171c18ec02fSPetter Reinholdtsen )
2172c18ec02fSPetter Reinholdtsen
2173c18ec02fSPetter Reinholdtsen {
2174c18ec02fSPetter Reinholdtsen //evt->sel_type.standard_type.event_data[1]
2175c18ec02fSPetter Reinholdtsen }
2176c18ec02fSPetter Reinholdtsen else
2177c18ec02fSPetter Reinholdtsen {
2178c18ec02fSPetter Reinholdtsen /* FIXME : Add sensor specific discrete types */
2179c18ec02fSPetter Reinholdtsen printf(" Event Interpretation : Missing\n");
2180c18ec02fSPetter Reinholdtsen }
2181c18ec02fSPetter Reinholdtsen } else if (evt->sel_type.standard_type.event_type >= 0x70 && evt->sel_type.standard_type.event_type <= 0x7f) {
2182c18ec02fSPetter Reinholdtsen /* OEM */
2183c18ec02fSPetter Reinholdtsen } else {
2184c18ec02fSPetter Reinholdtsen printf(" Event Data : %02x%02x%02x\n",
2185c18ec02fSPetter Reinholdtsen evt->sel_type.standard_type.event_data[0], evt->sel_type.standard_type.event_data[1], evt->sel_type.standard_type.event_data[2]);
2186c18ec02fSPetter Reinholdtsen }
2187c18ec02fSPetter Reinholdtsen
2188c18ec02fSPetter Reinholdtsen ipmi_get_event_desc(intf, evt, &description);
2189c18ec02fSPetter Reinholdtsen printf(" Description : %s\n",
2190c18ec02fSPetter Reinholdtsen description ? description : "");
2191c18ec02fSPetter Reinholdtsen free(description);
2192c18ec02fSPetter Reinholdtsen description = NULL;
2193c18ec02fSPetter Reinholdtsen
2194c18ec02fSPetter Reinholdtsen printf("\n");
2195c18ec02fSPetter Reinholdtsen }
2196c18ec02fSPetter Reinholdtsen
2197c18ec02fSPetter Reinholdtsen static int
__ipmi_sel_savelist_entries(struct ipmi_intf * intf,int count,const char * savefile,int binary)2198c18ec02fSPetter Reinholdtsen __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * savefile,
2199c18ec02fSPetter Reinholdtsen int binary)
2200c18ec02fSPetter Reinholdtsen {
2201c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
2202c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
2203c18ec02fSPetter Reinholdtsen uint16_t next_id = 0, curr_id = 0;
2204c18ec02fSPetter Reinholdtsen struct sel_event_record evt;
2205c18ec02fSPetter Reinholdtsen int n=0;
2206c18ec02fSPetter Reinholdtsen FILE * fp = NULL;
2207c18ec02fSPetter Reinholdtsen
2208c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
2209c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
2210c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_CMD_GET_SEL_INFO;
2211c18ec02fSPetter Reinholdtsen
2212c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
2213c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
2214c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Info command failed");
2215c18ec02fSPetter Reinholdtsen return -1;
2216c18ec02fSPetter Reinholdtsen }
2217c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
2218c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Info command failed: %s",
2219c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
2220c18ec02fSPetter Reinholdtsen return -1;
2221c18ec02fSPetter Reinholdtsen }
2222c18ec02fSPetter Reinholdtsen if (verbose > 2)
2223c18ec02fSPetter Reinholdtsen printbuf(rsp->data, rsp->data_len, "sel_info");
2224c18ec02fSPetter Reinholdtsen
2225c18ec02fSPetter Reinholdtsen if (rsp->data[1] == 0 && rsp->data[2] == 0) {
2226c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "SEL has no entries");
2227c18ec02fSPetter Reinholdtsen return 0;
2228c18ec02fSPetter Reinholdtsen }
2229c18ec02fSPetter Reinholdtsen
2230c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
2231c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
2232c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_CMD_RESERVE_SEL;
2233c18ec02fSPetter Reinholdtsen
2234c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
2235c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
2236c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Reserve SEL command failed");
2237c18ec02fSPetter Reinholdtsen return -1;
2238c18ec02fSPetter Reinholdtsen }
2239c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
2240c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Reserve SEL command failed: %s",
2241c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
2242c18ec02fSPetter Reinholdtsen return -1;
2243c18ec02fSPetter Reinholdtsen }
2244c18ec02fSPetter Reinholdtsen
2245c18ec02fSPetter Reinholdtsen if (count < 0) {
2246c18ec02fSPetter Reinholdtsen /** Show only the most recent 'count' records. */
2247c18ec02fSPetter Reinholdtsen int delta;
2248c18ec02fSPetter Reinholdtsen uint16_t entries;
2249c18ec02fSPetter Reinholdtsen
2250c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_CMD_GET_SEL_INFO;
2251c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
2252c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
2253c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Info command failed");
2254c18ec02fSPetter Reinholdtsen return -1;
2255c18ec02fSPetter Reinholdtsen }
2256c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
2257c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Info command failed: %s",
2258c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
2259c18ec02fSPetter Reinholdtsen return -1;
2260c18ec02fSPetter Reinholdtsen }
2261c18ec02fSPetter Reinholdtsen entries = buf2short(rsp->data + 1);
2262c18ec02fSPetter Reinholdtsen if (-count > entries)
2263c18ec02fSPetter Reinholdtsen count = -entries;
2264c18ec02fSPetter Reinholdtsen
2265c18ec02fSPetter Reinholdtsen /* Get first record. */
2266c18ec02fSPetter Reinholdtsen next_id = ipmi_sel_get_std_entry(intf, 0, &evt);
2267c18ec02fSPetter Reinholdtsen
2268c18ec02fSPetter Reinholdtsen delta = next_id - evt.record_id;
2269c18ec02fSPetter Reinholdtsen
2270c18ec02fSPetter Reinholdtsen /* Get last record. */
2271c18ec02fSPetter Reinholdtsen next_id = ipmi_sel_get_std_entry(intf, 0xffff, &evt);
2272c18ec02fSPetter Reinholdtsen
2273c18ec02fSPetter Reinholdtsen next_id = evt.record_id + count * delta + delta;
2274c18ec02fSPetter Reinholdtsen }
2275c18ec02fSPetter Reinholdtsen
2276c18ec02fSPetter Reinholdtsen if (savefile != NULL) {
2277c18ec02fSPetter Reinholdtsen fp = ipmi_open_file_write(savefile);
2278c18ec02fSPetter Reinholdtsen }
2279c18ec02fSPetter Reinholdtsen
2280c18ec02fSPetter Reinholdtsen while (next_id != 0xffff) {
2281c18ec02fSPetter Reinholdtsen curr_id = next_id;
2282c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "SEL Next ID: %04x", curr_id);
2283c18ec02fSPetter Reinholdtsen
2284c18ec02fSPetter Reinholdtsen next_id = ipmi_sel_get_std_entry(intf, curr_id, &evt);
2285c18ec02fSPetter Reinholdtsen if (next_id == 0) {
2286c18ec02fSPetter Reinholdtsen /*
2287c18ec02fSPetter Reinholdtsen * usually next_id of zero means end but
2288c18ec02fSPetter Reinholdtsen * retry because some hardware has quirks
2289c18ec02fSPetter Reinholdtsen * and will return 0 randomly.
2290c18ec02fSPetter Reinholdtsen */
2291c18ec02fSPetter Reinholdtsen next_id = ipmi_sel_get_std_entry(intf, curr_id, &evt);
2292c18ec02fSPetter Reinholdtsen if (next_id == 0)
2293c18ec02fSPetter Reinholdtsen break;
2294c18ec02fSPetter Reinholdtsen }
2295c18ec02fSPetter Reinholdtsen
2296c18ec02fSPetter Reinholdtsen if (verbose)
2297c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry_verbose(intf, &evt);
2298c18ec02fSPetter Reinholdtsen else
2299c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry(intf, &evt);
2300c18ec02fSPetter Reinholdtsen
2301c18ec02fSPetter Reinholdtsen if (fp != NULL) {
2302c18ec02fSPetter Reinholdtsen if (binary)
2303c18ec02fSPetter Reinholdtsen fwrite(&evt, 1, 16, fp);
2304c18ec02fSPetter Reinholdtsen else
2305c18ec02fSPetter Reinholdtsen ipmi_sel_print_event_file(intf, &evt, fp);
2306c18ec02fSPetter Reinholdtsen }
2307c18ec02fSPetter Reinholdtsen
2308c18ec02fSPetter Reinholdtsen if (++n == count) {
2309c18ec02fSPetter Reinholdtsen break;
2310c18ec02fSPetter Reinholdtsen }
2311c18ec02fSPetter Reinholdtsen }
2312c18ec02fSPetter Reinholdtsen
2313c18ec02fSPetter Reinholdtsen if (fp != NULL)
2314c18ec02fSPetter Reinholdtsen fclose(fp);
2315c18ec02fSPetter Reinholdtsen
2316c18ec02fSPetter Reinholdtsen return 0;
2317c18ec02fSPetter Reinholdtsen }
2318c18ec02fSPetter Reinholdtsen
2319c18ec02fSPetter Reinholdtsen static int
ipmi_sel_list_entries(struct ipmi_intf * intf,int count)2320c18ec02fSPetter Reinholdtsen ipmi_sel_list_entries(struct ipmi_intf * intf, int count)
2321c18ec02fSPetter Reinholdtsen {
2322c18ec02fSPetter Reinholdtsen return __ipmi_sel_savelist_entries(intf, count, NULL, 0);
2323c18ec02fSPetter Reinholdtsen }
2324c18ec02fSPetter Reinholdtsen
2325c18ec02fSPetter Reinholdtsen static int
ipmi_sel_save_entries(struct ipmi_intf * intf,int count,const char * savefile)2326c18ec02fSPetter Reinholdtsen ipmi_sel_save_entries(struct ipmi_intf * intf, int count, const char * savefile)
2327c18ec02fSPetter Reinholdtsen {
2328c18ec02fSPetter Reinholdtsen return __ipmi_sel_savelist_entries(intf, count, savefile, 0);
2329c18ec02fSPetter Reinholdtsen }
2330c18ec02fSPetter Reinholdtsen
2331c18ec02fSPetter Reinholdtsen /*
2332c18ec02fSPetter Reinholdtsen * ipmi_sel_interpret
2333c18ec02fSPetter Reinholdtsen *
2334c18ec02fSPetter Reinholdtsen * return 0 on success,
2335c18ec02fSPetter Reinholdtsen * -1 on error
2336c18ec02fSPetter Reinholdtsen */
2337c18ec02fSPetter Reinholdtsen static int
ipmi_sel_interpret(struct ipmi_intf * intf,unsigned long iana,const char * readfile,const char * format)2338c18ec02fSPetter Reinholdtsen ipmi_sel_interpret(struct ipmi_intf *intf, unsigned long iana,
2339c18ec02fSPetter Reinholdtsen const char *readfile, const char *format)
2340c18ec02fSPetter Reinholdtsen {
2341c18ec02fSPetter Reinholdtsen FILE *fp = 0;
2342c18ec02fSPetter Reinholdtsen struct sel_event_record evt;
2343c18ec02fSPetter Reinholdtsen char *buffer = NULL;
2344c18ec02fSPetter Reinholdtsen char *cursor = NULL;
2345c18ec02fSPetter Reinholdtsen int status = 0;
2346c18ec02fSPetter Reinholdtsen /* since the interface is not used, iana is taken from
2347c18ec02fSPetter Reinholdtsen * the command line
2348c18ec02fSPetter Reinholdtsen */
2349c18ec02fSPetter Reinholdtsen sel_iana = iana;
2350c18ec02fSPetter Reinholdtsen if (strncmp("pps", format, 3) == 0) {
2351c18ec02fSPetter Reinholdtsen /* Parser for the following format */
2352c18ec02fSPetter Reinholdtsen /* 0x001F: Event: at Mar 27 06:41:10 2007;from:(0x9a,0,7);
2353c18ec02fSPetter Reinholdtsen * sensor:(0xc3,119); event:0x6f(asserted): 0xA3 0x00 0x88
2354c18ec02fSPetter Reinholdtsen * commonly found in PPS shelf managers
2355c18ec02fSPetter Reinholdtsen * Supports a tweak for hotswap events that are already interpreted.
2356c18ec02fSPetter Reinholdtsen */
2357c18ec02fSPetter Reinholdtsen fp = ipmi_open_file(readfile, 0);
2358c18ec02fSPetter Reinholdtsen if (fp == NULL) {
2359c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Failed to open file '%s' for reading.",
2360c18ec02fSPetter Reinholdtsen readfile);
2361c18ec02fSPetter Reinholdtsen return (-1);
2362c18ec02fSPetter Reinholdtsen }
2363c18ec02fSPetter Reinholdtsen buffer = (char *)malloc((size_t)256);
2364c18ec02fSPetter Reinholdtsen if (buffer == NULL) {
2365c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: malloc failure");
2366c18ec02fSPetter Reinholdtsen fclose(fp);
2367c18ec02fSPetter Reinholdtsen return (-1);
2368c18ec02fSPetter Reinholdtsen }
2369c18ec02fSPetter Reinholdtsen do {
2370c18ec02fSPetter Reinholdtsen /* Only allow complete lines to be parsed,
2371c18ec02fSPetter Reinholdtsen * hardcoded maximum line length
2372c18ec02fSPetter Reinholdtsen */
2373c18ec02fSPetter Reinholdtsen if (fgets(buffer, 256, fp) == NULL) {
2374c18ec02fSPetter Reinholdtsen status = (-1);
2375c18ec02fSPetter Reinholdtsen break;
2376c18ec02fSPetter Reinholdtsen }
2377c18ec02fSPetter Reinholdtsen if (strlen(buffer) > 255) {
2378c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: invalid entry found in file.");
2379c18ec02fSPetter Reinholdtsen continue;
2380c18ec02fSPetter Reinholdtsen }
2381c18ec02fSPetter Reinholdtsen cursor = buffer;
2382c18ec02fSPetter Reinholdtsen /* assume normal "System" event */
2383c18ec02fSPetter Reinholdtsen evt.record_type = 2;
2384c18ec02fSPetter Reinholdtsen errno = 0;
2385c18ec02fSPetter Reinholdtsen evt.record_id = strtol((const char *)cursor, (char **)NULL, 16);
2386c18ec02fSPetter Reinholdtsen if (errno != 0) {
2387c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid record ID.");
2388c18ec02fSPetter Reinholdtsen status = (-1);
2389c18ec02fSPetter Reinholdtsen break;
2390c18ec02fSPetter Reinholdtsen }
2391c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.evm_rev = 4;
2392c18ec02fSPetter Reinholdtsen
2393c18ec02fSPetter Reinholdtsen /* FIXME: convert*/
2394c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.timestamp;
2395c18ec02fSPetter Reinholdtsen
2396c18ec02fSPetter Reinholdtsen /* skip timestamp */
2397c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, ';');
2398c18ec02fSPetter Reinholdtsen cursor++;
2399c18ec02fSPetter Reinholdtsen
2400c18ec02fSPetter Reinholdtsen /* FIXME: parse originator */
2401c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.gen_id = 0x0020;
2402c18ec02fSPetter Reinholdtsen
2403c18ec02fSPetter Reinholdtsen /* skip originator info */
2404c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, ';');
2405c18ec02fSPetter Reinholdtsen cursor++;
2406c18ec02fSPetter Reinholdtsen
2407c18ec02fSPetter Reinholdtsen /* Get sensor type */
2408c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, '(');
2409c18ec02fSPetter Reinholdtsen cursor++;
2410c18ec02fSPetter Reinholdtsen
2411c18ec02fSPetter Reinholdtsen errno = 0;
2412c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.sensor_type =
2413c18ec02fSPetter Reinholdtsen strtol((const char *)cursor, (char **)NULL, 16);
2414c18ec02fSPetter Reinholdtsen if (errno != 0) {
2415c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Sensor Type.");
2416c18ec02fSPetter Reinholdtsen status = (-1);
2417c18ec02fSPetter Reinholdtsen break;
2418c18ec02fSPetter Reinholdtsen }
2419c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, ',');
2420c18ec02fSPetter Reinholdtsen cursor++;
2421c18ec02fSPetter Reinholdtsen
2422c18ec02fSPetter Reinholdtsen errno = 0;
2423c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.sensor_num =
2424c18ec02fSPetter Reinholdtsen strtol((const char *)cursor, (char **)NULL, 10);
2425c18ec02fSPetter Reinholdtsen if (errno != 0) {
2426c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Sensor Number.");
2427c18ec02fSPetter Reinholdtsen status = (-1);
2428c18ec02fSPetter Reinholdtsen break;
2429c18ec02fSPetter Reinholdtsen }
2430c18ec02fSPetter Reinholdtsen
2431c18ec02fSPetter Reinholdtsen /* skip to event type info */
2432c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, ':');
2433c18ec02fSPetter Reinholdtsen cursor++;
2434c18ec02fSPetter Reinholdtsen
2435c18ec02fSPetter Reinholdtsen errno = 0;
2436c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.event_type=
2437c18ec02fSPetter Reinholdtsen strtol((const char *)cursor, (char **)NULL, 16);
2438c18ec02fSPetter Reinholdtsen if (errno != 0) {
2439c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Event Type.");
2440c18ec02fSPetter Reinholdtsen status = (-1);
2441c18ec02fSPetter Reinholdtsen break;
2442c18ec02fSPetter Reinholdtsen }
2443c18ec02fSPetter Reinholdtsen
2444c18ec02fSPetter Reinholdtsen /* skip to event dir info */
2445c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, '(');
2446c18ec02fSPetter Reinholdtsen cursor++;
2447c18ec02fSPetter Reinholdtsen if (*cursor == 'a') {
2448c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.event_dir = 0;
2449c18ec02fSPetter Reinholdtsen } else {
2450c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.event_dir = 1;
2451c18ec02fSPetter Reinholdtsen }
2452c18ec02fSPetter Reinholdtsen /* skip to data info */
2453c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, ' ');
2454c18ec02fSPetter Reinholdtsen cursor++;
2455c18ec02fSPetter Reinholdtsen
2456c18ec02fSPetter Reinholdtsen if (evt.sel_type.standard_type.sensor_type == 0xF0) {
2457c18ec02fSPetter Reinholdtsen /* got to FRU id */
2458c18ec02fSPetter Reinholdtsen while (!isdigit(*cursor)) {
2459c18ec02fSPetter Reinholdtsen cursor++;
2460c18ec02fSPetter Reinholdtsen }
2461c18ec02fSPetter Reinholdtsen /* store FRUid */
2462c18ec02fSPetter Reinholdtsen errno = 0;
2463c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.event_data[2] =
2464c18ec02fSPetter Reinholdtsen strtol(cursor, (char **)NULL, 10);
2465c18ec02fSPetter Reinholdtsen if (errno != 0) {
2466c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Event Data#2.");
2467c18ec02fSPetter Reinholdtsen status = (-1);
2468c18ec02fSPetter Reinholdtsen break;
2469c18ec02fSPetter Reinholdtsen }
2470c18ec02fSPetter Reinholdtsen
2471c18ec02fSPetter Reinholdtsen /* Get to previous state */
2472c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, 'M');
2473c18ec02fSPetter Reinholdtsen cursor++;
2474c18ec02fSPetter Reinholdtsen
2475c18ec02fSPetter Reinholdtsen /* Set previous state */
2476c18ec02fSPetter Reinholdtsen errno = 0;
2477c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.event_data[1] =
2478c18ec02fSPetter Reinholdtsen strtol(cursor, (char **)NULL, 10);
2479c18ec02fSPetter Reinholdtsen if (errno != 0) {
2480c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Event Data#1.");
2481c18ec02fSPetter Reinholdtsen status = (-1);
2482c18ec02fSPetter Reinholdtsen break;
2483c18ec02fSPetter Reinholdtsen }
2484c18ec02fSPetter Reinholdtsen
2485c18ec02fSPetter Reinholdtsen /* Get to current state */
2486c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, 'M');
2487c18ec02fSPetter Reinholdtsen cursor++;
2488c18ec02fSPetter Reinholdtsen
2489c18ec02fSPetter Reinholdtsen /* Set current state */
2490c18ec02fSPetter Reinholdtsen errno = 0;
2491c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.event_data[0] =
2492c18ec02fSPetter Reinholdtsen 0xA0 | strtol(cursor, (char **)NULL, 10);
2493c18ec02fSPetter Reinholdtsen if (errno != 0) {
2494c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Event Data#0.");
2495c18ec02fSPetter Reinholdtsen status = (-1);
2496c18ec02fSPetter Reinholdtsen break;
2497c18ec02fSPetter Reinholdtsen }
2498c18ec02fSPetter Reinholdtsen
2499c18ec02fSPetter Reinholdtsen /* skip to cause */
2500c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, '=');
2501c18ec02fSPetter Reinholdtsen cursor++;
2502c18ec02fSPetter Reinholdtsen errno = 0;
2503c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.event_data[1] |=
2504c18ec02fSPetter Reinholdtsen (strtol(cursor, (char **)NULL, 16)) << 4;
2505c18ec02fSPetter Reinholdtsen if (errno != 0) {
2506c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Event Data#1.");
2507c18ec02fSPetter Reinholdtsen status = (-1);
2508c18ec02fSPetter Reinholdtsen break;
2509c18ec02fSPetter Reinholdtsen }
2510c18ec02fSPetter Reinholdtsen } else if (*cursor == '0') {
2511c18ec02fSPetter Reinholdtsen errno = 0;
2512c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.event_data[0] =
2513c18ec02fSPetter Reinholdtsen strtol((const char *)cursor, (char **)NULL, 16);
2514c18ec02fSPetter Reinholdtsen if (errno != 0) {
2515c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Event Data#0.");
2516c18ec02fSPetter Reinholdtsen status = (-1);
2517c18ec02fSPetter Reinholdtsen break;
2518c18ec02fSPetter Reinholdtsen }
2519c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, ' ');
2520c18ec02fSPetter Reinholdtsen cursor++;
2521c18ec02fSPetter Reinholdtsen
2522c18ec02fSPetter Reinholdtsen errno = 0;
2523c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.event_data[1] =
2524c18ec02fSPetter Reinholdtsen strtol((const char *)cursor, (char **)NULL, 16);
2525c18ec02fSPetter Reinholdtsen if (errno != 0) {
2526c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Event Data#1.");
2527c18ec02fSPetter Reinholdtsen status = (-1);
2528c18ec02fSPetter Reinholdtsen break;
2529c18ec02fSPetter Reinholdtsen }
2530c18ec02fSPetter Reinholdtsen
2531c18ec02fSPetter Reinholdtsen cursor = index((const char *)cursor, ' ');
2532c18ec02fSPetter Reinholdtsen cursor++;
2533c18ec02fSPetter Reinholdtsen
2534c18ec02fSPetter Reinholdtsen errno = 0;
2535c18ec02fSPetter Reinholdtsen evt.sel_type.standard_type.event_data[2] =
2536c18ec02fSPetter Reinholdtsen strtol((const char *)cursor, (char **)NULL, 16);
2537c18ec02fSPetter Reinholdtsen if (errno != 0) {
2538c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid Event Data#2.");
2539c18ec02fSPetter Reinholdtsen status = (-1);
2540c18ec02fSPetter Reinholdtsen break;
2541c18ec02fSPetter Reinholdtsen }
2542c18ec02fSPetter Reinholdtsen } else {
2543c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: can't guess format.");
2544c18ec02fSPetter Reinholdtsen }
2545c18ec02fSPetter Reinholdtsen /* parse the PPS line into a sel_event_record */
2546c18ec02fSPetter Reinholdtsen if (verbose) {
2547c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry_verbose(intf, &evt);
2548c18ec02fSPetter Reinholdtsen } else {
2549c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry(intf, &evt);
2550c18ec02fSPetter Reinholdtsen }
2551c18ec02fSPetter Reinholdtsen cursor = NULL;
2552c18ec02fSPetter Reinholdtsen } while (status == 0); /* until file is completely read */
2553c18ec02fSPetter Reinholdtsen cursor = NULL;
2554c18ec02fSPetter Reinholdtsen free(buffer);
2555c18ec02fSPetter Reinholdtsen buffer = NULL;
2556c18ec02fSPetter Reinholdtsen fclose(fp);
2557c18ec02fSPetter Reinholdtsen } else {
2558c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Given format '%s' is unknown.", format);
2559c18ec02fSPetter Reinholdtsen status = (-1);
2560c18ec02fSPetter Reinholdtsen }
2561c18ec02fSPetter Reinholdtsen return status;
2562c18ec02fSPetter Reinholdtsen }
2563c18ec02fSPetter Reinholdtsen
2564c18ec02fSPetter Reinholdtsen
2565c18ec02fSPetter Reinholdtsen static int
ipmi_sel_writeraw(struct ipmi_intf * intf,const char * savefile)2566c18ec02fSPetter Reinholdtsen ipmi_sel_writeraw(struct ipmi_intf * intf, const char * savefile)
2567c18ec02fSPetter Reinholdtsen {
2568c18ec02fSPetter Reinholdtsen return __ipmi_sel_savelist_entries(intf, 0, savefile, 1);
2569c18ec02fSPetter Reinholdtsen }
2570c18ec02fSPetter Reinholdtsen
2571c18ec02fSPetter Reinholdtsen
2572c18ec02fSPetter Reinholdtsen static int
ipmi_sel_readraw(struct ipmi_intf * intf,const char * inputfile)2573c18ec02fSPetter Reinholdtsen ipmi_sel_readraw(struct ipmi_intf * intf, const char * inputfile)
2574c18ec02fSPetter Reinholdtsen {
2575c18ec02fSPetter Reinholdtsen struct sel_event_record evt;
2576c18ec02fSPetter Reinholdtsen int ret = 0;
2577c18ec02fSPetter Reinholdtsen FILE* fp = 0;
2578c18ec02fSPetter Reinholdtsen
2579c18ec02fSPetter Reinholdtsen fp = ipmi_open_file(inputfile, 0);
2580c18ec02fSPetter Reinholdtsen if (fp)
2581c18ec02fSPetter Reinholdtsen {
2582c18ec02fSPetter Reinholdtsen size_t bytesRead;
2583c18ec02fSPetter Reinholdtsen
2584c18ec02fSPetter Reinholdtsen do {
2585c18ec02fSPetter Reinholdtsen if ((bytesRead = fread(&evt, 1, 16, fp)) == 16)
2586c18ec02fSPetter Reinholdtsen {
2587c18ec02fSPetter Reinholdtsen if (verbose)
2588c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry_verbose(intf, &evt);
2589c18ec02fSPetter Reinholdtsen else
2590c18ec02fSPetter Reinholdtsen ipmi_sel_print_std_entry(intf, &evt);
2591c18ec02fSPetter Reinholdtsen }
2592c18ec02fSPetter Reinholdtsen else
2593c18ec02fSPetter Reinholdtsen {
2594c18ec02fSPetter Reinholdtsen if (bytesRead != 0)
2595c18ec02fSPetter Reinholdtsen {
2596c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: incomplete record found in file.");
2597c18ec02fSPetter Reinholdtsen ret = -1;
2598c18ec02fSPetter Reinholdtsen }
2599c18ec02fSPetter Reinholdtsen
2600c18ec02fSPetter Reinholdtsen break;
2601c18ec02fSPetter Reinholdtsen }
2602c18ec02fSPetter Reinholdtsen
2603c18ec02fSPetter Reinholdtsen } while (1);
2604c18ec02fSPetter Reinholdtsen fclose(fp);
2605c18ec02fSPetter Reinholdtsen }
2606c18ec02fSPetter Reinholdtsen else
2607c18ec02fSPetter Reinholdtsen {
2608c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: could not open input file.");
2609c18ec02fSPetter Reinholdtsen ret = -1;
2610c18ec02fSPetter Reinholdtsen }
2611c18ec02fSPetter Reinholdtsen return ret;
2612c18ec02fSPetter Reinholdtsen }
2613c18ec02fSPetter Reinholdtsen
2614c18ec02fSPetter Reinholdtsen
2615c18ec02fSPetter Reinholdtsen
2616c18ec02fSPetter Reinholdtsen static uint16_t
ipmi_sel_reserve(struct ipmi_intf * intf)2617c18ec02fSPetter Reinholdtsen ipmi_sel_reserve(struct ipmi_intf * intf)
2618c18ec02fSPetter Reinholdtsen {
2619c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
2620c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
2621c18ec02fSPetter Reinholdtsen
2622c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
2623c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
2624c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_CMD_RESERVE_SEL;
2625c18ec02fSPetter Reinholdtsen
2626c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
2627c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
2628c18ec02fSPetter Reinholdtsen lprintf(LOG_WARN, "Unable to reserve SEL");
2629c18ec02fSPetter Reinholdtsen return 0;
2630c18ec02fSPetter Reinholdtsen }
2631c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
2632c18ec02fSPetter Reinholdtsen printf("Unable to reserve SEL: %s",
2633c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
2634c18ec02fSPetter Reinholdtsen return 0;
2635c18ec02fSPetter Reinholdtsen }
2636c18ec02fSPetter Reinholdtsen
2637c18ec02fSPetter Reinholdtsen return (rsp->data[0] | (rsp->data[1] << 8));
2638c18ec02fSPetter Reinholdtsen }
2639c18ec02fSPetter Reinholdtsen
2640c18ec02fSPetter Reinholdtsen
2641c18ec02fSPetter Reinholdtsen
2642c18ec02fSPetter Reinholdtsen /*
2643c18ec02fSPetter Reinholdtsen * ipmi_sel_get_time
2644c18ec02fSPetter Reinholdtsen *
2645c18ec02fSPetter Reinholdtsen * return 0 on success,
2646c18ec02fSPetter Reinholdtsen * -1 on error
2647c18ec02fSPetter Reinholdtsen */
2648c18ec02fSPetter Reinholdtsen static int
ipmi_sel_get_time(struct ipmi_intf * intf)2649c18ec02fSPetter Reinholdtsen ipmi_sel_get_time(struct ipmi_intf * intf)
2650c18ec02fSPetter Reinholdtsen {
2651c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
2652c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
2653c18ec02fSPetter Reinholdtsen static char tbuf[40];
2654c18ec02fSPetter Reinholdtsen uint32_t timei;
2655c18ec02fSPetter Reinholdtsen time_t time;
2656c18ec02fSPetter Reinholdtsen
2657c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
2658c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
2659c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_GET_SEL_TIME;
2660c18ec02fSPetter Reinholdtsen
2661c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
2662c18ec02fSPetter Reinholdtsen
2663c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
2664c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Time command failed");
2665c18ec02fSPetter Reinholdtsen return -1;
2666c18ec02fSPetter Reinholdtsen }
2667c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
2668c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Time command failed: %s",
2669c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
2670c18ec02fSPetter Reinholdtsen return -1;
2671c18ec02fSPetter Reinholdtsen }
2672c18ec02fSPetter Reinholdtsen if (rsp->data_len != 4) {
2673c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get SEL Time command failed: "
2674c18ec02fSPetter Reinholdtsen "Invalid data length %d", rsp->data_len);
2675c18ec02fSPetter Reinholdtsen return -1;
2676c18ec02fSPetter Reinholdtsen }
2677c18ec02fSPetter Reinholdtsen
2678c18ec02fSPetter Reinholdtsen memcpy(&timei, rsp->data, 4);
2679c18ec02fSPetter Reinholdtsen #if WORDS_BIGENDIAN
2680c18ec02fSPetter Reinholdtsen time = (time_t)(BSWAP_32(timei));
2681c18ec02fSPetter Reinholdtsen #else
2682c18ec02fSPetter Reinholdtsen time = (time_t)timei;
2683c18ec02fSPetter Reinholdtsen #endif
2684c18ec02fSPetter Reinholdtsen
2685c18ec02fSPetter Reinholdtsen strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", gmtime(&time));
2686c18ec02fSPetter Reinholdtsen printf("%s\n", tbuf);
2687c18ec02fSPetter Reinholdtsen
2688c18ec02fSPetter Reinholdtsen return 0;
2689c18ec02fSPetter Reinholdtsen }
2690c18ec02fSPetter Reinholdtsen
2691c18ec02fSPetter Reinholdtsen
2692c18ec02fSPetter Reinholdtsen
2693c18ec02fSPetter Reinholdtsen /*
2694c18ec02fSPetter Reinholdtsen * ipmi_sel_set_time
2695c18ec02fSPetter Reinholdtsen *
2696c18ec02fSPetter Reinholdtsen * return 0 on success,
2697c18ec02fSPetter Reinholdtsen * -1 on error
2698c18ec02fSPetter Reinholdtsen */
2699c18ec02fSPetter Reinholdtsen static int
ipmi_sel_set_time(struct ipmi_intf * intf,const char * time_string)2700c18ec02fSPetter Reinholdtsen ipmi_sel_set_time(struct ipmi_intf * intf, const char * time_string)
2701c18ec02fSPetter Reinholdtsen {
2702c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
2703c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
2704c18ec02fSPetter Reinholdtsen struct tm tm = {0};
2705c18ec02fSPetter Reinholdtsen time_t t;
2706c18ec02fSPetter Reinholdtsen uint32_t timei;
2707c18ec02fSPetter Reinholdtsen const char * time_format = "%m/%d/%Y %H:%M:%S";
2708c18ec02fSPetter Reinholdtsen
2709c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
2710c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
2711c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_SET_SEL_TIME;
2712c18ec02fSPetter Reinholdtsen
2713c18ec02fSPetter Reinholdtsen /* See if user requested set to current client system time */
2714c18ec02fSPetter Reinholdtsen if (strncasecmp(time_string, "now", 3) == 0) {
2715c18ec02fSPetter Reinholdtsen t = time(NULL);
2716c18ec02fSPetter Reinholdtsen }
2717c18ec02fSPetter Reinholdtsen else {
2718c18ec02fSPetter Reinholdtsen /* Now how do we get our time_t from our ascii version? */
2719c18ec02fSPetter Reinholdtsen if (strptime(time_string, time_format, &tm) == 0) {
2720c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Specified time could not be parsed");
2721c18ec02fSPetter Reinholdtsen return -1;
2722c18ec02fSPetter Reinholdtsen }
2723c18ec02fSPetter Reinholdtsen tm.tm_isdst = (-1); /* look up DST information */
2724c18ec02fSPetter Reinholdtsen t = mktime(&tm);
2725c18ec02fSPetter Reinholdtsen if (t < 0) {
2726c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Specified time could not be parsed");
2727c18ec02fSPetter Reinholdtsen return -1;
2728c18ec02fSPetter Reinholdtsen }
2729c18ec02fSPetter Reinholdtsen }
2730c18ec02fSPetter Reinholdtsen
2731c18ec02fSPetter Reinholdtsen {
2732c18ec02fSPetter Reinholdtsen //modify UTC time to local time expressed in number of seconds from 1/1/70 0:0:0 1970 GMT
2733c18ec02fSPetter Reinholdtsen struct tm * tm_tmp = {0};
2734c18ec02fSPetter Reinholdtsen int gt_year,gt_yday,gt_hour,lt_year,lt_yday,lt_hour;
2735c18ec02fSPetter Reinholdtsen int delta_hour;
2736c18ec02fSPetter Reinholdtsen tm_tmp=gmtime(&t);
2737c18ec02fSPetter Reinholdtsen gt_year=tm_tmp->tm_year;
2738c18ec02fSPetter Reinholdtsen gt_yday=tm_tmp->tm_yday;
2739c18ec02fSPetter Reinholdtsen gt_hour=tm_tmp->tm_hour;
2740c18ec02fSPetter Reinholdtsen memset(&*tm_tmp, 0, sizeof(struct tm));
2741c18ec02fSPetter Reinholdtsen tm_tmp=localtime(&t);
2742c18ec02fSPetter Reinholdtsen lt_year=tm_tmp->tm_year;
2743c18ec02fSPetter Reinholdtsen lt_yday=tm_tmp->tm_yday;
2744c18ec02fSPetter Reinholdtsen lt_hour=tm_tmp->tm_hour;
2745c18ec02fSPetter Reinholdtsen delta_hour=lt_hour - gt_hour;
2746c18ec02fSPetter Reinholdtsen if ( (lt_year > gt_year) || ((lt_year == gt_year) && (lt_yday > gt_yday)) )
2747c18ec02fSPetter Reinholdtsen delta_hour += 24;
2748c18ec02fSPetter Reinholdtsen if ( (lt_year < gt_year) || ((lt_year == gt_year) && (lt_yday < gt_yday)) )
2749c18ec02fSPetter Reinholdtsen delta_hour -= 24;
2750c18ec02fSPetter Reinholdtsen
2751c18ec02fSPetter Reinholdtsen t += (delta_hour * 60 * 60);
2752c18ec02fSPetter Reinholdtsen }
2753c18ec02fSPetter Reinholdtsen
2754c18ec02fSPetter Reinholdtsen timei = (uint32_t)t;
2755c18ec02fSPetter Reinholdtsen req.msg.data = (uint8_t *)&timei;
2756c18ec02fSPetter Reinholdtsen req.msg.data_len = 4;
2757c18ec02fSPetter Reinholdtsen
2758c18ec02fSPetter Reinholdtsen #if WORDS_BIGENDIAN
2759c18ec02fSPetter Reinholdtsen timei = BSWAP_32(timei);
2760c18ec02fSPetter Reinholdtsen #endif
2761c18ec02fSPetter Reinholdtsen
2762c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
2763c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
2764c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Set SEL Time command failed");
2765c18ec02fSPetter Reinholdtsen return -1;
2766c18ec02fSPetter Reinholdtsen }
2767c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
2768c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Set SEL Time command failed: %s",
2769c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
2770c18ec02fSPetter Reinholdtsen return -1;
2771c18ec02fSPetter Reinholdtsen }
2772c18ec02fSPetter Reinholdtsen
2773c18ec02fSPetter Reinholdtsen ipmi_sel_get_time(intf);
2774c18ec02fSPetter Reinholdtsen
2775c18ec02fSPetter Reinholdtsen return 0;
2776c18ec02fSPetter Reinholdtsen }
2777c18ec02fSPetter Reinholdtsen
2778c18ec02fSPetter Reinholdtsen
2779c18ec02fSPetter Reinholdtsen
2780c18ec02fSPetter Reinholdtsen static int
ipmi_sel_clear(struct ipmi_intf * intf)2781c18ec02fSPetter Reinholdtsen ipmi_sel_clear(struct ipmi_intf * intf)
2782c18ec02fSPetter Reinholdtsen {
2783c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
2784c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
2785c18ec02fSPetter Reinholdtsen uint16_t reserve_id;
2786c18ec02fSPetter Reinholdtsen uint8_t msg_data[6];
2787c18ec02fSPetter Reinholdtsen
2788c18ec02fSPetter Reinholdtsen reserve_id = ipmi_sel_reserve(intf);
2789c18ec02fSPetter Reinholdtsen if (reserve_id == 0)
2790c18ec02fSPetter Reinholdtsen return -1;
2791c18ec02fSPetter Reinholdtsen
2792c18ec02fSPetter Reinholdtsen memset(msg_data, 0, 6);
2793c18ec02fSPetter Reinholdtsen msg_data[0] = reserve_id & 0xff;
2794c18ec02fSPetter Reinholdtsen msg_data[1] = reserve_id >> 8;
2795c18ec02fSPetter Reinholdtsen msg_data[2] = 'C';
2796c18ec02fSPetter Reinholdtsen msg_data[3] = 'L';
2797c18ec02fSPetter Reinholdtsen msg_data[4] = 'R';
2798c18ec02fSPetter Reinholdtsen msg_data[5] = 0xaa;
2799c18ec02fSPetter Reinholdtsen
2800c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
2801c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
2802c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_CMD_CLEAR_SEL;
2803c18ec02fSPetter Reinholdtsen req.msg.data = msg_data;
2804c18ec02fSPetter Reinholdtsen req.msg.data_len = 6;
2805c18ec02fSPetter Reinholdtsen
2806c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
2807c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
2808c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to clear SEL");
2809c18ec02fSPetter Reinholdtsen return -1;
2810c18ec02fSPetter Reinholdtsen }
2811c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
2812c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to clear SEL: %s",
2813c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
2814c18ec02fSPetter Reinholdtsen return -1;
2815c18ec02fSPetter Reinholdtsen }
2816c18ec02fSPetter Reinholdtsen
2817c18ec02fSPetter Reinholdtsen printf("Clearing SEL. Please allow a few seconds to erase.\n");
2818c18ec02fSPetter Reinholdtsen return 0;
2819c18ec02fSPetter Reinholdtsen }
2820c18ec02fSPetter Reinholdtsen
2821c18ec02fSPetter Reinholdtsen static int
ipmi_sel_delete(struct ipmi_intf * intf,int argc,char ** argv)2822c18ec02fSPetter Reinholdtsen ipmi_sel_delete(struct ipmi_intf * intf, int argc, char ** argv)
2823c18ec02fSPetter Reinholdtsen {
2824c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
2825c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
2826c18ec02fSPetter Reinholdtsen uint16_t id;
2827c18ec02fSPetter Reinholdtsen uint8_t msg_data[4];
2828c18ec02fSPetter Reinholdtsen int rc = 0;
2829c18ec02fSPetter Reinholdtsen
2830c18ec02fSPetter Reinholdtsen if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
2831c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "usage: delete <id>...<id>\n");
2832c18ec02fSPetter Reinholdtsen return -1;
2833c18ec02fSPetter Reinholdtsen }
2834c18ec02fSPetter Reinholdtsen
2835c18ec02fSPetter Reinholdtsen id = ipmi_sel_reserve(intf);
2836c18ec02fSPetter Reinholdtsen if (id == 0)
2837c18ec02fSPetter Reinholdtsen return -1;
2838c18ec02fSPetter Reinholdtsen
2839c18ec02fSPetter Reinholdtsen memset(msg_data, 0, 4);
2840c18ec02fSPetter Reinholdtsen msg_data[0] = id & 0xff;
2841c18ec02fSPetter Reinholdtsen msg_data[1] = id >> 8;
2842c18ec02fSPetter Reinholdtsen
2843c18ec02fSPetter Reinholdtsen for (; argc != 0; argc--)
2844c18ec02fSPetter Reinholdtsen {
2845c18ec02fSPetter Reinholdtsen if (str2ushort(argv[argc-1], &id) != 0) {
2846c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Given SEL ID '%s' is invalid.",
2847c18ec02fSPetter Reinholdtsen argv[argc-1]);
2848c18ec02fSPetter Reinholdtsen rc = (-1);
2849c18ec02fSPetter Reinholdtsen continue;
2850c18ec02fSPetter Reinholdtsen }
2851c18ec02fSPetter Reinholdtsen msg_data[2] = id & 0xff;
2852c18ec02fSPetter Reinholdtsen msg_data[3] = id >> 8;
2853c18ec02fSPetter Reinholdtsen
2854c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
2855c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_STORAGE;
2856c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_CMD_DELETE_SEL_ENTRY;
2857c18ec02fSPetter Reinholdtsen req.msg.data = msg_data;
2858c18ec02fSPetter Reinholdtsen req.msg.data_len = 4;
2859c18ec02fSPetter Reinholdtsen
2860c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
2861c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
2862c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to delete entry %d", id);
2863c18ec02fSPetter Reinholdtsen rc = -1;
2864c18ec02fSPetter Reinholdtsen }
2865c18ec02fSPetter Reinholdtsen else if (rsp->ccode > 0) {
2866c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to delete entry %d: %s", id,
2867c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
2868c18ec02fSPetter Reinholdtsen rc = -1;
2869c18ec02fSPetter Reinholdtsen }
2870c18ec02fSPetter Reinholdtsen else {
2871c18ec02fSPetter Reinholdtsen printf("Deleted entry %d\n", id);
2872c18ec02fSPetter Reinholdtsen }
2873c18ec02fSPetter Reinholdtsen }
2874c18ec02fSPetter Reinholdtsen
2875c18ec02fSPetter Reinholdtsen return rc;
2876c18ec02fSPetter Reinholdtsen }
2877c18ec02fSPetter Reinholdtsen
2878c18ec02fSPetter Reinholdtsen static int
ipmi_sel_show_entry(struct ipmi_intf * intf,int argc,char ** argv)2879c18ec02fSPetter Reinholdtsen ipmi_sel_show_entry(struct ipmi_intf * intf, int argc, char ** argv)
2880c18ec02fSPetter Reinholdtsen {
2881c18ec02fSPetter Reinholdtsen struct entity_id entity;
2882c56458daSZdenek Styblik struct sdr_record_list *entry;
2883c56458daSZdenek Styblik struct sdr_record_list *list;
2884c56458daSZdenek Styblik struct sdr_record_list *sdr;
2885c56458daSZdenek Styblik struct sel_event_record evt;
2886c56458daSZdenek Styblik int i;
2887c56458daSZdenek Styblik int oldv;
2888c18ec02fSPetter Reinholdtsen int rc = 0;
2889c56458daSZdenek Styblik uint16_t id;
2890c18ec02fSPetter Reinholdtsen
2891c18ec02fSPetter Reinholdtsen if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
2892c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "usage: sel get <id>...<id>");
2893c56458daSZdenek Styblik return (-1);
2894c18ec02fSPetter Reinholdtsen }
2895c18ec02fSPetter Reinholdtsen
2896c18ec02fSPetter Reinholdtsen if (ipmi_sel_reserve(intf) == 0) {
2897c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to reserve SEL");
2898c56458daSZdenek Styblik return (-1);
2899c18ec02fSPetter Reinholdtsen }
2900c18ec02fSPetter Reinholdtsen
2901c18ec02fSPetter Reinholdtsen for (i = 0; i < argc; i++) {
2902c18ec02fSPetter Reinholdtsen if (str2ushort(argv[i], &id) != 0) {
2903c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Given SEL ID '%s' is invalid.",
2904c18ec02fSPetter Reinholdtsen argv[i]);
2905c18ec02fSPetter Reinholdtsen rc = (-1);
2906c18ec02fSPetter Reinholdtsen continue;
2907c18ec02fSPetter Reinholdtsen }
2908c18ec02fSPetter Reinholdtsen
2909c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "Looking up SEL entry 0x%x", id);
2910c18ec02fSPetter Reinholdtsen
2911c18ec02fSPetter Reinholdtsen /* lookup SEL entry based on ID */
2912250eb15fSZdenek Styblik if (!ipmi_sel_get_std_entry(intf, id, &evt)) {
2913250eb15fSZdenek Styblik lprintf(LOG_DEBUG, "SEL Entry 0x%x not found.", id);
2914250eb15fSZdenek Styblik rc = (-1);
2915250eb15fSZdenek Styblik continue;
2916250eb15fSZdenek Styblik }
2917c56458daSZdenek Styblik if (evt.sel_type.standard_type.sensor_num == 0
2918c56458daSZdenek Styblik && evt.sel_type.standard_type.sensor_type == 0
2919c56458daSZdenek Styblik && evt.record_type == 0) {
2920c18ec02fSPetter Reinholdtsen lprintf(LOG_WARN, "SEL Entry 0x%x not found", id);
2921c56458daSZdenek Styblik rc = (-1);
2922c18ec02fSPetter Reinholdtsen continue;
2923c18ec02fSPetter Reinholdtsen }
2924c18ec02fSPetter Reinholdtsen
2925c18ec02fSPetter Reinholdtsen /* lookup SDR entry based on sensor number and type */
2926c18ec02fSPetter Reinholdtsen ipmi_sel_print_extended_entry_verbose(intf, &evt);
2927c18ec02fSPetter Reinholdtsen
2928c56458daSZdenek Styblik sdr = ipmi_sdr_find_sdr_bynumtype(intf,
2929c56458daSZdenek Styblik evt.sel_type.standard_type.gen_id,
2930c56458daSZdenek Styblik evt.sel_type.standard_type.sensor_num,
2931c56458daSZdenek Styblik evt.sel_type.standard_type.sensor_type);
2932c18ec02fSPetter Reinholdtsen if (sdr == NULL) {
2933c18ec02fSPetter Reinholdtsen continue;
2934c18ec02fSPetter Reinholdtsen }
2935c18ec02fSPetter Reinholdtsen
2936c18ec02fSPetter Reinholdtsen /* print SDR entry */
2937c18ec02fSPetter Reinholdtsen oldv = verbose;
293848117f5dSZdenek Styblik verbose = verbose ? verbose : 1;
2939c18ec02fSPetter Reinholdtsen switch (sdr->type) {
2940c18ec02fSPetter Reinholdtsen case SDR_RECORD_TYPE_FULL_SENSOR:
2941c18ec02fSPetter Reinholdtsen case SDR_RECORD_TYPE_COMPACT_SENSOR:
2942c18ec02fSPetter Reinholdtsen ipmi_sensor_print_fc(intf, sdr->record.common,
2943c18ec02fSPetter Reinholdtsen sdr->type);
2944c18ec02fSPetter Reinholdtsen entity.id = sdr->record.common->entity.id;
2945c18ec02fSPetter Reinholdtsen entity.instance = sdr->record.common->entity.instance;
2946c18ec02fSPetter Reinholdtsen break;
2947c18ec02fSPetter Reinholdtsen case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
2948c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_eventonly(intf, sdr->record.eventonly);
2949c18ec02fSPetter Reinholdtsen entity.id = sdr->record.eventonly->entity.id;
2950c18ec02fSPetter Reinholdtsen entity.instance = sdr->record.eventonly->entity.instance;
2951c18ec02fSPetter Reinholdtsen break;
2952c18ec02fSPetter Reinholdtsen default:
2953c18ec02fSPetter Reinholdtsen verbose = oldv;
2954c18ec02fSPetter Reinholdtsen continue;
2955c18ec02fSPetter Reinholdtsen }
2956c18ec02fSPetter Reinholdtsen verbose = oldv;
2957c18ec02fSPetter Reinholdtsen
2958c18ec02fSPetter Reinholdtsen /* lookup SDR entry based on entity id */
2959c18ec02fSPetter Reinholdtsen list = ipmi_sdr_find_sdr_byentity(intf, &entity);
2960c18ec02fSPetter Reinholdtsen for (entry=list; entry; entry=entry->next) {
2961c18ec02fSPetter Reinholdtsen /* print FRU devices we find for this entity */
2962c18ec02fSPetter Reinholdtsen if (entry->type == SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR)
2963c18ec02fSPetter Reinholdtsen ipmi_fru_print(intf, entry->record.fruloc);
2964c18ec02fSPetter Reinholdtsen }
2965c18ec02fSPetter Reinholdtsen
2966c56458daSZdenek Styblik if ((argc > 1) && (i < (argc - 1))) {
2967c18ec02fSPetter Reinholdtsen printf("----------------------\n\n");
2968c18ec02fSPetter Reinholdtsen }
2969c56458daSZdenek Styblik }
2970c18ec02fSPetter Reinholdtsen
2971c18ec02fSPetter Reinholdtsen return rc;
2972c18ec02fSPetter Reinholdtsen }
2973c18ec02fSPetter Reinholdtsen
ipmi_sel_main(struct ipmi_intf * intf,int argc,char ** argv)2974c18ec02fSPetter Reinholdtsen int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv)
2975c18ec02fSPetter Reinholdtsen {
2976c18ec02fSPetter Reinholdtsen int rc = 0;
2977c18ec02fSPetter Reinholdtsen
2978c18ec02fSPetter Reinholdtsen if (argc == 0)
2979c18ec02fSPetter Reinholdtsen rc = ipmi_sel_get_info(intf);
2980c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "help", 4) == 0)
2981c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "SEL Commands: "
2982c18ec02fSPetter Reinholdtsen "info clear delete list elist get add time save readraw writeraw interpret");
2983c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "interpret", 9) == 0) {
2984c18ec02fSPetter Reinholdtsen uint32_t iana = 0;
2985c18ec02fSPetter Reinholdtsen if (argc < 4) {
2986c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "usage: sel interpret iana filename format(pps)");
2987c18ec02fSPetter Reinholdtsen return 0;
2988c18ec02fSPetter Reinholdtsen }
2989c18ec02fSPetter Reinholdtsen if (str2uint(argv[1], &iana) != 0) {
2990c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Given IANA '%s' is invalid.",
2991c18ec02fSPetter Reinholdtsen argv[1]);
2992c18ec02fSPetter Reinholdtsen return (-1);
2993c18ec02fSPetter Reinholdtsen }
2994c18ec02fSPetter Reinholdtsen rc = ipmi_sel_interpret(intf, iana, argv[2], argv[3]);
2995c18ec02fSPetter Reinholdtsen }
2996c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "info", 4) == 0)
2997c18ec02fSPetter Reinholdtsen rc = ipmi_sel_get_info(intf);
2998c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "save", 4) == 0) {
2999c18ec02fSPetter Reinholdtsen if (argc < 2) {
3000c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "usage: sel save <filename>");
3001c18ec02fSPetter Reinholdtsen return 0;
3002c18ec02fSPetter Reinholdtsen }
3003c18ec02fSPetter Reinholdtsen rc = ipmi_sel_save_entries(intf, 0, argv[1]);
3004c18ec02fSPetter Reinholdtsen }
3005c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "add", 3) == 0) {
3006c18ec02fSPetter Reinholdtsen if (argc < 2) {
3007c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "usage: sel add <filename>");
3008c18ec02fSPetter Reinholdtsen return 0;
3009c18ec02fSPetter Reinholdtsen }
3010c18ec02fSPetter Reinholdtsen rc = ipmi_sel_add_entries_fromfile(intf, argv[1]);
3011c18ec02fSPetter Reinholdtsen }
3012c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "writeraw", 8) == 0) {
3013c18ec02fSPetter Reinholdtsen if (argc < 2) {
3014c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "usage: sel writeraw <filename>");
3015c18ec02fSPetter Reinholdtsen return 0;
3016c18ec02fSPetter Reinholdtsen }
3017c18ec02fSPetter Reinholdtsen rc = ipmi_sel_writeraw(intf, argv[1]);
3018c18ec02fSPetter Reinholdtsen }
3019c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "readraw", 7) == 0) {
3020c18ec02fSPetter Reinholdtsen if (argc < 2) {
3021c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "usage: sel readraw <filename>");
3022c18ec02fSPetter Reinholdtsen return 0;
3023c18ec02fSPetter Reinholdtsen }
3024c18ec02fSPetter Reinholdtsen rc = ipmi_sel_readraw(intf, argv[1]);
3025c18ec02fSPetter Reinholdtsen }
3026c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "ereadraw", 8) == 0) {
3027c18ec02fSPetter Reinholdtsen if (argc < 2) {
3028c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "usage: sel ereadraw <filename>");
3029c18ec02fSPetter Reinholdtsen return 0;
3030c18ec02fSPetter Reinholdtsen }
3031c18ec02fSPetter Reinholdtsen sel_extended = 1;
3032c18ec02fSPetter Reinholdtsen rc = ipmi_sel_readraw(intf, argv[1]);
3033c18ec02fSPetter Reinholdtsen }
3034c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "list", 4) == 0 ||
3035c18ec02fSPetter Reinholdtsen strncmp(argv[0], "elist", 5) == 0) {
3036c18ec02fSPetter Reinholdtsen /*
3037c18ec02fSPetter Reinholdtsen * Usage:
3038c18ec02fSPetter Reinholdtsen * list - show all SEL entries
3039c18ec02fSPetter Reinholdtsen * list first <n> - show the first (oldest) <n> SEL entries
3040c18ec02fSPetter Reinholdtsen * list last <n> - show the last (newsest) <n> SEL entries
3041c18ec02fSPetter Reinholdtsen */
3042c18ec02fSPetter Reinholdtsen int count = 0;
3043c18ec02fSPetter Reinholdtsen int sign = 1;
3044c18ec02fSPetter Reinholdtsen char *countstr = NULL;
3045c18ec02fSPetter Reinholdtsen
3046c18ec02fSPetter Reinholdtsen if (strncmp(argv[0], "elist", 5) == 0)
3047c18ec02fSPetter Reinholdtsen sel_extended = 1;
3048c18ec02fSPetter Reinholdtsen else
3049c18ec02fSPetter Reinholdtsen sel_extended = 0;
3050c18ec02fSPetter Reinholdtsen
3051c18ec02fSPetter Reinholdtsen if (argc == 2) {
3052c18ec02fSPetter Reinholdtsen countstr = argv[1];
3053c18ec02fSPetter Reinholdtsen }
3054c18ec02fSPetter Reinholdtsen else if (argc == 3) {
3055c18ec02fSPetter Reinholdtsen countstr = argv[2];
3056c18ec02fSPetter Reinholdtsen
3057c18ec02fSPetter Reinholdtsen if (strncmp(argv[1], "last", 4) == 0) {
3058c18ec02fSPetter Reinholdtsen sign = -1;
3059c18ec02fSPetter Reinholdtsen }
3060c18ec02fSPetter Reinholdtsen else if (strncmp(argv[1], "first", 5) != 0) {
3061c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unknown sel list option");
3062c18ec02fSPetter Reinholdtsen return -1;
3063c18ec02fSPetter Reinholdtsen }
3064c18ec02fSPetter Reinholdtsen }
3065c18ec02fSPetter Reinholdtsen
3066c18ec02fSPetter Reinholdtsen if (countstr) {
3067c18ec02fSPetter Reinholdtsen if (str2int(countstr, &count) != 0) {
3068c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Numeric argument required; got '%s'",
3069c18ec02fSPetter Reinholdtsen countstr);
3070c18ec02fSPetter Reinholdtsen return -1;
3071c18ec02fSPetter Reinholdtsen }
3072c18ec02fSPetter Reinholdtsen }
3073c18ec02fSPetter Reinholdtsen count *= sign;
3074c18ec02fSPetter Reinholdtsen
3075c18ec02fSPetter Reinholdtsen rc = ipmi_sel_list_entries(intf,count);
3076c18ec02fSPetter Reinholdtsen }
3077c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "clear", 5) == 0)
3078c18ec02fSPetter Reinholdtsen rc = ipmi_sel_clear(intf);
3079c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "delete", 6) == 0) {
3080c18ec02fSPetter Reinholdtsen if (argc < 2)
3081c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "usage: sel delete <id>...<id>");
3082c18ec02fSPetter Reinholdtsen else
3083c18ec02fSPetter Reinholdtsen rc = ipmi_sel_delete(intf, argc-1, &argv[1]);
3084c18ec02fSPetter Reinholdtsen }
3085c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "get", 3) == 0) {
3086c18ec02fSPetter Reinholdtsen if (argc < 2)
3087c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "usage: sel get <entry>");
3088c18ec02fSPetter Reinholdtsen else
3089c18ec02fSPetter Reinholdtsen rc = ipmi_sel_show_entry(intf, argc-1, &argv[1]);
3090c18ec02fSPetter Reinholdtsen }
3091c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "time", 4) == 0) {
3092c18ec02fSPetter Reinholdtsen if (argc < 2)
3093c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "sel time commands: get set");
3094c18ec02fSPetter Reinholdtsen else if (strncmp(argv[1], "get", 3) == 0)
3095c18ec02fSPetter Reinholdtsen ipmi_sel_get_time(intf);
3096c18ec02fSPetter Reinholdtsen else if (strncmp(argv[1], "set", 3) == 0) {
3097c18ec02fSPetter Reinholdtsen if (argc < 3)
3098c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "usage: sel time set \"mm/dd/yyyy hh:mm:ss\"");
3099c18ec02fSPetter Reinholdtsen else
3100c18ec02fSPetter Reinholdtsen rc = ipmi_sel_set_time(intf, argv[2]);
3101c18ec02fSPetter Reinholdtsen } else {
3102c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "sel time commands: get set");
3103c18ec02fSPetter Reinholdtsen }
3104c18ec02fSPetter Reinholdtsen }
3105c18ec02fSPetter Reinholdtsen else {
3106c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid SEL command: %s", argv[0]);
3107c18ec02fSPetter Reinholdtsen rc = -1;
3108c18ec02fSPetter Reinholdtsen }
3109c18ec02fSPetter Reinholdtsen
3110c18ec02fSPetter Reinholdtsen return rc;
3111c18ec02fSPetter Reinholdtsen }
3112