Blame lib/ipmi_sdradd.c

Packit d14fb6
/*
Packit d14fb6
 * Redistribution and use in source and binary forms, with or without
Packit d14fb6
 * modification, are permitted provided that the following conditions
Packit d14fb6
 * are met:
Packit d14fb6
 * 
Packit d14fb6
 * Redistribution of source code must retain the above copyright
Packit d14fb6
 * notice, this list of conditions and the following disclaimer.
Packit d14fb6
 * 
Packit d14fb6
 * Redistribution in binary form must reproduce the above copyright
Packit d14fb6
 * notice, this list of conditions and the following disclaimer in the
Packit d14fb6
 * documentation and/or other materials provided with the distribution.
Packit d14fb6
 * 
Packit d14fb6
 * Neither the name of Sun Microsystems, Inc. or the names of
Packit d14fb6
 * contributors may be used to endorse or promote products derived
Packit d14fb6
 * from this software without specific prior written permission.
Packit d14fb6
 * 
Packit d14fb6
 * This software is provided "AS IS," without a warranty of any kind.
Packit d14fb6
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
Packit d14fb6
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
Packit d14fb6
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
Packit d14fb6
 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
Packit d14fb6
 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
Packit d14fb6
 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
Packit d14fb6
 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
Packit d14fb6
 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
Packit d14fb6
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
Packit d14fb6
 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
Packit d14fb6
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
Packit d14fb6
 */
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Functions to program the SDR repository, from built-in sensors or
Packit d14fb6
 * from sensors dumped in a binary file.
Packit d14fb6
 */
Packit d14fb6
Packit d14fb6
#include <stdlib.h>
Packit d14fb6
#include <string.h>
Packit d14fb6
#include <stdio.h>
Packit d14fb6
#include <time.h>
Packit d14fb6
#include <fcntl.h>
Packit d14fb6
#include <unistd.h>
Packit d14fb6
Packit d14fb6
#include <ipmitool/helper.h>
Packit d14fb6
#include <ipmitool/log.h>
Packit d14fb6
#include <ipmitool/bswap.h>
Packit d14fb6
#include <ipmitool/ipmi.h>
Packit d14fb6
#include <ipmitool/ipmi_intf.h>
Packit d14fb6
#include <ipmitool/ipmi_mc.h>
Packit d14fb6
#include <ipmitool/ipmi_strings.h>
Packit d14fb6
Packit d14fb6
#include <ipmitool/ipmi_sdr.h>
Packit d14fb6
Packit d14fb6
Packit d14fb6
#define ADD_PARTIAL_SDR 0x25
Packit d14fb6
Packit d14fb6
#ifdef HAVE_PRAGMA_PACK
Packit d14fb6
#pragma pack(1)
Packit d14fb6
#endif
Packit d14fb6
struct sdr_add_rq {
Packit d14fb6
  uint16_t reserve_id;  /* reservation ID */
Packit d14fb6
  uint16_t id;          /* record ID */
Packit d14fb6
  uint8_t offset;       /* offset into SDR */
Packit d14fb6
  uint8_t in_progress;  /* 0=partial, 1=last */
Packit d14fb6
#define PARTIAL_ADD (0)
Packit d14fb6
#define LAST_RECORD (1)
Packit d14fb6
  uint8_t data[1];      /* SDR record data */
Packit d14fb6
} ATTRIBUTE_PACKING;
Packit d14fb6
#ifdef HAVE_PRAGMA_PACK
Packit d14fb6
#pragma pack(0)
Packit d14fb6
#endif
Packit d14fb6
Packit d14fb6
/* This was formerly initialized to 24, reduced this to 19 so the overall
Packit d14fb6
   message fits into the recommended 32-byte limit */
