1 /*
2 * cmd_pef.c
3 *
4 * A command interpreter for OpenIPMI
5 *
6 * Author: MontaVista Software, Inc.
7 * Corey Minyard <minyard@mvista.com>
8 * source@mvista.com
9 *
10 * Copyright 2004 MontaVista Software Inc.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this program; if not, write to the Free
31 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 */
33
34 #include <errno.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <OpenIPMI/ipmiif.h>
40 #include <OpenIPMI/ipmi_pef.h>
41 #include <OpenIPMI/ipmi_cmdlang.h>
42 #include <OpenIPMI/ipmi_mc.h>
43
44 /* Internal includes, do not use in your programs */
45 #include <OpenIPMI/internal/ipmi_malloc.h>
46 #include <OpenIPMI/internal/locked_list.h>
47
48 static locked_list_t *pefs;
49
50 static void
pef_list_handler(ipmi_pef_t * pef,void * cb_data)51 pef_list_handler(ipmi_pef_t *pef, void *cb_data)
52 {
53 ipmi_cmd_info_t *cmd_info = cb_data;
54 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
55 char pef_name[IPMI_PEF_NAME_LEN];
56
57 if (cmdlang->err)
58 return;
59
60 ipmi_pef_get_name(pef, pef_name, sizeof(pef_name));
61
62 ipmi_cmdlang_out(cmd_info, "Name", pef_name);
63 }
64
65 static void
pef_list(ipmi_domain_t * domain,void * cb_data)66 pef_list(ipmi_domain_t *domain, void *cb_data)
67 {
68 ipmi_cmd_info_t *cmd_info = cb_data;
69 char domain_name[IPMI_DOMAIN_NAME_LEN];
70
71 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
72 ipmi_cmdlang_out(cmd_info, "Domain", NULL);
73 ipmi_cmdlang_down(cmd_info);
74 ipmi_cmdlang_out(cmd_info, "Name", domain_name);
75 ipmi_cmdlang_out(cmd_info, "PEFs", NULL);
76 ipmi_cmdlang_down(cmd_info);
77 ipmi_pef_iterate_pefs(domain, pef_list_handler, cmd_info);
78 ipmi_cmdlang_up(cmd_info);
79 ipmi_cmdlang_up(cmd_info);
80 }
81
82 static void
get_mc_name(ipmi_mc_t * mc,void * cb_data)83 get_mc_name(ipmi_mc_t *mc, void *cb_data)
84 {
85 ipmi_cmd_info_t *cmd_info = cb_data;
86 char mc_name[IPMI_MC_NAME_LEN];
87
88 ipmi_mc_get_name(mc, mc_name, sizeof(mc_name));
89 ipmi_cmdlang_out(cmd_info, "MC", mc_name);
90 }
91
92 static void
pef_info(ipmi_pef_t * pef,void * cb_data)93 pef_info(ipmi_pef_t *pef, void *cb_data)
94 {
95 ipmi_cmd_info_t *cmd_info = cb_data;
96 char pef_name[IPMI_PEF_NAME_LEN];
97
98 ipmi_pef_get_name(pef, pef_name, sizeof(pef_name));
99
100 ipmi_cmdlang_out(cmd_info, "PEF", NULL);
101 ipmi_cmdlang_down(cmd_info);
102 ipmi_cmdlang_out(cmd_info, "Name", pef_name);
103 ipmi_mc_pointer_cb(ipmi_pef_get_mc(pef), get_mc_name, cmd_info);
104 ipmi_cmdlang_up(cmd_info);
105 }
106
107 static void
pef_new_done(ipmi_pef_t * pef,int err,void * cb_data)108 pef_new_done(ipmi_pef_t *pef, int err, void *cb_data)
109 {
110 ipmi_cmd_info_t *cmd_info = cb_data;
111 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
112 char pef_name[IPMI_PEF_NAME_LEN];
113
114 ipmi_cmdlang_lock(cmd_info);
115 if (err) {
116 cmdlang->errstr = "Error allocating PEF";
117 cmdlang->err = err;
118 cmdlang->location = "cmd_pef.c(pef_new_done)";
119 goto out;
120 }
121
122 ipmi_pef_get_name(pef, pef_name, sizeof(pef_name));
123 ipmi_cmdlang_out(cmd_info, "PEF", pef_name);
124
125 out:
126 ipmi_cmdlang_unlock(cmd_info);
127 ipmi_cmdlang_cmd_info_put(cmd_info);
128 }
129
130 static void
pef_new(ipmi_mc_t * mc,void * cb_data)131 pef_new(ipmi_mc_t *mc, void *cb_data)
132 {
133 ipmi_cmd_info_t *cmd_info = cb_data;
134 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
135 int rv;
136
137 ipmi_cmdlang_cmd_info_get(cmd_info);
138 rv = ipmi_pef_alloc(mc, pef_new_done, cmd_info, NULL);
139 if (rv) {
140 ipmi_cmdlang_cmd_info_put(cmd_info);
141 cmdlang->errstr = "Error from ipmi_pef_alloc";
142 cmdlang->err = rv;
143 goto out_err;
144 }
145 return;
146
147 out_err:
148 ipmi_mc_get_name(mc, cmdlang->objstr,
149 cmdlang->objstr_len);
150 cmdlang->location = "cmd_pef.c(pef_new)";
151 }
152
153 static void
pef_close_done(ipmi_pef_t * pef,int err,void * cb_data)154 pef_close_done(ipmi_pef_t *pef, int err, void *cb_data)
155 {
156 ipmi_cmd_info_t *cmd_info = cb_data;
157 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
158 char pef_name[IPMI_PEF_NAME_LEN];
159
160 ipmi_cmdlang_lock(cmd_info);
161 if (err) {
162 ipmi_pef_get_name(pef, cmdlang->objstr,
163 cmdlang->objstr_len);
164 cmdlang->errstr = "Error closing PEF";
165 cmdlang->err = err;
166 cmdlang->location = "cmd_pef.c(pef_close_done)";
167 goto out;
168 }
169
170 ipmi_pef_get_name(pef, pef_name, sizeof(pef_name));
171 ipmi_cmdlang_out(cmd_info, "PEF destroyed", pef_name);
172
173 out:
174 ipmi_cmdlang_unlock(cmd_info);
175 ipmi_cmdlang_cmd_info_put(cmd_info);
176 }
177
178 static void
pef_close(ipmi_pef_t * pef,void * cb_data)179 pef_close(ipmi_pef_t *pef, void *cb_data)
180 {
181 ipmi_cmd_info_t *cmd_info = cb_data;
182 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
183 int rv;
184
185 ipmi_cmdlang_cmd_info_get(cmd_info);
186 rv = ipmi_pef_destroy(pef, pef_close_done, cmd_info);
187 if (rv) {
188 ipmi_cmdlang_cmd_info_put(cmd_info);
189 ipmi_pef_get_name(pef, cmdlang->objstr,
190 cmdlang->objstr_len);
191 cmdlang->errstr = "Error closing PEF";
192 cmdlang->err = rv;
193 cmdlang->location = "cmd_pef.c(pef_close)";
194 }
195 }
196
197 #define PEF_CONFIG_NAME_LEN 80
198 typedef struct pef_config_info_s
199 {
200 char name[PEF_CONFIG_NAME_LEN];
201 ipmi_pef_config_t *config;
202 } pef_config_info_t;
203
204 static unsigned int unique_num = 0;
205
206 typedef struct find_config_s
207 {
208 char *name;
209 ipmi_pef_config_t *config;
210 int delete;
211 } find_config_t;
212
213 static int
find_config_handler(void * cb_data,void * item1,void * item2)214 find_config_handler(void *cb_data, void *item1, void *item2)
215 {
216 pef_config_info_t *info = item1;
217 find_config_t *find = cb_data;
218
219 if (strcmp(find->name, info->name) == 0) {
220 find->config = info->config;
221 if (find->delete) {
222 locked_list_remove(pefs, item1, item2);
223 ipmi_mem_free(info);
224 }
225 return LOCKED_LIST_ITER_STOP;
226 }
227
228 return LOCKED_LIST_ITER_CONTINUE;
229 }
230
231 static ipmi_pef_config_t *
find_config(char * name,int delete)232 find_config(char *name, int delete)
233 {
234 find_config_t find;
235
236 find.name = name;
237 find.config = NULL;
238 find.delete = delete;
239 locked_list_iterate(pefs, find_config_handler, &find);
240 return find.config;
241 }
242
243 typedef void (*lp_set)(ipmi_cmd_info_t *cmd_info, char *val,
244 ipmi_pef_config_t *lanc, void *func);
245 typedef void (*lp_out)(ipmi_cmd_info_t *cmd_info, char *name,
246 ipmi_pef_config_t *lanc, void *func);
247 typedef struct lp_item_s
248 {
249 lp_set set;
250 lp_out out;
251 } lp_item_t;
252
253 static void
set_retint(ipmi_cmd_info_t * cmd_info,char * val,ipmi_pef_config_t * lanc,void * func)254 set_retint(ipmi_cmd_info_t *cmd_info, char *val,
255 ipmi_pef_config_t *lanc, void *func)
256 {
257 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
258 int (*f)(ipmi_pef_config_t *l, unsigned int v) = func;
259 int v;
260
261 ipmi_cmdlang_get_int(val, &v, cmd_info);
262 if (!cmdlang->err) {
263 cmdlang->err = f(lanc, v);
264 if (cmdlang->err) {
265 cmdlang->errstr = "Error setting parameter";
266 }
267 }
268 }
269 static void
out_retint(ipmi_cmd_info_t * cmd_info,char * name,ipmi_pef_config_t * lanc,void * func)270 out_retint(ipmi_cmd_info_t *cmd_info, char *name,
271 ipmi_pef_config_t *lanc, void *func)
272 {
273 unsigned int (*f)(ipmi_pef_config_t *l) = func;
274 ipmi_cmdlang_out_int(cmd_info, name, f(lanc));
275 }
276 static lp_item_t lp_retint = {set_retint, out_retint};
277
278 static void
set_retbool(ipmi_cmd_info_t * cmd_info,char * val,ipmi_pef_config_t * lanc,void * func)279 set_retbool(ipmi_cmd_info_t *cmd_info, char *val,
280 ipmi_pef_config_t *lanc, void *func)
281 {
282 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
283 int (*f)(ipmi_pef_config_t *l, unsigned int v) = func;
284 int v;
285
286 ipmi_cmdlang_get_bool(val, &v, cmd_info);
287 if (!cmdlang->err) {
288 cmdlang->err = f(lanc, v);
289 if (cmdlang->err) {
290 cmdlang->errstr = "Error setting parameter";
291 }
292 }
293 }
294 static void
out_retbool(ipmi_cmd_info_t * cmd_info,char * name,ipmi_pef_config_t * lanc,void * func)295 out_retbool(ipmi_cmd_info_t *cmd_info, char *name,
296 ipmi_pef_config_t *lanc, void *func)
297 {
298 unsigned int (*f)(ipmi_pef_config_t *l) = func;
299 ipmi_cmdlang_out_bool(cmd_info, name, f(lanc));
300 }
301 static lp_item_t lp_retbool = {set_retbool, out_retbool};
302
303 static void
set_int(ipmi_cmd_info_t * cmd_info,char * val,ipmi_pef_config_t * lanc,void * func)304 set_int(ipmi_cmd_info_t *cmd_info, char *val,
305 ipmi_pef_config_t *lanc, void *func)
306 {
307 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
308 int (*f)(ipmi_pef_config_t *l, unsigned int v) = func;
309 int v;
310
311 ipmi_cmdlang_get_int(val, &v, cmd_info);
312 if (!cmdlang->err) {
313 cmdlang->err = f(lanc, v);
314 if (cmdlang->err) {
315 cmdlang->errstr = "Error setting parameter";
316 }
317 }
318 }
319 static void
out_int(ipmi_cmd_info_t * cmd_info,char * name,ipmi_pef_config_t * lanc,void * func)320 out_int(ipmi_cmd_info_t *cmd_info, char *name,
321 ipmi_pef_config_t *lanc, void *func)
322 {
323 unsigned int v;
324 int rv;
325 int (*f)(ipmi_pef_config_t *l, unsigned int *v) = func;
326
327 rv = f(lanc, &v);
328 if (!rv)
329 ipmi_cmdlang_out_int(cmd_info, name, v);
330 }
331 static lp_item_t lp_int = {set_int, out_int};
332
333 static void
set_guid(ipmi_cmd_info_t * cmd_info,char * val,ipmi_pef_config_t * lanc,void * func)334 set_guid(ipmi_cmd_info_t *cmd_info, char *val,
335 ipmi_pef_config_t *lanc, void *func)
336 {
337 unsigned char v[16];
338 char tmp[3];
339 char *end;
340 int i;
341 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
342 int (*f)(ipmi_pef_config_t *l, unsigned char *v,
343 unsigned int dl) = func;
344
345 if (strlen(val) != 32) {
346 cmdlang->err = EINVAL;
347 cmdlang->errstr = "Invalid GUID";
348 return;
349 }
350
351 for (i=0; i<16; i++) {
352 memset(tmp, 0, sizeof(tmp));
353 memcpy(tmp, val+(i*2), 2);
354 v[i] = strtoul(tmp, &end, 16);
355 if (*end != '\0') {
356 cmdlang->err = EINVAL;
357 cmdlang->errstr = "Invalid GUID";
358 return;
359 }
360 }
361 if (!cmdlang->err) {
362 cmdlang->err = f(lanc, v, sizeof(v));
363 if (cmdlang->err) {
364 cmdlang->errstr = "Error setting parameter";
365 }
366 }
367 }
368 static void
out_guid(ipmi_cmd_info_t * cmd_info,char * name,ipmi_pef_config_t * lanc,void * func)369 out_guid(ipmi_cmd_info_t *cmd_info, char *name,
370 ipmi_pef_config_t *lanc, void *func)
371 {
372 int rv;
373 int (*f)(ipmi_pef_config_t *l, unsigned char *v,
374 unsigned int *dl) = func;
375 unsigned char v[16];
376 unsigned int len = sizeof(v);
377 char str[33];
378 char *s;
379 int i;
380
381 rv = f(lanc, (unsigned char *) &v, &len);
382 if (!rv) {
383 s = str;
384 for (i=0; i<16; i++)
385 s += sprintf(s, "%2.2x", v[i]);
386 ipmi_cmdlang_out(cmd_info, name, str);
387 }
388 }
389 static lp_item_t lp_guid = {set_guid, out_guid};
390
391 static struct lps_s
392 {
393 char *name;
394 lp_item_t *lpi;
395 void *get_func;
396 void *set_func;
397 } lps[] =
398 /* read-only */
399 #define FR(name, type) { #name, &lp_ ## type, ipmi_pefconfig_get_ ## name, \
400 NULL }
401 /* Writable */
402 #define F(name, type) { #name, &lp_ ## type, ipmi_pefconfig_get_ ## name, \
403 ipmi_pefconfig_set_ ## name }
404 {
405 F(alert_startup_delay_enabled, retbool),
406 F(startup_delay_enabled, retbool),
407 F(event_messages_enabled, retbool),
408 F(pef_enabled, retbool),
409 F(diagnostic_interrupt_enabled, retbool),
410 F(oem_action_enabled, retbool),
411 F(power_cycle_enabled, retbool),
412 F(reset_enabled, retbool),
413 F(power_down_enabled, retbool),
414 F(alert_enabled, retbool),
415 F(startup_delay, int),
416 F(alert_startup_delay, int),
417 F(guid_enabled, retbool),
418 F(guid_val, guid),
419 FR(num_event_filters, retint),
420 FR(num_alert_policies, retint),
421 FR(num_alert_strings, retint),
422 { NULL }
423 };
424
425 /*
426 * Selector-based get/out routines.
427 */
428 typedef void (*ulp_set)(ipmi_cmd_info_t *cmd_info, int sel, char *val,
429 ipmi_pef_config_t *lanc, void *func);
430 typedef void (*ulp_out)(ipmi_cmd_info_t *cmd_info, int sel, char *name,
431 ipmi_pef_config_t *lanc, void *func);
432 typedef struct ulp_item_s
433 {
434 ulp_set set;
435 ulp_out out;
436 } ulp_item_t;
437
438 static void
uset_bool(ipmi_cmd_info_t * cmd_info,int sel,char * val,ipmi_pef_config_t * lanc,void * func)439 uset_bool(ipmi_cmd_info_t *cmd_info, int sel, char *val,
440 ipmi_pef_config_t *lanc, void *func)
441 {
442 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
443 int (*f)(ipmi_pef_config_t *l, unsigned int sel,
444 unsigned int v) = func;
445 int v;
446
447 ipmi_cmdlang_get_bool(val, &v, cmd_info);
448 if (!cmdlang->err) {
449 cmdlang->err = f(lanc, sel, v);
450 if (cmdlang->err) {
451 cmdlang->errstr = "Error setting parameter";
452 }
453 }
454 }
455 static void
uout_bool(ipmi_cmd_info_t * cmd_info,int sel,char * name,ipmi_pef_config_t * lanc,void * func)456 uout_bool(ipmi_cmd_info_t *cmd_info, int sel, char *name,
457 ipmi_pef_config_t *lanc, void *func)
458 {
459 unsigned int v;
460 int rv;
461 int (*f)(ipmi_pef_config_t *l, unsigned int sel,
462 unsigned int *v) = func;
463
464 rv = f(lanc, sel, &v);
465 if (!rv)
466 ipmi_cmdlang_out_bool(cmd_info, name, v);
467 }
468 static ulp_item_t lp_ubool = {uset_bool, uout_bool};
469
470 static void
uset_int(ipmi_cmd_info_t * cmd_info,int sel,char * val,ipmi_pef_config_t * lanc,void * func)471 uset_int(ipmi_cmd_info_t *cmd_info, int sel, char *val,
472 ipmi_pef_config_t *lanc, void *func)
473 {
474 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
475 int (*f)(ipmi_pef_config_t *l, unsigned int sel,
476 unsigned int v) = func;
477 int v;
478
479 ipmi_cmdlang_get_int(val, &v, cmd_info);
480 if (!cmdlang->err) {
481 cmdlang->err = f(lanc, sel, v);
482 if (cmdlang->err) {
483 cmdlang->errstr = "Error setting parameter";
484 }
485 }
486 }
487 static void
uout_int(ipmi_cmd_info_t * cmd_info,int sel,char * name,ipmi_pef_config_t * lanc,void * func)488 uout_int(ipmi_cmd_info_t *cmd_info, int sel, char *name,
489 ipmi_pef_config_t *lanc, void *func)
490 {
491 unsigned int v;
492 int rv;
493 int (*f)(ipmi_pef_config_t *l, unsigned int sel,
494 unsigned int *v) = func;
495
496 rv = f(lanc, sel, &v);
497 if (!rv)
498 ipmi_cmdlang_out_int(cmd_info, name, v);
499 }
500 static ulp_item_t lp_uint = {uset_int, uout_int};
501
502 static void
uset_str(ipmi_cmd_info_t * cmd_info,int sel,char * val,ipmi_pef_config_t * lanc,void * func)503 uset_str(ipmi_cmd_info_t *cmd_info, int sel, char *val,
504 ipmi_pef_config_t *lanc, void *func)
505 {
506 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
507 int (*f)(ipmi_pef_config_t *l, unsigned int sel,
508 char *v) = func;
509
510 if (!cmdlang->err) {
511 cmdlang->err = f(lanc, sel, val);
512 if (cmdlang->err) {
513 cmdlang->errstr = "Error setting parameter";
514 }
515 }
516 }
517 static void
uout_str(ipmi_cmd_info_t * cmd_info,int sel,char * name,ipmi_pef_config_t * lanc,void * func)518 uout_str(ipmi_cmd_info_t *cmd_info, int sel, char *name,
519 ipmi_pef_config_t *lanc, void *func)
520 {
521 char v[100];
522 int rv;
523 int (*f)(ipmi_pef_config_t *l, unsigned int sel,
524 char *v, unsigned int *dl) = func;
525 unsigned int len = sizeof(v);
526
527 rv = f(lanc, sel, v, &len);
528 if (!rv)
529 ipmi_cmdlang_out(cmd_info, name, v);
530 }
531 static ulp_item_t lp_ustr = {uset_str, uout_str};
532
533 /*
534 * event-filter table items
535 */
536 static struct ulps_s
537 {
538 char *name;
539 ulp_item_t *lpi;
540 void *get_func;
541 void *set_func;
542 } elps[] =
543 {
544 F(enable_filter, ubool),
545 F(filter_type, uint),
546 F(diagnostic_interrupt, ubool),
547 F(oem_action, ubool),
548 F(power_cycle, ubool),
549 F(reset, ubool),
550 F(power_down, ubool),
551 F(alert, ubool),
552 F(alert_policy_number, uint),
553 F(event_severity, uint),
554 F(generator_id_addr, uint),
555 F(generator_id_channel_lun, uint),
556 F(sensor_type, uint),
557 F(sensor_number, uint),
558 F(event_trigger, uint),
559 F(data1_offset_mask, uint),
560 F(data1_mask, uint),
561 F(data1_compare1, uint),
562 F(data1_compare2, uint),
563 F(data2_mask, uint),
564 F(data2_compare1, uint),
565 F(data2_compare2, uint),
566 F(data3_mask, uint),
567 F(data3_compare1, uint),
568 F(data3_compare2, uint),
569 { NULL }
570 };
571
572 /*
573 * Alert policy table items
574 */
575 static struct ulps_s plps[] =
576 {
577 F(policy_num, uint),
578 F(enabled, ubool),
579 F(policy, uint),
580 F(channel, uint),
581 F(destination_selector, uint),
582 F(alert_string_event_specific, ubool),
583 F(alert_string_selector, uint),
584 { NULL }
585 };
586
587 /*
588 * Alert string items
589 */
590 static struct ulps_s slps[] =
591 {
592 F(event_filter, uint),
593 F(alert_string_set, uint),
594 F(alert_string, ustr),
595 { NULL }
596 };
597
598 static void
config_info(ipmi_cmd_info_t * cmd_info,ipmi_pef_config_t * config)599 config_info(ipmi_cmd_info_t *cmd_info, ipmi_pef_config_t *config)
600 {
601 int i;
602 int j;
603 int num;
604
605 /* Basic items */
606 for (i=0; lps[i].name; i++) {
607 lp_item_t *lp = lps[i].lpi;
608 lp->out(cmd_info, lps[i].name, config, lps[i].get_func);
609 }
610
611 /* per-event-filter table items */
612 num = ipmi_pefconfig_get_num_event_filters(config);
613 for (j=0; j<num; j++) {
614 struct ulps_s *lps = elps;
615 ipmi_cmdlang_out(cmd_info, "Event Filter", NULL);
616 ipmi_cmdlang_down(cmd_info);
617 ipmi_cmdlang_out_int(cmd_info, "Number", j);
618 for (i=0; lps[i].name; i++) {
619 ulp_item_t *lp = lps[i].lpi;
620 lp->out(cmd_info, j, lps[i].name, config, lps[i].get_func);
621 }
622 ipmi_cmdlang_up(cmd_info);
623 }
624
625 /* per-alert policy table items */
626 num = ipmi_pefconfig_get_num_alert_policies(config);
627 for (j=0; j<num; j++) {
628 struct ulps_s *lps = plps;
629 ipmi_cmdlang_out(cmd_info, "Alert Policy", NULL);
630 ipmi_cmdlang_down(cmd_info);
631 ipmi_cmdlang_out_int(cmd_info, "Number", j);
632 for (i=0; lps[i].name; i++) {
633 ulp_item_t *lp = lps[i].lpi;
634 lp->out(cmd_info, j, lps[i].name, config, lps[i].get_func);
635 }
636 ipmi_cmdlang_up(cmd_info);
637 }
638
639 /* per-alert string items */
640 num = ipmi_pefconfig_get_num_alert_strings(config);
641 for (j=0; j<num; j++) {
642 struct ulps_s *lps = slps;
643 ipmi_cmdlang_out(cmd_info, "Alert String", NULL);
644 ipmi_cmdlang_down(cmd_info);
645 ipmi_cmdlang_out_int(cmd_info, "Number", j);
646 for (i=0; lps[i].name; i++) {
647 ulp_item_t *lp = lps[i].lpi;
648 lp->out(cmd_info, j, lps[i].name, config, lps[i].get_func);
649 }
650 ipmi_cmdlang_up(cmd_info);
651 }
652 }
653
654 static void
pef_config_get_done(ipmi_pef_t * pef,int err,ipmi_pef_config_t * config,void * cb_data)655 pef_config_get_done(ipmi_pef_t *pef,
656 int err,
657 ipmi_pef_config_t *config,
658 void *cb_data)
659 {
660 ipmi_cmd_info_t *cmd_info = cb_data;
661 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
662 char pef_name[IPMI_PEF_NAME_LEN];
663 pef_config_info_t *info;
664
665 ipmi_cmdlang_lock(cmd_info);
666 if (err) {
667 cmdlang->errstr = "Error getting PEF";
668 cmdlang->err = err;
669 goto out;
670 }
671
672 ipmi_pef_get_name(pef, pef_name, sizeof(pef_name));
673
674 info = ipmi_mem_alloc(sizeof(*info));
675 if (!info) {
676 cmdlang->errstr = "Out of memory";
677 cmdlang->err = ENOMEM;
678 ipmi_pef_free_config(config);
679 goto out;
680 }
681 snprintf(info->name, sizeof(info->name), "%s.%u",
682 pef_name, unique_num);
683 info->config = config;
684 if (!locked_list_add(pefs, info, NULL)) {
685 cmdlang->errstr = "Out of memory";
686 cmdlang->err = ENOMEM;
687 ipmi_pef_free_config(config);
688 ipmi_mem_free(info);
689 goto out;
690 }
691 unique_num++;
692
693 ipmi_cmdlang_out(cmd_info, "PEF Config", NULL);
694 ipmi_cmdlang_down(cmd_info);
695 ipmi_cmdlang_out(cmd_info, "Name", info->name);
696 config_info(cmd_info, config);
697 ipmi_cmdlang_up(cmd_info);
698
699 out:
700 if (cmdlang->err) {
701 ipmi_pef_get_name(pef, cmdlang->objstr,
702 cmdlang->objstr_len);
703 cmdlang->location = "cmd_pef.c(pef_config_get_done)";
704 }
705 ipmi_cmdlang_unlock(cmd_info);
706 ipmi_cmdlang_cmd_info_put(cmd_info);
707 }
708
709 static void
pef_config_get(ipmi_pef_t * pef,void * cb_data)710 pef_config_get(ipmi_pef_t *pef, void *cb_data)
711 {
712 ipmi_cmd_info_t *cmd_info = cb_data;
713 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
714 int rv;
715
716 ipmi_cmdlang_cmd_info_get(cmd_info);
717 rv = ipmi_pef_get_config(pef, pef_config_get_done, cmd_info);
718 if (rv) {
719 ipmi_pef_get_name(pef, cmdlang->objstr,
720 cmdlang->objstr_len);
721 ipmi_cmdlang_cmd_info_put(cmd_info);
722 cmdlang->errstr = "Error getting PEF";
723 cmdlang->err = rv;
724 cmdlang->location = "cmd_pef.c(pef_config_get)";
725 }
726 }
727
728 typedef struct pef_config_op_s
729 {
730 char name[PEF_CONFIG_NAME_LEN];
731 ipmi_cmd_info_t *cmd_info;
732 } pef_config_op_t;
733
734 static void
pef_config_set_done(ipmi_pef_t * pef,int err,void * cb_data)735 pef_config_set_done(ipmi_pef_t *pef,
736 int err,
737 void *cb_data)
738 {
739 pef_config_op_t *info = cb_data;
740 ipmi_cmd_info_t *cmd_info = info->cmd_info;
741 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
742
743 ipmi_cmdlang_lock(cmd_info);
744 if (err) {
745 ipmi_pef_get_name(pef, cmdlang->objstr,
746 cmdlang->objstr_len);
747 cmdlang->errstr = "Error setting PEF";
748 cmdlang->err = err;
749 cmdlang->location = "cmd_pef.c(pef_config_set_done)";
750 goto out;
751 }
752
753 ipmi_cmdlang_out(cmd_info, "PEF config set", info->name);
754
755 out:
756 ipmi_mem_free(info);
757 ipmi_cmdlang_unlock(cmd_info);
758 ipmi_cmdlang_cmd_info_put(cmd_info);
759 }
760
761 static void
pef_config_set(ipmi_pef_t * pef,void * cb_data)762 pef_config_set(ipmi_pef_t *pef, void *cb_data)
763 {
764 ipmi_cmd_info_t *cmd_info = cb_data;
765 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
766 int rv;
767 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
768 int argc = ipmi_cmdlang_get_argc(cmd_info);
769 char **argv = ipmi_cmdlang_get_argv(cmd_info);
770 ipmi_pef_config_t *lanc;
771 pef_config_op_t *info;
772 char *name;
773
774 if ((argc - curr_arg) < 1) {
775 /* Not enough parameters */
776 cmdlang->errstr = "Not enough parameters";
777 cmdlang->err = EINVAL;
778 goto out_err;
779 }
780
781 name = argv[curr_arg];
782 curr_arg++;
783 lanc = find_config(name, 0);
784 if (!lanc) {
785 cmdlang->errstr = "Invalid PEF config";
786 cmdlang->err = EINVAL;
787 goto out_err;
788 }
789
790 info = ipmi_mem_alloc(sizeof(*info));
791 if (!info) {
792 cmdlang->errstr = "Out of memory";
793 cmdlang->err = ENOMEM;
794 goto out_err;
795 }
796 info->cmd_info = cmd_info;
797 strncpy(info->name, name, sizeof(info->name) - 1);
798 info->name[sizeof(info->name) - 1] = '\0';
799
800 ipmi_cmdlang_cmd_info_get(cmd_info);
801 rv = ipmi_pef_set_config(pef, lanc, pef_config_set_done, info);
802 if (rv) {
803 ipmi_cmdlang_cmd_info_put(cmd_info);
804 cmdlang->errstr = "Error setting PEF";
805 cmdlang->err = rv;
806 ipmi_mem_free(info);
807 goto out_err;
808 }
809
810 return;
811
812 out_err:
813 ipmi_pef_get_name(pef, cmdlang->objstr,
814 cmdlang->objstr_len);
815 cmdlang->location = "cmd_pef.c(pef_config_set)";
816 }
817
818 static void
pef_config_unlock_done(ipmi_pef_t * pef,int err,void * cb_data)819 pef_config_unlock_done(ipmi_pef_t *pef,
820 int err,
821 void *cb_data)
822 {
823 pef_config_op_t *info = cb_data;
824 ipmi_cmd_info_t *cmd_info = info->cmd_info;
825 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
826
827 ipmi_cmdlang_lock(cmd_info);
828 if (err) {
829 ipmi_pef_get_name(pef, cmdlang->objstr,
830 cmdlang->objstr_len);
831 cmdlang->errstr = "Error unlocking PEF";
832 cmdlang->err = err;
833 cmdlang->location = "cmd_pef.c(pef_config_unlock_done)";
834 goto out;
835 }
836
837 ipmi_cmdlang_out(cmd_info, "PEF config unlocked", info->name);
838
839 out:
840 ipmi_mem_free(info);
841 ipmi_cmdlang_unlock(cmd_info);
842 ipmi_cmdlang_cmd_info_put(cmd_info);
843 }
844
845 static void
pef_config_unlock(ipmi_pef_t * pef,void * cb_data)846 pef_config_unlock(ipmi_pef_t *pef, void *cb_data)
847 {
848 ipmi_cmd_info_t *cmd_info = cb_data;
849 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
850 int rv;
851 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
852 int argc = ipmi_cmdlang_get_argc(cmd_info);
853 char **argv = ipmi_cmdlang_get_argv(cmd_info);
854 ipmi_pef_config_t *lanc;
855 pef_config_op_t *info;
856 char *name;
857
858 if ((argc - curr_arg) < 1) {
859 /* Not enough parameters */
860 cmdlang->errstr = "Not enough parameters";
861 cmdlang->err = EINVAL;
862 goto out_err;
863 }
864
865 name = argv[curr_arg];
866 curr_arg++;
867 lanc = find_config(name, 0);
868 if (!lanc) {
869 cmdlang->errstr = "Invalid PEF config";
870 cmdlang->err = EINVAL;
871 goto out_err;
872 }
873
874 info = ipmi_mem_alloc(sizeof(*info));
875 if (!info) {
876 cmdlang->errstr = "Out of memory";
877 cmdlang->err = ENOMEM;
878 goto out_err;
879 }
880 info->cmd_info = cmd_info;
881 strncpy(info->name, name, sizeof(info->name) - 1);
882 info->name[sizeof(info->name) - 1] = '\0';
883
884 ipmi_cmdlang_cmd_info_get(cmd_info);
885 rv = ipmi_pef_clear_lock(pef, lanc, pef_config_unlock_done, info);
886 if (rv) {
887 ipmi_cmdlang_cmd_info_put(cmd_info);
888 cmdlang->errstr = "Error clearing PEF lock";
889 cmdlang->err = rv;
890 ipmi_mem_free(info);
891 goto out_err;
892 }
893
894 return;
895
896 out_err:
897 ipmi_pef_get_name(pef, cmdlang->objstr,
898 cmdlang->objstr_len);
899 cmdlang->location = "cmd_pef.c(pef_config_unlock)";
900 }
901
902 static void
pef_config_close(ipmi_cmd_info_t * cmd_info)903 pef_config_close(ipmi_cmd_info_t *cmd_info)
904 {
905 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
906 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
907 int argc = ipmi_cmdlang_get_argc(cmd_info);
908 char **argv = ipmi_cmdlang_get_argv(cmd_info);
909 ipmi_pef_config_t *lanc;
910 char *lanc_name;
911
912 if ((argc - curr_arg) < 1) {
913 /* Not enough parameters */
914 cmdlang->errstr = "Not enough parameters";
915 cmdlang->err = EINVAL;
916 lanc_name = "";
917 goto out_err;
918 }
919 lanc_name = argv[curr_arg];
920
921 lanc = find_config(lanc_name, 1);
922 if (!lanc) {
923 cmdlang->errstr = "Invalid PEF config";
924 cmdlang->err = EINVAL;
925 goto out_err;
926 }
927
928 ipmi_pef_free_config(lanc);
929 ipmi_cmdlang_out(cmd_info, "PEF config destroyed", lanc_name);
930 return;
931
932 out_err:
933 strncpy(cmdlang->objstr, lanc_name, cmdlang->objstr_len);
934 cmdlang->location = "cmd_pef.c(pef_config_close)";
935 }
936
937 static int
pef_config_list_handler(void * cb_data,void * item1,void * item2)938 pef_config_list_handler(void *cb_data, void *item1, void *item2)
939 {
940 ipmi_cmd_info_t *cmd_info = cb_data;
941 pef_config_info_t *info = item1;
942
943 ipmi_cmdlang_out(cmd_info, "Name", info->name);
944 return LOCKED_LIST_ITER_CONTINUE;
945 }
946
947 static void
pef_config_list(ipmi_cmd_info_t * cmd_info)948 pef_config_list(ipmi_cmd_info_t *cmd_info)
949 {
950 ipmi_cmdlang_out(cmd_info, "PEF Configs", NULL);
951 ipmi_cmdlang_down(cmd_info);
952 locked_list_iterate(pefs, pef_config_list_handler, cmd_info);
953 ipmi_cmdlang_up(cmd_info);
954 }
955
956 static int
pef_config_info_handler(void * cb_data,void * item1,void * item2)957 pef_config_info_handler(void *cb_data, void *item1, void *item2)
958 {
959 ipmi_cmd_info_t *cmd_info = cb_data;
960 pef_config_info_t *info = item1;
961
962 ipmi_cmdlang_out(cmd_info, "PEF Config", NULL);
963 ipmi_cmdlang_down(cmd_info);
964 ipmi_cmdlang_out(cmd_info, "Name", info->name);
965 config_info(cmd_info, info->config);
966 ipmi_cmdlang_up(cmd_info);
967 return LOCKED_LIST_ITER_CONTINUE;
968 }
969
970 static void
pef_config_info(ipmi_cmd_info_t * cmd_info)971 pef_config_info(ipmi_cmd_info_t *cmd_info)
972 {
973 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
974 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
975 int argc = ipmi_cmdlang_get_argc(cmd_info);
976 char **argv = ipmi_cmdlang_get_argv(cmd_info);
977 ipmi_pef_config_t *lanc;
978
979 if ((argc - curr_arg) < 1) {
980 locked_list_iterate(pefs, pef_config_info_handler, cmd_info);
981 } else {
982 lanc = find_config(argv[curr_arg], 0);
983 if (!lanc) {
984 cmdlang->errstr = "Invalid PEF config";
985 cmdlang->err = EINVAL;
986 goto out_err;
987 }
988 ipmi_cmdlang_out(cmd_info, "PEF Config", NULL);
989 ipmi_cmdlang_down(cmd_info);
990 ipmi_cmdlang_out(cmd_info, "Name", argv[curr_arg]);
991 config_info(cmd_info, lanc);
992 ipmi_cmdlang_up(cmd_info);
993 }
994 return;
995
996 out_err:
997 strncpy(cmdlang->objstr, argv[curr_arg], cmdlang->objstr_len);
998 cmdlang->location = "cmd_pef.c(pef_config_info)";
999 }
1000
1001 static void
pef_config_update(ipmi_cmd_info_t * cmd_info)1002 pef_config_update(ipmi_cmd_info_t *cmd_info)
1003 {
1004 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
1005 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
1006 int argc = ipmi_cmdlang_get_argc(cmd_info);
1007 char **argv = ipmi_cmdlang_get_argv(cmd_info);
1008 ipmi_pef_config_t *lanc;
1009 int i;
1010 char *name;
1011 char *val;
1012 char *lanc_name;
1013 int sel;
1014
1015 if ((argc - curr_arg) < 3) {
1016 /* Not enough parameters */
1017 cmdlang->errstr = "Not enough parameters";
1018 cmdlang->err = EINVAL;
1019 lanc_name = "";
1020 goto out_err;
1021 }
1022 lanc_name = argv[curr_arg];
1023 curr_arg++;
1024
1025 lanc = find_config(lanc_name, 0);
1026 if (!lanc) {
1027 cmdlang->errstr = "Invalid PEF config";
1028 cmdlang->err = EINVAL;
1029 goto out_err;
1030 }
1031
1032 name = argv[curr_arg];
1033 curr_arg++;
1034 val = argv[curr_arg];
1035 curr_arg++;
1036
1037 /* Basic items */
1038 for (i=0; lps[i].name; i++) {
1039 if (strcmp(lps[i].name, name) == 0) {
1040 lp_item_t *lp = lps[i].lpi;
1041 if (!lp->set) {
1042 cmdlang->errstr = "Parameter is read-only";
1043 cmdlang->err = EINVAL;
1044 goto out_err;
1045 }
1046 lp->set(cmd_info, val, lanc, lps[i].set_func);
1047 goto out;
1048 }
1049 }
1050
1051 /* per-event filter items */
1052 for (i=0; elps[i].name; i++) {
1053 struct ulps_s *lps = elps;
1054 if (strcmp(lps[i].name, name) == 0) {
1055 ulp_item_t *lp = lps[i].lpi;
1056
1057 if ((argc - curr_arg) < 1) {
1058 /* Not enough parameters */
1059 cmdlang->errstr = "Not enough parameters";
1060 cmdlang->err = EINVAL;
1061 goto out_err;
1062 }
1063 if (!lp->set) {
1064 cmdlang->errstr = "Parameter is read-only";
1065 cmdlang->err = EINVAL;
1066 goto out_err;
1067 }
1068 ipmi_cmdlang_get_int(val, &sel, cmd_info);
1069 if (cmdlang->err) {
1070 cmdlang->errstr = "selector invalid";
1071 goto out_err;
1072 }
1073 val = argv[curr_arg];
1074 curr_arg++;
1075 lp->set(cmd_info, sel, val, lanc, lps[i].set_func);
1076 goto out;
1077 }
1078 }
1079
1080 /* per-event filter items */
1081 for (i=0; plps[i].name; i++) {
1082 struct ulps_s *lps = plps;
1083 if (strcmp(lps[i].name, name) == 0) {
1084 ulp_item_t *lp = lps[i].lpi;
1085
1086 if ((argc - curr_arg) < 1) {
1087 /* Not enough parameters */
1088 cmdlang->errstr = "Not enough parameters";
1089 cmdlang->err = EINVAL;
1090 goto out_err;
1091 }
1092 if (!lp->set) {
1093 cmdlang->errstr = "Parameter is read-only";
1094 cmdlang->err = EINVAL;
1095 goto out_err;
1096 }
1097 ipmi_cmdlang_get_int(val, &sel, cmd_info);
1098 if (cmdlang->err) {
1099 cmdlang->errstr = "selector invalid";
1100 goto out_err;
1101 }
1102 val = argv[curr_arg];
1103 curr_arg++;
1104 lp->set(cmd_info, sel, val, lanc, lps[i].set_func);
1105 goto out;
1106 }
1107 }
1108
1109 /* per-event filter items */
1110 for (i=0; slps[i].name; i++) {
1111 struct ulps_s *lps = slps;
1112 if (strcmp(lps[i].name, name) == 0) {
1113 ulp_item_t *lp = lps[i].lpi;
1114
1115 if ((argc - curr_arg) < 1) {
1116 /* Not enough parameters */
1117 cmdlang->errstr = "Not enough parameters";
1118 cmdlang->err = EINVAL;
1119 goto out_err;
1120 }
1121 if (!lp->set) {
1122 cmdlang->errstr = "Parameter is read-only";
1123 cmdlang->err = EINVAL;
1124 goto out_err;
1125 }
1126 ipmi_cmdlang_get_int(val, &sel, cmd_info);
1127 if (cmdlang->err) {
1128 cmdlang->errstr = "selector invalid";
1129 goto out_err;
1130 }
1131 val = argv[curr_arg];
1132 curr_arg++;
1133 lp->set(cmd_info, sel, val, lanc, lps[i].set_func);
1134 goto out;
1135 }
1136 }
1137
1138 cmdlang->errstr = "Invalid parameter name";
1139 cmdlang->err = EINVAL;
1140 goto out_err;
1141
1142 out:
1143 ipmi_cmdlang_out(cmd_info, "PEF config updated", lanc_name);
1144 return;
1145
1146 out_err:
1147 strncpy(cmdlang->objstr, lanc_name, cmdlang->objstr_len);
1148 cmdlang->location = "cmd_pef.c(pef_config_update)";
1149 }
1150
1151 typedef struct pet_mc_unlock_s
1152 {
1153 char name[IPMI_MC_NAME_LEN];
1154 ipmi_cmd_info_t *cmd_info;
1155 } pef_mc_unlock_t;
1156
1157 static void
pef_unlock_mc_done2(ipmi_pef_t * pef,int err,void * cb_data)1158 pef_unlock_mc_done2(ipmi_pef_t *pef, int err, void *cb_data)
1159 {
1160 pef_mc_unlock_t *info = cb_data;
1161 ipmi_cmd_info_t *cmd_info = info->cmd_info;
1162 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
1163
1164 ipmi_cmdlang_lock(cmd_info);
1165 if (err) {
1166 ipmi_pef_get_name(pef, cmdlang->objstr,
1167 cmdlang->objstr_len);
1168 cmdlang->errstr = "Error unlocking MC PEF";
1169 cmdlang->err = err;
1170 cmdlang->location = "cmd_pef.c(pef_unlock_mc_done)";
1171 goto out;
1172 }
1173
1174 ipmi_cmdlang_out(cmd_info, "PEF unlocked", info->name);
1175
1176 out:
1177 ipmi_cmdlang_unlock(cmd_info);
1178 ipmi_cmdlang_cmd_info_put(cmd_info);
1179 ipmi_pef_destroy(pef, NULL, NULL);
1180 ipmi_mem_free(info);
1181 }
1182
1183 static void
pef_unlock_mc_done1(ipmi_pef_t * pef,int err,void * cb_data)1184 pef_unlock_mc_done1(ipmi_pef_t *pef, int err, void *cb_data)
1185 {
1186 pef_mc_unlock_t *info = cb_data;
1187 ipmi_cmd_info_t *cmd_info = info->cmd_info;
1188 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
1189 int rv;
1190
1191 if (err) {
1192 ipmi_cmdlang_lock(cmd_info);
1193 cmdlang->errstr = "Error unlocking MC PEF";
1194 cmdlang->err = err;
1195 cmdlang->location = "cmd_pef.c(pef_unlock_mc_done)";
1196 ipmi_cmdlang_unlock(cmd_info);
1197 goto out_err;
1198 }
1199
1200 rv = ipmi_pef_clear_lock(pef, NULL, pef_unlock_mc_done2, info);
1201 if (rv) {
1202 ipmi_cmdlang_lock(cmd_info);
1203 cmdlang->errstr = "Error from ipmi_pef_clear_lock";
1204 cmdlang->err = rv;
1205 ipmi_cmdlang_unlock(cmd_info);
1206 goto out_err;
1207 }
1208 return;
1209
1210 out_err:
1211 ipmi_pef_destroy(pef, NULL, NULL);
1212 ipmi_cmdlang_cmd_info_put(cmd_info);
1213 ipmi_mem_free(info);
1214 }
1215
1216 static void
pef_unlock_mc(ipmi_mc_t * mc,void * cb_data)1217 pef_unlock_mc(ipmi_mc_t *mc, void *cb_data)
1218 {
1219 pef_mc_unlock_t *info;
1220 ipmi_cmd_info_t *cmd_info = cb_data;
1221 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
1222 int rv;
1223
1224 info = ipmi_mem_alloc(sizeof(*info));
1225 if (!info) {
1226 cmdlang->errstr = "Out of memory";
1227 cmdlang->err = ENOMEM;
1228 goto out_err;
1229 }
1230 info->cmd_info = cmd_info;
1231 ipmi_mc_get_name(mc, info->name, sizeof(info->name));
1232
1233 ipmi_cmdlang_cmd_info_get(cmd_info);
1234 rv = ipmi_pef_alloc(mc, pef_unlock_mc_done1, info, NULL);
1235 if (rv) {
1236 ipmi_cmdlang_cmd_info_put(cmd_info);
1237 cmdlang->errstr = "Error from ipmi_pef_alloc";
1238 cmdlang->err = rv;
1239 ipmi_mem_free(info);
1240 goto out_err;
1241 }
1242 return;
1243
1244 out_err:
1245 ipmi_mc_get_name(mc, cmdlang->objstr,
1246 cmdlang->objstr_len);
1247 cmdlang->location = "cmd_pef.c(pef_unlock_mc)";
1248 }
1249
1250 static ipmi_cmdlang_cmd_t *pef_cmds;
1251 static ipmi_cmdlang_cmd_t *config_cmds;
1252
1253 static ipmi_cmdlang_init_t cmds_pef[] =
1254 {
1255 { "pef", NULL,
1256 "- Commands dealing with PEF Parameters (pefs)",
1257 NULL, NULL, &pef_cmds},
1258 { "list", &pef_cmds,
1259 "- List all the pefs in the system",
1260 ipmi_cmdlang_domain_handler, pef_list, NULL },
1261 { "new", &pef_cmds,
1262 "<mc> - Create a pef for the given MC.",
1263 ipmi_cmdlang_mc_handler, pef_new, NULL },
1264 { "info", &pef_cmds,
1265 "<pef> - Dump information about a pef",
1266 ipmi_cmdlang_pef_handler, pef_info, NULL },
1267 { "config", &pef_cmds,
1268 "- Commands dealing with PEF configs",
1269 NULL, NULL, &config_cmds },
1270 { "list", &config_cmds,
1271 "- List the lan configurations that currently exist",
1272 pef_config_list, NULL, NULL },
1273 { "info", &config_cmds,
1274 "<config> - List info on lan configuration",
1275 pef_config_info, NULL, NULL },
1276 { "get", &config_cmds,
1277 "<pef> - Fetch the PEF information for the pef",
1278 ipmi_cmdlang_pef_handler, pef_config_get, NULL },
1279 { "set", &config_cmds,
1280 "<pef> <pef config> - Set the PEF information for the pef",
1281 ipmi_cmdlang_pef_handler, pef_config_set, NULL },
1282 { "unlock", &config_cmds,
1283 "<pef> <pef config> - Unlock, but do not set the config",
1284 ipmi_cmdlang_pef_handler, pef_config_unlock, NULL },
1285 { "update", &config_cmds,
1286 "<pef config> <parm> [selector] <value> - Set the given parameter"
1287 " in the pef config to the given value. If the parameter has"
1288 " a selector of some type, the selector must be given, otherwise"
1289 " no selector should be given.",
1290 pef_config_update, NULL, NULL },
1291 { "close", &config_cmds,
1292 "<pef config> - free the config",
1293 pef_config_close, NULL, NULL },
1294 { "unlock_mc", &pef_cmds,
1295 "<mc> - Unlock the pef for the given mc",
1296 ipmi_cmdlang_mc_handler, pef_unlock_mc, NULL },
1297 { "close", &pef_cmds,
1298 "<pef> - Close the pef",
1299 ipmi_cmdlang_pef_handler, pef_close, NULL },
1300 };
1301 #define CMDS_PEF_LEN (sizeof(cmds_pef)/sizeof(ipmi_cmdlang_init_t))
1302
1303 int
ipmi_cmdlang_pef_init(os_handler_t * os_hnd)1304 ipmi_cmdlang_pef_init(os_handler_t *os_hnd)
1305 {
1306 int rv;
1307
1308 pefs = locked_list_alloc(os_hnd);
1309 if (!pefs)
1310 return ENOMEM;
1311
1312 rv = ipmi_cmdlang_reg_table(cmds_pef, CMDS_PEF_LEN);
1313 if (rv) {
1314 locked_list_destroy(pefs);
1315 pefs = NULL;
1316 }
1317
1318 return rv;
1319 }
1320
1321 static int
config_destroy_handler(void * cb_data,void * item1,void * item2)1322 config_destroy_handler(void *cb_data, void *item1, void *item2)
1323 {
1324 pef_config_info_t *info = item1;
1325
1326 ipmi_pef_free_config(info->config);
1327 ipmi_mem_free(info);
1328 return LOCKED_LIST_ITER_CONTINUE;
1329 }
1330
1331 void
ipmi_cmdlang_pef_shutdown(void)1332 ipmi_cmdlang_pef_shutdown(void)
1333 {
1334 locked_list_iterate(pefs, config_destroy_handler, NULL);
1335 locked_list_destroy(pefs);
1336 pefs = NULL;
1337 }
1338