[Nut-upsdev] [RFC/PREVIEW] Move apcsmart driver to canonical processing + minor stuff
soltys at ziu.info
Sun Mar 13 20:33:42 UTC 2011
On 11-03-12 02:10, Michal Soltys wrote:
> Inital tests with two apc units (2005 and pre-2000) seem to go well. See commit
> message for details. I'll add more detailed rationale after getting some sleep :)
> Michal Soltys (1):
> apcsmart: switch processing to ICANON + minor fixes
> drivers/apcsmart.c | 270 +++++++++++++++++++++++++++++++++++-----------------
> drivers/apcsmart.h | 127 ++++++++++++++++---------
> 2 files changed, 267 insertions(+), 130 deletions(-)
While the switch to canonical mode was pretty straightforward, two small
issues showed up:
1) capability check was taking near 3 seconds to complete on one of the
models (and not the most advanced/newest one) - while not an issue with
non-canonical mode, it was too close to the edge in the canonical mode.
2) on older models, some shutdown commands (K, @) either don't respond
(on failure), or "respond" with '*' which is more like an alarm (and
supposedly can happen on other times when apc powers down for other
To resolve this gracefully:
All reads are performed using upsread() now, which is based on
ser_get_line_alert(). It takes few flags (see apcsmart.h) to handle
different behaviour depending on our needs. Basic flags are:
SER_TO - allow the read to timeout without rising error
SER_AL - run with alert_handler() (and enable proper ignore/alarm sets)
- when canonical mode is enabled, '*' functions as an additional EOL. It
doesn't conflicit with normal operation - as '*' generally doesn't
happen, and even if it did, upsread() would just skip over it continuing
reading. Similary to normal LF, * won't be included in the input either
- when upsread() is called in sdcmd*() functions, SER_SD flag is used.
Apart from assuming SER_TO, it drops the default timeout to 1.5 seconds.
This is generally used to eat responses from U or force-failed @nnn.
Both commands should answer immediately with something, though for older
apc stuff, failed @nnn will be silent.
- when upsread() is called in sdok() functions, SER_AX flag is used.
This implies SER_SD (see above) and enables handling '*'. Basically, if
it's detected (remember it functions as EOL now). the buffer with just
'*' is returned and sdok() actually knows if the command succeeded or not.
- when we do capability check, SER_CP is used, which rises timeout to 6
seconds (and enables special ignore set). This gives plenty of margin to
handle whole capability list without timing out. With canonical mode, we
will use the least amount of time possible either way.
More information about the Nut-upsdev