123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882 |
- /*
- * Copyright (C) 2008 Intel Corporation.
- * All rights reserved
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- /* Theory of operation
- *
- * DCMI is the Data Center Management Interface which is a subset of IPMI v2.0.
- * DCMI incorporates the ability to locate a system with DCMI functionality,
- * its available temperature sensors, and power limiting control.
- *
- * All of the available DCMI commands are contained in a struct with a numeric
- * value and a string. When the user specifies a command the string is
- * compared to one of several structs and is then given a numeric value based
- * on the matched string. A case statement is used to select the desired
- * action from the user. If an invalid string is entered, or a string that is
- * not a command option is entered, the available commands are printed to the
- * screen. This allows the strings to be changed quickly with the DCMI spec.
- *
- * Each called function usually executes whichever command was requested to
- * keep the main() from being overly complicated.
- *
- * This code conforms to the 1.0 DCMI Specification
- * released by Hari Ramachandran of the Intel Corporation
- */
- #define _BSD_SOURCE
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <math.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <time.h>
- #include <netdb.h>
- #include <ipmitool/ipmi_dcmi.h>
- #include <ipmitool/helper.h>
- #include <ipmitool/ipmi.h>
- #include <ipmitool/log.h>
- #include <ipmitool/ipmi_intf.h>
- #include <ipmitool/ipmi_strings.h>
- #include <ipmitool/ipmi_mc.h>
- #include <ipmitool/ipmi_entity.h>
- #include <ipmitool/ipmi_constants.h>
- #include <ipmitool/ipmi_sensor.h>
- #include "../src/plugins/lanplus/lanplus.h"
- #define IPMI_LAN_PORT 0x26f
- extern int verbose;
- extern int csv_output;
- static int ipmi_print_sensor_info(struct ipmi_intf *intf, uint16_t rec_id);
- /*******************************************************************************
- * The structs below are the DCMI command option strings. They are printed *
- * when the user does not issue enough options or the wrong ones. The reason *
- * that the DMCI command strings are in a struct is so that when the *
- * specification changes, the strings can be changed quickly with out having *
- * to change a lot of the code in the main(). *
- ******************************************************************************/
- /* Main set of DCMI commands */
- const struct dcmi_cmd dcmi_cmd_vals[] = {
- { 0x00, "discover", " Used to discover supported DCMI capabilities" },
- { 0x01, "power", " Platform power limit command options" },
- { 0x02, "sensors", " Prints the available DCMI sensors" },
- { 0x03, "asset_tag", " Prints the platform's asset tag" },
- { 0x04, "set_asset_tag", " Sets the platform's asset tag" },
- { 0x05, "get_mc_id_string", " Get management controller ID string" },
- { 0x06, "set_mc_id_string", " Set management controller ID string" },
- { 0x07, "thermalpolicy", " Thermal policy get/set" },
- { 0x08, "get_temp_reading", " Get Temperature Readings" },
- { 0x09, "get_conf_param", " Get DCMI Config Parameters" },
- { 0x0A, "set_conf_param", " Set DCMI Config Parameters" },
- { 0x0B, "oob_discover", " Ping/Pong Message for DCMI Discovery" },
- { 0xFF, NULL, NULL }
- };
- /* get capabilites */
- const struct dcmi_cmd dcmi_capable_vals[] = {
- { 0x01, "platform", " Lists the system capabilities" },
- { 0x02, "mandatory_attributes", "Lists SEL, identification and"
- "temperature attributes" },
- { 0x03, "optional_attributes", " Lists power capabilities" },
- { 0x04, "managebility access", " Lists OOB channel information" },
- { 0xFF, NULL, NULL }
- };
- /* platform capabilities
- * Since they are actually in two bytes, we need three structs to make this
- * human readable...
- */
- const struct dcmi_cmd dcmi_mandatory_platform_capabilities[] = {
- { 0x01, "Identification support available", "" },
- { 0x02, "SEL logging available", "" },
- { 0x03, "Chassis power available", "" },
- { 0x04, "Temperature monitor available", "" },
- { 0xFF, NULL, NULL }
- };
- /* optional capabilities */
- const struct dcmi_cmd dcmi_optional_platform_capabilities[] = {
- { 0x01, "Power management available", "" },
- { 0xFF, NULL, NULL }
- };
- /* access capabilties */
- const struct dcmi_cmd dcmi_management_access_capabilities[] = {
- { 0x01, "In-band KCS channel available", "" },
- { 0x02, "Out-of-band serial TMODE available", "" },
- { 0x03, "Out-of-band secondary LAN channel available", "" },
- { 0x04, "Out-of-band primary LAN channel available", "" },
- { 0x05, "SOL enabled", "" },
- { 0x06, "VLAN capable", "" },
- { 0xFF, NULL, NULL }
- };
- /* identification capabilities */
- const struct dcmi_cmd dcmi_id_capabilities_vals[] = {
- { 0x01, "GUID", "" },
- { 0x02, "DHCP hostname", "" },
- { 0x03, "Asset tag", "" },
- { 0xFF, NULL, NULL }
- };
- /* Configuration parameters*/
- const struct dcmi_cmd dcmi_conf_param_vals[] = {
- { 0x01, "activate_dhcp", "\tActivate DHCP"},
- { 0x02, "dhcp_config", "\tDHCP Configuration" },
- { 0x03, "init", "\t\tInitial timeout interval" },
- { 0x04, "timeout", "\t\tServer contact timeout interval" },
- { 0x05, "retry", "\t\tServer contact retry interval" },
- { 0xFF, NULL, NULL }
- };
- /* temperature monitoring capabilities */
- const struct dcmi_cmd dcmi_temp_monitoring_vals[] = {
- { 0x01, "inlet", " Inlet air temperature sensors" },
- { 0x02, "cpu", " CPU temperature sensors" },
- { 0x03, "baseboard", "Baseboard temperature sensors" },
- { 0xff, NULL, NULL }
- };
- /* These are not comands. These are the DCMI temp sensors and their numbers
- * If new sensors are added, they need to be added to this list with their
- * sensor number
- */
- const struct dcmi_cmd dcmi_discvry_snsr_vals[] = {
- { 0x40, "Inlet", " Inlet air temperature sensors" },
- { 0x41, "CPU", " CPU temperature sensors" },
- { 0x42, "Baseboard", "Baseboard temperature sensors" },
- { 0xff, NULL, NULL }
- };
- /* Temperature Readings */
- const struct dcmi_cmd dcmi_temp_read_vals[] = {
- { 0x40, "Inlet", "Inlet air temperature(40h) " },
- { 0x41, "CPU", "CPU temperature sensors(41h) " },
- { 0x42, "Baseboard", "Baseboard temperature sensors(42h) " },
- { 0xff, NULL, NULL }
- };
- /* power management/control commands */
- const struct dcmi_cmd dcmi_pwrmgmt_vals[] = {
- { 0x00, "reading", " Get power related readings from the system" },
- { 0x01, "get_limit", " Get the configured power limits" },
- { 0x02, "set_limit", " Set a power limit option" },
- { 0x03, "activate", " Activate the set power limit" },
- { 0x04, "deactivate", "Deactivate the set power limit" },
- { 0xFF, NULL, NULL }
- };
- /* set power limit commands */
- const struct dcmi_cmd dcmi_pwrmgmt_set_usage_vals[] = {
- { 0x00, "action", " <no_action | sel_logging | power_off>" },
- { 0x01, "limit", " <number in Watts>" },
- { 0x02, "correction", "<number in milliseconds>" },
- { 0x03, "sample", " <number in seconds>" },
- { 0xFF, NULL, NULL }
- };
- /* power management/get action commands */
- const struct dcmi_cmd dcmi_pwrmgmt_get_action_vals[] = {
- { 0x00, "No Action", ""},
- { 0x01, "Hard Power Off & Log Event to SEL", ""},
- { 0x02, "OEM reserved (02h)", ""},
- { 0x03, "OEM reserved (03h)", ""},
- { 0x04, "OEM reserved (04h)", ""},
- { 0x05, "OEM reserved (05h)", ""},
- { 0x06, "OEM reserved (06h)", ""},
- { 0x07, "OEM reserved (07h)", ""},
- { 0x08, "OEM reserved (08h)", ""},
- { 0x09, "OEM reserved (09h)", ""},
- { 0x0a, "OEM reserved (0ah)", ""},
- { 0x0b, "OEM reserved (0bh)", ""},
- { 0x0c, "OEM reserved (0ch)", ""},
- { 0x0d, "OEM reserved (0dh)", ""},
- { 0x0e, "OEM reserved (0eh)", ""},
- { 0x0f, "OEM reserved (0fh)", ""},
- { 0x10, "OEM reserved (10h)", ""},
- { 0x11, "Log Event to SEL", ""},
- { 0xFF, NULL, NULL }
- };
- /* power management/set action commands */
- const struct dcmi_cmd dcmi_pwrmgmt_action_vals[] = {
- { 0x00, "no_action", "No Action"},
- { 0x01, "power_off", "Hard Power Off & Log Event to SEL"},
- { 0x11, "sel_logging", "Log Event to SEL"},
- { 0x02, "oem_02", "OEM reserved (02h)"},
- { 0x03, "oem_03", "OEM reserved (03h)"},
- { 0x04, "oem_04", "OEM reserved (04h)"},
- { 0x05, "oem_05", "OEM reserved (05h)"},
- { 0x06, "oem_06", "OEM reserved (06h)"},
- { 0x07, "oem_07", "OEM reserved (07h)"},
- { 0x08, "oem_08", "OEM reserved (08h)"},
- { 0x09, "oem_09", "OEM reserved (09h)"},
- { 0x0a, "oem_0a", "OEM reserved (0ah)"},
- { 0x0b, "oem_0b", "OEM reserved (0bh)"},
- { 0x0c, "oem_0c", "OEM reserved (0ch)"},
- { 0x0d, "oem_0d", "OEM reserved (0dh)"},
- { 0x0e, "oem_0e", "OEM reserved (0eh)"},
- { 0x0f, "oem_0f", "OEM reserved (0fh)"},
- { 0x10, "oem_10", "OEM reserved (10h)"},
- { 0xFF, NULL, NULL }
- };
- /* thermal policy action commands */
- const struct dcmi_cmd dcmi_thermalpolicy_vals[] = {
- { 0x00, "get", "Get thermal policy" },
- { 0x01, "set", "Set thermal policy" },
- { 0xFF, NULL, NULL }
- };
- /* thermal policy action commands */
- const struct dcmi_cmd dcmi_confparameters_vals[] = {
- { 0x00, "get", "Get configuration parameters" },
- { 0x01, "set", "Set configuration parameters" },
- { 0xFF, NULL, NULL }
- };
- /* entityIDs used in thermap policy */
- const struct dcmi_cmd dcmi_thermalpolicy_set_parameters_vals[] = {
- { 0x00, "volatile", " Current Power Cycle" },
- { 0x01, "nonvolatile", "Set across power cycles" },
- { 0x01, "poweroff", " Hard Power Off system" },
- { 0x00, "nopoweroff", " No 'Hard Power Off' action" },
- { 0x01, "sel", " Log event to SEL" },
- { 0x00, "nosel", " No 'Log event to SEL' action" },
- { 0x00, "disabled", " Disabled" },
- { 0x00, NULL, NULL }
- };
- /* DCMI command specific completion code results per 1.0 spec
- * 80h - parameter not supported.
- * 81h - attempt to set the ‘set in progress’ value (in parameter #0) when not
- * in the ‘set complete’ state. (This completion code provides a way to
- * recognize that another party has already ‘claimed’ the parameters)
- * 82h - attempt to write read-only parameter
- * 82h - set not supported on selected channel (e.g. channel is session-less.)
- * 83h - access mode not supported
- * 84h – Power Limit out of range
- * 85h – Correction Time out of range
- * 89h – Statistics Reporting Period out of range
- */
- const struct valstr dcmi_ccode_vals[] = {
- { 0x80, "Parameter not supported" },
- { 0x81, "Something else has already claimed these parameters" },
- { 0x82, "Not supported or failed to write a read-only parameter" },
- { 0x83, "Access mode is not supported" },
- { 0x84, "Power/Thermal limit out of range" },
- { 0x85, "Correction/Exception time out of range" },
- { 0x89, "Sample/Statistics Reporting period out of range" },
- { 0x8A, "Power limit already active" },
- { 0xFF, NULL }
- };
- /*
- * Start of Node Manager Operations
- */
- const struct dcmi_cmd dcmi_sampling_vals[] = {
- { 0x05, "5_sec", "" },
- { 0x0f, "15_sec", "" },
- { 0x1E, "30_sec", "" },
- { 0x41, "1_min", "" },
- { 0x43, "3_min", "" },
- { 0x47, "7_min", "" },
- { 0x4F, "15_min", "" },
- { 0x5E, "30_min", "" },
- { 0x81, "1_hour", ""},
- { 0x00, NULL, NULL },
- };
- /* Primary Node Manager commands */
- const struct dcmi_cmd nm_cmd_vals[] = {
- { 0x00, "discover", "Discover Node Manager " },
- { 0x01, "capability", "Get Node Manager Capabilities" },
- { 0x02, "control", "Enable/Disable Policy Control" },
- { 0x03, "policy", "Add/Remove Policies" },
- { 0x04, "statistics", "Get Statistics" },
- { 0x05, "power", "Set Power Draw Range" },
- { 0x06, "suspend", "Set/Get Policy suspend periods" },
- { 0x07, "reset", "Reset Statistics" },
- { 0x08, "alert", "Set/Get/Clear Alert destination" },
- { 0x09, "threshold", "Set/Get Alert Thresholds" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_ctl_cmds[] = {
- { 0x01, "enable", " <control scope>" },
- { 0x00, "disable", "<control scope>"},
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_ctl_domain[] = {
- { 0x00, "global", "" },
- { 0x02, "per_domain", "<platform|CPU|Memory> (default is platform)" },
- { 0x04, "per_policy", "<0-7>" },
- { 0xFF, NULL, NULL },
- };
- /* Node Manager Domain codes */
- const struct dcmi_cmd nm_domain_vals[] = {
- { 0x00, "platform", "" },
- { 0x01, "CPU", "" },
- { 0x02, "Memory", "" },
- { 0x03, "protection", "" },
- { 0x04, "I/O", "" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_version_vals[] = {
- { 0x01, "1.0", "" },
- { 0x02, "1.5", "" },
- { 0x03, "2.0", "" },
- { 0x04, "2.5", "" },
- { 0x05, "3.0", "" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_capability_opts[] = {
- { 0x01, "domain", "<platform|CPU|Memory> (default is platform)" },
- { 0x02, "inlet", "Inlet temp trigger" },
- { 0x03, "missing", "Missing Power reading trigger" },
- { 0x04, "reset", "Time after Host reset trigger" },
- { 0x05, "boot", "Boot time policy" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_policy_type_vals[] = {
- { 0x00, "No trigger, use Power Limit", "" },
- { 0x01, "Inlet temp trigger", "" },
- { 0x02, "Missing Power reading trigger", "" },
- { 0x03, "Time after Host reset trigger", "" },
- { 0x04, "number of cores to disable at boot time", "" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_stats_opts[] = {
- { 0x01, "domain", "<platform|CPU|Memory> (default is platform)" },
- { 0x02, "policy_id", "<0-7>" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_stats_mode[] = {
- { 0x01, "power", "global power" },
- { 0x02, "temps", "inlet temperature" },
- { 0x11, "policy_power", "per policy power" },
- { 0x12, "policy_temps", "per policy inlet temp" },
- { 0x13, "policy_throt", "per policy throttling stats" },
- { 0x1B, "requests", "unhandled requests" },
- { 0x1C, "response", "response time" },
- { 0x1D, "cpu_throttling", "CPU throttling" },
- { 0x1E, "mem_throttling", "memory throttling" },
- { 0x1F, "comm_fail", "host communication failures" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_policy_action[] = {
- { 0x00, "get", "nm policy get policy_id <0-7> [domain <platform|CPU|Memory>]" },
- { 0x04, "add", "nm policy add policy_id <0-7> [domain <platform|CPU|Memory>] correction auto|soft|hard power <watts>|inlet <temp> trig_lim <param> stats <seconds> enable|disable" },
- { 0x05, "remove", "nm policy remove policy_id <0-7> [domain <platform|CPU|Memory>]" },
- { 0x06, "limiting", "nm policy limiting [domain <platform|CPU|Memory>]" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_policy_options[] = {
- { 0x01, "enable", "" },
- { 0x02, "disable", "" },
- { 0x03, "domain", "" },
- { 0x04, "inlet", "inlet air temp full limiting (SCRAM)"},
- { 0x06, "correction", "auto, soft, hard" },
- { 0x08, "power", "power limit in watts" },
- { 0x09, "trig_lim", "time to send alert" },
- { 0x0A, "stats", "moving window averaging time" },
- { 0x0B, "policy_id", "policy number" },
- { 0x0C, "volatile", "save policy in volatiel memory" },
- { 0x0D, "cores_off", "at boot time, disable N cores" },
- { 0xFF, NULL, NULL },
- };
- /* if "trigger" command used from nm_policy_options */
- const struct dcmi_cmd nm_trigger[] = {
- { 0x00, "none", "" },
- { 0x01, "temp", "" },
- { 0x02, "reset", "" },
- { 0x03, "boot", "" },
- { 0xFF, NULL, NULL },
- };
- /* if "correction" used from nm_policy_options */
- const struct dcmi_cmd nm_correction[] = {
- { 0x00, "auto", "" },
- { 0x01, "soft", "" },
- { 0x02, "hard", "" },
- { 0xFF, NULL, NULL },
- };
- /* returned codes from get policy */
- const struct dcmi_cmd nm_correction_vals[] = {
- { 0x00, "no T-state use", "" },
- { 0x01, "no T-state use", "" },
- { 0x02, "use T-states", "" },
- { 0xFF, NULL, NULL },
- };
- /* if "exception" used from nm_policy_options */
- const struct dcmi_cmd nm_exception[] = {
- { 0x00, "none", "" },
- { 0x01, "alert", "" },
- { 0x02, "shutdown", "" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_reset_mode[] = {
- { 0x00, "global", "" },
- { 0x01, "per_policy", "" },
- { 0x1B, "requests", "" },
- { 0x1C, "response", "" },
- { 0x1D, "throttling", "" },
- { 0x1E, "memory", "", },
- { 0x1F, "comm", "" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_power_range[] = {
- { 0x01, "domain", "domain <platform|CPU|Memory> (default is platform)" },
- { 0x02, "min", " min <integer value>" },
- { 0x03, "max", "max <integer value>" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_alert_opts[] = {
- { 0x01, "set", "nm alert set chan <chan> dest <dest> string <string>" },
- { 0x02, "get", "nm alert get" },
- { 0x03, "clear", "nm alert clear dest <dest>" },
- };
- const struct dcmi_cmd nm_set_alert_param[] = {
- { 0x01, "chan", "chan <channel>" },
- { 0x02, "dest", "dest <destination>" },
- { 0x03, "string", "string <string>" },
- };
- const struct dcmi_cmd nm_thresh_cmds[] = {
- { 0x01, "set", "nm thresh set [domain <platform|CPU|Memory>] policy_id <policy> thresh_array" },
- { 0x02, "get", "nm thresh get [domain <platform|CPU|Memory>] policy_id <policy>" },
- };
- const struct dcmi_cmd nm_thresh_param[] = {
- { 0x01, "domain", "<platform|CPU|Memory> (default is platform)" },
- { 0x02, "policy_id", "<0-7>" },
- { 0xFF, NULL, NULL },
- };
- const struct dcmi_cmd nm_suspend_cmds[] = {
- { 0x01, "set", "nm suspend set [domain <platform|CPU|Memory]> policy_id <policy> <start> <stop> <pattern>" },
- { 0x02, "get", "nm suspend get [domain <platform|CPU|Memory]> policy_id <policy>" },
- };
- const struct valstr nm_ccode_vals[] = {
- { 0x80, "Policy ID Invalid"},
- { 0x81, "Domain ID Invalid"},
- { 0x82, "Unknown policy trigger type"},
- { 0x84, "Power Limit out of range"},
- { 0x85, "Correction Time out of range"},
- { 0x86, "Policy Trigger value out of range"},
- { 0x88, "Invalid Mode"},
- { 0x89, "Statistics Reporting Period out of range"},
- { 0x8B, "Invalid value for Aggressive CPU correction field"},
- { 0xA1, "No policy is currently limiting for the specified domain ID"},
- { 0xC4, "No space available"},
- { 0xD4, "Insufficient privledge level due wrong responder LUN"},
- { 0xD5, "Policy exists and param unchangeable while enabled"},
- { 0xD6, "Command subfunction disabled or unavailable"},
- { 0xFF, NULL },
- };
- /* End strings */
- /* This was taken from print_valstr() from helper.c. It serves the same
- * purpose but with out the extra formatting. This function simply prints
- * the dcmi_cmd struct provided. verthorz specifies to print vertically or
- * horizontally. If the string is printed horizontally then a | will be
- * printed between each instance of vs[i].str until it is NULL
- *
- * @vs: value string list to print
- * @title: name of this value string list
- * @loglevel: what log level to print, -1 for stdout
- * @verthorz: printed vertically or horizontally, 0 or 1
- */
- void
- print_strs(const struct dcmi_cmd * vs, const char * title, int loglevel,
- int verthorz)
- {
- int i;
- if (vs == NULL)
- return;
- if (title != NULL) {
- if (loglevel < 0)
- printf("\n%s\n", title);
- else
- lprintf(loglevel, "\n%s", title);
- }
- for (i = 0; vs[i].str != NULL; i++) {
- if (loglevel < 0) {
- if (vs[i].val < 256)
- if (verthorz == 0)
- printf(" %s %s\n", vs[i].str, vs[i].desc);
- else
- printf("%s", vs[i].str);
- else if (verthorz == 0)
- printf(" %s %s\n", vs[i].str, vs[i].desc);
- else
- printf("%s", vs[i].str);
- } else {
- if (vs[i].val < 256)
- lprintf(loglevel, " %s %s", vs[i].str, vs[i].desc);
- else
- lprintf(loglevel, " %s %s", vs[i].str, vs[i].desc);
- }
- /* Check to see if this is NOT the last element in vs.str if true
- * print the | else don't print anything.
- */
- if ((verthorz == 1) && (vs[i+1].str != NULL))
- printf(" | ");
- }
- if (verthorz == 0) {
- if (loglevel < 0) {
- printf("\n");
- } else {
- lprintf(loglevel, "");
- }
- }
- }
- /* This was taken from str2val() from helper.c. It serves the same
- * purpose but with the addition of a desc field from the structure.
- * This function converts the str from the dcmi_cmd struct provided to the
- * value associated to the compared string in the struct.
- *
- * @str: string to compare against
- * @vs: dcmi_cmd structure
- */
- uint16_t
- str2val2(const char *str, const struct dcmi_cmd *vs)
- {
- int i;
- if (vs == NULL || str == NULL) {
- return 0;
- }
- for (i = 0; vs[i].str != NULL; i++) {
- if (strncasecmp(vs[i].str, str,
- __maxlen(str, vs[i].str)) == 0) {
- return vs[i].val;
- }
- }
- return vs[i].val;
- }
- /* This was taken from val2str() from helper.c. It serves the same
- * purpose but with the addition of a desc field from the structure.
- * This function converts the val and returns a string from the dcmi_cmd
- * struct provided in the struct.
- *
- * @val: value to compare against
- * @vs: dcmi_cmd structure
- */
- const char *
- val2str2(uint16_t val, const struct dcmi_cmd *vs)
- {
- static char un_str[32];
- int i;
- if (vs == NULL)
- return NULL;
- for (i = 0; vs[i].str != NULL; i++) {
- if (vs[i].val == val)
- return vs[i].str;
- }
- memset(un_str, 0, sizeof (un_str));
- snprintf(un_str, 32, "Unknown (0x%x)", val);
- return un_str;
- }
- /* check the DCMI response from the BMC
- * @rsp: Response data structure
- */
- static int
- chk_rsp(struct ipmi_rs * rsp)
- {
- /* if the response from the intf is NULL then the BMC is experiencing
- * some issue and cannot complete the command
- */
- if (rsp == NULL) {
- lprintf(LOG_ERR, "\n Unable to get DCMI information");
- return 1;
- }
- /* if the completion code is greater than zero there was an error. We'll
- * use val2str from helper.c to print the error from either the DCMI
- * completion code struct or the generic IPMI completion_code_vals struct
- */
- if ((rsp->ccode >= 0x80) && (rsp->ccode <= 0x8F)) {
- lprintf(LOG_ERR, "\n DCMI request failed because: %s (%x)",
- val2str(rsp->ccode, dcmi_ccode_vals), rsp->ccode);
- return 1;
- } else if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "\n DCMI request failed because: %s (%x)",
- val2str(rsp->ccode, completion_code_vals), rsp->ccode);
- return 1;
- }
- /* check to make sure this is a DCMI firmware */
- if(rsp->data[0] != IPMI_DCMI) {
- printf("\n A valid DCMI command was not returned! (%x)", rsp->data[0]);
- return 1;
- }
- return 0;
- }
- /* check the Node Manager response from the BMC
- * @rsp: Response data structure
- */
- static int
- chk_nm_rsp(struct ipmi_rs * rsp)
- {
- /* if the response from the intf is NULL then the BMC is experiencing
- * some issue and cannot complete the command
- */
- if (rsp == NULL) {
- lprintf(LOG_ERR, "\n No response to NM request");
- return 1;
- }
- /* if the completion code is greater than zero there was an error. We'll
- * use val2str from helper.c to print the error from either the DCMI
- * completion code struct or the generic IPMI completion_code_vals struct
- */
- if ((rsp->ccode >= 0x80) && (rsp->ccode <= 0xD6)) {
- lprintf(LOG_ERR, "\n NM request failed because: %s (%x)",
- val2str(rsp->ccode, nm_ccode_vals), rsp->ccode);
- return 1;
- } else if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "\n NM request failed because: %s (%x)",
- val2str(rsp->ccode, completion_code_vals), rsp->ccode);
- return 1;
- }
- /* check to make sure this is a DCMI firmware */
- if(rsp->data[0] != 0x57) {
- printf("\n A valid NM command was not returned! (%x)", rsp->data[0]);
- return 1;
- }
- return 0;
- }
- /* Get capabilities ipmi response
- *
- * This function returns the available capabilities of the platform.
- * The reason it returns in the rsp struct is so that it can be used for other
- * purposes.
- *
- * returns ipmi response structure
- *
- * @intf: ipmi interface handler
- * @selector: Parameter selector
- */
- struct ipmi_rs *
- ipmi_dcmi_getcapabilities(struct ipmi_intf * intf, uint8_t selector)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- uint8_t msg_data[2]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = selector;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP; /* 0x2C per 1.0 spec */
- req.msg.cmd = IPMI_DCMI_COMPAT; /* 0x01 per 1.0 spec */
- req.msg.data = msg_data; /* 0xDC 0x01 or the msg_data above */
- req.msg.data_len = 2; /* How many times does req.msg.data need to read */
- return intf->sendrecv(intf, &req);
- }
- /* end capabilities struct */
- /* Displays capabilities from structure
- * returns void
- *
- * @cmd: dcmi_cmd structure
- * @data_val: holds value of what to display
- */
- void
- display_capabilities_attributes(const struct dcmi_cmd *cmd, uint8_t data_val)
- {
- uint8_t i;
- for (i = 0x01; cmd[i-1].val != 0xFF; i++) {
- if (data_val & (1<<(i-1))) {
- printf(" %s\n", val2str2(i, cmd));
- }
- }
- }
- static int
- ipmi_dcmi_prnt_oobDiscover(struct ipmi_intf * intf)
- {
- # ifndef IPMI_INTF_LANPLUS
- lprintf(LOG_ERR,
- "DCMI Discovery is available only when LANplus(IPMI v2.0) is enabled.");
- return (-1);
- # else
- struct ipmi_session_params *p;
- if (intf->opened == 0 && intf->open != NULL) {
- if (intf->open(intf) < 0)
- return (-1);
- }
- if (intf == NULL || intf->session == NULL)
- return -1;
- p = &intf->ssn_params;
- if (p->port == 0)
- p->port = IPMI_LAN_PORT;
- if (p->privlvl == 0)
- p->privlvl = IPMI_SESSION_PRIV_ADMIN;
- if (p->timeout == 0)
- p->timeout = IPMI_LAN_TIMEOUT;
- if (p->retry == 0)
- p->retry = IPMI_LAN_RETRY;
- if (p->hostname == NULL || strlen((const char *)p->hostname) == 0) {
- lprintf(LOG_ERR, "No hostname specified!");
- return -1;
- }
- intf->abort = 1;
- intf->session->sol_data.sequence_number = 1;
- if (ipmi_intf_socket_connect (intf) == -1) {
- lprintf(LOG_ERR, "Could not open socket!");
- return -1;
- }
- if (intf->fd < 0) {
- lperror(LOG_ERR, "Connect to %s failed",
- p->hostname);
- intf->close(intf);
- return -1;
- }
- intf->opened = 1;
- /* Lets ping/pong */
- return ipmiv2_lan_ping(intf);
- # endif
- }
- /* This is the get DCMI Capabilities function to see what the BMC supports.
- *
- * returns 0 with out error -1 with any errors
- *
- * @intf: ipmi interface handler
- * @selector: selection parameter
- */
- static int
- ipmi_dcmi_prnt_getcapabilities(struct ipmi_intf * intf, uint8_t selector)
- {
- struct capabilities cape;
- struct ipmi_rs * rsp;
- uint8_t reply[16];
- rsp = ipmi_dcmi_getcapabilities(intf, selector);
- int j;
- if(chk_rsp(rsp))
- return -1;
- /* if there were no errors, the command worked! */
- memcpy(&cape, rsp->data, sizeof (cape));
- memcpy(&reply, rsp->data, sizeof (reply));
- /* check to make sure that this is a 1.0/1.1/1.5 command */
- if ((cape.conformance != IPMI_DCMI_CONFORM)
- && (cape.conformance != IPMI_DCMI_1_1_CONFORM)
- && (cape.conformance != IPMI_DCMI_1_5_CONFORM)) {
- lprintf(LOG_ERR,
- "ERROR! This command is not available on this platform");
- return -1;
- }
- /* check to make sure that this is a rev .01 or .02 */
- if (cape.revision != 0x01 && cape.revision != 0x02) {
- lprintf(LOG_ERR,
- "ERROR! This command is not compatible with this version");
- return -1;
- }
- /* 0x01 - platform capabilities
- * 0x02 - Manageability Access Capabilities
- * 0x03 - SEL Capability
- * 0x04 - Identification Capability
- * 0x05 - LAN Out-Of-Band Capability
- * 0x06 - Serial Out-Of-Band TMODE Capability
- */
- switch (selector) {
- case 0x01:
- printf(" Supported DCMI capabilities:\n");
- /* loop through each of the entries in the first byte from the
- * struct
- */
- printf("\n Mandatory platform capabilties\n");
- display_capabilities_attributes(
- dcmi_mandatory_platform_capabilities, cape.data_byte1);
- /* loop through each of the entries in the second byte from the
- * struct
- */
- printf("\n Optional platform capabilties\n");
- display_capabilities_attributes(
- dcmi_optional_platform_capabilities, cape.data_byte2);
- /* loop through each of the entries in the third byte from the
- * struct
- */
- printf("\n Managebility access capabilties\n");
- display_capabilities_attributes(
- dcmi_management_access_capabilities, cape.data_byte3);
- break;
- case 0x02:
- printf("\n Mandatory platform attributes:\n");
- /* byte 1 & 2 data */
- printf("\n SEL Attributes: ");
- printf("\n SEL automatic rollover is ");
- /* mask the 2nd byte of the data response with 10000000b or 0x80
- * because of the endian-ness the 15th bit is in the second byte
- */
- if ((cape.data_byte2 & 0x80))
- printf("enabled");
- else
- printf("not present");
- /* since the number of SEL entries is split across the two data
- * bytes we will need to bit shift and append them together again
- */
- /* cast cape.data_byte1 as 16 bits */
- uint16_t sel_entries = (uint16_t)cape.data_byte1;
- /* or sel_entries with byte 2 and shift it 8 places */
- sel_entries |= (uint16_t)cape.data_byte2 << 8;
- printf("\n %d SEL entries\n", sel_entries & 0xFFF);
- /* byte 3 data */
- printf("\n Identification Attributes: \n");
- display_capabilities_attributes(
- dcmi_id_capabilities_vals, cape.data_byte3);
- /* byte 4 data */
- printf("\n Temperature Monitoring Attributes: \n");
- display_capabilities_attributes(dcmi_temp_monitoring_vals,
- cape.data_byte4);
- break;
- case 0x03:
- printf("\n Optional Platform Attributes: \n");
- /* Power Management */
- printf("\n Power Management:\n");
- if (cape.data_byte1 == 0x40) {
- printf(" Slave address of device: 20h (BMC)\n" );
- } else {
- printf(" Slave address of device: %xh (8bits)"
- "(Satellite/External controller)\n",
- cape.data_byte1);
- }
- /* Controller channel number (4-7) bits */
- if ((cape.data_byte2>>4) == 0x00) {
- printf(" Channel number is 0h (Primary BMC)\n");
- } else {
- printf(" Channel number is %xh \n",
- (cape.data_byte2>>4));
- }
- /* Device revision (0-3) */
- printf(" Device revision is %d \n",
- cape.data_byte2 &0xf);
- break;
- case 0x04:
- /* LAN */
- printf("\n Manageability Access Attributes: \n");
- if (cape.data_byte1 == 0xFF) {
- printf(" Primary LAN channel is not available for OOB\n");
- } else {
- printf(" Primary LAN channel number: %d is available\n",
- cape.data_byte1);
- }
- if (cape.data_byte2 == 0xFF) {
- printf(" Secondary LAN channel is not available for OOB\n");
- } else {
- printf(" Secondary LAN channel number: %d is available\n",
- cape.data_byte2);
- }
- /* serial */
- if (cape.data_byte3 == 0xFF) {
- printf(" No serial channel is available\n");
- } else {
- printf(" Serial channel number: %d is available\n",
- cape.data_byte3);
- }
- break;
- case 0x05:
- /* Node Manager */
- printf("\n Node Manager Get DCMI Capability Info: \n");
- printf(" DCMI Specification %d.%d\n", reply[1], reply[2]);
- printf(" Rolling average time period options: %d\n", reply[4]);
- printf(" Sample time options: ");
- for (j = 1; dcmi_sampling_vals[j-1].str != NULL; j++)
- printf(" %s ", val2str2(reply[4+j],dcmi_sampling_vals));
- printf("\n");
- break;
- default:
- return -1;
- }
- return 0;
- /* return intf->sendrecv(intf, &req); */
- }
- /* This is the get asset tag command. This checks the length of the asset tag
- * with the first read, then reads n number of bytes thereafter to get the
- * complete asset tag.
- *
- * @intf: ipmi interface handler
- * @offset: where to start reading the asset tag
- * @length: how much to read
- *
- * returns ipmi_rs structure
- */
- struct ipmi_rs *
- ipmi_dcmi_getassettag(struct ipmi_intf * intf, uint8_t offset, uint8_t length)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- uint8_t msg_data[3]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = offset; /* offset 0 */
- msg_data[2] = length; /* read one byte */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP; /* 0x2C per 1.1 spec */
- req.msg.cmd = IPMI_DCMI_GETASSET; /* 0x01 per 1.1 spec */
- req.msg.data = msg_data; /* msg_data above */
- req.msg.data_len = 3; /* How many times does req.msg.data need to read */
- return intf->sendrecv(intf, &req);
- }
- /* This is the get asset tag command. The function first checks to see if the
- * platform is capable of getting the asset tag by calling the getcapabilities
- * function and checking the response. Then it checks the length of the asset
- * tag with the first read, then x number of reads thereafter to get the asset
- * complete asset tag then print it.
- *
- * @intf: ipmi interface handler
- *
- * returns 0 if no failure, -1 with a failure
- */
- static int
- ipmi_dcmi_prnt_getassettag(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp; /* ipmi response */
- uint8_t taglength = 0;
- uint8_t getlength = 0;
- uint8_t offset = 0;
- uint8_t i;
- /* now let's get the asset tag length */
- rsp = ipmi_dcmi_getassettag(intf, 0, 0);
- if (chk_rsp(rsp)) {
- return -1;
- }
- taglength = rsp->data[1];
- printf("\n Asset tag: ");
- while (taglength) {
- getlength = taglength / DCMI_MAX_BYTE_SIZE ?
- DCMI_MAX_BYTE_SIZE : taglength%DCMI_MAX_BYTE_SIZE;
- rsp = ipmi_dcmi_getassettag(intf, offset, getlength);
- /* macro has no effect here where can generate sig segv
- * if rsp occurs with null
- */
- if (rsp != NULL) {
- GOOD_ASSET_TAG_CCODE(rsp->ccode);
- }
- if (chk_rsp(rsp)) {
- return -1;
- }
- for (i=0; i<getlength; i++) {
- printf("%c", rsp->data[i+2]);
- }
- offset += getlength;
- taglength -= getlength;
- }
- printf("\n");
- return 0;
- }
- /* This is the set asset tag command. This checks the length of the asset tag
- * with the first read, then reads n number of bytes thereafter to set the
- * complete asset tag.
- *
- * @intf: ipmi interface handler
- * @offset: offset to write
- * @length: number of bytes to write (16 bytes maximum)
- * @data: data to write
- *
- * returns ipmi_rs structure
- */
- struct ipmi_rs *
- ipmi_dcmi_setassettag(struct ipmi_intf * intf, uint8_t offset, uint8_t length,
- uint8_t *data)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- uint8_t msg_data[3+length]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = offset; /* offset 0 */
- msg_data[2] = length; /* read one byte */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP; /* 0x2C per 1.1 spec */
- req.msg.cmd = IPMI_DCMI_SETASSET; /* 0x08 per 1.1 spec */
- req.msg.data = msg_data; /* msg_data above */
- /* How many times does req.msg.data need to read */
- req.msg.data_len = length + 3;
- memcpy(req.msg.data + 3, data, length);
- return intf->sendrecv(intf, &req);
- }
- static int
- ipmi_dcmi_prnt_setassettag(struct ipmi_intf * intf, uint8_t * data)
- {
- struct ipmi_rs * rsp; /* ipmi response */
- uint8_t tmpData[DCMI_MAX_BYTE_SIZE];
- int32_t taglength = 0;
- uint8_t getlength = 0;
- uint8_t offset = 0;
- uint8_t i;
- /* now let's get the asset tag length */
- taglength = strlen((char *)data);
- if (taglength > 64){
- lprintf(LOG_ERR, "\nValue is too long.");
- return -1;
- }
- printf("\n Set Asset Tag: ");
- while (taglength) {
- getlength = taglength / DCMI_MAX_BYTE_SIZE ?
- DCMI_MAX_BYTE_SIZE : taglength%DCMI_MAX_BYTE_SIZE;
- memcpy(tmpData, data + offset, getlength);
- rsp = ipmi_dcmi_setassettag(intf, offset, getlength, tmpData);
- if (chk_rsp(rsp)) {
- return -1;
- }
- for (i=0; i<getlength; i++) {
- printf("%c", tmpData[i]);
- }
- offset += getlength;
- taglength -= getlength;
- }
- printf("\n");
- return 0;
- }
- /* Management Controller Identifier String is provided in order to accommodate
- * the requirement for the management controllers to identify themselves.
- *
- * @intf: ipmi interface handler
- * @offset: offset to read
- * @length: number of bytes to read (16 bytes maximum)
- *
- * returns ipmi_rs structure
- */
- struct ipmi_rs *
- ipmi_dcmi_getmngctrlids(struct ipmi_intf * intf, uint8_t offset, uint8_t length)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- uint8_t msg_data[3]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = offset; /* offset 0 */
- msg_data[2] = length; /* read one byte */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP; /* 0x2C per 1.1 spec */
- req.msg.cmd = IPMI_DCMI_GETMNGCTRLIDS; /* 0x09 per 1.1 spec */
- req.msg.data = msg_data; /* msg_data above */
- /* How many times does req.msg.data need to read */
- req.msg.data_len = 3;
- return intf->sendrecv(intf, &req);
- }
- static int
- ipmi_dcmi_prnt_getmngctrlids(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp; /* ipmi response */
- uint8_t taglength = 0;
- uint8_t getlength = 0;
- uint8_t offset = 0;
- uint8_t i;
- /* now let's get the asset tag length */
- rsp = ipmi_dcmi_getmngctrlids(intf, 0, 1);
- if (chk_rsp(rsp)) {
- return -1;
- }
- taglength = rsp->data[1];
- printf("\n Get Management Controller Identifier String: ");
- while (taglength) {
- getlength = taglength / DCMI_MAX_BYTE_SIZE ?
- DCMI_MAX_BYTE_SIZE : taglength%DCMI_MAX_BYTE_SIZE;
- rsp = ipmi_dcmi_getmngctrlids(intf, offset, getlength);
- if (chk_rsp(rsp)) {
- return -1;
- }
- for (i=0; i<getlength; i++) {
- printf("%c", rsp->data[i+2]);
- }
- offset += getlength;
- taglength -= getlength;
- }
- printf("\n");
- return 0;
- }
- /* Management Controller Identifier String is provided in order to accommodate
- * the requirement for the management controllers to identify themselves.
- *
- * @intf: ipmi interface handler
- * @offset: offset to write
- * @length: number of bytes to write (16 bytes maximum)
- * @data: data to write
- *
- * returns ipmi_rs structure
- */
- struct ipmi_rs *
- ipmi_dcmi_setmngctrlids(struct ipmi_intf * intf, uint8_t offset, uint8_t length,
- uint8_t *data)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- uint8_t msg_data[3+length]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = offset; /* offset 0 */
- msg_data[2] = length; /* read one byte */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP; /* 0x2C per 1.1 spec */
- req.msg.cmd = IPMI_DCMI_SETMNGCTRLIDS; /* 0x0A per 1.1 spec */
- req.msg.data = msg_data; /* msg_data above */
- /* How many times does req.msg.data need to read */
- req.msg.data_len = 3 + length;
- memcpy(req.msg.data + 3, data, length);
- return intf->sendrecv(intf, &req);
- }
- /* Set Asset Tag command provides ability for the management console to set the
- * asset tag as appropriate. Management controller is not responsible for the
- * data format used for the Asset Tag once modified by IPDC.
- *
- * @intf: ipmi interface handler
- *
- * returns 0 if no failure, -1 with a failure
- */
- static int
- ipmi_dcmi_prnt_setmngctrlids(struct ipmi_intf * intf, uint8_t * data)
- {
- struct ipmi_rs * rsp; /* ipmi response */
- uint8_t tmpData[DCMI_MAX_BYTE_SIZE];
- uint8_t taglength = 0;
- uint8_t getlength = 0;
- uint8_t offset = 0;
- uint8_t i;
- data += '\0';
- taglength = strlen((char *)data) +1;
- if (taglength > 64) {
- lprintf(LOG_ERR, "\nValue is too long.");
- return -1;
- }
- printf("\n Set Management Controller Identifier String Command: ");
- while (taglength) {
- getlength = taglength / DCMI_MAX_BYTE_SIZE ?
- DCMI_MAX_BYTE_SIZE : taglength%DCMI_MAX_BYTE_SIZE;
- memcpy(tmpData, data + offset, getlength);
- rsp = ipmi_dcmi_setmngctrlids(intf, offset, getlength, tmpData);
- /* because after call "Set mc id string" RMCP+ will go down
- * we have no "rsp"
- */
- if (strncmp(intf->name, "lanplus", 7)) {
- if (chk_rsp(rsp)) {
- return -1;
- }
- }
- for (i=0; i<getlength; i++) {
- printf("%c", tmpData[i]);
- }
- offset += getlength;
- taglength -= getlength;
- }
- printf("\n");
- return 0;
- }
- /* Issues a discovery command to see what sensors are available on the target.
- * system.
- *
- * @intf: ipmi interface handler
- * @isnsr: entity ID
- * @offset: offset (Entity instace start)
- *
- * returns ipmi_rs structure
- */
- struct ipmi_rs *
- ipmi_dcmi_discvry_snsr(struct ipmi_intf * intf, uint8_t isnsr, uint8_t offset)
- {
- struct ipmi_rq req; /* ipmi request struct */
- uint8_t msg_data[5]; /* number of request data bytes */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = 0x01; /* Senser Type = Temp (01h) */
- msg_data[2] = isnsr; /* Sensor Number */
- msg_data[3] = 0x00; /* Entity Instance, set to read all instances */
- msg_data[4] = offset; /* Entity instace start */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- req.msg.cmd = IPMI_DCMI_GETSNSR;
- req.msg.data = msg_data; /* Contents above */
- req.msg.data_len = 5; /* how many times does req.msg.data need to read */
- return intf->sendrecv(intf, &req);
- }
- /* DCMI sensor discovery
- * Uses the dcmi_discvry_snsr_vals struct to print its string and
- * uses the numeric values to request the sensor sdr record id.
- *
- * @intf: ipmi interface handler
- * @isnsr: entity ID
- * @ient: sensor entity id
- */
- static int
- ipmi_dcmi_prnt_discvry_snsr(struct ipmi_intf * intf, uint8_t isnsr)
- {
- int i = 0;
- struct ipmi_rs * rsp; /* ipmi response */
- uint8_t records = 0;
- int8_t instances = 0;
- uint8_t offset = 0;
- uint16_t record_id = 0;
- uint8_t id_buff[16]; /* enough for 8 record IDs */
- rsp = ipmi_dcmi_discvry_snsr(intf, isnsr, 0);
- if (chk_rsp(rsp)) {
- return -1;
- }
- instances = rsp->data[1];
- printf("\n%s: %d temperature sensor%s found:\n",
- val2str2(isnsr, dcmi_discvry_snsr_vals),
- instances,
- (instances > 1) ? "s" : "");
- while(instances > 0) {
- ipmi_dcmi_discvry_snsr(intf, isnsr, offset);
- if (chk_rsp(rsp)) {
- return -1;
- }
- records = rsp->data[2];
- /* cache the data since it may be destroyed by subsequent
- * ipmi_xxx calls
- */
- memcpy(id_buff, &rsp->data[3], sizeof (id_buff));
- for (i=0; i<records; i++) {
- /* Record ID is in little endian format */
- record_id = (id_buff[2*i + 1] << 8) + id_buff[2*i];
- printf("Record ID 0x%04x: ", record_id);
- ipmi_print_sensor_info(intf, record_id);
- }
- offset += 8;
- instances -= records;
- }
- return 0;
- }
- /* end sensor discovery */
- /* Power Management get power reading
- *
- * @intf: ipmi interface handler
- */
- static int
- ipmi_dcmi_pwr_rd(struct ipmi_intf * intf, uint8_t sample_time)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- struct power_reading val;
- struct tm tm_t;
- time_t t;
- uint8_t msg_data[4]; /* number of request data bytes */
- memset(&tm_t, 0, sizeof(tm_t));
- memset(&t, 0, sizeof(t));
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- if (sample_time) {
- msg_data[1] = 0x02; /* Enhanced Power Statistics */
- msg_data[2] = sample_time;
- } else {
- msg_data[1] = 0x01; /* Mode Power Status */
- msg_data[2] = 0x00; /* reserved */
- }
- msg_data[3] = 0x00; /* reserved */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- req.msg.cmd = IPMI_DCMI_GETRED; /* Get power reading */
- req.msg.data = msg_data; /* msg_data above */
- req.msg.data_len = 4; /* how many times does req.msg.data need to read */
- rsp = intf->sendrecv(intf, &req);
- if (chk_rsp(rsp)) {
- return -1;
- }
- /* rsp->data[0] is equal to response data byte 2 in spec */
- /* printf("Group Extension Identification: %02x\n", rsp->data[0]); */
- memcpy(&val, rsp->data, sizeof (val));
- t = val.time_stamp;
- gmtime_r(&t, &tm_t);
- printf("\n");
- printf(" Instantaneous power reading: %8d Watts\n",
- val.curr_pwr);
- printf(" Minimum during sampling period: %8d Watts\n",
- val.min_sample);
- printf(" Maximum during sampling period: %8d Watts\n",
- val.max_sample);
- printf(" Average power reading over sample period: %8d Watts\n",
- val.avg_pwr);
- printf(" IPMI timestamp: %s",
- asctime(&tm_t));
- printf(" Sampling period: ");
- if (sample_time)
- printf("%s \n", val2str2(val.sample,dcmi_sampling_vals));
- else
- printf("%08u Seconds.\n", val.sample/1000);
- printf(" Power reading state is: ");
- /* mask the rsp->data so that we only care about bit 6 */
- if((val.state & 0x40) == 0x40) {
- printf("activated");
- } else {
- printf("deactivated");
- }
- printf("\n\n");
- return 0;
- }
- /* end Power Management get reading */
- /* This is the get thermalpolicy command.
- *
- * @intf: ipmi interface handler
- */
- int
- ipmi_dcmi_getthermalpolicy(struct ipmi_intf * intf, uint8_t entityID,
- uint8_t entityInstance)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- struct thermal_limit val;
- uint8_t msg_data[3]; /* number of request data bytes */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = entityID; /* Inlet Temperature DCMI ID*/
- msg_data[2] = entityInstance; /* Entity Instance */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- req.msg.cmd = IPMI_DCMI_GETTERMALLIMIT; /* Get thermal policy reading */
- req.msg.data = msg_data; /* msg_data above */
- req.msg.data_len = 3; /* how many times does req.msg.data need to read */
- rsp = intf->sendrecv(intf, &req);
- if (chk_rsp(rsp)) {
- return -1;
- }
- /* rsp->data[0] is equal to response data byte 2 in spec */
- memcpy(&val, rsp->data, sizeof (val));
- printf("\n");
- printf(" Persistence flag is: %s\n",
- ((val.exceptionActions & 0x80) ? "set" : "notset"));
- printf(" Exception Actions, taken if the Temperature Limit exceeded:\n");
- printf(" Hard Power Off system and log event: %s\n",
- ((val.exceptionActions & 0x40) ? "active":"inactive"));
- printf(" Log event to SEL only: %s\n",
- ((val.exceptionActions & 0x20) ? "active":"inactive"));
- printf(" Temperature Limit %d degrees\n",
- val.tempLimit);
- printf(" Exception Time %d seconds\n",
- val.exceptionTime);
- printf("\n\n");
- return 0;
- }
- /* This is the set thermalpolicy command.
- *
- * @intf: ipmi interface handler
- */
- int
- ipmi_dcmi_setthermalpolicy(struct ipmi_intf * intf,
- uint8_t entityID,
- uint8_t entityInst,
- uint8_t persistanceFlag,
- uint8_t actionHardPowerOff,
- uint8_t actionLogToSEL,
- uint8_t tempLimit,
- uint8_t samplingTimeLSB,
- uint8_t samplingTimeMSB)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- uint8_t msg_data[7]; /* number of request data bytes */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = entityID; /* Inlet Temperature DCMI ID*/
- msg_data[2] = entityInst; /* Entity Instance */
- /* persistance and actions or disabled if no actions */
- msg_data[3] = (((persistanceFlag ? 1 : 0) << 7) |
- ((actionHardPowerOff? 1 : 0) << 6) |
- ((actionLogToSEL ? 1 : 0) << 5));
- msg_data[4] = tempLimit;
- msg_data[5] = samplingTimeLSB;
- msg_data[6] = samplingTimeMSB;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- /* Get thermal policy reading */
- req.msg.cmd = IPMI_DCMI_SETTERMALLIMIT;
- req.msg.data = msg_data; /* msg_data above */
- /* how many times does req.msg.data need to read */
- req.msg.data_len = 7;
- rsp = intf->sendrecv(intf, &req);
- if (chk_rsp(rsp)) {
- return -1;
- }
- /* rsp->data[0] is equal to response data byte 2 in spec */
- printf("\nThermal policy %d for %0Xh entity successfully set.\n\n",
- entityInst, entityID);
- return 0;
- }
- /* This is Get Temperature Readings Command
- *
- * returns ipmi response structure
- *
- * @intf: ipmi interface handler
- */
- struct ipmi_rs *
- ipmi_dcmi_get_temp_readings(struct ipmi_intf * intf,
- uint8_t entityID,
- uint8_t entityInst,
- uint8_t entityInstStart)
- {
- struct ipmi_rq req;
- uint8_t msg_data[5]; /* number of request data bytes */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = 0x01; /* Sensor type */
- msg_data[2] = entityID; /* Entity Instance */
- msg_data[3] = entityInst;
- msg_data[4] = entityInstStart;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- req.msg.cmd = IPMI_DCMI_GETTEMPRED; /* Get thermal policy reading */
- req.msg.data = msg_data; /* msg_data above */
- /* how many times does req.msg.data need to read */
- req.msg.data_len = 5;
- return intf->sendrecv(intf, &req);
- }
- static int
- ipmi_dcmi_prnt_get_temp_readings(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp;
- int i,j, tota_inst, get_inst, offset = 0;
- /* Print sensor description */
- printf("\n\tEntity ID\t\t\tEntity Instance\t Temp. Readings");
- for (i = 0; dcmi_temp_read_vals[i].str != NULL; i++) {
- /* get all of the information about this sensor */
- rsp = ipmi_dcmi_get_temp_readings(intf,
- dcmi_temp_read_vals[i].val, 0, 0);
- if (chk_rsp(rsp)) {
- continue;
- }
- /* Total number of available instances for the Entity ID */
- offset = 0;
- tota_inst = rsp->data[1];
- while (tota_inst > 0) {
- get_inst = ((tota_inst / DCMI_MAX_BYTE_TEMP_READ_SIZE) ?
- DCMI_MAX_BYTE_TEMP_READ_SIZE :
- (tota_inst % DCMI_MAX_BYTE_TEMP_READ_SIZE));
- rsp = ipmi_dcmi_get_temp_readings(intf,
- dcmi_temp_read_vals[i].val, offset, 0);
- if (chk_rsp(rsp)) {
- continue;
- }
- /* Number of sets of Temperature Data in this
- * response (Max 8 per response)
- */
- for (j=0; j < rsp->data[2]*2; j=j+2) {
- /* Print Instance temperature info */
- printf("\n%s",dcmi_temp_read_vals[i].desc);
- printf("\t\t%i\t\t%c%i C", rsp->data[j+4],
- ((rsp->data[j+3]) >> 7) ?
- '-' : '+', (rsp->data[j+3] & 127));
- }
- offset += get_inst;
- tota_inst -= get_inst;
- }
- }
- return 0;
- }
- /* This is Get DCMI Config Parameters Command
- *
- * returns ipmi response structure
- *
- * @intf: ipmi interface handler
- */
- struct ipmi_rs *
- ipmi_dcmi_getconfparam(struct ipmi_intf * intf, int param_selector)
- {
- struct ipmi_rq req;
- uint8_t msg_data[3]; /* number of request data bytes */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = param_selector; /* Parameter selector */
- /* Set Selector. Selects a given set of parameters under a given Parameter
- * selector value. 00h if parameter doesn't use a Set Selector.
- */
- msg_data[2] = 0x00;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- req.msg.cmd = IPMI_DCMI_GETCONFPARAM; /* Get DCMI Config Parameters */
- req.msg.data = msg_data; /* Contents above */
- /* how many times does req.msg.data need to read */
- req.msg.data_len = 3;
- return intf->sendrecv(intf, &req);
- }
- static int
- ipmi_dcmi_prnt_getconfparam(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp;
- const int dcmi_conf_params = 5;
- int param_selector;
- uint16_t tmp_value = 0;
- /* We are not interested in parameter 1 which always will return 0 */
- for (param_selector = 2 ; param_selector <= dcmi_conf_params;
- param_selector++) {
- rsp = ipmi_dcmi_getconfparam(intf, param_selector);
- if (chk_rsp(rsp)) {
- return -1;
- }
- /* Time to print what we have got */
- switch(param_selector) {
- case 2:
- tmp_value = (rsp->data[4])& 1;
- printf("\n\tDHCP Discovery method\t: ");
- printf("\n\t\tManagement Controller ID String is %s",
- tmp_value ? "enabled" : "disabled");
- printf("\n\t\tVendor class identifier DCMI IANA and Vendor class-specific Informationa are %s",
- ((rsp->data[4])& 2) ? "enabled" : "disabled" );
- break;
- case 3:
- printf("\n\tInitial timeout interval\t: %i seconds",
- rsp->data[4]);
- break;
- case 4:
- printf("\n\tServer contact timeout interval\t: %i seconds",
- rsp->data[4] + (rsp->data[5]<<8));
- break;
- case 5:
- printf("\n\tServer contact retry interval\t: %i seconds",
- rsp->data[4] + (rsp->data[5] << 8));
- break;
- default:
- printf("\n\tConfiguration Parameter not supported.");
- }
- }
- return 0;
- }
- /* This is Set DCMI Config Parameters Command
- *
- * returns ipmi response structure
- *
- * @intf: ipmi interface handler
- */
- struct ipmi_rs *
- ipmi_dcmi_setconfparam(struct ipmi_intf * intf, uint8_t param_selector,
- uint16_t value)
- {
- struct ipmi_rq req;
- uint8_t msg_data[5]; /* number of request data bytes */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = param_selector; /* Parameter selector */
- /* Set Selector (use 00h for parameters that only have one set). */
- msg_data[2] = 0x00;
- if (param_selector > 3) {
- /* One bite more */
- msg_data[3] = value & 0xFF;
- msg_data[4] = value >> 8;
- } else {
- msg_data[3] = value;
- }
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- req.msg.cmd = IPMI_DCMI_SETCONFPARAM; /* Set DCMI Config Parameters */
- req.msg.data = msg_data; /* Contents above */
- if (param_selector > 3) {
- /* One bite more */
- /* how many times does req.msg.data need to read */
- req.msg.data_len = 5;
- } else {
- /* how many times does req.msg.data need to read */
- req.msg.data_len = 4;
- }
- return intf->sendrecv(intf, &req);
- }
- /* Power Management get limit ipmi response
- *
- * This function returns the currently set power management settings as an
- * ipmi response structure. The reason it returns in the rsp struct is so
- * that it can be used in the set limit [slimit()] function to populate
- * un-changed or un-edited values.
- *
- * returns ipmi response structure
- *
- * @intf: ipmi interface handler
- */
- struct ipmi_rs * ipmi_dcmi_pwr_glimit(struct ipmi_intf * intf)
- {
- struct ipmi_rq req;
- uint8_t msg_data[3]; /* number of request data bytes */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = 0x00; /* reserved */
- msg_data[2] = 0x00; /* reserved */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- req.msg.cmd = IPMI_DCMI_GETLMT; /* Get power limit */
- req.msg.data = msg_data; /* Contents above */
- /* how many times does req.msg.data need to read */
- req.msg.data_len = 3;
- return intf->sendrecv(intf, &req);
- }
- /* end Power Management get limit response */
- /* Power Management print the get limit command
- *
- * This function calls the get limit function that returns an ipmi response.
- *
- * returns 0 else 1 with error
- * @intf: ipmi interface handler
- */
- static int
- ipmi_dcmi_pwr_prnt_glimit(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp;
- struct power_limit val;
- uint8_t realCc = 0xff;
- rsp = ipmi_dcmi_pwr_glimit(intf);
- /* rsp can be a null so check response before any operation
- * on it to avoid sig segv
- */
- if (rsp != NULL) {
- realCc = rsp->ccode;
- GOOD_PWR_GLIMIT_CCODE(rsp->ccode);
- }
- if (chk_rsp(rsp)) {
- return -1;
- }
- /* rsp->data[0] is equal to response data byte 2 in spec */
- /* printf("Group Extension Identification: %02x\n", rsp->data[0]); */
- memcpy(&val, rsp->data, sizeof (val));
- printf("\n Current Limit State: %s\n",
- (realCc == 0) ?
- "Power Limit Active" : "No Active Power Limit");
- printf(" Exception actions: %s\n",
- val2str2(val.action, dcmi_pwrmgmt_get_action_vals));
- printf(" Power Limit: %i Watts\n", val.limit);
- printf(" Correction time: %i milliseconds\n", val.correction);
- printf(" Sampling period: %i seconds\n", val.sample);
- printf("\n");
- return 0;
- }
- /* end print get limit */
- /* Power Management set limit
- *
- * Undocumented bounds:
- * Power limit: 0 - 0xFFFF
- * Correction period 5750ms to 28751ms or 0x1676 to 0x704F
- * sample period: 3 sec to 65 sec and 69+
- *
- * @intf: ipmi interface handler
- * @option: Power option to change
- * @value: Value of the desired change
- */
- static int
- ipmi_dcmi_pwr_slimit(struct ipmi_intf * intf, const char * option,
- const char * value)
- {
- struct ipmi_rs * rsp; /* ipmi response */
- struct ipmi_rq req; /* ipmi request (to send) */
- struct power_limit val;
- uint8_t msg_data[15]; /* number of request data bytes */
- uint32_t lvalue = 0;
- rsp = ipmi_dcmi_pwr_glimit(intf); /* get the power limit settings */
- /* rsp can be a null so check response before any operation on it to
- * avoid sig segv
- */
- if (rsp != NULL) {
- GOOD_PWR_GLIMIT_CCODE(rsp->ccode);
- }
- if (chk_rsp(rsp)) {
- return -1;
- }
- memcpy(&val, rsp->data, sizeof (val));
- /* same as above; sets the values of the val struct
- * DCMI group ID *
- * val.grp_id = rsp->data[0];
- * exception action *
- * val.action = rsp->data[3]; *
- *
- * power limit in Watts *
- * store 16 bits of the rsp from the 4th entity *
- * val.limit = *(uint16_t*)(&rsp->data[4]);
- * correction period in mS *
- * store 32 bits of the rsp from the 6th entity *
- * val.correction = *(uint32_t*)(&rsp->data[6]);
- * store 16 bits of the rsp from the 12th entity *
- * sample period in seconds *
- * val.sample = *(uint16_t*)(&rsp->data[12]);
- */
- lprintf(LOG_INFO,
- "DCMI IN Limit=%d Correction=%d Action=%d Sample=%d\n",
- val.limit, val.correction, val.action, val.sample);
- switch (str2val2(option, dcmi_pwrmgmt_set_usage_vals)) {
- case 0x00:
- /* action */
- switch (str2val2(value, dcmi_pwrmgmt_action_vals)) {
- case 0x00:
- /* no_action */
- val.action = 0;
- break;
- case 0x01:
- /* power_off */
- val.action = 1;
- break;
- case 0x02:
- /* OEM reserved action */
- val.action = 0x02;
- break;
- case 0x03:
- /* OEM reserved action */
- val.action = 0x03;
- break;
- case 0x04:
- /* OEM reserved action */
- val.action = 0x04;
- break;
- case 0x05:
- /* OEM reserved action */
- val.action = 0x05;
- break;
- case 0x06:
- /* OEM reserved action */
- val.action = 0x06;
- break;
- case 0x07:
- /* OEM reserved action */
- val.action = 0x07;
- break;
- case 0x08:
- /* OEM reserved action */
- val.action = 0x08;
- break;
- case 0x09:
- /* OEM reserved action */
- val.action = 0x09;
- break;
- case 0x0a:
- /* OEM reserved action */
- val.action = 0x0a;
- break;
- case 0x0b:
- /* OEM reserved action */
- val.action = 0x0b;
- break;
- case 0x0c:
- /* OEM reserved action */
- val.action = 0x0c;
- break;
- case 0x0d:
- /* OEM reserved action */
- val.action = 0x0d;
- break;
- case 0x0e:
- /* OEM reserved action */
- val.action = 0x0e;
- break;
- case 0x0f:
- /* OEM reserved action */
- val.action = 0x0f;
- break;
- case 0x10:
- /* OEM reserved action */
- val.action = 0x10;
- break;
- case 0x11:
- /* sel_logging*/
- val.action = 0x11;
- break;
- case 0xFF:
- /* error - not a string we knew what to do with */
- lprintf(LOG_ERR, "Given %s '%s' is invalid.",
- option, value);
- return -1;
- }
- break;
- case 0x01:
- /* limit */
- if (str2uint(value, &lvalue) != 0) {
- lprintf(LOG_ERR, "Given %s '%s' is invalid.",
- option, value);
- return (-1);
- }
- val.limit = *(uint16_t*)(&lvalue);
- break;
- case 0x02:
- /* correction */
- if (str2uint(value, &lvalue) != 0) {
- lprintf(LOG_ERR, "Given %s '%s' is invalid.",
- option, value);
- return (-1);
- }
- val.correction = *(uint32_t*)(&lvalue);
- break;
- case 0x03:
- /* sample */
- if (str2uint(value, &lvalue) != 0) {
- lprintf(LOG_ERR, "Given %s '%s' is invalid.",
- option, value);
- return (-1);
- }
- val.sample = *(uint16_t*)(&lvalue);
- break;
- case 0xff:
- /* no valid options */
- return -1;
- }
- lprintf(LOG_INFO, "DCMI OUT Limit=%d Correction=%d Action=%d Sample=%d\n", val.limit, val.correction, val.action, val.sample);
- msg_data[0] = val.grp_id; /* Group Extension Identification */
- msg_data[1] = 0x00; /* reserved */
- msg_data[2] = 0x00; /* reserved */
- msg_data[3] = 0x00; /* reserved */
- msg_data[4] = val.action; /* exception action; 0x00 disables it */
- /* fill msg_data[5] with the first 16 bits of val.limit */
- *(uint16_t*)(&msg_data[5]) = val.limit;
- /* msg_data[5] = 0xFF;
- * msg_data[6] = 0xFF;
- */
- /* fill msg_data[7] with the first 32 bits of val.correction */
- *(uint32_t*)(&msg_data[7]) = val.correction;
- /* msg_data[7] = 0x76;
- * msg_data[8] = 0x16;
- * msg_data[9] = 0x00;
- * msg_data[10] = 0x00;
- */
- msg_data[11] = 0x00; /* reserved */
- msg_data[12] = 0x00; /* reserved */
- /* fill msg_data[13] with the first 16 bits of val.sample */
- *(uint16_t*)(&msg_data[13]) = val.sample;
- /* msg_data[13] = 0x03; */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- req.msg.cmd = IPMI_DCMI_SETLMT; /* Set power limit */
- req.msg.data = msg_data; /* Contents above */
- /* how many times does req.msg.data need to read */
- req.msg.data_len = 15;
- rsp = intf->sendrecv(intf, &req);
- if (chk_rsp(rsp)) {
- return -1;
- }
- return 0;
- }
- /* end Power Management set limit */
- /* Power Management activate deactivate
- *
- * @intf: ipmi interface handler
- * @option: uint8_t - 0 to deactivate or 1 to activate
- */
- static int
- ipmi_dcmi_pwr_actdeact(struct ipmi_intf * intf, uint8_t option)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- uint8_t msg_data[4]; /* number of request data bytes */
- msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
- msg_data[1] = option; /* 0 = Deactivate 1 = Activate */
- msg_data[2] = 0x00; /* reserved */
- msg_data[3] = 0x00; /* reserved */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- req.msg.cmd = IPMI_DCMI_PWRACT; /* Act-deactivate power limit */
- req.msg.data = msg_data; /* Contents above */
- req.msg.data_len = 4; /* how mant times does req.msg.data need to read */
- rsp = intf->sendrecv(intf, &req);
- if (chk_rsp(rsp)) {
- return -1;
- }
- printf("\n Power limit successfully ");
- if (option == 0x00) {
- printf("deactivated");
- } else {
- printf("activated");
- }
- printf("\n");
- return 0;
- }
- /* end power management activate/deactivate */
- /* Node Manager discover */
- static int
- _ipmi_nm_discover(struct ipmi_intf * intf, struct nm_discover *disc)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[3]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_GET_VERSION;
- req.msg.data = msg_data;
- req.msg.data_len = 3;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- memcpy(disc, rsp->data, sizeof (struct nm_discover));
- return 0;
- }
- /* Get NM capabilities
- *
- * This function returns the available capabilities of the platform.
- *
- * returns success/failure
- *
- * @intf: ipmi interface handler
- * @caps: fills in capability struct
- */
- static int
- _ipmi_nm_getcapabilities(struct ipmi_intf * intf, uint8_t domain, uint8_t trigger, struct nm_capability *caps)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[5]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = domain;
- msg_data[4] = trigger; /* power control policy or trigger */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_GET_CAP;
- req.msg.data = msg_data;
- req.msg.data_len = 5;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- memcpy(caps, rsp->data, sizeof (struct nm_capability));
- return 0;
- }
- static int
- _ipmi_nm_get_policy(struct ipmi_intf * intf, uint8_t domain, uint8_t policy_id, struct nm_get_policy *policy)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[5]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = domain;
- msg_data[4] = policy_id;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_GET_POLICY;
- req.msg.data = msg_data;
- req.msg.data_len = 5;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- memcpy(policy, rsp->data, sizeof (struct nm_get_policy));
- return 0;
- }
- static int
- _ipmi_nm_set_policy(struct ipmi_intf * intf, struct nm_policy *policy)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_SET_POLICY;
- req.msg.data = (uint8_t *)policy;
- req.msg.data_len = sizeof(struct nm_policy);
- policy->intel_id[0] = 0x57; policy->intel_id[1] =1; policy->intel_id[2] =0;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- return 0;
- }
- static int
- _ipmi_nm_policy_limiting(struct ipmi_intf * intf, uint8_t domain)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[4]; /* 'raw' data to be sent to the BMC */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_LIMITING;
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = domain;
- req.msg.data = msg_data;
- req.msg.data_len = 4;
- rsp = intf->sendrecv(intf, &req);
- /* check for special case error of no policy is limiting */
- if (rsp && (rsp->ccode == 0xA1))
- return 0x80;
- else if (chk_nm_rsp(rsp))
- return -1;
- return rsp->data[0];
- }
- static int
- _ipmi_nm_control(struct ipmi_intf * intf, uint8_t scope, uint8_t domain, uint8_t policy_id)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[6]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = scope;
- msg_data[4] = domain;
- msg_data[5] = policy_id;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_POLICY_CTL;
- req.msg.data = msg_data;
- req.msg.data_len = 6;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- return 0;
- }
- /* Get NM statistics
- *
- * This function returns the statistics
- *
- * returns success/failure
- *
- * @intf: ipmi interface handler
- * @selector: Parameter selector
- */
- static int
- _ipmi_nm_statistics(struct ipmi_intf * intf, uint8_t mode, uint8_t domain, uint8_t policy_id, struct nm_statistics *caps)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[6]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = mode;
- msg_data[4] = domain;
- msg_data[5] = policy_id;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_GET_STATS;
- req.msg.data = msg_data;
- req.msg.data_len = 6;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- memcpy(caps, rsp->data, sizeof (struct nm_statistics));
- return 0;
- }
- static int
- _ipmi_nm_reset_stats(struct ipmi_intf * intf, uint8_t mode, uint8_t domain, uint8_t policy_id)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[6]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = mode;
- msg_data[4] = domain;
- msg_data[5] = policy_id;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_RESET_STATS;
- req.msg.data = msg_data;
- req.msg.data_len = 6;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- return 0;
- }
- static int
- _nm_set_range(struct ipmi_intf * intf, uint8_t domain, uint16_t minimum, uint16_t maximum)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[8]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = domain;
- msg_data[4] = minimum & 0xFF;
- msg_data[5] = minimum >> 8;
- msg_data[6] = maximum & 0xFF;
- msg_data[7] = maximum >> 8;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_SET_POWER;
- req.msg.data = msg_data;
- req.msg.data_len = 8;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- return 0;
- }
- static int
- _ipmi_nm_get_alert(struct ipmi_intf * intf, struct nm_set_alert *alert)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[3]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_GET_ALERT_DS;
- req.msg.data = msg_data;
- req.msg.data_len = 3;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- memcpy(alert, rsp->data, sizeof (struct nm_set_alert));
- return 0;
- }
- static int
- _ipmi_nm_set_alert(struct ipmi_intf * intf, struct nm_set_alert *alert)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[6]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = alert->chan;
- msg_data[4] = alert->dest;
- msg_data[5] = alert->string;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_SET_ALERT_DS;
- req.msg.data = msg_data;
- req.msg.data_len = 6;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- return 0;
- }
- /*
- *
- * get alert threshold values.
- *
- * the list pointer is assumed to point to an array of 16 short integers.
- * This array is filled in for valid thresholds returned.
- */
- static int
- _ipmi_nm_get_thresh(struct ipmi_intf * intf, uint8_t domain, uint8_t policy_id, uint16_t *list)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[5]; /* 'raw' data to be sent to the BMC */
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = domain;
- msg_data[4] = policy_id;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_GET_ALERT_TH;
- req.msg.data = msg_data;
- req.msg.data_len = 5;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- if (rsp->data[3] > 0)
- *list++ = (rsp->data[5] << 8) | rsp->data[4];
- if (rsp->data[3] > 1)
- *list++ = (rsp->data[7] << 8) | rsp->data[6];
- if (rsp->data[3] > 2)
- *list = (rsp->data[9] << 8) | rsp->data[8];
- return 0;
- }
- static int
- _ipmi_nm_set_thresh(struct ipmi_intf * intf, struct nm_thresh * thresh)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[IPMI_NM_SET_THRESH_LEN]; /* 'raw' data to be sent to the BMC */
- memset(&msg_data, 0, sizeof(msg_data));
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = thresh->domain;
- msg_data[4] = thresh->policy_id;
- msg_data[5] = thresh->count;
- if (thresh->count > 0) {
- msg_data[7] = thresh->thresholds[0] >> 8;
- msg_data[6] = thresh->thresholds[0] & 0xFF;
- }
- if (thresh->count > 1) {
- msg_data[9] = thresh->thresholds[1] >> 8;
- msg_data[8] = thresh->thresholds[1] & 0xFF;
- }
- if (thresh->count > 2) {
- msg_data[11] = thresh->thresholds[2] >> 8;
- msg_data[10] = thresh->thresholds[2] & 0xFF;
- }
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_SET_ALERT_TH;
- req.msg.data = msg_data;
- req.msg.data_len = 6 + (thresh->count * 2);
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- return 0;
- }
- /*
- *
- * get suspend periods
- *
- */
- static int
- _ipmi_nm_get_suspend(struct ipmi_intf * intf, uint8_t domain, uint8_t policy_id, int *count, struct nm_period *periods)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[5]; /* 'raw' data to be sent to the BMC */
- int i;
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = domain;
- msg_data[4] = policy_id;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_GET_SUSPEND;
- req.msg.data = msg_data;
- req.msg.data_len = 5;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- *count = rsp->data[3];
- for (i = 0; i < rsp->data[3]; i += 3, periods++) {
- periods->start = rsp->data[4+i];
- periods->stop = rsp->data[5+i];
- periods->repeat = rsp->data[6+i];
- }
- return 0;
- }
- static int
- _ipmi_nm_set_suspend(struct ipmi_intf * intf, struct nm_suspend *suspend)
- {
- struct ipmi_rq req; /* request data to send to the BMC */
- struct ipmi_rs *rsp;
- uint8_t msg_data[21]; /* 6 control bytes + 5 suspend periods, 3 bytes per period */
- struct nm_period *periods;
- int i;
- msg_data[0] = 0x57;
- msg_data[1] = 1;
- msg_data[2] = 0;
- msg_data[3] = suspend->domain;
- msg_data[4] = suspend->policy_id;
- msg_data[5] = suspend->count;
- for (i = 0, periods = &suspend->period[0]; i < (suspend->count*3); i += 3, periods++) {
- msg_data[6+i] = periods->start;
- msg_data[7+i] = periods->stop;
- msg_data[8+i] = periods->repeat;
- }
- memset(&req, 0, sizeof(req));
- req.msg.data_len = 6 + (suspend->count*3);
- req.msg.netfn = IPMI_NETFN_OEM;
- req.msg.cmd = IPMI_NM_SET_SUSPEND;
- req.msg.data = msg_data;
- rsp = intf->sendrecv(intf, &req);
- if (chk_nm_rsp(rsp)) {
- return -1;
- }
- return 0;
- }
- static int
- ipmi_nm_getcapabilities(struct ipmi_intf * intf, int argc, char **argv)
- {
- uint8_t option;
- uint8_t domain = 0; /* default domain of platform */
- uint8_t trigger = 0; /* default power policy (no trigger) */
- struct nm_capability caps;
- while (--argc > 0) {
- argv++;
- if (argv[0] == NULL) break;
- if ((option = str2val2(argv[0], nm_capability_opts)) == 0xFF) {
- print_strs(nm_capability_opts, "Capability commands", LOG_ERR, 0);
- return -1;
- }
- switch (option) {
- case 0x01: /* get domain scope */
- if ((domain = str2val2(argv[1], nm_domain_vals)) == 0xFF) {
- print_strs(nm_domain_vals, "Domain Scope:", LOG_ERR, 0);
- return -1;
- }
- break;
- case 0x02: /* Inlet */
- trigger = 1;
- break;
- case 0x03: /* Missing power reading */
- trigger = 2;
- break;
- case 0x04: /* Time after host reset */
- trigger = 3;
- break;
- case 0x05: /* Boot time policy */
- trigger = 4;
- break;
- default:
- break;
- }
- argc--;
- argv++;
- }
- trigger |= 0x10;
- memset(&caps, 0, sizeof(caps));
- if (_ipmi_nm_getcapabilities(intf, domain, trigger, &caps))
- return -1;
- if (csv_output) {
- printf("%d,%u,%u,%u,%u,%u,%u,%s\n",
- caps.max_settings, caps.max_value,caps.min_value,
- caps.min_corr/1000, caps.max_corr/1000,
- caps.min_stats, caps.max_stats,
- val2str2(caps.scope&0xF, nm_domain_vals));
- return 0;
- }
- printf(" power policies:\t\t%d\n", caps.max_settings);
- switch (trigger&0xF) {
- case 0: /* power */
- printf(" max_power\t\t%7u Watts\n min_power\t\t%7u Watts\n",
- caps.max_value, caps.min_value);
- break;
- case 1: /* Inlet */
- printf(" max_temp\t\t%7u C\n min_temp\t\t%7u C\n",
- caps.max_value, caps.min_value);
- break;
- case 2: /* Missing reading time */
- case 3: /* Time after host reset */
- printf(" max_time\t\t%7u Secs\n min_time\t\t%7u Secs\n",
- caps.max_value/10, caps.min_value/10);
- break;
- case 4: /* boot time policy does not use these values */
- default:
- break;
- }
- printf(" min_corr\t\t%7u secs\n max_corr\t\t%7u secs\n",
- caps.min_corr/1000, caps.max_corr/1000);
- printf(" min_stats\t\t%7u secs\n max_stats\t\t%7u secs\n",
- caps.min_stats, caps.max_stats);
- printf(" domain scope:\t%s\n", val2str2(caps.scope&0xF, nm_domain_vals));
- return 0;
- }
- static int
- ipmi_nm_get_policy(struct ipmi_intf * intf, int argc, char **argv)
- {
- uint8_t option;
- uint8_t domain = 0; /* default domain of platform */
- uint8_t policy_id = -1;
- struct nm_get_policy policy;
- memset(&policy, 0, sizeof(policy));
- while (--argc) {
- argv++;
- if (argv[0] == NULL) break;
- if ((option = str2val2(argv[0], nm_policy_options)) == 0xFF) {
- print_strs(nm_policy_options, "Get Policy commands", LOG_ERR, 0);
- return -1;
- }
- switch (option) {
- case 0x03: /* get domain scope */
- if ((domain = str2val2(argv[1], nm_domain_vals)) == 0xFF) {
- print_strs(nm_domain_vals, "Domain Scope:", LOG_ERR, 0);
- return -1;
- }
- policy.domain |= domain & 0xF;
- break;
- case 0x0B: /* policy id */
- if (str2uchar(argv[1], &policy_id) < 0) {
- lprintf(LOG_ERR," Policy ID must be a positive integer 0-7.\n");
- return -1;
- }
- break;
- default:
- printf(" Unknown command 0x%x, skipping.\n", option);
- break;
- }
- argc--;
- argv++;
- }
- if (policy_id == 0xFF) {
- print_strs(nm_stats_opts, "Missing policy_id parameter:", LOG_ERR, 0);
- return -1;
- }
- if (_ipmi_nm_get_policy(intf, policy.domain, policy_id, &policy))
- return -1;
- if (csv_output) {
- printf("%s,0x%x,%s,%s,%s,%u,%u,%u,%u,%s\n",
- val2str2(policy.domain&0xF, nm_domain_vals),
- policy.domain,
- (policy.policy_type & 0x10) ? "power" : "nopower ",
- val2str2(policy.policy_type & 0xF, nm_policy_type_vals),
- val2str2(policy.policy_exception, nm_exception),
- policy.policy_limits,
- policy.corr_time,
- policy.trigger_limit,
- policy.stats_period,
- policy.policy_type & 0x80 ? "volatile" : "non-volatile");
- return 0;
- }
- printf(" Power domain: %s\n",
- val2str2(policy.domain&0xF, nm_domain_vals));
- printf(" Policy is %s %s%s%s\n",
- policy.domain&0x10 ? "enabled" : "not enabled",
- policy.domain&0x20 ? "per Domain " : "",
- policy.domain&0x40 ? "Globally " : "",
- policy.domain&0x80 ? "via DCMI api " : "");
- printf(" Policy is %sa power control type.\n", (policy.policy_type & 0x10) ? "" : "not ");
- printf(" Policy Trigger Type: %s\n",
- val2str2(policy.policy_type & 0xF, nm_policy_type_vals));
- printf(" Correction Aggressiveness: %s\n",
- val2str2((policy.policy_type>> 5) & 0x3, nm_correction_vals));
- printf(" Policy Exception Actions: %s\n",
- val2str2(policy.policy_exception, nm_exception));
- printf(" Power Limit: %u Watts\n",
- policy.policy_limits);
- printf(" Correction Time Limit: %u milliseconds\n",
- policy.corr_time);
- printf(" Trigger Limit: %u units\n",
- policy.trigger_limit);
- printf(" Statistics Reporting Period: %u seconds\n",
- policy.stats_period);
- printf(" Policy retention: %s\n",
- policy.policy_type & 0x80 ? "volatile" : "non-volatile");
- if ( (policy_id == 0) && ((policy.domain & 0xf) == 0x3) )
- printf(" HW Prot Power domain: %s\n",
- policy.policy_type & 0x80 ? "Secondary" : "Primary");
- return 0;
- }
- static int
- ipmi_nm_policy(struct ipmi_intf * intf, int argc, char **argv)
- {
- uint8_t action;
- uint8_t option;
- uint8_t correction;
- uint8_t domain = 0; /* default domain of platform */
- uint8_t policy_id = -1;
- uint16_t power, period, inlet;
- uint16_t cores;
- uint32_t limit;
- struct nm_policy policy;
- argv++;
- argc--;
- if ((argv[0] == NULL) ||
- ((action = str2val2(argv[0], nm_policy_action)) == 0xFF)) {
- print_strs(nm_policy_action, "Policy commands", LOG_ERR, 0);
- return -1;
- }
- if (action == 0) /* get */
- return (ipmi_nm_get_policy(intf, argc, argv));
- memset(&policy, 0, sizeof(policy));
- /*
- * nm policy add [domain <param>] enable|disable policy_id <param> correction <opt> power <watts> limit <param> period <param>
- * nm policy remove [domain <param>] policy_id <param>
- * nm policy limiting {domain <param>]
- */
- while (--argc > 0) {
- argv++;
- if (argv[0] == NULL) break;
- if ((option = str2val2(argv[0], nm_policy_options)) == 0xFF) {
- print_strs(nm_policy_options, "Policy options", LOG_ERR, 0);
- return -1;
- }
- switch (option) {
- case 0x01: /* policy enable */
- policy.domain |= IPMI_NM_POLICY_ENABLE;
- break;
- case 0x02: /* policy disable */
- break; /* value is initialized to zero already */
- case 0x03: /* get domain scope */
- if ((domain = str2val2(argv[1], nm_domain_vals)) == 0xFF) {
- print_strs(nm_domain_vals, "Domain Scope:", LOG_ERR, 0);
- return -1;
- }
- policy.domain |= domain & 0xF;
- break;
- case 0x04: /* inlet */
- if (str2ushort(argv[1], &inlet) < 0) {
- printf("Inlet Temp value must be 20-45.\n");
- return -1;
- }
- policy.policy_type |= 1;
- policy.policy_limits = 0;
- policy.trigger_limit = inlet;
- break;
- case 0x06: /* get correction action */
- if (action == 0x5) break; /* skip if this is a remove */
- if ((correction = str2val2(argv[1], nm_correction)) == 0xFF) {
- print_strs(nm_correction, "Correction Actions", LOG_ERR, 0);
- return -1;
- }
- policy.policy_type |= (correction << 5);
- break;
- case 0x07: /* not implemented */
- break;
- case 0x08: /* power */
- if (str2ushort(argv[1], &power) < 0) {
- printf("Power limit value must be 0-500.\n");
- return -1;
- }
- policy.policy_limits = power;
- break;
- case 0x09: /* trigger limit */
- if (str2uint(argv[1], &limit) < 0) {
- printf("Trigger Limit value must be positive integer.\n");
- return -1;
- }
- policy.corr_time = limit;
- break;
- case 0x0A: /* statistics period */
- if (str2ushort(argv[1], &period) < 0) {
- printf("Statistics Reporting Period must be positive integer.\n");
- return -1;
- }
- policy.stats_period = period;
- break;
- case 0x0B: /* policy ID */
- if (str2uchar(argv[1], &policy_id) < 0) {
- printf("Policy ID must be a positive integer 0-7.\n");
- return -1;
- }
- policy.policy_id = policy_id;
- break;
- case 0x0C: /* volatile */
- policy.policy_type |= 0x80;
- break;
- case 0x0D: /* cores_off, number of cores to disable at boot time */
- policy.policy_type |= 4;
- if (str2ushort(argv[1], &cores) < 0) {
- printf("number of cores disabled must be 1-127.\n");
- return -1;
- }
- if ((cores < 1) || (cores > 127)) {
- printf("number of cores disabled must be 1-127.\n");
- return -1;
- }
- policy.policy_type |= 4;
- policy.policy_limits = cores << 1;
- break;
- default:
- break;
- }
- argc--;
- argv++;
- }
- if (action == 0x06) { /* limiting */
- if ((limit = _ipmi_nm_policy_limiting(intf, domain) == -1))
- return -1;
- printf("limit %x\n", limit);
- return 0;
- }
- if (policy_id == 0xFF) {
- print_strs(nm_stats_opts, "Missing policy_id parameter:", LOG_ERR, 0);
- return -1;
- }
- if (action == 0x04) /* add */
- policy.policy_type |= 0x10;
- if (_ipmi_nm_set_policy(intf, &policy))
- return -1;
- return 0;
- }
- /* end policy */
- static int
- ipmi_nm_control(struct ipmi_intf * intf, int argc, char **argv)
- {
- uint8_t action;
- uint8_t scope = 0; /* default control scope of global */
- uint8_t domain = 0; /* default domain of platform */
- uint8_t policy_id = -1;
- argv++;
- argc--;
- /* nm_ctl_cmds returns 0 for disable, 1 for enable */
- if ((argv[0] == NULL) ||
- ((action = str2val2(argv[0], nm_ctl_cmds)) == 0xFF)) {
- print_strs(nm_ctl_cmds, "Control parameters:", LOG_ERR, 0);
- print_strs(nm_ctl_domain, "control Scope (required):", LOG_ERR, 0);
- return -1;
- }
- argv++;
- while (--argc) {
- /* nm_ctl_domain returns correct bit field except for action */
- if ((argv[0] == NULL) ||
- ((scope = str2val2(argv[0], nm_ctl_domain)) == 0xFF)) {
- print_strs(nm_ctl_domain, "Control Scope (required):", LOG_ERR, 0);
- return -1;
- }
- argv++;
- if (argv[0] == NULL) break;
- if (scope == 0x02) { /* domain */
- if ((domain = str2val2(argv[0], nm_domain_vals)) == 0xFF) {
- print_strs(nm_domain_vals, "Domain Scope:", LOG_ERR, 0);
- return -1;
- }
- } else if (scope == 0x04) { /* per_policy */
- if (str2uchar(argv[0], &policy_id) < 0) {
- lprintf(LOG_ERR,"Policy ID must be a positive integer.\n");
- return -1;
- }
- break;
- }
- argc--;
- argv++;
- }
- if ((scope == 0x04) && (policy_id == 0xFF)) {
- print_strs(nm_stats_opts, "Missing policy_id parameter:", LOG_ERR, 0);
- return -1;
- }
- if (_ipmi_nm_control(intf, scope|(action&1), domain, policy_id) < 0 )
- return -1;
- return 0;
- }
- static int
- ipmi_nm_get_statistics(struct ipmi_intf * intf, int argc, char **argv)
- {
- uint8_t mode = 0;
- uint8_t option;
- uint8_t domain = 0; /* default domain of platform */
- uint8_t policy_id = -1;
- int policy_mode = 0;
- int cut;
- char *units = "";
- char datebuf[27];
- struct nm_statistics stats;
- struct tm tm_t;
- time_t t;
- argv++;
- if ((argv[0] == NULL) ||
- ((mode = str2val2(argv[0], nm_stats_mode)) == 0xFF)) {
- print_strs(nm_stats_mode, "Statistics commands", LOG_ERR, 0);
- return -1;
- }
- while (--argc) {
- argv++;
- if (argv[0] == NULL) break;
- if ((option = str2val2(argv[0], nm_stats_opts)) == 0xFF) {
- print_strs(nm_stats_opts, "Control Scope options", LOG_ERR, 0);
- return -1;
- }
- switch (option) {
- case 0x01: /* get domain scope */
- if ((domain = str2val2(argv[1], nm_domain_vals)) == 0xFF) {
- print_strs(nm_domain_vals, "Domain Scope:", LOG_ERR, 0);
- return -1;
- }
- break;
- case 0x02: /* policy ID */
- if (str2uchar(argv[1], &policy_id) < 0) {
- lprintf(LOG_ERR,"Policy ID must be a positive integer.\n");
- return -1;
- }
- break;
- default:
- break;
- }
- argc--;
- argv++;
- }
- switch (mode) {
- case 0x01:
- units = "Watts";
- break;
- case 0x02:
- units = "Celsius";
- break;
- case 0x03:
- units = "%";
- break;
- case 0x11:
- case 0x12:
- case 0x13:
- policy_mode = 1;
- units = (mode == 0x11) ? "Watts" : (mode == 0x12) ? "Celsius" : " %";
- if (policy_id == 0xFF) {
- print_strs(nm_stats_opts, "Missing policy_id parameter:", LOG_ERR, 0);
- return -1;
- }
- break;
- default:
- break;
- }
- if (_ipmi_nm_statistics(intf, mode, domain, policy_id, &stats))
- return -1;
- t = stats.time_stamp;
- gmtime_r(&t, &tm_t);
- sprintf(datebuf, "%s", asctime(&tm_t));
- cut = strlen(datebuf) -1;
- datebuf[cut] = 0;
- if (csv_output) {
- printf("%s,%s,%s,%s,%s,%d,%d,%d,%d,%s,%d\n",
- val2str2(stats.id_state & 0xF, nm_domain_vals),
- ((stats.id_state >> 4) & 1) ? (policy_mode ? "Policy Enabled" : "Globally Enabled") : "Disabled" ,
- ((stats.id_state >> 5) & 1) ? "active" : "suspended",
- ((stats.id_state >> 6) & 1) ? "in progress" : "suspended",
- ((stats.id_state >> 7) & 1) ? "triggered" : "not triggered",
- stats.curr_value,
- stats.min_value,
- stats.max_value,
- stats.ave_value,
- datebuf,
- stats.stat_period);
- return 0;
- }
- printf(" Power domain: %s\n",
- val2str2(stats.id_state & 0xF, nm_domain_vals));
- printf(" Policy/Global Admin state %s\n",
- ((stats.id_state >> 4) & 1) ? (policy_mode ? "Policy Enabled" : "Globally Enabled") : "Disabled" );
- printf(" Policy/Global Operational state %s\n",
- ((stats.id_state >> 5) & 1) ? "active" : "suspended");
- printf(" Policy/Global Measurement state %s\n",
- ((stats.id_state >> 6) & 1) ? "in progress" : "suspended");
- printf(" Policy Activation state %s\n",
- ((stats.id_state >> 7) & 1) ? "triggered" : "not triggered");
- printf(" Instantaneous reading: %8d %s\n",
- stats.curr_value, units);
- printf(" Minimum during sampling period: %8d %s\n",
- stats.min_value, units);
- printf(" Maximum during sampling period: %8d %s\n",
- stats.max_value, units);
- printf(" Average reading over sample period: %8d %s\n",
- stats.ave_value, units);
- printf(" IPMI timestamp: %s\n",
- datebuf);
- printf(" Sampling period: %08d Seconds.\n", stats.stat_period);
- printf("\n");
- return 0;
- }
- static int
- ipmi_nm_reset_statistics(struct ipmi_intf * intf, int argc, char **argv)
- {
- uint8_t mode;
- uint8_t option;
- uint8_t domain = 0; /* default domain of platform */
- uint8_t policy_id = -1;
- argv++;
- if ((argv[0] == NULL) ||
- ((mode = str2val2(argv[0], nm_reset_mode)) == 0xFF)) {
- print_strs(nm_reset_mode, "Reset Statistics Modes:", LOG_ERR, 0);
- return -1;
- }
- while (--argc) {
- argv++;
- if (argv[0] == NULL) break;
- if ((option = str2val2(argv[0], nm_stats_opts)) == 0xFF) {
- print_strs(nm_stats_opts, "Reset Scope options", LOG_ERR, 0);
- return -1;
- }
- switch (option) {
- case 0x01: /* get domain scope */
- if ((domain = str2val2(argv[1], nm_domain_vals)) == 0xFF) {
- print_strs(nm_domain_vals, "Domain Scope:", LOG_ERR, 0);
- return -1;
- }
- break;
- case 0x02: /* policy ID */
- if (str2uchar(argv[1], &policy_id) < 0) {
- lprintf(LOG_ERR,"Policy ID must be a positive integer.\n");
- return -1;
- }
- break;
- default:
- break;
- }
- argc--;
- argv++;
- }
- if (mode && (policy_id == 0xFF)) {
- print_strs(nm_stats_opts, "Missing policy_id parameter:", LOG_ERR, 0);
- return -1;
- }
- if (_ipmi_nm_reset_stats(intf, mode, domain, policy_id) < 0)
- return -1;
- return 0;
- }
- static int
- ipmi_nm_set_range(struct ipmi_intf * intf, int argc, char **argv)
- {
- uint8_t domain = 0;
- uint8_t param;
- uint16_t minimum = -1;
- uint16_t maximum = -1;
- while (--argc) {
- argv++;
- if (argv[0] == NULL) break;
- if ((param = str2val2(argv[0], nm_power_range)) == 0xFF) {
- print_strs(nm_power_range, "power range parameters:", LOG_ERR, 0);
- return -1;
- }
- switch (param) {
- case 0x01: /* get domain scope */
- if ((domain = str2val2(argv[1], nm_domain_vals)) == 0xFF) {
- print_strs(nm_domain_vals, "Domain Scope:", LOG_ERR, 0);
- return -1;
- }
- break;
- case 0x02: /* min */
- if (str2ushort(argv[1], &minimum) < 0) {
- lprintf(LOG_ERR,"Power minimum must be a positive integer.\n");
- return -1;
- }
- break;
- case 0x03: /* max */
- if (str2ushort(argv[1], &maximum) < 0) {
- lprintf(LOG_ERR,"Power maximum must be a positive integer.\n");
- return -1;
- }
- break;
- default:
- break;
- }
- argc--;
- argv++;
- }
- if ((minimum == 0xFFFF) || (maximum == 0xFFFF)) {
- lprintf(LOG_ERR,"Missing parameters: nm power range min <minimum> max <maximum>.\n");
- return -1;
- }
- if (_nm_set_range(intf, domain, minimum, maximum) < 0)
- return -1;
- return 0;
- }
- static int
- ipmi_nm_get_alert(struct ipmi_intf * intf)
- {
- struct nm_set_alert alert;
- memset(&alert, 0, sizeof(alert));
- if (_ipmi_nm_get_alert(intf, &alert))
- return -1;
- if (csv_output) {
- printf("%d,%s,0x%x,%s,0x%x\n",
- alert.chan&0xF,
- (alert.chan >> 7) ? "not registered" : "registered",
- alert.dest,
- (alert.string >> 7) ? "yes" : "no",
- alert.string & 0x7F);
- return 0;
- }
- printf(" Alert Chan: %d\n",
- alert.chan&0xF);
- printf(" Alert Receiver: %s\n",
- (alert.chan >> 7) ? "not registered" : "registered");
- printf(" Alert Lan Destination: 0x%x\n",
- alert.dest);
- printf(" Use Alert String: %s\n",
- (alert.string >> 7) ? "yes" : "no");
- printf(" Alert String Selector: 0x%x\n",
- alert.string & 0x7F);
- return 0;
- }
- static int
- ipmi_nm_alert(struct ipmi_intf * intf, int argc, char **argv)
- {
- uint8_t param;
- uint8_t action;
- uint8_t chan = -1;
- uint8_t dest = -1;
- uint8_t string = -1;
- struct nm_set_alert alert;
- argv++;
- argc--;
- if ((argv[0] == NULL) ||
- ((action = str2val2(argv[0], nm_alert_opts)) == 0xFF)) {
- print_strs(nm_alert_opts, "Alert commands", LOG_ERR, 0);
- return -1;
- }
- if (action == 0x02) /* get */
- return (ipmi_nm_get_alert(intf));
- /* set */
- memset(&alert, 0, sizeof(alert));
- while (--argc) {
- argv++;
- if (argv[0] == NULL) break;
- if ((param = str2val2(argv[0], nm_set_alert_param)) == 0xFF) {
- print_strs(nm_set_alert_param, "Set alert Parameters:", LOG_ERR, 0);
- return -1;
- }
- switch (param) {
- case 0x01: /* channnel */
- if (str2uchar(argv[1], &chan) < 0) {
- lprintf(LOG_ERR,"Alert Lan chan must be a positive integer.\n");
- return -1;
- }
- if (action == 0x03) /* Clear */
- chan |= 0x80; /* deactivate alert reciever */
- break;
- case 0x02: /* dest */
- if (str2uchar(argv[1], &dest) < 0) {
- lprintf(LOG_ERR,"Alert Destination must be a positive integer.\n");
- return -1;
- }
- break;
- case 0x03: /* string number */
- if (str2uchar(argv[1], &string) < 0) {
- lprintf(LOG_ERR,"Alert String # must be a positive integer.\n");
- return -1;
- }
- string |= 0x80; /* set string select flag */
- break;
- }
- argc--;
- argv++;
- }
- if ((chan == 0xFF) || (dest == 0xFF)) {
- print_strs(nm_set_alert_param, "Must set alert chan and dest params.", LOG_ERR, 0);
- return -1;
- }
- if (string == 0xFF) string = 0;
- alert.chan = chan;
- alert.dest = dest;
- alert.string = string;
- if (_ipmi_nm_set_alert(intf, &alert))
- return -1;
- return 0;
- }
- static int
- ipmi_nm_get_thresh(struct ipmi_intf *intf, uint8_t domain, uint8_t policy_id)
- {
- uint16_t list[3];
- memset(list, 0, sizeof(list));
- if (_ipmi_nm_get_thresh(intf, domain, policy_id, &list[0]))
- return -1;
- printf(" Alert Threshold domain: %s\n",
- val2str2(domain, nm_domain_vals));
- printf(" Alert Threshold Policy ID: %d\n",
- policy_id);
- printf(" Alert Threshold 1: %d\n",
- list[0]);
- printf(" Alert Threshold 2: %d\n",
- list[1]);
- printf(" Alert Threshold 3: %d\n",
- list[2]);
- return 0;
- }
- static int
- ipmi_nm_thresh(struct ipmi_intf * intf, int argc, char **argv)
- {
- uint8_t option;
- uint8_t action;
- uint8_t domain = 0; /* default domain of platform */
- uint8_t policy_id = -1;
- struct nm_thresh thresh;
- int i = 0;
- argv++;
- argc--;
- /* set or get */
- if ((argv[0] == NULL) || (argc < 3) ||
- ((action = str2val2(argv[0], nm_thresh_cmds)) == 0xFF)) {
- print_strs(nm_thresh_cmds, "Theshold commands", LOG_ERR, 0);
- return -1;
- }
- memset(&thresh, 0, sizeof(thresh));
- while (--argc) {
- argv++;
- if (argv[0] == NULL) break;
- option = str2val2(argv[0], nm_thresh_param);
- switch (option) {
- case 0x01: /* get domain scope */
- if ((domain = str2val2(argv[1], nm_domain_vals)) == 0xFF) {
- print_strs(nm_domain_vals, "Domain Scope:", LOG_ERR, 0);
- return -1;
- }
- argc--;
- argv++;
- break;
- case 0x02: /* policy ID */
- if (str2uchar(argv[1], &policy_id) < 0) {
- lprintf(LOG_ERR,"Policy ID must be a positive integer.\n");
- return -1;
- }
- argc--;
- argv++;
- break;
- case 0xFF:
- if (i > 2) {
- lprintf(LOG_ERR,"Set Threshold requires 1, 2, or 3 threshold integer values.\n");
- return -1;
- }
- if (str2ushort(argv[0], &thresh.thresholds[i++]) < 0) {
- lprintf(LOG_ERR,"threshold value %d count must be a positive integer.\n", i);
- return -1;
- }
- default:
- break;
- }
- }
- if (policy_id == 0xFF) {
- print_strs(nm_stats_opts, "Missing policy_id parameter:", LOG_ERR, 0);
- return -1;
- }
- if (action == 0x02) /* get */
- return (ipmi_nm_get_thresh(intf, domain, policy_id));
- thresh.domain = domain;
- thresh.policy_id = policy_id;
- thresh.count = i;
- if (_ipmi_nm_set_thresh(intf, &thresh) < 0)
- return -1;
- return 0;
- }
- static inline int
- click2hour(int click)
- {
- if ((click*6) < 60) return 0;
- return ((click*6)/60);
- }
- static inline int
- click2min(int click)
- {
- if (!click) return 0;
- if ((click*6) < 60) return click*6;
- return (click*6)%60;
- }
- static int
- ipmi_nm_get_suspend(struct ipmi_intf *intf, uint8_t domain, uint8_t policy_id)
- {
- struct nm_period periods[5];
- int i;
- int j;
- int count = 0;
- const char *days[7] = {"M", "Tu", "W", "Th", "F", "Sa", "Su"};
- memset(periods, 0, sizeof(periods));
- if (_ipmi_nm_get_suspend(intf, domain, policy_id, &count, &periods[0]))
- return -1;
- printf(" Suspend Policy domain: %s\n",
- val2str2(domain, nm_domain_vals));
- printf(" Suspend Policy Policy ID: %d\n",
- policy_id);
- if (!count) {
- printf(" No suspend Periods.\n");
- return 0;
- }
- for (i = 0; i < count; i++) {
- printf(" Suspend Period %d: %02d:%02d to %02d:%02d",
- i, click2hour(periods[i].start), click2min(periods[i].start),
- click2hour(periods[i].stop), click2min(periods[i].stop));
- if (periods[i].repeat) printf(", ");
- for (j = 0; j < 7; j++)
- printf("%s", (periods[i].repeat >> j)&1 ? days[j] : "");
- printf("\n");
- }
- return 0;
- }
- static int
- ipmi_nm_suspend(struct ipmi_intf * intf, int argc, char **argv)
- {
- uint8_t option;
- uint8_t action;
- uint8_t domain = 0; /* default domain of platform */
- uint8_t policy_id = -1;
- uint8_t count = 0;
- struct nm_suspend suspend;
- int i;
- argv++;
- argc--;
- /* set or get */
- if ((argv[0] == NULL) || (argc < 3) ||
- ((action = str2val2(argv[0], nm_suspend_cmds)) == 0xFF)) {
- print_strs(nm_suspend_cmds, "Suspend commands", LOG_ERR, 0);
- return -1;
- }
- memset(&suspend, 0, sizeof(suspend));
- while (--argc > 0) {
- argv++;
- if (argv[0] == NULL) break;
- option = str2val2(argv[0], nm_thresh_param);
- switch (option) {
- case 0x01: /* get domain scope */
- if ((domain = str2val2(argv[1], nm_domain_vals)) == 0xFF) {
- print_strs(nm_domain_vals, "Domain Scope:", LOG_ERR, 0);
- return -1;
- }
- argc--;
- argv++;
- break;
- case 0x02: /* policy ID */
- if (str2uchar(argv[1], &policy_id) < 0) {
- lprintf(LOG_ERR,"Policy ID must be a positive integer.\n");
- return -1;
- }
- argc--;
- argv++;
- break;
- case 0xFF: /* process periods */
- for (i = 0; count < IPMI_NM_SUSPEND_PERIOD_MAX; i += 3, count++) {
- if (argc < 3) {
- lprintf(LOG_ERR,"Error: suspend period requires a start, stop, and repeat values.\n");
- return -1;
- }
- if (str2uchar(argv[i+0], &suspend.period[count].start) < 0) {
- lprintf(LOG_ERR,"suspend start value %d must be 0-239.\n", count);
- return -1;
- }
- if (str2uchar(argv[i+1], &suspend.period[count].stop) < 0) {
- lprintf(LOG_ERR,"suspend stop value %d must be 0-239.\n", count);
- return -1;
- }
- if (str2uchar(argv[i+2], &suspend.period[count].repeat) < 0) {
- lprintf(LOG_ERR,"suspend repeat value %d unable to convert.\n", count);
- return -1;
- }
- argc -= 3;
- if (argc <= 0)
- break;
- }
- if (argc <= 0)
- break;
- break;
- default:
- break;
- }
- }
- if (action == 0x02) /* get */
- return (ipmi_nm_get_suspend(intf, domain, policy_id));
- suspend.domain = domain;
- suspend.policy_id = policy_id;
- if (_ipmi_nm_set_suspend(intf, &suspend) < 0)
- return -1;
- return 0;
- }
- /* end nm */
- static int
- ipmi_dcmi_set_limit(struct ipmi_intf * intf, int argc, char **argv)
- {
- int rc = 0;
- if ( argc == 10) {
- /* Let`s initialize dcmi power parameters */
- struct ipmi_rq req;
- uint8_t data[256];
- uint16_t sample = 0;
- uint16_t limit = 0;
- uint32_t correction = 0;
- struct ipmi_rs *rsp;
- memset(data, 0, sizeof(data));
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_DCGRP;
- req.msg.lun = 0x00;
- req.msg.cmd = IPMI_DCMI_SETLMT; /* Set power limit */
- req.msg.data = data; /* Contents above */
- req.msg.data_len = 15;
- data[0] = IPMI_DCMI; /* Group Extension Identification */
- data[1] = 0x0; /* reserved */
- data[2] = 0x0; /* reserved */
- data[3] = 0x0; /* reserved */
- /* action */
- switch (str2val2(argv[2], dcmi_pwrmgmt_action_vals)) {
- case 0x00:
- /* no_action */
- data[4] = 0x00;
- break;
- case 0x01:
- /* power_off */
- data[4] = 0x01;
- break;
- case 0x11:
- /* sel_logging*/
- data[4] = 0x11;
- break;
- case 0xFF:
- /* error - not a string we knew what to do with */
- lprintf(LOG_ERR, "Given Action '%s' is invalid.",
- argv[2]);
- return -1;
- }
- /* limit */
- if (str2ushort(argv[4], &limit) != 0) {
- lprintf(LOG_ERR,
- "Given Limit '%s' is invalid.",
- argv[4]);
- return (-1);
- }
- data[5] = limit >> 0;
- data[6] = limit >> 8;
- /* correction */
- if (str2uint(argv[6], &correction) != 0) {
- lprintf(LOG_ERR,
- "Given Correction '%s' is invalid.",
- argv[6]);
- return (-1);
- }
- data[7] = correction >> 0;
- data[8] = correction >> 8;
- data[9] = correction >> 16;
- data[10] = correction >> 24;
- data[11] = 0x00; /* reserved */
- data[12] = 0x00; /* reserved */
- /* sample */
- if (str2ushort(argv[8], &sample) != 0) {
- lprintf(LOG_ERR,
- "Given Sample '%s' is invalid.",
- argv[8]);
- return (-1);
- }
- data[13] = sample >> 0;
- data[14] = sample >> 8;
- rsp = intf->sendrecv(intf, &req);
- if (chk_rsp(rsp)) {
- return -1;
- }
- } else {
- /* loop through each parameter and value until we have neither */
- while ((argv[1] != NULL) && (argv[2] != NULL)) {
- rc = ipmi_dcmi_pwr_slimit(intf, argv[1], argv[2]);
- /* catch any error that the set limit function returned */
- if (rc > 0) {
- print_strs(dcmi_pwrmgmt_set_usage_vals,
- "set_limit <parameter> <value>", LOG_ERR, 0);
- return -1;
- }
- /* the first argument is the command and the second is the
- * value. Move argv two places; what is now 3 will be 1
- */
- argv+=2;
- }
- }
- return rc;
- }
- static int
- ipmi_dcmi_parse_power(struct ipmi_intf * intf, int argc, char **argv)
- {
- int rc = 0;
- uint8_t sample_time = 0;
- /* power management */
- switch (str2val2(argv[0], dcmi_pwrmgmt_vals)) {
- case 0x00:
- /* get reading */
- if (argv[1] != NULL) {
- if (!(sample_time = str2val2(argv[1], dcmi_sampling_vals))) {
- print_strs(dcmi_sampling_vals,
- "Invalid sample time. Valid times are: ",
- LOG_ERR, 1);
- printf("\n");
- return -1;
- }
- }
- rc = ipmi_dcmi_pwr_rd(intf, sample_time);
- break;
- case 0x01:
- /* get limit */
- /* because the get limit function is also used to
- * populate unchanged values for the set limit
- * command it returns an ipmi response structure
- */
- rc = ipmi_dcmi_pwr_prnt_glimit(intf);
- break;
- case 0x02:
- /* set limit */
- if (argc < 4) {
- print_strs(dcmi_pwrmgmt_set_usage_vals,
- "set_limit <parameter> <value>",
- LOG_ERR, 0);
- return -1;
- }
- if (ipmi_dcmi_set_limit(intf, argc, argv) < 0)
- return -1;
- rc = ipmi_dcmi_pwr_prnt_glimit(intf);
- break;
- case 0x03:
- /* activate */
- rc = ipmi_dcmi_pwr_actdeact(intf, 1);
- break;
- case 0x04:
- /* deactivate */
- rc = ipmi_dcmi_pwr_actdeact(intf, 0);
- break;
- default:
- /* no valid options */
- print_strs(dcmi_pwrmgmt_vals,
- "power <command>", LOG_ERR, 0);
- break;
- }
- return rc;
- }
- /* end dcmi power command */
- static int
- ipmi_dcmi_thermalpolicy(struct ipmi_intf * intf, int argc, char **argv)
- {
- int rc = 0;
- uint8_t entityID = 0;
- uint8_t entityInst = 0;
- uint8_t persistanceFlag;
- uint8_t actionHardPowerOff;
- uint8_t actionLogToSEL;
- uint8_t tempLimit = 0;
- uint8_t samplingTimeLSB;
- uint8_t samplingTimeMSB;
- uint16_t samplingTime = 0;
- /* Thermal policy get/set */
- /* dcmitool dcmi thermalpolicy get */
- switch (str2val2(argv[1], dcmi_thermalpolicy_vals)) {
- case 0x00:
- if (argc < 4) {
- lprintf(LOG_NOTICE, "Get <entityID> <instanceID>");
- return -1;
- }
- if (str2uchar(argv[2], &entityID) != 0) {
- lprintf(LOG_ERR,
- "Given Entity ID '%s' is invalid.",
- argv[2]);
- return (-1);
- }
- if (str2uchar(argv[3], &entityInst) != 0) {
- lprintf(LOG_ERR,
- "Given Instance ID '%s' is invalid.",
- argv[3]);
- return (-1);
- }
- rc = ipmi_dcmi_getthermalpolicy(intf, entityID, entityInst);
- break;
- case 0x01:
- if (argc < 4) {
- lprintf(LOG_NOTICE, "Set <entityID> <instanceID>");
- return -1;
- } else if (argc < 9) {
- print_strs(dcmi_thermalpolicy_set_parameters_vals,
- "Set thermalpolicy instance parameters: "
- "<volatile/nonvolatile/disabled> "
- "<poweroff/nopoweroff/disabled> "
- "<sel/nosel/disabled> <templimitByte> <exceptionTime>",
- LOG_ERR, 0);
- return -1;
- }
- if (str2uchar(argv[2], &entityID) != 0) {
- lprintf(LOG_ERR,
- "Given Entity ID '%s' is invalid.",
- argv[2]);
- return (-1);
- }
- if (str2uchar(argv[3], &entityInst) != 0) {
- lprintf(LOG_ERR,
- "Given Instance ID '%s' is invalid.",
- argv[3]);
- return (-1);
- }
- persistanceFlag = (uint8_t) str2val2(argv[4], dcmi_thermalpolicy_set_parameters_vals);
- actionHardPowerOff = (uint8_t) str2val2(argv[5], dcmi_thermalpolicy_set_parameters_vals);
- actionLogToSEL = (uint8_t) str2val2(argv[6], dcmi_thermalpolicy_set_parameters_vals);
- if (str2uchar(argv[7], &tempLimit) != 0) {
- lprintf(LOG_ERR,
- "Given Temp Limit '%s' is invalid.",
- argv[7]);
- return (-1);
- }
- if (str2ushort(argv[8], &samplingTime) != 0) {
- lprintf(LOG_ERR,
- "Given Sampling Time '%s' is invalid.",
- argv[8]);
- return (-1);
- }
- samplingTimeLSB = (samplingTime & 0xFF);
- samplingTimeMSB = ((samplingTime & 0xFF00) >> 8);
- rc = ipmi_dcmi_setthermalpolicy(intf,
- entityID,
- entityInst,
- persistanceFlag,
- actionHardPowerOff,
- actionLogToSEL,
- tempLimit,
- samplingTimeLSB,
- samplingTimeMSB);
- break;
- default:
- print_strs(dcmi_thermalpolicy_vals,
- "thermalpolicy <command>",
- LOG_ERR, 0);
- return -1;
- }
- return rc;
- }
- /* main
- *
- * @intf: dcmi interface handler
- * @argc: argument count
- * @argv: argument vector
- */
- int
- ipmi_dcmi_main(struct ipmi_intf * intf, int argc, char **argv)
- {
- int rc = 0;
- int i;
- struct ipmi_rs *rsp;
- if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0)) {
- print_strs(dcmi_cmd_vals,
- "Data Center Management Interface commands",
- LOG_ERR, 0);
- return -1;
- }
- /* start the cmd requested */
- switch (str2val2(argv[0], dcmi_cmd_vals)) {
- case 0x00:
- /* discover capabilities*/
- for (i = 1; dcmi_capable_vals[i-1].str != NULL; i++) {
- if (ipmi_dcmi_prnt_getcapabilities(intf, i) < 0) {
- lprintf(LOG_ERR,"Error discovering %s capabilities!\n",
- val2str2(i, dcmi_capable_vals));
- return -1;
- }
- }
- break;
- case 0x01:
- /* power */
- argv++;
- if (argv[0] == NULL) {
- print_strs(dcmi_pwrmgmt_vals, "power <command>",
- LOG_ERR, 0);
- return -1;
- }
- rc = ipmi_dcmi_parse_power(intf, argc, argv);
- break;
- /* end power command */
- case 0x02:
- /* sensor print */
- /* Look for each item in the dcmi_discvry_snsr_vals struct
- * and if it exists, print the sdr record id(s) for it.
- * Use the val from each one as the sensor number.
- */
- for (i = 0; dcmi_discvry_snsr_vals[i].str != NULL; i++) {
- /* get all of the information about this sensor */
- rc = ipmi_dcmi_prnt_discvry_snsr(intf,
- dcmi_discvry_snsr_vals[i].val);
- }
- break;
- /* end sensor print */
- case 0x03:
- /* asset tag */
- if(ipmi_dcmi_prnt_getassettag(intf) < 0) {
- lprintf(LOG_ERR, "Error getting asset tag!");
- return -1;
- }
- break;
- /* end asset tag */
- case 0x04:
- {
- /* set asset tag */
- if (argc == 1 ) {
- print_strs(dcmi_cmd_vals,
- "Data Center Management Interface commands",
- LOG_ERR, 0);
- return -1;
- }
- if (ipmi_dcmi_prnt_setassettag(intf, (uint8_t *)argv[1]) < 0) {
- lprintf(LOG_ERR, "\nError setting asset tag!");
- return -1;
- }
- break;
- }
- /* end set asset tag */
- case 0x05:
- /* get management controller identifier string */
- if (ipmi_dcmi_prnt_getmngctrlids(intf) < 0) {
- lprintf(LOG_ERR,
- "Error getting management controller identifier string!");
- return -1;
- }
- break;
- /* end get management controller identifier string */
- case 0x06:
- {
- /* set management controller identifier string */
- if (argc == 1 ) {
- print_strs(dcmi_cmd_vals,
- "Data Center Management Interface commands",
- LOG_ERR, 0);
- return -1;
- }
- if (ipmi_dcmi_prnt_setmngctrlids(intf, (uint8_t *)argv[1]) < 0) {
- lprintf(LOG_ERR,
- "Error setting management controller identifier string!");
- return -1;
- }
- break;
- }
- /* end set management controller identifier string */
- case 0x07:
- /* get/set thermal policy */
- rc = ipmi_dcmi_thermalpolicy(intf, argc, argv);
- break;
- case 0x08:
- if(ipmi_dcmi_prnt_get_temp_readings(intf) < 0 ) {
- lprintf(LOG_ERR,
- "Error get temperature readings!");
- return -1;
- }
- break;
- case 0x09:
- if(ipmi_dcmi_prnt_getconfparam(intf) < 0 ) {
- lprintf(LOG_ERR,
- "Error Get DCMI Configuration Parameters!");
- return -1;
- };
- break;
- case 0x0A:
- {
- switch (argc) {
- case 2:
- if (strncmp(argv[1], "activate_dhcp", 13) != 0) {
- print_strs( dcmi_conf_param_vals,
- "DCMI Configuration Parameters",
- LOG_ERR, 0);
- return -1;
- }
- break;
- default:
- if (argc != 3 || strncmp(argv[1], "help", 4) == 0) {
- print_strs(dcmi_conf_param_vals,
- "DCMI Configuration Parameters",
- LOG_ERR, 0);
- return -1;
- }
- }
- if (strncmp(argv[1], "activate_dhcp", 13) == 0) {
- rsp = ipmi_dcmi_setconfparam(intf, 1, 1);
- } else {
- uint16_t tmp_val = 0;
- if (str2ushort(argv[2], &tmp_val) != 0) {
- lprintf(LOG_ERR,
- "Given %s '%s' is invalid.",
- argv[1], argv[2]);
- return (-1);
- }
- rsp = ipmi_dcmi_setconfparam(intf,
- str2val2(argv[1], dcmi_conf_param_vals),
- tmp_val);
- }
- if (chk_rsp(rsp)) {
- lprintf(LOG_ERR,
- "Error Set DCMI Configuration Parameters!");
- }
- break;
- }
- case 0x0B:
- {
- if (intf->session == NULL) {
- lprintf(LOG_ERR,
- "\nOOB discovery is available only via RMCP interface.");
- return -1;
- }
- if(ipmi_dcmi_prnt_oobDiscover(intf) < 0) {
- lprintf(LOG_ERR, "\nOOB discovering capabilities failed.");
- return -1;
- }
- break;
- }
- default:
- /* couldn't detect what the user entered */
- print_strs(dcmi_cmd_vals,
- "Data Center Management Interface commands",
- LOG_ERR, 0);
- return -1;
- break;
- }
- printf("\n");
- return rc;
- }
- /* Node Manager main
- *
- * @intf: nm interface handler
- * @argc: argument count
- * @argv: argument vector
- */
- int
- ipmi_nm_main(struct ipmi_intf * intf, int argc, char **argv)
- {
- struct nm_discover disc;
- if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0)) {
- print_strs(nm_cmd_vals,
- "Node Manager Interface commands",
- LOG_ERR, 0);
- return -1;
- }
- switch (str2val2(argv[0], nm_cmd_vals)) {
- /* discover */
- case 0x00:
- if (_ipmi_nm_discover(intf, &disc))
- return -1;
- printf(" Node Manager Version %s\n", val2str2(disc.nm_version, nm_version_vals));
- printf(" revision %d.%d%d patch version %d\n", disc.major_rev,
- disc.minor_rev>>4, disc.minor_rev&0xf, disc.patch_version);
- break;
- /* capability */
- case 0x01:
- if (ipmi_nm_getcapabilities(intf, argc, argv))
- return -1;
- break;
- /* policy control enable-disable */
- case 0x02:
- if (ipmi_nm_control(intf, argc, argv))
- return -1;
- break;
- /* policy */
- case 0x03:
- if (ipmi_nm_policy(intf, argc, argv))
- return -1;
- break;
- /* Get statistics */
- case 0x04:
- if (ipmi_nm_get_statistics(intf, argc, argv))
- return -1;
- break;
- /* set power draw range */
- case 0x05:
- if (ipmi_nm_set_range(intf, argc, argv))
- return -1;
- break;
- /* set/get suspend periods */
- case 0x06:
- if (ipmi_nm_suspend(intf, argc, argv))
- return -1;
- break;
- /* reset statistics */
- case 0x07:
- if (ipmi_nm_reset_statistics(intf, argc, argv))
- return -1;
- break;
- /* set/get alert destination */
- case 0x08:
- if (ipmi_nm_alert(intf, argc, argv))
- return -1;
- break;
- /* set/get alert thresholds */
- case 0x09:
- if (ipmi_nm_thresh(intf, argc, argv))
- return -1;
- break;
- default:
- print_strs(nm_cmd_vals, "Node Manager Interface commands", LOG_ERR, 0);
- break;
- }
- return 0;
- }
- /* Display DCMI sensor information
- * Uses the ipmi_sdr_get_next_header to read SDR header and compare to the
- * target Record ID. Then either ipmi_sensor_print_full or
- * ipmi_sensor_print_compact is called to print the data
- *
- * @intf: ipmi interface handler
- * @rec_id: target Record ID
- */
- static int
- ipmi_print_sensor_info(struct ipmi_intf *intf, uint16_t rec_id)
- {
- struct sdr_get_rs *header;
- struct ipmi_sdr_iterator *itr;
- int rc = 0;
- uint8_t *rec = NULL;
- itr = ipmi_sdr_start(intf, 0);
- if (itr == NULL) {
- lprintf(LOG_ERR, "Unable to open SDR for reading");
- return (-1);
- }
- while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
- if (header->id == rec_id) {
- break;
- }
- }
- if (header == NULL) {
- lprintf(LOG_DEBUG, "header == NULL");
- ipmi_sdr_end(intf, itr);
- return (-1);
- }
- /* yes, we found the SDR for this record ID, now get full record */
- rec = ipmi_sdr_get_record(intf, header, itr);
- if (rec == NULL) {
- lprintf(LOG_DEBUG, "rec == NULL");
- ipmi_sdr_end(intf, itr);
- return (-1);
- }
- if ((header->type == SDR_RECORD_TYPE_FULL_SENSOR) ||
- (header->type == SDR_RECORD_TYPE_COMPACT_SENSOR)) {
- rc = ipmi_sdr_print_rawentry(intf, header->type,
- rec, header->length);
- } else {
- rc = (-1);
- }
- free(rec);
- rec = NULL;
- ipmi_sdr_end(intf, itr);
- return rc;
- }
|