|
Packit |
6639f8 |
// Copyright(c) 2018-2020, Intel Corporation
|
|
Packit |
6639f8 |
//
|
|
Packit |
6639f8 |
// Redistribution and use in source and binary forms, with or without
|
|
Packit |
6639f8 |
// modification, are permitted provided that the following conditions are met:
|
|
Packit |
6639f8 |
//
|
|
Packit |
6639f8 |
// * Redistributions of source code must retain the above copyright notice,
|
|
Packit |
6639f8 |
// this list of conditions and the following disclaimer.
|
|
Packit |
6639f8 |
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
Packit |
6639f8 |
// this list of conditions and the following disclaimer in the documentation
|
|
Packit |
6639f8 |
// and/or other materials provided with the distribution.
|
|
Packit |
6639f8 |
// * Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
6639f8 |
// may be used to endorse or promote products derived from this software
|
|
Packit |
6639f8 |
// without specific prior written permission.
|
|
Packit |
6639f8 |
//
|
|
Packit |
6639f8 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
6639f8 |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
6639f8 |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
6639f8 |
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
Packit |
6639f8 |
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
Packit |
6639f8 |
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
Packit |
6639f8 |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
Packit |
6639f8 |
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
Packit |
6639f8 |
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
6639f8 |
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
Packit |
6639f8 |
// POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
6639f8 |
#include <config.h>
|
|
Packit |
6639f8 |
#endif // HAVE_CONFIG_H
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#include <stdio.h>
|
|
Packit |
6639f8 |
#include <linux/limits.h>
|
|
Packit |
6639f8 |
#include <dlfcn.h>
|
|
Packit |
6639f8 |
#include <glob.h>
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#include <uuid/uuid.h>
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#include "monitored_device.h"
|
|
Packit |
6639f8 |
#include "monitor_thread.h"
|
|
Packit |
6639f8 |
#include "api/sysfs.h"
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#ifdef LOG
|
|
Packit |
6639f8 |
#undef LOG
|
|
Packit |
6639f8 |
#endif
|
|
Packit |
6639f8 |
#define LOG(format, ...) \
|
|
Packit |
6639f8 |
log_printf("monitored_device: " format, ##__VA_ARGS__)
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgad_supported_device default_supported_devices_table[] = {
|
|
Packit |
6639f8 |
{ 0x8086, 0xbcc0, "libfpgad-xfpga.so", 0, NULL, "" },
|
|
Packit |
6639f8 |
{ 0x8086, 0xbcc1, "libfpgad-xfpga.so", 0, NULL, "" },
|
|
Packit |
6639f8 |
{ 0x8086, 0x0b30, "libfpgad-vc.so", 0, NULL, "" },
|
|
Packit |
6639f8 |
{ 0x8086, 0x0b31, "libfpgad-vc.so", 0, NULL, "" },
|
|
Packit |
6639f8 |
{ 0, 0, NULL, 0, NULL, "" },
|
|
Packit |
6639f8 |
};
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC fpgad_supported_device *mon_is_loaded(struct fpgad_config *c,
|
|
Packit |
6639f8 |
const char *library_path)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
unsigned i;
|
|
Packit |
6639f8 |
int res = 0;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (i = 0 ; c->supported_devices[i].library_path ; ++i) {
|
|
Packit |
6639f8 |
fpgad_supported_device *d = &c->supported_devices[i];
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = strcmp(library_path, d->library_path);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!res && (d->flags & FPGAD_DEV_LOADED))
|
|
Packit |
6639f8 |
return d;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
return NULL;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC fpgad_monitored_device *
|
|
Packit |
6639f8 |
allocate_monitored_device(struct fpgad_config *config,
|
|
Packit |
6639f8 |
fpgad_supported_device *supported,
|
|
Packit |
6639f8 |
fpga_token token,
|
|
Packit |
6639f8 |
uint64_t object_id,
|
|
Packit |
6639f8 |
fpga_objtype object_type,
|
|
Packit |
6639f8 |
opae_bitstream_info *bitstr)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
fpgad_monitored_device *d;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
d = (fpgad_monitored_device *) calloc(
|
|
Packit |
6639f8 |
1, sizeof(fpgad_monitored_device));
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!d) {
|
|
Packit |
6639f8 |
LOG("out of memory");
|
|
Packit |
6639f8 |
return NULL;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
d->config = config;
|
|
Packit |
6639f8 |
d->supported = supported;
|
|
Packit |
6639f8 |
d->token = token;
|
|
Packit |
6639f8 |
d->object_id = object_id;
|
|
Packit |
6639f8 |
d->object_type = object_type;
|
|
Packit |
6639f8 |
d->bitstr = bitstr;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
return d;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC void *mon_find_plugin(const char *libpath)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
char plugin_path[PATH_MAX];
|
|
Packit |
6639f8 |
const char *search_paths[] = { OPAE_MODULE_SEARCH_PATHS };
|
|
Packit |
6639f8 |
unsigned i;
|
|
Packit |
6639f8 |
void *dl_handle;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (i = 0 ;
|
|
Packit |
6639f8 |
i < sizeof(search_paths) / sizeof(search_paths[0]) ;
|
|
Packit |
6639f8 |
++i) {
|
|
Packit |
6639f8 |
snprintf(plugin_path, sizeof(plugin_path),
|
|
Packit |
6639f8 |
"%s%s", search_paths[i], libpath);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
dl_handle = dlopen(plugin_path, RTLD_LAZY|RTLD_LOCAL);
|
|
Packit |
6639f8 |
if (dl_handle)
|
|
Packit |
6639f8 |
return dl_handle;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
return NULL;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC bool mon_consider_device(struct fpgad_config *c, fpga_token token)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
unsigned i;
|
|
Packit |
6639f8 |
fpga_properties props = NULL;
|
|
Packit |
6639f8 |
fpga_token parent = NULL;
|
|
Packit |
6639f8 |
fpga_properties parent_props = NULL;
|
|
Packit |
6639f8 |
fpga_result res;
|
|
Packit |
6639f8 |
uint16_t vendor_id;
|
|
Packit |
6639f8 |
uint16_t device_id;
|
|
Packit |
6639f8 |
uint64_t object_id;
|
|
Packit |
6639f8 |
fpga_objtype object_type;
|
|
Packit |
6639f8 |
opae_bitstream_info *bitstr = NULL;
|
|
Packit |
6639f8 |
fpga_guid pr_ifc_id;
|
|
Packit |
6639f8 |
bool added = false;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = fpgaGetProperties(token, &props;;
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("failed to get properties\n");
|
|
Packit |
6639f8 |
return false;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
vendor_id = 0;
|
|
Packit |
6639f8 |
res = fpgaPropertiesGetVendorID(props, &vendor_id);
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("failed to get vendor ID\n");
|
|
Packit |
6639f8 |
goto err_out_destroy;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
device_id = 0;
|
|
Packit |
6639f8 |
res = fpgaPropertiesGetDeviceID(props, &device_id);
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("failed to get device ID\n");
|
|
Packit |
6639f8 |
goto err_out_destroy;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
object_id = 0;
|
|
Packit |
6639f8 |
res = fpgaPropertiesGetObjectID(props, &object_id);
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("failed to get object ID\n");
|
|
Packit |
6639f8 |
goto err_out_destroy;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
object_type = FPGA_ACCELERATOR;
|
|
Packit |
6639f8 |
res = fpgaPropertiesGetObjectType(props, &object_type);
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("failed to get object type\n");
|
|
Packit |
6639f8 |
goto err_out_destroy;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// Do we have a NULL GBS from the command line
|
|
Packit |
6639f8 |
// that matches this device?
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (object_type == FPGA_DEVICE) {
|
|
Packit |
6639f8 |
// The token's guid is the PR interface ID.
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = fpgaPropertiesGetGUID(props, &pr_ifc_id);
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("failed to get PR interface ID\n");\
|
|
Packit |
6639f8 |
goto err_out_destroy;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (i = 0 ; i < c->num_null_gbs ; ++i) {
|
|
Packit |
6639f8 |
if (!uuid_compare(c->null_gbs[i].pr_interface_id,
|
|
Packit |
6639f8 |
pr_ifc_id)) {
|
|
Packit |
6639f8 |
bitstr = &c->null_gbs[i];
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
// The parent token's guid is the PR interface ID.
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = fpgaPropertiesGetParent(props, &parent);
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("failed to get parent token\n");
|
|
Packit |
6639f8 |
goto err_out_destroy;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = fpgaGetProperties(parent, &parent_props);
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("failed to get parent properties\n");
|
|
Packit |
6639f8 |
goto err_out_destroy;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = fpgaPropertiesGetGUID(parent_props, &pr_ifc_id);
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("failed to get PR interface ID\n");
|
|
Packit |
6639f8 |
goto err_out_destroy;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgaDestroyProperties(&parent_props);
|
|
Packit |
6639f8 |
fpgaDestroyToken(&parent);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (i = 0 ; i < c->num_null_gbs ; ++i) {
|
|
Packit |
6639f8 |
if (!uuid_compare(c->null_gbs[i].pr_interface_id,
|
|
Packit |
6639f8 |
pr_ifc_id)) {
|
|
Packit |
6639f8 |
bitstr = &c->null_gbs[i];
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
fpgaDestroyProperties(&props;;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (i = 0 ; c->supported_devices[i].library_path ; ++i) {
|
|
Packit |
6639f8 |
fpgad_supported_device *d = &c->supported_devices[i];
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// Do we support this device?
|
|
Packit |
6639f8 |
if (d->vendor_id == vendor_id &&
|
|
Packit |
6639f8 |
d->device_id == device_id) {
|
|
Packit |
6639f8 |
fpgad_supported_device *loaded_by;
|
|
Packit |
6639f8 |
fpgad_monitored_device *monitored;
|
|
Packit |
6639f8 |
fpgad_plugin_configure_t cfg;
|
|
Packit |
6639f8 |
int res;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
d->flags |= FPGAD_DEV_DETECTED;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// Is the fpgad plugin already loaded?
|
|
Packit |
6639f8 |
loaded_by = mon_is_loaded(c, d->library_path);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (loaded_by) {
|
|
Packit |
6639f8 |
// The two table entries will share the
|
|
Packit |
6639f8 |
// same plugin handle (but only loaded_by
|
|
Packit |
6639f8 |
// will have FPGAD_DEV_LOADED).
|
|
Packit |
6639f8 |
d->dl_handle = loaded_by->dl_handle;
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
// Plugin hasn't been loaded.
|
|
Packit |
6639f8 |
// Load it now.
|
|
Packit |
6639f8 |
d->dl_handle =
|
|
Packit |
6639f8 |
mon_find_plugin(d->library_path);
|
|
Packit |
6639f8 |
if (!d->dl_handle) {
|
|
Packit |
6639f8 |
char *err = dlerror();
|
|
Packit |
6639f8 |
LOG("failed to load \"%s\" %s\n",
|
|
Packit |
6639f8 |
d->library_path,
|
|
Packit |
6639f8 |
err ? err : "");
|
|
Packit |
6639f8 |
continue;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
d->flags |= FPGAD_DEV_LOADED;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!bitstr) {
|
|
Packit |
6639f8 |
LOG("Warning: no NULL GBS for vid=0x%04x "
|
|
Packit |
6639f8 |
"did=0x%04x objid=0x%x (%s)\n",
|
|
Packit |
6639f8 |
vendor_id,
|
|
Packit |
6639f8 |
device_id,
|
|
Packit |
6639f8 |
object_id,
|
|
Packit |
6639f8 |
object_type == FPGA_ACCELERATOR ?
|
|
Packit |
6639f8 |
"accelerator" : "device");
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// Add the device to the monitored list.
|
|
Packit |
6639f8 |
monitored = allocate_monitored_device(c,
|
|
Packit |
6639f8 |
d,
|
|
Packit |
6639f8 |
token,
|
|
Packit |
6639f8 |
object_id,
|
|
Packit |
6639f8 |
object_type,
|
|
Packit |
6639f8 |
bitstr);
|
|
Packit |
6639f8 |
if (!monitored) {
|
|
Packit |
6639f8 |
LOG("failed to add device 0x%04x:0x%04x\n",
|
|
Packit |
6639f8 |
vendor_id, device_id);
|
|
Packit |
6639f8 |
continue;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// Success
|
|
Packit |
6639f8 |
cfg = (fpgad_plugin_configure_t)
|
|
Packit |
6639f8 |
dlsym(d->dl_handle,
|
|
Packit |
6639f8 |
FPGAD_PLUGIN_CONFIGURE);
|
|
Packit |
6639f8 |
if (!cfg) {
|
|
Packit |
6639f8 |
LOG("failed to find %s in \"%s\"\n",
|
|
Packit |
6639f8 |
FPGAD_PLUGIN_CONFIGURE,
|
|
Packit |
6639f8 |
d->library_path);
|
|
Packit |
6639f8 |
free(monitored);
|
|
Packit |
6639f8 |
continue;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = cfg(monitored, d->config);
|
|
Packit |
6639f8 |
if (res) {
|
|
Packit |
6639f8 |
LOG("%s for \"%s\" returned %d.\n",
|
|
Packit |
6639f8 |
FPGAD_PLUGIN_CONFIGURE,
|
|
Packit |
6639f8 |
d->library_path,
|
|
Packit |
6639f8 |
res);
|
|
Packit |
6639f8 |
free(monitored);
|
|
Packit |
6639f8 |
continue;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (monitored->type == FPGAD_PLUGIN_TYPE_THREAD) {
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (monitored->thread_fn) {
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (pthread_create(&monitored->thread,
|
|
Packit |
6639f8 |
NULL,
|
|
Packit |
6639f8 |
monitored->thread_fn,
|
|
Packit |
6639f8 |
monitored)) {
|
|
Packit |
6639f8 |
LOG("failed to create thread"
|
|
Packit |
6639f8 |
" for \"%s\"\n",
|
|
Packit |
6639f8 |
d->library_path);
|
|
Packit |
6639f8 |
free(monitored);
|
|
Packit |
6639f8 |
continue;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
LOG("Thread plugin \"%s\" has no "
|
|
Packit |
6639f8 |
"thread_fn\n", d->library_path);
|
|
Packit |
6639f8 |
free(monitored);
|
|
Packit |
6639f8 |
continue;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
mon_monitor_device(monitored);
|
|
Packit |
6639f8 |
added = true;
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
return added;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
err_out_destroy:
|
|
Packit |
6639f8 |
if (props)
|
|
Packit |
6639f8 |
fpgaDestroyProperties(&props;;
|
|
Packit |
6639f8 |
if (parent)
|
|
Packit |
6639f8 |
fpgaDestroyToken(&parent);
|
|
Packit |
6639f8 |
if (parent_props)
|
|
Packit |
6639f8 |
fpgaDestroyProperties(&parent_props);
|
|
Packit |
6639f8 |
return false;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
int mon_enumerate(struct fpgad_config *c)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
fpga_token *tokens = NULL;
|
|
Packit |
6639f8 |
fpga_result res;
|
|
Packit |
6639f8 |
uint32_t num_matches = 0;
|
|
Packit |
6639f8 |
uint32_t i;
|
|
Packit |
6639f8 |
unsigned monitored_devices = 0;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = fpgaEnumerate(NULL, 0, NULL, 0, &num_matches);
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("enumeration failed\n");
|
|
Packit |
6639f8 |
return res;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!num_matches) {
|
|
Packit |
6639f8 |
res = 1;
|
|
Packit |
6639f8 |
return res;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
tokens = calloc(num_matches, sizeof(fpga_token));
|
|
Packit |
6639f8 |
if (!tokens) {
|
|
Packit |
6639f8 |
res = 1;
|
|
Packit |
6639f8 |
LOG("out of memory\n");
|
|
Packit |
6639f8 |
return res;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = fpgaEnumerate(NULL, 0, tokens, num_matches, &num_matches);
|
|
Packit |
6639f8 |
if (res != FPGA_OK) {
|
|
Packit |
6639f8 |
LOG("enumeration failed (2)\n");
|
|
Packit |
6639f8 |
goto out_exit;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (i = 0 ; i < num_matches ; ++i) {
|
|
Packit |
6639f8 |
if (!mon_consider_device(c, tokens[i])) {
|
|
Packit |
6639f8 |
// Not monitoring it. Destroy the token.
|
|
Packit |
6639f8 |
fpgaDestroyToken(&tokens[i]);
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
++monitored_devices;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
out_exit:
|
|
Packit |
6639f8 |
if (tokens)
|
|
Packit |
6639f8 |
free(tokens);
|
|
Packit |
6639f8 |
return res + (monitored_devices ? 0 : 1);
|
|
Packit |
6639f8 |
}
|