As we want the user to be able do issue all shutdown methods manually,
adjust sdcmd_*() to use STAT_INSTCMD_{HANDLED,FAILED}, so they can
be used directly.Also minor text corrections, and APC specific command renames. Signed-off-by: Michal Soltys <[email protected]> --- drivers/apcsmart.c | 75 ++++++++++++++++++++++++++++++++++------------------ drivers/apcsmart.h | 5 +++- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/drivers/apcsmart.c b/drivers/apcsmart.c index 70aebfc..7f3c575 100644 --- a/drivers/apcsmart.c +++ b/drivers/apcsmart.c @@ -835,11 +835,11 @@ static int sdok(void) if (!strcmp(temp, "*") || !strcmp(temp, "OK")) { upsdebugx(4, "Last issued shutdown command succeeded"); - return 1; + return STAT_INSTCMD_HANDLED; } upsdebugx(1, "Last issued shutdown command failed"); - return 0; + return STAT_INSTCMD_FAILED; } /* soft hibernate: S - working only when OB, otherwise ignored */ @@ -864,7 +864,7 @@ static int sdcmd_CS(int status) ser_send_char(upsfd, 'U'); ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, IGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); } - return sdcmd_S(tval); + return sdcmd_S(0); } /* @@ -897,7 +897,7 @@ static int sdcmd_ATn(int cnt) ser_send_pace(upsfd, UPSDELAY, temp); ret = sdok(); - if (ret || cnt == 3) + if (ret == STAT_INSTCMD_HANDLED || cnt == 3) return ret; /* @@ -998,7 +998,7 @@ static void upsdrv_shutdown_simple(int status) (status & APC_STAT_OL) ? "on-line" : "on battery"); /* S works only when OB */ - if ((status & APC_STAT_OB) && sdcmd_S(0)) + if ((status & APC_STAT_OB) && sdcmd_S(0) == STAT_INSTCMD_HANDLED) break; sdcmd_ATn(3); break; @@ -1051,7 +1051,7 @@ static void upsdrv_shutdown_advanced(int status) } else if (strval[i] - 48 == SDIDX_AT2N) { n = 2; } - if (sdlist[strval[i] - 48](n)) + if (sdlist[strval[i] - 48](n) == STAT_INSTCMD_HANDLED) break; /* finish if command succeeded */ } } @@ -1343,7 +1343,7 @@ static int do_cmd(apc_cmdtab_t *ct) if (ret != 1) { upslog_with_errno(LOG_ERR, "do_cmd: ser_send_char failed"); - return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + return STAT_INSTCMD_FAILED; } /* some commands have to be sent twice with a 1.5s gap */ @@ -1354,24 +1354,24 @@ static int do_cmd(apc_cmdtab_t *ct) if (ret != 1) { upslog_with_errno(LOG_ERR, "do_cmd: ser_send_char failed"); - return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + return STAT_INSTCMD_FAILED; } } ret = read_buf(buf, sizeof(buf)); if (ret < 1) - return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + return STAT_INSTCMD_FAILED; - if (strcmp(buf, "OK") != 0) { + if (strcmp(buf, "OK") != 0 && strcmp(buf, "*") != 0) { upslogx(LOG_WARNING, "Got [%s] after command [%s]", buf, ct->name); - return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + return STAT_INSTCMD_FAILED; } upslogx(LOG_INFO, "Command: %s", ct->name); - return STAT_INSTCMD_HANDLED; /* FUTURE: success */ + return STAT_INSTCMD_HANDLED; } /* some commands must be repeated in a window to execute */ @@ -1390,10 +1390,10 @@ static int instcmd_chktime(apc_cmdtab_t *ct) if ((elapsed < MINCMDTIME) || (elapsed > MAXCMDTIME)) { upsdebugx(1, "instcmd_chktime: outside window for %s (%2.0f)", ct->name, elapsed); - return STAT_INSTCMD_HANDLED; /* FUTURE: again */ + return 0; } - return do_cmd(ct); + return 1; } static int instcmd(const char *cmdname, const char *extra) @@ -1424,10 +1424,33 @@ static int instcmd(const char *cmdname, const char *extra) if (!strcasecmp(cmdname, "calibrate.stop")) return do_cal(0); - if (ct->flags & APC_NASTY) - return instcmd_chktime(ct); + /* standard non-APC_NASTY command */ + if (!(ct->flags & APC_NASTY)) + return do_cmd(ct); + + /* APC_NASTY barrier */ + if (!instcmd_chktime(ct)) + return STAT_INSTCMD_FAILED; /* FUTURE: again */ + + if (!strcasecmp(cmdname, "load.off")) + return sdcmd_Z(0); + + if (!strcasecmp(cmdname, "shutdown.stayoff")) + return sdcmd_K(0); + + if (!strcasecmp(cmdname, "shutdown.return")) + return sdcmd_S(0); + + if (!strcasecmp(cmdname, "shutdown.return.cs")) + return sdcmd_CS(ups_status); + + if (!strcasecmp(cmdname, "shutdown.return.awd")) + return sdcmd_ATn(3); + + if (!strcasecmp(cmdname, "shutdown.return.awd.h")) + return sdcmd_ATn(2); - /* nothing special here */ + /* standard APC_NASTY command */ return do_cmd(ct); } @@ -1443,7 +1466,7 @@ static void setuphandlers(void) void upsdrv_makevartable(void) { addvar(VAR_VALUE, "cable", "Specify alternate cable (940-0095B)"); - addvar(VAR_VALUE, "wugrace", "Hard hibernate's wakeup grace"); + addvar(VAR_VALUE, "awd", "Additional wakeup delay for hard hibernate command"); addvar(VAR_VALUE, "sdtype", "Specify simple shutdown method (0-6)"); addvar(VAR_VALUE, "advorder", "Enable advanced shutdown control"); } @@ -1475,8 +1498,8 @@ void upsdrv_help(void) " advorder:\n" " see \"Advanced shutdown control\" below for details\n\n" - " wugrace:\n" - " Additional grace period used with 'hard hibernate' shutdown command.\n" + " awd:\n" + " Additional wakeup delay used with \"hard hibernate\" shutdown command.\n" " The value is in 6 minute units and its acceptable range is 0 - 999.\n" " If the value is invalid or out of range, it's assumed to be 0.\n" " \"nn hack\" version of the command expects 0 - 99 range.\n\n" @@ -1492,7 +1515,7 @@ void upsdrv_help(void) " On older models (usually w/o programmable eeprom), the ups will power up\n" " immediately after the power returns. On such models, it's safer to use\n" - " 'hard hibernate'. YMMV, depending on the ups model and firmware\n" + " \"hard hibernate\". YMMV, depending on the ups model and firmware\n" " revision.\n\n" " hard hibernate:\n" @@ -1500,8 +1523,8 @@ void upsdrv_help(void) " after the eeprom defined grace period. The ups will wake up when the\n" " power returns, after the eeprom defined delay + 6*n AND if the eeprom\n" " defined min. battery charge level is met. The delay is counted from the\n" - " power's return. Value 'n' is in 6 minute units, and can be provided by\n" - " the user.\n\n" + " power's return. Value \"n\" is in 6 minute units, and can be provided by\n" + " the user (see \"awd\" option).\n\n" " On older models (usually w/o programmable eeprom), the ups will power up\n" " after 6*n minutes, often regardless it the power returned on not. YMMV,\n" @@ -1516,7 +1539,7 @@ void upsdrv_help(void) " user's intervention.\n\n" " CS 350 hack:\n" - " The same as 'soft hibernate', but first the ups is forced to go into OB\n" + " The same as \"soft hibernate\", but first the ups is forced to go into OB\n" " state.\n\n" "Simple shutdown method:\n\n" @@ -1529,7 +1552,7 @@ void upsdrv_help(void) " 5: \"hack nn\" hard hibernate only\n" " 6: hard hibernate only\n\n" - " User should provide requested method in 'sdtype'. The default is 0.\n\n" + " User should provide requested method in \"sdtype\". The default is 0.\n\n" "Advanced shutdown control:\n\n" @@ -1540,7 +1563,7 @@ void upsdrv_help(void) " 4: \"force OB\" hack method for CS 350\n" " 5: \"nn hack\" hard hibernate\n\n" - " User should set the 'advorder' option and provide the list of the methods.\n" + " User should set the \"advorder\" option and provide the list of the methods.\n" " The methods are tried in order, until one of them succeedes.\n" " If the list is too long or contains invalid characters, it will fallback to\n" " the default - 0123. You can also use \"no\" to explicitly ignore it and use\n" diff --git a/drivers/apcsmart.h b/drivers/apcsmart.h index 9862326..6c4df52 100644 --- a/drivers/apcsmart.h +++ b/drivers/apcsmart.h @@ -235,9 +235,12 @@ apc_cmdtab_t apc_cmdtab[] = { "test.battery.start", 0, APC_CMD_BTESTTOGGLE }, { "test.battery.stop", 0, APC_CMD_BTESTTOGGLE }, - { "shutdown.return.grace", + { "shutdown.return.awd",APC_NASTY, APC_CMD_GRACEDOWN }, + { "shutdown.return.awd.h", APC_NASTY, APC_CMD_GRACEDOWN }, { "shutdown.return", APC_NASTY, APC_CMD_SOFTDOWN }, + { "shutdown.return.cs", + APC_NASTY, APC_CMD_SOFTDOWN }, { "shutdown.stayoff", APC_NASTY|APC_REPEAT, APC_CMD_SHUTDOWN }, { "calibrate.start", 0, APC_CMD_CALTOGGLE }, -- 1.7.2.1 _______________________________________________ Nut-upsdev mailing list [email protected] http://lists.alioth.debian.org/mailman/listinfo/nut-upsdev
