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; }
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; }
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; }
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; }
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 ); }
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; }
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 ); }
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; }
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; }
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; }
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 ); }
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 ); }
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; }
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; }
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; }
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; }
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" ) )
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; }
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; }