Main Page | Class List | Directories | File List | Class Members | File Members

cmd_fru.c

Go to the documentation of this file.
00001 /*
00002  * cmd_fru.c
00003  *
00004  * A command interpreter for OpenIPMI
00005  *
00006  * Author: MontaVista Software, Inc.
00007  *         Corey Minyard <minyard@mvista.com>
00008  *         source@mvista.com
00009  *
00010  * Copyright 2004 MontaVista Software Inc.
00011  *
00012  *  This program is free software; you can redistribute it and/or
00013  *  modify it under the terms of the GNU Lesser General Public License
00014  *  as published by the Free Software Foundation; either version 2 of
00015  *  the License, or (at your option) any later version.
00016  *
00017  *
00018  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
00019  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00020  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00021  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00025  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00026  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00027  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  *
00029  *  You should have received a copy of the GNU Lesser General Public
00030  *  License along with this program; if not, write to the Free
00031  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 /* Internal includes, do not use in your programs */
00045 #include <OpenIPMI/internal/ipmi_malloc.h>
00046 
00047 /* Don't pollute the namespace iwth ipmi_fru_t. */
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     /* We need to be holding our own reference to the FRU because
00201        ipmi_fru_destroy will do a deref on it, but the calling code
00202        will also be doing a deref.. */
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         /* Not enough parameters */
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         /* Need the number */
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             /* Not enough parameters */
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             /* Not enough parameters */
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         /* Not relevant for normal FRU data. */
00410         break;
00411     }
00412 
00413     goto out;
00414 
00415  do_multi_record:
00416     curr_arg++;
00417     if ((argc - curr_arg) < 1) {
00418         /* Not enough parameters */
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         /* Deleting the record. */
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         /* Not enough parameters */
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         /* Not enough parameters */
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         /* Not enough parameters */
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         /* Not enough parameters */
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         /* Not enough parameters */
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 }

© sourcejam.com 2005-2008