~ubuntu-branches/ubuntu/maverick/ipmitool/maverick

« back to all changes in this revision

Viewing changes to lib/ipmi_mc.c

  • Committer: Bazaar Package Importer
  • Author(s): Petter Reinholdtsen
  • Date: 2005-04-07 01:18:44 UTC
  • Revision ID: james.westby@ubuntu.com-20050407011844-a1b206z5iefiu5vi
Tags: upstream-1.8.1
ImportĀ upstreamĀ versionĀ 1.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
 
3
 * 
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions
 
6
 * are met:
 
7
 * 
 
8
 * Redistribution of source code must retain the above copyright
 
9
 * notice, this list of conditions and the following disclaimer.
 
10
 * 
 
11
 * Redistribution in binary form must reproduce the above copyright
 
12
 * notice, this list of conditions and the following disclaimer in the
 
13
 * documentation and/or other materials provided with the distribution.
 
14
 * 
 
15
 * Neither the name of Sun Microsystems, Inc. or the names of
 
16
 * contributors may be used to endorse or promote products derived
 
17
 * from this software without specific prior written permission.
 
18
 * 
 
19
 * This software is provided "AS IS," without a warranty of any kind.
 
20
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 
21
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 
22
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
 
23
 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
 
24
 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 
25
 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
 
26
 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
 
27
 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
 
28
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
 
29
 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
 
30
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 
31
 * 
 
32
 * You acknowledge that this software is not designed or intended for use
 
33
 * in the design, construction, operation or maintenance of any nuclear
 
34
 * facility.
 
35
 */
 
36
 
 
37
#include <stdlib.h>
 
38
#include <string.h>
 
39
#include <stdio.h>
 
40
 
 
41
#include <ipmitool/helper.h>
 
42
#include <ipmitool/log.h>
 
43
#include <ipmitool/ipmi.h>
 
44
#include <ipmitool/ipmi_intf.h>
 
45
#include <ipmitool/ipmi_mc.h>
 
46
#include <ipmitool/ipmi_strings.h>
 
47
 
 
48
extern int verbose;
 
49
 
 
50
/* ipmi_mc_reset  -  attempt to reset an MC
 
51
 *
 
52
 * @intf:       ipmi interface
 
53
 * @cmd:        reset command to send
 
54
 *              BMC_WARM_RESET or
 
55
 *              BMC_COLD_RESET
 
56
 *
 
57
 * returns 0 on success
 
58
 * returns -1 on error
 
59
 */
 
60
static int
 
61
ipmi_mc_reset(struct ipmi_intf * intf, int cmd)
 
62
{
 
63
        struct ipmi_rs * rsp;
 
64
        struct ipmi_rq req;
 
65
 
 
66
        memset(&req, 0, sizeof(req));
 
67
        req.msg.netfn = IPMI_NETFN_APP;
 
68
        req.msg.cmd = cmd;
 
69
        req.msg.data_len = 0;
 
70
 
 
71
        rsp = intf->sendrecv(intf, &req);
 
72
        if (rsp == NULL) {
 
73
                lprintf(LOG_ERR, "Reset command failed");
 
74
                return -1;
 
75
        }
 
76
        if (rsp->ccode > 0) {
 
77
                lprintf(LOG_ERR, "Reset command failed: %s",
 
78
                        val2str(rsp->ccode, completion_code_vals));
 
79
                return -1;
 
80
        }
 
81
 
 
82
        return 0;
 
83
}
 
84
 
 
85
struct bmc_enables_data {
 
86
#if WORDS_BIGENDIAN
 
87
        uint8_t oem2            : 1;
 
88
        uint8_t oem1            : 1;
 
89
        uint8_t oem0            : 1;
 
90
        uint8_t __reserved      : 1;
 
91
        uint8_t system_event_log        : 1;
 
92
        uint8_t event_msgbuf    : 1;
 
93
        uint8_t event_msgbuf_intr       : 1;
 
94
        uint8_t receive_msg_intr        : 1;
 
95
#else
 
96
        uint8_t receive_msg_intr        : 1;
 
97
        uint8_t event_msgbuf_intr       : 1;
 
98
        uint8_t event_msgbuf    : 1;
 
99
        uint8_t system_event_log        : 1;
 
100
        uint8_t __reserved      : 1;
 
101
        uint8_t oem0            : 1;
 
102
        uint8_t oem1            : 1;
 
103
        uint8_t oem2            : 1;
 
104
#endif
 
105
} __attribute__ ((packed));
 
106
 
 
107
struct bitfield_data {
 
108
        const char * name;
 
109
        const char * desc;
 
110
        uint32_t mask;
 
111
};
 
