1c18ec02fSPetter Reinholdtsen /*
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 <stdlib.h>
34c18ec02fSPetter Reinholdtsen #include <string.h>
35c18ec02fSPetter Reinholdtsen #include <stdio.h>
36c18ec02fSPetter Reinholdtsen #include <time.h>
37c18ec02fSPetter Reinholdtsen
38c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
39c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
40c18ec02fSPetter Reinholdtsen #include <ipmitool/bswap.h>
41c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
42c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
43c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_mc.h>
44c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h>
45c18ec02fSPetter Reinholdtsen
46c18ec02fSPetter Reinholdtsen extern int verbose;
47c18ec02fSPetter Reinholdtsen
48c18ec02fSPetter Reinholdtsen static int ipmi_sysinfo_main(struct ipmi_intf *intf, int argc, char ** argv,
49c18ec02fSPetter Reinholdtsen int is_set);
50c18ec02fSPetter Reinholdtsen static void printf_sysinfo_usage(int full_help);
51c18ec02fSPetter Reinholdtsen
52c18ec02fSPetter Reinholdtsen /* ipmi_mc_reset - attempt to reset an MC
53c18ec02fSPetter Reinholdtsen *
54c18ec02fSPetter Reinholdtsen * @intf: ipmi interface
55c18ec02fSPetter Reinholdtsen * @cmd: reset command to send
56c18ec02fSPetter Reinholdtsen * BMC_WARM_RESET or
57c18ec02fSPetter Reinholdtsen * BMC_COLD_RESET
58c18ec02fSPetter Reinholdtsen *
59c18ec02fSPetter Reinholdtsen * returns 0 on success
60c18ec02fSPetter Reinholdtsen * returns -1 on error
61c18ec02fSPetter Reinholdtsen */
62c18ec02fSPetter Reinholdtsen static int
ipmi_mc_reset(struct ipmi_intf * intf,int cmd)63c18ec02fSPetter Reinholdtsen ipmi_mc_reset(struct ipmi_intf * intf, int cmd)
64c18ec02fSPetter Reinholdtsen {
65c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
66c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
67c18ec02fSPetter Reinholdtsen
68c18ec02fSPetter Reinholdtsen if( !intf->opened )
69c18ec02fSPetter Reinholdtsen intf->open(intf);
70c18ec02fSPetter Reinholdtsen
71c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
72c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
73c18ec02fSPetter Reinholdtsen req.msg.cmd = cmd;
74c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
75c18ec02fSPetter Reinholdtsen
76c18ec02fSPetter Reinholdtsen if (cmd == BMC_COLD_RESET)
77c18ec02fSPetter Reinholdtsen intf->noanswer = 1;
78c18ec02fSPetter Reinholdtsen
79c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
80c18ec02fSPetter Reinholdtsen
81c18ec02fSPetter Reinholdtsen if (cmd == BMC_COLD_RESET)
82c18ec02fSPetter Reinholdtsen intf->abort = 1;
83c18ec02fSPetter Reinholdtsen
84c18ec02fSPetter Reinholdtsen if (cmd == BMC_COLD_RESET && rsp == NULL) {
85c18ec02fSPetter Reinholdtsen /* This is expected. See 20.2 Cold Reset Command, p.243, IPMIv2.0 rev1.0 */
86c18ec02fSPetter Reinholdtsen } else if (rsp == NULL) {
87c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "MC reset command failed.");
88c18ec02fSPetter Reinholdtsen return (-1);
89c18ec02fSPetter Reinholdtsen } else if (rsp->ccode > 0) {
90c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "MC reset command failed: %s",
91c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
92c18ec02fSPetter Reinholdtsen return (-1);
93c18ec02fSPetter Reinholdtsen }
94c18ec02fSPetter Reinholdtsen
95c18ec02fSPetter Reinholdtsen printf("Sent %s reset command to MC\n",
96c18ec02fSPetter Reinholdtsen (cmd == BMC_WARM_RESET) ? "warm" : "cold");
97c18ec02fSPetter Reinholdtsen
98c18ec02fSPetter Reinholdtsen return 0;
99c18ec02fSPetter Reinholdtsen }
100c18ec02fSPetter Reinholdtsen
101c18ec02fSPetter Reinholdtsen #ifdef HAVE_PRAGMA_PACK
102c18ec02fSPetter Reinholdtsen #pragma pack(1)
103c18ec02fSPetter Reinholdtsen #endif
104c18ec02fSPetter Reinholdtsen struct bmc_enables_data {
105c18ec02fSPetter Reinholdtsen #if WORDS_BIGENDIAN
106c18ec02fSPetter Reinholdtsen uint8_t oem2 : 1;
107c18ec02fSPetter Reinholdtsen uint8_t oem1 : 1;
108c18ec02fSPetter Reinholdtsen uint8_t oem0 : 1;
109c18ec02fSPetter Reinholdtsen uint8_t __reserved : 1;
110c18ec02fSPetter Reinholdtsen uint8_t system_event_log : 1;
111c18ec02fSPetter Reinholdtsen uint8_t event_msgbuf : 1;
112c18ec02fSPetter Reinholdtsen uint8_t event_msgbuf_intr : 1;
113c18ec02fSPetter Reinholdtsen uint8_t receive_msg_intr : 1;
114c18ec02fSPetter Reinholdtsen #else
115c18ec02fSPetter Reinholdtsen uint8_t receive_msg_intr : 1;
116c18ec02fSPetter Reinholdtsen uint8_t event_msgbuf_intr : 1;
117c18ec02fSPetter Reinholdtsen uint8_t event_msgbuf : 1;
118c18ec02fSPetter Reinholdtsen uint8_t system_event_log : 1;
119c18ec02fSPetter Reinholdtsen uint8_t __reserved : 1;
120c18ec02fSPetter Reinholdtsen uint8_t oem0 : 1;
121c18ec02fSPetter Reinholdtsen uint8_t oem1 : 1;
122c18ec02fSPetter Reinholdtsen uint8_t oem2 : 1;
123c18ec02fSPetter Reinholdtsen #endif
124c18ec02fSPetter Reinholdtsen } ATTRIBUTE_PACKING;
125c18ec02fSPetter Reinholdtsen #ifdef HAVE_PRAGMA_PACK
126c18ec02fSPetter Reinholdtsen #pragma pack(0)
127c18ec02fSPetter Reinholdtsen #endif
128c18ec02fSPetter Reinholdtsen
129c18ec02fSPetter Reinholdtsen struct bitfield_data {
130c18ec02fSPetter Reinholdtsen const char * name;
131c18ec02fSPetter Reinholdtsen const char * desc;
132c18ec02fSPetter Reinholdtsen uint32_t mask;
133*70984dcaSZdenek Styblik } mc_enables_bf[] = {
134c18ec02fSPetter Reinholdtsen {
135*70984dcaSZdenek Styblik .name = "recv_msg_intr",
136*70984dcaSZdenek Styblik .desc = "Receive Message Queue Interrupt",
137*70984dcaSZdenek Styblik .mask = 1<<0,
138c18ec02fSPetter Reinholdtsen },
139c18ec02fSPetter Reinholdtsen {
140*70984dcaSZdenek Styblik .name = "event_msg_intr",
141*70984dcaSZdenek Styblik .desc = "Event Message Buffer Full Interrupt",
142*70984dcaSZdenek Styblik .mask = 1<<1,
143c18ec02fSPetter Reinholdtsen },
144c18ec02fSPetter Reinholdtsen {
145*70984dcaSZdenek Styblik .name = "event_msg",
146*70984dcaSZdenek Styblik .desc = "Event Message Buffer",
147*70984dcaSZdenek Styblik .mask = 1<<2,
148c18ec02fSPetter Reinholdtsen },
149c18ec02fSPetter Reinholdtsen {
150*70984dcaSZdenek Styblik .name = "system_event_log",
151*70984dcaSZdenek Styblik .desc = "System Event Logging",
152*70984dcaSZdenek Styblik .mask = 1<<3,
153c18ec02fSPetter Reinholdtsen },
154c18ec02fSPetter Reinholdtsen {
155*70984dcaSZdenek Styblik .name = "oem0",
156*70984dcaSZdenek Styblik .desc = "OEM 0",
157*70984dcaSZdenek Styblik .mask = 1<<5,
158c18ec02fSPetter Reinholdtsen },
159c18ec02fSPetter Reinholdtsen {
160*70984dcaSZdenek Styblik .name = "oem1",
161*70984dcaSZdenek Styblik .desc = "OEM 1",
162*70984dcaSZdenek Styblik .mask = 1<<6,
163c18ec02fSPetter Reinholdtsen },
164c18ec02fSPetter Reinholdtsen {
165*70984dcaSZdenek Styblik .name = "oem2",
166*70984dcaSZdenek Styblik .desc = "OEM 2",
167*70984dcaSZdenek Styblik .mask = 1<<7,
168c18ec02fSPetter Reinholdtsen },
169c18ec02fSPetter Reinholdtsen { NULL },
170c18ec02fSPetter Reinholdtsen };
171c18ec02fSPetter Reinholdtsen
172c18ec02fSPetter Reinholdtsen static void
printf_mc_reset_usage(void)173c18ec02fSPetter Reinholdtsen printf_mc_reset_usage(void)
174c18ec02fSPetter Reinholdtsen {
175c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "usage: mc reset <warm|cold>");
176c18ec02fSPetter Reinholdtsen } /* printf_mc_reset_usage(void) */
177c18ec02fSPetter Reinholdtsen
178c18ec02fSPetter Reinholdtsen static void
printf_mc_usage(void)179c18ec02fSPetter Reinholdtsen printf_mc_usage(void)
180c18ec02fSPetter Reinholdtsen {
181c18ec02fSPetter Reinholdtsen struct bitfield_data * bf;
182c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "MC Commands:");
183c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " reset <warm|cold>");
184c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " guid");
185c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " info");
186c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " watchdog <get|reset|off>");
187c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " selftest");
188c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " getenables");
189c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " setenables <option=on|off> ...");
190c18ec02fSPetter Reinholdtsen for (bf = mc_enables_bf; bf->name != NULL; bf++) {
191c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " %-20s %s", bf->name, bf->desc);
192c18ec02fSPetter Reinholdtsen }
193c18ec02fSPetter Reinholdtsen printf_sysinfo_usage(0);
194c18ec02fSPetter Reinholdtsen }
195c18ec02fSPetter Reinholdtsen
196c18ec02fSPetter Reinholdtsen static void
printf_sysinfo_usage(int full_help)197c18ec02fSPetter Reinholdtsen printf_sysinfo_usage(int full_help)
198c18ec02fSPetter Reinholdtsen {
199c18ec02fSPetter Reinholdtsen if (full_help != 0)
200c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "usage:");
201c18ec02fSPetter Reinholdtsen
202c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " getsysinfo <argument>");
203c18ec02fSPetter Reinholdtsen
204c18ec02fSPetter Reinholdtsen if (full_help != 0) {
205c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,
206c18ec02fSPetter Reinholdtsen " Retrieves system info from BMC for given argument");
207c18ec02fSPetter Reinholdtsen }
208c18ec02fSPetter Reinholdtsen
209c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " setsysinfo <argument> <string>");
210c18ec02fSPetter Reinholdtsen
211c18ec02fSPetter Reinholdtsen if (full_help != 0) {
212c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,
213c18ec02fSPetter Reinholdtsen " Stores system info string for given argument to BMC");
214c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "");
215c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " Valid arguments are:");
216c18ec02fSPetter Reinholdtsen }
217c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,
218aaf98b89SZdenek Styblik " system_fw_version System firmware (e.g. BIOS) version");
219aaf98b89SZdenek Styblik lprintf(LOG_NOTICE,
220c18ec02fSPetter Reinholdtsen " primary_os_name Primary operating system name");
221c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " os_name Operating system name");
222c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,
223c18ec02fSPetter Reinholdtsen " system_name System Name of server(vendor dependent)");
224c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,
225c18ec02fSPetter Reinholdtsen " delloem_os_version Running version of operating system");
226c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " delloem_url URL of BMC webserver");
227c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "");
228c18ec02fSPetter Reinholdtsen }
229c18ec02fSPetter Reinholdtsen
230c18ec02fSPetter Reinholdtsen static void
print_watchdog_usage(void)231c18ec02fSPetter Reinholdtsen print_watchdog_usage(void)
232c18ec02fSPetter Reinholdtsen {
233c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, "usage: watchdog <command>:");
234c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " get : Get Current Watchdog settings");
235c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " reset : Restart Watchdog timer based on most recent settings");
236c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, " off : Shut off a running Watchdog timer");
237c18ec02fSPetter Reinholdtsen }
238c18ec02fSPetter Reinholdtsen
239c18ec02fSPetter Reinholdtsen /* ipmi_mc_get_enables - print out MC enables
240c18ec02fSPetter Reinholdtsen *
241c18ec02fSPetter Reinholdtsen * @intf: ipmi inteface
242c18ec02fSPetter Reinholdtsen *
243c18ec02fSPetter Reinholdtsen * returns 0 on success
244c18ec02fSPetter Reinholdtsen * returns -1 on error
245c18ec02fSPetter Reinholdtsen */
246c18ec02fSPetter Reinholdtsen static int
ipmi_mc_get_enables(struct ipmi_intf * intf)247c18ec02fSPetter Reinholdtsen ipmi_mc_get_enables(struct ipmi_intf * intf)
248c18ec02fSPetter Reinholdtsen {
249c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
250c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
251c18ec02fSPetter Reinholdtsen struct bitfield_data * bf;
252c18ec02fSPetter Reinholdtsen
253c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
254c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
255c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_GET_GLOBAL_ENABLES;
256c18ec02fSPetter Reinholdtsen
257c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
258c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
259c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Global Enables command failed");
260c18ec02fSPetter Reinholdtsen return -1;
261c18ec02fSPetter Reinholdtsen }
262c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
263c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Global Enables command failed: %s",
264c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
265c18ec02fSPetter Reinholdtsen return -1;
266c18ec02fSPetter Reinholdtsen }
267c18ec02fSPetter Reinholdtsen
268c18ec02fSPetter Reinholdtsen for (bf = mc_enables_bf; bf->name != NULL; bf++) {
269c18ec02fSPetter Reinholdtsen printf("%-40s : %sabled\n", bf->desc,
270c18ec02fSPetter Reinholdtsen rsp->data[0] & bf->mask ? "en" : "dis");
271c18ec02fSPetter Reinholdtsen }
272c18ec02fSPetter Reinholdtsen
273c18ec02fSPetter Reinholdtsen return 0;
274c18ec02fSPetter Reinholdtsen }
275c18ec02fSPetter Reinholdtsen
276c18ec02fSPetter Reinholdtsen /* ipmi_mc_set_enables - set MC enable flags
277c18ec02fSPetter Reinholdtsen *
278c18ec02fSPetter Reinholdtsen * @intf: ipmi inteface
279c18ec02fSPetter Reinholdtsen * @argc: argument count
280c18ec02fSPetter Reinholdtsen * @argv: argument list
281c18ec02fSPetter Reinholdtsen *
282c18ec02fSPetter Reinholdtsen * returns 0 on success
283c18ec02fSPetter Reinholdtsen * returns -1 on error
284c18ec02fSPetter Reinholdtsen */
285c18ec02fSPetter Reinholdtsen static int
ipmi_mc_set_enables(struct ipmi_intf * intf,int argc,char ** argv)286c18ec02fSPetter Reinholdtsen ipmi_mc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
287c18ec02fSPetter Reinholdtsen {
288c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
289c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
290c18ec02fSPetter Reinholdtsen struct bitfield_data * bf;
291c18ec02fSPetter Reinholdtsen uint8_t en;
292c18ec02fSPetter Reinholdtsen int i;
293c18ec02fSPetter Reinholdtsen
294c18ec02fSPetter Reinholdtsen if (argc < 1) {
295c18ec02fSPetter Reinholdtsen printf_mc_usage();
296c18ec02fSPetter Reinholdtsen return (-1);
297c18ec02fSPetter Reinholdtsen }
298c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "help", 4) == 0) {
299c18ec02fSPetter Reinholdtsen printf_mc_usage();
300c18ec02fSPetter Reinholdtsen return 0;
301c18ec02fSPetter Reinholdtsen }
302c18ec02fSPetter Reinholdtsen
303c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
304c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
305c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_GET_GLOBAL_ENABLES;
306c18ec02fSPetter Reinholdtsen
307c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
308c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
309c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Global Enables command failed");
310c18ec02fSPetter Reinholdtsen return -1;
311c18ec02fSPetter Reinholdtsen }
312c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
313c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Global Enables command failed: %s",
314c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
315c18ec02fSPetter Reinholdtsen return -1;
316c18ec02fSPetter Reinholdtsen }
317c18ec02fSPetter Reinholdtsen
318c18ec02fSPetter Reinholdtsen en = rsp->data[0];
319c18ec02fSPetter Reinholdtsen
320c18ec02fSPetter Reinholdtsen for (i = 0; i < argc; i++) {
321c18ec02fSPetter Reinholdtsen for (bf = mc_enables_bf; bf->name != NULL; bf++) {
322c18ec02fSPetter Reinholdtsen int nl = strlen(bf->name);
323c18ec02fSPetter Reinholdtsen if (strncmp(argv[i], bf->name, nl) != 0)
324c18ec02fSPetter Reinholdtsen continue;
325c18ec02fSPetter Reinholdtsen if (strncmp(argv[i]+nl+1, "off", 3) == 0) {
326c18ec02fSPetter Reinholdtsen printf("Disabling %s\n", bf->desc);
327c18ec02fSPetter Reinholdtsen en &= ~bf->mask;
328c18ec02fSPetter Reinholdtsen }
329c18ec02fSPetter Reinholdtsen else if (strncmp(argv[i]+nl+1, "on", 2) == 0) {
330c18ec02fSPetter Reinholdtsen printf("Enabling %s\n", bf->desc);
331c18ec02fSPetter Reinholdtsen en |= bf->mask;
332c18ec02fSPetter Reinholdtsen }
333c18ec02fSPetter Reinholdtsen else {
334c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unrecognized option: %s", argv[i]);
335c18ec02fSPetter Reinholdtsen }
336c18ec02fSPetter Reinholdtsen }
337c18ec02fSPetter Reinholdtsen }
338c18ec02fSPetter Reinholdtsen
339c18ec02fSPetter Reinholdtsen if (en == rsp->data[0]) {
340c18ec02fSPetter Reinholdtsen printf("\nNothing to change...\n");
341c18ec02fSPetter Reinholdtsen ipmi_mc_get_enables(intf);
342c18ec02fSPetter Reinholdtsen return 0;
343c18ec02fSPetter Reinholdtsen }
344c18ec02fSPetter Reinholdtsen
345c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_SET_GLOBAL_ENABLES;
346c18ec02fSPetter Reinholdtsen req.msg.data = &en;
347c18ec02fSPetter Reinholdtsen req.msg.data_len = 1;
348c18ec02fSPetter Reinholdtsen
349c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
350c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
351c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Set Global Enables command failed");
352c18ec02fSPetter Reinholdtsen return -1;
353c18ec02fSPetter Reinholdtsen }
354c18ec02fSPetter Reinholdtsen else if (rsp->ccode > 0) {
355c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Set Global Enables command failed: %s",
356c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
357c18ec02fSPetter Reinholdtsen return -1;
358c18ec02fSPetter Reinholdtsen }
359c18ec02fSPetter Reinholdtsen
360c18ec02fSPetter Reinholdtsen printf("\nVerifying...\n");
361c18ec02fSPetter Reinholdtsen ipmi_mc_get_enables(intf);
362c18ec02fSPetter Reinholdtsen
363c18ec02fSPetter Reinholdtsen return 0;
364c18ec02fSPetter Reinholdtsen }
365c18ec02fSPetter Reinholdtsen
366c18ec02fSPetter Reinholdtsen /* IPM Device, Get Device ID Command - Additional Device Support */
367c18ec02fSPetter Reinholdtsen const char *ipm_dev_adtl_dev_support[8] = {
368c18ec02fSPetter Reinholdtsen "Sensor Device", /* bit 0 */
369c18ec02fSPetter Reinholdtsen "SDR Repository Device", /* bit 1 */
370c18ec02fSPetter Reinholdtsen "SEL Device", /* bit 2 */
371c18ec02fSPetter Reinholdtsen "FRU Inventory Device", /* ... */
372c18ec02fSPetter Reinholdtsen "IPMB Event Receiver",
373c18ec02fSPetter Reinholdtsen "IPMB Event Generator",
374c18ec02fSPetter Reinholdtsen "Bridge",
375c18ec02fSPetter Reinholdtsen "Chassis Device" /* bit 7 */
376c18ec02fSPetter Reinholdtsen };
377c18ec02fSPetter Reinholdtsen
378c18ec02fSPetter Reinholdtsen /* ipmi_mc_get_deviceid - print information about this MC
379c18ec02fSPetter Reinholdtsen *
380c18ec02fSPetter Reinholdtsen * @intf: ipmi interface
381c18ec02fSPetter Reinholdtsen *
382c18ec02fSPetter Reinholdtsen * returns 0 on success
383c18ec02fSPetter Reinholdtsen * returns -1 on error
384c18ec02fSPetter Reinholdtsen */
385c18ec02fSPetter Reinholdtsen static int
ipmi_mc_get_deviceid(struct ipmi_intf * intf)386c18ec02fSPetter Reinholdtsen ipmi_mc_get_deviceid(struct ipmi_intf * intf)
387c18ec02fSPetter Reinholdtsen {
388c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
389c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
390c18ec02fSPetter Reinholdtsen struct ipm_devid_rsp *devid;
391c18ec02fSPetter Reinholdtsen int i;
392c18ec02fSPetter Reinholdtsen const char *product=NULL;
393c18ec02fSPetter Reinholdtsen
394c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
395c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
396c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_GET_DEVICE_ID;
397c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
398c18ec02fSPetter Reinholdtsen
399c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
400c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
401c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Device ID command failed");
402c18ec02fSPetter Reinholdtsen return -1;
403c18ec02fSPetter Reinholdtsen }
404c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
405c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Device ID command failed: %s",
406c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
407c18ec02fSPetter Reinholdtsen return -1;
408c18ec02fSPetter Reinholdtsen }
409c18ec02fSPetter Reinholdtsen
410c18ec02fSPetter Reinholdtsen devid = (struct ipm_devid_rsp *) rsp->data;
411c18ec02fSPetter Reinholdtsen printf("Device ID : %i\n",
412c18ec02fSPetter Reinholdtsen devid->device_id);
413c18ec02fSPetter Reinholdtsen printf("Device Revision : %i\n",
414c18ec02fSPetter Reinholdtsen devid->device_revision & IPM_DEV_DEVICE_ID_REV_MASK);
415c18ec02fSPetter Reinholdtsen printf("Firmware Revision : %u.%02x\n",
416c18ec02fSPetter Reinholdtsen devid->fw_rev1 & IPM_DEV_FWREV1_MAJOR_MASK,
417c18ec02fSPetter Reinholdtsen devid->fw_rev2);
418c18ec02fSPetter Reinholdtsen printf("IPMI Version : %x.%x\n",
419c18ec02fSPetter Reinholdtsen IPM_DEV_IPMI_VERSION_MAJOR(devid->ipmi_version),
420c18ec02fSPetter Reinholdtsen IPM_DEV_IPMI_VERSION_MINOR(devid->ipmi_version));
421c18ec02fSPetter Reinholdtsen printf("Manufacturer ID : %lu\n",
422c18ec02fSPetter Reinholdtsen (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id));
423c18ec02fSPetter Reinholdtsen printf("Manufacturer Name : %s\n",
424c18ec02fSPetter Reinholdtsen val2str( (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id),
425c18ec02fSPetter Reinholdtsen ipmi_oem_info) );
426c18ec02fSPetter Reinholdtsen
427c18ec02fSPetter Reinholdtsen printf("Product ID : %u (0x%02x%02x)\n",
428c18ec02fSPetter Reinholdtsen buf2short((uint8_t *)(devid->product_id)),
429c18ec02fSPetter Reinholdtsen devid->product_id[1], devid->product_id[0]);
430c18ec02fSPetter Reinholdtsen
431c18ec02fSPetter Reinholdtsen product=oemval2str(IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id),
432c18ec02fSPetter Reinholdtsen (devid->product_id[1]<<8)+devid->product_id[0],
433c18ec02fSPetter Reinholdtsen ipmi_oem_product_info);
434c18ec02fSPetter Reinholdtsen
435c18ec02fSPetter Reinholdtsen if (product!=NULL) {
436c18ec02fSPetter Reinholdtsen printf("Product Name : %s\n", product);
437c18ec02fSPetter Reinholdtsen }
438c18ec02fSPetter Reinholdtsen
439c18ec02fSPetter Reinholdtsen printf("Device Available : %s\n",
440c18ec02fSPetter Reinholdtsen (devid->fw_rev1 & IPM_DEV_FWREV1_AVAIL_MASK) ?
441c18ec02fSPetter Reinholdtsen "no" : "yes");
442c18ec02fSPetter Reinholdtsen printf("Provides Device SDRs : %s\n",
443c18ec02fSPetter Reinholdtsen (devid->device_revision & IPM_DEV_DEVICE_ID_SDR_MASK) ?
444c18ec02fSPetter Reinholdtsen "yes" : "no");
445c18ec02fSPetter Reinholdtsen printf("Additional Device Support :\n");
446c18ec02fSPetter Reinholdtsen for (i = 0; i < IPM_DEV_ADTL_SUPPORT_BITS; i++) {
447c18ec02fSPetter Reinholdtsen if (devid->adtl_device_support & (1 << i)) {
448c18ec02fSPetter Reinholdtsen printf(" %s\n", ipm_dev_adtl_dev_support[i]);
449c18ec02fSPetter Reinholdtsen }
450c18ec02fSPetter Reinholdtsen }
451c18ec02fSPetter Reinholdtsen if (rsp->data_len == sizeof(*devid)) {
452c18ec02fSPetter Reinholdtsen printf("Aux Firmware Rev Info : \n");
453c18ec02fSPetter Reinholdtsen /* These values could be looked-up by vendor if documented,
454c18ec02fSPetter Reinholdtsen * so we put them on individual lines for better treatment later
455c18ec02fSPetter Reinholdtsen */
456c18ec02fSPetter Reinholdtsen printf(" 0x%02x\n 0x%02x\n 0x%02x\n 0x%02x\n",
457c18ec02fSPetter Reinholdtsen devid->aux_fw_rev[0],
458c18ec02fSPetter Reinholdtsen devid->aux_fw_rev[1],
459c18ec02fSPetter Reinholdtsen devid->aux_fw_rev[2],
460c18ec02fSPetter Reinholdtsen devid->aux_fw_rev[3]);
461c18ec02fSPetter Reinholdtsen }
462c18ec02fSPetter Reinholdtsen return 0;
463c18ec02fSPetter Reinholdtsen }
464c18ec02fSPetter Reinholdtsen
465c18ec02fSPetter Reinholdtsen /* Structure follow the IPMI V.2 Rev 1.0
466c18ec02fSPetter Reinholdtsen * See Table 20-10 */
467c18ec02fSPetter Reinholdtsen #ifdef HAVE_PRAGMA_PACK
468c18ec02fSPetter Reinholdtsen #pragma pack(1)
469c18ec02fSPetter Reinholdtsen #endif
470c18ec02fSPetter Reinholdtsen
471c18ec02fSPetter Reinholdtsen struct ipmi_guid {
472c18ec02fSPetter Reinholdtsen uint32_t time_low; /* timestamp low field */
473c18ec02fSPetter Reinholdtsen uint16_t time_mid; /* timestamp middle field */
474c18ec02fSPetter Reinholdtsen uint16_t time_hi_and_version; /* timestamp high field and version number */
475c18ec02fSPetter Reinholdtsen uint8_t clock_seq_hi_variant;/* clock sequence high field and variant */
476c18ec02fSPetter Reinholdtsen uint8_t clock_seq_low; /* clock sequence low field */
477c18ec02fSPetter Reinholdtsen uint8_t node[6]; /* node */
478c18ec02fSPetter Reinholdtsen } ATTRIBUTE_PACKING;
479c18ec02fSPetter Reinholdtsen #ifdef HAVE_PRAGMA_PACK
480c18ec02fSPetter Reinholdtsen #pragma pack(0)
481c18ec02fSPetter Reinholdtsen #endif
482c18ec02fSPetter Reinholdtsen
483c18ec02fSPetter Reinholdtsen /* ipmi_mc_get_guid - print this MC GUID
484c18ec02fSPetter Reinholdtsen *
485c18ec02fSPetter Reinholdtsen * @intf: ipmi interface
486c18ec02fSPetter Reinholdtsen *
487c18ec02fSPetter Reinholdtsen * returns 0 on success
488c18ec02fSPetter Reinholdtsen * returns -1 on error
489c18ec02fSPetter Reinholdtsen */
490c18ec02fSPetter Reinholdtsen static int
ipmi_mc_get_guid(struct ipmi_intf * intf)491c18ec02fSPetter Reinholdtsen ipmi_mc_get_guid(struct ipmi_intf * intf)
492c18ec02fSPetter Reinholdtsen {
493c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
494c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
495c18ec02fSPetter Reinholdtsen struct ipmi_guid guid;
496c18ec02fSPetter Reinholdtsen
497c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
498c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
499c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_GET_GUID;
500c18ec02fSPetter Reinholdtsen
501c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
502c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
503c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get GUID command failed");
504c18ec02fSPetter Reinholdtsen return -1;
505c18ec02fSPetter Reinholdtsen }
506c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
507c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get GUID command failed: %s",
508c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
509c18ec02fSPetter Reinholdtsen return -1;
510c18ec02fSPetter Reinholdtsen }
511c18ec02fSPetter Reinholdtsen
512c18ec02fSPetter Reinholdtsen if (rsp->data_len == sizeof(struct ipmi_guid)) {
513c18ec02fSPetter Reinholdtsen char tbuf[40];
514c18ec02fSPetter Reinholdtsen time_t s;
515c18ec02fSPetter Reinholdtsen memset(tbuf, 0, 40);
516c18ec02fSPetter Reinholdtsen memset(&guid, 0, sizeof(struct ipmi_guid));
517c18ec02fSPetter Reinholdtsen memcpy(&guid, rsp->data, rsp->data_len);
518c18ec02fSPetter Reinholdtsen
519c18ec02fSPetter Reinholdtsen /* Kipp - changed order of last field (node) to follow specification */
520c18ec02fSPetter Reinholdtsen printf("System GUID : %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\n",
521c18ec02fSPetter Reinholdtsen guid.time_low, guid.time_mid, guid.time_hi_and_version,
522c18ec02fSPetter Reinholdtsen guid.clock_seq_hi_variant << 8 | guid.clock_seq_low,
523c18ec02fSPetter Reinholdtsen guid.node[0], guid.node[1], guid.node[2],
524c18ec02fSPetter Reinholdtsen guid.node[3], guid.node[4], guid.node[5]);
525c18ec02fSPetter Reinholdtsen
526c18ec02fSPetter Reinholdtsen s = (time_t)guid.time_low; /* Kipp - removed the BSWAP_32, it was not needed here */
527c18ec02fSPetter Reinholdtsen strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", localtime(&s));
528c18ec02fSPetter Reinholdtsen printf("Timestamp : %s\n", tbuf);
529c18ec02fSPetter Reinholdtsen }
530c18ec02fSPetter Reinholdtsen else {
531c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid GUID length %d", rsp->data_len);
532c18ec02fSPetter Reinholdtsen }
533c18ec02fSPetter Reinholdtsen
534c18ec02fSPetter Reinholdtsen return 0;
535c18ec02fSPetter Reinholdtsen }
536c18ec02fSPetter Reinholdtsen
537c18ec02fSPetter Reinholdtsen /* ipmi_mc_get_selftest - returns and print selftest results
538c18ec02fSPetter Reinholdtsen *
539c18ec02fSPetter Reinholdtsen * @intf: ipmi interface
540c18ec02fSPetter Reinholdtsen */
ipmi_mc_get_selftest(struct ipmi_intf * intf)541c18ec02fSPetter Reinholdtsen static int ipmi_mc_get_selftest(struct ipmi_intf * intf)
542c18ec02fSPetter Reinholdtsen {
543c18ec02fSPetter Reinholdtsen int rv = 0;
544c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
545c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
546c18ec02fSPetter Reinholdtsen struct ipm_selftest_rsp *sft_res;
547c18ec02fSPetter Reinholdtsen
548c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
549c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
550c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_GET_SELF_TEST;
551c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
552c18ec02fSPetter Reinholdtsen
553c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
554c18ec02fSPetter Reinholdtsen if (!rsp) {
555c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "No response from devices\n");
556c18ec02fSPetter Reinholdtsen return -1;
557c18ec02fSPetter Reinholdtsen }
558c18ec02fSPetter Reinholdtsen
559c18ec02fSPetter Reinholdtsen if (rsp->ccode) {
560c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Bad response: (%s)",
561c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
562c18ec02fSPetter Reinholdtsen return -1;
563c18ec02fSPetter Reinholdtsen }
564c18ec02fSPetter Reinholdtsen
565c18ec02fSPetter Reinholdtsen sft_res = (struct ipm_selftest_rsp *) rsp->data;
566c18ec02fSPetter Reinholdtsen
567c18ec02fSPetter Reinholdtsen if (sft_res->code == IPM_SFT_CODE_OK) {
568c18ec02fSPetter Reinholdtsen printf("Selftest: passed\n");
569c18ec02fSPetter Reinholdtsen rv = 0;
570c18ec02fSPetter Reinholdtsen }
571c18ec02fSPetter Reinholdtsen
572c18ec02fSPetter Reinholdtsen else if (sft_res->code == IPM_SFT_CODE_NOT_IMPLEMENTED) {
573c18ec02fSPetter Reinholdtsen printf("Selftest: not implemented\n");
574c18ec02fSPetter Reinholdtsen rv = -1;
575c18ec02fSPetter Reinholdtsen }
576c18ec02fSPetter Reinholdtsen
577c18ec02fSPetter Reinholdtsen else if (sft_res->code == IPM_SFT_CODE_DEV_CORRUPTED) {
578c18ec02fSPetter Reinholdtsen printf("Selftest: device corrupted\n");
579c18ec02fSPetter Reinholdtsen rv = -1;
580c18ec02fSPetter Reinholdtsen
581c18ec02fSPetter Reinholdtsen if (sft_res->test & IPM_SELFTEST_SEL_ERROR) {
582c18ec02fSPetter Reinholdtsen printf(" -> SEL device not accessible\n");
583c18ec02fSPetter Reinholdtsen }
584c18ec02fSPetter Reinholdtsen if (sft_res->test & IPM_SELFTEST_SDR_ERROR) {
585c18ec02fSPetter Reinholdtsen printf(" -> SDR repository not accesible\n");
586c18ec02fSPetter Reinholdtsen }
587c18ec02fSPetter Reinholdtsen if (sft_res->test & IPM_SELFTEST_FRU_ERROR) {
588c18ec02fSPetter Reinholdtsen printf("FRU device not accessible\n");
589c18ec02fSPetter Reinholdtsen }
590c18ec02fSPetter Reinholdtsen if (sft_res->test & IPM_SELFTEST_IPMB_ERROR) {
591c18ec02fSPetter Reinholdtsen printf("IPMB signal lines do not respond\n");
592c18ec02fSPetter Reinholdtsen }
593c18ec02fSPetter Reinholdtsen if (sft_res->test & IPM_SELFTEST_SDRR_EMPTY) {
594c18ec02fSPetter Reinholdtsen printf("SDR repository empty\n");
595c18ec02fSPetter Reinholdtsen }
596c18ec02fSPetter Reinholdtsen if (sft_res->test & IPM_SELFTEST_INTERNAL_USE) {
597c18ec02fSPetter Reinholdtsen printf("Internal Use Area corrupted\n");
598c18ec02fSPetter Reinholdtsen }
599c18ec02fSPetter Reinholdtsen if (sft_res->test & IPM_SELFTEST_FW_BOOTBLOCK) {
600c18ec02fSPetter Reinholdtsen printf("Controller update boot block corrupted\n");
601c18ec02fSPetter Reinholdtsen }
602c18ec02fSPetter Reinholdtsen if (sft_res->test & IPM_SELFTEST_FW_CORRUPTED) {
603c18ec02fSPetter Reinholdtsen printf("controller operational firmware corrupted\n");
604c18ec02fSPetter Reinholdtsen }
605c18ec02fSPetter Reinholdtsen }
606c18ec02fSPetter Reinholdtsen
607c18ec02fSPetter Reinholdtsen else if (sft_res->code == IPM_SFT_CODE_FATAL_ERROR) {
608c18ec02fSPetter Reinholdtsen printf("Selftest : fatal error\n");
609c18ec02fSPetter Reinholdtsen printf("Failure code : %02x\n", sft_res->test);
610c18ec02fSPetter Reinholdtsen rv = -1;
611c18ec02fSPetter Reinholdtsen }
612c18ec02fSPetter Reinholdtsen
613c18ec02fSPetter Reinholdtsen else if (sft_res->code == IPM_SFT_CODE_RESERVED) {
614c18ec02fSPetter Reinholdtsen printf("Selftest: N/A");
615c18ec02fSPetter Reinholdtsen rv = -1;
616c18ec02fSPetter Reinholdtsen }
617c18ec02fSPetter Reinholdtsen
618c18ec02fSPetter Reinholdtsen else {
619c18ec02fSPetter Reinholdtsen printf("Selftest : device specific (%02Xh)\n", sft_res->code);
620c18ec02fSPetter Reinholdtsen printf("Failure code : %02Xh\n", sft_res->test);
621c18ec02fSPetter Reinholdtsen rv = 0;
622c18ec02fSPetter Reinholdtsen }
623c18ec02fSPetter Reinholdtsen
624c18ec02fSPetter Reinholdtsen return rv;
625c18ec02fSPetter Reinholdtsen }
626c18ec02fSPetter Reinholdtsen
627c18ec02fSPetter Reinholdtsen /* ipmi_mc_get_watchdog
628c18ec02fSPetter Reinholdtsen *
629c18ec02fSPetter Reinholdtsen * @intf: ipmi interface
630c18ec02fSPetter Reinholdtsen *
631c18ec02fSPetter Reinholdtsen * returns 0 on success
632c18ec02fSPetter Reinholdtsen * returns -1 on error
633c18ec02fSPetter Reinholdtsen */
634c18ec02fSPetter Reinholdtsen
635c18ec02fSPetter Reinholdtsen const char *wdt_use_string[8] = {
636c18ec02fSPetter Reinholdtsen "Reserved",
637c18ec02fSPetter Reinholdtsen "BIOS FRB2",
638c18ec02fSPetter Reinholdtsen "BIOS/POST",
639c18ec02fSPetter Reinholdtsen "OS Load",
640c18ec02fSPetter Reinholdtsen "SMS/OS",
641c18ec02fSPetter Reinholdtsen "OEM",
642c18ec02fSPetter Reinholdtsen "Reserved",
643c18ec02fSPetter Reinholdtsen "Reserved"
644c18ec02fSPetter Reinholdtsen };
645c18ec02fSPetter Reinholdtsen
646c18ec02fSPetter Reinholdtsen const char *wdt_action_string[8] = {
647c18ec02fSPetter Reinholdtsen "No action",
648c18ec02fSPetter Reinholdtsen "Hard Reset",
649c18ec02fSPetter Reinholdtsen "Power Down",
650c18ec02fSPetter Reinholdtsen "Power Cycle",
651c18ec02fSPetter Reinholdtsen "Reserved",
652c18ec02fSPetter Reinholdtsen "Reserved",
653c18ec02fSPetter Reinholdtsen "Reserved",
654c18ec02fSPetter Reinholdtsen "Reserved"
655c18ec02fSPetter Reinholdtsen };
656c18ec02fSPetter Reinholdtsen
657c18ec02fSPetter Reinholdtsen static int
ipmi_mc_get_watchdog(struct ipmi_intf * intf)658c18ec02fSPetter Reinholdtsen ipmi_mc_get_watchdog(struct ipmi_intf * intf)
659c18ec02fSPetter Reinholdtsen {
660c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
661c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
662c18ec02fSPetter Reinholdtsen struct ipm_get_watchdog_rsp * wdt_res;
663c18ec02fSPetter Reinholdtsen
664c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
665c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
666c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_GET_WATCHDOG_TIMER;
667c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
668c18ec02fSPetter Reinholdtsen
669c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
670c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
671c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Watchdog Timer command failed");
672c18ec02fSPetter Reinholdtsen return -1;
673c18ec02fSPetter Reinholdtsen }
674c18ec02fSPetter Reinholdtsen
675c18ec02fSPetter Reinholdtsen if (rsp->ccode) {
676c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Watchdog Timer command failed: %s",
677c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
678c18ec02fSPetter Reinholdtsen return -1;
679c18ec02fSPetter Reinholdtsen }
680c18ec02fSPetter Reinholdtsen
681c18ec02fSPetter Reinholdtsen wdt_res = (struct ipm_get_watchdog_rsp *) rsp->data;
682c18ec02fSPetter Reinholdtsen
683c18ec02fSPetter Reinholdtsen printf("Watchdog Timer Use: %s (0x%02x)\n",
684c18ec02fSPetter Reinholdtsen wdt_use_string[(wdt_res->timer_use & 0x07 )], wdt_res->timer_use);
685c18ec02fSPetter Reinholdtsen printf("Watchdog Timer Is: %s\n",
686c18ec02fSPetter Reinholdtsen wdt_res->timer_use & 0x40 ? "Started/Running" : "Stopped");
687c18ec02fSPetter Reinholdtsen printf("Watchdog Timer Actions: %s (0x%02x)\n",
688c18ec02fSPetter Reinholdtsen wdt_action_string[(wdt_res->timer_actions&0x07)], wdt_res->timer_actions);
689c18ec02fSPetter Reinholdtsen printf("Pre-timeout interval: %d seconds\n", wdt_res->pre_timeout);
690c18ec02fSPetter Reinholdtsen printf("Timer Expiration Flags: 0x%02x\n", wdt_res->timer_use_exp);
691c18ec02fSPetter Reinholdtsen printf("Initial Countdown: %i sec\n",
692c18ec02fSPetter Reinholdtsen ((wdt_res->initial_countdown_msb << 8) | wdt_res->initial_countdown_lsb)/10);
693c18ec02fSPetter Reinholdtsen printf("Present Countdown: %i sec\n",
694c18ec02fSPetter Reinholdtsen (((wdt_res->present_countdown_msb << 8) | wdt_res->present_countdown_lsb)) / 10);
695c18ec02fSPetter Reinholdtsen
696c18ec02fSPetter Reinholdtsen return 0;
697c18ec02fSPetter Reinholdtsen }
698c18ec02fSPetter Reinholdtsen
699c18ec02fSPetter Reinholdtsen /* ipmi_mc_shutoff_watchdog
700c18ec02fSPetter Reinholdtsen *
701c18ec02fSPetter Reinholdtsen * @intf: ipmi interface
702c18ec02fSPetter Reinholdtsen *
703c18ec02fSPetter Reinholdtsen * returns 0 on success
704c18ec02fSPetter Reinholdtsen * returns -1 on error
705c18ec02fSPetter Reinholdtsen */
706c18ec02fSPetter Reinholdtsen static int
ipmi_mc_shutoff_watchdog(struct ipmi_intf * intf)707c18ec02fSPetter Reinholdtsen ipmi_mc_shutoff_watchdog(struct ipmi_intf * intf)
708c18ec02fSPetter Reinholdtsen {
709c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
710c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
711c18ec02fSPetter Reinholdtsen unsigned char msg_data[6];
712c18ec02fSPetter Reinholdtsen
713c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
714c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
715c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_SET_WATCHDOG_TIMER;
716c18ec02fSPetter Reinholdtsen req.msg.data = msg_data;
717c18ec02fSPetter Reinholdtsen req.msg.data_len = 6;
718c18ec02fSPetter Reinholdtsen
719c18ec02fSPetter Reinholdtsen /*
720c18ec02fSPetter Reinholdtsen * The only set cmd we're allowing is to shut off the timer.
721c18ec02fSPetter Reinholdtsen * Turning on the timer should be the job of the ipmi watchdog driver.
722c18ec02fSPetter Reinholdtsen * See 'modinfo ipmi_watchdog' for more info. (NOTE: the reset
723c18ec02fSPetter Reinholdtsen * command will restart the timer if it's already been initialized.)
724c18ec02fSPetter Reinholdtsen *
725c18ec02fSPetter Reinholdtsen * Out-of-band watchdog set commands can still be sent via the raw
726c18ec02fSPetter Reinholdtsen * command interface but this is a very dangerous thing to do since
727c18ec02fSPetter Reinholdtsen * a periodic "poke"/reset over a network is unreliable. This is
728c18ec02fSPetter Reinholdtsen * not a recommended way to use the IPMI watchdog commands.
729c18ec02fSPetter Reinholdtsen */
730c18ec02fSPetter Reinholdtsen
731c18ec02fSPetter Reinholdtsen msg_data[0] = IPM_WATCHDOG_SMS_OS;
732c18ec02fSPetter Reinholdtsen msg_data[1] = IPM_WATCHDOG_NO_ACTION;
733c18ec02fSPetter Reinholdtsen msg_data[2] = 0x00; /* pretimeout interval */
734c18ec02fSPetter Reinholdtsen msg_data[3] = IPM_WATCHDOG_CLEAR_SMS_OS;
735c18ec02fSPetter Reinholdtsen msg_data[4] = 0xb8; /* countdown lsb (100 ms/count) */
736c18ec02fSPetter Reinholdtsen msg_data[5] = 0x0b; /* countdown msb - 5 mins */
737c18ec02fSPetter Reinholdtsen
738c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
739c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
740c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Watchdog Timer Shutoff command failed!");
741c18ec02fSPetter Reinholdtsen return -1;
742c18ec02fSPetter Reinholdtsen }
743c18ec02fSPetter Reinholdtsen
744c18ec02fSPetter Reinholdtsen if (rsp->ccode) {
745c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Watchdog Timer Shutoff command failed! %s",
746c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
747c18ec02fSPetter Reinholdtsen return -1;
748c18ec02fSPetter Reinholdtsen }
749c18ec02fSPetter Reinholdtsen
750c18ec02fSPetter Reinholdtsen printf("Watchdog Timer Shutoff successful -- timer stopped\n");
751c18ec02fSPetter Reinholdtsen return 0;
752c18ec02fSPetter Reinholdtsen }
753c18ec02fSPetter Reinholdtsen
754c18ec02fSPetter Reinholdtsen
755c18ec02fSPetter Reinholdtsen /* ipmi_mc_rst_watchdog
756c18ec02fSPetter Reinholdtsen *
757c18ec02fSPetter Reinholdtsen * @intf: ipmi interface
758c18ec02fSPetter Reinholdtsen *
759c18ec02fSPetter Reinholdtsen * returns 0 on success
760c18ec02fSPetter Reinholdtsen * returns -1 on error
761c18ec02fSPetter Reinholdtsen */
762c18ec02fSPetter Reinholdtsen static int
ipmi_mc_rst_watchdog(struct ipmi_intf * intf)763c18ec02fSPetter Reinholdtsen ipmi_mc_rst_watchdog(struct ipmi_intf * intf)
764c18ec02fSPetter Reinholdtsen {
765c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
766c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
767c18ec02fSPetter Reinholdtsen
768c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
769c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
770c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_RESET_WATCHDOG_TIMER;
771c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
772c18ec02fSPetter Reinholdtsen
773c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
774c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
775c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Reset Watchdog Timer command failed!");
776c18ec02fSPetter Reinholdtsen return -1;
777c18ec02fSPetter Reinholdtsen }
778c18ec02fSPetter Reinholdtsen
779c18ec02fSPetter Reinholdtsen if (rsp->ccode) {
780c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Reset Watchdog Timer command failed: %s",
781c18ec02fSPetter Reinholdtsen (rsp->ccode == IPM_WATCHDOG_RESET_ERROR) ?
782c18ec02fSPetter Reinholdtsen "Attempt to reset unitialized watchdog" :
783c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
784c18ec02fSPetter Reinholdtsen return -1;
785c18ec02fSPetter Reinholdtsen }
786c18ec02fSPetter Reinholdtsen
787c18ec02fSPetter Reinholdtsen printf("IPMI Watchdog Timer Reset - countdown restarted!\n");
788c18ec02fSPetter Reinholdtsen return 0;
789c18ec02fSPetter Reinholdtsen }
790c18ec02fSPetter Reinholdtsen
791c18ec02fSPetter Reinholdtsen /* ipmi_mc_main - top-level handler for MC functions
792c18ec02fSPetter Reinholdtsen *
793c18ec02fSPetter Reinholdtsen * @intf: ipmi interface
794c18ec02fSPetter Reinholdtsen * @argc: number of arguments
795c18ec02fSPetter Reinholdtsen * @argv: argument list
796c18ec02fSPetter Reinholdtsen *
797c18ec02fSPetter Reinholdtsen * returns 0 on success
798c18ec02fSPetter Reinholdtsen * returns -1 on error
799c18ec02fSPetter Reinholdtsen */
800c18ec02fSPetter Reinholdtsen int
ipmi_mc_main(struct ipmi_intf * intf,int argc,char ** argv)801c18ec02fSPetter Reinholdtsen ipmi_mc_main(struct ipmi_intf * intf, int argc, char ** argv)
802c18ec02fSPetter Reinholdtsen {
803c18ec02fSPetter Reinholdtsen int rc = 0;
804c18ec02fSPetter Reinholdtsen
805c18ec02fSPetter Reinholdtsen if (argc < 1) {
806c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Not enough parameters given.");
807c18ec02fSPetter Reinholdtsen printf_mc_usage();
808c18ec02fSPetter Reinholdtsen rc = (-1);
809c18ec02fSPetter Reinholdtsen }
810c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "help", 4) == 0) {
811c18ec02fSPetter Reinholdtsen printf_mc_usage();
812c18ec02fSPetter Reinholdtsen rc = 0;
813c18ec02fSPetter Reinholdtsen }
814c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "reset", 5) == 0) {
815c18ec02fSPetter Reinholdtsen if (argc < 2) {
816c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Not enough parameters given.");
817c18ec02fSPetter Reinholdtsen printf_mc_reset_usage();
818c18ec02fSPetter Reinholdtsen rc = (-1);
819c18ec02fSPetter Reinholdtsen }
820c18ec02fSPetter Reinholdtsen else if (strncmp(argv[1], "help", 4) == 0) {
821c18ec02fSPetter Reinholdtsen printf_mc_reset_usage();
822c18ec02fSPetter Reinholdtsen rc = 0;
823c18ec02fSPetter Reinholdtsen }
824c18ec02fSPetter Reinholdtsen else if (strncmp(argv[1], "cold", 4) == 0) {
825c18ec02fSPetter Reinholdtsen rc = ipmi_mc_reset(intf, BMC_COLD_RESET);
826c18ec02fSPetter Reinholdtsen }
827c18ec02fSPetter Reinholdtsen else if (strncmp(argv[1], "warm", 4) == 0) {
828c18ec02fSPetter Reinholdtsen rc = ipmi_mc_reset(intf, BMC_WARM_RESET);
829c18ec02fSPetter Reinholdtsen }
830c18ec02fSPetter Reinholdtsen else {
831c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid mc/bmc %s command: %s", argv[0], argv[1]);
832c18ec02fSPetter Reinholdtsen printf_mc_reset_usage();
833c18ec02fSPetter Reinholdtsen rc = (-1);
834c18ec02fSPetter Reinholdtsen }
835c18ec02fSPetter Reinholdtsen }
836c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "info", 4) == 0) {
837c18ec02fSPetter Reinholdtsen rc = ipmi_mc_get_deviceid(intf);
838c18ec02fSPetter Reinholdtsen }
839c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "guid", 4) == 0) {
840c18ec02fSPetter Reinholdtsen rc = ipmi_mc_get_guid(intf);
841c18ec02fSPetter Reinholdtsen }
842c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "getenables", 10) == 0) {
843c18ec02fSPetter Reinholdtsen rc = ipmi_mc_get_enables(intf);
844c18ec02fSPetter Reinholdtsen }
845c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "setenables", 10) == 0) {
846c18ec02fSPetter Reinholdtsen rc = ipmi_mc_set_enables(intf, argc-1, &(argv[1]));
847c18ec02fSPetter Reinholdtsen }
848c18ec02fSPetter Reinholdtsen else if (!strncmp(argv[0], "selftest", 8)) {
849c18ec02fSPetter Reinholdtsen rc = ipmi_mc_get_selftest(intf);
850c18ec02fSPetter Reinholdtsen }
851c18ec02fSPetter Reinholdtsen else if (!strncmp(argv[0], "watchdog", 8)) {
852c18ec02fSPetter Reinholdtsen if (argc < 2) {
853c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Not enough parameters given.");
854c18ec02fSPetter Reinholdtsen print_watchdog_usage();
855c18ec02fSPetter Reinholdtsen rc = (-1);
856c18ec02fSPetter Reinholdtsen }
857c18ec02fSPetter Reinholdtsen else if (strncmp(argv[1], "help", 4) == 0) {
858c18ec02fSPetter Reinholdtsen print_watchdog_usage();
859c18ec02fSPetter Reinholdtsen rc = 0;
860c18ec02fSPetter Reinholdtsen }
861c18ec02fSPetter Reinholdtsen else if (strncmp(argv[1], "get", 3) == 0) {
862c18ec02fSPetter Reinholdtsen rc = ipmi_mc_get_watchdog(intf);
863c18ec02fSPetter Reinholdtsen }
864c18ec02fSPetter Reinholdtsen else if(strncmp(argv[1], "off", 3) == 0) {
865c18ec02fSPetter Reinholdtsen rc = ipmi_mc_shutoff_watchdog(intf);
866c18ec02fSPetter Reinholdtsen }
867c18ec02fSPetter Reinholdtsen else if(strncmp(argv[1], "reset", 5) == 0) {
868c18ec02fSPetter Reinholdtsen rc = ipmi_mc_rst_watchdog(intf);
869c18ec02fSPetter Reinholdtsen }
870c18ec02fSPetter Reinholdtsen else {
871c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid mc/bmc %s command: %s", argv[0], argv[1]);
872c18ec02fSPetter Reinholdtsen print_watchdog_usage();
873c18ec02fSPetter Reinholdtsen rc = (-1);
874c18ec02fSPetter Reinholdtsen }
875c18ec02fSPetter Reinholdtsen }
876c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "getsysinfo", 10) == 0) {
877c18ec02fSPetter Reinholdtsen rc = ipmi_sysinfo_main(intf, argc, argv, 0);
878c18ec02fSPetter Reinholdtsen }
879c18ec02fSPetter Reinholdtsen else if (strncmp(argv[0], "setsysinfo", 10) == 0) {
880c18ec02fSPetter Reinholdtsen rc = ipmi_sysinfo_main(intf, argc, argv, 1);
881c18ec02fSPetter Reinholdtsen }
882c18ec02fSPetter Reinholdtsen else {
883c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid mc/bmc command: %s", argv[0]);
884c18ec02fSPetter Reinholdtsen printf_mc_usage();
885c18ec02fSPetter Reinholdtsen rc = (-1);
886c18ec02fSPetter Reinholdtsen }
887c18ec02fSPetter Reinholdtsen return rc;
888c18ec02fSPetter Reinholdtsen }
889c18ec02fSPetter Reinholdtsen
890c18ec02fSPetter Reinholdtsen /*
891c18ec02fSPetter Reinholdtsen * sysinfo_param() - function converts sysinfo param to int
892c18ec02fSPetter Reinholdtsen *
893c18ec02fSPetter Reinholdtsen * @str - user input string
894c18ec02fSPetter Reinholdtsen * @maxset - ?
895c18ec02fSPetter Reinholdtsen *
896c18ec02fSPetter Reinholdtsen * returns (-1) on error
897c18ec02fSPetter Reinholdtsen * returns > 0 on success
898c18ec02fSPetter Reinholdtsen */
899c18ec02fSPetter Reinholdtsen static int
sysinfo_param(const char * str,int * maxset)900c18ec02fSPetter Reinholdtsen sysinfo_param(const char *str, int *maxset)
901c18ec02fSPetter Reinholdtsen {
902c18ec02fSPetter Reinholdtsen if (!str || !maxset)
903c18ec02fSPetter Reinholdtsen return (-1);
904c18ec02fSPetter Reinholdtsen
905c18ec02fSPetter Reinholdtsen *maxset = 4;
906c18ec02fSPetter Reinholdtsen if (!strcmp(str, "system_name"))
907c18ec02fSPetter Reinholdtsen return IPMI_SYSINFO_HOSTNAME;
908c18ec02fSPetter Reinholdtsen else if (!strcmp(str, "primary_os_name"))
909c18ec02fSPetter Reinholdtsen return IPMI_SYSINFO_PRIMARY_OS_NAME;
910c18ec02fSPetter Reinholdtsen else if (!strcmp(str, "os_name"))
911c18ec02fSPetter Reinholdtsen return IPMI_SYSINFO_OS_NAME;
912c18ec02fSPetter Reinholdtsen else if (!strcmp(str, "delloem_os_version"))
913c18ec02fSPetter Reinholdtsen return IPMI_SYSINFO_DELL_OS_VERSION;
914c18ec02fSPetter Reinholdtsen else if (!strcmp(str, "delloem_url")) {
915c18ec02fSPetter Reinholdtsen *maxset = 2;
916c18ec02fSPetter Reinholdtsen return IPMI_SYSINFO_DELL_URL;
917aaf98b89SZdenek Styblik } else if (!strcmp(str, "system_fw_version")) {
918aaf98b89SZdenek Styblik return IPMI_SYSINFO_SYSTEM_FW_VERSION;
919c18ec02fSPetter Reinholdtsen }
920c18ec02fSPetter Reinholdtsen
921c18ec02fSPetter Reinholdtsen return (-1);
922c18ec02fSPetter Reinholdtsen }
923c18ec02fSPetter Reinholdtsen
924c18ec02fSPetter Reinholdtsen /*
925c18ec02fSPetter Reinholdtsen * ipmi_mc_getsysinfo() - function processes the IPMI Get System Info command
926c18ec02fSPetter Reinholdtsen *
927c18ec02fSPetter Reinholdtsen * @intf - ipmi interface
928c18ec02fSPetter Reinholdtsen * @param - parameter eg. 0xC0..0xFF = OEM
929c18ec02fSPetter Reinholdtsen * @block - number of block parameters
930c18ec02fSPetter Reinholdtsen * @set - number of set parameters
931c18ec02fSPetter Reinholdtsen * @len - length of buffer
932c18ec02fSPetter Reinholdtsen * @buffer - pointer to buffer
933c18ec02fSPetter Reinholdtsen *
934c18ec02fSPetter Reinholdtsen * returns (-1) on failure
935c18ec02fSPetter Reinholdtsen * returns 0 on success
936c18ec02fSPetter Reinholdtsen * returns > 0 IPMI code
937c18ec02fSPetter Reinholdtsen */
938c18ec02fSPetter Reinholdtsen int
ipmi_mc_getsysinfo(struct ipmi_intf * intf,int param,int block,int set,int len,void * buffer)939c18ec02fSPetter Reinholdtsen ipmi_mc_getsysinfo(struct ipmi_intf * intf, int param, int block, int set,
940c18ec02fSPetter Reinholdtsen int len, void *buffer)
941c18ec02fSPetter Reinholdtsen {
942c18ec02fSPetter Reinholdtsen uint8_t data[4];
943c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp = NULL;
944c18ec02fSPetter Reinholdtsen struct ipmi_rq req = {0};
945c18ec02fSPetter Reinholdtsen
946c18ec02fSPetter Reinholdtsen memset(buffer, 0, len);
947c18ec02fSPetter Reinholdtsen memset(data, 0, 4);
948c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
949c18ec02fSPetter Reinholdtsen req.msg.lun = 0;
950c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_GET_SYS_INFO;
951c18ec02fSPetter Reinholdtsen req.msg.data_len = 4;
952c18ec02fSPetter Reinholdtsen req.msg.data = data;
953c18ec02fSPetter Reinholdtsen
954c18ec02fSPetter Reinholdtsen if (verbose > 1)
955c18ec02fSPetter Reinholdtsen printf("getsysinfo: %.2x/%.2x/%.2x\n", param, block, set);
956c18ec02fSPetter Reinholdtsen
957c18ec02fSPetter Reinholdtsen data[0] = 0; /* get/set */
958c18ec02fSPetter Reinholdtsen data[1] = param;
959c18ec02fSPetter Reinholdtsen data[2] = block;
960c18ec02fSPetter Reinholdtsen data[3] = set;
961c18ec02fSPetter Reinholdtsen
962c18ec02fSPetter Reinholdtsen /*
963c18ec02fSPetter Reinholdtsen * Format of get output is:
964c18ec02fSPetter Reinholdtsen * u8 param_rev
965c18ec02fSPetter Reinholdtsen * u8 selector
966c18ec02fSPetter Reinholdtsen * u8 encoding bit[0-3];
967c18ec02fSPetter Reinholdtsen * u8 length
968c18ec02fSPetter Reinholdtsen * u8 data0[14]
969c18ec02fSPetter Reinholdtsen */
970c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
971c18ec02fSPetter Reinholdtsen if (rsp == NULL)
972c18ec02fSPetter Reinholdtsen return (-1);
973c18ec02fSPetter Reinholdtsen
974c18ec02fSPetter Reinholdtsen if (rsp->ccode == 0) {
975c18ec02fSPetter Reinholdtsen if (len > rsp->data_len)
976c18ec02fSPetter Reinholdtsen len = rsp->data_len;
977c18ec02fSPetter Reinholdtsen if (len && buffer)
978c18ec02fSPetter Reinholdtsen memcpy(buffer, rsp->data, len);
979c18ec02fSPetter Reinholdtsen }
980c18ec02fSPetter Reinholdtsen return rsp->ccode;
981c18ec02fSPetter Reinholdtsen }
982c18ec02fSPetter Reinholdtsen
983c18ec02fSPetter Reinholdtsen /*
984c18ec02fSPetter Reinholdtsen * ipmi_mc_setsysinfo() - function processes the IPMI Set System Info command
985c18ec02fSPetter Reinholdtsen *
986c18ec02fSPetter Reinholdtsen * @intf - ipmi interface
987c18ec02fSPetter Reinholdtsen * @len - length of buffer
988c18ec02fSPetter Reinholdtsen * @buffer - pointer to buffer
989c18ec02fSPetter Reinholdtsen *
990c18ec02fSPetter Reinholdtsen * returns (-1) on failure
991c18ec02fSPetter Reinholdtsen * returns 0 on success
992c18ec02fSPetter Reinholdtsen * returns > 0 IPMI code
993c18ec02fSPetter Reinholdtsen */
994c18ec02fSPetter Reinholdtsen int
ipmi_mc_setsysinfo(struct ipmi_intf * intf,int len,void * buffer)995c18ec02fSPetter Reinholdtsen ipmi_mc_setsysinfo(struct ipmi_intf * intf, int len, void *buffer)
996c18ec02fSPetter Reinholdtsen {
997c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp = NULL;
998c18ec02fSPetter Reinholdtsen struct ipmi_rq req = {0};
999c18ec02fSPetter Reinholdtsen
1000c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
1001c18ec02fSPetter Reinholdtsen req.msg.lun = 0;
1002c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_SET_SYS_INFO;
1003c18ec02fSPetter Reinholdtsen req.msg.data_len = len;
1004c18ec02fSPetter Reinholdtsen req.msg.data = buffer;
1005c18ec02fSPetter Reinholdtsen
1006c18ec02fSPetter Reinholdtsen /*
1007c18ec02fSPetter Reinholdtsen * Format of set input:
1008c18ec02fSPetter Reinholdtsen * u8 param rev
1009c18ec02fSPetter Reinholdtsen * u8 selector
1010c18ec02fSPetter Reinholdtsen * u8 data1[16]
1011c18ec02fSPetter Reinholdtsen */
1012c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
1013c18ec02fSPetter Reinholdtsen if (rsp != NULL) {
1014c18ec02fSPetter Reinholdtsen return rsp->ccode;
1015c18ec02fSPetter Reinholdtsen }
1016c18ec02fSPetter Reinholdtsen return -1;
1017c18ec02fSPetter Reinholdtsen }
1018c18ec02fSPetter Reinholdtsen
1019c18ec02fSPetter Reinholdtsen static int
ipmi_sysinfo_main(struct ipmi_intf * intf,int argc,char ** argv,int is_set)1020c18ec02fSPetter Reinholdtsen ipmi_sysinfo_main(struct ipmi_intf *intf, int argc, char ** argv, int is_set)
1021c18ec02fSPetter Reinholdtsen {
1022c18ec02fSPetter Reinholdtsen char *str;
1023c18ec02fSPetter Reinholdtsen unsigned char infostr[256];
1024c18ec02fSPetter Reinholdtsen unsigned char paramdata[18];
1025c18ec02fSPetter Reinholdtsen int len, maxset, param, pos, rc, set;
1026c18ec02fSPetter Reinholdtsen
1027c18ec02fSPetter Reinholdtsen if (argc == 2 && strcmp(argv[1], "help") == 0) {
1028c18ec02fSPetter Reinholdtsen printf_sysinfo_usage(1);
1029c18ec02fSPetter Reinholdtsen return 0;
1030c18ec02fSPetter Reinholdtsen }
1031c18ec02fSPetter Reinholdtsen else if (argc < 2 || (is_set == 1 && argc < 3)) {
1032c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Not enough parameters given.");
1033c18ec02fSPetter Reinholdtsen printf_sysinfo_usage(1);
1034c18ec02fSPetter Reinholdtsen return (-1);
1035c18ec02fSPetter Reinholdtsen }
1036c18ec02fSPetter Reinholdtsen
1037c18ec02fSPetter Reinholdtsen /* Get Parameters */
1038c18ec02fSPetter Reinholdtsen if ((param = sysinfo_param(argv[1], &maxset)) < 0) {
1039c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid mc/bmc %s command: %s", argv[0], argv[1]);
1040c18ec02fSPetter Reinholdtsen printf_sysinfo_usage(1);
1041c18ec02fSPetter Reinholdtsen return (-1);
1042c18ec02fSPetter Reinholdtsen }
1043c18ec02fSPetter Reinholdtsen
1044c18ec02fSPetter Reinholdtsen rc = 0;
1045c18ec02fSPetter Reinholdtsen if (is_set != 0) {
1046c18ec02fSPetter Reinholdtsen str = argv[2];
1047c18ec02fSPetter Reinholdtsen set = pos = 0;
1048c18ec02fSPetter Reinholdtsen len = strlen(str);
1049c18ec02fSPetter Reinholdtsen
1050c18ec02fSPetter Reinholdtsen /* first block holds 14 bytes, all others hold 16 */
1051c18ec02fSPetter Reinholdtsen if ((len + 2 + 15) / 16 >= maxset)
1052c18ec02fSPetter Reinholdtsen len = (maxset * 16) - 2;
1053c18ec02fSPetter Reinholdtsen
1054c18ec02fSPetter Reinholdtsen do {
1055c18ec02fSPetter Reinholdtsen memset(paramdata, 0, sizeof(paramdata));
1056c18ec02fSPetter Reinholdtsen paramdata[0] = param;
1057c18ec02fSPetter Reinholdtsen paramdata[1] = set;
1058c18ec02fSPetter Reinholdtsen if (set == 0) {
1059c18ec02fSPetter Reinholdtsen /* First block is special case */
1060c18ec02fSPetter Reinholdtsen paramdata[2] = 0; /* ascii encoding */
1061c18ec02fSPetter Reinholdtsen paramdata[3] = len; /* length */
1062c18ec02fSPetter Reinholdtsen strncpy(paramdata + 4, str + pos, IPMI_SYSINFO_SET0_SIZE);
1063c18ec02fSPetter Reinholdtsen pos += IPMI_SYSINFO_SET0_SIZE;
1064c18ec02fSPetter Reinholdtsen }
1065c18ec02fSPetter Reinholdtsen else {
1066c18ec02fSPetter Reinholdtsen strncpy(paramdata + 2, str + pos, IPMI_SYSINFO_SETN_SIZE);
1067c18ec02fSPetter Reinholdtsen pos += IPMI_SYSINFO_SETN_SIZE;
1068c18ec02fSPetter Reinholdtsen }
1069c18ec02fSPetter Reinholdtsen rc = ipmi_mc_setsysinfo(intf, 18, paramdata);
1070c18ec02fSPetter Reinholdtsen
1071c18ec02fSPetter Reinholdtsen if (rc)
1072c18ec02fSPetter Reinholdtsen break;
1073c18ec02fSPetter Reinholdtsen
1074c18ec02fSPetter Reinholdtsen set++;
1075c18ec02fSPetter Reinholdtsen } while (pos < len);
1076c18ec02fSPetter Reinholdtsen }
1077c18ec02fSPetter Reinholdtsen else {
1078c18ec02fSPetter Reinholdtsen memset(infostr, 0, sizeof(infostr));
1079c18ec02fSPetter Reinholdtsen /* Read blocks of data */
1080c18ec02fSPetter Reinholdtsen pos = 0;
1081c18ec02fSPetter Reinholdtsen for (set = 0; set < maxset; set++) {
1082c18ec02fSPetter Reinholdtsen rc = ipmi_mc_getsysinfo(intf, param, set, 0, 18, paramdata);
1083c18ec02fSPetter Reinholdtsen
1084c18ec02fSPetter Reinholdtsen if (rc)
1085c18ec02fSPetter Reinholdtsen break;
1086c18ec02fSPetter Reinholdtsen
1087c18ec02fSPetter Reinholdtsen if (set == 0) {
1088c18ec02fSPetter Reinholdtsen /* First block is special case */
1089c18ec02fSPetter Reinholdtsen if ((paramdata[2] & 0xF) == 0) {
1090c18ec02fSPetter Reinholdtsen /* Determine max number of blocks to read */
1091c18ec02fSPetter Reinholdtsen maxset = ((paramdata[3] + 2) + 15) / 16;
1092c18ec02fSPetter Reinholdtsen }
1093c18ec02fSPetter Reinholdtsen memcpy(infostr + pos, paramdata + 4, IPMI_SYSINFO_SET0_SIZE);
1094c18ec02fSPetter Reinholdtsen pos += IPMI_SYSINFO_SET0_SIZE;
1095c18ec02fSPetter Reinholdtsen }
1096c18ec02fSPetter Reinholdtsen else {
1097c18ec02fSPetter Reinholdtsen memcpy(infostr + pos, paramdata + 2, IPMI_SYSINFO_SETN_SIZE);
1098c18ec02fSPetter Reinholdtsen pos += IPMI_SYSINFO_SETN_SIZE;
1099c18ec02fSPetter Reinholdtsen }
1100c18ec02fSPetter Reinholdtsen }
1101c18ec02fSPetter Reinholdtsen printf("%s\n", infostr);
1102c18ec02fSPetter Reinholdtsen }
1103c18ec02fSPetter Reinholdtsen if (rc < 0) {
1104c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "%s %s set %d command failed", argv[0], argv[1], set);
1105c18ec02fSPetter Reinholdtsen }
1106c18ec02fSPetter Reinholdtsen else if (rc == 0x80) {
1107c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "%s %s parameter not supported", argv[0], argv[1]);
1108c18ec02fSPetter Reinholdtsen }
1109c18ec02fSPetter Reinholdtsen else if (rc > 0) {
1110c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "%s command failed: %s", argv[0],
1111c18ec02fSPetter Reinholdtsen val2str(rc, completion_code_vals));
1112c18ec02fSPetter Reinholdtsen }
1113c18ec02fSPetter Reinholdtsen return rc;
1114c18ec02fSPetter Reinholdtsen }
1115