[Nut-upsdev] [RFC apcsmart V3 18/18] drivers/apcsmart: use STAT_INSTCMD_{HANDLED, FAILED} for sdcmd_*()
Michal Soltys
soltys at ziu.info
Sat Mar 5 10:38:35 UTC 2011
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 <soltys at ziu.info>
---
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
More information about the Nut-upsdev
mailing list