112
 
 
113
struct bitfield_data mc_enables_bf[] = {
 
114
        {
 
115
                name:   "recv_msg_intr",
 
116
                desc:   "Receive Message Queue Interrupt",
 
117
                mask:   1<<0,
 
118
        },
 
119
        {
 
120
                name:   "event_msg_intr",
 
121
                desc:   "Event Message Buffer Full Interrupt",
 
122
                mask:   1<<1,
 
123
        },
 
124
        {
 
125
                name:   "event_msg",
 
126
                desc:   "Event Message Buffer",
 
127
                mask:   1<<2,
 
128
        },
 
129
        {
 
130
                name:   "system_event_log",
 
131
                desc:   "System Event Logging",
 
132
                mask:   1<<3,
 
133
        },
 
134
        {
 
135
                name:   "oem0",
 
136
                desc:   "OEM 0",
 
137
                mask:   1<<5,
 
138
        },
 
139
        {
 
140
                name:   "oem1",
 
141
                desc:   "OEM 1",
 
142
                mask:   1<<6,
 
143
        },
 
144
        {
 
145
                name:   "oem2",
 
146
                desc:   "OEM 2",
 
147
                mask:   1<<7,
 
148
        },
 
149
        { NULL },
 
150
};
 
151
 
 
152
static void
 
153
printf_mc_usage()
 
154
{
 
155
        struct bitfield_data * bf;
 
156
        printf("MC Commands:\n");
 
157
        printf("  reset <warm|cold>\n");
 
158
        printf("  info\n");
 
159
        printf("  getenables\n");
 
160
        printf("  setenables <option=on|off> ...\n");
 
161
 
 
162
        for (bf = mc_enables_bf; bf->name != NULL; bf++) {
 
163
                printf("    %-20s  %s\n", bf->name, bf->desc);
 
164
        }
 
165
}
 
166
 
 
167
/* ipmi_mc_get_enables  -  print out MC enables
 
168
 *
 
169
 * @intf:       ipmi inteface
 
170
 *
 
171
 * returns 0 on success
 
172
 * returns -1 on error
 
173
 */
 
174
static int
 
175
ipmi_mc_get_enables(struct ipmi_intf * intf)
 
176
{
 
177
        struct ipmi_rs * rsp;
 
178
        struct ipmi_rq req;
 
179
        struct bitfield_data * bf;
 
180
 
 
181
        memset(&req, 0, sizeof(req));
 
182
        req.msg.netfn = IPMI_NETFN_APP;
 
183
        req.msg.cmd = BMC_GET_GLOBAL_ENABLES;
 
184
 
 
185
        rsp = intf->sendrecv(intf, &req);
 
186
        if (rsp == NULL) {
 
187
                lprintf(LOG_ERR, "Get Global Enables command failed");
 
188
                return -1;
 
189
        }
 
190
        if (rsp->ccode > 0) {
 
191
                lprintf(LOG_ERR, "Get Global Enables command failed: %s",
 
192
                       val2str(rsp->ccode, completion_code_vals));
 
193
                return -1;
 
194
        }
 
195
 
 
196
        for (bf = mc_enables_bf; bf->name != NULL; bf++) {
 
197
                printf("%-40s : %sabled\n", bf->desc,
 
198
                       rsp->data[0] & bf->mask ? "en" : "dis");
 
199
        }
 
200
 
 
201
        return 0;
 
202
}
 
203
 
 
204
/* ipmi_mc_set_enables  -  set MC enable flags
 
205
 *
 
206
 * @intf:       ipmi inteface
 
207
 * @argc:       argument count
 
208
 * @argv:       argument list
 
209
 *
 
210
 * returns 0 on success
 
211
 * returns -1 on error
 
212
 */
 
213
static int
 
214
ipmi_mc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
 
215
{
 
216
        struct ipmi_rs * rsp;
 
217
        struct ipmi_rq req;
 
218
        struct bitfield_data * bf;
 
219
        uint8_t en;
 
220
        int i;
 
221
 
 
222
        if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
 
223
                printf_mc_usage();
 
224
                return 0;
 
225
        }
 
226
 
 
227
        memset(&req, 0, sizeof(req));
 
228
        req.msg.netfn = IPMI_NETFN_APP;
 
229
        req.msg.cmd = BMC_GET_GLOBAL_ENABLES;
 
230
 
 
231
        rsp = intf->sendrecv(intf, &req);
 
232
        if (rsp == NULL) {
 
233
                lprintf(LOG_ERR, "Get Global Enables command failed");
 
234
                return -1;
 
235
        }
 
236
        if (rsp->ccode > 0) {
 
237
                lprintf(LOG_ERR, "Get Global Enables command failed: %s",
 
238
                       val2str(rsp->ccode, completion_code_vals));
 
239
                return -1;
 
240
        }
 
241
 
 
242
        en = rsp->data[0];
 
