Messages in this thread Patch in this message | | | From | Dimitris Papastamos <> | Subject | [PATCH 1/3 v2] firmware: Convert firmware path setup from an array to a list | Date | Tue, 23 Oct 2012 13:52:54 +0100 |
| |
In preparation to support dynamic listing/updating of firmware paths via procfs, this patch converts the firmware path configuration from an array to a list.
Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> --- drivers/base/firmware_class.c | 74 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 9 deletions(-)
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 8945f4e..d76152b 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -36,6 +36,13 @@ MODULE_AUTHOR("Manuel Estrada Sainz"); MODULE_DESCRIPTION("Multi purpose firmware loading support"); MODULE_LICENSE("GPL"); +struct fw_path_rec { + const char *name; + struct list_head list; +}; + +static LIST_HEAD(fw_path_list); + /* Builtin firmware support */ #ifdef CONFIG_FW_LOADER @@ -267,12 +274,6 @@ static void fw_free_buf(struct firmware_buf *buf) } /* direct firmware loading support */ -static const char *fw_path[] = { - "/lib/firmware/updates/" UTS_RELEASE, - "/lib/firmware/updates", - "/lib/firmware/" UTS_RELEASE, - "/lib/firmware" -}; /* Don't inline this: 'struct kstat' is biggish */ static noinline long fw_file_size(struct file *file) @@ -309,13 +310,13 @@ static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf static bool fw_get_filesystem_firmware(struct firmware_buf *buf) { - int i; bool success = false; char *path = __getname(); + struct fw_path_rec *fwp; - for (i = 0; i < ARRAY_SIZE(fw_path); i++) { + list_for_each_entry(fwp, &fw_path_list, list) { struct file *file; - snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id); + snprintf(path, PATH_MAX, "%s/%s", fwp->name, buf->fw_id); file = filp_open(path, O_RDONLY, 0); if (IS_ERR(file)) @@ -1423,6 +1424,50 @@ static int fw_cache_piggyback_on_request(const char *name) } #endif +static void fw_free_path_list(void) +{ + struct fw_path_rec *fwp; + + while (!list_empty(&fw_path_list)) { + fwp = list_first_entry(&fw_path_list, + struct fw_path_rec, + list); + kfree(fwp->name); + list_del(&fwp->list); + kfree(fwp); + } +} + +static int fw_populate_path_list(void) +{ + int i; + struct fw_path_rec *fwp; + static const char *fw_path[] = { + "/lib/firmware/updates/" UTS_RELEASE, + "/lib/firmware/updates", + "/lib/firmware/" UTS_RELEASE, + "/lib/firmware" + }; + + for (i = 0; i < ARRAY_SIZE(fw_path); i++) { + fwp = kmalloc(sizeof(*fwp), GFP_KERNEL); + if (!fwp) + goto err_fwp_alloc; + fwp->name = kstrdup(fw_path[i], GFP_KERNEL); + if (!fwp->name) + goto err_fwp_name_alloc; + list_add_tail(&fwp->list, &fw_path_list); + } + + return 0; + +err_fwp_name_alloc: + kfree(fwp); +err_fwp_alloc: + fw_free_path_list(); + return -ENOMEM; +} + static void __init fw_cache_init(void) { spin_lock_init(&fw_cache.lock); @@ -1445,7 +1490,17 @@ static void __init fw_cache_init(void) static int __init firmware_class_init(void) { + int ret; + fw_cache_init(); + + ret = fw_populate_path_list(); + if (ret < 0) { + pr_err("%s: Failed to populate firmware path list: %d\n", + __func__, ret); + return ret; + } + return class_register(&firmware_class); } @@ -1455,6 +1510,7 @@ static void __exit firmware_class_exit(void) unregister_syscore_ops(&fw_syscore_ops); unregister_pm_notifier(&fw_cache.pm_notify); #endif + fw_free_path_list(); class_unregister(&firmware_class); } -- 1.8.0
| |