summaryrefslogtreecommitdiffstats
path: root/mdk-stage1
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1')
-rw-r--r--mdk-stage1/Makefile6
-rw-r--r--mdk-stage1/NEWS2
-rw-r--r--mdk-stage1/hotplug.c90
3 files changed, 97 insertions, 1 deletions
diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile
index b9d961772..3f145e311 100644
--- a/mdk-stage1/Makefile
+++ b/mdk-stage1/Makefile
@@ -128,7 +128,7 @@ NETWORK_STANDALONE_DEFS = -DDISABLE_CDROM -DDISABLE_DISK -DENABLE_NETWORK_STANDA
STAGE1OBJS-FULL = $(subst .c,-FULL.o,$(STAGE1_ALLSRC))
-BINS = init stage1 dhcp-client rescue-gui probe-modules
+BINS = init stage1 dhcp-client rescue-gui probe-modules hotplug
DIRS += pci-resource usb-resource
ifeq (i386, $(ARCH))
@@ -196,6 +196,10 @@ localclean:
rm -f *.o .depend *.rdz *.img $(BINS)
+hotplug: hotplug.o
+ $(DIET) $(CC) $(LDFLAGS) -o $@ $^
+ $(STRIPCMD) $@
+
rescue-gui: rescue-gui.o frontend-common.o params.o utils.o log.o automatic.o $(FRONTEND_LINK) $(STAGE1_LIBC)
$(DIET) $(CC) $(LDFLAGS) -o $@ $^
$(STRIPCMD) $@
diff --git a/mdk-stage1/NEWS b/mdk-stage1/NEWS
index 9bc98cc00..90b96f938 100644
--- a/mdk-stage1/NEWS
+++ b/mdk-stage1/NEWS
@@ -1,3 +1,5 @@
+- add firmware loader written in C (based on hotplug2) (mga#6323)
+
1.72
- fix URL passed to stage2 when user didn't provide the arch in the
install path (mga#6823)
diff --git a/mdk-stage1/hotplug.c b/mdk-stage1/hotplug.c
new file mode 100644
index 000000000..8e4379462
--- /dev/null
+++ b/mdk-stage1/hotplug.c
@@ -0,0 +1,90 @@
+/*
+ * Firmware loader
+ * Base on hotplug2 code (GPL v2) (http://code.google.com/p/hotplug2/)
+ * Copyright stepan@davidovic.cz, iSteve <isteve@bofh.cz> Tomas Janousek <tomi@nomi.cz>
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/**
+ * Function supplementing 'echo > file'
+ *
+ * @1 File to be written to
+ * @2 Data to be written
+ * @3 Data size
+ *
+ * Returns: 0 on success, -1 on failure.
+ */
+static int echo_to_file(const char *filename, const char *data, size_t size) {
+ FILE *fp;
+ size_t written;
+
+ fp = fopen(filename, "w");
+ if (fp == NULL)
+ return -1;
+ written = fwrite(data, size, 1, fp);
+ fclose(fp);
+
+ return (written == size) ? 0 : -1;
+}
+
+
+int main(int argc, char **argv) {
+ char buffer[1024];
+ char *devpath;
+ char *firmware;
+ char firmware_path[PATH_MAX];
+ char sysfs_path_loading[PATH_MAX];
+ char sysfs_path_data[PATH_MAX];
+ int rv;
+ FILE *infp, *outfp;
+ size_t inlen, outlen;
+
+ devpath = getenv("DEVPATH");
+ if (devpath == NULL)
+ return -1;
+
+ firmware = getenv("FIRMWARE");
+ if (firmware == NULL)
+ return -1;
+
+ if (snprintf(sysfs_path_loading, PATH_MAX, "/sysfs%s/loading", devpath) >= PATH_MAX)
+ return -1;
+ if (snprintf(sysfs_path_data, PATH_MAX, "/sysfs%s/data", devpath) >= PATH_MAX)
+ return -1;
+ if (snprintf(firmware_path, PATH_MAX, "%s/%s", argv[0], firmware) >= PATH_MAX)
+ return -1;
+
+ echo_to_file(sysfs_path_loading, "1\n", 2);
+
+ infp = fopen(firmware_path, "r");
+ if (infp == NULL) {
+ echo_to_file(sysfs_path_loading, "0\n", 2);
+ return -1;
+ }
+ outfp = fopen(sysfs_path_data, "w");
+ if (outfp == NULL) {
+ fclose(infp);
+ echo_to_file(sysfs_path_loading, "0\n", 2);
+ return -1;
+ }
+
+ rv = 0;
+ while ((inlen = fread(buffer, 1, 1024, infp)) > 0) {
+ outlen = fwrite(buffer, 1, inlen, outfp);
+ if (outlen != inlen) {
+ rv = -1;
+ break;
+ }
+ }
+
+ fclose(infp);
+
+ echo_to_file(sysfs_path_loading, "0\n", 2);
+
+ return rv;
+}