diff options
author | Christopher N. Hesse <raymanfx@gmail.com> | 2017-08-02 15:21:35 +0200 |
---|---|---|
committer | Christopher N. Hesse <raymanfx@gmail.com> | 2017-08-13 08:38:58 +0000 |
commit | 231dc651ab1ca082ba6d63559d79ae748b02eb1f (patch) | |
tree | 46f19477a6fe432399d7507eca8fbe0e0945451d | |
parent | 2c868b183c81f46dc110caa53050d0a14686d902 (diff) | |
download | android_hardware_samsung-231dc651ab1ca082ba6d63559d79ae748b02eb1f.tar.gz android_hardware_samsung-231dc651ab1ca082ba6d63559d79ae748b02eb1f.tar.bz2 android_hardware_samsung-231dc651ab1ca082ba6d63559d79ae748b02eb1f.zip |
wifiloader: Load kernel module if present
Samsung does this in the macloader service,
but this is the more appropriate place for
our platform.
Change-Id: I6335fea1d73d48f3c3f9938f33b536c5cda52acb
-rw-r--r-- | wifiloader/Android.mk | 8 | ||||
-rw-r--r-- | wifiloader/wifiloader.c | 72 |
2 files changed, 79 insertions, 1 deletions
diff --git a/wifiloader/Android.mk b/wifiloader/Android.mk index 15c9dc2..72c1c49 100644 --- a/wifiloader/Android.mk +++ b/wifiloader/Android.mk @@ -9,6 +9,14 @@ LOCAL_SRC_FILES := \ LOCAL_SHARED_LIBRARIES := \ liblog libutils +ifneq ($(WIFI_DRIVER_MODULE_NAME),) +LOCAL_CFLAGS += -DWIFI_DRIVER_MODULE_NAME=\"$(WIFI_DRIVER_MODULE_NAME)\" +endif + +ifneq ($(WIFI_DRIVER_MODULE_PATH),) +LOCAL_CFLAGS += -DWIFI_DRIVER_MODULE_PATH=\"$(WIFI_DRIVER_MODULE_PATH)\" +endif + LOCAL_MODULE := wifiloader LOCAL_MODULE_TAGS := optional diff --git a/wifiloader/wifiloader.c b/wifiloader/wifiloader.c index 54afdaf..6c29660 100644 --- a/wifiloader/wifiloader.c +++ b/wifiloader/wifiloader.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015 Andreas Schneider <asn@cryptomilk.org> + * Copyright (c) 2017 Christopher N. Hesse <raymanfx@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,17 +19,86 @@ #define LOG_NDEBUG 0 #include <errno.h> +#include <fcntl.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <cutils/log.h> +#include <sys/stat.h> +#include <sys/syscall.h> -#define DEFERRED_INITCALLS "/proc/deferred_initcalls" +#define DEFERRED_INITCALLS "/proc/deferred_initcalls" + +#ifndef WIFI_DRIVER_MODULE_NAME +#define WIFI_DRIVER_MODULE_NAME "wlan" +#endif + +#ifndef WIFI_DRIVER_MODULE_PATH +#define WIFI_DRIVER_MODULE_PATH "/system/lib/modules/" WIFI_DRIVER_MODULE_NAME ".ko" +#endif + +#define finit_module(fd, params, flags) syscall(__NR_finit_module, fd, params, flags) + + +static int check_module_loaded(char const *tag) +{ + FILE *proc; + char line[126]; + + if ((proc = fopen("/proc/modules", "r")) == NULL) { + ALOGW("Could not open %s: %s", "/proc/modules", strerror(errno)); + return -errno; + } + + while ((fgets(line, sizeof(line), proc)) != NULL) { + if (strncmp(line, tag, strlen(tag)) == 0) { + fclose(proc); + return 1; + } + } + + fclose(proc); + return 0; +} + +static int load_module(char const *path) +{ + int fd; + + if (check_module_loaded(WIFI_DRIVER_MODULE_NAME) > 0) { + ALOGE("Driver: %s already loaded", path); + return -1; + } + + fd = open(path, O_RDONLY); + if (fd == -1) { + ALOGE("Failed to open %s - error: %s", path, strerror(errno)); + return -errno; + } + + // load the .ko image + if (finit_module(fd, "", 0) != 0) { + ALOGE("Failed to load module %s - error: %s", path, strerror(errno)); + close(fd); + return -errno; + } + + close(fd); + return 0; +} int main(void) { char buf[8] = { '\0' }; FILE *fp; size_t r; + int fd; + struct stat st; + + if (stat(WIFI_DRIVER_MODULE_PATH, &st) == 0) { + ALOGD("Loading WiFi kernel module: %s", WIFI_DRIVER_MODULE_PATH); + load_module(WIFI_DRIVER_MODULE_PATH); + } ALOGD("Trigger initcall of deferred modules\n"); |