kopia lustrzana https://github.com/cariboulabs/cariboulite
119 wiersze
2.7 KiB
C
119 wiersze
2.7 KiB
C
#ifndef ZF_LOG_LEVEL
|
|
#define ZF_LOG_LEVEL ZF_LOG_VERBOSE
|
|
#endif
|
|
|
|
#define ZF_LOG_DEF_SRCLOC ZF_LOG_SRCLOC_LONG
|
|
#define ZF_LOG_TAG "CARIBOU_SMI_MODULES"
|
|
|
|
#define _GNU_SOURCE
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/syscall.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "zf_log/zf_log.h"
|
|
#include "caribou_smi.h"
|
|
#include "kernel/smi_stream_dev_gen.h"
|
|
|
|
|
|
#define delete_module(name, flags) syscall(__NR_delete_module, name, flags)
|
|
#define init_module(module_image, len, param_values) syscall(__NR_init_module, module_image, len, param_values)
|
|
#define finit_module(fd, param_values, flags) syscall(__NR_finit_module, fd, param_values, flags)
|
|
|
|
//===========================================================
|
|
int caribou_smi_check_modules_loaded(char* mod_name)
|
|
{
|
|
char line[256] = {0};
|
|
int found = 0;
|
|
FILE *fid = fopen ("/proc/modules", "r");
|
|
if (fid == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
while (fgets(line, sizeof(line), fid))
|
|
{
|
|
char* srch = strstr(line, mod_name);
|
|
if (srch != NULL)
|
|
{
|
|
if (!isspace(srch[strlen(mod_name)])) continue;
|
|
found = 1;
|
|
}
|
|
}
|
|
fclose(fid);
|
|
return found;
|
|
}
|
|
|
|
//===========================================================
|
|
int caribou_smi_remove_module(char* module_name)
|
|
{
|
|
if (delete_module(module_name, O_NONBLOCK) != 0)
|
|
{
|
|
ZF_LOGE("Module removing '%s' failed", module_name);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//===========================================================
|
|
int caribou_smi_insert_smi_modules(char* module_name,
|
|
uint8_t* buffer,
|
|
size_t len,
|
|
const char* params)
|
|
{
|
|
if (init_module(buffer, len, params) != 0)
|
|
{
|
|
ZF_LOGE("Module insertion '%s' failed", module_name);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//===========================================================
|
|
int caribou_smi_check_modules(bool reload)
|
|
{
|
|
int ret = 0;
|
|
int bcm_smi_dev_loaded = caribou_smi_check_modules_loaded("bcm2835_smi_dev");
|
|
int smi_stream_dev_loaded = caribou_smi_check_modules_loaded("smi_stream_dev");
|
|
int bcm_smi_loaded = caribou_smi_check_modules_loaded("bcm2835_smi");
|
|
|
|
if (bcm_smi_loaded != 1)
|
|
{
|
|
ZF_LOGE("SMI base driver not loaded - check device tree");
|
|
return -1;
|
|
}
|
|
|
|
if (smi_stream_dev_loaded == 1 && reload)
|
|
{
|
|
ZF_LOGD("Unloading smi-stream module");
|
|
ret = caribou_smi_remove_module("smi_stream_dev");
|
|
smi_stream_dev_loaded = 0;
|
|
}
|
|
|
|
if (bcm_smi_dev_loaded == 1)
|
|
{
|
|
ret = caribou_smi_remove_module("bcm2835_smi_dev");
|
|
}
|
|
|
|
|
|
if (ret != 0)
|
|
{
|
|
ZF_LOGE("Error unloading module from system");
|
|
return -1;
|
|
}
|
|
|
|
if (!smi_stream_dev_loaded || reload)
|
|
{
|
|
ZF_LOGD("Loading smi-stream module");
|
|
return caribou_smi_insert_smi_modules("smi_stream_dev", smi_stream_dev, sizeof(smi_stream_dev), "");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|