Files
OpenCellular/util/misc_util.c
Shawn Nematbakhsh 911da8c150 ectool: Always try v0 of GET_VERSIONS command if v1 fails
The ioctl return status for CROS_EC_DEV_IOCXCMD is inconsistent across
kernel versions:

- In 3.8 kernel, on INVALID_VERSION EC result, -EBADMSG is returned
- In 3.14 kernel, on INVALID_VERSION EC result, success status is
  returned

In both cases, the INVALID_VERSION result is written to the
cros_ec_command.result parameter.

The inconsistency here should be fixed with kernel patches. In any case,
there is little harm with trying v0 of GET_VERSIONS on any failure of the v1
command.

BUG=chrome-os-partner:37668,chromium:466896
TEST=Manual on peppy. Verify 'ectool thermalget 0 0' prints threshold info.
BRANCH=None

Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Change-Id: Ic1eb3f8f2fa95711ec15a5afb740af8f18b88b55
Reviewed-on: https://chromium-review.googlesource.com/260004
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Queue: Bill Richardson <wfrichar@chromium.org>
Trybot-Ready: Bill Richardson <wfrichar@chromium.org>
Tested-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2015-03-14 00:45:41 +00:00

136 lines
2.5 KiB
C

/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "comm-host.h"
#include "misc_util.h"
int write_file(const char *filename, const char *buf, int size)
{
FILE *f;
int i;
/* Write to file */
f = fopen(filename, "wb");
if (!f) {
perror("Error opening output file");
return -1;
}
i = fwrite(buf, 1, size, f);
fclose(f);
if (i != size) {
perror("Error writing to file");
return -1;
}
return 0;
}
char *read_file(const char *filename, int *size)
{
FILE *f = fopen(filename, "rb");
char *buf;
int i;
if (!f) {
perror("Error opening input file");
return NULL;
}
fseek(f, 0, SEEK_END);
*size = ftell(f);
rewind(f);
if (*size > 0x100000) {
fprintf(stderr, "File seems unreasonably large\n");
fclose(f);
return NULL;
}
buf = (char *)malloc(*size);
if (!buf) {
fprintf(stderr, "Unable to allocate buffer.\n");
fclose(f);
return NULL;
}
printf("Reading %d bytes from %s...\n", *size, filename);
i = fread(buf, 1, *size, f);
fclose(f);
if (i != *size) {
perror("Error reading file");
free(buf);
return NULL;
}
return buf;
}
int is_string_printable(const char *buf)
{
while (*buf) {
if (!isprint(*buf))
return 0;
buf++;
}
return 1;
}
/**
* Get the versions of the command supported by the EC.
*
* @param cmd Command
* @param pmask Destination for version mask; will be set to 0 on
* error.
* @return 0 if success, <0 if error
*/
int ec_get_cmd_versions(int cmd, uint32_t *pmask)
{
struct ec_params_get_cmd_versions_v1 pver_v1;
struct ec_params_get_cmd_versions pver;
struct ec_response_get_cmd_versions rver;
int rv;
*pmask = 0;
pver_v1.cmd = cmd;
rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 1, &pver_v1, sizeof(pver_v1),
&rver, sizeof(rver));
if (rv < 0) {
pver.cmd = cmd;
rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &pver, sizeof(pver),
&rver, sizeof(rver));
}
if (rv < 0)
return rv;
*pmask = rver.version_mask;
return 0;
}
/**
* Return non-zero if the EC supports the command and version
*
* @param cmd Command to check
* @param ver Version to check
* @return non-zero if command version supported; 0 if not.
*/
int ec_cmd_version_supported(int cmd, int ver)
{
uint32_t mask = 0;
if (ec_get_cmd_versions(cmd, &mask))
return 0;
return (mask & EC_VER_MASK(ver)) ? 1 : 0;
}