Packit d14fb6
static int sdr_max_write_len = 19;
Packit d14fb6
int ipmi_parse_range_list(const char *rangeList, unsigned char *pHexList);
Packit d14fb6
int ipmi_hex_to_dec( char * rangeList, unsigned char * pDecValue);
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
partial_send(struct ipmi_intf *intf, struct ipmi_rq *req, uint16_t *id)
Packit d14fb6
{
Packit d14fb6
  struct ipmi_rs *rsp;
Packit d14fb6
  rsp = intf->sendrecv(intf, req);
Packit d14fb6
  if (rsp == NULL) {
Packit d14fb6
    return -1;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  if (rsp->ccode || rsp->data_len < 2) {
Packit d14fb6
    return -1;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  *id = rsp->data[0] + (rsp->data[1] << 8);
Packit d14fb6
  return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
int
Packit d14fb6
ipmi_sdr_add_record(struct ipmi_intf *intf, struct sdr_record_list *sdrr)
Packit d14fb6
{
Packit d14fb6
  struct ipmi_rq req;
Packit d14fb6
  struct sdr_add_rq *sdr_rq;
Packit d14fb6
  uint16_t reserve_id;
Packit d14fb6
  uint16_t id;
Packit d14fb6
  int i;
Packit d14fb6
  int len = sdrr->length;
Packit d14fb6
  int rc = 0;
Packit d14fb6
Packit d14fb6
  /* actually no SDR to program */
Packit d14fb6
  if (len < 1 || !sdrr->raw) {
Packit d14fb6
    lprintf(LOG_ERR, "ipmitool: bad record , skipped");
Packit d14fb6
    return 0;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  if (ipmi_sdr_get_reservation(intf, 0, &reserve_id)) {
Packit d14fb6
    lprintf(LOG_ERR, "ipmitool: reservation failed");
Packit d14fb6
    return -1;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  sdr_rq = (struct sdr_add_rq *)malloc(sizeof(*sdr_rq) + sdr_max_write_len);
Packit d14fb6
  if (sdr_rq == NULL) {
Packit d14fb6
    lprintf(LOG_ERR, "ipmitool: malloc failure");
Packit d14fb6
    return -1;
Packit d14fb6
  }
Packit d14fb6
  sdr_rq->reserve_id = reserve_id;
Packit d14fb6
  sdr_rq->in_progress = PARTIAL_ADD;
Packit d14fb6
Packit d14fb6
  memset(&req, 0, sizeof(req));
Packit d14fb6
  req.msg.netfn = IPMI_NETFN_STORAGE;
Packit d14fb6
  req.msg.cmd = ADD_PARTIAL_SDR;
Packit d14fb6
  req.msg.data = (uint8_t *) sdr_rq;
Packit d14fb6
Packit d14fb6
  /* header first */
Packit d14fb6
  sdr_rq->id = 0;
Packit d14fb6
  sdr_rq->offset = 0;
Packit d14fb6
  sdr_rq->data[0] = sdrr->id & 0xFF;
Packit d14fb6
  sdr_rq->data[1] = (sdrr->id >> 8) & 0xFF;
Packit d14fb6
  sdr_rq->data[2] = sdrr->version;
Packit d14fb6
  sdr_rq->data[3] = sdrr->type;
Packit d14fb6
  sdr_rq->data[4] = sdrr->length;
Packit d14fb6
  req.msg.data_len = 5 + sizeof(*sdr_rq) - 1;
Packit d14fb6
Packit d14fb6
  if (partial_send(intf, &req, &id)) {
Packit d14fb6
     lprintf(LOG_ERR, "ipmitool: partial send error");
Packit d14fb6
    free(sdr_rq);
Packit d14fb6
    sdr_rq = NULL;
Packit d14fb6
    return -1;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  i = 0;
Packit d14fb6
Packit d14fb6
  /* sdr entry */
Packit d14fb6
  while (i < len) {
Packit d14fb6
     int data_len = 0;
Packit d14fb6
     if ( (len - i) <= sdr_max_write_len) {
Packit d14fb6
      /* last crunch */
Packit d14fb6
      data_len = len - i;
Packit d14fb6
      sdr_rq->in_progress = LAST_RECORD;
Packit d14fb6
    } else {
Packit d14fb6
      data_len = sdr_max_write_len;
Packit d14fb6
    }
Packit d14fb6
Packit d14fb6
    sdr_rq->id = id;
Packit d14fb6
    sdr_rq->offset = i + 5;
Packit d14fb6
    memcpy(sdr_rq->data, sdrr->raw + i, data_len);
Packit d14fb6
    req.msg.data_len = data_len + sizeof(*sdr_rq) - 1;
Packit d14fb6
Packit d14fb6
    if ((rc = partial_send(intf, &req, &id)) != 0) {
Packit d14fb6
       lprintf(LOG_ERR, "ipmitool: partial add failed");
Packit d14fb6
      break;
Packit d14fb6
    }
Packit d14fb6
Packit d14fb6
    i += data_len;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  free(sdr_rq);
Packit d14fb6
  sdr_rq = NULL;
Packit d14fb6
  return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
ipmi_sdr_repo_clear(struct ipmi_intf *intf)
Packit d14fb6
{
Packit d14fb6
  struct ipmi_rs * rsp;
Packit d14fb6
  struct ipmi_rq req;
Packit d14fb6
  uint8_t msg_data[8];
Packit d14fb6
  uint16_t reserve_id;
Packit d14fb6
  int try;
Packit d14fb6
Packit d14fb6
  if (ipmi_sdr_get_reservation(intf, 0, &reserve_id))
Packit d14fb6
    return -1;
Packit d14fb6
Packit d14fb6
  memset(&req, 0, sizeof(req));
Packit d14fb6
  req.msg.netfn = IPMI_NETFN_STORAGE;
Packit d14fb6
  req.msg.cmd = 0x27; // FIXME
Packit d14fb6
  req.msg.data = msg_data;
Packit d14fb6
  req.msg.data_len = 6;
Packit d14fb6
Packit d14fb6
  msg_data[0] = reserve_id & 0xFF;
Packit d14fb6
  msg_data[1] = reserve_id >> 8;
Packit d14fb6
  msg_data[2] = 'C';
Packit d14fb6
  msg_data[3] = 'L';
Packit d14fb6
  msg_data[4] = 'R';
Packit d14fb6
  msg_data[5] = 0xAA;
Packit d14fb6
Packit d14fb6
  for (try = 0; try < 5; try++) {
Packit d14fb6
    rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
    if (rsp == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "Unable to clear SDRR");
Packit d14fb6
      return -1;
Packit d14fb6
    }
Packit d14fb6
    if (rsp->ccode > 0) {
Packit d14fb6
      lprintf(LOG_ERR, "Unable to clear SDRR: %s",
Packit d14fb6
        val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
      return -1;
Packit d14fb6
    }
Packit d14fb6
    if ((rsp->data[0] & 1) == 1) {
Packit d14fb6
      printf("SDRR successfully erased\n");
Packit d14fb6
      return 0;
Packit d14fb6
    }
Packit d14fb6
    printf("Wait for SDRR erasure completed...\n");
Packit d14fb6
    msg_data[5] = 0;
Packit d14fb6
    sleep(1);
Packit d14fb6
  }
Packit d14fb6
    
Packit d14fb6
  /* if we are here we fed up trying erase */
Packit d14fb6
  return -1;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
struct sdrr_queue {
Packit d14fb6
  struct sdr_record_list *head;
Packit d14fb6
  struct sdr_record_list *tail;
Packit d14fb6
}; 
Packit d14fb6
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Fill the SDR repository from built-in sensors
Packit d14fb6
 *
Packit d14fb6
 */
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Get all the SDR records stored in <queue>
Packit d14fb6
 */
Packit d14fb6
static int
Packit d14fb6
sdrr_get_records(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr,
Packit d14fb6
                 struct sdrr_queue *queue)
Packit d14fb6
{
Packit d14fb6
  struct sdr_get_rs *header;
Packit d14fb6
Packit d14fb6
  queue->head = NULL;
Packit d14fb6
  queue->tail = NULL;
Packit d14fb6
Packit d14fb6
  while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
Packit d14fb6
    struct sdr_record_list *sdrr;
Packit d14fb6
Packit d14fb6
    sdrr = malloc(sizeof (struct sdr_record_list));
Packit d14fb6
    if (sdrr == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "ipmitool: malloc failure");
Packit d14fb6
      return -1;
Packit d14fb6
    }
Packit d14fb6
    memset(sdrr, 0, sizeof (struct sdr_record_list));
Packit d14fb6
   
Packit d14fb6
    sdrr->id = header->id;
Packit d14fb6
    sdrr->version = header->version;
Packit d14fb6
    sdrr->type = header->type;
Packit d14fb6
    sdrr->length = header->length;
Packit d14fb6
    sdrr->raw = ipmi_sdr_get_record(intf, header, itr);
Packit d14fb6
    (void)ipmi_sdr_print_name_from_rawentry(intf,  sdrr->id, sdrr->type,sdrr->raw);
Packit d14fb6
Packit d14fb6
    /* put in the record queue */
Packit d14fb6
    if (queue->head == NULL)
Packit d14fb6
      queue->head = sdrr;
Packit d14fb6
    else
Packit d14fb6
      queue->tail->next = sdrr;
Packit d14fb6
    queue->tail = sdrr;
Packit d14fb6
  }
Packit d14fb6
  return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
sdr_copy_to_sdrr(struct ipmi_intf *intf, int use_builtin,
Packit d14fb6
                 int from_addr, int to_addr)
Packit d14fb6
{
Packit d14fb6
  int rc;
Packit d14fb6
  struct sdrr_queue sdrr_queue;
Packit d14fb6
  struct ipmi_sdr_iterator *itr;
Packit d14fb6
  struct sdr_record_list *sdrr;
Packit d14fb6
  struct sdr_record_list *sdrr_next;
Packit d14fb6
Packit d14fb6
  /* generate list of records for this target */
Packit d14fb6
  intf->target_addr = from_addr;
Packit d14fb6
Packit d14fb6
  /* initialize iterator */
Packit d14fb6
  itr = ipmi_sdr_start(intf, use_builtin);
Packit d14fb6
  if (itr == 0)
Packit d14fb6
    return 0;
Packit d14fb6
Packit d14fb6
  printf("Load SDRs from 0x%x\n", from_addr);
Packit d14fb6
  rc = sdrr_get_records(intf, itr, &sdrr_queue);
Packit d14fb6
  ipmi_sdr_end(intf, itr);
Packit d14fb6
  /* ... */
Packit d14fb6
Packit d14fb6
  /* write the SDRs to the destination SDR Repository */
Packit d14fb6
  intf->target_addr = to_addr;
Packit d14fb6
  for (sdrr = sdrr_queue.head; sdrr != NULL; sdrr = sdrr_next) {
Packit d14fb6
    sdrr_next = sdrr->next;
Packit d14fb6
    rc = ipmi_sdr_add_record(intf, sdrr);
Packit d14fb6
    if(rc < 0){
Packit d14fb6
      lprintf(LOG_ERR, "Cannot add SDR ID 0x%04x to repository...", sdrr->id);
Packit d14fb6
    }
Packit d14fb6
    free(sdrr);
Packit d14fb6
    sdrr = NULL;
Packit d14fb6
  }
Packit d14fb6
  return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
int
Packit d14fb6
ipmi_sdr_add_from_sensors(struct ipmi_intf *intf, int maxslot)
Packit d14fb6
{
Packit d14fb6
  int i;
Packit d14fb6
  int rc = 0;
Packit d14fb6
  int slave_addr;
Packit d14fb6
  int myaddr = intf->target_addr;
Packit d14fb6
Packit d14fb6
  if (ipmi_sdr_repo_clear(intf)) {
Packit d14fb6
    lprintf(LOG_ERR, "Cannot erase SDRR. Give up.");
Packit d14fb6
    return -1;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  /* First fill the SDRR from local built-in sensors */
Packit d14fb6
  rc = sdr_copy_to_sdrr(intf, 1, myaddr, myaddr);
Packit d14fb6
Packit d14fb6
  /* Now fill the SDRR with remote sensors */
Packit d14fb6
  if( maxslot != 0 ) {
Packit d14fb6
     for (i = 0, slave_addr = 0xB0; i < maxslot; i++, slave_addr += 2) {
Packit d14fb6
        /* Hole in the PICMG 2.9 mapping */
Packit d14fb6
        if (slave_addr == 0xC2) slave_addr += 2;
Packit d14fb6
        if(sdr_copy_to_sdrr(intf, 0, slave_addr, myaddr) < 0)
Packit d14fb6
        {
Packit d14fb6
           rc = -1;
Packit d14fb6
        }
Packit d14fb6
     }
Packit d14fb6
  }
Packit d14fb6
  return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
int ipmi_hex_to_dec( char * strchar, unsigned char * pDecValue)
Packit d14fb6
{
Packit d14fb6
  int rc = -1;
Packit d14fb6
  unsigned char retValue = 0; 
Packit d14fb6
Packit d14fb6
  if(
Packit d14fb6
     (strlen(strchar) == 4) 
Packit d14fb6
     &&
Packit d14fb6
     (strchar[0] == '0') 
Packit d14fb6
     && 
Packit d14fb6
     (strchar[1] == 'x') 
Packit d14fb6
    ) 
Packit d14fb6
  {
Packit d14fb6
      rc = 0;
Packit d14fb6
Packit d14fb6
      if((strchar[2] >= '0') && (strchar[2] <= '9')) 
Packit d14fb6
      {
Packit d14fb6
        retValue += ((strchar[2]-'0') * 16);
Packit d14fb6
      }
Packit d14fb6
      else if((strchar[2] >= 'a') && (strchar[2] <= 'f')) 
Packit d14fb6
      {
Packit d14fb6
        retValue += (((strchar[2]-'a') + 10) * 16);
Packit d14fb6
      }
Packit d14fb6
      else if((strchar[2] >= 'A') && (strchar[2] <= 'F')) 
Packit d14fb6
      {
Packit d14fb6
        retValue += (((strchar[2]-'A') + 10) * 16);
Packit d14fb6
      }
Packit d14fb6
      else
Packit d14fb6
      {
Packit d14fb6
        rc = -1;
Packit d14fb6
      }
Packit d14fb6
Packit d14fb6
      if((strchar[3] >= '0') && (strchar[3] <= '9')) 
Packit d14fb6
      {
Packit d14fb6
        retValue += ((strchar[3]-'0'));
Packit d14fb6
      }
Packit d14fb6
      else if((strchar[3] >= 'a') && (strchar[3] <= 'f')) 
Packit d14fb6
      {
Packit d14fb6
        retValue += (((strchar[3]-'a') + 10));
Packit d14fb6
      }
Packit d14fb6
      else if((strchar[3] >= 'A') && (strchar[3] <= 'F')) 
Packit d14fb6
      {
Packit d14fb6
        retValue += (((strchar[3]-'A') + 10));
Packit d14fb6
      }
Packit d14fb6
      else
Packit d14fb6
      {
Packit d14fb6
        rc = -1;
Packit d14fb6
      }
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  if(rc == 0) 
Packit d14fb6
  {
Packit d14fb6
    * pDecValue = retValue;
Packit d14fb6
  }
Packit d14fb6
  else
Packit d14fb6
  {
Packit d14fb6
    lprintf(LOG_ERR, "Must be Hex value of 4 characters (Ex.: 0x24)");
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
Packit d14fb6
#define MAX_NUM_SLOT  128
Packit d14fb6
int ipmi_parse_range_list(const char *rangeList, unsigned char * pHexList)
Packit d14fb6
{
Packit d14fb6
  int rc = -1;
Packit d14fb6
Packit d14fb6
  unsigned char listOffset = 0;
Packit d14fb6
  char * nextString;
Packit d14fb6
  char * rangeString;
Packit d14fb6
  char * inProcessString = (char *) rangeList;
Packit d14fb6
Packit d14fb6
  /* Discard empty string */
Packit d14fb6
  if(strlen(rangeList) == 0) 
Packit d14fb6
  {
Packit d14fb6
    return rc;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  /* First, cut to comma separated string */
Packit d14fb6
  nextString = strstr( rangeList, "," );
Packit d14fb6
Packit d14fb6
  if(nextString != rangeList) 
Packit d14fb6
  {
Packit d14fb6
    unsigned char isLast;
Packit d14fb6
    /* We get a valid string so far */
Packit d14fb6
    rc = 0;
Packit d14fb6
Packit d14fb6
    do
Packit d14fb6
    {
Packit d14fb6
      if(nextString != NULL) 
Packit d14fb6
      {
Packit d14fb6
        (*nextString)= 0;
Packit d14fb6
        nextString   ++;
Packit d14fb6
        isLast = 0;
Packit d14fb6
      }
Packit d14fb6
      else
Packit d14fb6
      {
Packit d14fb6
        isLast = 1;
Packit d14fb6
      }
Packit d14fb6
Packit d14fb6
      /* At this point, it is a single entry or a range */
Packit d14fb6
      rangeString = strstr( inProcessString, "-" );
Packit d14fb6
      if(rangeString == NULL) 
Packit d14fb6
      {
Packit d14fb6
        unsigned char decValue = 0;
Packit d14fb6
Packit d14fb6
        /* Single entry */
Packit d14fb6
        rc = ipmi_hex_to_dec( inProcessString, &decValue); 
Packit d14fb6
        
Packit d14fb6
        if(rc == 0)
Packit d14fb6
        {  
Packit d14fb6
          if((decValue % 2) == 0)
Packit d14fb6
          {
Packit d14fb6
            pHexList[listOffset++] = decValue;
Packit d14fb6
          }
Packit d14fb6
          else
Packit d14fb6
          {
Packit d14fb6
            lprintf(LOG_ERR, "I2C address provided value must be even.");
Packit d14fb6
          }
Packit d14fb6
        }
Packit d14fb6
      }
Packit d14fb6
      else
Packit d14fb6
      {
Packit d14fb6
        unsigned char startValue = 0;
Packit d14fb6
        unsigned char endValue = 0;
Packit d14fb6
Packit d14fb6
Packit d14fb6
        (*rangeString)= 0; /* Cut string*/
Packit d14fb6
        rangeString ++;
Packit d14fb6
Packit d14fb6
        /* Range */
Packit d14fb6
        rc = ipmi_hex_to_dec( inProcessString, &startValue); 
Packit d14fb6
        if(rc == 0) 
Packit d14fb6
          rc = ipmi_hex_to_dec( rangeString, &endValue); 
Packit d14fb6
Packit d14fb6
        if(rc == 0)
Packit d14fb6
        {  
Packit d14fb6
          if(((startValue % 2) == 0) && ((endValue % 2) == 0))
Packit d14fb6
          {
Packit d14fb6
            do
Packit d14fb6
            {
Packit d14fb6
              pHexList[listOffset++] = startValue;
Packit d14fb6
              startValue += 2;
Packit d14fb6
            }
Packit d14fb6
            while(startValue != endValue);
Packit d14fb6
            pHexList[listOffset++] = endValue;
Packit d14fb6
          }
Packit d14fb6
          else
Packit d14fb6
          {
Packit d14fb6
            lprintf(LOG_ERR, "I2C address provided value must be even.");
Packit d14fb6
          }
Packit d14fb6
        }
Packit d14fb6
      }
Packit d14fb6
Packit d14fb6
      if(isLast == 0) 
Packit d14fb6
      {
Packit d14fb6
        /* Setup for next string */
Packit d14fb6
        inProcessString = nextString;
Packit d14fb6
        nextString = strstr( rangeList, "," );
Packit d14fb6
      }
Packit d14fb6
    }while ((isLast == 0) && (rc == 0)); 
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
int
Packit d14fb6
ipmi_sdr_add_from_list(struct ipmi_intf *intf, const char *rangeList)
Packit d14fb6
{
Packit d14fb6
  int rc = 0;
Packit d14fb6
  int slave_addr;
Packit d14fb6
  int myaddr = intf->target_addr;
Packit d14fb6
  unsigned char listValue[MAX_NUM_SLOT];
Packit d14fb6
Packit d14fb6
  memset( listValue, 0, MAX_NUM_SLOT );
Packit d14fb6
Packit d14fb6
  /* Build list from string */
Packit d14fb6
  if(ipmi_parse_range_list(rangeList, listValue) != 0)
Packit d14fb6
  {
Packit d14fb6
    lprintf(LOG_ERR, "Range - List invalid, cannot be parsed.");
Packit d14fb6
    return -1;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  {
Packit d14fb6
    unsigned char counter = 0;
Packit d14fb6
    printf("List to scan: (Built-in) ");
Packit d14fb6
    while(listValue[counter] != 0) 
Packit d14fb6
    {
Packit d14fb6
      printf("%02x ", listValue[counter]);
Packit d14fb6
      counter++;
Packit d14fb6
    }
Packit d14fb6
    printf("\n");
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  printf("Clearing SDR Repository\n");
Packit d14fb6
  if (ipmi_sdr_repo_clear(intf)) {
Packit d14fb6
    lprintf(LOG_ERR, "Cannot erase SDRR. Give up.");
Packit d14fb6
    return -1;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  /* First fill the SDRR from local built-in sensors */
Packit d14fb6
  printf("Sanning built-in sensors..\n");
Packit d14fb6
  rc = sdr_copy_to_sdrr(intf, 1, myaddr, myaddr);
Packit d14fb6
Packit d14fb6
  /* Now fill the SDRR with provided sensors list */
Packit d14fb6
  {
Packit d14fb6
    unsigned char counter = 0;
Packit d14fb6
    while((rc == 0) && (listValue[counter] != 0)) 
Packit d14fb6
    {
Packit d14fb6
      slave_addr = listValue[counter];
Packit d14fb6
      printf("Scanning %02Xh..\n", slave_addr);
Packit d14fb6
      if(sdr_copy_to_sdrr(intf, 0, slave_addr, myaddr) < 0)
Packit d14fb6
      {
Packit d14fb6
         rc = -1;
Packit d14fb6
      }
Packit d14fb6
      counter++;
Packit d14fb6
    }
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Fill the SDR repository from records stored in a binary file
Packit d14fb6
 *
Packit d14fb6
 */
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
ipmi_sdr_read_records(const char *filename, struct sdrr_queue *queue)
Packit d14fb6
{
Packit d14fb6
  int rc = 0;
Packit d14fb6
  int fd;
Packit d14fb6
  uint8_t binHdr[5];
Packit d14fb6
Packit d14fb6
  queue->head = NULL;
Packit d14fb6
  queue->tail = NULL;
Packit d14fb6
Packit d14fb6
  if ((fd = open(filename, O_RDONLY)) < 0) {
Packit d14fb6
    return -1;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  while (read(fd, binHdr, 5) == 5) {
Packit d14fb6
    
Packit d14fb6
    struct sdr_record_list *sdrr;
Packit d14fb6
Packit d14fb6
    lprintf(LOG_DEBUG, "binHdr[0] (id[MSB]) = 0x%02x", binHdr[0]);
Packit d14fb6
    lprintf(LOG_DEBUG, "binHdr[1] (id[LSB]) = 0x%02x", binHdr[1]);
Packit d14fb6
    lprintf(LOG_DEBUG, "binHdr[2] (version) = 0x%02x", binHdr[2]);
Packit d14fb6
    lprintf(LOG_DEBUG, "binHdr[3] (type) = 0x%02x", binHdr[3]);
Packit d14fb6
    lprintf(LOG_DEBUG, "binHdr[4] (length) = 0x%02x", binHdr[4]);
Packit d14fb6
Packit d14fb6
    sdrr = malloc(sizeof(*sdrr));
Packit d14fb6
    if (sdrr == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "ipmitool: malloc failure");
Packit d14fb6
      rc = -1;
Packit d14fb6
      break;
Packit d14fb6
    }
Packit d14fb6
    sdrr->id = (binHdr[1] << 8) | binHdr[0];  // LS Byte first
Packit d14fb6
    sdrr->version = binHdr[2];
Packit d14fb6
    sdrr->type = binHdr[3];
Packit d14fb6
    sdrr->length = binHdr[4];
Packit d14fb6
Packit d14fb6
    if ((sdrr->raw = malloc(sdrr->length)) == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "ipmitool: malloc failure");
Packit d14fb6
      free(sdrr);
Packit d14fb6
      sdrr = NULL;
Packit d14fb6
      rc = -1;
Packit d14fb6
      break;
Packit d14fb6
    }
Packit d14fb6
Packit d14fb6
    if (read(fd, sdrr->raw, sdrr->length) != sdrr->length) {
Packit d14fb6
      lprintf(LOG_ERR, "SDR from '%s' truncated", filename);
Packit d14fb6
      free(sdrr->raw);
Packit d14fb6
      sdrr->raw = NULL;
Packit d14fb6
      free(sdrr);
Packit d14fb6
      sdrr = NULL;
Packit d14fb6
      rc = -1;
Packit d14fb6
      break;
Packit d14fb6
    }
Packit d14fb6
Packit d14fb6
    /* put in the record queue */
Packit d14fb6
    if (queue->head == NULL)
Packit d14fb6
      queue->head = sdrr;
Packit d14fb6
    else
Packit d14fb6
      queue->tail->next = sdrr;
Packit d14fb6
    queue->tail = sdrr;
Packit d14fb6
  }
Packit d14fb6
  close(fd);
Packit d14fb6
  return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
int
Packit d14fb6
ipmi_sdr_add_from_file(struct ipmi_intf *intf, const char *ifile)
Packit d14fb6
{
Packit d14fb6
  int rc;
Packit d14fb6
  struct sdrr_queue sdrr_queue;
Packit d14fb6
  struct sdr_record_list *sdrr;
Packit d14fb6
  struct sdr_record_list *sdrr_next;
Packit d14fb6
Packit d14fb6
  /* read the SDR records from file */
Packit d14fb6
  rc = ipmi_sdr_read_records(ifile, &sdrr_queue);
Packit d14fb6
Packit d14fb6
  if (ipmi_sdr_repo_clear(intf)) {
Packit d14fb6
    lprintf(LOG_ERR, "Cannot erase SDRR. Giving up.");
Packit d14fb6
    /* FIXME: free sdr list */
Packit d14fb6
    return -1;
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
  /* write the SDRs to the SDR Repository */
Packit d14fb6
  for (sdrr = sdrr_queue.head; sdrr != NULL; sdrr = sdrr_next) {
Packit d14fb6
    sdrr_next = sdrr->next;
Packit d14fb6
    rc = ipmi_sdr_add_record(intf, sdrr);
Packit d14fb6
    if(rc < 0){
Packit d14fb6
      lprintf(LOG_ERR, "Cannot add SDR ID 0x%04x to repository...", sdrr->id);
Packit d14fb6
    }
Packit d14fb6
    free(sdrr);
Packit d14fb6
    sdrr = NULL;
Packit d14fb6
  }
Packit d14fb6
  return rc;
Packit d14fb6
}
Packit d14fb6