Provided by: libedac-dev_0.18+git12-gd98769e-1_amd64 bug


       libedac - EDAC error reporting library


       #include <edac.h>

       cc ... -ledac

       edac_handle * edac_handle_create (void);

       void edac_handle_destroy (edac_handle *edac);

       int edac_handle_init (edac_handle *edac);

       unsigned int edac_mc_count (edac_handle *edac);

       int edac_handle_reset (edac_handle *edac);

       int edac_error_totals (edac_handle *edac, struct edac_totals *totals);

       edac_mc * edac_next_mc (edac_handle *edac);

       int edac_mc_get_info (edac_mc *mc, struct edac_mc_info *info);

       edac_mc *edac_next_mc_info (edac_handle *edac,
                                   struct edac_mc_info *info);

       int edac_mc_reset (struct edac_mc *mc);

       edac_csrow * edac_next_csrow (struct edac_mc *mc);

       int edac_csrow_get_info (edac_csrow *csrow,
                                struct edac_csrow_info *info);

       edac_csrow * edac_next_csrow_info (edac_mc *mc,
                                          struct edac_csrow_info *info);

       const char * edac_strerror (edac_handle *edac);

       edac_for_each_mc_info (edac_handle *edac, edac_mc *mc,
                              struct edac_csrow_info *info)    { ... }

       edac_for_each_csrow_info (edac_mc *mc, edac_csrow *csrow,
                                 struct edac_csrow_info *info) { ... }


       The libedac library offers a very simple programming interface to the information exported
       from in-kernel EDAC (Error Detection and Correction) drivers in  sysfs.  The  edac-util(8)
       utility uses libedac to report errors in a user-friendly manner from the command line.

       EDAC  errors for most systems are recorded in sysfs on a per memory controller (MC) basis.
       Memory controllers are further subdivided  by  csrow  and  channel.  The  libedac  library
       provides  a method to loop through multiple MCs, and their corresponding csrows, obtaining
       information about each component from sysfs along the way. There is also a  simple  single
       call to retrieve the total error counts for a given machine.

       In   order   to   use   libedac   an  edac_handle  must  first  be  opened  via  the  call
       edac_handle_create(). Once the handle is created, sysfs data can be loaded into the handle
       with  edac_handle_init().  A  final call to edac_handle_destroy() will free all memory and
       open files associated with the edac handle.

       edac_handle_create() will return NULL on failure to allocate memory.

       The edac_strerror function will return a descriptive string  representation  of  the  last
       error for the libedac handle edac.

       The  edac_error_totals() function will return the total counts of memory and pci errors in
       the totals structure passed to the function. The totals structure is of  type  edac_totals
       which has the form:

              struct edac_totals {
                 unsigned int  ce_total;         /* Total corrected errors   */
                 unsigned int  ue_total;         /* Total uncorrected errors */
                 unsigned int  pci_parity_total; /* Total PCI Parity errors  */


       Systems  may  have one or more memory controllers (MCs) with EDAC information.  The number
       of MCs detected by EDAC drivers may be queried with the  edac_mc_count()  function,  while
       the  edac_next_mc  function  will  return  a  handle  to the next memory controller in the
       libedac handle┬┤s internal list. This  memory  controller  is  represented  by  the  opaque
       edac_mc type.

       edac_next_mc will return NULL when there are no further memory controllers to return. Thus
       the following example code is another method to count all  EDAC  MCs  (assuming  the  EDAC
       library handle edac has already been initialized):

              int i = 0;
              edac_mc *mc;
              while ((mc = edac_next_mc (edac)))
              return (i);

       To  query  information  about an edac_mc, use the edac_mc_get_info function. This function
       fills in the given info structure, which is of type edac_mc_info:

              struct edac_mc_info {
                  char           id[];           /* Id of memory controller */
                  char           mc_name[];      /* Name of MC              */
                  unsigned int   size_mb;        /* Amount of RAM in MB     */
                  unsigned int   ce_count;       /* Corrected error count   */
                  unsigned int   ce_noinfo_count;/* noinfo Corrected errors */
                  unsigned int   ue_count;       /* Uncorrected error count */
                  unsigned int   ue_noinfo_count;/* noinfo Uncorrected errors*/

       The function edac_next_mc_info() can be used to loop through all EDAC  memory  controllers
       and  obtain  MC  information  in  a  single  call.  It  is  a  combined edac_next_mc() and

       The function edac_handle_reset() will reset the internal memory controller iterator in the
       libedac handle. A subsequent call to edac_next_mc() would thus return the first EDAC MC.

       A  convenience  macro,  edac_for_each_mc_info(), is provided which defines a for loop that
       iterates through all memory controller
        objects for a given EDAC handle, returning the MC information in the  info  structure  on
       each iteration. For example (assuming initialized libedac handle edac):

              edac_mc *mc;
              struct edac_mc_info info;
              int count = 0;

              edac_for_each_mc_info (edac, mc, info) {
                  printf ("MC info: id=%s name=%s\n",, info.mc_name);


       Each EDAC memory controller may have one or more csrows associated with it. Similar to the
       MC iterator functions described above, the edac_next_csrow() function allows libedac users
       to loop through all csrows within a given MC. Once the last csrow is reached, the function
       will return NULL.

       The  edac_csrow_get_info()  function  returns  information   about   edac_csrow   in   the
       edac_csrow_info structure, which has the contents:

              struct edac_csrow_info {
                  char          id[];      /* CSROW Identity (e.g. csrow0)  */
                  unsigned int  size_mb;   /* CSROW size in MB              */
                  unsigned int  ce_count;  /* Total corrected errors        */
                  unsigned int  ue_count;  /* Total uncorrected errors      */
                  struct edac_channel channel[EDAC_MAX_CHANNELS];

              struct edac_channel {
                  int           valid;            /* Is this channel valid */
                  unsigned int  ce_count;         /* Corrected error count */
                  int           dimm_label_valid; /* Is DIMM label valid?  */
                  char          dimm_label[];     /* DIMM name             */

       The  edac_next_csrow_info()  function  is  a  combined  version  of  edac_next_csrow() and
       edac_csrow_get_info() for convenience.

       The edac_mc_reset() function is provided to reset the edac_mc internal csrow iterator.

       A convenience macro, edac_for_each_csrow_info(), is provided which defines a for loop that
       iterates  through  all  csrow  objects  in  an EDAC memory controller, returning the csrow
       information in the info structure on each iteration.


       Initialize libedac handle:

              edac_handle *edac;

              if (!(edac = edac_handle_create ())) {
                  fprintf (stderr, "edac_handle_create: Out of memory!\n");
                  exit (1);

              if (edac_handle_init (edac) < 0) {
                 fprintf (stderr, "Unable to get EDAC data: %s\n",
                                  edac_strerror (edac));
                 exit (1);

              printf ("EDAC initialized with %d MCs\n", edac_mc_count (edac));

              edac_handle_destroy (edac);

       Report all DIMM labels for MC:csrow:channel combinations

              edac_mc *mc;
              edac_csrow *csrow;
              struct edac_mc_info mci;
              struct edac_csrow_info csi;

              edac_for_each_mc_info (ctx->edac, mc, mci) {
                  edac_for_each_csrow_info (mc, csrow, csi) {
                      char *label[2] = { "unset", "unset" };

                      if ([0].dimm_label_valid)
                          label[0] =[0].dimm_label;
                      if ([1].dimm_label_valid)
                          label[1] =[1].dimm_label;

                      printf ("%s:%s:ch0 = %s\n",,, label[0]);
                      printf ("%s:%s:ch1 = %s\n",,, label[1]);


       edac-util(8), edac-ctl(8)

@META_ALIAS                                 2011-11-09                                    EDAC(3)