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

cmd_pef.c

Go to the documentation of this file.
00001 /*
00002  * cmd_pef.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_pef.h>
00041 #include <OpenIPMI/ipmi_cmdlang.h>
00042 #include <OpenIPMI/ipmi_mc.h>
00043 
00044 /* Internal includes, do not use in your programs */
00045 #include <OpenIPMI/internal/ipmi_malloc.h>
00046 #include <OpenIPMI/internal/locked_list.h>
00047 
00048 static locked_list_t *pefs;
00049 
00050 static void
00051 pef_list_handler(ipmi_pef_t *pef, 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            pef_name[IPMI_PEF_NAME_LEN];
00056 
00057     if (cmdlang->err)
00058         return;
00059 
00060     ipmi_pef_get_name(pef, pef_name, sizeof(pef_name));
00061 
00062     ipmi_cmdlang_out(cmd_info, "Name", pef_name);
00063 }
00064 
00065 static void
00066 pef_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, "PEFs", NULL);
00076     ipmi_cmdlang_down(cmd_info);
00077     ipmi_pef_iterate_pefs(domain, pef_list_handler, cmd_info);
00078     ipmi_cmdlang_up(cmd_info);
00079     ipmi_cmdlang_up(cmd_info);
00080 }
00081 
00082 static void
00083 get_mc_name(ipmi_mc_t *mc, void *cb_data)
00084 {
00085     ipmi_cmd_info_t *cmd_info = cb_data;
00086     char            mc_name[IPMI_MC_NAME_LEN];
00087 
00088     ipmi_mc_get_name(mc, mc_name, sizeof(mc_name));
00089     ipmi_cmdlang_out(cmd_info, "MC", mc_name);
00090 }
00091 
00092 static void
00093 pef_info(ipmi_pef_t *pef, void *cb_data)
00094 {
00095     ipmi_cmd_info_t *cmd_info = cb_data;
00096     char            pef_name[IPMI_PEF_NAME_LEN];
00097 
00098     ipmi_pef_get_name(pef, pef_name, sizeof(pef_name));
00099 
00100     ipmi_cmdlang_out(cmd_info, "PEF", NULL);
00101     ipmi_cmdlang_down(cmd_info);
00102     ipmi_cmdlang_out(cmd_info, "Name", pef_name);
00103     ipmi_mc_pointer_cb(ipmi_pef_get_mc(pef), get_mc_name, cmd_info);
00104     ipmi_cmdlang_up(cmd_info);
00105 }
00106 
00107 static void
00108 pef_new_done(ipmi_pef_t *pef, int err, void *cb_data)
00109 {
00110     ipmi_cmd_info_t *cmd_info = cb_data;
00111     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00112     char            pef_name[IPMI_PEF_NAME_LEN];
00113 
00114     ipmi_cmdlang_lock(cmd_info);
00115     if (err) {
00116         cmdlang->errstr = "Error allocating PEF";
00117         cmdlang->err = err;
00118         cmdlang->location = "cmd_pef.c(pef_new_done)";
00119         goto out;
00120     }
00121 
00122     ipmi_pef_get_name(pef, pef_name, sizeof(pef_name));
00123     ipmi_cmdlang_out(cmd_info, "PEF", pef_name);
00124 
00125  out:
00126     ipmi_cmdlang_unlock(cmd_info);
00127     ipmi_cmdlang_cmd_info_put(cmd_info);
00128 }
00129 
00130 static void
00131 pef_new(ipmi_mc_t *mc, void *cb_data)
00132 {
00133     ipmi_cmd_info_t *cmd_info = cb_data;
00134     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00135     int             rv;
00136 
00137     ipmi_cmdlang_cmd_info_get(cmd_info);
00138     rv = ipmi_pef_alloc(mc, pef_new_done, cmd_info, NULL);
00139     if (rv) {
00140         ipmi_cmdlang_cmd_info_put(cmd_info);
00141         cmdlang->errstr = "Error from ipmi_pef_alloc";
00142         cmdlang->err = rv;
00143         goto out_err;
00144     }
00145     return;
00146 
00147  out_err:
00148     ipmi_mc_get_name(mc, cmdlang->objstr,
00149                      cmdlang->objstr_len);
00150     cmdlang->location = "cmd_pef.c(pef_new)";
00151 }
00152 
00153 static void
00154 pef_close_done(ipmi_pef_t *pef, int err, void *cb_data)
00155 {
00156     ipmi_cmd_info_t *cmd_info = cb_data;
00157     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00158     char            pef_name[IPMI_PEF_NAME_LEN];
00159 
00160     ipmi_cmdlang_lock(cmd_info);
00161     if (err) {
00162         ipmi_pef_get_name(pef, cmdlang->objstr,
00163                           cmdlang->objstr_len);
00164         cmdlang->errstr = "Error closing PEF";
00165         cmdlang->err = err;
00166         cmdlang->location = "cmd_pef.c(pef_close_done)";
00167         goto out;
00168     }
00169 
00170     ipmi_pef_get_name(pef, pef_name, sizeof(pef_name));
00171     ipmi_cmdlang_out(cmd_info, "PEF destroyed", pef_name);
00172 
00173  out:
00174     ipmi_cmdlang_unlock(cmd_info);
00175     ipmi_cmdlang_cmd_info_put(cmd_info);
00176 }
00177 
00178 static void
00179 pef_close(ipmi_pef_t *pef, void *cb_data)
00180 {
00181     ipmi_cmd_info_t *cmd_info = cb_data;
00182     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00183     int             rv;
00184 
00185     ipmi_cmdlang_cmd_info_get(cmd_info);
00186     rv = ipmi_pef_destroy(pef, pef_close_done, cmd_info);
00187     if (rv) {
00188         ipmi_cmdlang_cmd_info_put(cmd_info);
00189         ipmi_pef_get_name(pef, cmdlang->objstr,
00190                               cmdlang->objstr_len);
00191         cmdlang->errstr = "Error closing PEF";
00192         cmdlang->err = rv;
00193         cmdlang->location = "cmd_pef.c(pef_close)";
00194     }
00195 }
00196 
00197 #define PEF_CONFIG_NAME_LEN 80
00198 typedef struct pef_config_info_s
00199 {
00200     char              name[PEF_CONFIG_NAME_LEN];
00201     ipmi_pef_config_t *config;
00202 } pef_config_info_t;
00203 
00204 static unsigned int unique_num = 0;
00205 
00206 typedef struct find_config_s
00207 {
00208     char              *name;
00209     ipmi_pef_config_t *config;
00210     int               delete;
00211 } find_config_t;
00212 
00213 static int
00214 find_config_handler(void *cb_data, void *item1, void *item2)
00215 {
00216     pef_config_info_t *info = item1;
00217     find_config_t     *find = cb_data;
00218 
00219     if (strcmp(find->name, info->name) == 0) {
00220         find->config = info->config;
00221         if (find->delete) {
00222             locked_list_remove(pefs, item1, item2);
00223             ipmi_mem_free(info);
00224         }
00225         return LOCKED_LIST_ITER_STOP;
00226     }
00227 
00228     return LOCKED_LIST_ITER_CONTINUE;
00229 }
00230 
00231 static ipmi_pef_config_t *
00232 find_config(char *name, int delete)
00233 {
00234     find_config_t find;
00235 
00236     find.name = name;
00237     find.config = NULL;
00238     find.delete = delete;
00239     locked_list_iterate(pefs, find_config_handler, &find);
00240     return find.config;
00241 }
00242 
00243 typedef void (*lp_set)(ipmi_cmd_info_t *cmd_info, char *val,
00244                        ipmi_pef_config_t *lanc, void *func);
00245 typedef void (*lp_out)(ipmi_cmd_info_t *cmd_info, char *name,
00246                        ipmi_pef_config_t *lanc, void *func);
00247 typedef struct lp_item_s
00248 {
00249     lp_set set;
00250     lp_out out;
00251 } lp_item_t;
00252 
00253 static void
00254 set_retint(ipmi_cmd_info_t *cmd_info, char *val,
00255            ipmi_pef_config_t *lanc, void *func)
00256 {
00257     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00258     int            (*f)(ipmi_pef_config_t *l, unsigned int v) = func;
00259     int            v;
00260 
00261     ipmi_cmdlang_get_int(val, &v, cmd_info);
00262     if (!cmdlang->err) {
00263         cmdlang->err = f(lanc, v);
00264         if (cmdlang->err) {
00265             cmdlang->errstr = "Error setting parameter";
00266         }
00267     }
00268 }
00269 static void
00270 out_retint(ipmi_cmd_info_t *cmd_info, char *name,
00271            ipmi_pef_config_t *lanc, void *func)
00272 {
00273     unsigned int   (*f)(ipmi_pef_config_t *l) = func;
00274     ipmi_cmdlang_out_int(cmd_info, name, f(lanc));
00275 }
00276 static lp_item_t lp_retint = {set_retint, out_retint};
00277 
00278 static void
00279 set_retbool(ipmi_cmd_info_t *cmd_info, char *val,
00280             ipmi_pef_config_t *lanc, void *func)
00281 {
00282     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00283     int            (*f)(ipmi_pef_config_t *l, unsigned int v) = func;
00284     int            v;
00285 
00286     ipmi_cmdlang_get_bool(val, &v, cmd_info);
00287     if (!cmdlang->err) {
00288         cmdlang->err = f(lanc, v);
00289         if (cmdlang->err) {
00290             cmdlang->errstr = "Error setting parameter";
00291         }
00292     }
00293 }
00294 static void
00295 out_retbool(ipmi_cmd_info_t *cmd_info, char *name,
00296             ipmi_pef_config_t *lanc, void *func)
00297 {
00298     unsigned int   (*f)(ipmi_pef_config_t *l) = func;
00299     ipmi_cmdlang_out_bool(cmd_info, name, f(lanc));
00300 }
00301 static lp_item_t lp_retbool = {set_retbool, out_retbool};
00302 
00303 static void
00304 set_int(ipmi_cmd_info_t *cmd_info, char *val,
00305         ipmi_pef_config_t *lanc, void *func)
00306 {
00307     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00308     int            (*f)(ipmi_pef_config_t *l, unsigned int v) = func;
00309     int            v;
00310 
00311     ipmi_cmdlang_get_int(val, &v, cmd_info);
00312     if (!cmdlang->err) {
00313         cmdlang->err = f(lanc, v);
00314         if (cmdlang->err) {
00315             cmdlang->errstr = "Error setting parameter";
00316         }
00317     }
00318 }
00319 static void
00320 out_int(ipmi_cmd_info_t *cmd_info, char *name,
00321         ipmi_pef_config_t *lanc, void *func)
00322 {
00323     unsigned int   v;
00324     int            rv;
00325     int            (*f)(ipmi_pef_config_t *l, unsigned int *v) = func;
00326     
00327     rv = f(lanc, &v);
00328     if (!rv)
00329         ipmi_cmdlang_out_int(cmd_info, name, v);
00330 }
00331 static lp_item_t lp_int = {set_int, out_int};
00332 
00333 static void
00334 set_guid(ipmi_cmd_info_t *cmd_info, char *val,
00335          ipmi_pef_config_t *lanc, void *func)
00336 {
00337     unsigned char  v[16];
00338     char           tmp[3];
00339     char           *end;
00340     int            i;
00341     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00342     int            (*f)(ipmi_pef_config_t *l, unsigned char *v,
00343                         unsigned int dl) = func;
00344 
00345     if (strlen(val) != 32) {
00346         cmdlang->err = EINVAL;
00347         cmdlang->errstr = "Invalid GUID";
00348         return;
00349     }
00350 
00351     for (i=0; i<16; i++) {
00352         memset(tmp, 0, sizeof(tmp));
00353         memcpy(tmp, val+(i*2), 2);
00354         v[i] = strtoul(tmp, &end, 16);
00355         if (*end != '\0') {
00356             cmdlang->err = EINVAL;
00357             cmdlang->errstr = "Invalid GUID";
00358             return;
00359         }
00360     }
00361     if (!cmdlang->err) {
00362         cmdlang->err = f(lanc, v, sizeof(v));
00363         if (cmdlang->err) {
00364             cmdlang->errstr = "Error setting parameter";
00365         }
00366     }
00367 }
00368 static void
00369 out_guid(ipmi_cmd_info_t *cmd_info, char *name,
00370        ipmi_pef_config_t *lanc, void *func)
00371 {
00372     int            rv;
00373     int            (*f)(ipmi_pef_config_t *l, unsigned char *v,
00374                         unsigned int *dl) = func;
00375     unsigned char  v[16];
00376     unsigned int   len = sizeof(v);
00377     char           str[33];
00378     char           *s;
00379     int            i;
00380     
00381     rv = f(lanc, (unsigned char *) &v, &len);
00382     if (!rv) {
00383         s = str;
00384         for (i=0; i<16; i++)
00385             s += sprintf(s, "%2.2x", v[i]);
00386         ipmi_cmdlang_out(cmd_info, name, str);
00387     }
00388 }
00389 static lp_item_t lp_guid = {set_guid, out_guid};
00390 
00391 static struct lps_s
00392 {
00393     char      *name;
00394     lp_item_t *lpi;
00395     void      *get_func;
00396     void      *set_func;
00397 } lps[] =
00398 /* read-only */
00399 #define FR(name, type) { #name, &lp_ ## type, ipmi_pefconfig_get_ ## name, \
00400                          NULL }
00401 /* Writable */
00402 #define F(name, type) { #name, &lp_ ## type, ipmi_pefconfig_get_ ## name, \
00403                         ipmi_pefconfig_set_ ## name }
00404 {
00405     F(alert_startup_delay_enabled, retbool),
00406     F(startup_delay_enabled, retbool),
00407     F(event_messages_enabled, retbool),
00408     F(pef_enabled, retbool),
00409     F(diagnostic_interrupt_enabled, retbool),
00410     F(oem_action_enabled, retbool),
00411     F(power_cycle_enabled, retbool),
00412     F(reset_enabled, retbool),
00413     F(power_down_enabled, retbool),
00414     F(alert_enabled, retbool),
00415     F(startup_delay, int),
00416     F(alert_startup_delay, int),
00417     F(guid_enabled, retbool),
00418     F(guid_val, guid),
00419     FR(num_event_filters, retint),
00420     FR(num_alert_policies, retint),
00421     FR(num_alert_strings, retint),
00422     { NULL }
00423 };
00424 
00425 /*
00426  * Selector-based get/out routines.
00427  */
00428 typedef void (*ulp_set)(ipmi_cmd_info_t *cmd_info, int sel, char *val,
00429                         ipmi_pef_config_t *lanc, void *func);
00430 typedef void (*ulp_out)(ipmi_cmd_info_t *cmd_info, int sel, char *name,
00431                         ipmi_pef_config_t *lanc, void *func);
00432 typedef struct ulp_item_s
00433 {
00434     ulp_set set;
00435     ulp_out out;
00436 } ulp_item_t;
00437 
00438 static void
00439 uset_bool(ipmi_cmd_info_t *cmd_info, int sel, char *val,
00440          ipmi_pef_config_t *lanc, void *func)
00441 {
00442     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00443     int            (*f)(ipmi_pef_config_t *l, unsigned int sel,
00444                         unsigned int v) = func;
00445     int            v;
00446 
00447     ipmi_cmdlang_get_bool(val, &v, cmd_info);
00448     if (!cmdlang->err) {
00449         cmdlang->err = f(lanc, sel, v);
00450         if (cmdlang->err) {
00451             cmdlang->errstr = "Error setting parameter";
00452         }
00453     }
00454 }
00455 static void
00456 uout_bool(ipmi_cmd_info_t *cmd_info, int sel, char *name,
00457          ipmi_pef_config_t *lanc, void *func)
00458 {
00459     unsigned int   v;
00460     int            rv;
00461     int            (*f)(ipmi_pef_config_t *l, unsigned int sel,
00462                         unsigned int *v) = func;
00463     
00464     rv = f(lanc, sel, &v);
00465     if (!rv)
00466         ipmi_cmdlang_out_bool(cmd_info, name, v);
00467 }
00468 static ulp_item_t lp_ubool = {uset_bool, uout_bool};
00469 
00470 static void
00471 uset_int(ipmi_cmd_info_t *cmd_info, int sel, char *val,
00472          ipmi_pef_config_t *lanc, void *func)
00473 {
00474     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00475     int            (*f)(ipmi_pef_config_t *l, unsigned int sel,
00476                         unsigned int v) = func;
00477     int            v;
00478 
00479     ipmi_cmdlang_get_int(val, &v, cmd_info);
00480     if (!cmdlang->err) {
00481         cmdlang->err = f(lanc, sel, v);
00482         if (cmdlang->err) {
00483             cmdlang->errstr = "Error setting parameter";
00484         }
00485     }
00486 }
00487 static void
00488 uout_int(ipmi_cmd_info_t *cmd_info, int sel, char *name,
00489          ipmi_pef_config_t *lanc, void *func)
00490 {
00491     unsigned int   v;
00492     int            rv;
00493     int            (*f)(ipmi_pef_config_t *l, unsigned int sel,
00494                         unsigned int *v) = func;
00495     
00496     rv = f(lanc, sel, &v);
00497     if (!rv)
00498         ipmi_cmdlang_out_int(cmd_info, name, v);
00499 }
00500 static ulp_item_t lp_uint = {uset_int, uout_int};
00501 
00502 static void
00503 uset_str(ipmi_cmd_info_t *cmd_info, int sel, char *val,
00504          ipmi_pef_config_t *lanc, void *func)
00505 {
00506     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00507     int            (*f)(ipmi_pef_config_t *l, unsigned int sel,
00508                         char *v) = func;
00509 
00510     if (!cmdlang->err) {
00511         cmdlang->err = f(lanc, sel, val);
00512         if (cmdlang->err) {
00513             cmdlang->errstr = "Error setting parameter";
00514         }
00515     }
00516 }
00517 static void
00518 uout_str(ipmi_cmd_info_t *cmd_info, int sel, char *name,
00519          ipmi_pef_config_t *lanc, void *func)
00520 {
00521     char          v[100];
00522     int           rv;
00523     int           (*f)(ipmi_pef_config_t *l, unsigned int sel,
00524                        char *v, unsigned int *dl) = func;
00525     unsigned int  len = sizeof(v);
00526     
00527     rv = f(lanc, sel, v, &len);
00528     if (!rv)
00529         ipmi_cmdlang_out(cmd_info, name, v);
00530 }
00531 static ulp_item_t lp_ustr = {uset_str, uout_str};
00532 
00533 /*
00534  * event-filter table items
00535  */
00536 static struct ulps_s
00537 {
00538     char       *name;
00539     ulp_item_t *lpi;
00540     void       *get_func;
00541     void       *set_func;
00542 } elps[] =
00543 {
00544     F(enable_filter, ubool),
00545     F(filter_type, uint),
00546     F(diagnostic_interrupt, ubool),
00547     F(oem_action, ubool),
00548     F(power_cycle, ubool),
00549     F(reset, ubool),
00550     F(power_down, ubool),
00551     F(alert, ubool),
00552     F(alert_policy_number, uint),
00553     F(event_severity, uint),
00554     F(generator_id_addr, uint),
00555     F(generator_id_channel_lun, uint),
00556     F(sensor_type, uint),
00557     F(sensor_number, uint),
00558     F(event_trigger, uint),
00559     F(data1_offset_mask, uint),
00560     F(data1_mask, uint),
00561     F(data1_compare1, uint),
00562     F(data1_compare2, uint),
00563     F(data2_mask, uint),
00564     F(data2_compare1, uint),
00565     F(data2_compare2, uint),
00566     F(data3_mask, uint),
00567     F(data3_compare1, uint),
00568     F(data3_compare2, uint),
00569     { NULL }
00570 };
00571 
00572 /*
00573  * Alert policy table items
00574  */
00575 static struct ulps_s plps[] =
00576 {
00577     F(policy_num, uint),
00578     F(enabled, ubool),
00579     F(policy, uint),
00580     F(channel, uint),
00581     F(destination_selector, uint),
00582     F(alert_string_event_specific, ubool),
00583     F(alert_string_selector, uint),
00584     { NULL }
00585 };
00586 
00587 /*
00588  * Alert string items
00589  */
00590 static struct ulps_s slps[] =
00591 {
00592     F(event_filter, uint),
00593     F(alert_string_set, uint),
00594     F(alert_string, ustr),
00595     { NULL }
00596 };
00597 
00598 static void
00599 config_info(ipmi_cmd_info_t *cmd_info, ipmi_pef_config_t *config)
00600 {
00601     int i;
00602     int j;
00603     int num;
00604 
00605     /* Basic items */
00606     for (i=0; lps[i].name; i++) {
00607         lp_item_t *lp = lps[i].lpi;
00608         lp->out(cmd_info, lps[i].name, config, lps[i].get_func);
00609     }
00610 
00611     /* per-event-filter table items */
00612     num = ipmi_pefconfig_get_num_event_filters(config);
00613     for (j=0; j<num; j++) {
00614         struct ulps_s *lps = elps;
00615         ipmi_cmdlang_out(cmd_info, "Event Filter", NULL);
00616         ipmi_cmdlang_down(cmd_info);
00617         ipmi_cmdlang_out_int(cmd_info, "Number", j);
00618         for (i=0; lps[i].name; i++) {
00619             ulp_item_t *lp = lps[i].lpi;
00620             lp->out(cmd_info, j, lps[i].name, config, lps[i].get_func);
00621         }
00622         ipmi_cmdlang_up(cmd_info);
00623     }
00624 
00625     /* per-alert policy table items */
00626     num = ipmi_pefconfig_get_num_alert_policies(config);
00627     for (j=0; j<num; j++) {
00628         struct ulps_s *lps = plps;
00629         ipmi_cmdlang_out(cmd_info, "Alert Policy", NULL);
00630         ipmi_cmdlang_down(cmd_info);
00631         ipmi_cmdlang_out_int(cmd_info, "Number", j);
00632         for (i=0; lps[i].name; i++) {
00633             ulp_item_t *lp = lps[i].lpi;
00634             lp->out(cmd_info, j, lps[i].name, config, lps[i].get_func);
00635         }
00636         ipmi_cmdlang_up(cmd_info);
00637     }
00638 
00639     /* per-alert string items */
00640     num = ipmi_pefconfig_get_num_alert_strings(config);
00641     for (j=0; j<num; j++) {
00642         struct ulps_s *lps = slps;
00643         ipmi_cmdlang_out(cmd_info, "Alert String", NULL);
00644         ipmi_cmdlang_down(cmd_info);
00645         ipmi_cmdlang_out_int(cmd_info, "Number", j);
00646         for (i=0; lps[i].name; i++) {
00647             ulp_item_t *lp = lps[i].lpi;
00648             lp->out(cmd_info, j, lps[i].name, config, lps[i].get_func);
00649         }
00650         ipmi_cmdlang_up(cmd_info);
00651     }
00652 }
00653 
00654 static void
00655 pef_config_get_done(ipmi_pef_t        *pef,
00656                     int               err,
00657                     ipmi_pef_config_t *config,
00658                     void              *cb_data)
00659 {
00660     ipmi_cmd_info_t   *cmd_info = cb_data;
00661     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00662     char              pef_name[IPMI_PEF_NAME_LEN];
00663     pef_config_info_t *info;
00664 
00665     ipmi_cmdlang_lock(cmd_info);
00666     if (err) {
00667         cmdlang->errstr = "Error getting PEF";
00668         cmdlang->err = err;
00669         goto out;
00670     }
00671 
00672     ipmi_pef_get_name(pef, pef_name, sizeof(pef_name));
00673 
00674     info = ipmi_mem_alloc(sizeof(*info));
00675     if (!info) {
00676         cmdlang->errstr = "Out of memory";
00677         cmdlang->err = ENOMEM;
00678         ipmi_pef_free_config(config);
00679         goto out;
00680     }
00681     snprintf(info->name, sizeof(info->name), "%s.%u",
00682              pef_name, unique_num);
00683     info->config = config;
00684     if (!locked_list_add(pefs, info, NULL)) {
00685         cmdlang->errstr = "Out of memory";
00686         cmdlang->err = ENOMEM;
00687         ipmi_pef_free_config(config);
00688         ipmi_mem_free(info);
00689         goto out;
00690     }
00691     unique_num++;
00692 
00693     ipmi_cmdlang_out(cmd_info, "PEF Config", NULL);
00694     ipmi_cmdlang_down(cmd_info);
00695     ipmi_cmdlang_out(cmd_info, "Name", info->name);
00696     config_info(cmd_info, config);
00697     ipmi_cmdlang_up(cmd_info);
00698 
00699  out:
00700     if (cmdlang->err) {
00701         ipmi_pef_get_name(pef, cmdlang->objstr,
00702                               cmdlang->objstr_len);
00703         cmdlang->location = "cmd_pef.c(pef_config_get_done)";
00704     }
00705     ipmi_cmdlang_unlock(cmd_info);
00706     ipmi_cmdlang_cmd_info_put(cmd_info);
00707 }
00708 
00709 static void
00710 pef_config_get(ipmi_pef_t *pef, void *cb_data)
00711 {
00712     ipmi_cmd_info_t *cmd_info = cb_data;
00713     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00714     int             rv;
00715 
00716     ipmi_cmdlang_cmd_info_get(cmd_info);
00717     rv = ipmi_pef_get_config(pef, pef_config_get_done, cmd_info);
00718     if (rv) {
00719         ipmi_pef_get_name(pef, cmdlang->objstr,
00720                               cmdlang->objstr_len);
00721         ipmi_cmdlang_cmd_info_put(cmd_info);
00722         cmdlang->errstr = "Error getting PEF";
00723         cmdlang->err = rv;
00724         cmdlang->location = "cmd_pef.c(pef_config_get)";
00725     }
00726 }
00727 
00728 typedef struct pef_config_op_s
00729 {
00730     char            name[PEF_CONFIG_NAME_LEN];
00731     ipmi_cmd_info_t *cmd_info;
00732 } pef_config_op_t;
00733 
00734 static void
00735 pef_config_set_done(ipmi_pef_t *pef,
00736                     int        err,
00737                     void       *cb_data)
00738 {
00739     pef_config_op_t *info = cb_data;
00740     ipmi_cmd_info_t *cmd_info = info->cmd_info;
00741     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00742 
00743     ipmi_cmdlang_lock(cmd_info);
00744     if (err) {
00745         ipmi_pef_get_name(pef, cmdlang->objstr,
00746                               cmdlang->objstr_len);
00747         cmdlang->errstr = "Error setting PEF";
00748         cmdlang->err = err;
00749         cmdlang->location = "cmd_pef.c(pef_config_set_done)";
00750         goto out;
00751     }
00752 
00753     ipmi_cmdlang_out(cmd_info, "PEF config set", info->name);
00754 
00755  out:
00756     ipmi_mem_free(info);
00757     ipmi_cmdlang_unlock(cmd_info);
00758     ipmi_cmdlang_cmd_info_put(cmd_info);
00759 }
00760 
00761 static void
00762 pef_config_set(ipmi_pef_t *pef, void *cb_data)
00763 {
00764     ipmi_cmd_info_t   *cmd_info = cb_data;
00765     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00766     int               rv;
00767     int               curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00768     int               argc = ipmi_cmdlang_get_argc(cmd_info);
00769     char              **argv = ipmi_cmdlang_get_argv(cmd_info);
00770     ipmi_pef_config_t *lanc;
00771     pef_config_op_t   *info;
00772     char              *name;
00773 
00774     if ((argc - curr_arg) < 1) {
00775         /* Not enough parameters */
00776         cmdlang->errstr = "Not enough parameters";
00777         cmdlang->err = EINVAL;
00778         goto out_err;
00779     }
00780 
00781     name = argv[curr_arg];
00782     curr_arg++;
00783     lanc = find_config(name, 0);
00784     if (!lanc) {
00785         cmdlang->errstr = "Invalid PEF config";
00786         cmdlang->err = EINVAL;
00787         goto out_err;
00788     }
00789 
00790     info = ipmi_mem_alloc(sizeof(*info));
00791     if (!info) {
00792         cmdlang->errstr = "Out of memory";
00793         cmdlang->err = ENOMEM;
00794         goto out_err;
00795     }
00796     info->cmd_info = cmd_info;
00797     strncpy(info->name, name, sizeof(info->name));
00798 
00799     ipmi_cmdlang_cmd_info_get(cmd_info);
00800     rv = ipmi_pef_set_config(pef, lanc, pef_config_set_done, info);
00801     if (rv) {
00802         ipmi_cmdlang_cmd_info_put(cmd_info);
00803         cmdlang->errstr = "Error setting PEF";
00804         cmdlang->err = rv;
00805         ipmi_mem_free(info);
00806         goto out_err;
00807     }
00808 
00809     return;
00810 
00811  out_err:
00812     ipmi_pef_get_name(pef, cmdlang->objstr,
00813                           cmdlang->objstr_len);
00814     cmdlang->location = "cmd_pef.c(pef_config_set)";
00815 }
00816 
00817 static void
00818 pef_config_unlock_done(ipmi_pef_t *pef,
00819                        int        err,
00820                        void       *cb_data)
00821 {
00822     pef_config_op_t *info = cb_data;
00823     ipmi_cmd_info_t *cmd_info = info->cmd_info;
00824     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00825 
00826     ipmi_cmdlang_lock(cmd_info);
00827     if (err) {
00828         ipmi_pef_get_name(pef, cmdlang->objstr,
00829                               cmdlang->objstr_len);
00830         cmdlang->errstr = "Error unlocking PEF";
00831         cmdlang->err = err;
00832         cmdlang->location = "cmd_pef.c(pef_config_unlock_done)";
00833         goto out;
00834     }
00835 
00836     ipmi_cmdlang_out(cmd_info, "PEF config unlocked", info->name);
00837 
00838  out:
00839     ipmi_mem_free(info);
00840     ipmi_cmdlang_unlock(cmd_info);
00841     ipmi_cmdlang_cmd_info_put(cmd_info);
00842 }
00843 
00844 static void
00845 pef_config_unlock(ipmi_pef_t *pef, void *cb_data)
00846 {
00847     ipmi_cmd_info_t   *cmd_info = cb_data;
00848     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00849     int               rv;
00850     int               curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00851     int               argc = ipmi_cmdlang_get_argc(cmd_info);
00852     char              **argv = ipmi_cmdlang_get_argv(cmd_info);
00853     ipmi_pef_config_t *lanc;
00854     pef_config_op_t   *info;
00855     char              *name;
00856 
00857     if ((argc - curr_arg) < 1) {
00858         /* Not enough parameters */
00859         cmdlang->errstr = "Not enough parameters";
00860         cmdlang->err = EINVAL;
00861         goto out_err;
00862     }
00863 
00864     name = argv[curr_arg];
00865     curr_arg++;
00866     lanc = find_config(name, 0);
00867     if (!lanc) {
00868         cmdlang->errstr = "Invalid PEF config";
00869         cmdlang->err = EINVAL;
00870         goto out_err;
00871     }
00872 
00873     info = ipmi_mem_alloc(sizeof(*info));
00874     if (!info) {
00875         cmdlang->errstr = "Out of memory";
00876         cmdlang->err = ENOMEM;
00877         goto out_err;
00878     }
00879     info->cmd_info = cmd_info;
00880     strncpy(info->name, name, sizeof(info->name));
00881 
00882     ipmi_cmdlang_cmd_info_get(cmd_info);
00883     rv = ipmi_pef_clear_lock(pef, lanc, pef_config_unlock_done, info);
00884     if (rv) {
00885         ipmi_cmdlang_cmd_info_put(cmd_info);
00886         cmdlang->errstr = "Error clearing PEF lock";
00887         cmdlang->err = rv;
00888         ipmi_mem_free(info);
00889         goto out_err;
00890     }
00891 
00892     return;
00893 
00894  out_err:
00895     ipmi_pef_get_name(pef, cmdlang->objstr,
00896                           cmdlang->objstr_len);
00897     cmdlang->location = "cmd_pef.c(pef_config_unlock)";
00898 }
00899 
00900 static void
00901 pef_config_close(ipmi_cmd_info_t *cmd_info)
00902 {
00903     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00904     int               curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00905     int               argc = ipmi_cmdlang_get_argc(cmd_info);
00906     char              **argv = ipmi_cmdlang_get_argv(cmd_info);
00907     ipmi_pef_config_t *lanc;
00908     char              *lanc_name;
00909 
00910     if ((argc - curr_arg) < 1) {
00911         /* Not enough parameters */
00912         cmdlang->errstr = "Not enough parameters";
00913         cmdlang->err = EINVAL;
00914         lanc_name = "";
00915         goto out_err;
00916     }
00917     lanc_name = argv[curr_arg];
00918 
00919     lanc = find_config(lanc_name, 1);
00920     if (!lanc) {
00921         cmdlang->errstr = "Invalid PEF config";
00922         cmdlang->err = EINVAL;
00923         goto out_err;
00924     }
00925 
00926     ipmi_pef_free_config(lanc);
00927     ipmi_cmdlang_out(cmd_info, "PEF config destroyed", lanc_name);
00928     return;
00929 
00930  out_err:
00931     strncpy(cmdlang->objstr, lanc_name, cmdlang->objstr_len);
00932     cmdlang->location = "cmd_pef.c(pef_config_close)";
00933 }
00934 
00935 static int
00936 pef_config_list_handler(void *cb_data, void *item1, void *item2)
00937 {
00938     ipmi_cmd_info_t   *cmd_info = cb_data;
00939     pef_config_info_t *info = item1;
00940 
00941     ipmi_cmdlang_out(cmd_info, "Name", info->name);
00942     return LOCKED_LIST_ITER_CONTINUE;
00943 }
00944 
00945 static void
00946 pef_config_list(ipmi_cmd_info_t *cmd_info)
00947 {
00948     ipmi_cmdlang_out(cmd_info, "PEF Configs", NULL);
00949     ipmi_cmdlang_down(cmd_info);
00950     locked_list_iterate(pefs, pef_config_list_handler, cmd_info);
00951     ipmi_cmdlang_up(cmd_info);
00952 }
00953 
00954 static int
00955 pef_config_info_handler(void *cb_data, void *item1, void *item2)
00956 {
00957     ipmi_cmd_info_t   *cmd_info = cb_data;
00958     pef_config_info_t *info = item1;
00959 
00960     ipmi_cmdlang_out(cmd_info, "PEF Config", NULL);
00961     ipmi_cmdlang_down(cmd_info);
00962     ipmi_cmdlang_out(cmd_info, "Name", info->name);
00963     config_info(cmd_info, info->config);
00964     ipmi_cmdlang_up(cmd_info);
00965     return LOCKED_LIST_ITER_CONTINUE;
00966 }
00967 
00968 static void
00969 pef_config_info(ipmi_cmd_info_t *cmd_info)
00970 {
00971     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00972     int               curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00973     int               argc = ipmi_cmdlang_get_argc(cmd_info);
00974     char              **argv = ipmi_cmdlang_get_argv(cmd_info);
00975     ipmi_pef_config_t *lanc;
00976 
00977     if ((argc - curr_arg) < 1) {
00978         locked_list_iterate(pefs, pef_config_info_handler, cmd_info);
00979     } else {
00980         lanc = find_config(argv[curr_arg], 0);
00981         if (!lanc) {
00982             cmdlang->errstr = "Invalid PEF config";
00983             cmdlang->err = EINVAL;
00984             goto out_err;
00985         }
00986         ipmi_cmdlang_out(cmd_info, "PEF Config", NULL);
00987         ipmi_cmdlang_down(cmd_info);
00988         ipmi_cmdlang_out(cmd_info, "Name", argv[curr_arg]);
00989         config_info(cmd_info, lanc);
00990         ipmi_cmdlang_up(cmd_info);
00991     }
00992     return;
00993 
00994  out_err:
00995     strncpy(cmdlang->objstr, argv[curr_arg], cmdlang->objstr_len);
00996     cmdlang->location = "cmd_pef.c(pef_config_info)";
00997 }
00998 
00999 static void
01000 pef_config_update(ipmi_cmd_info_t *cmd_info)
01001 {
01002     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
01003     int               curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
01004     int               argc = ipmi_cmdlang_get_argc(cmd_info);
01005     char              **argv = ipmi_cmdlang_get_argv(cmd_info);
01006     ipmi_pef_config_t *lanc;
01007     int               i;
01008     char              *name;
01009     char              *val;
01010     char              *lanc_name;
01011     int               sel;
01012 
01013     if ((argc - curr_arg) < 3) {
01014         /* Not enough parameters */
01015         cmdlang->errstr = "Not enough parameters";
01016         cmdlang->err = EINVAL;
01017         lanc_name = "";
01018         goto out_err;
01019     }
01020     lanc_name = argv[curr_arg];
01021     curr_arg++;
01022 
01023     lanc = find_config(lanc_name, 0);
01024     if (!lanc) {
01025         cmdlang->errstr = "Invalid PEF config";
01026         cmdlang->err = EINVAL;
01027         goto out_err;
01028     }
01029 
01030     name = argv[curr_arg];
01031     curr_arg++;
01032     val = argv[curr_arg];
01033     curr_arg++;
01034 
01035     /* Basic items */
01036     for (i=0; lps[i].name; i++) {
01037         if (strcmp(lps[i].name, name) == 0) {
01038             lp_item_t *lp = lps[i].lpi;
01039             if (!lp->set) {
01040                 cmdlang->errstr = "Parameter is read-only";
01041                 cmdlang->err = EINVAL;
01042                 goto out_err;
01043             }
01044             lp->set(cmd_info, val, lanc, lps[i].set_func);
01045             goto out;
01046         }
01047     }
01048 
01049     /* per-event filter items */
01050     for (i=0; elps[i].name; i++) {
01051         struct ulps_s *lps = elps;
01052         if (strcmp(lps[i].name, name) == 0) {
01053             ulp_item_t *lp = lps[i].lpi;
01054 
01055             if ((argc - curr_arg) < 1) {
01056                 /* Not enough parameters */
01057                 cmdlang->errstr = "Not enough parameters";
01058                 cmdlang->err = EINVAL;
01059                 goto out_err;
01060             }
01061             if (!lp->set) {
01062                 cmdlang->errstr = "Parameter is read-only";
01063                 cmdlang->err = EINVAL;
01064                 goto out_err;
01065             }
01066             ipmi_cmdlang_get_int(val, &sel, cmd_info);
01067             if (cmdlang->err) {
01068                 cmdlang->errstr = "selector invalid";
01069                 goto out_err;
01070             }
01071             val = argv[curr_arg];
01072             curr_arg++;
01073             lp->set(cmd_info, sel, val, lanc, lps[i].set_func);
01074             goto out;
01075         }
01076     }
01077 
01078     /* per-event filter items */
01079     for (i=0; plps[i].name; i++) {
01080         struct ulps_s *lps = plps;
01081         if (strcmp(lps[i].name, name) == 0) {
01082             ulp_item_t *lp = lps[i].lpi;
01083 
01084             if ((argc - curr_arg) < 1) {
01085                 /* Not enough parameters */
01086                 cmdlang->errstr = "Not enough parameters";
01087                 cmdlang->err = EINVAL;
01088                 goto out_err;
01089             }
01090             if (!lp->set) {
01091                 cmdlang->errstr = "Parameter is read-only";
01092                 cmdlang->err = EINVAL;
01093                 goto out_err;
01094             }
01095             ipmi_cmdlang_get_int(val, &sel, cmd_info);
01096             if (cmdlang->err) {
01097                 cmdlang->errstr = "selector invalid";
01098                 goto out_err;
01099             }
01100             val = argv[curr_arg];
01101             curr_arg++;
01102             lp->set(cmd_info, sel, val, lanc, lps[i].set_func);
01103             goto out;
01104         }
01105     }
01106 
01107     /* per-event filter items */
01108     for (i=0; slps[i].name; i++) {
01109         struct ulps_s *lps = slps;
01110         if (strcmp(lps[i].name, name) == 0) {
01111             ulp_item_t *lp = lps[i].lpi;
01112 
01113             if ((argc - curr_arg) < 1) {
01114                 /* Not enough parameters */
01115                 cmdlang->errstr = "Not enough parameters";
01116                 cmdlang->err = EINVAL;
01117                 goto out_err;
01118             }
01119             if (!lp->set) {
01120                 cmdlang->errstr = "Parameter is read-only";
01121                 cmdlang->err = EINVAL;
01122                 goto out_err;
01123             }
01124             ipmi_cmdlang_get_int(val, &sel, cmd_info);
01125             if (cmdlang->err) {
01126                 cmdlang->