Пример #1
0
SaErrorT
cIpmi::IfSetResetState( cIpmiEntity *ent, SaHpiResetActionT state )
{
  unsigned char reset_state;

  switch( state )
     {
       case SAHPI_COLD_RESET:
            reset_state = 0x00;
            break;

       case SAHPI_WARM_RESET:
            reset_state = 0x01;
            break;

       default:
            IpmiLog( "IfSetResetState: unsupported state 0x%02x !\n", state );
            return SA_ERR_HPI_INVALID_CMD;
     }

  cIpmiMsg  cmd_msg;
  cIpmiMsg  rsp;
  cIpmiAddr addr;

  addr.m_type       = eIpmiAddrTypeIpmb;
  addr.m_channel    = ent->Channel();
  addr.m_slave_addr = ent->AccessAddress();
  addr.m_lun        = ent->Lun();

  cmd_msg.m_netfn    = eIpmiNetfnPicmg;
  cmd_msg.m_cmd      = eIpmiCmdFruControl;
  cmd_msg.m_data[0]  = dIpmiPigMgId;
  cmd_msg.m_data[1]  = ent->FruId();
  cmd_msg.m_data[2]  = state;
  cmd_msg.m_data_len = 3;

  int rv = SendCommand( addr, cmd_msg, rsp );

  if ( rv )
     {
       IpmiLog( "SetHotSwapState: could not send FRU control: 0x%02x !\n", rv );
       return SA_ERR_HPI_INVALID_CMD;
     }

  if (    rsp.m_data_len < 2
       || rsp.m_data[0] != 0
       || rsp.m_data[1] != dIpmiPigMgId )
     {
       IpmiLog( "SetHotSwapState: IPMI error set FRU activation: %x !\n",
                rsp.m_data[0]);

       return SA_ERR_HPI_INVALID_CMD;
     }

  return SA_OK;
}
Пример #2
0
SaErrorT
cIpmi::IfRequestHotswapAction( cIpmiEntity *ent,
                               SaHpiHsActionT act )
{
  if ( !m_is_atca )
     {
       IpmiLog( "ATCA not supported by SI !\n" );
       return SA_ERR_HPI_INVALID;
     }

  unsigned char bit_mask = 0;

  if ( act == SAHPI_HS_ACTION_INSERTION )
     {
       if ( (SaHpiHsStateT)ent->HsState() != SAHPI_HS_STATE_INACTIVE )
            return SA_ERR_HPI_INVALID;

       bit_mask = 1;
     }
  else
     {
       if ( (SaHpiHsStateT)ent->HsState() != SAHPI_HS_STATE_ACTIVE_HEALTHY )
            return SA_ERR_HPI_INVALID;

       bit_mask = 2;
     }

  cIpmiMsg  msg;
  cIpmiMsg  rsp;
  cIpmiAddr addr;

  addr.m_type       = eIpmiAddrTypeIpmb;
  addr.m_channel    = ent->Channel();
  addr.m_slave_addr = ent->AccessAddress();
  addr.m_lun        = 0; //ent->lun;

  msg.m_netfn    = eIpmiNetfnPicmg;
  msg.m_cmd      = eIpmiCmdSetFruActivationPolicy;
  msg.m_data_len = 4;
  msg.m_data[0]  = dIpmiPigMgId;
  msg.m_data[1]  = ent->FruId();
  msg.m_data[2]  = bit_mask;
  msg.m_data[3]  = 0; // clear the activation/deactivation locked

  int rv = SendCommand( addr, msg, rsp );

  if ( rv )
     {
       IpmiLog( "IfRequestHotswapAction: could not send set FRU activation policy: 0x%02x !\n", rv );
       return SA_ERR_HPI_INVALID_CMD;
     }

  return SA_OK;
}
Пример #3
0
SaErrorT
cIpmiSensorHotswap::GetState( tIpmiFruState &state )
{
  // read hotswap state
  cIpmiMsg rsp;

  SaErrorT rv = GetSensorReading( rsp );

  if ( rv != SA_OK )
     {
       IpmiLog( "cannot get hotswap state !\n" );
       return rv;
     }

  unsigned int value = rsp.m_data[3];

  for( int i = 0; i < 8; i++ )
       if ( value & ( 1 << i ) )
          {
            state = (tIpmiFruState)i;
            return SA_OK;
          }

  assert( 0 );
  return SA_ERR_HPI_INVALID_CMD;
}
Пример #4
0
bool
cIpmiSensorHotswap::CreateRdr( SaHpiRptEntryT &resource,
                               SaHpiRdrT &rdr )
{
  if ( cIpmiSensorDiscrete::CreateRdr( resource, rdr ) == false )
       return false;

  if ( !(resource.ResourceCapabilities & SAHPI_CAPABILITY_MANAGED_HOTSWAP) )
     {
       // update resource capabilities
       resource.ResourceCapabilities |= SAHPI_CAPABILITY_MANAGED_HOTSWAP;

       struct oh_event *e = (struct oh_event *)g_malloc0( sizeof( struct oh_event ) );

       if ( !e )
          {
            IpmiLog( "Out of space !\n" );
            return false;
          }

       memset( e, 0, sizeof( struct oh_event ) );
       e->type               = oh_event::OH_ET_RESOURCE;
       e->u.res_event.entry = resource;

       m_mc->Domain()->AddHpiEvent( e );
     }

  return true;
}
Пример #5
0
static void
AddInventoryDataEvent( cIpmiEntity *ent, cIpmiFru *fru, const SaHpiRptEntryT &resource )
{
  struct oh_event *e;

  e = (oh_event *)g_malloc0( sizeof( struct oh_event ) );

  if ( !e )
     {
       IpmiLog( "Out of space !\n" );   
       return;
     }

  memset( e, 0, sizeof( struct oh_event ) );

  e->type                   = oh_event::OH_ET_RDR;

  AddFruEventRdr( fru, e->u.rdr_event.rdr, resource );

  //  SaHpiResourceIdT rid = oh_uid_lookup( &e->u.rdr_event.rdr.Entity );
  oh_add_rdr( ent->Domain()->GetHandler()->rptcache,
              resource.ResourceId,
              &e->u.rdr_event.rdr, fru, 1);

  // assign the hpi record id to fru, so we can find
  // the rdr for a given fru.
  // the id comes from oh_add_rdr.
  fru->m_record_id = e->u.rdr_event.rdr.RecordId;

  ent->Domain()->AddHpiEvent( e );
}
Пример #6
0
bool
cIpmiMcVendor::CreateControlAtcaFan( cIpmiMc *mc, cIpmiSdrs *sdrs,
                                     cIpmiEntity *ent )
{
  cIpmiMsg msg( eIpmiNetfnPicmg, eIpmiCmdGetFanSpeedProperties );
  msg.m_data[0] = dIpmiPigMgId;
  msg.m_data[1] = 0;
  msg.m_data_len = 2;

  cIpmiMsg rsp;

  int rv = mc->SendCommand( msg, rsp );
  
  if (    rv 
       || rsp.m_data_len < 6
       || rsp.m_data[0] != eIpmiCcOk
          || rsp.m_data[1] != dIpmiPigMgId )
     {
       IpmiLog( "cannot send get fan speed properties !\n" );
       return true;
     }

  unsigned int min      = rsp.m_data[2];
  unsigned int max      = rsp.m_data[3];
  unsigned int def      = rsp.m_data[4];
  bool         auto_adj = rsp.m_data[5] & 0x80;

  cIpmiControlFan *f = new cIpmiControlFan( mc, ent, ent->GetControlNum(),
                                            "ATCA-Fan", min, max, def,
                                            auto_adj );

  ent->AddControl( f );

  return true;
}
Пример #7
0
void
cIpmi::HotswapGenerateEvent( cIpmiSensor *sensor, cIpmiEntity *ent,
                             cIpmiEvent *event, SaHpiHsStateT state )
{
  oh_event *e = (oh_event *)g_malloc0( sizeof( oh_event ) );

  if ( !e )
     {
       IpmiLog( "Out of space !\n" );
       return;
     }

  memset( e, 0, sizeof( struct oh_event ) );
  e->type = oh_event::OH_ET_HPI;
  e->u.hpi_event.parent = ent->m_resource_id;

  if ( sensor )
       e->u.hpi_event.id = sensor->m_record_id;
  else
       e->u.hpi_event.id = 0;

  e->u.hpi_event.event.Source = 0;

  e->u.hpi_event.event.EventType = SAHPI_ET_HOTSWAP;
  e->u.hpi_event.event.Timestamp = IpmiGetUint32( event->m_data );

  // Do not find the severity of hotswap event
  e->u.hpi_event.event.Severity = SAHPI_MAJOR;

  e->u.hpi_event.event.EventDataUnion.HotSwapEvent.PreviousHotSwapState = (SaHpiHsStateT)ent->HsState();
  e->u.hpi_event.event.EventDataUnion.HotSwapEvent.HotSwapState = state;

  IpmiLog( "Creating HPI hotswap event: %s -> %s.\n",
           hs_state[ent->HsState()], hs_state[state] );

  dbg( "creating Creating HPI hotswap event: %s -> %s.\n",
       hs_state[ent->HsState()], hs_state[state] );

  //assert( (SaHpiHsStateT)ent->HsState() != state );

  ent->HsState() = state;

  AddHpiEvent( e );
}
Пример #8
0
SaErrorT
cIpmi::IfSetIndicatorState( cIpmiEntity *ent, SaHpiHsIndicatorStateT state )
{
  cIpmiMsg  msg;
  cIpmiMsg  rsp;
  cIpmiAddr addr;

  addr.m_type       = eIpmiAddrTypeIpmb;
  addr.m_channel    = ent->Channel();
  addr.m_slave_addr = ent->AccessAddress();
  addr.m_lun        = 0; //ent->lun;

  msg.m_netfn    = eIpmiNetfnPicmg;
  msg.m_cmd      = eIpmiCmdSetFruLedState;
  msg.m_data_len = 6;
  msg.m_data[0]  = dIpmiPigMgId;
  msg.m_data[1]  = ent->FruId();
  msg.m_data[2]  = 0; // blue led;

  msg.m_data[3]  = (state == SAHPI_HS_INDICATOR_ON) ? 0xff : 0;
  msg.m_data[4]  = 0;
  msg.m_data[5]  = 1; // blue

  int rv = SendCommand( addr, msg, rsp );

  if ( rv )
     {
       IpmiLog( "IfGetIndicatorState: could not send get FRU LED state: 0x%02x !\n", rv );
       return SA_ERR_HPI_INVALID_CMD;
     }

  if (    rsp.m_data_len < 2
       || rsp.m_data[0] != 0
       || rsp.m_data[1] != dIpmiPigMgId )
     {
       IpmiLog( "IfGetIndicatorState: IPMI error set FRU LED state: %x !\n",
                rsp.m_data[0] );

       return SA_ERR_HPI_DATA_LEN_INVALID;
     }

  return SA_OK;
}
Пример #9
0
bool
cIpmiMcVendor::CreateControlsAtca( cIpmiMc *mc, cIpmiSdrs *sdrs,
                                   unsigned int mc_type )
{
  // can only create fan controls 
  if ( (mc_type & dIpmiMcTypeBitFan) == 0 )
       return true;

  // find the mcdlr
  cIpmiSdr *mcdlr = 0;

  for( unsigned int i = 0; i < sdrs->NumSdrs(); i++ )
     {
       cIpmiSdr *sdr = sdrs->Sdr( i );

       if ( sdr->m_type == eSdrTypeMcDeviceLocatorRecord )
          {
            mcdlr = sdr;
            break;
          }
     }

  if ( mcdlr == 0 )
     {
       IpmiLog( "cannot find MC device locator record for ATCA MC !\n" );
       return true;
     }

  // find entity
  tIpmiEntityId ent_id       = (tIpmiEntityId)mcdlr->m_data[12];
  unsigned int  ent_instance =  mcdlr->m_data[13];

  cIpmiEntity *ent = mc->Domain()->Entities().Add( mc, 0,
                                             ent_id, ent_instance,
                                             "" );

  // cannot find or create ent
  if ( ent == 0 )
       return true;

  // create ATCA fan
  if ( mc_type & dIpmiMcTypeBitFan )
     {
       if ( CreateControlAtcaFan( mc, sdrs, ent ) == false )
            return false;
     }

  return true;
}
Пример #10
0
SaErrorT
cIpmi::IfGetPowerState( cIpmiEntity *ent, SaHpiHsPowerStateT &state )
{
  cIpmiAddr addr( eIpmiAddrTypeIpmb, ent->Channel(), 
                  0, ent->AccessAddress() );

  // get power level
  cIpmiMsg msg( eIpmiNetfnPicmg, eIpmiCmdGetPowerLevel );
  cIpmiMsg rsp;

  msg.m_data[0] = dIpmiPigMgId;
  msg.m_data[1] = ent->FruId();
  msg.m_data[2] = 0x01; // desired steady power
  msg.m_data_len = 3;

  int rv = SendCommand( addr, msg, rsp );

  if ( rv )
     {
       IpmiLog( "cannot send get power level: %d\n", rv );
       return SA_ERR_HPI_INVALID_CMD;
     }

  if (    rsp.m_data_len < 3
       || rsp.m_data[0] != eIpmiCcOk 
       || rsp.m_data[0] != dIpmiPigMgId )
     {
       IpmiLog( "cannot get power level: 0x%02x !\n", rsp.m_data[0] );
       return SA_ERR_HPI_INVALID_CMD;
     }

  unsigned char power_level = rsp.m_data[2] & 0x1f;

  // get current power level
  msg.m_data[2]  = 0; // steady state power

  rv = SendCommand( addr, msg, rsp );

  if ( rv )
     {
       IpmiLog( "SetHotSwapState: could not send get power level: 0x%02x !\n", rv );
       return SA_ERR_HPI_INVALID_CMD;
     }

  if (    rsp.m_data_len < 6
       || rsp.m_data[0] != eIpmiCcOk
       || rsp.m_data[1] != dIpmiPigMgId )
     {
       IpmiLog( "SetHotSwapState: IPMI error get power level: 0x%02x !\n",
                rsp.m_data[0]);

       return SA_ERR_HPI_INVALID_CMD;
     }

  unsigned char current_power_level = rsp.m_data[2] & 0x1f;
  
  if ( current_power_level >= power_level )
       state = SAHPI_HS_POWER_ON;
  else
       state = SAHPI_HS_POWER_OFF;

  return SA_OK;
}
Пример #11
0
void
cIpmi::IfHotswapEvent( cIpmiMc *mc, cIpmiSensor *sensor,
                       cIpmiEvent *event )
{
  tIpmiFruState current_state = (tIpmiFruState)(event->m_data[10] & 0x0f);
  tIpmiFruState prev_state    = (tIpmiFruState)(event->m_data[11] & 0x0f);

  if ( mc == 0 )
     {
       IpmiLog( "hotswap event from unknown mc !\n" );
       return;
     }

  if ( sensor == 0 )
     {
       IpmiLog( "hotswap event from unknown sensor !\n" );
       assert( 0 );
     }

  // Not a state change. SetEventReceiver => sensor rearm
  if ( current_state == prev_state )
     {
       assert( current_state != prev_state );
       return;
     }

  cIpmiEntity *ent = sensor->GetEntity();
  assert( ent );

  SaHpiHsStateT state;

  switch( current_state )
     {
       case eIpmiFruStateNotInstalled:
            // prev == eIpmiFruStateInactive or eIpmiFruStateCommunicationLost
            state = SAHPI_HS_STATE_NOT_PRESENT;
            break;

       case eIpmiFruStateInactive:
            // eIpmiFruStateNotInstalled
            // => eIpmiFruStateInactive
            // => eIpmiFruStateActivationRequest
            if ( prev_state == eIpmiFruStateNotInstalled )
                 return;

            state = SAHPI_HS_STATE_INACTIVE;
            break;

       case eIpmiFruStateActivationRequest:
            state = SAHPI_HS_STATE_INSERTION_PENDING;
            break;

       case eIpmiFruStateActivationInProgress:
            return;

       case eIpmiFruStateActive:
            state = SAHPI_HS_STATE_ACTIVE_HEALTHY;
            break;

       case eIpmiFruStateDeactivationRequest:
            state = SAHPI_HS_STATE_EXTRACTION_PENDING;
            break;

       case eIpmiFruStateDeactivationInProgress:
            return;

       case eIpmiFruStateCommunicationLost:
            state = SAHPI_HS_STATE_NOT_PRESENT;
            break;

       default:
            assert( 0 );
            return;
     }

  if ( ent->HsState() == state )
     {
       //assert( ent->HsState() != state );
       return;
     }

  HotswapGenerateEvent( sensor, ent, event, state );
}
Пример #12
0
void
cIpmi::IfFruAdd( cIpmiEntity *ent, cIpmiFru *fru )
{
  IpmiLog( "adding inventory data\n" );

  dbg( "adding inventory data %d.%d (%s): id %02x",
       ent->EntityId(), ent->EntityInstance(),
       ent->EntityIdString(), fru->FruId() );

  // calulate fru inventory size
  unsigned char *buffer = new unsigned char[1024*128];
  SaHpiInventoryDataT *d = (SaHpiInventoryDataT *)buffer;
  fru->m_inventory_size = GetInventoryInfo( fru, *d );
  delete [] buffer;

  // check for overflow
  {
    unsigned int n = 256;

    buffer = new unsigned char[fru->m_inventory_size+n];

    unsigned char *b = buffer + fru->m_inventory_size;
    unsigned int i;

    for( i = 0; i < n; i++ )
         *b++ = (unsigned char)i;

    d = (SaHpiInventoryDataT *)buffer;
    unsigned int s = GetInventoryInfo( fru, *d );

    assert( s == fru->m_inventory_size );

    b = buffer + fru->m_inventory_size;

    for( i = 0; i < n; i++, b++ )
       {
         //printf( "%d = 0x%02x\n", i, *b );
         assert( *b == i );
       }

    delete [] buffer;
  }

  // find resource
  SaHpiRptEntryT *resource = ent->Domain()->FindResource( ent->m_resource_id );

  if ( !resource )
     {
       assert( 0 );
       return;
     }

  if ( !(resource->ResourceCapabilities & SAHPI_CAPABILITY_INVENTORY_DATA ) )
     {
       // update resource
       resource->ResourceCapabilities |= SAHPI_CAPABILITY_RDR|SAHPI_CAPABILITY_INVENTORY_DATA;

       struct oh_event *e = (struct oh_event *)g_malloc0( sizeof( struct oh_event ) );

       if ( !e )
          {
            IpmiLog( "Out of space !\n" );
            return;
          }

       memset( e, 0, sizeof( struct oh_event ) );
       e->type               = oh_event::OH_ET_RESOURCE;
       e->u.res_event.entry = *resource;

       AddHpiEvent( e );
     }

  // create rdr
  AddInventoryDataEvent( ent, fru, *resource );
}
Пример #13
0
SaErrorT
cIpmi::IfGetIndicatorState( cIpmiEntity *ent, SaHpiHsIndicatorStateT &state )
{
  cIpmiMsg  msg;
  cIpmiMsg  rsp;
  cIpmiAddr addr;

  addr.m_type       = eIpmiAddrTypeIpmb;
  addr.m_channel    = ent->Channel();
  addr.m_slave_addr = ent->AccessAddress();
  addr.m_lun        = 0; //ent->lun;

  msg.m_netfn    = eIpmiNetfnPicmg;
  msg.m_cmd      = eIpmiCmdGetFruLedState;
  msg.m_data_len = 3;
  msg.m_data[0]  = dIpmiPigMgId;
  msg.m_data[1]  = ent->FruId();
  msg.m_data[2]  = 0; // blue led;

  int rv = SendCommand( addr, msg, rsp );

  if ( rv )
     {
       IpmiLog( "IfGetIndicatorState: could not send get FRU LED state: 0x%02x !\n", rv );
       return SA_ERR_HPI_INVALID_CMD;
     }

  if (    rsp.m_data_len < 6
       || rsp.m_data[0] != 0
       || rsp.m_data[1] != dIpmiPigMgId )
     {
       IpmiLog( "IfGetIndicatorState: IPMI error set FRU LED state: %x !\n",
                rsp.m_data[0]);

       return SA_ERR_HPI_DATA_LEN_INVALID;
     }

  // lamp test
  if ( rsp.m_data[2] & 4 )
     {     
       if ( rsp.m_data_len < 10 )
          {
            IpmiLog( "IfGetIndicatorState: IPMI error (lamp test) message to short: %d !\n",
                     rsp.m_data_len);

            return SA_ERR_HPI_DATA_LEN_INVALID;
          }
       
       state = SAHPI_HS_INDICATOR_ON;
       return SA_OK;
     }
  
  // overwrite state
  if ( rsp.m_data[2] & 2 )
     {
       if ( rsp.m_data_len < 9 )
          {
            IpmiLog( "IfGetIndicatorState: IPMI error (overwrite) message to short: %d !\n",
                     rsp.m_data_len );

            return SA_ERR_HPI_DATA_LEN_INVALID;
          }

       if ( rsp.m_data[6] == 0 )
            state = SAHPI_HS_INDICATOR_OFF;
       else
            state = SAHPI_HS_INDICATOR_ON;

       return SA_OK;
     }

  // local control state
  if ( rsp.m_data[3] == 0 )
       state = SAHPI_HS_INDICATOR_OFF;
  else
       state = SAHPI_HS_INDICATOR_ON;

  return SA_OK;
}
Пример #14
0
SaErrorT
cIpmi::IfSetPowerState( cIpmiEntity *ent, SaHpiHsPowerStateT state )
{
  int rv;
  unsigned int power_level = 0;

  cIpmiAddr addr( eIpmiAddrTypeIpmb, ent->Channel(), 
                  0, ent->AccessAddress() );
  cIpmiMsg msg( eIpmiNetfnPicmg, eIpmiCmdGetPowerLevel );
  msg.m_data[0] = dIpmiPigMgId;
  msg.m_data[1] = ent->FruId();
  cIpmiMsg rsp;

  if ( state == SAHPI_HS_POWER_CYCLE )
     {
       // power off
       msg.m_cmd = eIpmiCmdSetPowerLevel;

       msg.m_data[2] = power_level;
       msg.m_data[3] = 0x01; // copy desierd level to present level
       msg.m_data_len = 4;

       rv = SendCommand( addr, msg, rsp );

       if ( rv )
          {
            IpmiLog( "cannot send set power level: %d\n", rv );
            return SA_ERR_HPI_INVALID_CMD;
          }

       if (    rsp.m_data_len < 2
               || rsp.m_data[0] != eIpmiCcOk 
               || rsp.m_data[1] != dIpmiPigMgId )
          {
            IpmiLog( "cannot set power level: 0x%02x !\n", rsp.m_data[0] );
            return SA_ERR_HPI_INVALID_CMD;
          }

       // power on
       state = SAHPI_HS_POWER_ON;
     }

  if ( state == SAHPI_HS_POWER_ON )
     {
       // get power level
       msg.m_cmd = eIpmiCmdGetPowerLevel;

       msg.m_data[2] = 0x01; // desired steady power
       msg.m_data_len = 3;

       rv = SendCommand( addr, msg, rsp );

       if ( rv )
          {
            IpmiLog( "cannot send get power level: %d\n", rv );
            return SA_ERR_HPI_INVALID_CMD;
          }

       if (    rsp.m_data_len < 3
            || rsp.m_data[0] != eIpmiCcOk 
            || rsp.m_data[1] != dIpmiPigMgId )
          {
            IpmiLog( "cannot get power level: 0x%02x !\n", rsp.m_data[0] );
            return SA_ERR_HPI_INVALID_CMD;
          }

       power_level = rsp.m_data[2] & 0x1f;
     }
  else
       assert( state == SAHPI_HS_POWER_OFF );

  // set power level
  msg.m_cmd = eIpmiCmdSetPowerLevel;

  msg.m_data[2] = power_level;
  msg.m_data[3] = 0x01; // copy desierd level to present level
  msg.m_data_len = 4;

  rv = SendCommand( addr, msg, rsp );

  if ( rv )
     {
       IpmiLog( "cannot send set power level: %d\n", rv );
       return SA_ERR_HPI_INVALID_CMD;
     }

  if (    rsp.m_data_len < 2
       || rsp.m_data[0] != eIpmiCcOk 
       || rsp.m_data[1] != dIpmiPigMgId )
     {
       IpmiLog( "cannot set power level: 0x%02x !\n", rsp.m_data[0] );
       return SA_ERR_HPI_INVALID_CMD;
     }

  return SA_OK;
}
Пример #15
0
SaErrorT
cIpmi::IfSetHotswapState( cIpmiEntity *ent, SaHpiHsStateT state )
{
  if ( !m_is_atca )
     {
       IpmiLog( "ATCA not supported by SI !\n" );
       return SA_ERR_HPI_INVALID;
     }

  unsigned char fru_state;

  switch( state )
     {
       case SAHPI_HS_STATE_ACTIVE_HEALTHY:
            fru_state = dIpmiActivateFru;
            break;

       case SAHPI_HS_STATE_INACTIVE:
            fru_state = dIpmiDeactivateFru;
            break;

       default:
            IpmiLog( "IfSetHotSwapState: illegal state %d !\n", state );
            return SA_ERR_HPI_INVALID;
     }

  cIpmiMsg  cmd_msg;
  cIpmiMsg  rsp;
  cIpmiAddr addr;

  addr.m_type       = eIpmiAddrTypeIpmb;
  addr.m_channel    = ent->Channel();
  addr.m_slave_addr = ent->AccessAddress();
  addr.m_lun        = 0; //ent->lun;

  cmd_msg.m_netfn    = eIpmiNetfnPicmg;
  cmd_msg.m_cmd      = eIpmiCmdSetFruActivation;
  cmd_msg.m_data_len = 3;
  cmd_msg.m_data[0]  = dIpmiPigMgId;
  cmd_msg.m_data[1]  = ent->FruId();
  cmd_msg.m_data[2]  = fru_state;

  int rv = SendCommand( addr, cmd_msg, rsp );

  if ( rv )
     {
       IpmiLog( "IfSetHotSwapState: could not send set FRU activation: 0x%02x !\n", rv );
       return SA_ERR_HPI_INVALID_CMD;
     }

  if (    rsp.m_data_len < 2
       || rsp.m_data[0] != 0
       || rsp.m_data[1] != dIpmiPigMgId )
     {
       IpmiLog( "IfSetHotSwapState: IPMI error set FRU activation: %x !\n",
                rsp.m_data[0]);

       return SA_ERR_HPI_DATA_LEN_INVALID;
     }

  return SA_OK;
}
Пример #16
0
bool
cIpmiMcVendor::CreateSensors( cIpmiMc *mc, cIpmiSdrs *sdrs )
{
  unsigned int   i;
  unsigned int   j;
  cIpmiSensor  **sdr_sensors;
  cIpmiSensor  **old_sdr_sensors;
  unsigned int   old_count;
  unsigned int   count;
  cIpmiDomain *domain = mc->Domain();

  sdr_sensors = GetSensorsFromSdrs( mc, sdrs, count );

  if ( !sdr_sensors )
       return true;

  for( i = 0; i < count; i++ )
     {
       cIpmiSensor *nsensor = sdr_sensors[i];

       if ( nsensor == 0 )
            continue;

       if ( domain->Entities().Add( nsensor->Mc(),
                                    i, // is this right (lun) ?
                                    nsensor->EntityId(),
                                    (unsigned int)nsensor->EntityInstance(),
                                    "" ) == 0 )
            goto out_err;

       cIpmiSensorInfo *sensors = nsensor->Mc()->Sensors();

       // There's not enough room in the sensor repository for the new
       // item, so expand the array.
       if ( nsensor->Num() >= sensors->m_idx_size[nsensor->Lun()] )
          {
            unsigned int  new_size = nsensor->Num() + 10;
            cIpmiSensor **new_by_idx = new cIpmiSensor *[new_size];
            if ( !new_by_idx )
                 goto out_err;

            if ( sensors->m_sensors_by_idx[nsensor->Lun()] )
               {
                 memcpy( new_by_idx,
                        sensors->m_sensors_by_idx[nsensor->Lun()],
                        (sensors->m_idx_size[nsensor->Lun()]
                         * sizeof( cIpmiSensor *) ) );

                 delete [] sensors->m_sensors_by_idx[nsensor->Lun()];
               }

            for( j = sensors->m_idx_size[nsensor->Lun()]; j < new_size; j++)
                 new_by_idx[j] = 0;

            sensors->m_sensors_by_idx[nsensor->Lun()] = new_by_idx;
            sensors->m_idx_size[nsensor->Lun()] = new_size;
          }
     }

  // After this point, the operation cannot fail.
  old_sdr_sensors = domain->GetSdrSensors( mc, old_count );

  // For each new sensor, put it into the MC it belongs with.
  for( i = 0; i < count; i++ )
     {
       cIpmiSensor *nsensor = sdr_sensors[i];

       if ( !nsensor )
            continue;

       cIpmiSensorInfo *sensors = nsensor->Mc()->Sensors();

       if (    sensors->m_sensors_by_idx[nsensor->Lun()]
            && (nsensor->Num() < sensors->m_idx_size[nsensor->Lun()])
            && sensors->m_sensors_by_idx[nsensor->Lun()][nsensor->Num()])
          {
            // It's already there.
            cIpmiSensor *osensor
              = sensors->m_sensors_by_idx[nsensor->Lun()][nsensor->Num()];

            if ( osensor->SourceArray() == sdr_sensors )
               {
                 // It's from the same SDR repository, log an error
                 // and continue to delete the first one.
                 IpmiLog( "Sensor 0x%x is the same as sensor 0x%x in the"
                          " repository",
                          osensor->SourceIdx(),
                          nsensor->SourceIdx());
               }

            // Delete the sensor from the source array it came
            // from.
            if ( osensor->SourceArray() )
               {
                 osensor->SetSourceArray( osensor->SourceIdx(), 0 );
                 osensor->SetSourceArray( 0 );
               }

            if ( nsensor->Cmp( *osensor ) )
               {
                 // They compare, prefer to keep the old data.
                 delete nsensor;
                 sdr_sensors[i] = osensor;
                 osensor->SourceIdx() = i;
                 osensor->SetSourceArray( sdr_sensors );
               }
            else
               {
                 osensor->Destroy();

                 sensors->m_sensors_by_idx[nsensor->Lun()][nsensor->Num()]
                   = nsensor;
                 nsensor->HandleNew( domain );
               }
          }
       else
          {
            // It's a new sensor.
            sensors->m_sensors_by_idx[nsensor->Lun()][nsensor->Num()] = nsensor;
            sensors->m_sensor_count++;
            nsensor->HandleNew( domain );
          }
     }

  domain->SetSdrSensors( mc, sdr_sensors, count );

  if ( old_sdr_sensors )
     {
       for( i = 0; i < old_count; i++ )
          {
            cIpmiSensor *osensor = old_sdr_sensors[i];
            if ( osensor != 0 )
               {
                 // This sensor was not in the new repository, so it must
                 // have been deleted.
                 osensor->Destroy();
               }
          }

       delete [] old_sdr_sensors;
     }

  return true;

out_err:
  return false;
}
Пример #17
0
cIpmiCon *
cIpmi::AllocConnection( GHashTable *handler_config )
{
  // default is 5s for IPMI
  unsigned int ipmi_timeout = GetIntNotNull( handler_config, "IpmiConnectionTimeout", 5000 );
  IpmiLog( "AllocConnection: IPMITimeout %d ms.\n", ipmi_timeout );

   // default is 1s for ATCA systems
  unsigned int atca_timeout = GetIntNotNull( handler_config, "AtcaConnectionTimeout", 1000 );
  IpmiLog( "AllocConnection: AtcaTimeout %d ms.\n", atca_timeout );

  // default 8 outstanding messages
  unsigned int max_outstanding = GetIntNotNull( handler_config, "MaxOutstanding", 8 );

  if ( max_outstanding < 1 )
       max_outstanding = 1;
  else if ( max_outstanding > 256 )
       max_outstanding = 256;

  IpmiLog( "AllocConnection: Max Outstanding IPMI messages %d.\n", max_outstanding );

  const char *name = (const char *)g_hash_table_lookup(handler_config, "name");

  if ( !name )
     {
       IpmiLog( "Empty parameter !\n");
       return 0;
     }

  IpmiLog( "IpmiAllocConnection: connection name = '%s'.\n", name );

  if ( !strcmp( name, "lan" ) )
     {
       const char     *addr;
       struct in_addr  lan_addr;
       int             lan_port   = dIpmiConLanStdPort;
       tIpmiAuthType   auth       = eIpmiAuthTypeNone;
       tIpmiPrivilege  priv       = eIpmiPrivilegeAdmin;
       char            user[32]   = "";
       char            passwd[32] = "";
       char           *value;
       struct hostent *ent;

       // Address
       addr = (const char *)g_hash_table_lookup(handler_config, "addr");

       if ( !addr )
          {
            IpmiLog( "TCP/IP address missing in config file !\n" );
            return 0;
          }

       IpmiLog( "IpmiAllocConnection: addr = '%s'.\n", addr );
       ent = gethostbyname( addr );

       if ( !ent )
          {
            IpmiLog( "Unable to resolve IPMI LAN address: %s !\n", addr );
            return 0;
          }

       memcpy( &lan_addr, ent->h_addr_list[0], ent->h_length );
       unsigned int a = *(unsigned int *)ent->h_addr_list[0];

       IpmiLog( "Using host at %d.%d.%d.%d.\n",
                a & 0xff, (a >> 8 ) & 0xff, 
                (a >> 16) & 0xff, (a >> 24) & 0xff );

       // Port
       lan_port = GetIntNotNull( handler_config, "port", 623 );

       IpmiLog( "IpmiAllocConnection: port = %i.\n", lan_port );

       // Authentication type
       value = (char *)g_hash_table_lookup( handler_config, "auth_type" );

       if ( value )
          {
            if ( !strcmp( value, "none" ) )
                 auth = eIpmiAuthTypeNone;
            else if ( !strcmp( value, "straight" ) )
                 auth = eIpmiAuthTypeStraight;
            else if ( !strcmp( value, "md2" ) )
                 auth = eIpmiAuthTypeMd2;
            else if ( !strcmp( value, "md5" ) )
                 auth = eIpmiAuthTypeMd5;
            else
               {
                 IpmiLog( "Invalid IPMI LAN authenication method '%s' !\n", value );
                 return 0;
               }
          }

       IpmiLog( "IpmiAllocConnection: authority: %s(%i).\n", value, auth );

       // Priviledge
       value = (char *)g_hash_table_lookup(handler_config, "auth_level" );

       if ( value )
          {
            if ( !strcmp( value, "callback" ) )
                 priv = eIpmiPrivilegeCallback;
            else if ( !strcmp( value, "user" ) )
                 priv = eIpmiPrivilegeUser;
            else if ( !strcmp( value, "operator" ) )
                 priv = eIpmiPrivilegeOperator;
            else if ( !strcmp( value, "admin" ) )
                 priv = eIpmiPrivilegeAdmin;
            else
               {
                 IpmiLog( "Invalid authentication method '%s' !\n", value );
                 return 0;
               }
          }

       IpmiLog( "IpmiAllocConnection: priviledge = %s(%i).\n", value, priv );

       // User Name
       value = (char *)g_hash_table_lookup( handler_config, "username" ); 

       if ( value )
            strncpy( user, value, 32);

       IpmiLog( "IpmiAllocConnection: user = %s.\n", user );

       // Password
       value = (char *)g_hash_table_lookup( handler_config, "password" );

       if ( value )
            strncpy( passwd, value, 32 );

       IpmiLog( "IpmiAllocConnection: password = %s.\n", user );

       return new cIpmiConLan( ipmi_timeout, atca_timeout, max_outstanding, 
                               lan_addr, lan_port, auth, priv,
                               user, passwd );
     }
  else if ( !strcmp( name, "smi" ) )
Пример #18
0
bool
cIpmiMcVendorForceShMc::Init( cIpmiMc *mc, const cIpmiMsg &devid )
{
  IpmiLog( "Force ShMc found.\n" );

  // because we are talking to a ShMC and not the ShM,
  // we need to do some setup:
  // 1.) set the MC in ShMc mode
  // 2.) clear repository SDR

  if ( mc->Addr().IsType( eIpmiAddrTypeSystemInterface ) )
     {
       // we want to go into BMC mode
       IpmiLog( "switch to ShMc mode.\n" );

       cIpmiMsg msg( (tIpmiNetfn)0x30, (tIpmiCmd)0x03 );
       msg.m_data[0] = 0;
       msg.m_data_len = 1;

       cIpmiMsg rsp;

       int rv = mc->SendCommand( msg, rsp );

       if ( rv )
          {
            IpmiLog( "cannot send set BMC mode: %d\n", rv );
            return false;
          }

       if ( rsp.m_data_len <= 0 || rsp.m_data[0] != eIpmiCcOk )
          {
            IpmiLog( "cannot go into BMC mode: %02x\n", rsp.m_data[0] );
            return false;
          }
     }

  // check if there is a repository SDR
  if ( devid.m_data[6] & 2 )
     {
       IpmiLog( "clear repository SDR.\n" );

       // clear repository SDR

       // get a reservation
       cIpmiMsg msg( eIpmiNetfnStorage, eIpmiCmdReserveSdrRepository );
       msg.m_data_len = 0;
       cIpmiMsg rsp;
       
       int rv = mc->SendCommand( msg, rsp );

       if ( rv )
          {
            IpmiLog( "cannot send reserve reposotory SDR: %d\n", rv );
            return false;
          }

       if ( rsp.m_data_len != 3 || rsp.m_data[0] != eIpmiCcOk )
          {
            IpmiLog( "cannot reserve repository SDR: %02x\n",
                     rsp.m_data[0] );

            return false;
          }

       unsigned short reservation = IpmiGetUint16( rsp.m_data + 1 );

       // create repository SDR and wait until erase completed
       bool first = true;

       msg.m_netfn = eIpmiNetfnStorage;
       msg.m_cmd   = eIpmiCmdClearSdrRepository;
       IpmiSetUint16( msg.m_data, reservation );
       msg.m_data[2] = 'C';
       msg.m_data[3] = 'L';
       msg.m_data[4] = 'R';
       msg.m_data_len = 6;

       do
          {
            msg.m_data[5] = first ? 0xaa : 0; // initiate erase/ erase status
            first = false;

            rv = mc->SendCommand( msg, rsp );

            if ( rv )
               {
                 IpmiLog( "cannot send clear SDR reposotory: %d\n", rv );
                 return false;
               }

            if ( rsp.m_data_len != 2 || rsp.m_data[0] != eIpmiCcOk )
               {
                 IpmiLog( "cannot reserve repository SDR: %02x\n",
                          rsp.m_data[0] );

                 return false;
               }
          }
       // wait until erase is complete
       while( (rsp.m_data[1] & 0x7) != 0x1 );
     }

  // this is for debugging only
  if ( devid.m_data[6] & 4 )
     {
       IpmiLog( "clear SEL.\n" );

       // get a reservation
       cIpmiMsg msg( eIpmiNetfnStorage, eIpmiCmdReserveSel );
       msg.m_data_len = 0;
       cIpmiMsg rsp;

       int rv = mc->SendCommand( msg, rsp );

       if ( rv )
          {
            IpmiLog( "cannot send reserve SEL: %d\n", rv );
            return false;
          }

       if ( rsp.m_data_len != 3 || rsp.m_data[0] != eIpmiCcOk )
          {
            IpmiLog( "cannot reserve SEL: %02x\n",
                     rsp.m_data[0] );
       
            return false;
          }

       unsigned short reservation = IpmiGetUint16( rsp.m_data + 1 );

       // clear SEL
       msg.m_netfn = eIpmiNetfnStorage;
       msg.m_cmd   = eIpmiCmdClearSel;
       IpmiSetUint16( msg.m_data, reservation );
       msg.m_data[2] = 'C';
       msg.m_data[3] = 'L';
       msg.m_data[4] = 'R';
       msg.m_data_len = 6;
       
       bool first = true;

       do
          {
            msg.m_data[5] = first ? 0xaa : 0; // initiate erase/ erase status
            first = false;

            rv = mc->SendCommand( msg, rsp );

            if ( rv )
               {
                 IpmiLog( "cannot send clear SDR reposotory: %d\n", rv );
                 return false;
               }

            if ( rsp.m_data_len != 2 || rsp.m_data[0] != eIpmiCcOk )
               {
                 IpmiLog( "cannot reserve repository SDR: %02x\n",
                          rsp.m_data[0] );

                 return false;
               }
          }
       // wait until erase is complete
       while( (rsp.m_data[1] & 0x7) != 0x1 );
     }

  return true;
}
Пример #19
0
SaErrorT
cIpmi::IfRequestHotswapAction( cIpmiEntity *ent,
                               SaHpiHsActionT act )
{
  if ( !m_is_atca )
     {
       IpmiLog( "ATCA not supported by SI !\n" );
       return SA_ERR_HPI_INVALID;
     }

  // get hotswap sensor
  cIpmiSensorHotswap *hs = ent->GetHotswapSensor();

  if ( !hs )
       return SA_ERR_HPI_INVALID_PARAMS;

  SaHpiHsStateT current;
  SaErrorT rv = hs->GetState( current );
  
  if ( rv != SA_OK )
       return rv;

  cIpmiAddr addr;

  addr.m_type       = eIpmiAddrTypeIpmb;
  addr.m_channel    = ent->Channel();
  addr.m_slave_addr = ent->AccessAddress();
  addr.m_lun        = 0; //ent->lun;

  cIpmiMsg msg;
  msg.m_netfn = eIpmiNetfnPicmg;

  if ( act == SAHPI_HS_ACTION_INSERTION )
     {
       if ( current != SAHPI_HS_STATE_INACTIVE )
          {
            IpmiLog( "FRU not SAHPI_HS_STATE_INACTIVE: %d !\n",
                     current );
            return SA_ERR_HPI_INVALID;
          }

       msg.m_cmd      = eIpmiCmdSetFruActivationPolicy;
       msg.m_data_len = 4;
       msg.m_data[0]  = dIpmiPigMgId;
       msg.m_data[1]  = ent->FruId();
       msg.m_data[2]  = 1;
       msg.m_data[3]  = 0; // clear the activation/deactivation locked
     }
  else
     {
       if ( current != SAHPI_HS_STATE_ACTIVE_HEALTHY )
          {
            IpmiLog( "FRU not SAHPI_HS_STATE_ACTIVE_HEALTHY: %d !\n",
                     current );
            return SA_ERR_HPI_INVALID;
          }

       msg.m_cmd      = eIpmiCmdSetFruActivation;
       msg.m_data_len = 3;
       msg.m_data[0]  = dIpmiPigMgId;
       msg.m_data[1]  = ent->FruId();
       msg.m_data[2]  = 0; // deactivate
     }

  cIpmiMsg  rsp;

  int r = SendCommand( addr, msg, rsp );

  if ( r )
     {
       IpmiLog( "IfRequestHotswapAction: could not send set FRU activation policy: 0x%02x !\n", r );
       return SA_ERR_HPI_INVALID_CMD;
     }

  if (    rsp.m_data_len != 2 
       || rsp.m_data[0] != eIpmiCcOk
       || rsp.m_data[1] != dIpmiPigMgId )
     {
       IpmiLog( "IfRequestHotswapAction: set FRU activation: 0x%02x !\n", rsp.m_data[0] );
       return SA_ERR_HPI_INVALID_CMD;
     }

  return SA_OK;
}