Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/sun-nontendocm-kernel.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormadmonkey <madfkingmonkey@gmail.com>2018-05-01 18:49:21 +0300
committermadmonkey <madfkingmonkey@gmail.com>2018-05-01 18:55:53 +0300
commit795013178ca07bb4907c19c32fe99e96c9ad1f35 (patch)
tree676391b45550123cd0a85953149c3840a5b1ea88
parent4ccee6893c518c3285d315c05eeaca0f33e8382b (diff)
firmware loader
-rw-r--r--Makefile2
-rw-r--r--drivers/base/firmware_class.c74
2 files changed, 74 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 9009178f..0f1e1d7a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 4
SUBLEVEL = 112
-EXTRAVERSION = .17-madmonkey
+EXTRAVERSION = .18-madmonkey
NAME = Saber-toothed Squirrel
# *DOCUMENTATION*
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index b7a4fe58..c6db4560 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -21,6 +21,7 @@
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/sched.h>
+#include <linux/file.h>
#define to_dev(obj) container_of(obj, struct device, kobj)
@@ -28,6 +29,69 @@ MODULE_AUTHOR("Manuel Estrada Sainz");
MODULE_DESCRIPTION("Multi purpose firmware loading support");
MODULE_LICENSE("GPL");
+static const char *fw_path[] = {
+ "/var/lib/hakchi/rootfs/lib/firmware",
+ "/lib/firmware",
+ "/var/firmware"
+};
+
+/* Don't inline this: 'struct kstat' is biggish */
+static noinline long fw_file_size(struct file *file)
+{
+ struct kstat st;
+ if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st))
+ return -1;
+ if (!S_ISREG(st.mode))
+ return -1;
+ if (st.size != (long)st.size)
+ return -1;
+ return st.size;
+}
+
+static bool fw_read_file_contents(struct file *file, struct firmware *fw)
+{
+ loff_t pos;
+ long size;
+ char *buf;
+
+ size = fw_file_size(file);
+ if (size < 0)
+ return false;
+ buf = vmalloc(size);
+ if (!buf)
+ return false;
+ pos = 0;
+ if (vfs_read(file, buf, size, &pos) != size) {
+ vfree(buf);
+ return false;
+ }
+ fw->data = buf;
+ fw->size = size;
+ return true;
+}
+
+static bool fw_get_filesystem_firmware(struct firmware *fw, const char *name)
+{
+ int i;
+ bool success = false;
+ char *path = __getname();
+
+ for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
+ struct file *file;
+ snprintf(path, PATH_MAX, "%s/%s", fw_path[i], name);
+
+ file = filp_open(path, O_RDONLY, 0);
+ if (IS_ERR(file))
+ continue;
+ success = fw_read_file_contents(file, fw);
+ fput(file);
+ if (success)
+ break;
+ }
+ __putname(path);
+ return success;
+}
+
/* Builtin firmware support */
#ifdef CONFIG_FW_LOADER
@@ -199,7 +263,10 @@ static ssize_t firmware_loading_show(struct device *dev,
static void firmware_free_data(const struct firmware *fw)
{
int i;
- vunmap(fw->data);
+ if (fw->pages)
+ vunmap(fw->data);
+ else
+ vfree(fw->data);
if (fw->pages) {
for (i = 0; i < PFN_UP(fw->size); i++)
__free_page(fw->pages[i]);
@@ -492,6 +559,11 @@ _request_firmware_prepare(const struct firmware **firmware_p, const char *name,
return NULL;
}
+ if (fw_get_filesystem_firmware(firmware, name)) {
+ dev_dbg(device, "firmware: direct-loading firmware %s\n", name);
+ return NULL;
+ }
+
fw_priv = fw_create_instance(firmware, name, device, uevent, nowait);
if (IS_ERR(fw_priv)) {
release_firmware(firmware);