intelvbttool: Add support for reading vbt from sysfs

VBT on Intel(R) systems is available via sysfs as
    /sys/kernel/debug/dri/0/i915_vbt
However the size of this file reads as 0 causing
intelvbttool to fail. This patch implements incremental reads
with realloc for such cases or whenever the file size is not
available (e.g. reading from stdin).
After this patch is applied, intelvbttool can be used as follows:
    sudo intelvbttool -f /sys/kernel/debug/dri/0/i915_vbt -d

Change-Id: I5d17095a5747550b7115a54a7619b7294a846196
Signed-off-by: Alex Feinman <alexfeinman@hotmail.com>
Reviewed-on: https://review.coreboot.org/c/31531
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
Alex Feinman 2019-02-20 11:49:51 -08:00 committed by Patrick Georgi
parent 180ac500fc
commit 2223cbf7de
1 changed files with 17 additions and 22 deletions

View File

@ -29,6 +29,7 @@ typedef uint8_t u8;
typedef uint16_t u16; typedef uint16_t u16;
typedef uint32_t u32; typedef uint32_t u32;
#define DEF_ALLOC 1024
typedef struct { typedef struct {
u16 signature; u16 signature;
@ -380,39 +381,33 @@ static struct fileobject *malloc_fo_sub(const struct fileobject *old,
static struct fileobject *read_file(const char *filename) static struct fileobject *read_file(const char *filename)
{ {
FILE *fd = fopen(filename, "rb"); FILE *fd = fopen(filename, "rb");
off_t read_size = DEF_ALLOC;
if (!fd) { if (!fd) {
printerr("%s open failed: %s\n", filename, strerror(errno)); printerr("%s open failed: %s\n", filename, strerror(errno));
return NULL; return NULL;
} }
if (fseek(fd, 0, SEEK_END)) { struct fileobject *fo = malloc_fo(read_size);
printerr("%s seek failed: %s\n", filename, strerror(errno));
fclose(fd);
return NULL;
}
const off_t size = ftell(fd);
if (size < 0 || size > SIZE_MAX) {
printerr("%s tell failed: %s\n", filename, strerror(errno));
fclose(fd);
return NULL;
}
if (fseek(fd, 0, SEEK_SET)) {
printerr("%s seek failed: %s\n", filename, strerror(errno));
fclose(fd);
return NULL;
}
struct fileobject *fo = malloc_fo(size);
if (!fo) { if (!fo) {
printerr("malloc failed\n"); printerr("malloc failed\n");
fclose(fd); fclose(fd);
return NULL; return NULL;
} }
if (fread(fo->data, 1, size, fd) != size) { off_t total_bytes_read = 0, bytes_read;
while ((bytes_read = fread(fo->data + total_bytes_read, 1, read_size, fd)) > 0) {
total_bytes_read += bytes_read;
struct fileobject *newfo = remalloc_fo(fo, fo->size + read_size);
if (!newfo) {
fclose(fd);
free_fo(fo);
return NULL;
}
fo = newfo;
}
if (!total_bytes_read) {
fclose(fd); fclose(fd);
free_fo(fo); free_fo(fo);
return NULL; return NULL;
@ -424,7 +419,7 @@ static struct fileobject *read_file(const char *filename)
return NULL; return NULL;
} }
fo->size = size; fo->size = total_bytes_read;
return fo; return fo;
} }