ACK: [PATCH] lib: fwts_acpi_tables: load tables from /sys (LP: #1437043)
ivanhu
ivan.hu at canonical.com
Fri Mar 27 02:58:10 UTC 2015
On 2015年03月27日 08:57, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
>
> The /dev/mem interface is going to be deprecated, so if we can't
> load directly from memory then try to load from the alternative
> /sys/firmware/acpi/tables raw ACPI tables.
>
> This will address issues on ARM first, and eventually x86 when
> the /dev/mem interface gets removed. I discovered this fact
> at the fw-summit today.
>
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
> src/lib/src/fwts_acpi_tables.c | 69 ++++++++++++++++++++++++++++++++++++------
> 1 file changed, 60 insertions(+), 9 deletions(-)
>
> diff --git a/src/lib/src/fwts_acpi_tables.c b/src/lib/src/fwts_acpi_tables.c
> index 35d0414..d3ef6cd 100644
> --- a/src/lib/src/fwts_acpi_tables.c
> +++ b/src/lib/src/fwts_acpi_tables.c
> @@ -677,10 +677,17 @@ static uint8_t *fwts_acpi_load_table_from_file(const int fd, size_t *length)
> return ptr;
> }
>
> -static int fwts_acpi_load_tables_from_file(fwts_framework *fw)
> +/*
> + * fwts_acpi_load_tables_from_file_generic()
> + * load acpi tables from a given path with a given file extention
> + */
> +static int fwts_acpi_load_tables_from_file_generic(
> + fwts_framework *fw,
> + char *acpi_table_path,
> + const char *extention,
> + int *count)
> {
> struct dirent **dir_entries;
> - int count = 0;
> int i;
>
> /*
> @@ -688,22 +695,38 @@ static int fwts_acpi_load_tables_from_file(fwts_framework *fw)
> * to ensure the tables are always loaded into memory
> * in some form of deterministic order
> */
> - if ((count = scandir(fw->acpi_table_path, &dir_entries, 0, alphasort)) < 0) {
> + if ((*count = scandir(acpi_table_path, &dir_entries, 0, alphasort)) < 0) {
> fwts_log_error(fw, "Cannot open directory '%s' to read ACPI tables.",
> fw->acpi_table_path);
> return FWTS_ERROR;
> }
>
> - for (i = 0; i < count; i++) {
> - if (strstr(dir_entries[i]->d_name, ".dat")) {
> + for (i = 0; i < *count; i++) {
> + /* Ignore . directories */
> + if (dir_entries[i]->d_name[0] == '.')
> + continue;
> +
> + if (strstr(dir_entries[i]->d_name, extention)) {
> char path[PATH_MAX];
> int fd;
>
> snprintf(path, sizeof(path), "%s/%s",
> - fw->acpi_table_path, dir_entries[i]->d_name);
> + acpi_table_path, dir_entries[i]->d_name);
> if ((fd = open(path, O_RDONLY)) >= 0) {
> uint8_t *table;
> size_t length;
> + struct stat buf;
> +
> + if (fstat(fd, &buf) < 0) {
> + fwts_log_error(fw, "Cannot stat file '%s'\n", path);
> + close(fd);
> + continue;
> + }
> + /* Must be a regular file */
> + if (!S_ISREG(buf.st_mode)) {
> + close(fd);
> + continue;
> + }
>
> if ((table = fwts_acpi_load_table_from_file(fd, &length)) != NULL) {
> char name[9]; /* "RSD PTR " or standard ACPI 4 letter name */
> @@ -749,12 +772,22 @@ static int fwts_acpi_load_tables_from_file(fwts_framework *fw)
> free(dir_entries[i]);
> }
> free(dir_entries);
> + return FWTS_OK;
> +}
>
> +/*
> + * fwts_acpi_load_tables_from_file()
> + * load raw acpi tables from a user given path, files must end in ".dat"
> + */
> +static int fwts_acpi_load_tables_from_file(fwts_framework *fw)
> +{
> + int count;
> +
> + fwts_acpi_load_tables_from_file_generic(fw, fw->acpi_table_path, ".dat", &count);
> if (count == 0) {
> fwts_log_error(fw, "Could not find any APCI tables in directory '%s'.\n", fw->acpi_table_path);
> return FWTS_ERROR;
> }
> -
> return FWTS_OK;
> }
>
> @@ -976,6 +1009,20 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw)
> return FWTS_OK;
> }
>
> +
> +static int fwts_acpi_load_tables_from_sysfs(fwts_framework *fw)
> +{
> + int count, total;
> + fwts_acpi_load_tables_from_file_generic(fw, "/sys/firmware/acpi/tables", "", &total);
> + fwts_acpi_load_tables_from_file_generic(fw, "/sys/firmware/acpi/tables/dynamic", "", &count);
> + total += count;
> + if (total == 0) {
> + fwts_log_error(fw, "Could not find any APCI tables in directory '/sys/firmware/acpi/tables'.\n");
> + return FWTS_ERROR;
> + }
> + return FWTS_OK;
> +}
> +
> /*
> * fwts_acpi_load_tables()
> * Load from firmware or from files in a specified directory
> @@ -988,9 +1035,13 @@ int fwts_acpi_load_tables(fwts_framework *fw)
> ret = fwts_acpi_load_tables_from_file(fw);
> else if (fw->acpi_table_acpidump_file != NULL)
> ret = fwts_acpi_load_tables_from_acpidump(fw);
> - else if (fwts_check_root_euid(fw, true) == FWTS_OK)
> + else if (fwts_check_root_euid(fw, true) == FWTS_OK) {
> ret = fwts_acpi_load_tables_from_firmware(fw);
> - else
> +
> + /* Load from memory failed (e.g. no /dev/mem), so try sysfs */
> + if (ret != FWTS_OK)
> + ret = fwts_acpi_load_tables_from_sysfs(fw);
> + } else
> ret = FWTS_ERROR_NO_PRIV;
>
> if (ret == FWTS_OK) {
Acked-by: Ivan Hu <ivan.hu at canonical.com>
More information about the fwts-devel
mailing list