00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <errno.h>
00035 #include <string.h>
00036 #include <ctype.h>
00037 #include <stdlib.h>
00038 #include <stdio.h>
00039 #include <OpenIPMI/ipmiif.h>
00040 #include <OpenIPMI/ipmi_mc.h>
00041 #include <OpenIPMI/ipmi_cmdlang.h>
00042 #include <OpenIPMI/ipmi_fru.h>
00043
00044
00045 #include <OpenIPMI/internal/ipmi_malloc.h>
00046
00047
00048 void ipmi_cmdlang_dump_fru_info(ipmi_cmd_info_t *cmd_info, ipmi_fru_t *fru);
00049
00050 static void
00051 fru_list_handler(ipmi_fru_t *fru, void *cb_data)
00052 {
00053 ipmi_cmd_info_t *cmd_info = cb_data;
00054 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00055 char fru_name[IPMI_FRU_NAME_LEN];
00056
00057 if (cmdlang->err)
00058 return;
00059
00060 ipmi_fru_get_name(fru, fru_name, sizeof(fru_name));
00061
00062 ipmi_cmdlang_out(cmd_info, "Name", fru_name);
00063 }
00064
00065 static void
00066 fru_list(ipmi_domain_t *domain, void *cb_data)
00067 {
00068 ipmi_cmd_info_t *cmd_info = cb_data;
00069 char domain_name[IPMI_DOMAIN_NAME_LEN];
00070
00071 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
00072 ipmi_cmdlang_out(cmd_info, "Domain", NULL);
00073 ipmi_cmdlang_down(cmd_info);
00074 ipmi_cmdlang_out(cmd_info, "Name", domain_name);
00075 ipmi_cmdlang_out(cmd_info, "FRUs", NULL);
00076 ipmi_cmdlang_down(cmd_info);
00077 ipmi_fru_iterate_frus(domain, fru_list_handler, cmd_info);
00078 ipmi_cmdlang_up(cmd_info);
00079 ipmi_cmdlang_up(cmd_info);
00080 }
00081
00082 static void
00083 fru_info(ipmi_fru_t *fru, void *cb_data)
00084 {
00085 ipmi_cmd_info_t *cmd_info = cb_data;
00086 char fru_name[IPMI_FRU_NAME_LEN];
00087
00088 ipmi_fru_get_name(fru, fru_name, sizeof(fru_name));
00089
00090 ipmi_cmdlang_dump_fru_info(cmd_info, fru);
00091 }
00092
00093 static char *areas[IPMI_FRU_FTR_NUMBER] =
00094 {
00095 "internal_use",
00096 "chassis_info",
00097 "board_info",
00098 "product_info",
00099 "multi_record"
00100 };
00101
00102 static void
00103 fru_areainfo(ipmi_fru_t *fru, void *cb_data)
00104 {
00105 ipmi_cmd_info_t *cmd_info = cb_data;
00106 char fru_name[IPMI_FRU_NAME_LEN];
00107 int i;
00108 int rv;
00109
00110 ipmi_fru_get_name(fru, fru_name, sizeof(fru_name));
00111
00112 ipmi_cmdlang_out(cmd_info, "FRU", NULL);
00113 ipmi_cmdlang_down(cmd_info);
00114 ipmi_cmdlang_out(cmd_info, "Name", fru_name);
00115 ipmi_cmdlang_out_int(cmd_info, "FRU Length",
00116 ipmi_fru_get_data_length(fru));
00117 for (i=0; i<IPMI_FRU_FTR_NUMBER; i++) {
00118 unsigned int offset, length, used_length;
00119 rv = ipmi_fru_area_get_offset(fru, i, &offset);
00120 rv |= ipmi_fru_area_get_length(fru, i, &length);
00121 rv |= ipmi_fru_area_get_used_length(fru, i, &used_length);
00122 if (rv)
00123 continue;
00124 ipmi_cmdlang_out(cmd_info, "Area", NULL);
00125 ipmi_cmdlang_down(cmd_info);
00126 ipmi_cmdlang_out(cmd_info, "Name", areas[i]);
00127 ipmi_cmdlang_out_int(cmd_info, "Number", i);
00128 ipmi_cmdlang_out_int(cmd_info, "Offset", offset);
00129 ipmi_cmdlang_out_int(cmd_info, "Length", length);
00130 ipmi_cmdlang_out_int(cmd_info, "Used Length", used_length);
00131 ipmi_cmdlang_up(cmd_info);
00132 }
00133 ipmi_cmdlang_up(cmd_info);
00134 }
00135
00136 static void
00137 fru_written(ipmi_domain_t *domain, ipmi_fru_t *fru, int err, void *cb_data)
00138 {
00139 ipmi_cmd_info_t *cmd_info = cb_data;
00140 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00141 char fru_name[IPMI_FRU_NAME_LEN];
00142
00143 if (err) {
00144 cmdlang->errstr = "Unable to write FRU";
00145 cmdlang->err = err;
00146 ipmi_fru_get_name(fru, cmdlang->objstr,
00147 cmdlang->objstr_len);
00148 cmdlang->location = "cmd_fru.c(fru_written)";
00149 } else {
00150 ipmi_fru_get_name(fru, fru_name, sizeof(fru_name));
00151 ipmi_cmdlang_out(cmd_info, "FRU written", fru_name);
00152 }
00153
00154 ipmi_cmdlang_cmd_info_put(cmd_info);
00155 }
00156
00157 static void
00158 fru_write(ipmi_fru_t *fru, void *cb_data)
00159 {
00160 ipmi_cmd_info_t *cmd_info = cb_data;
00161 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00162 int rv;
00163
00164 ipmi_cmdlang_cmd_info_get(cmd_info);
00165 rv = ipmi_fru_write(fru, fru_written, cmd_info);
00166 if (rv) {
00167 ipmi_cmdlang_cmd_info_put(cmd_info);
00168 cmdlang->errstr = "Unable to write FRU";
00169 cmdlang->err = rv;
00170 goto out_err;
00171 }
00172
00173 return;
00174
00175 out_err:
00176 ipmi_fru_get_name(fru, cmdlang->objstr,
00177 cmdlang->objstr_len);
00178 cmdlang->location = "cmd_fru.c(fru_write)";
00179 }
00180
00181 static void
00182 fru_deleted(ipmi_fru_t *fru, void *cb_data)
00183 {
00184 ipmi_cmd_info_t *cmd_info = cb_data;
00185 char fru_name[IPMI_FRU_NAME_LEN];
00186
00187 ipmi_fru_get_name(fru, fru_name, sizeof(fru_name));
00188 ipmi_cmdlang_out(cmd_info, "FRU deleted", fru_name);
00189 ipmi_cmdlang_cmd_info_put(cmd_info);
00190 }
00191
00192 static void
00193 fru_close(ipmi_fru_t *fru, void *cb_data)
00194 {
00195 ipmi_cmd_info_t *cmd_info = cb_data;
00196 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00197 int rv;
00198
00199 ipmi_cmdlang_cmd_info_get(cmd_info);
00200
00201
00202
00203 ipmi_fru_ref(fru);
00204 rv = ipmi_fru_destroy(fru, fru_deleted, cmd_info);
00205 if (rv) {
00206 ipmi_cmdlang_cmd_info_put(cmd_info);
00207 cmdlang->errstr = "Unable to close domain";
00208 cmdlang->err = rv;
00209 goto out_err;
00210 }
00211
00212 return;
00213
00214 out_err:
00215 ipmi_fru_get_name(fru, cmdlang->objstr,
00216 cmdlang->objstr_len);
00217 cmdlang->location = "cmd_fru.c(fru_close)";
00218 }
00219
00220 static void
00221 fru_setval(ipmi_fru_t *fru, void *cb_data)
00222 {
00223 ipmi_cmd_info_t *cmd_info = cb_data;
00224 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00225 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00226 int argc = ipmi_cmdlang_get_argc(cmd_info);
00227 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00228 char fru_name[IPMI_FRU_NAME_LEN];
00229 enum ipmi_fru_data_type_e dtype;
00230 int i;
00231 int num;
00232 const char *name;
00233 int ival;
00234 double dval;
00235 int rv;
00236 int len;
00237 unsigned char *data;
00238 int j;
00239 int type;
00240 int version;
00241
00242 if ((argc - curr_arg) < 2) {
00243
00244 cmdlang->errstr = "Not enough parameters";
00245 cmdlang->err = EINVAL;
00246 goto out_err;
00247 }
00248
00249 if (strcmp(argv[curr_arg], "multi_record") == 0)
00250 goto do_multi_record;
00251
00252 for (i=0; ; i++) {
00253 num = -2;
00254 rv = ipmi_fru_get(fru, i, &name, &num, &dtype, NULL, NULL, NULL, NULL);
00255 if (rv == EINVAL) {
00256 cmdlang->errstr = "Name not found";
00257 cmdlang->err = EINVAL;
00258 goto out_err;
00259 }
00260 if (strcmp(name, argv[curr_arg]) == 0)
00261 break;
00262 }
00263 curr_arg++;
00264
00265 if (num != -2) {
00266
00267 ipmi_cmdlang_get_int(argv[curr_arg], &num, cmd_info);
00268 if (cmdlang->err) {
00269 cmdlang->errstr = "value number";
00270 goto out_err;
00271 }
00272 curr_arg++;
00273
00274 if ((argc - curr_arg) < 1) {
00275
00276 cmdlang->errstr = "Not enough parameters";
00277 cmdlang->err = EINVAL;
00278 goto out_err;
00279 }
00280 }
00281
00282 switch (dtype) {
00283 case IPMI_FRU_DATA_TIME:
00284 ipmi_cmdlang_get_int(argv[curr_arg], &ival, cmd_info);
00285 if (cmdlang->err) {
00286 cmdlang->errstr = "value invalid";
00287 goto out_err;
00288 }
00289 curr_arg++;
00290 rv = ipmi_fru_set_time_val(fru, i, num, ival);
00291 if (rv) {
00292 cmdlang->errstr = "value invalid";
00293 cmdlang->err = EINVAL;
00294 goto out_err;
00295 }
00296 break;
00297
00298 case IPMI_FRU_DATA_INT:
00299 ipmi_cmdlang_get_int(argv[curr_arg], &ival, cmd_info);
00300 if (cmdlang->err) {
00301 cmdlang->errstr = "value invalid";
00302 goto out_err;
00303 }
00304 curr_arg++;
00305 rv = ipmi_fru_set_int_val(fru, i, num, ival);
00306 if (rv) {
00307 cmdlang->errstr = "value invalid";
00308 cmdlang->err = EINVAL;
00309 goto out_err;
00310 }
00311 break;
00312
00313 case IPMI_FRU_DATA_BOOLEAN:
00314 ipmi_cmdlang_get_bool(argv[curr_arg], &ival, cmd_info);
00315 if (cmdlang->err) {
00316 cmdlang->errstr = "value invalid";
00317 goto out_err;
00318 }
00319 curr_arg++;
00320 rv = ipmi_fru_set_int_val(fru, i, num, ival);
00321 if (rv) {
00322 cmdlang->errstr = "value invalid";
00323 cmdlang->err = EINVAL;
00324 goto out_err;
00325 }
00326 break;
00327
00328 case IPMI_FRU_DATA_FLOAT:
00329 ipmi_cmdlang_get_double(argv[curr_arg], &dval, cmd_info);
00330 if (cmdlang->err) {
00331 cmdlang->errstr = "value invalid";
00332 goto out_err;
00333 }
00334 curr_arg++;
00335 rv = ipmi_fru_set_float_val(fru, i, num, dval);
00336 if (rv) {
00337 cmdlang->errstr = "value invalid";
00338 cmdlang->err = EINVAL;
00339 goto out_err;
00340 }
00341 break;
00342
00343 case IPMI_FRU_DATA_ASCII:
00344 case IPMI_FRU_DATA_BINARY:
00345 case IPMI_FRU_DATA_UNICODE:
00346 if ((argc - curr_arg) < 1) {
00347
00348 cmdlang->errstr = "Not enough parameters";
00349 cmdlang->err = EINVAL;
00350 goto out_err;
00351 }
00352 if (strcasecmp(argv[curr_arg], "binary") == 0) {
00353 dtype = IPMI_FRU_DATA_BINARY;
00354 } else if (strcasecmp(argv[curr_arg], "ascii") == 0) {
00355 dtype = IPMI_FRU_DATA_ASCII;
00356 } else if (strcasecmp(argv[curr_arg], "unicode") == 0) {
00357 dtype = IPMI_FRU_DATA_UNICODE;
00358 } else {
00359 cmdlang->errstr = "Invalid data type";
00360 cmdlang->err = EINVAL;
00361 goto out_err;
00362 }
00363 curr_arg++;
00364 if (dtype == IPMI_FRU_DATA_ASCII) {
00365 char *str;
00366 int len;
00367 if (curr_arg < argc) {
00368 str = argv[curr_arg];
00369 len = strlen(str);
00370 } else {
00371 str = NULL;
00372 len = 0;
00373 }
00374 rv = ipmi_fru_set_data_val(fru, i, num, dtype, str, len);
00375 } else {
00376 len = argc - curr_arg;
00377
00378 if (len == 0)
00379 data = ipmi_mem_alloc(1);
00380 else
00381 data = ipmi_mem_alloc(len);
00382 if (!data) {
00383 cmdlang->errstr = "Out of memory";
00384 cmdlang->err = ENOMEM;
00385 goto out_err;
00386 }
00387 j = 0;
00388 while (curr_arg < argc) {
00389 ipmi_cmdlang_get_int(argv[curr_arg], &ival, cmd_info);
00390 if (cmdlang->err) {
00391 cmdlang->errstr = "value invalid";
00392 ipmi_mem_free(data);
00393 goto out_err;
00394 }
00395 data[j] = ival;
00396 curr_arg++;
00397 j++;
00398 }
00399 rv = ipmi_fru_set_data_val(fru, i, num, dtype, (char *) data, len);
00400 ipmi_mem_free(data);
00401 }
00402 if (rv) {
00403 cmdlang->errstr = "Error setting data value";
00404 cmdlang->err = rv;
00405 goto out_err;
00406 }
00407
00408 case IPMI_FRU_DATA_SUB_NODE:
00409
00410 break;
00411 }
00412
00413 goto out;
00414
00415 do_multi_record:
00416 curr_arg++;
00417 if ((argc - curr_arg) < 1) {
00418
00419 cmdlang->errstr = "Not enough parameters";
00420 cmdlang->err = EINVAL;
00421 goto out_err;
00422 }
00423
00424 ipmi_cmdlang_get_int(argv[curr_arg], &num, cmd_info);
00425 if (cmdlang->err) {
00426 cmdlang->errstr = "value number";
00427 goto out_err;
00428 }
00429 curr_arg++;
00430
00431 if ((argc - curr_arg) == 0) {
00432
00433 rv = ipmi_fru_set_multi_record(fru, num, 0, 0, NULL, 0);
00434 if (rv) {
00435 cmdlang->errstr = "Error clearing data value";
00436 cmdlang->err = rv;
00437 goto out_err;
00438 }
00439 goto out;
00440 }
00441
00442 if ((argc - curr_arg) < 2) {
00443
00444 cmdlang->errstr = "Not enough parameters";
00445 cmdlang->err = EINVAL;
00446 goto out_err;
00447 }
00448
00449 ipmi_cmdlang_get_int(argv[curr_arg], &type, cmd_info);
00450 if (cmdlang->err) {
00451 cmdlang->errstr = "type number";
00452 goto out_err;
00453 }
00454 curr_arg++;
00455
00456 ipmi_cmdlang_get_int(argv[curr_arg], &version, cmd_info);
00457 if (cmdlang->err) {
00458 cmdlang->errstr = "version number";
00459 goto out_err;
00460 }
00461 curr_arg++;
00462
00463 len = argc - curr_arg;
00464
00465 if (len == 0)
00466 data = ipmi_mem_alloc(1);
00467 else
00468 data = ipmi_mem_alloc(len);
00469 if (!data) {
00470 cmdlang->errstr = "Out of memory";
00471 cmdlang->err = ENOMEM;
00472 goto out_err;
00473 }
00474 j = 0;
00475 while (curr_arg < argc) {
00476 ipmi_cmdlang_get_int(argv[curr_arg], &ival, cmd_info);
00477 if (cmdlang->err) {
00478 cmdlang->errstr = "value invalid";
00479 ipmi_mem_free(data);
00480 goto out_err;
00481 }
00482 data[j] = ival;
00483 curr_arg++;
00484 j++;
00485 }
00486 rv = ipmi_fru_set_multi_record(fru, num, type, version, data, len);
00487 ipmi_mem_free(data);
00488 if (rv) {
00489 cmdlang->errstr = "Error setting data value";
00490 cmdlang->err = rv;
00491 goto out_err;
00492 }
00493
00494 out:
00495 ipmi_fru_get_name(fru, fru_name, sizeof(fru_name));
00496 ipmi_cmdlang_out(cmd_info, "FRU value set", fru_name);
00497
00498 return;
00499
00500 out_err:
00501 ipmi_fru_get_name(fru, cmdlang->objstr,
00502 cmdlang->objstr_len);
00503 cmdlang->location = "cmd_fru.c(fru_setval)";
00504 }
00505
00506 static void
00507 get_fru_by_name(char *name, ipmi_cmdlang_t *cmdlang, unsigned int *area)
00508 {
00509 if (strcmp(name, "internal_data") == 0) {
00510 *area = IPMI_FRU_FTR_INTERNAL_USE_AREA;
00511 } else if (strcmp(name, "chassis_info") == 0) {
00512 *area = IPMI_FRU_FTR_CHASSIS_INFO_AREA;
00513 } else if (strcmp(name, "board_info") == 0) {
00514 *area = IPMI_FRU_FTR_BOARD_INFO_AREA ;
00515 } else if (strcmp(name, "product_info") == 0) {
00516 *area = IPMI_FRU_FTR_PRODUCT_INFO_AREA;
00517 } else if (strcmp(name, "multi_record") == 0) {
00518 *area = IPMI_FRU_FTR_MULTI_RECORD_AREA;
00519 } else {
00520 cmdlang->errstr = "Invalid area name";
00521 cmdlang->err = EINVAL;
00522 }
00523 }
00524
00525 static void
00526 fru_area_offset(ipmi_fru_t *fru, void *cb_data)
00527 {
00528 ipmi_cmd_info_t *cmd_info = cb_data;
00529 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00530 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00531 int argc = ipmi_cmdlang_get_argc(cmd_info);
00532 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00533 char fru_name[IPMI_FRU_NAME_LEN];
00534 unsigned int area;
00535 int offset;
00536 int rv;
00537
00538 if ((argc - curr_arg) < 2) {
00539
00540 cmdlang->errstr = "Not enough parameters";
00541 cmdlang->err = EINVAL;
00542 goto out_err;
00543 }
00544
00545 get_fru_by_name(argv[curr_arg], cmdlang, &area);
00546 if (cmdlang->err)
00547 goto out_err;
00548 curr_arg++;
00549
00550 ipmi_cmdlang_get_int(argv[curr_arg], &offset, cmd_info);
00551 if (cmdlang->err) {
00552 cmdlang->errstr = "offset invalid";
00553 goto out_err;
00554 }
00555
00556 rv = ipmi_fru_area_set_offset(fru, area, offset);
00557 if (rv) {
00558 cmdlang->errstr = "Error setting area offset";
00559 cmdlang->err = rv;
00560 goto out_err;
00561 }
00562
00563 ipmi_fru_get_name(fru, fru_name, sizeof(fru_name));
00564 ipmi_cmdlang_out(cmd_info, "FRU area offset set", fru_name);
00565 return;
00566
00567 out_err:
00568 ipmi_fru_get_name(fru, cmdlang->objstr,
00569 cmdlang->objstr_len);
00570 cmdlang->location = "cmd_fru.c(fru_area_offset)";
00571 }
00572
00573 static void
00574 fru_area_length(ipmi_fru_t *fru, void *cb_data)
00575 {
00576 ipmi_cmd_info_t *cmd_info = cb_data;
00577 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00578 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00579 int argc = ipmi_cmdlang_get_argc(cmd_info);
00580 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00581 char fru_name[IPMI_FRU_NAME_LEN];
00582 unsigned int area;
00583 int length;
00584 int rv;
00585
00586 if ((argc - curr_arg) < 2) {
00587
00588 cmdlang->errstr = "Not enough parameters";
00589 cmdlang->err = EINVAL;
00590 goto out_err;
00591 }
00592
00593 get_fru_by_name(argv[curr_arg], cmdlang, &area);
00594 if (cmdlang->err)
00595 goto out_err;
00596 curr_arg++;
00597
00598 ipmi_cmdlang_get_int(argv[curr_arg], &length, cmd_info);
00599 if (cmdlang->err) {
00600 cmdlang->errstr = "length invalid";
00601 goto out_err;
00602 }
00603
00604 rv = ipmi_fru_area_set_length(fru, area, length);
00605 if (rv) {
00606 cmdlang->errstr = "Error setting area length";
00607 cmdlang->err = rv;
00608 goto out_err;
00609 }
00610
00611 ipmi_fru_get_name(fru, fru_name, sizeof(fru_name));
00612 ipmi_cmdlang_out(cmd_info, "FRU area length set", fru_name);
00613 return;
00614
00615 out_err:
00616 ipmi_fru_get_name(fru, cmdlang->objstr,
00617 cmdlang->objstr_len);
00618 cmdlang->location = "cmd_fru.c(fru_area_length)";
00619 }
00620
00621 static void
00622 fru_area_add(ipmi_fru_t *fru, void *cb_data)
00623 {
00624 ipmi_cmd_info_t *cmd_info = cb_data;
00625 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00626 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00627 int argc = ipmi_cmdlang_get_argc(cmd_info);
00628 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00629 char fru_name[IPMI_FRU_NAME_LEN];
00630 unsigned int area;
00631 int length, offset;
00632 int rv;
00633
00634 if ((argc - curr_arg) < 3) {
00635
00636 cmdlang->errstr = "Not enough parameters";
00637 cmdlang->err = EINVAL;
00638 goto out_err;
00639 }
00640
00641 get_fru_by_name(argv[curr_arg], cmdlang, &area);
00642 if (cmdlang->err)
00643 goto out_err;
00644 curr_arg++;
00645
00646 ipmi_cmdlang_get_int(argv[curr_arg], &offset, cmd_info);
00647 if (cmdlang->err) {
00648 cmdlang->errstr = "offset invalid";
00649 goto out_err;
00650 }
00651 curr_arg++;
00652
00653 ipmi_cmdlang_get_int(argv[curr_arg], &length, cmd_info);
00654 if (cmdlang->err) {
00655 cmdlang->errstr = "length invalid";
00656 goto out_err;
00657 }
00658 curr_arg++;
00659
00660 rv = ipmi_fru_add_area(fru, area, offset, length);
00661 if (rv) {
00662 cmdlang->errstr = "Error adding area";
00663 cmdlang->err = rv;
00664 goto out_err;
00665 }
00666
00667 ipmi_fru_get_name(fru, fru_name, sizeof(fru_name));
00668 ipmi_cmdlang_out(cmd_info, "FRU area added", fru_name);
00669 return;
00670
00671 out_err:
00672 ipmi_fru_get_name(fru, cmdlang->objstr,
00673 cmdlang->objstr_len);
00674 cmdlang->location = "cmd_fru.c(fru_area_add)";
00675 }
00676
00677 static void
00678 fru_area_delete(ipmi_fru_t *fru, void *cb_data)
00679 {
00680 ipmi_cmd_info_t *cmd_info = cb_data;
00681 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00682 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00683 int argc = ipmi_cmdlang_get_argc(cmd_info);
00684 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00685 char fru_name[IPMI_FRU_NAME_LEN];
00686 unsigned int area;
00687 int rv;
00688
00689 if ((argc - curr_arg) < 1) {
00690
00691 cmdlang->errstr = "Not enough parameters";
00692 cmdlang->err = EINVAL;
00693 goto out_err;
00694 }
00695
00696 get_fru_by_name(argv[curr_arg], cmdlang, &area);
00697 if (cmdlang->err)
00698 goto out_err;
00699 curr_arg++;
00700
00701 rv = ipmi_fru_delete_area(fru, area);
00702 if (rv) {
00703 cmdlang->errstr = "Error deleting area";
00704 cmdlang->err = rv;
00705 goto out_err;
00706 }
00707
00708 ipmi_fru_get_name(fru, fru_name, sizeof(fru_name));
00709 ipmi_cmdlang_out(cmd_info, "FRU area deleted", fru_name);
00710 return;
00711
00712 out_err:
00713 ipmi_fru_get_name(fru, cmdlang->objstr,
00714 cmdlang->objstr_len);
00715 cmdlang->location = "cmd_fru.c(fru_area_delete)";
00716 }
00717
00718 static ipmi_cmdlang_cmd_t *fru_cmds;
00719
00720 static ipmi_cmdlang_init_t cmds_fru[] =
00721 {
00722 { "fru", NULL,
00723 "- Commands dealing with FRUs",
00724 NULL, NULL, &fru_cmds},
00725 { "list", &fru_cmds,
00726 "- List all the frus in the system",
00727 ipmi_cmdlang_domain_handler, fru_list, NULL },
00728 { "info", &fru_cmds,
00729 "<fru> - Dump information about a FRU",
00730 ipmi_cmdlang_fru_handler, fru_info, NULL },
00731 { "areainfo", &fru_cmds,
00732 "<fru> - Dump the info about the FRU's areas",
00733 ipmi_cmdlang_fru_handler, fru_areainfo, NULL },
00734 { "write", &fru_cmds,
00735 "<fru> - Write the local FRU data out into the FRU",
00736 ipmi_cmdlang_fru_handler, fru_write, NULL },
00737 { "close", &fru_cmds,
00738 "<fru> - Delete the FRU",
00739 ipmi_cmdlang_fru_handler, fru_close, NULL },
00740 { "setval", &fru_cmds,
00741 "<fru> <name> [num] value - Set the value of a FRU element. The"
00742 " name is the record name, or multi_record. The number is required"
00743 " for fields that need it (custom and multi-record). The value is"
00744 " an a single value for integers. For strings it is a string"
00745 " type (either binary, ascii, or unicode) and the info. Binary and"
00746 " unicode data is specified as numbers. ascii data is specified in"
00747 " a string. Note that setting a ascii value with no string will"
00748 " clear the value. Zero length strings and data is valid. For"
00749 " multi_record, the value is <type> <version> [<data> ...]",
00750 ipmi_cmdlang_fru_handler, fru_setval, NULL },
00751 { "area_offset", &fru_cmds,
00752 "<fru> <area name> <offset> - Set the offset of the given area"
00753 " to the given value. Area names are internal_data, chassis_info,"
00754 " board_info, product_info, and multi_record",
00755 ipmi_cmdlang_fru_handler, fru_area_offset, NULL },
00756 { "area_length", &fru_cmds,
00757 "<fru> <area name> <length> - Set the length of the given area"
00758 " to the given value. Area names are internal_data, chassis_info,"
00759 " board_info, product_info, and multi_record",
00760 ipmi_cmdlang_fru_handler, fru_area_length, NULL },
00761 { "area_add", &fru_cmds,
00762 "<fru> <area name> <offset> <length> - Add the given area to the FRU",
00763 ipmi_cmdlang_fru_handler, fru_area_add, NULL },
00764 { "area_delete", &fru_cmds,
00765 "<fru> <area name> - Delete the given area from the FRU",
00766 ipmi_cmdlang_fru_handler, fru_area_delete, NULL },
00767 };
00768 #define CMDS_FRU_LEN (sizeof(cmds_fru)/sizeof(ipmi_cmdlang_init_t))
00769
00770 int
00771 ipmi_cmdlang_fru_init(os_handler_t *os_hnd)
00772 {
00773 return ipmi_cmdlang_reg_table(cmds_fru, CMDS_FRU_LEN);
00774 }