1 /*
2 * cmd_domain.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_mc.h>
41 #include <OpenIPMI/ipmi_err.h>
42 #include <OpenIPMI/ipmi_cmdlang.h>
43 #include <OpenIPMI/ipmi_fru.h>
44 #include <OpenIPMI/ipmi_conn.h>
45
46 /* Internal includes, do not use in your programs */
47 #include <OpenIPMI/internal/ipmi_malloc.h>
48
49 /* Don't pollute the namespace iwth ipmi_fru_t. */
50 void ipmi_cmdlang_dump_fru_info(ipmi_cmd_info_t *cmd_info, ipmi_fru_t *fru);
51
52 static void
domain_list_handler(ipmi_domain_t * domain,void * cb_data)53 domain_list_handler(ipmi_domain_t *domain, void *cb_data)
54 {
55 ipmi_cmd_info_t *cmd_info = cb_data;
56 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
57 char domain_name[IPMI_DOMAIN_NAME_LEN];
58
59 if (cmdlang->err)
60 return;
61
62 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
63
64 ipmi_cmdlang_out(cmd_info, "Name", domain_name);
65 }
66
67 static void
domain_list(ipmi_cmd_info_t * cmd_info)68 domain_list(ipmi_cmd_info_t *cmd_info)
69 {
70 ipmi_cmdlang_out(cmd_info, "Domains", NULL);
71 ipmi_cmdlang_down(cmd_info);
72 ipmi_domain_iterate_domains(domain_list_handler, cmd_info);
73 ipmi_cmdlang_up(cmd_info);
74 }
75
76 static void
domain_info(ipmi_domain_t * domain,void * cb_data)77 domain_info(ipmi_domain_t *domain, void *cb_data)
78 {
79 ipmi_cmd_info_t *cmd_info = cb_data;
80 char domain_name[IPMI_DOMAIN_NAME_LEN];
81 unsigned char guid[16];
82
83 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
84
85 ipmi_cmdlang_out(cmd_info, "Domain", NULL);
86 ipmi_cmdlang_down(cmd_info);
87 ipmi_cmdlang_out(cmd_info, "Name", domain_name);
88 if (ipmi_domain_get_guid(domain, guid) == 0)
89 ipmi_cmdlang_out_binary(cmd_info, "GUID", (char *) guid, 16);
90 ipmi_cmdlang_out(cmd_info, "Type",
91 ipmi_domain_get_type_string(ipmi_domain_get_type(domain)));
92 ipmi_cmdlang_out_int(cmd_info, "SEL Rescan Time",
93 ipmi_domain_get_sel_rescan_time(domain));
94 ipmi_cmdlang_out_int(cmd_info, "IPMB Rescan Time",
95 ipmi_domain_get_ipmb_rescan_time(domain));
96 ipmi_cmdlang_up(cmd_info);
97 }
98
99 static void domain_con_change(ipmi_domain_t *domain,
100 int err,
101 unsigned int conn_num,
102 unsigned int port_num,
103 int still_connected,
104 void *cb_data);
105 void ipmi_cmdlang_entity_change(enum ipmi_update_e op,
106 ipmi_domain_t *domain,
107 ipmi_entity_t *entity,
108 void *cb_data);
109 void ipmi_cmdlang_mc_change(enum ipmi_update_e op,
110 ipmi_domain_t *domain,
111 ipmi_mc_t *mc,
112 void *cb_data);
113
114 static void
domain_new_done(ipmi_domain_t * domain,int err,unsigned int conn_num,unsigned int port_num,int still_connected,void * cb_data)115 domain_new_done(ipmi_domain_t *domain,
116 int err,
117 unsigned int conn_num,
118 unsigned int port_num,
119 int still_connected,
120 void *cb_data)
121 {
122 ipmi_cmd_info_t *cmd_info = cb_data;
123 int rv;
124
125
126 /* This call will detect and ignore duplicates, no special
127 handling required. */
128 ipmi_domain_add_connect_change_handler(domain, domain_con_change, NULL);
129
130 /* Remove ourselves from the connection change list. This may fail,
131 but that means it's already been done and we don't care. */
132 rv = ipmi_domain_remove_connect_change_handler(domain, domain_new_done,
133 cb_data);
134
135
136 /* Handle the rest as a normal event. */
137 domain_con_change(domain, err, conn_num, port_num, still_connected,
138 NULL);
139
140 /* If we get an error removing the connect change handler,
141 that means this has already been done. */
142 if ((!rv) && cmd_info) {
143 char domain_name[IPMI_DOMAIN_NAME_LEN];
144
145 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
146 ipmi_cmdlang_lock(cmd_info);
147 ipmi_cmdlang_out(cmd_info, "Domain Created", domain_name);
148 ipmi_cmdlang_unlock(cmd_info);
149 ipmi_cmdlang_cmd_info_put(cmd_info);
150 }
151 }
152
153 void
domain_fully_up(ipmi_domain_t * domain,void * cb_data)154 domain_fully_up(ipmi_domain_t *domain, void *cb_data)
155 {
156 ipmi_cmd_info_t *cmd_info = cb_data;
157 char *errstr = NULL;
158 int rv = 0;
159 ipmi_cmd_info_t *evi;
160 char domain_name[IPMI_DOMAIN_NAME_LEN];
161
162 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
163
164 evi = ipmi_cmdlang_alloc_event_info();
165 if (!evi) {
166 rv = ENOMEM;
167 errstr = "Out of memory";
168 goto out_err;
169 }
170
171 ipmi_cmdlang_out(evi, "Object Type", "Domain");
172 ipmi_cmdlang_out(evi, "Domain", domain_name);
173 ipmi_cmdlang_out(evi, "Operation", "Domain fully up");
174
175 out_err:
176 if (rv) {
177 ipmi_cmdlang_global_err(domain_name,
178 "cmd_domain.c(domain_fully_up)",
179 errstr, rv);
180 }
181 if (evi)
182 ipmi_cmdlang_cmd_info_put(evi);
183
184 if (cmd_info) {
185 ipmi_cmdlang_lock(cmd_info);
186 ipmi_cmdlang_out(cmd_info, "Domain Created", domain_name);
187 ipmi_cmdlang_unlock(cmd_info);
188 ipmi_cmdlang_cmd_info_put(cmd_info);
189 }
190 }
191
192 static void
domain_new(ipmi_cmd_info_t * cmd_info)193 domain_new(ipmi_cmd_info_t *cmd_info)
194 {
195 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
196 ipmi_args_t *con_parms[2];
197 int set = 0;
198 int i, j;
199 ipmi_con_t *con[2];
200 int rv;
201 char *name;
202 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
203 int argc = ipmi_cmdlang_get_argc(cmd_info);
204 char **argv = ipmi_cmdlang_get_argv(cmd_info);
205 int num_options = 0;
206 ipmi_open_option_t options[10];
207 int wait_til_up = 0;
208 void *up_info = NULL;
209 void *con_info = NULL;
210
211 if (curr_arg >= argc) {
212 cmdlang->errstr = "No domain name entered";
213 cmdlang->err = EINVAL;
214 goto out;
215 }
216 name = argv[curr_arg];
217 curr_arg++;
218
219 while ((curr_arg < argc) && argv[curr_arg][0] == '-') {
220 if (num_options >= 10) {
221 cmdlang->errstr = "Too many options";
222 cmdlang->err = EINVAL;
223 goto out;
224 }
225
226 if (! ipmi_parse_options(options+num_options, argv[curr_arg]))
227 num_options++;
228 else if (strcmp(argv[curr_arg], "-wait_til_up") == 0)
229 wait_til_up = 1;
230 else
231 break;
232 curr_arg++;
233 }
234
235 rv = ipmi_parse_args(&curr_arg, argc, argv, &con_parms[set]);
236 if (rv) {
237 cmdlang->errstr = "First connection parms are invalid";
238 cmdlang->err = rv;
239 goto out;
240 }
241 set++;
242
243 if (curr_arg < argc) {
244 rv = ipmi_parse_args(&curr_arg, argc, argv, &con_parms[set]);
245 if (rv) {
246 ipmi_free_args(con_parms[0]);
247 cmdlang->errstr = "Second connection parms are invalid";
248 cmdlang->err = rv;
249 goto out;
250 }
251 set++;
252 }
253
254 for (i=0; i<set; i++) {
255 rv = ipmi_args_setup_con(con_parms[i],
256 cmdlang->os_hnd,
257 NULL,
258 &con[i]);
259 if (rv) {
260 cmdlang->errstr = "Unable to setup connection";
261 cmdlang->err = rv;
262 for (j=0; j<set; j++)
263 ipmi_free_args(con_parms[j]);
264 goto out;
265 }
266 }
267
268 if (wait_til_up)
269 up_info = cmd_info;
270 else
271 con_info = cmd_info;
272
273 ipmi_cmdlang_cmd_info_get(cmd_info);
274 rv = ipmi_open_domain(name, con, set, domain_new_done, con_info,
275 domain_fully_up, up_info,
276 options, num_options, NULL);
277 if (rv) {
278 ipmi_cmdlang_cmd_info_put(cmd_info);
279 cmdlang->errstr = strerror(rv);
280 cmdlang->err = rv;
281 for (i=0; i<set; i++) {
282 ipmi_free_args(con_parms[i]);
283 con[i]->close_connection(con[i]);
284 }
285 goto out;
286 }
287
288 for (i=0; i<set; i++)
289 ipmi_free_args(con_parms[i]);
290
291 out:
292 if (cmdlang->err)
293 cmdlang->location = "cmd_domain.c(domain_new)";
294
295 return;
296 }
297
298
299 static void
domain_open(ipmi_cmd_info_t * cmd_info)300 domain_open(ipmi_cmd_info_t *cmd_info)
301 {
302 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
303 ipmi_args_t *con_parms[2];
304 int set = 0;
305 int i, j;
306 ipmi_con_t *con[2];
307 int rv;
308 char *name;
309 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
310 int argc = ipmi_cmdlang_get_argc(cmd_info);
311 char **argv = ipmi_cmdlang_get_argv(cmd_info);
312 int num_options = 0;
313 ipmi_open_option_t options[10];
314 int wait_til_up = 0;
315 void *up_info = NULL;
316 void *con_info = NULL;
317
318 if (curr_arg >= argc) {
319 cmdlang->errstr = "No domain name entered";
320 cmdlang->err = EINVAL;
321 goto out;
322 }
323 name = argv[curr_arg];
324 curr_arg++;
325
326 while ((curr_arg < argc) && argv[curr_arg][0] == '-') {
327 if (num_options >= 10) {
328 cmdlang->errstr = "Too many options";
329 cmdlang->err = EINVAL;
330 goto out;
331 }
332
333 if (! ipmi_parse_options(options+num_options, argv[curr_arg]))
334 num_options++;
335 else if (strcmp(argv[curr_arg], "-wait_til_up") == 0)
336 wait_til_up = 1;
337 else
338 break;
339 curr_arg++;
340 }
341
342 rv = ipmi_parse_args2(&curr_arg, argc, argv, &con_parms[set]);
343 if (rv) {
344 cmdlang->errstr = "First connection parms are invalid";
345 cmdlang->err = rv;
346 goto out;
347 }
348 set++;
349
350 if (curr_arg < argc) {
351 rv = ipmi_parse_args2(&curr_arg, argc, argv, &con_parms[set]);
352 if (rv) {
353 ipmi_free_args(con_parms[0]);
354 cmdlang->errstr = "Second connection parms are invalid";
355 cmdlang->err = rv;
356 goto out;
357 }
358 set++;
359 }
360
361 for (i=0; i<set; i++) {
362 rv = ipmi_args_setup_con(con_parms[i],
363 cmdlang->os_hnd,
364 NULL,
365 &con[i]);
366 if (rv) {
367 cmdlang->errstr = "Unable to setup connection";
368 cmdlang->err = rv;
369 for (j=0; j<i; j++)
370 con[j]->close_connection(con[j]);
371 for (j=0; j<set; j++)
372 ipmi_free_args(con_parms[j]);
373 goto out;
374 }
375 }
376
377 if (wait_til_up)
378 up_info = cmd_info;
379 else
380 con_info = cmd_info;
381
382 ipmi_cmdlang_cmd_info_get(cmd_info);
383 rv = ipmi_open_domain(name, con, set, domain_new_done, con_info,
384 domain_fully_up, up_info,
385 options, num_options, NULL);
386 if (rv) {
387 ipmi_cmdlang_cmd_info_put(cmd_info);
388 cmdlang->errstr = strerror(rv);
389 cmdlang->err = rv;
390 for (i=0; i<set; i++) {
391 ipmi_free_args(con_parms[i]);
392 con[i]->close_connection(con[i]);
393 }
394 goto out;
395 }
396
397 for (i=0; i<set; i++)
398 ipmi_free_args(con_parms[i]);
399
400 out:
401 if (cmdlang->err)
402 cmdlang->location = "cmd_domain.c(domain_open)";
403
404 return;
405 }
406
con_usage(const char * name,const char * help,void * cb_data)407 void con_usage(const char *name, const char *help, void *cb_data)
408 {
409 ipmi_cmdlang_t *cmdlang = cb_data;
410
411 cmdlang->out(cmdlang, name, help);
412 }
413
414 static void
domain_open_help(ipmi_cmdlang_t * cmdlang)415 domain_open_help(ipmi_cmdlang_t *cmdlang)
416 {
417 ipmi_parse_args_iter_help(con_usage, cmdlang);
418 cmdlang->out(cmdlang, "Options are:\n", ipmi_parse_options_help());
419 }
420
421 static void
domain_fru_fetched(ipmi_domain_t * domain,ipmi_fru_t * fru,int err,void * cb_data)422 domain_fru_fetched(ipmi_domain_t *domain, ipmi_fru_t *fru,
423 int err, void *cb_data)
424 {
425 ipmi_cmd_info_t *cmd_info = cb_data;
426 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
427 char domain_name[IPMI_DOMAIN_NAME_LEN];
428
429 ipmi_cmdlang_lock(cmd_info);
430
431 if (err && (ipmi_fru_get_data_length(fru) == 0)) {
432 cmdlang->errstr = "Error fetching FRU info";
433 cmdlang->err = err;
434 ipmi_domain_get_name(domain, cmdlang->objstr,
435 cmdlang->objstr_len);
436 cmdlang->location = "cmd_domain.c(domain_fru_fetched)";
437 goto out;
438 }
439
440 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
441 ipmi_cmdlang_out(cmd_info, "Domain", NULL);
442 ipmi_cmdlang_down(cmd_info);
443 ipmi_cmdlang_out(cmd_info, "Name", domain_name);
444 if (err)
445 ipmi_cmdlang_out_int(cmd_info, "Warning fetching FRU", err);
446 ipmi_cmdlang_dump_fru_info(cmd_info, fru);
447 ipmi_cmdlang_up(cmd_info);
448
449 out:
450 ipmi_cmdlang_unlock(cmd_info);
451 ipmi_cmdlang_cmd_info_put(cmd_info);
452 }
453
454 static void
domain_fru(ipmi_domain_t * domain,void * cb_data)455 domain_fru(ipmi_domain_t *domain, void *cb_data)
456 {
457 ipmi_cmd_info_t *cmd_info = cb_data;
458 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
459 int is_logical;
460 int device_addr;
461 int device_id;
462 int lun;
463 int private_bus;
464 int channel;
465 int rv;
466 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
467 int argc = ipmi_cmdlang_get_argc(cmd_info);
468 char **argv = ipmi_cmdlang_get_argv(cmd_info);
469
470 if ((argc - curr_arg) < 6) {
471 /* Not enough parameters */
472 cmdlang->errstr = "Not enough parameters";
473 cmdlang->err = EINVAL;
474 goto out_err;
475 }
476
477 ipmi_cmdlang_get_bool(argv[curr_arg], &is_logical, cmd_info);
478 if (cmdlang->err) {
479 cmdlang->errstr = "is_logical invalid";
480 goto out_err;
481 }
482 curr_arg++;
483
484 ipmi_cmdlang_get_int(argv[curr_arg], &device_addr, cmd_info);
485 if (cmdlang->err) {
486 cmdlang->errstr = "device_address invalid";
487 goto out_err;
488 }
489 curr_arg++;
490
491 ipmi_cmdlang_get_int(argv[curr_arg], &device_id, cmd_info);
492 if (cmdlang->err) {
493 cmdlang->errstr = "device_id invalid";
494 goto out_err;
495 }
496 curr_arg++;
497
498 ipmi_cmdlang_get_int(argv[curr_arg], &lun, cmd_info);
499 if (cmdlang->err) {
500 cmdlang->errstr = "lun invalid";
501 goto out_err;
502 }
503 curr_arg++;
504
505 ipmi_cmdlang_get_int(argv[curr_arg], &private_bus, cmd_info);
506 if (cmdlang->err) {
507 cmdlang->errstr = "private_bus invalid";
508 goto out_err;
509 }
510 curr_arg++;
511
512 ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
513 if (cmdlang->err) {
514 cmdlang->errstr = "channel invalid";
515 goto out_err;
516 }
517 curr_arg++;
518
519 ipmi_cmdlang_cmd_info_get(cmd_info);
520 rv = ipmi_domain_fru_alloc(domain,
521 is_logical,
522 device_addr,
523 device_id,
524 lun,
525 private_bus,
526 channel,
527 domain_fru_fetched,
528 cmd_info,
529 NULL);
530 if (rv) {
531 ipmi_cmdlang_cmd_info_put(cmd_info);
532 cmdlang->errstr = "Error allocating FRU info";
533 cmdlang->err = rv;
534 goto out_err;
535 }
536
537 return;
538
539 out_err:
540 ipmi_domain_get_name(domain, cmdlang->objstr,
541 cmdlang->objstr_len);
542 cmdlang->location = "cmd_domain.c(domain_fru)";
543 }
544
545 static int
domain_msg_handler(ipmi_domain_t * domain,ipmi_msgi_t * rspi)546 domain_msg_handler(ipmi_domain_t *domain, ipmi_msgi_t *rspi)
547 {
548 ipmi_msg_t *msg = &rspi->msg;
549 ipmi_ipmb_addr_t *addr = (ipmi_ipmb_addr_t *) &rspi->addr;
550 ipmi_cmd_info_t *cmd_info = rspi->data1;
551 char domain_name[IPMI_DOMAIN_NAME_LEN];
552
553 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
554
555 ipmi_cmdlang_lock(cmd_info);
556 ipmi_cmdlang_out(cmd_info, "Response", NULL);
557 ipmi_cmdlang_down(cmd_info);
558 ipmi_cmdlang_out(cmd_info, "Domain", domain_name);
559 ipmi_cmdlang_out_int(cmd_info, "channel", addr->channel);
560 ipmi_cmdlang_out_hex(cmd_info, "ipmb", addr->slave_addr);
561 ipmi_cmdlang_out_int(cmd_info, "LUN", addr->lun);
562 ipmi_cmdlang_out_int(cmd_info, "NetFN", msg->netfn);
563 ipmi_cmdlang_out_int(cmd_info, "command", msg->cmd);
564 if (msg->data_len)
565 ipmi_cmdlang_out_binary(cmd_info, "Data",
566 (char *) msg->data, msg->data_len);
567 ipmi_cmdlang_unlock(cmd_info);
568 ipmi_cmdlang_up(cmd_info);
569
570 ipmi_cmdlang_cmd_info_put(cmd_info);
571
572 return IPMI_MSG_ITEM_NOT_USED;
573 }
574
575 static void
domain_msg(ipmi_domain_t * domain,void * cb_data)576 domain_msg(ipmi_domain_t *domain, void *cb_data)
577 {
578 ipmi_cmd_info_t *cmd_info = cb_data;
579 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
580 int channel;
581 int ipmb;
582 int is_broadcast = 0;
583 int LUN;
584 int NetFN;
585 int command;
586 unsigned char data[100];
587 int rv;
588 int i;
589 ipmi_ipmb_addr_t addr;
590 ipmi_msg_t msg;
591 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
592 int argc = ipmi_cmdlang_get_argc(cmd_info);
593 char **argv = ipmi_cmdlang_get_argv(cmd_info);
594
595
596 if ((argc - curr_arg) < 5) {
597 /* Not enough parameters */
598 cmdlang->errstr = "Not enough parameters";
599 cmdlang->err = EINVAL;
600 goto out_err;
601 }
602
603 ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
604 if (cmdlang->err) {
605 cmdlang->errstr = "channel invalid";
606 goto out_err;
607 }
608 curr_arg++;
609
610 ipmi_cmdlang_get_int(argv[curr_arg], &ipmb, cmd_info);
611 if (cmdlang->err) {
612 cmdlang->errstr = "ipmb invalid";
613 goto out_err;
614 }
615 curr_arg++;
616
617 if (ipmb == 0) {
618 is_broadcast = 1;
619 if ((argc - curr_arg) < 5) {
620 /* Not enough parameters */
621 cmdlang->errstr = "Not enough parameters";
622 cmdlang->err = EINVAL;
623 goto out_err;
624 }
625 ipmi_cmdlang_get_int(argv[curr_arg], &ipmb, cmd_info);
626 if (cmdlang->err) {
627 cmdlang->errstr = "ipmb invalid";
628 goto out_err;
629 }
630 curr_arg++;
631 }
632
633 ipmi_cmdlang_get_int(argv[curr_arg], &LUN, cmd_info);
634 if (cmdlang->err) {
635 cmdlang->errstr = "LUN invalid";
636 goto out_err;
637 }
638 curr_arg++;
639
640 ipmi_cmdlang_get_int(argv[curr_arg], &NetFN, cmd_info);
641 if (cmdlang->err) {
642 cmdlang->errstr = "NetFN invalid";
643 goto out_err;
644 }
645 curr_arg++;
646
647 ipmi_cmdlang_get_int(argv[curr_arg], &command, cmd_info);
648 if (cmdlang->err) {
649 cmdlang->errstr = "command invalid";
650 goto out_err;
651 }
652 curr_arg++;
653
654 i = 0;
655 while (curr_arg < argc) {
656 ipmi_cmdlang_get_uchar(argv[curr_arg], &data[i], cmd_info);
657 if (cmdlang->err) {
658 cmdlang->errstr = "data invalid";
659 goto out_err;
660 }
661 curr_arg++;
662 i++;
663 }
664
665 if (is_broadcast)
666 addr.addr_type = IPMI_IPMB_BROADCAST_ADDR_TYPE;
667 else
668 addr.addr_type = IPMI_IPMB_ADDR_TYPE;
669 addr.channel = channel;
670 addr.slave_addr = ipmb;
671 addr.lun = LUN;
672 msg.netfn = NetFN;
673 msg.cmd = command;
674 msg.data_len = i;
675 msg.data = data;
676
677 ipmi_cmdlang_cmd_info_get(cmd_info);
678 rv = ipmi_send_command_addr(domain,
679 (ipmi_addr_t *) &(addr),
680 sizeof(addr),
681 &msg,
682 domain_msg_handler,
683 cmd_info, NULL);
684 if (rv) {
685 ipmi_cmdlang_cmd_info_put(cmd_info);
686 cmdlang->errstr = "Error sending message";
687 cmdlang->err = rv;
688 goto out_err;
689 }
690
691 return;
692
693 out_err:
694 if (cmdlang->err) {
695 ipmi_domain_get_name(domain, cmdlang->objstr,
696 cmdlang->objstr_len);
697 cmdlang->location = "cmd_domain.c(domain_msg)";
698 }
699 }
700
701 static void
scan_done(ipmi_domain_t * domain,int err,void * cb_data)702 scan_done(ipmi_domain_t *domain, int err, void *cb_data)
703 {
704 ipmi_cmd_info_t *cmd_info = cb_data;
705 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
706 char domain_name[IPMI_DOMAIN_NAME_LEN];
707
708 ipmi_cmdlang_lock(cmd_info);
709 if (err) {
710 if (! cmdlang->err) {
711 cmdlang->err = err;
712 cmdlang->errstr = "Error scanning domain";
713 ipmi_domain_get_name(domain, cmdlang->objstr,
714 cmdlang->objstr_len);
715 cmdlang->location = "cmd_domain.c(scan_done)";
716 }
717 goto out;
718 }
719
720 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
721 ipmi_cmdlang_out(cmd_info, "Scan done", domain_name);
722
723 out:
724 ipmi_cmdlang_unlock(cmd_info);
725 ipmi_cmdlang_cmd_info_put(cmd_info);
726 }
727
728 static void
domain_scan(ipmi_domain_t * domain,void * cb_data)729 domain_scan(ipmi_domain_t *domain, void *cb_data)
730 {
731 ipmi_cmd_info_t *cmd_info = cb_data;
732 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
733 int rv;
734 int channel;
735 int ipmb1, ipmb2;
736 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
737 int argc = ipmi_cmdlang_get_argc(cmd_info);
738 char **argv = ipmi_cmdlang_get_argv(cmd_info);
739
740 if ((argc - curr_arg) < 2) {
741 /* Not enough parameters */
742 cmdlang->errstr = "Not enough parameters";
743 cmdlang->err = EINVAL;
744 goto out_err;
745 }
746
747 ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
748 if (cmdlang->err) {
749 cmdlang->errstr = "channel invalid";
750 goto out_err;
751 }
752 curr_arg++;
753
754 ipmi_cmdlang_get_int(argv[curr_arg], &ipmb1, cmd_info);
755 if (cmdlang->err) {
756 cmdlang->errstr = "ipmb1 invalid";
757 goto out_err;
758 }
759 curr_arg++;
760
761 if (curr_arg < argc) {
762 ipmi_cmdlang_get_int(argv[curr_arg], &ipmb2, cmd_info);
763 if (cmdlang->err) {
764 cmdlang->errstr = "ipmb2 invalid";
765 goto out_err;
766 }
767 curr_arg++;
768 } else
769 ipmb2 = ipmb1;
770
771 ipmi_cmdlang_cmd_info_get(cmd_info);
772 rv = ipmi_start_ipmb_mc_scan(domain, channel, ipmb1, ipmb2,
773 scan_done, cmd_info);
774 if (rv) {
775 ipmi_cmdlang_cmd_info_put(cmd_info);
776 cmdlang->errstr = "Error requesting scan";
777 cmdlang->err = rv;
778 goto out_err;
779 }
780
781 out_err:
782 if (cmdlang->err) {
783 ipmi_domain_get_name(domain, cmdlang->objstr,
784 cmdlang->objstr_len);
785 cmdlang->location = "cmd_domain.c(domain_scan)";
786 }
787 }
788
789 static void
domain_rescan_sels_done(ipmi_domain_t * domain,int err,void * cb_data)790 domain_rescan_sels_done(ipmi_domain_t *domain, int err, void *cb_data)
791 {
792 ipmi_cmd_info_t *cmd_info = cb_data;
793 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
794 char domain_name[IPMI_DOMAIN_NAME_LEN];
795
796 ipmi_cmdlang_lock(cmd_info);
797 if (err) {
798 if (! cmdlang->err) {
799 cmdlang->err = err;
800 cmdlang->errstr = "Error scanning SELs";
801 ipmi_domain_get_name(domain, cmdlang->objstr,
802 cmdlang->objstr_len);
803 cmdlang->location = "cmd_domain.c(sel_rescan_done)";
804 }
805 goto out;
806 }
807
808 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
809 ipmi_cmdlang_out(cmd_info, "SEL Rescan done", domain_name);
810
811 out:
812 ipmi_cmdlang_unlock(cmd_info);
813 ipmi_cmdlang_cmd_info_put(cmd_info);
814 }
815
816 static void
domain_rescan_sels(ipmi_domain_t * domain,void * cb_data)817 domain_rescan_sels(ipmi_domain_t *domain, void *cb_data)
818 {
819 ipmi_cmd_info_t *cmd_info = cb_data;
820 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
821 int rv;
822
823 ipmi_cmdlang_cmd_info_get(cmd_info);
824 rv = ipmi_domain_reread_sels(domain, domain_rescan_sels_done, cmd_info);
825 if (rv) {
826 ipmi_cmdlang_cmd_info_put(cmd_info);
827 cmdlang->errstr = "Error requesting SEL rescan";
828 cmdlang->err = rv;
829 goto out_err;
830 }
831
832 out_err:
833 if (cmdlang->err) {
834 ipmi_domain_get_name(domain, cmdlang->objstr,
835 cmdlang->objstr_len);
836 cmdlang->location = "cmd_domain.c(domain_rescan_sels)";
837 }
838 }
839
840 static void
domain_presence(ipmi_domain_t * domain,void * cb_data)841 domain_presence(ipmi_domain_t *domain, void *cb_data)
842 {
843 ipmi_cmd_info_t *cmd_info = cb_data;
844 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
845 int rv;
846 char domain_name[IPMI_DOMAIN_NAME_LEN];
847
848 rv = ipmi_detect_domain_presence_changes(domain, 1);
849 if (rv) {
850 cmdlang->err = rv;
851 ipmi_domain_get_name(domain, cmdlang->objstr,
852 cmdlang->objstr_len);
853 cmdlang->location = "cmd_domain.c(domain_presence)";
854 goto out;
855 }
856 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
857 ipmi_cmdlang_out(cmd_info, "Presence check started", domain_name);
858 out:
859 return;
860 }
861
862 static void
domain_sel_rescan_time(ipmi_domain_t * domain,void * cb_data)863 domain_sel_rescan_time(ipmi_domain_t *domain, void *cb_data)
864 {
865 ipmi_cmd_info_t *cmd_info = cb_data;
866 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
867 int time;
868 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
869 int argc = ipmi_cmdlang_get_argc(cmd_info);
870 char **argv = ipmi_cmdlang_get_argv(cmd_info);
871 char domain_name[IPMI_DOMAIN_NAME_LEN];
872
873 if ((argc - curr_arg) < 1) {
874 /* Not enough parameters */
875 cmdlang->errstr = "Not enough parameters";
876 cmdlang->err = EINVAL;
877 goto out_err;
878 }
879
880 ipmi_cmdlang_get_int(argv[curr_arg], &time, cmd_info);
881 if (cmdlang->err) {
882 cmdlang->errstr = "time invalid";
883 goto out_err;
884 }
885 curr_arg++;
886
887 ipmi_domain_set_sel_rescan_time(domain, time);
888
889 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
890 ipmi_cmdlang_out(cmd_info, "Domain SEL rescan time set", domain_name);
891
892 out_err:
893 if (cmdlang->err) {
894 ipmi_domain_get_name(domain, cmdlang->objstr,
895 cmdlang->objstr_len);
896 cmdlang->location = "cmd_domain.c(domain_sel_rescan_time)";
897 }
898 }
899
900
901 static void
domain_ipmb_rescan_time(ipmi_domain_t * domain,void * cb_data)902 domain_ipmb_rescan_time(ipmi_domain_t *domain, void *cb_data)
903 {
904 ipmi_cmd_info_t *cmd_info = cb_data;
905 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
906 int time;
907 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
908 int argc = ipmi_cmdlang_get_argc(cmd_info);
909 char **argv = ipmi_cmdlang_get_argv(cmd_info);
910 char domain_name[IPMI_DOMAIN_NAME_LEN];
911
912 if ((argc - curr_arg) < 1) {
913 cmdlang->errstr = "Not enough parameters";
914 cmdlang->err = EINVAL;
915 goto out_err;
916 }
917
918 ipmi_cmdlang_get_int(argv[curr_arg], &time, cmd_info);
919 if (cmdlang->err) {
920 cmdlang->errstr = "time invalid";
921 goto out_err;
922 }
923 curr_arg++;
924
925 ipmi_domain_set_ipmb_rescan_time(domain, time);
926
927 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
928 ipmi_cmdlang_out(cmd_info, "Domain IPMB rescan time set", domain_name);
929
930 out_err:
931 if (cmdlang->err) {
932 ipmi_domain_get_name(domain, cmdlang->objstr,
933 cmdlang->objstr_len);
934 cmdlang->location = "cmd_domain.c(domain_ipmb_rescan_time)";
935 }
936 }
937
938 static void
handle_stat(ipmi_domain_t * domain,ipmi_domain_stat_t * stat,void * cb_data)939 handle_stat(ipmi_domain_t *domain, ipmi_domain_stat_t *stat, void *cb_data)
940 {
941 ipmi_cmd_info_t *cmd_info = cb_data;
942 const char *name = ipmi_domain_stat_get_name(stat);
943 const char *inst = ipmi_domain_stat_get_instance(stat);
944 char *s = ipmi_mem_alloc(strlen(name) + strlen(inst) + 2);
945
946 if (!s)
947 return;
948 sprintf(s, "%s %s", name, inst);
949 ipmi_cmdlang_out_int(cmd_info, s, ipmi_domain_stat_get(stat));
950 ipmi_mem_free(s);
951 }
952
953 static void
domain_stats(ipmi_domain_t * domain,void * cb_data)954 domain_stats(ipmi_domain_t *domain, void *cb_data)
955 {
956 ipmi_cmd_info_t *cmd_info = cb_data;
957 char domain_name[IPMI_DOMAIN_NAME_LEN];
958
959 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
960 ipmi_cmdlang_out(cmd_info, "Domain statistics", NULL);
961 ipmi_cmdlang_down(cmd_info);
962 ipmi_cmdlang_out(cmd_info, "Domain", domain_name);
963 ipmi_domain_stat_iterate(domain, NULL, NULL, handle_stat, cmd_info);
964 ipmi_cmdlang_up(cmd_info);
965 }
966
967 typedef struct domain_close_info_s
968 {
969 char domain_name[IPMI_DOMAIN_NAME_LEN];
970 ipmi_cmd_info_t *cmd_info;
971 } domain_close_info_t;
972
973 static void
final_close(void * cb_data)974 final_close(void *cb_data)
975 {
976 domain_close_info_t *info = cb_data;
977 ipmi_cmd_info_t *cmd_info = info->cmd_info;
978
979 ipmi_cmdlang_lock(cmd_info);
980 ipmi_cmdlang_out(cmd_info, "Domain closed", info->domain_name);
981 ipmi_cmdlang_unlock(cmd_info);
982
983 ipmi_mem_free(info);
984
985 ipmi_cmdlang_cmd_info_put(cmd_info);
986 }
987
988 static void
domain_close(ipmi_domain_t * domain,void * cb_data)989 domain_close(ipmi_domain_t *domain, void *cb_data)
990 {
991 ipmi_cmd_info_t *cmd_info = cb_data;
992 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
993 int rv;
994 domain_close_info_t *info = cb_data;
995
996 info = ipmi_mem_alloc(sizeof(*info));
997 if (!info) {
998 cmdlang->errstr = "Out of memory";
999 cmdlang->err = ENOMEM;
1000 goto out_err;
1001 }
1002 ipmi_domain_get_name(domain, info->domain_name, sizeof(info->domain_name));
1003 info->cmd_info = cmd_info;
1004
1005 ipmi_cmdlang_cmd_info_get(cmd_info);
1006 rv = ipmi_domain_close(domain, final_close, info);
1007 if (rv) {
1008 ipmi_cmdlang_cmd_info_put(cmd_info);
1009 cmdlang->errstr = "Unable to close domain";
1010 cmdlang->err = rv;
1011 goto out_err;
1012 }
1013 return;
1014
1015 out_err:
1016 ipmi_domain_get_name(domain, cmdlang->objstr,
1017 cmdlang->objstr_len);
1018 cmdlang->location = "cmd_domain.c(domain_close)";
1019 }
1020
1021
1022 /**********************************************************************
1023 *
1024 * Domain event handling.
1025 *
1026 **********************************************************************/
1027
1028 static void
domain_event_handler(ipmi_domain_t * domain,ipmi_event_t * event,void * cb_data)1029 domain_event_handler(ipmi_domain_t *domain,
1030 ipmi_event_t *event,
1031 void *cb_data)
1032 {
1033 char *errstr = NULL;
1034 int rv = 0;
1035 ipmi_cmd_info_t *evi;
1036
1037 evi = ipmi_cmdlang_alloc_event_info();
1038 if (!evi) {
1039 rv = ENOMEM;
1040 errstr = "Out of memory";
1041 goto out_err;
1042 }
1043
1044 ipmi_cmdlang_out(evi, "Object Type", "Event");
1045 ipmi_cmdlang_event_out(event, evi);
1046
1047 out_err:
1048 if (rv) {
1049 char domain_name[IPMI_DOMAIN_NAME_LEN];
1050
1051 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
1052 ipmi_cmdlang_global_err(domain_name,
1053 "cmd_domain.c(domain_event_handler)",
1054 errstr, rv);
1055 }
1056 if (evi)
1057 ipmi_cmdlang_cmd_info_put(evi);
1058 }
1059
1060 static void
domain_con_change(ipmi_domain_t * domain,int err,unsigned int conn_num,unsigned int port_num,int still_connected,void * cb_data)1061 domain_con_change(ipmi_domain_t *domain,
1062 int err,
1063 unsigned int conn_num,
1064 unsigned int port_num,
1065 int still_connected,
1066 void *cb_data)
1067 {
1068 char *errstr;
1069 int rv = 0;
1070 ipmi_cmd_info_t *evi;
1071 char domain_name[IPMI_DOMAIN_NAME_LEN];
1072
1073 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
1074
1075 evi = ipmi_cmdlang_alloc_event_info();
1076 if (!evi) {
1077 rv = ENOMEM;
1078 errstr = "Out of memory";
1079 goto out_err;
1080 }
1081
1082 ipmi_cmdlang_out(evi, "Object Type", "Domain");
1083 ipmi_cmdlang_out(evi, "Name", domain_name);
1084 ipmi_cmdlang_out(evi, "Operation", "Connection Change");
1085 ipmi_cmdlang_out_int(evi, "Connection Number", conn_num);
1086 ipmi_cmdlang_out_int(evi, "Port Number", port_num);
1087 ipmi_cmdlang_out_bool(evi, "Any Connection Up", still_connected);
1088 ipmi_cmdlang_out_int(evi, "Error", err);
1089
1090 if (err) {
1091 char errval[128];
1092 ipmi_cmdlang_out(evi, "Error String",
1093 ipmi_get_error_string(err, errval, sizeof(errval)));
1094
1095 }
1096 errstr = NULL; /* Get rid of warning */
1097
1098 out_err:
1099 if (rv) {
1100 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
1101 ipmi_cmdlang_global_err(domain_name, "cmd_domain.c(domain_con_change)",
1102 errstr, rv);
1103 }
1104 if (evi)
1105 ipmi_cmdlang_cmd_info_put(evi);
1106 }
1107
1108 void
domain_change(ipmi_domain_t * domain,enum ipmi_update_e op,void * cb_data)1109 domain_change(ipmi_domain_t *domain,
1110 enum ipmi_update_e op,
1111 void *cb_data)
1112 {
1113 ipmi_cmd_info_t *evi;
1114 int rv = 0;
1115 char *errstr = NULL;
1116 char domain_name[IPMI_DOMAIN_NAME_LEN];
1117
1118 evi = ipmi_cmdlang_alloc_event_info();
1119 if (!evi) {
1120 rv = ENOMEM;
1121 errstr = "Out of memory";
1122 goto out_err;
1123 }
1124
1125 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
1126
1127
1128 ipmi_cmdlang_out(evi, "Object Type", "Domain");
1129 ipmi_cmdlang_out(evi, "Name", domain_name);
1130
1131 switch (op) {
1132 case IPMI_ADDED:
1133 ipmi_cmdlang_out(evi, "Operation", "Add");
1134 if (ipmi_cmdlang_get_evinfo()) {
1135 ipmi_cmdlang_down(evi);
1136 domain_info(domain, evi);
1137 ipmi_cmdlang_up(evi);
1138 }
1139 /* Register handlers. */
1140 rv = ipmi_domain_add_event_handler(domain, domain_event_handler, NULL);
1141 if (rv) {
1142 errstr = "ipmi_register_for_events";
1143 goto out_err;
1144 }
1145
1146 rv = ipmi_domain_enable_events(domain);
1147 if (rv) {
1148 errstr = "ipmi_domain_enable_events";
1149 goto out_err;
1150 }
1151
1152 rv = ipmi_domain_add_entity_update_handler(domain,
1153 ipmi_cmdlang_entity_change,
1154 domain);
1155 if (rv) {
1156 errstr = "ipmi_bmc_set_entity_update_handler";
1157 goto out_err;
1158 }
1159
1160 rv = ipmi_domain_add_mc_updated_handler(domain,
1161 ipmi_cmdlang_mc_change,
1162 domain);
1163 if (rv) {
1164 errstr = "ipmi_bmc_set_entity_update_handler";
1165 goto out_err;
1166 }
1167 break;
1168
1169 case IPMI_DELETED:
1170 ipmi_cmdlang_out(evi, "Operation", "Delete");
1171 break;
1172
1173 default:
1174 break;
1175 }
1176
1177 out_err:
1178 /* FIXME - should we shut the connection down on errors? */
1179 if (rv) {
1180 ipmi_cmdlang_global_err(domain_name, "cmd_domain.c(domain_change)",
1181 errstr, rv);
1182 }
1183 if (evi)
1184 ipmi_cmdlang_cmd_info_put(evi);
1185 }
1186
1187 static void
get_mc_name(ipmi_mc_t * mc,void * cb_data)1188 get_mc_name(ipmi_mc_t *mc, void *cb_data)
1189 {
1190 char *mc_name = cb_data;
1191
1192 ipmi_mc_get_name(mc, mc_name, IPMI_MC_NAME_LEN);
1193 }
1194
1195 void
ipmi_cmdlang_event_out(ipmi_event_t * event,ipmi_cmd_info_t * cmd_info)1196 ipmi_cmdlang_event_out(ipmi_event_t *event,
1197 ipmi_cmd_info_t *cmd_info)
1198 {
1199 ipmi_mcid_t mcid;
1200 char mc_name[IPMI_MC_NAME_LEN];
1201 unsigned int len;
1202 int rv;
1203
1204 mcid = ipmi_event_get_mcid(event);
1205 rv = ipmi_mc_pointer_cb(mcid, get_mc_name, mc_name);
1206 if (rv) {
1207 /* The MC went away, that's actually ok, just ignore it. */
1208 ipmi_cmdlang_cmd_info_put(cmd_info);
1209 return;
1210 }
1211
1212 ipmi_cmdlang_out(cmd_info, "MC", mc_name);
1213 ipmi_cmdlang_out_int(cmd_info, "Record ID",
1214 ipmi_event_get_record_id(event));
1215 ipmi_cmdlang_out_int(cmd_info, "Event type", ipmi_event_get_type(event));
1216 ipmi_cmdlang_out_time(cmd_info, "Timestamp",
1217 ipmi_event_get_timestamp(event));
1218 len = ipmi_event_get_data_len(event);
1219 if (len) {
1220 unsigned char *data;
1221 data = ipmi_mem_alloc(len);
1222 if (!data)
1223 return;
1224 len = ipmi_event_get_data(event, data, 0, len);
1225 ipmi_cmdlang_out_binary(cmd_info, "Data", (char *) data, len);
1226 ipmi_mem_free(data);
1227 }
1228 }
1229
1230 static ipmi_cmdlang_cmd_t *domain_cmds;
1231
1232 static ipmi_cmdlang_init_t cmds_domain[] =
1233 {
1234 { "domain", NULL,
1235 "- Commands dealing with domains",
1236 NULL, NULL, &domain_cmds},
1237 { "list", &domain_cmds,
1238 "- List all the domains in the system",
1239 domain_list, NULL, NULL },
1240 { "info", &domain_cmds,
1241 "<domain> - Dump information about a domain",
1242 ipmi_cmdlang_domain_handler, domain_info, NULL },
1243 { "new", &domain_cmds,
1244 "Obsolete, use domain open",
1245 domain_new, NULL, NULL },
1246 { "open", &domain_cmds,
1247 "<domain name> [<options>] <domain parms> [<domain parms>]- Set up a"
1248 " new domain using an argument parser. Format for the connection's"
1249 " <domain parms> depends on the connections type. Two connections"
1250 " (to two different MCs) can be done by specifying two sets of parms."
1251 " Connections types are:",
1252 domain_open, NULL, NULL, domain_open_help },
1253 { "close", &domain_cmds,
1254 "<domain> - Close the domain",
1255 ipmi_cmdlang_domain_handler, domain_close, NULL },
1256 { "fru", &domain_cmds,
1257 "<domain> <is_logical> <device_address> <device_id>"
1258 " <lun> <private_bus> <channel>"
1259 " - Fetch FRU data with the given parms",
1260 ipmi_cmdlang_domain_handler, domain_fru, NULL },
1261 { "msg", &domain_cmds,
1262 "<domain> <channel> <ipmb> <LUN> <NetFN> <command> [data...]"
1263 " - Send a message to the given address",
1264 ipmi_cmdlang_domain_handler, domain_msg, NULL },
1265 { "scan", &domain_cmds,
1266 "<domain> <channel> <ipmb addr> [ipmb addr]"
1267 " - scan an IPMB to add or remove it. If a range is given,"
1268 " then scan all IPMBs in the range",
1269 ipmi_cmdlang_domain_handler, domain_scan, NULL },
1270 { "presence", &domain_cmds,
1271 "<domain> - Check the presence of all entities in the domain",
1272 ipmi_cmdlang_domain_handler, domain_presence, NULL },
1273 { "sel_rescan_time", &domain_cmds,
1274 "<domain> <time in seconds> - Set the time between SEL rescans"
1275 " for all SELs in the domain. Zero disables scans.",
1276 ipmi_cmdlang_domain_handler, domain_sel_rescan_time, NULL },
1277 { "rescan_sels", &domain_cmds,
1278 "<domain> - Rescan all the SELs in the domain",
1279 ipmi_cmdlang_domain_handler, domain_rescan_sels, NULL },
1280 { "ipmb_rescan_time", &domain_cmds,
1281 "<domain> <time in seconds> - Set the time between IPMB rescans"
1282 " for this domain. zero disables scans.",
1283 ipmi_cmdlang_domain_handler, domain_ipmb_rescan_time, NULL },
1284 { "stats", &domain_cmds,
1285 "<domain> - Dump all the domain's statistics",
1286 ipmi_cmdlang_domain_handler, domain_stats, NULL },
1287 };
1288 #define CMDS_DOMAIN_LEN (sizeof(cmds_domain)/sizeof(ipmi_cmdlang_init_t))
1289
1290 int
ipmi_cmdlang_domain_init(os_handler_t * os_hnd)1291 ipmi_cmdlang_domain_init(os_handler_t *os_hnd)
1292 {
1293 int rv;
1294
1295 rv = ipmi_domain_add_domain_change_handler(domain_change, NULL);
1296 if (rv)
1297 return rv;
1298
1299 return ipmi_cmdlang_reg_table(cmds_domain, CMDS_DOMAIN_LEN);
1300 }
1301