summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-07-18 16:40:56 +0200
committerFelix Fietkau <nbd@openwrt.org>2014-07-18 16:40:56 +0200
commitfb60df0eb16d4300efabda72249598d0748439e2 (patch)
treef3260ba6a1f14cf0079624d186efa3eb250d2466
parent619ec82ececcbe9b9d1ca18ac6bc7c5c68c96825 (diff)
downloadunitd-fb60df0eb16d4300efabda72249598d0748439e2.tar
unitd-fb60df0eb16d4300efabda72249598d0748439e2.zip
hotplug: fix firmware loading
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-rw-r--r--plug/hotplug.c53
1 files changed, 23 insertions, 30 deletions
diff --git a/plug/hotplug.c b/plug/hotplug.c
index 075062b..b50c04e 100644
--- a/plug/hotplug.c
+++ b/plug/hotplug.c
@@ -161,10 +161,10 @@ static void handle_firmware(struct blob_attr *msg, struct blob_attr *data)
char *dir = blobmsg_get_string(blobmsg_data(data));
char *file = hotplug_msg_find_var(msg, "FIRMWARE");
char *dev = hotplug_msg_find_var(msg, "DEVPATH");
- void *fw_data;
- struct stat s;
+ struct stat s = { 0 };
char *path, loadpath[256], syspath[256];
- int fw, load, sys, len;
+ int fw, src, load, len;
+ static char buf[4096];
DEBUG(2, "Firmware request for %s/%s\n", dir, file);
@@ -173,35 +173,24 @@ static void handle_firmware(struct blob_attr *msg, struct blob_attr *data)
exit(-1);
}
- path = malloc(strlen(dir) + strlen(file) + 2);
- if (!path) {
- ERROR("Failed to allocate memory\n");
- exit(-1);
- }
+ path = alloca(strlen(dir) + strlen(file) + 2);
sprintf(path, "%s/%s", dir, file);
if (stat(path, &s)) {
ERROR("Could not find firmware %s\n", path);
- exit(-1);
- }
-
- fw_data = malloc(s.st_size);
- if (!fw_data) {
- ERROR("Failed to allocate firmware data memory\n");
- exit(-1);
+ src = -1;
+ s.st_size = 0;
+ goto send_to_kernel;
}
- fw = open(path, O_RDONLY);
- if (!fw) {
+ src = open(path, O_RDONLY);
+ if (src < 0) {
ERROR("Failed to open %s\n", path);
- exit(-1);
- }
- if (read(fw, fw_data, s.st_size) != s.st_size) {
- ERROR("Failed to read firmware data\n");
- exit(-1);
+ s.st_size = 0;
+ goto send_to_kernel;
}
- close(fw);
+send_to_kernel:
snprintf(loadpath, sizeof(loadpath), "/sys/%s/loading", dev);
load = open(loadpath, O_WRONLY);
if (!load) {
@@ -212,19 +201,23 @@ static void handle_firmware(struct blob_attr *msg, struct blob_attr *data)
close(load);
snprintf(syspath, sizeof(syspath), "/sys/%s/data", dev);
- sys = open(syspath, O_WRONLY);
- if (!sys) {
+ fw = open(syspath, O_WRONLY);
+ if (fw < 0) {
ERROR("Failed to open %s\n", syspath);
exit(-1);
}
len = s.st_size;
- while (len > 4096) {
- write(fw, fw_data, 4096);
- len -= 4096;
+ while (len) {
+ len = read(src, buf, sizeof(buf));
+ if (len <= 0)
+ break;
+
+ write(fw, buf, len);
}
- if (len)
- write(fw, fw_data, len);
+
+ if (src >= 0)
+ close(src);
close(fw);
load = open(loadpath, O_WRONLY);