243
 
 
244
        for (i = 0; i < argc; i++) {
 
245
                for (bf = mc_enables_bf; bf->name != NULL; bf++) {
 
246
                        int nl = strlen(bf->name);
 
247
                        if (strncmp(argv[i], bf->name, nl) != 0)
 
248
                                continue;
 
249
                        if (strncmp(argv[i]+nl+1, "off", 3) == 0) {
 
250
                                printf("Disabling %s\n", bf->desc);
 
251
                                en &= ~bf->mask;
 
252
                        }
 
253
                        else if (strncmp(argv[i]+nl+1, "on", 2) == 0) {
 
254
                                printf("Enabling %s\n", bf->desc);
 
255
                                en |= bf->mask;
 
256
                        }
 
257
                        else {
 
258
                                lprintf(LOG_ERR, "Unrecognized option: %s", argv[i]);
 
259
                        }
 
260
                }
 
261
        }
 
262
 
 
263
        if (en == rsp->data[0]) {
 
264
                printf("\nNothing to change...\n");
 
265
                ipmi_mc_get_enables(intf);
 
266
                return 0;
 
267
        }
 
268
 
 
269
        req.msg.cmd = BMC_SET_GLOBAL_ENABLES;
 
270
        req.msg.data = &en;
 
271
        req.msg.data_len = 1;
 
272
 
 
273
        rsp = intf->sendrecv(intf, &req);
 
274
        if (rsp == NULL) {
 
275
                lprintf(LOG_ERR, "Set Global Enables command failed");
 
276
                return -1;
 
277
        }
 
278
        else if (rsp->ccode > 0) {
 
279
                lprintf(LOG_ERR, "Set Global Enables command failed: %s",
 
280
                        val2str(rsp->ccode, completion_code_vals));
 
281
                return -1;
 
282
        }
 
283
 
 
284
        printf("\nVerifying...\n");
 
285
        ipmi_mc_get_enables(intf);
 
286
 
 
287
        return 0;
 
288
}
 
289
 
 
290
/* IPM Device, Get Device ID Command - Additional Device Support */
 
291
const char *ipm_dev_adtl_dev_support[8] = {
 
292
        "Sensor Device",         /* bit 0 */
 
293
        "SDR Repository Device", /* bit 1 */
 
294
        "SEL Device",            /* bit 2 */
 
295
        "FRU Inventory Device",  /*  ...  */
 
296
        "IPMB Event Receiver",
 
297
        "IPMB Event Generator",
 
298
        "Bridge",
 
299
        "Chassis Device"         /* bit 7 */
 
300
};
 
301
 
 
302
/* ipmi_mc_get_deviceid  -  print information about this MC
 
303
 *
 
304
 * @intf:       ipmi interface
 
305
 *
 
306
 * returns 0 on success
 
307
 * returns -1 on error
 
308
 */
 
309
static int
 
310
ipmi_mc_get_deviceid(struct ipmi_intf * intf)
 
311
{
 
312
        struct ipmi_rs * rsp;
 
313
        struct ipmi_rq req;
 
314
        struct ipm_devid_rsp *devid;
 
315
        int i;
 
316
 
 
317
        memset(&req, 0, sizeof(req));
 
318
        req.msg.netfn = IPMI_NETFN_APP;
 
319
        req.msg.cmd = BMC_GET_DEVICE_ID;
 
320
        req.msg.data_len = 0;
 
321
 
 
322
        rsp = intf->sendrecv(intf, &req);
 
323
        if (rsp == NULL) {
 
324
                lprintf(LOG_ERR, "Get Device ID command failed");
 
325
                return -1;
 
326
        }
 
327
        if (rsp->ccode > 0) {
 
328
                lprintf(LOG_ERR, "Get Device ID command failed: %s",
 
329
                        val2str(rsp->ccode, completion_code_vals));
 
330
                return -1;
 
331
        }
 
332
 
 
333
        devid = (struct ipm_devid_rsp *) rsp->data;
 
334
        printf("Device ID                 : %i\n", 
 
335
                devid->device_id);
 
336
        printf("Device Revision           : %i\n",
 
337
                devid->device_revision & IPM_DEV_DEVICE_ID_REV_MASK);
 
338
        printf("Firmware Revision         : %u.%x\n",
 
339
                devid->fw_rev1 & IPM_DEV_FWREV1_MAJOR_MASK,
 
340
                devid->fw_rev2);
 
341
        printf("IPMI Version              : %x.%x\n",
 
342
                IPM_DEV_IPMI_VERSION_MAJOR(devid->ipmi_version),
 
343
                IPM_DEV_IPMI_VERSION_MINOR(devid->ipmi_version));
 
344
        printf("Manufacturer ID           : %lu\n",
 
345
                (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id));
 
346
        printf("Product ID                : %u (0x%02x%02x)\n",
 
347
                buf2short((uint8_t *)(devid->product_id)),
 
348
                devid->product_id[1], devid->product_id[0]);
 
349
        printf("Device Available          : %s\n",
 
350
                (devid->fw_rev1 & IPM_DEV_FWREV1_AVAIL_MASK) ? 
 
351
                "no" : "yes");
 
352
        printf("Provides Device SDRs      : %s\n",
 
353
                (devid->device_revision & IPM_DEV_DEVICE_ID_SDR_MASK) ?
 
354
                "yes" : "no");
 
355
        printf("Additional Device Support :\n");
 
356
        for (i = 0; i < IPM_DEV_ADTL_SUPPORT_BITS; i++) {
 
357
                if (devid->adtl_device_support & (1 << i)) {
 
358
                        printf("    %s\n", ipm_dev_adtl_dev_support[i]);
 
359
                }
 
360
        }
 
361
        printf("Aux Firmware Rev Info     : \n");
 
362
        /* These values could be looked-up by vendor if documented,
 
363
         * so we put them on individual lines for better treatment later
 
364
         */
 
365
        printf("    0x%02x\n    0x%02x\n    0x%02x\n    0x%02x\n",
 
366
                devid->aux_fw_rev[0], devid->aux_fw_rev[1],
 
367
                devid->aux_fw_rev[2], devid->aux_fw_rev[3]);
 
368
        return 0;
 
369
}
 
370
 
 
371
/* ipmi_mc_get_guid  -  print this MC GUID
 
372
 *
 
373
 * @intf:       ipmi interface
 
374
 *
 
375
 * returns 0 on success
 
376
 * returns -1 on error
 
377
 */
 
378
static int
 
379
ipmi_mc_get_guid(struct ipmi_intf * intf)
 
380
{
 
381
        struct ipmi_rs * rsp;
 
382
        struct ipmi_rq req;
 
383
 
 
384
        memset(&req, 0, sizeof(req));
 
385
        req.msg.netfn = IPMI_NETFN_APP;
 
386
        req.msg.cmd = BMC_GET_GUID;
 
387
 
 
388
        rsp = intf->sendrecv(intf, &req);
 
389
        if (rsp == NULL) {
 
390
                lprintf(LOG_ERR, "Get GUID command failed");
 
391
                return -1;
 
392
        }
 
393
        if (rsp->ccode > 0) {
 
394
                lprintf(LOG_ERR, "Get GUID command failed: %s",
 
395
                        val2str(rsp->ccode, completion_code_vals));
 
396
                return -1;
 
397
        }
 
398
 
 
399
        printf("System GUID: %s\n", buf2str(rsp->data, rsp->data_len));
 
400
 
 
401
        return 0;
 
402
}
 
403
 
 
404
/* ipmi_mc_main  -  top-level handler for MC functions
 
405
 *
 
406
 * @intf:       ipmi interface
 
407
 * @argc:       number of arguments
 
408
 * @argv:       argument list
 
409
 *
 
410
 * returns 0 on success
 
411
 * returns -1 on error
 
412
 */
 
413
int
 
414
ipmi_mc_main(struct ipmi_intf * intf, int argc, char ** argv)
 
415
{
 
416
        int rc = 0;
 
417
 
 
418
        if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
 
419
                printf_mc_usage();
 
420
        }
 
421
        else if (strncmp(argv[0], "reset", 5) == 0) {
 
422
                if (argc < 2 || strncmp(argv[1], "help", 4) == 0) {
 
423
                        lprintf(LOG_ERR, "reset commands: warm, cold");
 
424
                }
 
425
                else if (strncmp(argv[1], "cold", 4) == 0) {
 
426
                        rc = ipmi_mc_reset(intf, BMC_COLD_RESET);
 
427
                }
 
428
                else if (strncmp(argv[1], "warm", 4) == 0) {
 
429
                        rc = ipmi_mc_reset(intf, BMC_WARM_RESET);
 
430
                }
 
431
                else {
 
432
                        lprintf(LOG_ERR, "reset commands: warm, cold");
 
433
                }
 
434
        }
 
435
        else if (strncmp(argv[0], "info", 4) == 0) {
 
436
                rc = ipmi_mc_get_deviceid(intf);
 
437
        }
 
438
        else if (strncmp(argv[0], "guid", 4) == 0) {
 
439
                rc = ipmi_mc_get_guid(intf);
 
440
        }
 
441
        else if (strncmp(argv[0], "getenables", 10) == 0) {
 
442
                rc = ipmi_mc_get_enables(intf);
 
443
        }
 
444
        else if (strncmp(argv[0], "setenables", 10) == 0) {
 
445
                rc = ipmi_mc_set_enables(intf, argc-1, &(argv[1]));
 
446
        }
 
447
 
 
448
        return rc;
 
449
}