123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389 |
- /*
- * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistribution in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind.
- * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
- * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
- * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
- * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
- * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
- * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
- * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
- * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
- * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- */
- #define _SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE >= 1 || \
- _XOPEN_SOURCE || _POSIX_SOURCE
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <time.h>
- #include <ipmitool/bswap.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_chassis.h>
- extern int verbose;
- int
- ipmi_chassis_power_status(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_CHASSIS;
- req.msg.cmd = 0x1;
- req.msg.data_len = 0;
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Unable to get Chassis Power Status");
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Get Chassis Power Status failed: %s",
- val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
- return rsp->data[0] & 1;
- }
- static int
- ipmi_chassis_print_power_status(struct ipmi_intf * intf)
- {
- int ps = ipmi_chassis_power_status(intf);
- if (ps < 0)
- return -1;
- printf("Chassis Power is %s\n", ps ? "on" : "off");
- return 0;
- }
- int
- ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_CHASSIS;
- req.msg.cmd = 0x2;
- req.msg.data = &ctl;
- req.msg.data_len = 1;
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Unable to set Chassis Power Control to %s",
- val2str(ctl, ipmi_chassis_power_control_vals));
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Set Chassis Power Control to %s failed: %s",
- val2str(ctl, ipmi_chassis_power_control_vals),
- val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
- printf("Chassis Power Control: %s\n",
- val2str(ctl, ipmi_chassis_power_control_vals));
- return 0;
- }
- static int
- ipmi_chassis_identify(struct ipmi_intf * intf, char * arg)
- {
- struct ipmi_rq req;
- struct ipmi_rs * rsp;
- int rc = (-3);
- struct {
- uint8_t interval;
- uint8_t force_on;
- } identify_data = { .interval = 0, .force_on = 0 };
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_CHASSIS;
- req.msg.cmd = 0x4;
- if (arg != NULL) {
- if (strncmp(arg, "force", 5) == 0) {
- identify_data.force_on = 1;
- } else {
- if ( (rc = str2uchar(arg, &identify_data.interval)) != 0) {
- if (rc == (-2)) {
- lprintf(LOG_ERR, "Invalid interval given.");
- } else {
- lprintf(LOG_ERR, "Given interval is too big.");
- }
- return (-1);
- }
- }
- req.msg.data = (uint8_t *)&identify_data;
- /* The Force Identify On byte is optional and not
- * supported by all devices-- if force is not specified,
- * we pass only one data byte; if specified, we pass two
- * data bytes and check for an error completion code
- */
- req.msg.data_len = (identify_data.force_on) ? 2 : 1;
- }
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Unable to set Chassis Identify");
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Set Chassis Identify failed: %s",
- val2str(rsp->ccode, completion_code_vals));
- if (identify_data.force_on != 0) {
- /* Intel SE7501WV2 F/W 1.2 returns CC 0xC7, but
- * the IPMI v1.5 spec does not standardize a CC
- * if unsupported, so we warn
- */
- lprintf(LOG_WARNING, "Chassis may not support Force Identify On\n");
- }
- return -1;
- }
- printf("Chassis identify interval: ");
- if (arg == NULL) {
- printf("default (15 seconds)\n");
- } else {
- if (identify_data.force_on != 0) {
- printf("indefinite\n");
- } else {
- if (identify_data.interval == 0)
- printf("off\n");
- else
- printf("%i seconds\n", identify_data.interval);
- }
- }
- return 0;
- }
- static int
- ipmi_chassis_poh(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- uint8_t mins_per_count;
- uint32_t count;
- float minutes;
- uint32_t days, hours;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_CHASSIS;
- req.msg.cmd = 0xf;
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Unable to get Chassis Power-On-Hours");
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Get Chassis Power-On-Hours failed: %s",
- val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
- mins_per_count = rsp->data[0];
- memcpy(&count, rsp->data+1, 4);
- #if WORDS_BIGENDIAN
- count = BSWAP_32(count);
- #endif
- minutes = (float)count * mins_per_count;
- days = minutes / 1440;
- minutes -= (float)days * 1440;
- hours = minutes / 60;
- minutes -= hours * 60;
- if (mins_per_count < 60) {
- printf("POH Counter : %i days, %i hours, %li minutes\n",
- days, hours, (long)minutes);
- } else {
- printf("POH Counter : %i days, %i hours\n", days, hours);
- }
- return 0;
- }
- static int
- ipmi_chassis_restart_cause(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_CHASSIS;
- req.msg.cmd = 0x7;
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Unable to get Chassis Restart Cause");
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Get Chassis Restart Cause failed: %s",
- val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
- printf("System restart cause: ");
- switch (rsp->data[0] & 0xf) {
- case 0:
- printf("unknown\n");
- break;
- case 1:
- printf("chassis power control command\n");
- break;
- case 2:
- printf("reset via pushbutton\n");
- break;
- case 3:
- printf("power-up via pushbutton\n");
- break;
- case 4:
- printf("watchdog expired\n");
- break;
- case 5:
- printf("OEM\n");
- break;
- case 6:
- printf("power-up due to always-restore power policy\n");
- break;
- case 7:
- printf("power-up due to restore-previous power policy\n");
- break;
- case 8:
- printf("reset via PEF\n");
- break;
- case 9:
- printf("power-cycle via PEF\n");
- break;
- default:
- printf("invalid\n");
- }
- return 0;
- }
- int
- ipmi_chassis_status(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_CHASSIS;
- req.msg.cmd = 0x1;
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Error sending Chassis Status command");
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Error sending Chassis Status command: %s",
- val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
- /* byte 1 */
- printf("System Power : %s\n", (rsp->data[0] & 0x1) ? "on" : "off");
- printf("Power Overload : %s\n", (rsp->data[0] & 0x2) ? "true" : "false");
- printf("Power Interlock : %s\n", (rsp->data[0] & 0x4) ? "active" : "inactive");
- printf("Main Power Fault : %s\n", (rsp->data[0] & 0x8) ? "true" : "false");
- printf("Power Control Fault : %s\n", (rsp->data[0] & 0x10) ? "true" : "false");
- printf("Power Restore Policy : ");
- switch ((rsp->data[0] & 0x60) >> 5) {
- case 0x0:
- printf("always-off\n");
- break;
- case 0x1:
- printf("previous\n");
- break;
- case 0x2:
- printf("always-on\n");
- break;
- case 0x3:
- default:
- printf("unknown\n");
- }
- /* byte 2 */
- printf("Last Power Event : ");
- if (rsp->data[1] & 0x1)
- printf("ac-failed ");
- if (rsp->data[1] & 0x2)
- printf("overload ");
- if (rsp->data[1] & 0x4)
- printf("interlock ");
- if (rsp->data[1] & 0x8)
- printf("fault ");
- if (rsp->data[1] & 0x10)
- printf("command");
- printf("\n");
- /* byte 3 */
- printf("Chassis Intrusion : %s\n", (rsp->data[2] & 0x1) ? "active" : "inactive");
- printf("Front-Panel Lockout : %s\n", (rsp->data[2] & 0x2) ? "active" : "inactive");
- printf("Drive Fault : %s\n", (rsp->data[2] & 0x4) ? "true" : "false");
- printf("Cooling/Fan Fault : %s\n", (rsp->data[2] & 0x8) ? "true" : "false");
- if (rsp->data_len > 3) {
- /* optional byte 4 */
- if (rsp->data[3] == 0) {
- printf("Front Panel Control : none\n");
- } else {
- printf("Sleep Button Disable : %s\n", (rsp->data[3] & 0x80) ? "allowed" : "not allowed");
- printf("Diag Button Disable : %s\n", (rsp->data[3] & 0x40) ? "allowed" : "not allowed");
- printf("Reset Button Disable : %s\n", (rsp->data[3] & 0x20) ? "allowed" : "not allowed");
- printf("Power Button Disable : %s\n", (rsp->data[3] & 0x10) ? "allowed" : "not allowed");
- printf("Sleep Button Disabled: %s\n", (rsp->data[3] & 0x08) ? "true" : "false");
- printf("Diag Button Disabled : %s\n", (rsp->data[3] & 0x04) ? "true" : "false");
- printf("Reset Button Disabled: %s\n", (rsp->data[3] & 0x02) ? "true" : "false");
- printf("Power Button Disabled: %s\n", (rsp->data[3] & 0x01) ? "true" : "false");
- }
- }
- return 0;
- }
- static int
- ipmi_chassis_selftest(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_APP;
- req.msg.cmd = 0x4;
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Error sending Get Self Test command");
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Error sending Get Self Test command: %s",
- val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
- printf("Self Test Results : ");
- switch (rsp->data[0]) {
- case 0x55:
- printf("passed\n");
- break;
- case 0x56:
- printf("not implemented\n");
- break;
- case 0x57:
- {
- int i;
- const struct valstr broken_dev_vals[] = {
- { 0, "firmware corrupted" },
- { 1, "boot block corrupted" },
- { 2, "FRU Internal Use Area corrupted" },
- { 3, "SDR Repository empty" },
- { 4, "IPMB not responding" },
- { 5, "cannot access BMC FRU" },
- { 6, "cannot access SDR Repository" },
- { 7, "cannot access SEL Device" },
- { 0xff, NULL },
- };
- printf("device error\n");
- for (i=0; i<8; i++) {
- if (rsp->data[1] & (1<<i)) {
- printf(" [%s]\n",
- val2str(i, broken_dev_vals));
- }
- }
- }
- break;
- case 0x58:
- printf("Fatal hardware error: %02xh\n", rsp->data[1]);
- break;
- default:
- printf("Device-specific failure %02xh:%02xh\n",
- rsp->data[0], rsp->data[1]);
- break;
- }
- return 0;
- }
- static int
- ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * data, int len)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- uint8_t msg_data[16];
- memset(msg_data, 0, 16);
- msg_data[0] = param & 0x7f;
- memcpy(msg_data+1, data, len);
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_CHASSIS;
- req.msg.cmd = 0x8;
- req.msg.data = msg_data;
- req.msg.data_len = len + 1;
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Error setting Chassis Boot Parameter %d", param);
- return -1;
- }
- if (rsp->ccode > 0) {
- if (param != 0) {
- lprintf(LOG_ERR, "Set Chassis Boot Parameter %d failed: %s",
- param, val2str(rsp->ccode, completion_code_vals));
- }
- return -1;
- }
- lprintf(LOG_DEBUG, "Chassis Set Boot Parameter %d to %s", param, buf2str(data, len));
- return 0;
- }
- static int
- ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- uint8_t msg_data[3];
- uint8_t param_id = 0;
- if (arg == NULL)
- return -1;
- if (str2uchar(arg, ¶m_id) != 0) {
- lprintf(LOG_ERR, "Invalid parameter '%s' given instead of bootparam.",
- arg);
- return (-1);
- }
- memset(msg_data, 0, 3);
- msg_data[0] = param_id & 0x7f;
- msg_data[1] = 0;
- msg_data[2] = 0;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_CHASSIS;
- req.msg.cmd = 0x9;
- req.msg.data = msg_data;
- req.msg.data_len = 3;
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Error Getting Chassis Boot Parameter %s", arg);
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Get Chassis Boot Parameter %s failed: %s",
- arg, val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
- if (verbose > 2)
- printbuf(rsp->data, rsp->data_len, "Boot Option");
- param_id = 0;
- param_id = (rsp->data[1] & 0x7f);
- printf("Boot parameter version: %d\n", rsp->data[0]);
- printf("Boot parameter %d is %s\n", rsp->data[1] & 0x7f,
- (rsp->data[1] & 0x80) ? "invalid/locked" : "valid/unlocked");
- printf("Boot parameter data: %s\n", buf2str(rsp->data+2, rsp->data_len - 2));
- switch(param_id)
- {
- case 0:
- {
- printf(" Set In Progress : ");
- switch((rsp->data[2]) &0x03)
- {
- case 0: printf("set complete\n"); break;
- case 1: printf("set in progress\n"); break;
- case 2: printf("commit write\n"); break;
- default: printf("error, reserved bit\n"); break;
- }
- }
- break;
- case 1:
- {
- printf(" Service Partition Selector : ");
- if((rsp->data[2]) == 0)
- {
- printf("unspecified\n");
- }
- else
- {
- printf("%d\n",(rsp->data[2]));
- }
- }
- break;
- case 2:
- {
- printf( " Service Partition Scan :\n");
- if((rsp->data[2]&0x03) != 0)
- {
- if((rsp->data[2]&0x01) == 0x01)
- printf(" - Request BIOS to scan\n");
- if((rsp->data[2]&0x02) == 0x02)
- printf(" - Service Partition Discovered\n");
- }
- else
- {
- printf(" No flag set\n");
- }
- }
- break;
- case 3:
- {
- printf( " BMC boot flag valid bit clearing :\n");
- if((rsp->data[2]&0x1f) != 0)
- {
- if((rsp->data[2]&0x10) == 0x10)
- printf(" - Don't clear valid bit on reset/power cycle cause by PEF\n");
- if((rsp->data[2]&0x08) == 0x08)
- printf(" - Don't automatically clear boot flag valid bit on timeout\n");
- if((rsp->data[2]&0x04) == 0x04)
- printf(" - Don't clear valid bit on reset/power cycle cause by watchdog\n");
- if((rsp->data[2]&0x02) == 0x02)
- printf(" - Don't clear valid bit on push button reset // soft reset\n");
- if((rsp->data[2]&0x01) == 0x01)
- printf(" - Don't clear valid bit on power up via power push button or wake event\n");
- }
- else
- {
- printf(" No flag set\n");
- }
- }
- break;
- case 4:
- {
- printf( " Boot Info Acknowledge :\n");
- if((rsp->data[3]&0x1f) != 0)
- {
- if((rsp->data[3]&0x10) == 0x10)
- printf(" - OEM has handled boot info\n");
- if((rsp->data[3]&0x08) == 0x08)
- printf(" - SMS has handled boot info\n");
- if((rsp->data[3]&0x04) == 0x04)
- printf(" - OS // service partition has handled boot info\n");
- if((rsp->data[3]&0x02) == 0x02)
- printf(" - OS Loader has handled boot info\n");
- if((rsp->data[3]&0x01) == 0x01)
- printf(" - BIOS/POST has handled boot info\n");
- }
- else
- {
- printf(" No flag set\n");
- }
- }
- break;
- case 5:
- {
- printf( " Boot Flags :\n");
- if((rsp->data[2]&0x80) == 0x80)
- printf(" - Boot Flag Valid\n");
- else
- printf(" - Boot Flag Invalid\n");
- if((rsp->data[2]&0x40) == 0x40)
- printf(" - Options apply to all future boots\n");
- else
- printf(" - Options apply to only next boot\n");
- if((rsp->data[2]&0x20) == 0x20)
- printf(" - BIOS EFI boot \n");
- else
- printf(" - BIOS PC Compatible (legacy) boot \n");
- if((rsp->data[3]&0x80) == 0x80)
- printf(" - CMOS Clear\n");
- if((rsp->data[3]&0x40) == 0x40)
- printf(" - Lock Keyboard\n");
- printf(" - Boot Device Selector : ");
- switch( ((rsp->data[3]>>2)&0x0f))
- {
- case 0: printf("No override\n"); break;
- case 1: printf("Force PXE\n"); break;
- case 2: printf("Force Boot from default Hard-Drive\n"); break;
- case 3: printf("Force Boot from default Hard-Drive, request Safe-Mode\n"); break;
- case 4: printf("Force Boot from Diagnostic Partition\n"); break;
- case 5: printf("Force Boot from CD/DVD\n"); break;
- case 6: printf("Force Boot into BIOS Setup\n"); break;
- case 15: printf("Force Boot from Floppy/primary removable media\n"); break;
- default: printf("Flag error\n"); break;
- }
- if((rsp->data[3]&0x02) == 0x02)
- printf(" - Screen blank\n");
- if((rsp->data[3]&0x01) == 0x01)
- printf(" - Lock out Reset buttons\n");
- if((rsp->data[4]&0x80) == 0x80)
- printf(" - Lock out (power off/sleep request) vi Power Button\n");
- printf(" - Console Redirection control : ");
- switch( ((rsp->data[4]>>5)&0x03))
- {
- case 0: printf("System Default\n"); break;
- case 1: printf("Request Quiet Display\n"); break;
- case 2: printf("Request Verbose Display\n"); break;
- default: printf("Flag error\n"); break;
- }
- if((rsp->data[4]&0x10) == 0x10)
- printf(" - Force progress event traps\n");
- if((rsp->data[4]&0x08) == 0x08)
- printf(" - User password bypass\n");
- if((rsp->data[4]&0x04) == 0x04)
- printf(" - Lock Out Sleep Button\n");
- if((rsp->data[4]&0x02) == 0x02)
- printf(" - Lock Out Sleep Button\n");
- printf(" - BIOS verbosity : ");
- switch( ((rsp->data[4]>>0)&0x03))
- {
- case 0: printf("Console redirection occurs per BIOS configuration setting (default)\n"); break;
- case 1: printf("Suppress (skip) console redirection if enabled\n"); break;
- case 2: printf("Request console redirection be enabled\n"); break;
- default: printf("Flag error\n"); break;
- }
- if((rsp->data[5]&0x08) == 0x08)
- printf(" - BIOS Shared Mode Override\n");
- printf(" - BIOS Mux Control Override : ");
- switch( ((rsp->data[5]>>0)&0x07))
- {
- case 0: printf("BIOS uses recommended setting of the mux at the end of POST\n"); break;
- case 1: printf("Requests BIOS to force mux to BMC at conclusion of POST/start of OS boot\n"); break;
- case 2: printf("Requests BIOS to force mux to system at conclusion of POST/start of OS boot\n"); break;
- default: printf("Flag error\n"); break;
- }
- }
- break;
- case 6:
- {
- unsigned long session_id;
- unsigned long timestamp;
- char time_buf[40];
- time_t out_time;
- session_id = ((unsigned long) rsp->data[3]);
- session_id |= (((unsigned long) rsp->data[4])<<8);
- session_id |= (((unsigned long) rsp->data[5])<<16);
- session_id |= (((unsigned long) rsp->data[6])<<24);
- timestamp = ((unsigned long) rsp->data[7]);
- timestamp |= (((unsigned long) rsp->data[8])<<8);
- timestamp |= (((unsigned long) rsp->data[9])<<16);
- timestamp |= (((unsigned long) rsp->data[10])<<24);
- memset(time_buf, 0, 40);
- strftime(
- time_buf,
- sizeof(time_buf),
- "%m/%d/%Y %H:%M:%S", localtime(&out_time)
- );
- printf(" Boot Initiator Info :\n");
- printf(" Channel Number : %d\n", (rsp->data[2] & 0x0f));
- printf(" Session Id : %08lXh\n",session_id);
- if(timestamp != 0)
- {
- printf(" Timestamp : %08lXh, %s\n",timestamp,time_buf);
- }
- else
- {
- printf(" Timestamp : %08lXh, undefined\n",timestamp);
- }
- }
- break;
- case 7:
- {
- printf(" Selector : %d\n", rsp->data[2] );
- printf(" Block Data : %s\n", buf2str(rsp->data+3, rsp->data_len - 2));
- }
- break;
- default:
- printf(" Undefined byte\n");
- break;
- }
- return 0;
- }
- static int
- get_bootparam_options(char *optstring,
- unsigned char *set_flag, unsigned char *clr_flag)
- {
- char *token;
- char *saveptr = NULL;
- int optionError = 0;
- *set_flag = 0;
- *clr_flag = 0;
- static struct {
- char *name;
- unsigned char value;
- char *desc;
- } options[] = {
- {"PEF", 0x10,
- "Clear valid bit on reset/power cycle cause by PEF"},
- {"timeout", 0x08,
- "Automatically clear boot flag valid bit on timeout"},
- {"watchdog", 0x04,
- "Clear valid bit on reset/power cycle cause by watchdog"},
- {"reset", 0x02,
- "Clear valid bit on push button reset/soft reset"},
- {"power", 0x01,
- "Clear valid bit on power up via power push button or wake event"},
- {NULL} /* End marker */
- }, *op;
- if (strncmp(optstring, "options=", 8) != 0) {
- lprintf(LOG_ERR, "No options= keyword found \"%s\"", optstring);
- return -1;
- }
- token = strtok_r(optstring + 8, ",", &saveptr);
- while (token != NULL) {
- int setbit = 0;
- if (strcmp(token, "help") == 0) {
- optionError = 1;
- break;
- }
- if (strncmp(token, "no-", 3) == 0) {
- setbit = 1;
- token += 3;
- }
- for (op = options; op->name != NULL; ++op) {
- if (strncmp(token, op->name, strlen(op->name)) == 0) {
- if (setbit) {
- *set_flag |= op->value;
- } else {
- *clr_flag |= op->value;
- }
- break;
- }
- }
- if (op->name == NULL) {
- /* Option not found */
- optionError = 1;
- if (setbit) {
- token -=3;
- }
- lprintf(LOG_ERR, "Invalid option: %s", token);
- }
- token = strtok_r(NULL, ",", &saveptr);
- }
- if (optionError) {
- lprintf(LOG_NOTICE, " Legal options are:");
- lprintf(LOG_NOTICE, " %-8s: print this message", "help");
- for (op = options; op->name != NULL; ++op) {
- lprintf(LOG_NOTICE, " %-8s: %s", op->name, op->desc);
- }
- lprintf(LOG_NOTICE, " Any Option may be prepended with no-"
- " to invert sense of operation\n");
- return (-1);
- }
- return (0);
- }
- static int
- ipmi_chassis_get_bootvalid(struct ipmi_intf * intf)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- uint8_t msg_data[3];
- uint8_t param_id = IPMI_CHASSIS_BOOTPARAM_FLAG_VALID;
- memset(msg_data, 0, 3);
- msg_data[0] = param_id & 0x7f;
- msg_data[1] = 0;
- msg_data[2] = 0;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_CHASSIS;
- req.msg.cmd = 0x9;
- req.msg.data = msg_data;
- req.msg.data_len = 3;
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR,
- "Error Getting Chassis Boot Parameter %d", param_id);
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Get Chassis Boot Parameter %d failed: %s",
- param_id, val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
- if (verbose > 2)
- printbuf(rsp->data, rsp->data_len, "Boot Option");
- return(rsp->data[2]);
- }
- static int
- ipmi_chassis_set_bootvalid(struct ipmi_intf *intf, uint8_t set_flag, uint8_t clr_flag)
- {
- int bootvalid;
- uint8_t flags[5];
- int rc = 0;
- int use_progress = 1;
- uint8_t param_id = IPMI_CHASSIS_BOOTPARAM_FLAG_VALID;
- if (use_progress) {
- /* set set-in-progress flag */
- memset(flags, 0, 5);
- flags[0] = 0x01;
- rc = ipmi_chassis_set_bootparam(intf,
- IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS, flags, 1);
- if (rc < 0)
- use_progress = 0;
- }
- memset(flags, 0, 5);
- flags[0] = 0x01;
- flags[1] = 0x01;
- rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_INFO_ACK,
- flags, 2);
- if (rc < 0) {
- if (use_progress) {
- /* set-in-progress = set-complete */
- memset(flags, 0, 5);
- ipmi_chassis_set_bootparam(intf,
- IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
- flags, 1);
- }
- return -1;
- }
- bootvalid = ipmi_chassis_get_bootvalid(intf);
- if (bootvalid < 0) {
- if (use_progress) {
- /* set-in-progress = set-complete */
- memset(flags, 0, 5);
- ipmi_chassis_set_bootparam(intf,
- IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
- flags, 1);
- }
- return -1;
- }
- flags[0] = (bootvalid & ~clr_flag) | set_flag;
- rc = ipmi_chassis_set_bootparam(intf, param_id, flags, 1);
- if (rc == 0) {
- if (use_progress) {
- /* set-in-progress = commit-write */
- memset(flags, 0, 5);
- flags[0] = 0x02;
- ipmi_chassis_set_bootparam(intf,
- IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
- flags, 1);
- }
- }
- if (use_progress) {
- /* set-in-progress = set-complete */
- memset(flags, 0, 5);
- ipmi_chassis_set_bootparam(intf,
- IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
- flags, 1);
- }
- return rc;
- }
- static int
- ipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg, uint8_t *iflags)
- {
- uint8_t flags[5];
- int rc = 0;
- int use_progress = 1;
- if (use_progress) {
- /* set set-in-progress flag */
- memset(flags, 0, 5);
- flags[0] = 0x01;
- rc = ipmi_chassis_set_bootparam(intf,
- IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS, flags, 1);
- if (rc < 0)
- use_progress = 0;
- }
- memset(flags, 0, 5);
- flags[0] = 0x01;
- flags[1] = 0x01;
- rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_INFO_ACK,
- flags, 2);
- if (rc < 0) {
- if (use_progress) {
- /* set-in-progress = set-complete */
- memset(flags, 0, 5);
- ipmi_chassis_set_bootparam(intf,
- IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
- flags, 1);
- }
- return -1;
- }
- if (iflags == NULL)
- memset(flags, 0, 5);
- else
- memcpy(flags, iflags, sizeof (flags));
- if (arg == NULL)
- flags[1] |= 0x00;
- else if (strncmp(arg, "none", 4) == 0)
- flags[1] |= 0x00;
- else if (strncmp(arg, "pxe", 3) == 0 ||
- strncmp(arg, "force_pxe", 9) == 0)
- flags[1] |= 0x04;
- else if (strncmp(arg, "disk", 4) == 0 ||
- strncmp(arg, "force_disk", 10) == 0)
- flags[1] |= 0x08;
- else if (strncmp(arg, "safe", 4) == 0 ||
- strncmp(arg, "force_safe", 10) == 0)
- flags[1] |= 0x0c;
- else if (strncmp(arg, "diag", 4) == 0 ||
- strncmp(arg, "force_diag", 10) == 0)
- flags[1] |= 0x10;
- else if (strncmp(arg, "cdrom", 5) == 0 ||
- strncmp(arg, "force_cdrom", 11) == 0)
- flags[1] |= 0x14;
- else if (strncmp(arg, "floppy", 6) == 0 ||
- strncmp(arg, "force_floppy", 12) == 0)
- flags[1] |= 0x3c;
- else if (strncmp(arg, "bios", 4) == 0 ||
- strncmp(arg, "force_bios", 10) == 0)
- flags[1] |= 0x18;
- else {
- lprintf(LOG_ERR, "Invalid argument: %s", arg);
- if (use_progress) {
- /* set-in-progress = set-complete */
- memset(flags, 0, 5);
- ipmi_chassis_set_bootparam(intf,
- IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
- flags, 1);
- }
- return -1;
- }
- /* set flag valid bit */
- flags[0] |= 0x80;
- rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_BOOT_FLAGS,
- flags, 5);
- if (rc == 0) {
- if (use_progress) {
- /* set-in-progress = commit-write */
- memset(flags, 0, 5);
- flags[0] = 0x02;
- ipmi_chassis_set_bootparam(intf,
- IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
- flags, 1);
- }
- printf("Set Boot Device to %s\n", arg);
- }
- if (use_progress) {
- /* set-in-progress = set-complete */
- memset(flags, 0, 5);
- ipmi_chassis_set_bootparam(intf,
- IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
- flags, 1);
- }
- return rc;
- }
- static int
- ipmi_chassis_power_policy(struct ipmi_intf * intf, uint8_t policy)
- {
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_CHASSIS;
- req.msg.cmd = 0x6;
- req.msg.data = &policy;
- req.msg.data_len = 1;
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Error in Power Restore Policy command");
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Power Restore Policy command failed: %s",
- val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
- if (policy == IPMI_CHASSIS_POLICY_NO_CHANGE) {
- printf("Supported chassis power policy: ");
- if (rsp->data[0] & (1<<IPMI_CHASSIS_POLICY_ALWAYS_OFF))
- printf("always-off ");
- if (rsp->data[0] & (1<<IPMI_CHASSIS_POLICY_ALWAYS_ON))
- printf("always-on ");
- if (rsp->data[0] & (1<<IPMI_CHASSIS_POLICY_PREVIOUS))
- printf("previous");
- printf("\n");
- }
- else {
- printf("Set chassis power restore policy to ");
- switch (policy) {
- case IPMI_CHASSIS_POLICY_ALWAYS_ON:
- printf("always-on\n");
- break;
- case IPMI_CHASSIS_POLICY_ALWAYS_OFF:
- printf("always-off\n");
- break;
- case IPMI_CHASSIS_POLICY_PREVIOUS:
- printf("previous\n");
- break;
- default:
- printf("unknown\n");
- }
- }
- return 0;
- }
- int
- ipmi_power_main(struct ipmi_intf * intf, int argc, char ** argv)
- {
- int rc = 0;
- uint8_t ctl = 0;
- if ((argc < 1) || (strncmp(argv[0], "help", 4) == 0)) {
- lprintf(LOG_NOTICE, "chassis power Commands: status, on, off, cycle, reset, diag, soft");
- return 0;
- }
- if (strncmp(argv[0], "status", 6) == 0) {
- rc = ipmi_chassis_print_power_status(intf);
- return rc;
- }
- if ((strncmp(argv[0], "up", 2) == 0) || (strncmp(argv[0], "on", 2) == 0))
- ctl = IPMI_CHASSIS_CTL_POWER_UP;
- else if ((strncmp(argv[0], "down", 4) == 0) || (strncmp(argv[0], "off", 3) == 0))
- ctl = IPMI_CHASSIS_CTL_POWER_DOWN;
- else if (strncmp(argv[0], "cycle", 5) == 0)
- ctl = IPMI_CHASSIS_CTL_POWER_CYCLE;
- else if (strncmp(argv[0], "reset", 5) == 0)
- ctl = IPMI_CHASSIS_CTL_HARD_RESET;
- else if (strncmp(argv[0], "diag", 4) == 0)
- ctl = IPMI_CHASSIS_CTL_PULSE_DIAG;
- else if ((strncmp(argv[0], "acpi", 4) == 0) || (strncmp(argv[0], "soft", 4) == 0))
- ctl = IPMI_CHASSIS_CTL_ACPI_SOFT;
- else {
- lprintf(LOG_ERR, "Invalid chassis power command: %s", argv[0]);
- return -1;
- }
- rc = ipmi_chassis_power_control(intf, ctl);
- return rc;
- }
- void
- ipmi_chassis_set_bootflag_help()
- {
- unsigned char set_flag;
- unsigned char clr_flag;
- lprintf(LOG_NOTICE, "bootparam set bootflag <device> [options=...]");
- lprintf(LOG_NOTICE, " Legal devices are:");
- lprintf(LOG_NOTICE, " none : No override");
- lprintf(LOG_NOTICE, " force_pxe : Force PXE boot");
- lprintf(LOG_NOTICE, " force_disk : Force boot from default Hard-drive");
- lprintf(LOG_NOTICE, " force_safe : Force boot from default Hard-drive, request Safe Mode");
- lprintf(LOG_NOTICE, " force_diag : Force boot from Diagnostic Partition");
- lprintf(LOG_NOTICE, " force_cdrom : Force boot from CD/DVD");
- lprintf(LOG_NOTICE, " force_bios : Force boot into BIOS Setup");
- get_bootparam_options("options=help", &set_flag, &clr_flag);
- }
- int
- ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
- {
- int rc = 0;
- if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0)) {
- lprintf(LOG_NOTICE, "Chassis Commands: status, power, identify, policy, restart_cause, poh, bootdev, bootparam, selftest");
- }
- else if (strncmp(argv[0], "status", 6) == 0) {
- rc = ipmi_chassis_status(intf);
- }
- else if (strncmp(argv[0], "selftest", 8) == 0) {
- rc = ipmi_chassis_selftest(intf);
- }
- else if (strncmp(argv[0], "power", 5) == 0) {
- uint8_t ctl = 0;
- if ((argc < 2) || (strncmp(argv[1], "help", 4) == 0)) {
- lprintf(LOG_NOTICE, "chassis power Commands: status, on, off, cycle, reset, diag, soft");
- return 0;
- }
- if (strncmp(argv[1], "status", 6) == 0) {
- rc = ipmi_chassis_print_power_status(intf);
- return rc;
- }
- if ((strncmp(argv[1], "up", 2) == 0) || (strncmp(argv[1], "on", 2) == 0))
- ctl = IPMI_CHASSIS_CTL_POWER_UP;
- else if ((strncmp(argv[1], "down", 4) == 0) || (strncmp(argv[1], "off", 3) == 0))
- ctl = IPMI_CHASSIS_CTL_POWER_DOWN;
- else if (strncmp(argv[1], "cycle", 5) == 0)
- ctl = IPMI_CHASSIS_CTL_POWER_CYCLE;
- else if (strncmp(argv[1], "reset", 5) == 0)
- ctl = IPMI_CHASSIS_CTL_HARD_RESET;
- else if (strncmp(argv[1], "diag", 4) == 0)
- ctl = IPMI_CHASSIS_CTL_PULSE_DIAG;
- else if ((strncmp(argv[1], "acpi", 4) == 0) || (strncmp(argv[1], "soft", 4) == 0))
- ctl = IPMI_CHASSIS_CTL_ACPI_SOFT;
- else {
- lprintf(LOG_ERR, "Invalid chassis power command: %s", argv[1]);
- return -1;
- }
- rc = ipmi_chassis_power_control(intf, ctl);
- }
- else if (strncmp(argv[0], "identify", 8) == 0) {
- if (argc < 2) {
- rc = ipmi_chassis_identify(intf, NULL);
- }
- else if (strncmp(argv[1], "help", 4) == 0) {
- lprintf(LOG_NOTICE, "chassis identify <interval>");
- lprintf(LOG_NOTICE, " default is 15 seconds");
- lprintf(LOG_NOTICE, " 0 to turn off");
- lprintf(LOG_NOTICE, " force to turn on indefinitely");
- } else {
- rc = ipmi_chassis_identify(intf, argv[1]);
- }
- }
- else if (strncmp(argv[0], "poh", 3) == 0) {
- rc = ipmi_chassis_poh(intf);
- }
- else if (strncmp(argv[0], "restart_cause", 13) == 0) {
- rc = ipmi_chassis_restart_cause(intf);
- }
- else if (strncmp(argv[0], "policy", 4) == 0) {
- if ((argc < 2) || (strncmp(argv[1], "help", 4) == 0)) {
- lprintf(LOG_NOTICE, "chassis policy <state>");
- lprintf(LOG_NOTICE, " list : return supported policies");
- lprintf(LOG_NOTICE, " always-on : turn on when power is restored");
- lprintf(LOG_NOTICE, " previous : return to previous state when power is restored");
- lprintf(LOG_NOTICE, " always-off : stay off after power is restored");
- } else {
- uint8_t ctl;
- if (strncmp(argv[1], "list", 4) == 0)
- ctl = IPMI_CHASSIS_POLICY_NO_CHANGE;
- else if (strncmp(argv[1], "always-on", 9) == 0)
- ctl = IPMI_CHASSIS_POLICY_ALWAYS_ON;
- else if (strncmp(argv[1], "previous", 8) == 0)
- ctl = IPMI_CHASSIS_POLICY_PREVIOUS;
- else if (strncmp(argv[1], "always-off", 10) == 0)
- ctl = IPMI_CHASSIS_POLICY_ALWAYS_OFF;
- else {
- lprintf(LOG_ERR, "Invalid chassis policy: %s", argv[1]);
- return -1;
- }
- rc = ipmi_chassis_power_policy(intf, ctl);
- }
- }
- else if (strncmp(argv[0], "bootparam", 9) == 0) {
- if ((argc < 3) || (strncmp(argv[1], "help", 4) == 0)) {
- lprintf(LOG_NOTICE, "bootparam get <param #>");
- ipmi_chassis_set_bootflag_help();
- }
- else {
- if (strncmp(argv[1], "get", 3) == 0) {
- rc = ipmi_chassis_get_bootparam(intf, argv[2]);
- }
- else if (strncmp(argv[1], "set", 3) == 0) {
- unsigned char set_flag=0;
- unsigned char clr_flag=0;
- if (strncmp(argv[2], "help", 4) == 0 ||
- argc < 4 || (argc >= 4 &&
- strncmp(argv[2], "bootflag", 8) != 0)) {
- ipmi_chassis_set_bootflag_help();
- } else {
- if (argc == 5) {
- get_bootparam_options(argv[4], &set_flag, &clr_flag);
- }
- rc = ipmi_chassis_set_bootdev(intf, argv[3], NULL);
- if (argc == 5 && (set_flag != 0 || clr_flag != 0)) {
- rc = ipmi_chassis_set_bootvalid(intf, set_flag, clr_flag);
- }
- }
- }
- else
- lprintf(LOG_NOTICE, "bootparam get|set <option> [value ...]");
- }
- }
- else if (strncmp(argv[0], "bootdev", 7) == 0) {
- if ((argc < 2) || (strncmp(argv[1], "help", 4) == 0)) {
- lprintf(LOG_NOTICE, "bootdev <device> [clear-cmos=yes|no]");
- lprintf(LOG_NOTICE, "bootdev <device> [options=help,...]");
- lprintf(LOG_NOTICE, " none : Do not change boot device order");
- lprintf(LOG_NOTICE, " pxe : Force PXE boot");
- lprintf(LOG_NOTICE, " disk : Force boot from default Hard-drive");
- lprintf(LOG_NOTICE, " safe : Force boot from default Hard-drive, request Safe Mode");
- lprintf(LOG_NOTICE, " diag : Force boot from Diagnostic Partition");
- lprintf(LOG_NOTICE, " cdrom : Force boot from CD/DVD");
- lprintf(LOG_NOTICE, " bios : Force boot into BIOS Setup");
- lprintf(LOG_NOTICE, " floppy: Force boot from Floppy/primary removable media");
- } else {
- if (argc < 3)
- rc = ipmi_chassis_set_bootdev(intf, argv[1], NULL);
- else if (strncmp(argv[2], "clear-cmos=", 11) == 0) {
- if (strncmp(argv[2]+11, "yes", 3) == 0) {
- uint8_t flags[5] = {0, (1<<7), 0, 0, 0};
- rc = ipmi_chassis_set_bootdev(intf, argv[1], flags);
- } else
- rc = ipmi_chassis_set_bootdev(intf, argv[1], NULL);
- }
- else if (strncmp(argv[2], "options=", 8) == 0) {
- char *token;
- char *saveptr = NULL;
- int optionError = 0;
- unsigned char flags[5];
- static struct {
- char *name;
- int i;
- unsigned char mask;
- unsigned char value;
- char *desc;
- } options[] = {
- /* data 1 */
- {"valid", 0, (1<<7), (1<<7),
- "Boot flags valid"},
- {"persistent", 0, (1<<6), (1<<6),
- "Changes are persistent for all future boots"},
- {"efiboot", 0, (1<<5), (1<<5),
- "Extensible Firmware Interface Boot (EFI)"},
- /* data 2 */
- {"clear-cmos", 1, (1<<7), (1<<7),
- "CMOS clear"},
- {"lockkbd", 1, (1<<6), (1<<6),
- "Lock Keyboard"},
- /* data2[5:2] is parsed elsewhere */
- {"screenblank", 1, (1<<1), (1<<1),
- "Screen Blank"},
- {"lockoutreset", 1, (1<<0), (1<<0),
- "Lock out Resetbuttons"},
- /* data 3 */
- {"lockout_power", 2, (1<<7), (1<<7),
- "Lock out (power off/sleep request) via Power Button"},
- {"verbose=default", 2, (3<<5), (0<<5),
- "Request quiet BIOS display"},
- {"verbose=no", 2, (3<<5), (1<<5),
- "Request quiet BIOS display"},
- {"verbose=yes", 2, (3<<5), (2<<5),
- "Request verbose BIOS display"},
- {"force_pet", 2, (1<<4), (1<<4),
- "Force progress event traps"},
- {"upw_bypass", 2, (1<<3), (1<<3),
- "User password bypass"},
- {"lockout_sleep", 2, (1<<2), (1<<2),
- "Log Out Sleep Button"},
- {"cons_redirect=default", 2, (3<<0), (0<<0),
- "Console redirection occurs per BIOS configuration setting"},
- {"cons_redirect=skip", 2, (3<<0), (1<<0),
- "Suppress (skip) console redirection if enabled"},
- {"cons_redirect=enable", 2, (3<<0), (2<<0),
- "Suppress (skip) console redirection if enabled"},
- /* data 4 */
- /* data4[7:4] reserved */
- /* data4[3] BIOS Shared Mode Override, not implemented here */
- /* data4[2:0] BIOS Mux Control Override, not implemented here */
- /* data5 reserved */
- {NULL} /* End marker */
- }, *op;
- memset(&flags[0], 0, sizeof(flags));
- token = strtok_r(argv[2] + 8, ",", &saveptr);
- while (token != NULL) {
- if (strcmp(token, "help") == 0) {
- optionError = 1;
- break;
- }
- for (op = options; op->name != NULL; ++op) {
- if (strcmp(token, op->name) == 0) {
- flags[op->i] &= op->mask;
- flags[op->i] |= op->value;
- break;
- }
- }
- if (op->name == NULL) {
- /* Option not found */
- optionError = 1;
- lprintf(LOG_ERR, "Invalid option: %s", token);
- }
- token = strtok_r(NULL, ",", &saveptr);
- }
- if (optionError) {
- lprintf(LOG_NOTICE, "Legal options settings are:");
- lprintf(LOG_NOTICE, "\thelp:\tprint this message");
- for (op = options; op->name != NULL; ++op) {
- lprintf(LOG_NOTICE, "\t%s:\t%s", op->name, op->desc);
- }
- return (-1);
- }
- rc = ipmi_chassis_set_bootdev(intf, argv[1], flags);
- }
- else
- rc = ipmi_chassis_set_bootdev(intf, argv[1], NULL);
- }
- }
- else {
- lprintf(LOG_ERR, "Invalid chassis command: %s", argv[0]);
- return -1;
- }
- return rc;
- }
|