summaryrefslogtreecommitdiffstats
path: root/init/devices.cpp
diff options
context:
space:
mode:
authorChris Fries <cfries@motorola.com>2015-09-27 22:24:40 +0200
committerAlberto97 <albertop2197@gmail.com>2015-11-23 17:06:59 +0100
commitfc73ae3d9432a00519d684bd73d714d04de3da83 (patch)
tree56bad2d04d94f0e86b7636cec49bc3b201a62e93 /init/devices.cpp
parent29f7779fdbccb5926a3f74d70c8721fa62e75a0c (diff)
downloadsystem_core-fc73ae3d9432a00519d684bd73d714d04de3da83.zip
system_core-fc73ae3d9432a00519d684bd73d714d04de3da83.tar.gz
system_core-fc73ae3d9432a00519d684bd73d714d04de3da83.tar.bz2
init: Add support for gzipped firmware files
In case no matching firmware is found, re-search the paths for [path][firmware].gz and use that instead if found. Reviewed-on: http://gerrit.mot.com/724787 SLTApproved: Slta Waiver <sltawvr@motorola.com> Tested-by: Jira Key <jirakey@motorola.com> Reviewed-by: Wen-Long Che <wenlong@motorola.com> SME-Granted: Gerrit Application <gerritmailarchive@motorola.com> Reviewed-by: Christopher Fries <cfries@motorola.com> Submit-Approved: Jira Key <jirakey@motorola.com> Adapted for Marshmallow by Benjamin Legrand (scritch007) Change-Id: I74e42ab3c77eb7722c58042489d7bd4856f3be63
Diffstat (limited to 'init/devices.cpp')
-rw-r--r--init/devices.cpp52
1 files changed, 37 insertions, 15 deletions
diff --git a/init/devices.cpp b/init/devices.cpp
index 0bc0df7..d8de450 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -48,6 +48,7 @@
#include "util.h"
#include "log.h"
#include "property_service.h"
+#include <zlib.h>
#define SYSFS_PREFIX "/sys"
static const char *firmware_dirs[] = { "/etc/firmware",
@@ -825,23 +826,20 @@ static void handle_device_event(struct uevent *uevent)
}
}
-static int load_firmware(int fw_fd, int loading_fd, int data_fd)
+static int load_firmware(int fw_fd, gzFile gz_fd, int loading_fd, int data_fd)
{
- struct stat st;
- long len_to_copy;
int ret = 0;
- if(fstat(fw_fd, &st) < 0)
- return -1;
- len_to_copy = st.st_size;
-
write(loading_fd, "1", 1); /* start transfer */
- while (len_to_copy > 0) {
+ while (1) {
char buf[PAGE_SIZE];
ssize_t nr;
- nr = read(fw_fd, buf, sizeof(buf));
+ if (gz_fd)
+ nr = gzread(gz_fd, buf, sizeof(buf));
+ else
+ nr = read(fw_fd, buf, sizeof(buf));
if(!nr)
break;
if(nr < 0) {
@@ -849,7 +847,6 @@ static int load_firmware(int fw_fd, int loading_fd, int data_fd)
break;
}
- len_to_copy -= nr;
while (nr > 0) {
ssize_t nw = 0;
@@ -865,8 +862,10 @@ static int load_firmware(int fw_fd, int loading_fd, int data_fd)
out:
if(!ret)
write(loading_fd, "0", 1); /* successful end of transfer */
- else
+ else {
+ ERROR("%s: aborted transfer\n", __func__);
write(loading_fd, "-1", 2); /* abort transfer */
+ }
return ret;
}
@@ -876,12 +875,29 @@ static int is_booting(void)
return access("/dev/.booting", F_OK) == 0;
}
+gzFile fw_gzopen(const char *fname, const char *mode)
+{
+ char *file1 = NULL;
+ int l;
+ gzFile gz_fd = NULL;
+
+ l = asprintf(&file1, "%s.gz", fname);
+ if (l == -1)
+ goto out;
+
+ gz_fd = gzopen(file1, mode);
+ free(file1);
+out:
+ return gz_fd;
+}
+
static void process_firmware_event(struct uevent *uevent)
{
char *root, *loading, *data;
int l, loading_fd, data_fd, fw_fd;
size_t i;
int booting = is_booting();
+ gzFile gz_fd = NULL;
INFO("firmware: loading '%s' for '%s'\n",
uevent->firmware, uevent->path);
@@ -914,15 +930,18 @@ try_loading_again:
goto data_free_out;
fw_fd = open(file, O_RDONLY|O_CLOEXEC);
free(file);
- if (fw_fd >= 0) {
- if(!load_firmware(fw_fd, loading_fd, data_fd))
+ if (fw_fd < 0){
+ gz_fd = fw_gzopen(file, "rb");
+ }
+ if (fw_fd >= 0 || gz_fd) {
+ if(!load_firmware(fw_fd, gz_fd, loading_fd, data_fd))
INFO("firmware: copy success { '%s', '%s' }\n", root, uevent->firmware);
else
INFO("firmware: copy failure { '%s', '%s' }\n", root, uevent->firmware);
break;
}
}
- if (fw_fd < 0) {
+ if ((fw_fd < 0) && !gz_fd) {
if (booting) {
/* If we're not fully booted, we may be missing
* filesystems needed for firmware, wait and retry.
@@ -936,7 +955,10 @@ try_loading_again:
goto data_close_out;
}
- close(fw_fd);
+ if (gz_fd)
+ gzclose(gz_fd);
+ else
+ close(fw_fd);
data_close_out:
close(data_fd);
loading_close_out: