|
Packit |
534379 |
// Copyright(c) 2018-2020, Intel Corporation
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// Redistribution and use in source and binary forms, with or without
|
|
Packit |
534379 |
// modification, are permitted provided that the following conditions are met:
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// * Redistributions of source code must retain the above copyright notice,
|
|
Packit |
534379 |
// this list of conditions and the following disclaimer.
|
|
Packit |
534379 |
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
Packit |
534379 |
// this list of conditions and the following disclaimer in the documentation
|
|
Packit |
534379 |
// and/or other materials provided with the distribution.
|
|
Packit |
534379 |
// * Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
534379 |
// may be used to endorse or promote products derived from this software
|
|
Packit |
534379 |
// without specific prior written permission.
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
534379 |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
534379 |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
534379 |
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
Packit |
534379 |
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
Packit |
534379 |
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
Packit |
534379 |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
Packit |
534379 |
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
Packit |
534379 |
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
534379 |
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
Packit |
534379 |
// POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
534379 |
#include <config.h>
|
|
Packit |
534379 |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
534379 |
#define _GNU_SOURCE
|
|
Packit |
534379 |
#include <stdio.h>
|
|
Packit |
534379 |
#include <stdlib.h>
|
|
Packit |
534379 |
#include <string.h>
|
|
Packit |
534379 |
#include <stdint.h>
|
|
Packit |
534379 |
#include <dlfcn.h>
|
|
Packit |
534379 |
#include <sys/types.h>
|
|
Packit |
534379 |
#include <dirent.h>
|
|
Packit |
534379 |
#include <linux/limits.h>
|
|
Packit |
534379 |
#include <pthread.h>
|
|
Packit |
534379 |
#include <pwd.h>
|
|
Packit |
534379 |
#include <unistd.h>
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#include <json-c/json.h>
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#include "pluginmgr.h"
|
|
Packit |
534379 |
#include "opae_int.h"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define OPAE_PLUGIN_CONFIGURE "opae_plugin_configure"
|
|
Packit |
534379 |
typedef int (*opae_plugin_configure_t)(opae_api_adapter_table *, const char *);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
typedef struct _platform_data {
|
|
Packit |
534379 |
uint16_t vendor_id;
|
|
Packit |
534379 |
uint16_t device_id;
|
|
Packit |
534379 |
const char *native_plugin;
|
|
Packit |
534379 |
uint32_t flags;
|
|
Packit |
534379 |
#define OPAE_PLATFORM_DATA_DETECTED 0x00000001
|
|
Packit |
534379 |
#define OPAE_PLATFORM_DATA_LOADED 0x00000002
|
|
Packit |
534379 |
} platform_data;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
static platform_data platform_data_table[] = {
|
|
Packit |
534379 |
{ 0x8086, 0xbcbd, "libxfpga.so", 0 },
|
|
Packit |
534379 |
{ 0x8086, 0xbcc0, "libxfpga.so", 0 },
|
|
Packit |
534379 |
{ 0x8086, 0xbcc1, "libxfpga.so", 0 },
|
|
Packit |
534379 |
{ 0x8086, 0x09c4, "libxfpga.so", 0 },
|
|
Packit |
534379 |
{ 0x8086, 0x09c5, "libxfpga.so", 0 },
|
|
Packit |
534379 |
{ 0x8086, 0x0b2b, "libxfpga.so", 0 },
|
|
Packit |
534379 |
{ 0x8086, 0x0b2c, "libxfpga.so", 0 },
|
|
Packit |
534379 |
{ 0x8086, 0x0b30, "libxfpga.so", 0 },
|
|
Packit |
534379 |
{ 0x8086, 0x0b31, "libxfpga.so", 0 },
|
|
Packit |
534379 |
{ 0, 0, NULL, 0 },
|
|
Packit |
534379 |
};
|
|
Packit |
534379 |
|
|
Packit |
534379 |
static int initialized;
|
|
Packit |
534379 |
static int finalizing;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC opae_api_adapter_table *adapter_list = (void *)0;
|
|
Packit |
534379 |
static pthread_mutex_t adapter_list_lock =
|
|
Packit |
534379 |
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define MAX_PLUGINS PLUGIN_SUPPORTED_DEVICES_MAX
|
|
Packit |
534379 |
STATIC plugin_cfg *opae_plugin_mgr_config_list;
|
|
Packit |
534379 |
STATIC int opae_plugin_mgr_plugin_count;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define CFG_PATH_MAX 64
|
|
Packit |
534379 |
#define HOME_CFG_PATHS 3
|
|
Packit |
534379 |
STATIC const char _opae_home_cfg_files[HOME_CFG_PATHS][CFG_PATH_MAX] = {
|
|
Packit |
534379 |
{ "/.local/opae.cfg" },
|
|
Packit |
534379 |
{ "/.local/opae/opae.cfg" },
|
|
Packit |
534379 |
{ "/.config/opae/opae.cfg" },
|
|
Packit |
534379 |
};
|
|
Packit |
534379 |
#define SYS_CFG_PATHS 2
|
|
Packit |
534379 |
STATIC const char _opae_sys_cfg_files[SYS_CFG_PATHS][CFG_PATH_MAX] = {
|
|
Packit |
534379 |
{ "/usr/local/etc/opae/opae.cfg" },
|
|
Packit |
534379 |
{ "/etc/opae/opae.cfg" },
|
|
Packit |
534379 |
};
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// Find the canonicalized configuration file. If null, the file was not found.
|
|
Packit |
534379 |
// Otherwise, it's the first configuration file found from a list of possible
|
|
Packit |
534379 |
// paths. Note: The char * returned is allocated here, caller must free.
|
|
Packit |
534379 |
STATIC char *find_cfg(void)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int i = 0;
|
|
Packit |
534379 |
char *file_name = NULL;
|
|
Packit |
534379 |
char home_cfg[PATH_MAX] = { 0, };
|
|
Packit |
534379 |
char *home_cfg_ptr = &home_cfg[0];
|
|
Packit |
534379 |
size_t len;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// get the user's home directory
|
|
Packit |
534379 |
struct passwd *user_passwd = getpwuid(getuid());
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// first look in possible paths in the users home directory
|
|
Packit |
534379 |
for (i = 0; i < HOME_CFG_PATHS; ++i) {
|
|
Packit |
534379 |
len = strnlen(user_passwd->pw_dir,
|
|
Packit |
534379 |
sizeof(home_cfg) - 1);
|
|
Packit |
534379 |
memcpy(home_cfg, user_passwd->pw_dir, len);
|
|
Packit |
534379 |
home_cfg[len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
home_cfg_ptr = home_cfg + strlen(home_cfg);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len = strnlen(_opae_home_cfg_files[i], CFG_PATH_MAX);
|
|
Packit |
534379 |
memcpy(home_cfg_ptr, _opae_home_cfg_files[i], len);
|
|
Packit |
534379 |
home_cfg_ptr[len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
file_name = canonicalize_file_name(home_cfg);
|
|
Packit |
534379 |
if (file_name)
|
|
Packit |
534379 |
return file_name;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
home_cfg[0] = '\0';
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// now look in possible system paths
|
|
Packit |
534379 |
for (i = 0; i < SYS_CFG_PATHS; ++i) {
|
|
Packit |
534379 |
len = strnlen(_opae_sys_cfg_files[i], CFG_PATH_MAX);
|
|
Packit |
534379 |
memcpy(home_cfg, _opae_sys_cfg_files[i], len);
|
|
Packit |
534379 |
home_cfg[len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
file_name = canonicalize_file_name(home_cfg);
|
|
Packit |
534379 |
if (file_name)
|
|
Packit |
534379 |
return file_name;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC void *opae_plugin_mgr_find_plugin(const char *lib_path)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
char plugin_path[PATH_MAX];
|
|
Packit |
534379 |
const char *search_paths[] = { OPAE_MODULE_SEARCH_PATHS };
|
|
Packit |
534379 |
unsigned i;
|
|
Packit |
534379 |
void *dl_handle;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
for (i = 0 ;
|
|
Packit |
534379 |
i < sizeof(search_paths) / sizeof(search_paths[0]) ; ++i) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(plugin_path, sizeof(plugin_path),
|
|
Packit |
534379 |
"%s%s", search_paths[i], lib_path);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
dl_handle = dlopen(plugin_path, RTLD_LAZY | RTLD_LOCAL);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (dl_handle)
|
|
Packit |
534379 |
return dl_handle;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC opae_api_adapter_table *opae_plugin_mgr_alloc_adapter(const char *lib_path)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
void *dl_handle;
|
|
Packit |
534379 |
opae_api_adapter_table *adapter;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
dl_handle = opae_plugin_mgr_find_plugin(lib_path);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!dl_handle) {
|
|
Packit |
534379 |
char *err = dlerror();
|
|
Packit |
534379 |
OPAE_ERR("failed to load \"%s\" %s", lib_path, err ? err : "");
|
|
Packit |
534379 |
return NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
adapter = (opae_api_adapter_table *)calloc(
|
|
Packit |
534379 |
1, sizeof(opae_api_adapter_table));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!adapter) {
|
|
Packit |
534379 |
dlclose(dl_handle);
|
|
Packit |
534379 |
OPAE_ERR("out of memory");
|
|
Packit |
534379 |
return NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
adapter->plugin.path = (char *)lib_path;
|
|
Packit |
534379 |
adapter->plugin.dl_handle = dl_handle;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return adapter;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int opae_plugin_mgr_free_adapter(opae_api_adapter_table *adapter)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
char *err;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = dlclose(adapter->plugin.dl_handle);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
err = dlerror();
|
|
Packit |
534379 |
OPAE_ERR("dlclose failed with %d %s", res, err ? err : "");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
free(adapter);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int opae_plugin_mgr_configure_plugin(opae_api_adapter_table *adapter,
|
|
Packit |
534379 |
const char *config)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
opae_plugin_configure_t cfg;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
cfg = (opae_plugin_configure_t)dlsym(adapter->plugin.dl_handle,
|
|
Packit |
534379 |
OPAE_PLUGIN_CONFIGURE);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!cfg) {
|
|
Packit |
534379 |
OPAE_ERR("failed to find %s in \"%s\"", OPAE_PLUGIN_CONFIGURE,
|
|
Packit |
534379 |
adapter->plugin.path);
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return cfg(adapter, config);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC void opae_plugin_mgr_reset_cfg(void)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
plugin_cfg *ptr = opae_plugin_mgr_config_list;
|
|
Packit |
534379 |
plugin_cfg *tmp = NULL;
|
|
Packit |
534379 |
while (ptr) {
|
|
Packit |
534379 |
tmp = ptr;
|
|
Packit |
534379 |
ptr = ptr->next;
|
|
Packit |
534379 |
free(tmp->cfg);
|
|
Packit |
534379 |
free(tmp);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
opae_plugin_mgr_config_list = NULL;
|
|
Packit |
534379 |
opae_plugin_mgr_plugin_count = 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC void opae_plugin_mgr_add_plugin(plugin_cfg *cfg)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
plugin_cfg *ptr = opae_plugin_mgr_config_list;
|
|
Packit |
534379 |
cfg->next = NULL;
|
|
Packit |
534379 |
if (!ptr) {
|
|
Packit |
534379 |
opae_plugin_mgr_config_list = cfg;
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
while (ptr->next) {
|
|
Packit |
534379 |
ptr = ptr->next;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
ptr->next = cfg;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
opae_plugin_mgr_plugin_count++;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int opae_plugin_mgr_initialize_all(void)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
opae_api_adapter_table *aptr;
|
|
Packit |
534379 |
int errors = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
for (aptr = adapter_list; aptr; aptr = aptr->next) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (aptr->initialize) {
|
|
Packit |
534379 |
res = aptr->initialize();
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
OPAE_MSG("\"%s\" initialize() routine failed",
|
|
Packit |
534379 |
aptr->plugin.path);
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return errors;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_plugin_mgr_finalize_all(void)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
opae_api_adapter_table *aptr;
|
|
Packit |
534379 |
int errors = 0;
|
|
Packit |
534379 |
int i = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
opae_mutex_lock(res, &adapter_list_lock);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (finalizing)
|
|
Packit |
534379 |
return 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
finalizing = 1;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
for (aptr = adapter_list; aptr;) {
|
|
Packit |
534379 |
opae_api_adapter_table *trash;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (aptr->finalize) {
|
|
Packit |
534379 |
res = aptr->finalize();
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
OPAE_MSG("\"%s\" finalize() routine failed",
|
|
Packit |
534379 |
aptr->plugin.path);
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
trash = aptr;
|
|
Packit |
534379 |
aptr = aptr->next;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (opae_plugin_mgr_free_adapter(trash))
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
adapter_list = NULL;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// reset platforms detected to 0
|
|
Packit |
534379 |
for (i = 0 ; platform_data_table[i].native_plugin ; ++i) {
|
|
Packit |
534379 |
platform_data_table[i].flags = 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
opae_plugin_mgr_reset_cfg();
|
|
Packit |
534379 |
initialized = 0;
|
|
Packit |
534379 |
finalizing = 0;
|
|
Packit |
534379 |
opae_mutex_unlock(res, &adapter_list_lock);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return errors;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define JSON_GET(_jobj, _key, _jvar) \
|
|
Packit |
534379 |
do { \
|
|
Packit |
534379 |
if (!json_object_object_get_ex(_jobj, _key, _jvar)) { \
|
|
Packit |
534379 |
OPAE_ERR("Error getting object: %s", _key); \
|
|
Packit |
534379 |
return 1; \
|
|
Packit |
534379 |
} \
|
|
Packit |
534379 |
} while (0)
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define MAX_PLUGIN_CFG_SIZE 8192
|
|
Packit |
534379 |
STATIC int process_plugin(const char *name, json_object *j_config)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
json_object *j_plugin = NULL;
|
|
Packit |
534379 |
json_object *j_plugin_cfg = NULL;
|
|
Packit |
534379 |
json_object *j_enabled = NULL;
|
|
Packit |
534379 |
const char *stringified = NULL;
|
|
Packit |
534379 |
size_t len;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
JSON_GET(j_config, "plugin", &j_plugin);
|
|
Packit |
534379 |
JSON_GET(j_config, "configuration", &j_plugin_cfg);
|
|
Packit |
534379 |
JSON_GET(j_config, "enabled", &j_enabled);
|
|
Packit |
534379 |
if (json_object_get_string_len(j_plugin) > PLUGIN_NAME_MAX) {
|
|
Packit |
534379 |
OPAE_ERR("plugin name too long");
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
plugin_cfg *cfg = malloc(sizeof(plugin_cfg));
|
|
Packit |
534379 |
if (!cfg) {
|
|
Packit |
534379 |
OPAE_ERR("Could not allocate memory for plugin cfg");
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
stringified = json_object_to_json_string_ext(j_plugin_cfg, JSON_C_TO_STRING_PLAIN);
|
|
Packit |
534379 |
if (!stringified) {
|
|
Packit |
534379 |
OPAE_ERR("error getting plugin configuration");
|
|
Packit |
534379 |
free(cfg);
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
cfg->cfg_size = strlen(stringified) + 1;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (cfg->cfg_size >= MAX_PLUGIN_CFG_SIZE) {
|
|
Packit |
534379 |
OPAE_ERR("plugin config too large");
|
|
Packit |
534379 |
free(cfg);
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
cfg->cfg = malloc(cfg->cfg_size);
|
|
Packit |
534379 |
if (!cfg->cfg) {
|
|
Packit |
534379 |
OPAE_ERR("error allocating memory for plugin configuration");
|
|
Packit |
534379 |
cfg->cfg_size = 0;
|
|
Packit |
534379 |
free(cfg);
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len = strnlen(stringified, cfg->cfg_size - 1);
|
|
Packit |
534379 |
memcpy(cfg->cfg, stringified, len);
|
|
Packit |
534379 |
cfg->cfg[len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len = strnlen(name, PLUGIN_NAME_MAX - 1);
|
|
Packit |
534379 |
memcpy(cfg->name, name, len);
|
|
Packit |
534379 |
cfg->name[len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len = strnlen(json_object_get_string(j_plugin), PLUGIN_NAME_MAX - 1);
|
|
Packit |
534379 |
memcpy(cfg->plugin, json_object_get_string(j_plugin), len);
|
|
Packit |
534379 |
cfg->plugin[len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
cfg->enabled = json_object_get_boolean(j_enabled);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
opae_plugin_mgr_add_plugin(cfg);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int process_cfg_buffer(const char *buffer, const char *filename)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int num_plugins = 0;
|
|
Packit |
534379 |
int num_errors = 0;
|
|
Packit |
534379 |
int i = 0;
|
|
Packit |
534379 |
int res = 1;
|
|
Packit |
534379 |
json_object *root = NULL;
|
|
Packit |
534379 |
json_object *j_plugins = NULL;
|
|
Packit |
534379 |
json_object *j_configs = NULL;
|
|
Packit |
534379 |
json_object *j_plugin = NULL;
|
|
Packit |
534379 |
json_object *j_config = NULL;
|
|
Packit |
534379 |
const char *plugin_name = NULL;
|
|
Packit |
534379 |
enum json_tokener_error j_err = json_tokener_success;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
root = json_tokener_parse_verbose(buffer, &j_err);
|
|
Packit |
534379 |
if (!root) {
|
|
Packit |
534379 |
OPAE_ERR("Error parsing config file: '%s' - %s", filename,
|
|
Packit |
534379 |
json_tokener_error_desc(j_err));
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!json_object_object_get_ex(root, "plugins", &j_plugins)) {
|
|
Packit |
534379 |
OPAE_ERR("Error parsing config file: '%s' - missing 'plugins'", filename);
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (!json_object_object_get_ex(root, "configurations", &j_configs)) {
|
|
Packit |
534379 |
OPAE_ERR("Error parsing config file: '%s' - missing 'configs'", filename);
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!json_object_is_type(j_plugins, json_type_array)) {
|
|
Packit |
534379 |
OPAE_ERR("'plugins' JSON object not array type");
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
num_plugins = json_object_array_length(j_plugins);
|
|
Packit |
534379 |
num_errors = 0;
|
|
Packit |
534379 |
for (i = 0; i < num_plugins; ++i) {
|
|
Packit |
534379 |
j_plugin = json_object_array_get_idx(j_plugins, i);
|
|
Packit |
534379 |
plugin_name = json_object_get_string(j_plugin);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (json_object_object_get_ex(j_configs, plugin_name, &j_config)) {
|
|
Packit |
534379 |
num_errors += process_plugin(plugin_name, j_config);
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
OPAE_ERR("Could not find plugin configuration for '%s'", plugin_name);
|
|
Packit |
534379 |
num_errors += 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
res = num_errors;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_free:
|
|
Packit |
534379 |
if (root)
|
|
Packit |
534379 |
json_object_put(root);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define MAX_CFG_SIZE 4096
|
|
Packit |
534379 |
STATIC int opae_plugin_mgr_parse_config(const char *filename)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
char buffer[MAX_CFG_SIZE] = { 0 };
|
|
Packit |
534379 |
char *ptr = &buffer[0];
|
|
Packit |
534379 |
size_t bytes_read = 0, total_read = 0;
|
|
Packit |
534379 |
FILE *fp = NULL;
|
|
Packit |
534379 |
if (filename) {
|
|
Packit |
534379 |
fp = fopen(filename, "r");
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
OPAE_MSG("config file is NULL");
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!fp) {
|
|
Packit |
534379 |
OPAE_ERR("Error opening config file: %s", filename);
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
while ((bytes_read = fread(ptr + total_read, 1, 1, fp))
|
|
Packit |
534379 |
&& total_read < MAX_CFG_SIZE) {
|
|
Packit |
534379 |
total_read += bytes_read;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (ferror(fp)) {
|
|
Packit |
534379 |
OPAE_ERR("Error reading config file: %s - %s", filename, strerror(errno));
|
|
Packit |
534379 |
goto out_err;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (!feof(fp)) {
|
|
Packit |
534379 |
OPAE_ERR("Unknown error reading config file: %s", filename);
|
|
Packit |
534379 |
goto out_err;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
fclose(fp);
|
|
Packit |
534379 |
fp = NULL;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return process_cfg_buffer(buffer, filename);
|
|
Packit |
534379 |
out_err:
|
|
Packit |
534379 |
fclose(fp);
|
|
Packit |
534379 |
fp = NULL;
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int opae_plugin_mgr_register_adapter(opae_api_adapter_table *adapter)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
opae_api_adapter_table *aptr;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
adapter->next = NULL;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!adapter_list) {
|
|
Packit |
534379 |
adapter_list = adapter;
|
|
Packit |
534379 |
return 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// new entries go to the end of the list.
|
|
Packit |
534379 |
for (aptr = adapter_list; aptr->next; aptr = aptr->next)
|
|
Packit |
534379 |
/* find the last entry */;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
aptr->next = adapter;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC void opae_plugin_mgr_detect_platform(uint16_t vendor, uint16_t device)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int i;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
for (i = 0 ; platform_data_table[i].native_plugin ; ++i) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (platform_data_table[i].vendor_id == vendor &&
|
|
Packit |
534379 |
platform_data_table[i].device_id == device) {
|
|
Packit |
534379 |
OPAE_DBG("platform detected: vid=0x%04x did=0x%04x -> %s",
|
|
Packit |
534379 |
vendor, device,
|
|
Packit |
534379 |
platform_data_table[i].native_plugin);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
platform_data_table[i].flags |= OPAE_PLATFORM_DATA_DETECTED;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int opae_plugin_mgr_detect_platforms(void)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
DIR *dir;
|
|
Packit |
534379 |
char base_dir[PATH_MAX];
|
|
Packit |
534379 |
char file_path[PATH_MAX];
|
|
Packit |
534379 |
struct dirent *dirent;
|
|
Packit |
534379 |
int errors = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// Iterate over the directories in /sys/bus/pci/devices.
|
|
Packit |
534379 |
// This directory contains symbolic links to device directories
|
|
Packit |
534379 |
// where 'vendor' and 'device' files exist.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
memcpy(base_dir, "/sys/bus/pci/devices", 21);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
dir = opendir(base_dir);
|
|
Packit |
534379 |
if (!dir) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to open %s. Aborting platform detection.", base_dir);
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
while ((dirent = readdir(dir)) != NULL) {
|
|
Packit |
534379 |
FILE *fp;
|
|
Packit |
534379 |
unsigned vendor = 0;
|
|
Packit |
534379 |
unsigned device = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!strcmp(dirent->d_name, ".") ||
|
|
Packit |
534379 |
!strcmp(dirent->d_name, ".."))
|
|
Packit |
534379 |
continue;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// Read the 'vendor' file.
|
|
Packit |
534379 |
if (snprintf(file_path, sizeof(file_path),
|
|
Packit |
534379 |
"%s/%s/vendor",
|
|
Packit |
534379 |
base_dir,
|
|
Packit |
534379 |
dirent->d_name) < 0) {
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fp = fopen(file_path, "r");
|
|
Packit |
534379 |
if (!fp) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to open %s. Aborting platform detection.", file_path);
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (EOF == fscanf(fp, "%x", &vendor)) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to read %s. Aborting platform detection.", file_path);
|
|
Packit |
534379 |
fclose(fp);
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fclose(fp);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// Read the 'device' file.
|
|
Packit |
534379 |
if (snprintf(file_path, sizeof(file_path),
|
|
Packit |
534379 |
"%s/%s/device",
|
|
Packit |
534379 |
base_dir,
|
|
Packit |
534379 |
dirent->d_name) < 0) {
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fp = fopen(file_path, "r");
|
|
Packit |
534379 |
if (!fp) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to open %s. Aborting platform detection.", file_path);
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (EOF == fscanf(fp, "%x", &device)) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to read %s. Aborting platform detection.", file_path);
|
|
Packit |
534379 |
fclose(fp);
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fclose(fp);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// Detect platform for this (vendor, device).
|
|
Packit |
534379 |
opae_plugin_mgr_detect_platform((uint16_t) vendor, (uint16_t) device);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_close:
|
|
Packit |
534379 |
closedir(dir);
|
|
Packit |
534379 |
return errors;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int opae_plugin_mgr_load_cfg_plugin(plugin_cfg *cfg)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int res = 0;
|
|
Packit |
534379 |
opae_api_adapter_table *adapter = NULL;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (cfg->enabled && cfg->cfg && cfg->cfg_size) {
|
|
Packit |
534379 |
adapter = opae_plugin_mgr_alloc_adapter(cfg->plugin);
|
|
Packit |
534379 |
if (!adapter) {
|
|
Packit |
534379 |
OPAE_ERR("malloc failed");
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
res = opae_plugin_mgr_configure_plugin(adapter, cfg->cfg);
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
opae_plugin_mgr_free_adapter(adapter);
|
|
Packit |
534379 |
OPAE_ERR("failed to configure plugin \"%s\"",
|
|
Packit |
534379 |
cfg->name);
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = opae_plugin_mgr_register_adapter(adapter);
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
opae_plugin_mgr_free_adapter(adapter);
|
|
Packit |
534379 |
OPAE_ERR("Failed to register \"%s\"", cfg->name);
|
|
Packit |
534379 |
return 1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int opae_plugin_mgr_load_cfg_plugins(void)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
plugin_cfg *ptr = opae_plugin_mgr_config_list;
|
|
Packit |
534379 |
int errors = 0;
|
|
Packit |
534379 |
while (ptr) {
|
|
Packit |
534379 |
errors += opae_plugin_mgr_load_cfg_plugin(ptr);
|
|
Packit |
534379 |
ptr = ptr->next;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return errors;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int opae_plugin_mgr_load_dflt_plugins(int *platforms_detected)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int i = 0, j = 0;
|
|
Packit |
534379 |
int res = 0;
|
|
Packit |
534379 |
opae_api_adapter_table *adapter = NULL;
|
|
Packit |
534379 |
int errors = opae_plugin_mgr_detect_platforms();
|
|
Packit |
534379 |
if (errors)
|
|
Packit |
534379 |
return errors;
|
|
Packit |
534379 |
// Load each of the native plugins that were detected.
|
|
Packit |
534379 |
*platforms_detected = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
for (i = 0 ; platform_data_table[i].native_plugin ; ++i) {
|
|
Packit |
534379 |
const char *native_plugin;
|
|
Packit |
534379 |
int already_loaded;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!(platform_data_table[i].flags & OPAE_PLATFORM_DATA_DETECTED))
|
|
Packit |
534379 |
continue; // This platform was not detected.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
native_plugin = platform_data_table[i].native_plugin;
|
|
Packit |
534379 |
(*platforms_detected)++;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// Iterate over the table again to prevent multiple loads
|
|
Packit |
534379 |
// of the same native plugin.
|
|
Packit |
534379 |
already_loaded = 0;
|
|
Packit |
534379 |
for (j = 0 ; platform_data_table[j].native_plugin ; ++j) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!strcmp(native_plugin, platform_data_table[j].native_plugin) &&
|
|
Packit |
534379 |
(platform_data_table[j].flags & OPAE_PLATFORM_DATA_LOADED)) {
|
|
Packit |
534379 |
already_loaded = 1;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (already_loaded)
|
|
Packit |
534379 |
continue;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
adapter = opae_plugin_mgr_alloc_adapter(native_plugin);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!adapter) {
|
|
Packit |
534379 |
OPAE_ERR("malloc failed");
|
|
Packit |
534379 |
return ++errors;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// TODO: pass serialized json for native plugin
|
|
Packit |
534379 |
res = opae_plugin_mgr_configure_plugin(adapter, "");
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
opae_plugin_mgr_free_adapter(adapter);
|
|
Packit |
534379 |
OPAE_ERR("failed to configure plugin \"%s\"",
|
|
Packit |
534379 |
native_plugin);
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
continue; // Keep going.
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = opae_plugin_mgr_register_adapter(adapter);
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
opae_plugin_mgr_free_adapter(adapter);
|
|
Packit |
534379 |
OPAE_ERR("Failed to register \"%s\"", native_plugin);
|
|
Packit |
534379 |
++errors;
|
|
Packit |
534379 |
continue; // Keep going.
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
platform_data_table[i].flags |= OPAE_PLATFORM_DATA_LOADED;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return errors;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_plugin_mgr_initialize(const char *cfg_file)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
int errors = 0;
|
|
Packit |
534379 |
int platforms_detected = 0;
|
|
Packit |
534379 |
opae_plugin_mgr_plugin_count = 0;
|
|
Packit |
534379 |
char *found_cfg = NULL;
|
|
Packit |
534379 |
const char *use_cfg = NULL;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
opae_mutex_lock(res, &adapter_list_lock);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (initialized) { // prevent multiple init.
|
|
Packit |
534379 |
opae_mutex_unlock(res, &adapter_list_lock);
|
|
Packit |
534379 |
return 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
found_cfg = find_cfg();
|
|
Packit |
534379 |
use_cfg = cfg_file ? cfg_file : found_cfg;
|
|
Packit |
534379 |
if (use_cfg) {
|
|
Packit |
534379 |
opae_plugin_mgr_parse_config(use_cfg);
|
|
Packit |
534379 |
if (found_cfg) {
|
|
Packit |
534379 |
free(found_cfg);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (opae_plugin_mgr_plugin_count) {
|
|
Packit |
534379 |
errors = opae_plugin_mgr_load_cfg_plugins();
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
// fail-safe, try to detect plugins based on supported devices
|
|
Packit |
534379 |
errors = opae_plugin_mgr_load_dflt_plugins(&platforms_detected);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (errors)
|
|
Packit |
534379 |
goto out_unlock;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// Call each plugin's initialization routine.
|
|
Packit |
534379 |
errors += opae_plugin_mgr_initialize_all();
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!errors && (opae_plugin_mgr_plugin_count || platforms_detected))
|
|
Packit |
534379 |
initialized = 1;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_unlock:
|
|
Packit |
534379 |
opae_mutex_unlock(res, &adapter_list_lock);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return errors;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_plugin_mgr_for_each_adapter
|
|
Packit |
534379 |
(int (*callback)(const opae_api_adapter_table *, void *), void *context)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
int cb_res = OPAE_ENUM_CONTINUE;
|
|
Packit |
534379 |
opae_api_adapter_table *aptr;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!callback) {
|
|
Packit |
534379 |
OPAE_ERR("NULL callback passed to %s()", __func__);
|
|
Packit |
534379 |
return OPAE_ENUM_STOP;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
opae_mutex_lock(res, &adapter_list_lock);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
for (aptr = adapter_list; aptr; aptr = aptr->next) {
|
|
Packit |
534379 |
cb_res = callback(aptr, context);
|
|
Packit |
534379 |
if (cb_res)
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
opae_mutex_unlock(res, &adapter_list_lock);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return cb_res;
|
|
Packit |
534379 |
}
|