mirror of
https://github.com/linux-msm/pd-mapper.git
synced 2026-02-25 13:12:10 -08:00
Use firmware load path from sysfs
Some distributions override firmware loading path using /sys/module/firmware_class/parameters/path. Kernel supports it, teach pd-mapper to support it too. Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com> Co-authored-by: Alexey Minnekhanov <alexeymin@postmarketos.org>
This commit is contained in:
85
pd-mapper.c
85
pd-mapper.c
@@ -193,10 +193,72 @@ static int pd_load_map(const char *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int concat_path(char *base_path, char *firmware_path, char *path)
|
||||||
|
{
|
||||||
|
if ((strlen(base_path) > 0) && (strlen(base_path) + 1 + strlen(firmware_path) + 1 < PATH_MAX)) {
|
||||||
|
strcpy(path, base_path);
|
||||||
|
strcat(path, "/");
|
||||||
|
strcat(path, firmware_path);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
warn("Path length exceeded %lu\n", sizeof(path));
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef ANDROID
|
#ifndef ANDROID
|
||||||
#define FIRMWARE_BASE "/lib/firmware/"
|
#define FIRMWARE_BASE "/lib/firmware/"
|
||||||
|
#define FIRMWARE_PARAM_PATH "/sys/module/firmware_class/parameters/path"
|
||||||
|
|
||||||
|
static DIR *opendir_firmware(char *firmware_path, char *out_path_opened)
|
||||||
|
{
|
||||||
|
int ret = 0, n;
|
||||||
|
DIR *fw_dir = NULL;
|
||||||
|
int fw_param_path = open(FIRMWARE_PARAM_PATH, O_RDONLY);
|
||||||
|
char fw_sysfs_path[PATH_MAX];
|
||||||
|
|
||||||
|
if (fw_param_path < 0) {
|
||||||
|
warn("Cannot open sysfs path: %s", FIRMWARE_PARAM_PATH);
|
||||||
|
close(fw_param_path);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = read(fw_param_path, fw_sysfs_path, sizeof(char) * PATH_MAX);
|
||||||
|
close(fw_param_path);
|
||||||
|
if (n < 0) {
|
||||||
|
warn("Cannot read sysfs path: %s", FIRMWARE_PARAM_PATH);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
fw_sysfs_path[n - 1] = '\0';
|
||||||
|
|
||||||
|
ret = concat_path(fw_sysfs_path, firmware_path, out_path_opened);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
fw_dir = opendir(out_path_opened);
|
||||||
|
if (!fw_dir)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return fw_dir;
|
||||||
|
err:
|
||||||
|
ret = concat_path(fw_sysfs_path, FIRMWARE_BASE, out_path_opened);
|
||||||
|
if (ret)
|
||||||
|
return fw_dir;
|
||||||
|
|
||||||
|
fw_dir = opendir(out_path_opened);
|
||||||
|
if (!fw_dir)
|
||||||
|
warn("Cannot open firmware path: %s", fw_sysfs_path);
|
||||||
|
|
||||||
|
return fw_dir;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#define FIRMWARE_BASE "/vendor/firmware/"
|
#define FIRMWARE_BASE "/vendor/firmware/"
|
||||||
|
|
||||||
|
DIR opendir_firmware(char *firmware_path)
|
||||||
|
{
|
||||||
|
return open_concat_path("/vendor/firmware/", firmware_path);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char *known_extensions[] = {
|
static char *known_extensions[] = {
|
||||||
@@ -208,6 +270,8 @@ static char *known_extensions[] = {
|
|||||||
static int pd_enumerate_jsons(struct assoc *json_set)
|
static int pd_enumerate_jsons(struct assoc *json_set)
|
||||||
{
|
{
|
||||||
char firmware_value[PATH_MAX];
|
char firmware_value[PATH_MAX];
|
||||||
|
char *firmware_value_copy = NULL;
|
||||||
|
char *firmware_path = NULL;
|
||||||
char json_path[PATH_MAX];
|
char json_path[PATH_MAX];
|
||||||
char firmware_attr[32];
|
char firmware_attr[32];
|
||||||
struct dirent *fw_de;
|
struct dirent *fw_de;
|
||||||
@@ -253,19 +317,14 @@ static int pd_enumerate_jsons(struct assoc *json_set)
|
|||||||
}
|
}
|
||||||
|
|
||||||
firmware_value[n] = '\0';
|
firmware_value[n] = '\0';
|
||||||
|
/* dirname() function can (and will) modify the parameter, so make a copy */
|
||||||
|
firmware_value_copy = strdup(firmware_value);
|
||||||
|
firmware_path = dirname(firmware_value_copy);
|
||||||
|
|
||||||
if (strlen(FIRMWARE_BASE) + strlen(firmware_value) + 1 > sizeof(path))
|
fw_dir = opendir_firmware(firmware_path, path);
|
||||||
|
if (!fw_dir)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strcpy(path, FIRMWARE_BASE);
|
|
||||||
strcat(path, dirname(firmware_value));
|
|
||||||
|
|
||||||
fw_dir = opendir(path);
|
|
||||||
if (!fw_dir) {
|
|
||||||
warn("Cannot open %s", path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((fw_de = readdir(fw_dir)) != NULL) {
|
while ((fw_de = readdir(fw_dir)) != NULL) {
|
||||||
int extens_index;
|
int extens_index;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@@ -287,9 +346,8 @@ static int pd_enumerate_jsons(struct assoc *json_set)
|
|||||||
if (!found)
|
if (!found)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strlen(FIRMWARE_BASE) + strlen(firmware_value) + 1 +
|
if (strlen(path) + 1 + strlen(fw_de->d_name) + 1 > sizeof(json_path))
|
||||||
strlen(fw_de->d_name) + 1 > sizeof(path))
|
continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
strcpy(json_path, path);
|
strcpy(json_path, path);
|
||||||
strcat(json_path, "/");
|
strcat(json_path, "/");
|
||||||
@@ -299,6 +357,7 @@ static int pd_enumerate_jsons(struct assoc *json_set)
|
|||||||
}
|
}
|
||||||
|
|
||||||
closedir(fw_dir);
|
closedir(fw_dir);
|
||||||
|
free(firmware_value_copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(class_dir);
|
closedir(class_dir);
|
||||||
|
|||||||
Reference in New Issue
Block a user