diff options
Diffstat (limited to 'mdk-stage1')
-rw-r--r-- | mdk-stage1/Makefile | 6 | ||||
-rw-r--r-- | mdk-stage1/NEWS | 2 | ||||
-rw-r--r-- | mdk-stage1/hotplug.c | 90 |
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; +} |