|
Packit |
534379 |
// Copyright(c) 2017-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 |
|
|
Packit |
534379 |
#define _GNU_SOURCE
|
|
Packit |
534379 |
#include <pthread.h>
|
|
Packit |
534379 |
#include <glob.h>
|
|
Packit |
534379 |
#include <dirent.h>
|
|
Packit |
534379 |
#include <unistd.h>
|
|
Packit |
534379 |
#include <string.h>
|
|
Packit |
534379 |
#include <stdlib.h>
|
|
Packit |
534379 |
#include <stdio.h>
|
|
Packit |
534379 |
#include <fcntl.h>
|
|
Packit |
534379 |
#include <errno.h>
|
|
Packit |
534379 |
#include <sys/stat.h>
|
|
Packit |
534379 |
#include <regex.h>
|
|
Packit |
534379 |
#undef _GNU_SOURCE
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#include <opae/types.h>
|
|
Packit |
534379 |
#include <opae/log.h>
|
|
Packit |
534379 |
#include <opae/types_enum.h>
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#include "types_int.h"
|
|
Packit |
534379 |
#include "sysfs_int.h"
|
|
Packit |
534379 |
#include "common_int.h"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// substring that identifies a sysfs directory as the FME device.
|
|
Packit |
534379 |
#define FPGA_SYSFS_FME "fme"
|
|
Packit |
534379 |
#define FPGA_SYSFS_FME_LEN 3
|
|
Packit |
534379 |
// substring that identifies a sysfs directory as the AFU device.
|
|
Packit |
534379 |
#define FPGA_SYSFS_PORT "port"
|
|
Packit |
534379 |
#define FPGA_SYSFS_PORT_LEN 4
|
|
Packit |
534379 |
#define OPAE_KERNEL_DRIVERS 2
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
typedef struct _sysfs_formats {
|
|
Packit |
534379 |
const char *sysfs_class_path;
|
|
Packit |
534379 |
const char *sysfs_pcidrv_fpga;
|
|
Packit |
534379 |
const char *sysfs_device_fmt;
|
|
Packit |
534379 |
const char *sysfs_region_fmt;
|
|
Packit |
534379 |
const char *sysfs_device_glob;
|
|
Packit |
534379 |
const char *sysfs_fme_glob;
|
|
Packit |
534379 |
const char *sysfs_port_glob;
|
|
Packit |
534379 |
const char *sysfs_compat_id;
|
|
Packit |
534379 |
const char *sysfs_fme_pwr_glob;
|
|
Packit |
534379 |
const char *sysfs_fme_temp_glob;
|
|
Packit |
534379 |
const char *sysfs_fme_perf_glob;
|
|
Packit |
534379 |
const char *sysfs_port_err;
|
|
Packit |
534379 |
const char *sysfs_port_err_clear;
|
|
Packit |
534379 |
const char *sysfs_bmc_glob;
|
|
Packit |
534379 |
const char *sysfs_max10_glob;
|
|
Packit |
534379 |
} sysfs_formats;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
static sysfs_formats sysfs_path_table[OPAE_KERNEL_DRIVERS] = {
|
|
Packit |
534379 |
// upstream driver sysfs formats
|
|
Packit |
534379 |
{.sysfs_class_path = "/sys/class/fpga_region",
|
|
Packit |
534379 |
.sysfs_pcidrv_fpga = "fpga_region",
|
|
Packit |
534379 |
.sysfs_device_fmt = "(region)([0-9])+",
|
|
Packit |
534379 |
.sysfs_region_fmt = "dfl-(fme|port)\\.([0-9]+)",
|
|
Packit |
534379 |
.sysfs_device_glob = "region*",
|
|
Packit |
534379 |
.sysfs_fme_glob = "dfl-fme.*",
|
|
Packit |
534379 |
.sysfs_port_glob = "dfl-port.*",
|
|
Packit |
534379 |
.sysfs_compat_id = "/dfl-fme-region.*/fpga_region/region*/compat_id",
|
|
Packit |
534379 |
.sysfs_fme_temp_glob = "hwmon/hwmon*/temp*_*",
|
|
Packit |
534379 |
.sysfs_fme_pwr_glob = "hwmon/hwmon*/power*_*",
|
|
Packit |
534379 |
.sysfs_fme_perf_glob = "*perf",
|
|
Packit |
534379 |
.sysfs_port_err = "errors/errors",
|
|
Packit |
534379 |
.sysfs_port_err_clear = "errors/errors",
|
|
Packit |
534379 |
.sysfs_bmc_glob = "avmmi-bmc.*/bmc_info",
|
|
Packit |
534379 |
.sysfs_max10_glob = "spi-*/spi_master/spi*/spi*.*"
|
|
Packit |
534379 |
},
|
|
Packit |
534379 |
// intel driver sysfs formats
|
|
Packit |
534379 |
{.sysfs_class_path = "/sys/class/fpga",
|
|
Packit |
534379 |
.sysfs_pcidrv_fpga = "fpga",
|
|
Packit |
534379 |
.sysfs_device_fmt = "(intel-fpga-dev\\.)([0-9]+)",
|
|
Packit |
534379 |
.sysfs_region_fmt = "intel-fpga-(fme|port)\\.([0-9]+)",
|
|
Packit |
534379 |
.sysfs_device_glob = "intel-fpga-dev.*",
|
|
Packit |
534379 |
.sysfs_fme_glob = "intel-fpga-fme.*",
|
|
Packit |
534379 |
.sysfs_port_glob = "intel-fpga-port.*",
|
|
Packit |
534379 |
.sysfs_compat_id = "pr/interface_id",
|
|
Packit |
534379 |
.sysfs_fme_temp_glob = "thermal_mgmt/*",
|
|
Packit |
534379 |
.sysfs_fme_pwr_glob = "power_mgmt/*",
|
|
Packit |
534379 |
.sysfs_fme_perf_glob = "*perf",
|
|
Packit |
534379 |
.sysfs_port_err = "errors/errors",
|
|
Packit |
534379 |
.sysfs_port_err_clear = "errors/clear",
|
|
Packit |
534379 |
.sysfs_bmc_glob = "avmmi-bmc.*/bmc_info",
|
|
Packit |
534379 |
.sysfs_max10_glob = "spi-*/spi_master/spi*/spi*.*"
|
|
Packit |
534379 |
} };
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// RE_MATCH_STRING is index 0 in a regex match array
|
|
Packit |
534379 |
#define RE_MATCH_STRING 0
|
|
Packit |
534379 |
// RE_DEVICE_GROUPS is the matching groups for the device regex in the
|
|
Packit |
534379 |
// sysfs_path_table above.
|
|
Packit |
534379 |
// Currently this only has three groups:
|
|
Packit |
534379 |
// * The matching string itself - group 0
|
|
Packit |
534379 |
// * The prefix (either 'region' or 'intel-fpga-dev.') - group 1
|
|
Packit |
534379 |
// * The number - group 2
|
|
Packit |
534379 |
// These indices are used when indexing a regex match object
|
|
Packit |
534379 |
#define RE_DEVICE_GROUPS 3
|
|
Packit |
534379 |
#define RE_DEVICE_GROUP_PREFIX 1
|
|
Packit |
534379 |
#define RE_DEVICE_GROUP_NUM 2
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// RE_REGION_GROUPS is the matching groups for the region regex in the
|
|
Packit |
534379 |
// sysfs_path_table above.
|
|
Packit |
534379 |
// Currently this only has three groups:
|
|
Packit |
534379 |
// * The matching string itself - group 0
|
|
Packit |
534379 |
// * The type ('fme' or 'port') - group 1
|
|
Packit |
534379 |
// * The number - group 2
|
|
Packit |
534379 |
// These indices are used when indexing a regex match object
|
|
Packit |
534379 |
#define RE_REGION_GROUPS 3
|
|
Packit |
534379 |
#define RE_REGION_GROUP_TYPE 1
|
|
Packit |
534379 |
#define RE_REGION_GROUP_NUM 2
|
|
Packit |
534379 |
|
|
Packit |
534379 |
static sysfs_formats *_sysfs_format_ptr;
|
|
Packit |
534379 |
static uint32_t _sysfs_device_count;
|
|
Packit |
534379 |
/* mutex to protect sysfs device data structures */
|
|
Packit |
534379 |
pthread_mutex_t _sysfs_device_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define SYSFS_FORMAT(s) (_sysfs_format_ptr ? _sysfs_format_ptr->s : NULL)
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define SYSFS_MAX_DEVICES 128
|
|
Packit |
534379 |
static sysfs_fpga_device _devices[SYSFS_MAX_DEVICES];
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define PCIE_PATH_PATTERN "([0-9a-fA-F]{4}):([0-9a-fA-F]{2}):([0-9]{2})\\.([0-9])/fpga"
|
|
Packit |
534379 |
#define PCIE_PATH_PATTERN_GROUPS 5
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define PARSE_MATCH_INT(_p, _m, _v, _b, _l) \
|
|
Packit |
534379 |
do { \
|
|
Packit |
534379 |
errno = 0; \
|
|
Packit |
534379 |
_v = strtoul(_p + _m.rm_so, NULL, _b); \
|
|
Packit |
534379 |
if (errno) { \
|
|
Packit |
534379 |
OPAE_MSG("error parsing int"); \
|
|
Packit |
534379 |
goto _l; \
|
|
Packit |
534379 |
} \
|
|
Packit |
534379 |
} while (0)
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define FREE_IF(var) \
|
|
Packit |
534379 |
do { \
|
|
Packit |
534379 |
if (var) { \
|
|
Packit |
534379 |
free(var); \
|
|
Packit |
534379 |
var = NULL; \
|
|
Packit |
534379 |
} \
|
|
Packit |
534379 |
} while (0)
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int parse_pcie_info(sysfs_fpga_device *device, char *buffer)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
char err[128] = {0};
|
|
Packit |
534379 |
regex_t re;
|
|
Packit |
534379 |
regmatch_t matches[PCIE_PATH_PATTERN_GROUPS] = { {0} };
|
|
Packit |
534379 |
int res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int reg_res = regcomp(&re, PCIE_PATH_PATTERN, REG_EXTENDED | REG_ICASE);
|
|
Packit |
534379 |
if (reg_res) {
|
|
Packit |
534379 |
OPAE_ERR("Error compling regex");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
reg_res = regexec(&re, buffer, PCIE_PATH_PATTERN_GROUPS, matches, 0);
|
|
Packit |
534379 |
if (reg_res) {
|
|
Packit |
534379 |
regerror(reg_res, &re, err, 128);
|
|
Packit |
534379 |
OPAE_ERR("Error executing regex: %s", err);
|
|
Packit |
534379 |
res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
goto out;
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
PARSE_MATCH_INT(buffer, matches[1], device->segment, 16, out);
|
|
Packit |
534379 |
PARSE_MATCH_INT(buffer, matches[2], device->bus, 16, out);
|
|
Packit |
534379 |
PARSE_MATCH_INT(buffer, matches[3], device->device, 16, out);
|
|
Packit |
534379 |
PARSE_MATCH_INT(buffer, matches[4], device->function, 10, out);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
res = FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out:
|
|
Packit |
534379 |
regfree(&re);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int sysfs_parse_attribute64(const char *root, const char *attr_path, uint64_t *value)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
uint64_t pg_size = (uint64_t)sysconf(_SC_PAGE_SIZE);
|
|
Packit |
534379 |
char path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
char buffer[pg_size];
|
|
Packit |
534379 |
int fd = -1;
|
|
Packit |
534379 |
ssize_t bytes_read = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(path, sizeof(path),
|
|
Packit |
534379 |
"%s/%s", root, attr_path);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fd = open(path, O_RDONLY);
|
|
Packit |
534379 |
if (fd < 0) {
|
|
Packit |
534379 |
OPAE_MSG("Error opening %s: %s", path, strerror(errno));
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
bytes_read = eintr_read(fd, buffer, pg_size);
|
|
Packit |
534379 |
if (bytes_read < 0) {
|
|
Packit |
534379 |
OPAE_ERR("Error reading from %s: %s", path,
|
|
Packit |
534379 |
strerror(errno));
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*value = strtoull(buffer, NULL, 0);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int parse_device_vendor_id(sysfs_fpga_device *device)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
uint64_t value = 0;
|
|
Packit |
534379 |
int res = sysfs_parse_attribute64(device->sysfs_path, "device/device", &value);
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
OPAE_MSG("Error parsing device_id for device: %s",
|
|
Packit |
534379 |
device->sysfs_path);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
device->device_id = value;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = sysfs_parse_attribute64(device->sysfs_path, "device/vendor", &value);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
OPAE_ERR("Error parsing vendor_id for device: %s",
|
|
Packit |
534379 |
device->sysfs_path);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
device->vendor_id = value;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC sysfs_fpga_region *make_region(sysfs_fpga_device *device, char *name,
|
|
Packit |
534379 |
int num, fpga_objtype type)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
size_t len;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
sysfs_fpga_region *region = malloc(sizeof(sysfs_fpga_region));
|
|
Packit |
534379 |
if (region == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("error creating region");
|
|
Packit |
534379 |
return NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
region->device = device;
|
|
Packit |
534379 |
region->type = type;
|
|
Packit |
534379 |
region->number = num;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// sysfs path of region is sysfs path of device + / + name
|
|
Packit |
534379 |
if (snprintf(region->sysfs_path, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
"%s/%s", device->sysfs_path, name) < 0) {
|
|
Packit |
534379 |
free(region);
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
return NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len = strnlen(name, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
memcpy(region->sysfs_name, name, len);
|
|
Packit |
534379 |
region->sysfs_name[len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return region;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/**
|
|
Packit |
534379 |
* @brief Match a device node given a format pattern
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
* @param fmt A regex pattern for the device node
|
|
Packit |
534379 |
* @param inpstr A sysfs path to a potential device node
|
|
Packit |
534379 |
* @param(out) prefix[] A prefix string for the device node
|
|
Packit |
534379 |
* @param prefix_len capacity of prefix (max length)
|
|
Packit |
534379 |
* @param(out) num The sysfs number encoded in the name
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
* @note fmt is expected to be a regex pattern in our sysfs_format_table
|
|
Packit |
534379 |
* Matching input strings could could look like:
|
|
Packit |
534379 |
* * region0 where 'region' is the prefix and 0 is the num
|
|
Packit |
534379 |
* * intel-fpga-dev.0 where 'intel-fpga-dev.' is the prefix and 0 is the
|
|
Packit |
534379 |
* num
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
* @return FPGA_OK if a match is found, FPGA_NOT_FOUND it no match is found,
|
|
Packit |
534379 |
* FPGA_EXCEPTION if an error is encountered
|
|
Packit |
534379 |
*/
|
|
Packit |
534379 |
STATIC fpga_result re_match_device(const char *fmt, char *inpstr, char prefix[],
|
|
Packit |
534379 |
size_t prefix_len, int *num)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int reg_res = 0;
|
|
Packit |
534379 |
fpga_result res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
regmatch_t matches[RE_DEVICE_GROUPS];
|
|
Packit |
534379 |
char err[128];
|
|
Packit |
534379 |
char *ptr = NULL;
|
|
Packit |
534379 |
char *end = NULL;
|
|
Packit |
534379 |
regex_t re;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ASSERT_NOT_NULL(fmt);
|
|
Packit |
534379 |
ASSERT_NOT_NULL(inpstr);
|
|
Packit |
534379 |
ASSERT_NOT_NULL(prefix);
|
|
Packit |
534379 |
ASSERT_NOT_NULL(num);
|
|
Packit |
534379 |
reg_res = regcomp(&re, fmt, REG_EXTENDED);
|
|
Packit |
534379 |
if (reg_res) {
|
|
Packit |
534379 |
regerror(reg_res, &re, err, sizeof(err));
|
|
Packit |
534379 |
OPAE_ERR("Error compiling regex: %s", err);
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
reg_res = regexec(&re, inpstr, RE_DEVICE_GROUPS, matches, 0);
|
|
Packit |
534379 |
if (reg_res) {
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ptr = inpstr + matches[RE_DEVICE_GROUP_PREFIX].rm_so;
|
|
Packit |
534379 |
end = inpstr + matches[RE_DEVICE_GROUP_PREFIX].rm_eo;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((size_t)(end - ptr) >= prefix_len) {
|
|
Packit |
534379 |
OPAE_ERR("Regex result too long");
|
|
Packit |
534379 |
res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
strncpy(prefix, ptr, end - ptr);
|
|
Packit |
534379 |
*(prefix + (end - ptr)) = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ptr = inpstr + matches[RE_DEVICE_GROUP_NUM].rm_so;
|
|
Packit |
534379 |
errno = 0;
|
|
Packit |
534379 |
*num = strtoul(ptr, NULL, 10);
|
|
Packit |
534379 |
if (errno) {
|
|
Packit |
534379 |
OPAE_ERR("Error parsing number: %s", inpstr);
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
res = FPGA_OK;
|
|
Packit |
534379 |
out_free:
|
|
Packit |
534379 |
regfree(&re);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/**
|
|
Packit |
534379 |
* @brief Match a device node given a format pattern
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
* @param fmt A regex pattern for the device node
|
|
Packit |
534379 |
* @param inpstr A sysfs path to a potential device node
|
|
Packit |
534379 |
* @param(out) type[] A type string for the device node
|
|
Packit |
534379 |
* @param type_len capacity of type (max length)
|
|
Packit |
534379 |
* @param(out) num The sysfs number encoded in the name
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
* @note fmt is expected to be a regex pattern in our sysfs_format_table
|
|
Packit |
534379 |
* Matching input strings could could look like:
|
|
Packit |
534379 |
* * dfl-fme.0 where 'fme' is the type and 0 is the num
|
|
Packit |
534379 |
* * dfl-port.1 where 'port' is the type and 1 is the num
|
|
Packit |
534379 |
* * intel-fpga-fme.0 where 'fme' is the type and 0 is the num
|
|
Packit |
534379 |
* * intel-fpga-port.1 where 'port' is the type and 1 is the num
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
* @return FPGA_OK if a match is found, FPGA_NOT_FOUND it no match is found,
|
|
Packit |
534379 |
* FPGA_EXCEPTION if an error is encountered
|
|
Packit |
534379 |
*/
|
|
Packit |
534379 |
STATIC fpga_result re_match_region(const char *fmt, char *inpstr, char type[],
|
|
Packit |
534379 |
size_t type_len, int *num)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int reg_res = 0;
|
|
Packit |
534379 |
fpga_result res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
regmatch_t matches[RE_REGION_GROUPS];
|
|
Packit |
534379 |
char err[128];
|
|
Packit |
534379 |
char *ptr = NULL;
|
|
Packit |
534379 |
char *end = NULL;
|
|
Packit |
534379 |
regex_t re;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ASSERT_NOT_NULL(fmt);
|
|
Packit |
534379 |
ASSERT_NOT_NULL(inpstr);
|
|
Packit |
534379 |
ASSERT_NOT_NULL(type);
|
|
Packit |
534379 |
ASSERT_NOT_NULL(num);
|
|
Packit |
534379 |
reg_res = regcomp(&re, fmt, REG_EXTENDED);
|
|
Packit |
534379 |
if (reg_res) {
|
|
Packit |
534379 |
regerror(reg_res, &re, err, sizeof(err));
|
|
Packit |
534379 |
OPAE_ERR("Error compiling regex: %s", err);
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
reg_res = regexec(&re, inpstr, RE_REGION_GROUPS, matches, 0);
|
|
Packit |
534379 |
if (reg_res) {
|
|
Packit |
534379 |
res = FPGA_NOT_FOUND;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ptr = inpstr + matches[RE_REGION_GROUP_TYPE].rm_so;
|
|
Packit |
534379 |
end = inpstr + matches[RE_REGION_GROUP_TYPE].rm_eo;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((size_t)(end - ptr) >= type_len) {
|
|
Packit |
534379 |
OPAE_ERR("Error copying type from string: %s", inpstr);
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
strncpy(type, ptr, end - ptr);
|
|
Packit |
534379 |
*(type + (end - ptr)) = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ptr = inpstr + matches[RE_REGION_GROUP_NUM].rm_so;
|
|
Packit |
534379 |
errno = 0;
|
|
Packit |
534379 |
*num = strtoul(ptr, NULL, 10);
|
|
Packit |
534379 |
if (errno) {
|
|
Packit |
534379 |
OPAE_ERR("Error parsing number: %s", inpstr);
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
res = FPGA_OK;
|
|
Packit |
534379 |
out_free:
|
|
Packit |
534379 |
regfree(&re);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int find_regions(sysfs_fpga_device *device)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int num = -1;
|
|
Packit |
534379 |
char type[8];
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
fpga_result match_res = FPGA_NOT_FOUND;
|
|
Packit |
534379 |
fpga_objtype region_type = FPGA_DEVICE;
|
|
Packit |
534379 |
sysfs_fpga_region **region_ptr = NULL;
|
|
Packit |
534379 |
struct dirent *dirent = NULL;
|
|
Packit |
534379 |
DIR *dir = opendir(device->sysfs_path);
|
|
Packit |
534379 |
if (!dir) {
|
|
Packit |
534379 |
OPAE_ERR("failed to open device path: %s", device->sysfs_path);
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
while ((dirent = readdir(dir)) != NULL) {
|
|
Packit |
534379 |
res = FPGA_OK;
|
|
Packit |
534379 |
if (!strcmp(dirent->d_name, "."))
|
|
Packit |
534379 |
continue;
|
|
Packit |
534379 |
if (!strcmp(dirent->d_name, ".."))
|
|
Packit |
534379 |
continue;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
match_res = re_match_region(SYSFS_FORMAT(sysfs_region_fmt),
|
|
Packit |
534379 |
dirent->d_name, type, sizeof(type),
|
|
Packit |
534379 |
&num);
|
|
Packit |
534379 |
if (match_res == FPGA_OK) {
|
|
Packit |
534379 |
if (!strncmp(FPGA_SYSFS_FME, type,
|
|
Packit |
534379 |
FPGA_SYSFS_FME_LEN)) {
|
|
Packit |
534379 |
region_type = FPGA_DEVICE;
|
|
Packit |
534379 |
region_ptr = &device->fme;
|
|
Packit |
534379 |
} else if (!strncmp(FPGA_SYSFS_PORT, type,
|
|
Packit |
534379 |
FPGA_SYSFS_PORT_LEN)) {
|
|
Packit |
534379 |
region_type = FPGA_ACCELERATOR;
|
|
Packit |
534379 |
region_ptr = &device->port;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (region_ptr)
|
|
Packit |
534379 |
*region_ptr = make_region(device,
|
|
Packit |
534379 |
dirent->d_name, num, region_type);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
region_ptr = NULL;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} else if (match_res != FPGA_NOT_FOUND) {
|
|
Packit |
534379 |
res = match_res;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (dir)
|
|
Packit |
534379 |
closedir(dir);
|
|
Packit |
534379 |
if (!device->fme && !device->port) {
|
|
Packit |
534379 |
OPAE_ERR("did not find fme/port in device: %s", device->sysfs_path);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int make_device(sysfs_fpga_device *device, const char *sysfs_class_fpga,
|
|
Packit |
534379 |
char *dir_name, int num)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int res = FPGA_OK;
|
|
Packit |
534379 |
char buffer[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
ssize_t sym_link_len = 0;
|
|
Packit |
534379 |
size_t len;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (snprintf(device->sysfs_path, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
"%s/%s", sysfs_class_fpga, dir_name) < 0) {
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len = strnlen(dir_name, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
memcpy(device->sysfs_name, dir_name, len);
|
|
Packit |
534379 |
device->sysfs_name[len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
sym_link_len = readlink(device->sysfs_path, buffer, SYSFS_PATH_MAX);
|
|
Packit |
534379 |
if (sym_link_len < 0) {
|
|
Packit |
534379 |
OPAE_ERR("Error reading sysfs link: %s", device->sysfs_path);
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
device->number = num;
|
|
Packit |
534379 |
res = parse_pcie_info(device, buffer);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
OPAE_ERR("Could not parse symlink");
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = parse_device_vendor_id(device);
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
OPAE_MSG("Could not parse vendor/device id");
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return find_regions(device);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int sysfs_device_destroy(sysfs_fpga_device *device)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
ASSERT_NOT_NULL(device);
|
|
Packit |
534379 |
if (device->fme) {
|
|
Packit |
534379 |
free(device->fme);
|
|
Packit |
534379 |
device->fme = NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (device->port) {
|
|
Packit |
534379 |
free(device->port);
|
|
Packit |
534379 |
device->port = NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int sysfs_device_count(void)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int res = 0, count = 0;
|
|
Packit |
534379 |
if (!opae_mutex_lock(res, &_sysfs_device_lock)) {
|
|
Packit |
534379 |
count = _sysfs_device_count;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (opae_mutex_unlock(res, &_sysfs_device_lock)) {
|
|
Packit |
534379 |
count = 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return count;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_foreach_device(device_cb cb, void *context)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
uint32_t i = 0;
|
|
Packit |
534379 |
int res = 0;
|
|
Packit |
534379 |
fpga_result result = FPGA_OK;
|
|
Packit |
534379 |
if (opae_mutex_lock(res, &_sysfs_device_lock)) {
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = sysfs_finalize();
|
|
Packit |
534379 |
if (result) {
|
|
Packit |
534379 |
goto out_unlock;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
result = sysfs_initialize();
|
|
Packit |
534379 |
if (result) {
|
|
Packit |
534379 |
goto out_unlock;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
for (; i < _sysfs_device_count; ++i) {
|
|
Packit |
534379 |
result = cb(&_devices[i], context);
|
|
Packit |
534379 |
if (result) {
|
|
Packit |
534379 |
goto out_unlock;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_unlock:
|
|
Packit |
534379 |
opae_mutex_unlock(res, &_sysfs_device_lock);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int sysfs_initialize(void)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int stat_res = -1;
|
|
Packit |
534379 |
int res = FPGA_OK;
|
|
Packit |
534379 |
uint32_t i = 0;
|
|
Packit |
534379 |
struct stat st;
|
|
Packit |
534379 |
DIR *dir = NULL;
|
|
Packit |
534379 |
struct dirent *dirent = NULL;
|
|
Packit |
534379 |
int num = -1;
|
|
Packit |
534379 |
char prefix[64] = {0};
|
|
Packit |
534379 |
|
|
Packit |
534379 |
for (i = 0; i < OPAE_KERNEL_DRIVERS; ++i) {
|
|
Packit |
534379 |
errno = 0;
|
|
Packit |
534379 |
stat_res = stat(sysfs_path_table[i].sysfs_class_path, &st);
|
|
Packit |
534379 |
if (!stat_res) {
|
|
Packit |
534379 |
_sysfs_format_ptr = &sysfs_path_table[i];
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (errno != ENOENT) {
|
|
Packit |
534379 |
OPAE_ERR("Error while inspecting sysfs: %s",
|
|
Packit |
534379 |
strerror(errno));
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (i == OPAE_KERNEL_DRIVERS) {
|
|
Packit |
534379 |
OPAE_ERR(
|
|
Packit |
534379 |
"No valid sysfs class files found - a suitable driver may not be loaded");
|
|
Packit |
534379 |
return FPGA_NO_DRIVER;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
_sysfs_device_count = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
const char *sysfs_class_fpga = SYSFS_FORMAT(sysfs_class_path);
|
|
Packit |
534379 |
if (!sysfs_class_fpga) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid fpga class path: %s", sysfs_class_fpga);
|
|
Packit |
534379 |
res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// open the root sysfs class directory
|
|
Packit |
534379 |
// look in the directory and get device objects
|
|
Packit |
534379 |
dir = opendir(sysfs_class_fpga);
|
|
Packit |
534379 |
if (!dir) {
|
|
Packit |
534379 |
OPAE_MSG("failed to open device path: %s", sysfs_class_fpga);
|
|
Packit |
534379 |
res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
while ((dirent = readdir(dir))) {
|
|
Packit |
534379 |
if (!strcmp(dirent->d_name, "."))
|
|
Packit |
534379 |
continue;
|
|
Packit |
534379 |
if (!strcmp(dirent->d_name, ".."))
|
|
Packit |
534379 |
continue;
|
|
Packit |
534379 |
res = re_match_device(SYSFS_FORMAT(sysfs_device_fmt),
|
|
Packit |
534379 |
dirent->d_name, prefix, sizeof(prefix),
|
|
Packit |
534379 |
&num);
|
|
Packit |
534379 |
if (res == FPGA_OK) {
|
|
Packit |
534379 |
// increment our device count after filling out details
|
|
Packit |
534379 |
// of the discovered device in our _devices array
|
|
Packit |
534379 |
if (opae_mutex_lock(res, &_sysfs_device_lock)) {
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (make_device(&_devices[_sysfs_device_count++],
|
|
Packit |
534379 |
sysfs_class_fpga, dirent->d_name,
|
|
Packit |
534379 |
num)) {
|
|
Packit |
534379 |
OPAE_MSG("Error processing device: %s",
|
|
Packit |
534379 |
dirent->d_name);
|
|
Packit |
534379 |
_sysfs_device_count--;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (opae_mutex_unlock(res, &_sysfs_device_lock)) {
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!_sysfs_device_count) {
|
|
Packit |
534379 |
OPAE_ERR("Error discovering fpga devices");
|
|
Packit |
534379 |
res = FPGA_NO_DRIVER;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
out_free:
|
|
Packit |
534379 |
if (dir)
|
|
Packit |
534379 |
closedir(dir);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int sysfs_finalize(void)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
uint32_t i = 0;
|
|
Packit |
534379 |
int res = 0;
|
|
Packit |
534379 |
if (opae_mutex_lock(res, &_sysfs_device_lock)) {
|
|
Packit |
534379 |
OPAE_ERR("Error locking mutex");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
for (; i < _sysfs_device_count; ++i) {
|
|
Packit |
534379 |
sysfs_device_destroy(&_devices[i]);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
_sysfs_device_count = 0;
|
|
Packit |
534379 |
_sysfs_format_ptr = NULL;
|
|
Packit |
534379 |
if (opae_mutex_unlock(res, &_sysfs_device_lock)) {
|
|
Packit |
534379 |
OPAE_ERR("Error unlocking mutex");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
const sysfs_fpga_device *sysfs_get_device(size_t num)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
const sysfs_fpga_device *ptr = NULL;
|
|
Packit |
534379 |
int res = 0;
|
|
Packit |
534379 |
if (!opae_mutex_lock(res, &_sysfs_device_lock)) {
|
|
Packit |
534379 |
if (num >= _sysfs_device_count) {
|
|
Packit |
534379 |
OPAE_ERR("No such device with index: %d", num);
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
ptr = &_devices[num];
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (opae_mutex_unlock(res, &_sysfs_device_lock)) {
|
|
Packit |
534379 |
ptr = NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return ptr;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_interface_id(fpga_token token, fpga_guid guid)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
char path[SYSFS_PATH_MAX];
|
|
Packit |
534379 |
struct _fpga_token *_token = (struct _fpga_token *)token;
|
|
Packit |
534379 |
ASSERT_NOT_NULL(_token);
|
|
Packit |
534379 |
res = cat_token_sysfs_path(path, token, SYSFS_FORMAT(sysfs_compat_id));
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
res = opae_glob_path(path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return sysfs_read_guid(path, guid);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_fme_pwr_path(fpga_token token, char *sysfs_pwr)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
struct _fpga_token *_token = (struct _fpga_token *)token;
|
|
Packit |
534379 |
ASSERT_NOT_NULL(_token);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (sysfs_pwr == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input parameters");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
res = cat_token_sysfs_path(sysfs_pwr, token, SYSFS_FORMAT(sysfs_fme_pwr_glob));
|
|
Packit |
534379 |
if (res != FPGA_OK) {
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// check for path is valid
|
|
Packit |
534379 |
res = check_sysfs_path_is_valid(sysfs_pwr);
|
|
Packit |
534379 |
if (res != FPGA_OK) {
|
|
Packit |
534379 |
OPAE_MSG("Invalid path %s", sysfs_pwr);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_fme_temp_path(fpga_token token, char *sysfs_temp)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
struct _fpga_token *_token = (struct _fpga_token *)token;
|
|
Packit |
534379 |
ASSERT_NOT_NULL(_token);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (sysfs_temp == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input parameters");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = cat_token_sysfs_path(sysfs_temp, token, SYSFS_FORMAT(sysfs_fme_temp_glob));
|
|
Packit |
534379 |
if (res != FPGA_OK) {
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// check for path is valid
|
|
Packit |
534379 |
res = check_sysfs_path_is_valid(sysfs_temp);
|
|
Packit |
534379 |
if (res != FPGA_OK) {
|
|
Packit |
534379 |
OPAE_MSG("Invalid path %s", sysfs_temp);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_fme_perf_path(fpga_token token, char *sysfs_perf)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
struct _fpga_token *_token = (struct _fpga_token *)token;
|
|
Packit |
534379 |
ASSERT_NOT_NULL(_token);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (sysfs_perf == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input parameters");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = cat_token_sysfs_path(sysfs_perf, token, SYSFS_FORMAT(sysfs_fme_perf_glob));
|
|
Packit |
534379 |
if (res != FPGA_OK) {
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// check for path is valid
|
|
Packit |
534379 |
res = check_sysfs_path_is_valid(sysfs_perf);
|
|
Packit |
534379 |
if (res != FPGA_OK) {
|
|
Packit |
534379 |
OPAE_MSG("Invalid path %s", sysfs_perf);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_port_error_path(fpga_handle handle, char *sysfs_port_error)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result result = FPGA_OK;
|
|
Packit |
534379 |
char sysfs_path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (sysfs_port_error == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input parameters");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = get_port_sysfs(handle, sysfs_path);
|
|
Packit |
534379 |
if (result != FPGA_OK) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to get port syfs path");
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!SYSFS_FORMAT(sysfs_port_err)) {
|
|
Packit |
534379 |
OPAE_ERR("_sysfs_format_ptr is not set.");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (snprintf(sysfs_port_error, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
"%s/%s", sysfs_path, _sysfs_format_ptr->sysfs_port_err) < 0) {
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_port_error_clear_path(fpga_handle handle, char *sysfs_port_error_clear)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result result = FPGA_OK;
|
|
Packit |
534379 |
char sysfs_path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (sysfs_port_error_clear == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input parameters");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = get_port_sysfs(handle, sysfs_path);
|
|
Packit |
534379 |
if (result != FPGA_OK) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to get port syfs path");
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!SYSFS_FORMAT(sysfs_port_err_clear)) {
|
|
Packit |
534379 |
OPAE_ERR("_sysfs_format_ptr is not set.");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (snprintf(sysfs_port_error_clear, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
"%s/%s", sysfs_path,
|
|
Packit |
534379 |
_sysfs_format_ptr->sysfs_port_err_clear) < 0) {
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_bmc_path(fpga_token token, char *sysfs_bmc)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
struct _fpga_token *_token = (struct _fpga_token *)token;
|
|
Packit |
534379 |
ASSERT_NOT_NULL(_token);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (sysfs_bmc == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input parameters");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = cat_token_sysfs_path(sysfs_bmc, token, SYSFS_FORMAT(sysfs_bmc_glob));
|
|
Packit |
534379 |
if (res != FPGA_OK) {
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return opae_glob_path(sysfs_bmc, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_max10_path(fpga_token token, char *sysfs_max10)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
struct _fpga_token *_token = (struct _fpga_token *)token;
|
|
Packit |
534379 |
ASSERT_NOT_NULL(_token);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (sysfs_max10 == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input parameters");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = cat_token_sysfs_path(sysfs_max10, token, SYSFS_FORMAT(sysfs_max10_glob));
|
|
Packit |
534379 |
if (res != FPGA_OK) {
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return opae_glob_path(sysfs_max10, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_fme_pr_interface_id(const char *sysfs_sysfs_path, fpga_guid guid)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
char sysfs_path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!SYSFS_FORMAT(sysfs_compat_id)) {
|
|
Packit |
534379 |
OPAE_ERR("_sysfs_format_ptr is not set.");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(sysfs_path, sizeof(sysfs_path),
|
|
Packit |
534379 |
"%s/%s",
|
|
Packit |
534379 |
sysfs_sysfs_path,
|
|
Packit |
534379 |
_sysfs_format_ptr->sysfs_compat_id);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = opae_glob_path(sysfs_path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
if (res)
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return sysfs_read_guid(sysfs_path, guid);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_guid(fpga_token token, const char *sysfspath, fpga_guid guid)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
char sysfs_path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
struct _fpga_token *_token = (struct _fpga_token *)token;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (_token == NULL || sysfspath == NULL)
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (snprintf(sysfs_path, sizeof(sysfs_path),
|
|
Packit |
534379 |
"%s/%s", _token->sysfspath, sysfspath) < 0) {
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = opae_glob_path(sysfs_path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
if (res)
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return sysfs_read_guid(sysfs_path, guid);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int sysfs_filter(const struct dirent *de)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
return de->d_name[0] != '.';
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/**
|
|
Packit |
534379 |
* @brief Get a path to an fme node given a path to a port node
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
* @param sysfs_port sysfs path to a port node
|
|
Packit |
534379 |
* @param(out) sysfs_fme realpath to an fme node in sysfs
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
* @return FPGA_OK if able to find the path to the fme
|
|
Packit |
534379 |
* FPGA_EXCEPTION if errors encountered during copying,
|
|
Packit |
534379 |
* formatting strings
|
|
Packit |
534379 |
* FPGA_NOT_FOUND if unable to find fme path or any relevant paths
|
|
Packit |
534379 |
*/
|
|
Packit |
534379 |
fpga_result sysfs_get_fme_path(const char *sysfs_port, char *sysfs_fme)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result result = FPGA_EXCEPTION;
|
|
Packit |
534379 |
char sysfs_path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
char fpga_path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
// subdir candidates to look for when locating "fpga*" node in sysfs
|
|
Packit |
534379 |
// order is important here because a physfn node is the exception
|
|
Packit |
534379 |
// (will only exist when a port is on a VF) and will be used to point
|
|
Packit |
534379 |
// to the PF that the FME is on
|
|
Packit |
534379 |
const char *fpga_globs[] = {"device/physfn/fpga*", "device/fpga*", NULL};
|
|
Packit |
534379 |
int i = 0;
|
|
Packit |
534379 |
size_t len;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// now try globbing fme resource sysfs path + a candidate
|
|
Packit |
534379 |
// sysfs_port is expected to be the sysfs path to a port
|
|
Packit |
534379 |
for (; fpga_globs[i]; ++i) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(sysfs_path, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
"%s/../%s", sysfs_port, fpga_globs[i]);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = opae_glob_path(sysfs_path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
if (result == FPGA_OK) {
|
|
Packit |
534379 |
// we've found a path to the "fpga*" node
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
} else if (result != FPGA_NOT_FOUND) {
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!fpga_globs[i]) {
|
|
Packit |
534379 |
OPAE_ERR("Could not find path to port device/fpga*");
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// format a string to look for in the subdirectory of the "fpga*" node
|
|
Packit |
534379 |
// this subdirectory should include glob patterns for the current
|
|
Packit |
534379 |
// driver
|
|
Packit |
534379 |
// -- intel-fpga-dev.*/intel-fpga-fme.*
|
|
Packit |
534379 |
// -- region*/dfl-fme.*
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!SYSFS_FORMAT(sysfs_device_glob)) {
|
|
Packit |
534379 |
OPAE_ERR("_sysfs_format_ptr is not set.");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(fpga_path, sizeof(fpga_path),
|
|
Packit |
534379 |
"/%s/%s",
|
|
Packit |
534379 |
_sysfs_format_ptr->sysfs_device_glob,
|
|
Packit |
534379 |
_sysfs_format_ptr->sysfs_fme_glob);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len = strnlen(sysfs_path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
strncat(sysfs_path, fpga_path, SYSFS_PATH_MAX - len);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = opae_glob_path(sysfs_path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
if (result)
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// copy the assembled and verified path to the output param
|
|
Packit |
534379 |
if (!realpath(sysfs_path, sysfs_fme))
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// sysfs access (read/write) functions
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_read_int(const char *path, int *i)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int fd;
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
char buf[SYSFS_PATH_MAX];
|
|
Packit |
534379 |
int b;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (path == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input path");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fd = open(path, O_RDONLY);
|
|
Packit |
534379 |
if (fd < 0) {
|
|
Packit |
534379 |
OPAE_MSG("open(%s) failed", path);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((off_t)-1 == lseek(fd, 0, SEEK_SET)) {
|
|
Packit |
534379 |
OPAE_MSG("seek failed");
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
b = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
do {
|
|
Packit |
534379 |
res = read(fd, buf + b, sizeof(buf) - b);
|
|
Packit |
534379 |
if (res <= 0) {
|
|
Packit |
534379 |
OPAE_MSG("Read from %s failed", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
b += res;
|
|
Packit |
534379 |
if (((unsigned)b > sizeof(buf)) || (b <= 0)) {
|
|
Packit |
534379 |
OPAE_MSG("Unexpected size reading from %s", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} while (buf[b - 1] != '\n' && buf[b - 1] != '\0'
|
|
Packit |
534379 |
&& (unsigned)b < sizeof(buf));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// erase \n
|
|
Packit |
534379 |
buf[b - 1] = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*i = atoi(buf);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_close:
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_read_u32(const char *path, uint32_t *u)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int fd;
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
char buf[SYSFS_PATH_MAX];
|
|
Packit |
534379 |
int b;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (path == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input path");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fd = open(path, O_RDONLY);
|
|
Packit |
534379 |
if (fd < 0) {
|
|
Packit |
534379 |
OPAE_MSG("open(%s) failed", path);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((off_t)-1 == lseek(fd, 0, SEEK_SET)) {
|
|
Packit |
534379 |
OPAE_MSG("seek failed");
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
b = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
do {
|
|
Packit |
534379 |
res = read(fd, buf + b, sizeof(buf) - b);
|
|
Packit |
534379 |
if (res <= 0) {
|
|
Packit |
534379 |
OPAE_MSG("Read from %s failed", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
b += res;
|
|
Packit |
534379 |
if (((unsigned)b > sizeof(buf)) || (b <= 0)) {
|
|
Packit |
534379 |
OPAE_MSG("Unexpected size reading from %s", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} while (buf[b - 1] != '\n' && buf[b - 1] != '\0'
|
|
Packit |
534379 |
&& (unsigned)b < sizeof(buf));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// erase \n
|
|
Packit |
534379 |
buf[b - 1] = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*u = strtoul(buf, NULL, 0);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_close:
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// read tuple separated by 'sep' character
|
|
Packit |
534379 |
fpga_result sysfs_read_u32_pair(const char *path, uint32_t *u1, uint32_t *u2,
|
|
Packit |
534379 |
char sep)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int fd;
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
char buf[SYSFS_PATH_MAX];
|
|
Packit |
534379 |
int b;
|
|
Packit |
534379 |
char *c;
|
|
Packit |
534379 |
uint32_t x1, x2;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (sep == '\0') {
|
|
Packit |
534379 |
OPAE_MSG("invalid separation character");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (path == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input path");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fd = open(path, O_RDONLY);
|
|
Packit |
534379 |
if (fd < 0) {
|
|
Packit |
534379 |
OPAE_MSG("open(%s) failed", path);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((off_t)-1 == lseek(fd, 0, SEEK_SET)) {
|
|
Packit |
534379 |
OPAE_MSG("seek failed");
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
b = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
do {
|
|
Packit |
534379 |
res = read(fd, buf + b, sizeof(buf) - b);
|
|
Packit |
534379 |
if (res <= 0) {
|
|
Packit |
534379 |
OPAE_MSG("Read from %s failed", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
b += res;
|
|
Packit |
534379 |
if (((unsigned)b > sizeof(buf)) || (b <= 0)) {
|
|
Packit |
534379 |
OPAE_MSG("Unexpected size reading from %s", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} while (buf[b - 1] != '\n' && buf[b - 1] != '\0'
|
|
Packit |
534379 |
&& (unsigned)b < sizeof(buf));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// erase \n
|
|
Packit |
534379 |
buf[b - 1] = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// read first value
|
|
Packit |
534379 |
x1 = strtoul(buf, &c, 0);
|
|
Packit |
534379 |
if (*c != sep) {
|
|
Packit |
534379 |
OPAE_MSG("couldn't find separation character '%c' in '%s'", sep,
|
|
Packit |
534379 |
path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
// read second value
|
|
Packit |
534379 |
x2 = strtoul(c + 1, &c, 0);
|
|
Packit |
534379 |
if (*c != '\0') {
|
|
Packit |
534379 |
OPAE_MSG("unexpected character '%c' in '%s'", *c, path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*u1 = x1;
|
|
Packit |
534379 |
*u2 = x2;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_close:
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_read_u64(const char *path, uint64_t *u)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int fd = -1;
|
|
Packit |
534379 |
int res = 0;
|
|
Packit |
534379 |
char buf[SYSFS_PATH_MAX] = {0};
|
|
Packit |
534379 |
int b = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (path == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input path");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fd = open(path, O_RDONLY);
|
|
Packit |
534379 |
if (fd < 0) {
|
|
Packit |
534379 |
OPAE_MSG("open(%s) failed", path);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((off_t)-1 == lseek(fd, 0, SEEK_SET)) {
|
|
Packit |
534379 |
OPAE_MSG("seek failed");
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
do {
|
|
Packit |
534379 |
res = read(fd, buf + b, sizeof(buf) - b);
|
|
Packit |
534379 |
if (res <= 0) {
|
|
Packit |
534379 |
OPAE_MSG("Read from %s failed", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
b += res;
|
|
Packit |
534379 |
if (((unsigned)b > sizeof(buf)) || (b <= 0)) {
|
|
Packit |
534379 |
OPAE_MSG("Unexpected size reading from %s", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} while (buf[b - 1] != '\n' && buf[b - 1] != '\0'
|
|
Packit |
534379 |
&& (unsigned)b < sizeof(buf));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// erase \n
|
|
Packit |
534379 |
buf[b - 1] = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*u = strtoull(buf, NULL, 0);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_close:
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_write_u64(const char *path, uint64_t u)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int fd = -1;
|
|
Packit |
534379 |
int res = 0;
|
|
Packit |
534379 |
char buf[SYSFS_PATH_MAX] = {0};
|
|
Packit |
534379 |
int b = 0;
|
|
Packit |
534379 |
int len;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (path == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input path");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fd = open(path, O_WRONLY);
|
|
Packit |
534379 |
if (fd < 0) {
|
|
Packit |
534379 |
OPAE_MSG("open(%s) failed: %s", path, strerror(errno));
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((off_t)-1 == lseek(fd, 0, SEEK_SET)) {
|
|
Packit |
534379 |
OPAE_MSG("seek: %s", strerror(errno));
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len = snprintf(buf, sizeof(buf), "0x%lx\n", u);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
do {
|
|
Packit |
534379 |
res = write(fd, buf + b, len - b);
|
|
Packit |
534379 |
if (res <= 0) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to write");
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
b += res;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (b > len || b <= 0) {
|
|
Packit |
534379 |
OPAE_MSG("Unexpected size writing to %s", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} while (buf[b - 1] != '\n' && buf[b - 1] != '\0'
|
|
Packit |
534379 |
&& b < len);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_close:
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_write_u64_decimal(const char *path, uint64_t u)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int fd = -1;
|
|
Packit |
534379 |
int res = 0;
|
|
Packit |
534379 |
char buf[SYSFS_PATH_MAX] = {0};
|
|
Packit |
534379 |
int b = 0;
|
|
Packit |
534379 |
int len;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (path == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input path");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fd = open(path, O_WRONLY);
|
|
Packit |
534379 |
if (fd < 0) {
|
|
Packit |
534379 |
OPAE_MSG("open(%s) failed: %s", path, strerror(errno));
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((off_t)-1 == lseek(fd, 0, SEEK_SET)) {
|
|
Packit |
534379 |
OPAE_MSG("seek: %s", strerror(errno));
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len = snprintf(buf, sizeof(buf), "%ld\n", u);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
do {
|
|
Packit |
534379 |
res = write(fd, buf + b, len - b);
|
|
Packit |
534379 |
if (res <= 0) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to write");
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
b += res;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (b > len || b <= 0) {
|
|
Packit |
534379 |
OPAE_MSG("Unexpected size writing to %s", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} while (buf[b - 1] != '\n' && buf[b - 1] != '\0'
|
|
Packit |
534379 |
&& b < len);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_close:
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_read_guid(const char *path, fpga_guid guid)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int fd;
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
char buf[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
int b;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int i;
|
|
Packit |
534379 |
char tmp;
|
|
Packit |
534379 |
unsigned octet;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (path == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input path");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fd = open(path, O_RDONLY);
|
|
Packit |
534379 |
if (fd < 0) {
|
|
Packit |
534379 |
OPAE_MSG("open(%s) failed", path);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((off_t)-1 == lseek(fd, 0, SEEK_SET)) {
|
|
Packit |
534379 |
OPAE_MSG("seek failed");
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
b = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
do {
|
|
Packit |
534379 |
res = read(fd, buf + b, sizeof(buf) - b);
|
|
Packit |
534379 |
if (res <= 0) {
|
|
Packit |
534379 |
OPAE_MSG("Read from %s failed", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
b += res;
|
|
Packit |
534379 |
if (((unsigned)b > sizeof(buf)) || (b <= 0)) {
|
|
Packit |
534379 |
OPAE_MSG("Unexpected size reading from %s", path);
|
|
Packit |
534379 |
goto out_close;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} while (buf[b - 1] != '\n' && buf[b - 1] != '\0'
|
|
Packit |
534379 |
&& (unsigned)b < sizeof(buf));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// erase \n
|
|
Packit |
534379 |
buf[b - 1] = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
for (i = 0; i < 32; i += 2) {
|
|
Packit |
534379 |
tmp = buf[i + 2];
|
|
Packit |
534379 |
buf[i + 2] = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
octet = 0;
|
|
Packit |
534379 |
sscanf(&buf[i], "%x", &octet);
|
|
Packit |
534379 |
guid[i / 2] = (uint8_t)octet;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
buf[i + 2] = tmp;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_close:
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result check_sysfs_path_is_valid(const char *sysfs_path)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result result = FPGA_OK;
|
|
Packit |
534379 |
char path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
struct stat stats;
|
|
Packit |
534379 |
size_t len;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!sysfs_path) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input path");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len = strnlen(sysfs_path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
memcpy(path, sysfs_path, len);
|
|
Packit |
534379 |
path[len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = opae_glob_path(path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
if (result) {
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (stat(path, &stats) != 0) {
|
|
Packit |
534379 |
OPAE_ERR("stat failed: %s", strerror(errno));
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (S_ISDIR(stats.st_mode) || S_ISREG(stats.st_mode)) {
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_path_is_valid(const char *root, const char *attr_path)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
char path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
fpga_result result = FPGA_OK;
|
|
Packit |
534379 |
struct stat stats;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!root || !attr_path) {
|
|
Packit |
534379 |
OPAE_ERR("input path is NULL");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(path, sizeof(path),
|
|
Packit |
534379 |
"%s/%s", root, attr_path);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = opae_glob_path(path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
if (result) {
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (stat(path, &stats) != 0) {
|
|
Packit |
534379 |
OPAE_ERR("stat failed: %s", strerror(errno));
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (S_ISDIR(stats.st_mode) || S_ISREG(stats.st_mode)) {
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// sysfs convenience functions to access device components by device number
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_socket_id(int dev, int subdev, uint8_t *socket_id)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result result;
|
|
Packit |
534379 |
char spath[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
int i;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(spath, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
SYSFS_FPGA_CLASS_PATH SYSFS_FME_PATH_FMT
|
|
Packit |
534379 |
"/" FPGA_SYSFS_SOCKET_ID,
|
|
Packit |
534379 |
dev, subdev);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
i = 0;
|
|
Packit |
534379 |
result = sysfs_read_int(spath, &i);
|
|
Packit |
534379 |
if (FPGA_OK != result)
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*socket_id = (uint8_t)i;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_afu_id(int dev, int subdev, fpga_guid guid)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
char spath[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(spath, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
SYSFS_FPGA_CLASS_PATH SYSFS_AFU_PATH_FMT
|
|
Packit |
534379 |
"/" FPGA_SYSFS_AFU_GUID,
|
|
Packit |
534379 |
dev, subdev);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return sysfs_read_guid(spath, guid);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_pr_id(int dev, int subdev, fpga_guid guid)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
char spath[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(spath, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
SYSFS_FPGA_CLASS_PATH SYSFS_FME_PATH_FMT
|
|
Packit |
534379 |
"/" FPGA_SYSFS_FME_INTERFACE_ID,
|
|
Packit |
534379 |
dev, subdev);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return sysfs_read_guid(spath, guid);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_slots(int dev, int subdev, uint32_t *slots)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
char spath[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(spath, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
SYSFS_FPGA_CLASS_PATH SYSFS_FME_PATH_FMT
|
|
Packit |
534379 |
"/" FPGA_SYSFS_NUM_SLOTS,
|
|
Packit |
534379 |
dev, subdev);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return sysfs_read_u32(spath, slots);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_get_bitstream_id(int dev, int subdev, uint64_t *id)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
char spath[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(spath, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
SYSFS_FPGA_CLASS_PATH SYSFS_FME_PATH_FMT
|
|
Packit |
534379 |
"/" FPGA_SYSFS_BITSTREAM_ID,
|
|
Packit |
534379 |
dev, subdev);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return sysfs_read_u64(spath, id);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/**
|
|
Packit |
534379 |
* @brief Get a path to a port node given a handle to an resource
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
* @param handle Open handle to an fme resource (FPGA_DEVICE)
|
|
Packit |
534379 |
* @param(out) sysfs_port realpath to a port node in sysfs
|
|
Packit |
534379 |
*
|
|
Packit |
534379 |
* @return FPGA_OK if able to find the path to the port
|
|
Packit |
534379 |
* FPGA_EXCEPTION if errors encountered during copying,
|
|
Packit |
534379 |
* formatting strings
|
|
Packit |
534379 |
* FPGA_NOT_FOUND if unable to find fme path or any relevant paths
|
|
Packit |
534379 |
*/
|
|
Packit |
534379 |
fpga_result get_port_sysfs(fpga_handle handle, char *sysfs_port)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
|
|
Packit |
534379 |
struct _fpga_token *_token;
|
|
Packit |
534379 |
struct _fpga_handle *_handle = (struct _fpga_handle *)handle;
|
|
Packit |
534379 |
char sysfs_path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
char fpga_path[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
fpga_result result = FPGA_OK;
|
|
Packit |
534379 |
int i = 0;
|
|
Packit |
534379 |
size_t len;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// subdir candidates to look for when locating "fpga*" node in sysfs
|
|
Packit |
534379 |
// order is important here because a virtfn* node is the exception
|
|
Packit |
534379 |
// (will only exist when a port is on a VF) and will be used to point
|
|
Packit |
534379 |
// to the VF that the port is on
|
|
Packit |
534379 |
const char *fpga_globs[] = {"device/virtfn*/fpga*", "device/fpga*", NULL};
|
|
Packit |
534379 |
if (sysfs_port == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid output pointer");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (_handle == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid handle");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
_token = (struct _fpga_token *)_handle->token;
|
|
Packit |
534379 |
if (_token == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Token not found");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!strstr(_token->sysfspath, FPGA_SYSFS_FME)) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid sysfspath in token");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// now try globbing fme token's sysfs path + a candidate
|
|
Packit |
534379 |
for (; fpga_globs[i]; ++i) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (snprintf(sysfs_path, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
"%s/../%s", _token->sysfspath, fpga_globs[i]) < 0) {
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = opae_glob_path(sysfs_path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
if (result == FPGA_OK) {
|
|
Packit |
534379 |
// we've found a path to the "fpga*" node
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
} else if (result != FPGA_NOT_FOUND) {
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!fpga_globs[i]) {
|
|
Packit |
534379 |
OPAE_ERR("Could not find path to port device/fpga");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!SYSFS_FORMAT(sysfs_device_glob) ||
|
|
Packit |
534379 |
!SYSFS_FORMAT(sysfs_port_glob)) {
|
|
Packit |
534379 |
OPAE_ERR("NULL glob pattern");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// format a string to look for in the subdirectory of the "fpga*" node
|
|
Packit |
534379 |
// this subdirectory should include glob patterns for the current
|
|
Packit |
534379 |
// driver
|
|
Packit |
534379 |
// -- intel-fgga-dev.*/intel-fpga-port.*
|
|
Packit |
534379 |
// -- region*/dfl-port.*
|
|
Packit |
534379 |
snprintf(fpga_path, SYSFS_PATH_MAX, "/%s/%s",
|
|
Packit |
534379 |
SYSFS_FORMAT(sysfs_device_glob),
|
|
Packit |
534379 |
SYSFS_FORMAT(sysfs_port_glob));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// now concatenate the subdirectory to the "fpga*" node
|
|
Packit |
534379 |
len = strnlen(fpga_path, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
strncat(sysfs_path, fpga_path, len + 1);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = opae_glob_path(sysfs_path, sizeof(sysfs_path) - 1);
|
|
Packit |
534379 |
if (result) {
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// copy the assembled and verified path to the output param
|
|
Packit |
534379 |
if (!realpath(sysfs_path, sysfs_port)) {
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
enum fpga_hw_type opae_id_to_hw_type(uint16_t vendor_id, uint16_t device_id)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
enum fpga_hw_type hw_type = FPGA_HW_UNKNOWN;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (vendor_id == 0x8086) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
switch (device_id) {
|
|
Packit |
534379 |
case 0xbcbc: /* FALLTHROUGH */
|
|
Packit |
534379 |
case 0xbcbd: /* FALLTHROUGH */
|
|
Packit |
534379 |
case 0xbcbe: /* FALLTHROUGH */
|
|
Packit |
534379 |
case 0xbcbf: /* FALLTHROUGH */
|
|
Packit |
534379 |
case 0xbcc0: /* FALLTHROUGH */
|
|
Packit |
534379 |
case 0xbcc1: /* FALLTHROUGH */
|
|
Packit |
534379 |
case 0x09cb:
|
|
Packit |
534379 |
hw_type = FPGA_HW_MCP;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
case 0x09c4: /* FALLTHROUGH */
|
|
Packit |
534379 |
case 0x09c5:
|
|
Packit |
534379 |
hw_type = FPGA_HW_DCP_RC;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
case 0x0b2b: /* FALLTHROUGH */
|
|
Packit |
534379 |
case 0x0b2c:
|
|
Packit |
534379 |
hw_type = FPGA_HW_DCP_DC;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
case 0x0b30: /* FALLTHROUGH */
|
|
Packit |
534379 |
case 0x0b31:
|
|
Packit |
534379 |
hw_type = FPGA_HW_DCP_VC;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
default:
|
|
Packit |
534379 |
OPAE_ERR("unknown device id: 0x%04x", device_id);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
OPAE_ERR("unknown vendor id: 0x%04x", vendor_id);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return hw_type;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// get fpga hardware type from handle
|
|
Packit |
534379 |
fpga_result get_fpga_hw_type(fpga_handle handle, enum fpga_hw_type *hw_type)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
struct _fpga_token *_token = NULL;
|
|
Packit |
534379 |
struct _fpga_handle *_handle = (struct _fpga_handle *)handle;
|
|
Packit |
534379 |
char sysfs_path[SYSFS_PATH_MAX] = {0};
|
|
Packit |
534379 |
fpga_result result = FPGA_OK;
|
|
Packit |
534379 |
int err = 0;
|
|
Packit |
534379 |
uint64_t vendor_id = 0;
|
|
Packit |
534379 |
uint64_t device_id = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (_handle == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid handle");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (hw_type == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input Parameters");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (pthread_mutex_lock(&_handle->lock)) {
|
|
Packit |
534379 |
OPAE_MSG("Failed to lock handle mutex");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
_token = (struct _fpga_token *)_handle->token;
|
|
Packit |
534379 |
if (_token == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Token not found");
|
|
Packit |
534379 |
result = FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
goto out_unlock;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (snprintf(sysfs_path, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
"%s/../device/vendor", _token->sysfspath) < 0) {
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
result = FPGA_EXCEPTION;
|
|
Packit |
534379 |
goto out_unlock;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = sysfs_read_u64(sysfs_path, &vendor_id);
|
|
Packit |
534379 |
if (result != 0) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to read vendor ID");
|
|
Packit |
534379 |
goto out_unlock;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (snprintf(sysfs_path, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
"%s/../device/device", _token->sysfspath) < 0) {
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
result = FPGA_EXCEPTION;
|
|
Packit |
534379 |
goto out_unlock;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = sysfs_read_u64(sysfs_path, &device_id);
|
|
Packit |
534379 |
if (result != 0) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to read device ID");
|
|
Packit |
534379 |
goto out_unlock;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*hw_type = opae_id_to_hw_type((uint16_t)vendor_id,
|
|
Packit |
534379 |
(uint16_t)device_id);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_unlock:
|
|
Packit |
534379 |
err = pthread_mutex_unlock(&_handle->lock);
|
|
Packit |
534379 |
if (err)
|
|
Packit |
534379 |
OPAE_ERR("pthread_mutex_unlock() failed: %s", strerror(err));
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/*
|
|
Packit |
534379 |
* The rlpath path is assumed to be of the form:
|
|
Packit |
534379 |
* ../../devices/pci0000:5e/0000:5e:00.0/fpga/intel-fpga-dev.0
|
|
Packit |
534379 |
*/
|
|
Packit |
534379 |
fpga_result sysfs_sbdf_from_path(const char *sysfspath, int *s, int *b, int *d,
|
|
Packit |
534379 |
int *f)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
char rlpath[SYSFS_PATH_MAX];
|
|
Packit |
534379 |
char *p;
|
|
Packit |
534379 |
|
|
Packit Service |
c388c9 |
res = readlink(sysfspath, rlpath, sizeof(rlpath));
|
|
Packit |
534379 |
if (-1 == res) {
|
|
Packit |
534379 |
OPAE_MSG("Can't read link %s (no driver?)", sysfspath);
|
|
Packit |
534379 |
return FPGA_NO_DRIVER;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// Find the BDF from the link path.
|
|
Packit |
534379 |
rlpath[res] = 0;
|
|
Packit |
534379 |
p = strrchr(rlpath, '/');
|
|
Packit |
534379 |
if (!p) {
|
|
Packit |
534379 |
OPAE_MSG("Invalid link %s (no driver?)", rlpath);
|
|
Packit |
534379 |
return FPGA_NO_DRIVER;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
*p = 0;
|
|
Packit |
534379 |
p = strrchr(rlpath, '/');
|
|
Packit |
534379 |
if (!p) {
|
|
Packit |
534379 |
OPAE_MSG("Invalid link %s (no driver?)", rlpath);
|
|
Packit |
534379 |
return FPGA_NO_DRIVER;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
*p = 0;
|
|
Packit |
534379 |
p = strrchr(rlpath, '/');
|
|
Packit |
534379 |
if (!p) {
|
|
Packit |
534379 |
OPAE_MSG("Invalid link %s (no driver?)", rlpath);
|
|
Packit |
534379 |
return FPGA_NO_DRIVER;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
++p;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// 11
|
|
Packit |
534379 |
// 012345678901
|
|
Packit |
534379 |
// ssss:bb:dd.f
|
|
Packit |
534379 |
*f = (int)strtoul(p + 11, NULL, 16);
|
|
Packit |
534379 |
*(p + 10) = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*d = (int)strtoul(p + 8, NULL, 16);
|
|
Packit |
534379 |
*(p + 7) = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*b = (int)strtoul(p + 5, NULL, 16);
|
|
Packit |
534379 |
*(p + 4) = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*s = (int)strtoul(p, NULL, 16);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sysfs_objectid_from_path(const char *sysfspath, uint64_t *object_id)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
char sdevpath[SYSFS_PATH_MAX] = { 0, };
|
|
Packit |
534379 |
uint32_t major = 0;
|
|
Packit |
534379 |
uint32_t minor = 0;
|
|
Packit |
534379 |
fpga_result result;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
snprintf(sdevpath, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
"%s/dev", sysfspath);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = sysfs_read_u32_pair(sdevpath, &major, &minor, ':');
|
|
Packit |
534379 |
if (FPGA_OK != result)
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*object_id = ((major & 0xFFF) << 20) | (minor & 0xFFFFF);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ssize_t eintr_read(int fd, void *buf, size_t count)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
ssize_t bytes_read = 0, total_read = 0;
|
|
Packit |
534379 |
char *ptr = buf;
|
|
Packit |
534379 |
while (total_read < (ssize_t)count) {
|
|
Packit |
534379 |
bytes_read = read(fd, ptr + total_read, count - total_read);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (bytes_read < 0) {
|
|
Packit |
534379 |
if (errno == EINTR) {
|
|
Packit |
534379 |
continue;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return bytes_read;
|
|
Packit |
534379 |
} else if (bytes_read == 0) {
|
|
Packit |
534379 |
return lseek(fd, 0, SEEK_CUR);
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
total_read += bytes_read;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return total_read;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ssize_t eintr_write(int fd, void *buf, size_t count)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
ssize_t bytes_written = 0, total_written = 0;
|
|
Packit |
534379 |
char *ptr = buf;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!buf) {
|
|
Packit |
534379 |
return -1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
while (total_written < (ssize_t)count) {
|
|
Packit |
534379 |
bytes_written =
|
|
Packit |
534379 |
write(fd, ptr + total_written, count - total_written);
|
|
Packit |
534379 |
if (bytes_written < 0) {
|
|
Packit |
534379 |
if (errno == EINTR) {
|
|
Packit |
534379 |
continue;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return bytes_written;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
total_written += bytes_written;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return total_written;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result cat_token_sysfs_path(char *dest, fpga_token token, const char *path)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
struct _fpga_token *_token = (struct _fpga_token *)token;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!dest) {
|
|
Packit |
534379 |
OPAE_ERR("destination str is NULL");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!path) {
|
|
Packit |
534379 |
OPAE_ERR("path str is NULL");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (snprintf(dest, SYSFS_PATH_MAX,
|
|
Packit |
534379 |
"%s/%s", _token->sysfspath, path) < 0) {
|
|
Packit |
534379 |
OPAE_ERR("snprintf buffer overflow");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result cat_sysfs_path(char *dest, const char *path)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
size_t len_dest;
|
|
Packit |
534379 |
size_t len_path;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!dest || !path) {
|
|
Packit |
534379 |
OPAE_ERR("NULL pointer in name");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
len_dest = strnlen(dest, SYSFS_PATH_MAX);
|
|
Packit |
534379 |
len_path = strnlen(path, SYSFS_PATH_MAX);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (len_dest + len_path > SYSFS_PATH_MAX) {
|
|
Packit |
534379 |
OPAE_ERR("concat strings too long");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
strncat(dest, path, SYSFS_PATH_MAX);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result cat_handle_sysfs_path(char *dest, fpga_handle handle,
|
|
Packit |
534379 |
const char *path)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
struct _fpga_handle *_handle = (struct _fpga_handle *)(handle);
|
|
Packit |
534379 |
return cat_token_sysfs_path(dest, _handle->token, path);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC char *cstr_dup(const char *str)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
size_t s;
|
|
Packit |
534379 |
char *p;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!str) {
|
|
Packit |
534379 |
OPAE_ERR("NULL param to cstr_dup");
|
|
Packit |
534379 |
return NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
s = strnlen(str, PATH_MAX - 1);
|
|
Packit |
534379 |
p = malloc(s+1);
|
|
Packit |
534379 |
if (!p) {
|
|
Packit |
534379 |
OPAE_ERR("malloc failed");
|
|
Packit |
534379 |
return NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
strncpy(p, str, s + 1);
|
|
Packit |
534379 |
p[s] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return p;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
struct _fpga_object *alloc_fpga_object(const char *sysfspath, const char *name)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
struct _fpga_object *obj = calloc(1, sizeof(struct _fpga_object));
|
|
Packit |
534379 |
if (obj) {
|
|
Packit |
534379 |
pthread_mutexattr_t mattr;
|
|
Packit |
534379 |
if (pthread_mutexattr_init(&mattr)) {
|
|
Packit |
534379 |
OPAE_ERR("pthread_mutexattr_init() failed");
|
|
Packit |
534379 |
goto out_err;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (pthread_mutexattr_settype(&mattr,
|
|
Packit |
534379 |
PTHREAD_MUTEX_RECURSIVE)) {
|
|
Packit |
534379 |
OPAE_ERR("pthread_mutexattr_settype() failed");
|
|
Packit |
534379 |
pthread_mutexattr_destroy(&mattr);
|
|
Packit |
534379 |
goto out_err;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (pthread_mutex_init(&obj->lock, &mattr)) {
|
|
Packit |
534379 |
OPAE_ERR("pthread_mutex_init() failed");
|
|
Packit |
534379 |
pthread_mutexattr_destroy(&mattr);
|
|
Packit |
534379 |
goto out_err;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
pthread_mutexattr_destroy(&mattr);
|
|
Packit |
534379 |
obj->handle = NULL;
|
|
Packit |
534379 |
obj->path = cstr_dup(sysfspath);
|
|
Packit |
534379 |
obj->name = cstr_dup(name);
|
|
Packit |
534379 |
obj->perm = 0;
|
|
Packit |
534379 |
obj->size = 0;
|
|
Packit |
534379 |
obj->max_size = 0;
|
|
Packit |
534379 |
obj->buffer = NULL;
|
|
Packit |
534379 |
obj->objects = NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return obj;
|
|
Packit |
534379 |
out_err:
|
|
Packit |
534379 |
if (obj) {
|
|
Packit |
534379 |
free(obj);
|
|
Packit |
534379 |
obj = NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return obj;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result destroy_fpga_object(struct _fpga_object *obj)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
FREE_IF(obj->path);
|
|
Packit |
534379 |
FREE_IF(obj->name);
|
|
Packit |
534379 |
FREE_IF(obj->buffer);
|
|
Packit |
534379 |
while (obj->size && obj->objects) {
|
|
Packit |
534379 |
res = destroy_fpga_object(
|
|
Packit |
534379 |
(struct _fpga_object *)obj->objects[--obj->size]);
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
OPAE_ERR("Error freeing subobject");
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
FREE_IF(obj->objects);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (pthread_mutex_unlock(&obj->lock)) {
|
|
Packit |
534379 |
OPAE_MSG("pthread_mutex_unlock() failed");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (pthread_mutex_destroy(&obj->lock)) {
|
|
Packit |
534379 |
OPAE_ERR("Error destroying mutex");
|
|
Packit |
534379 |
res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
free(obj);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result opae_glob_path(char *path, size_t len)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
glob_t pglob;
|
|
Packit |
534379 |
pglob.gl_pathc = 0;
|
|
Packit |
534379 |
pglob.gl_pathv = NULL;
|
|
Packit |
534379 |
int globres = glob(path, 0, NULL, &pglob);
|
|
Packit |
534379 |
if (!globres) {
|
|
Packit |
534379 |
if (pglob.gl_pathc > 1) {
|
|
Packit |
534379 |
OPAE_MSG("Ambiguous object key - using first one");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
memcpy(path, pglob.gl_pathv[0], len);
|
|
Packit |
534379 |
path[len] = '\0';
|
|
Packit |
534379 |
globfree(&pglob);
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
switch (globres) {
|
|
Packit |
534379 |
case GLOB_NOSPACE:
|
|
Packit |
534379 |
res = FPGA_NO_MEMORY;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
case GLOB_NOMATCH:
|
|
Packit |
534379 |
res = FPGA_NOT_FOUND;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
default:
|
|
Packit |
534379 |
res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (pglob.gl_pathv) {
|
|
Packit |
534379 |
globfree(&pglob);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result opae_glob_paths(const char *path, size_t found_max, char *found[],
|
|
Packit |
534379 |
size_t *num_found)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
glob_t pglob;
|
|
Packit |
534379 |
pglob.gl_pathc = 0;
|
|
Packit |
534379 |
pglob.gl_pathv = NULL;
|
|
Packit |
534379 |
int globres = glob(path, 0, NULL, &pglob);
|
|
Packit |
534379 |
size_t i = 0;
|
|
Packit |
534379 |
size_t to_copy = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!globres) {
|
|
Packit |
534379 |
*num_found = pglob.gl_pathc;
|
|
Packit |
534379 |
to_copy = *num_found < found_max ? *num_found : found_max;
|
|
Packit |
534379 |
while (found && i < to_copy) {
|
|
Packit |
534379 |
found[i] = cstr_dup(pglob.gl_pathv[i]);
|
|
Packit |
534379 |
if (!found[i]) {
|
|
Packit |
534379 |
// we had an error duplicating the string
|
|
Packit |
534379 |
// undo what we've duplicated so far
|
|
Packit |
534379 |
while (i) {
|
|
Packit |
534379 |
free(found[--i]);
|
|
Packit |
534379 |
found[i] = NULL;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
OPAE_ERR("Could not copy globbed path");
|
|
Packit |
534379 |
res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
i++;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
switch (globres) {
|
|
Packit |
534379 |
case GLOB_NOSPACE:
|
|
Packit |
534379 |
res = FPGA_NO_MEMORY;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
case GLOB_NOMATCH:
|
|
Packit |
534379 |
res = FPGA_NOT_FOUND;
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
default:
|
|
Packit |
534379 |
res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
out_free:
|
|
Packit |
534379 |
if (pglob.gl_pathv) {
|
|
Packit |
534379 |
globfree(&pglob);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result sync_object(fpga_object obj)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
struct _fpga_object *_obj;
|
|
Packit |
534379 |
int fd = -1;
|
|
Packit |
534379 |
ssize_t bytes_read = 0;
|
|
Packit |
534379 |
ASSERT_NOT_NULL(obj);
|
|
Packit |
534379 |
_obj = (struct _fpga_object *)obj;
|
|
Packit |
534379 |
fd = open(_obj->path, _obj->perm);
|
|
Packit |
534379 |
if (fd < 0) {
|
|
Packit |
534379 |
OPAE_ERR("Error opening %s: %s", _obj->path, strerror(errno));
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
bytes_read = eintr_read(fd, _obj->buffer, _obj->max_size);
|
|
Packit |
534379 |
if (bytes_read < 0) {
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
_obj->size = bytes_read;
|
|
Packit |
534379 |
close(fd);
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result make_sysfs_group(char *sysfspath, const char *name,
|
|
Packit |
534379 |
fpga_object *object, int flags, fpga_handle handle)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
struct dirent **namelist;
|
|
Packit |
534379 |
int n;
|
|
Packit |
534379 |
size_t pathlen = strlen(sysfspath);
|
|
Packit |
534379 |
char *ptr = NULL;
|
|
Packit |
534379 |
fpga_object subobj;
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
struct _fpga_object *group;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (flags & FPGA_OBJECT_GLOB) {
|
|
Packit |
534379 |
res = opae_glob_path(sysfspath, SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (res != FPGA_OK) {
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
n = scandir(sysfspath, &namelist, sysfs_filter, alphasort);
|
|
Packit |
534379 |
if (n < 0) {
|
|
Packit |
534379 |
OPAE_ERR("Error calling scandir: %s", strerror(errno));
|
|
Packit |
534379 |
switch (errno) {
|
|
Packit |
534379 |
case ENOMEM:
|
|
Packit |
534379 |
return FPGA_NO_MEMORY;
|
|
Packit |
534379 |
case ENOENT:
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (n == 0) {
|
|
Packit |
534379 |
OPAE_ERR("Group is empty");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
group = alloc_fpga_object(sysfspath, name);
|
|
Packit |
534379 |
if (!group) {
|
|
Packit |
534379 |
res = FPGA_NO_MEMORY;
|
|
Packit |
534379 |
goto out_free_namelist;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
group->handle = handle;
|
|
Packit |
534379 |
group->type = FPGA_SYSFS_DIR;
|
|
Packit |
534379 |
if (flags & FPGA_OBJECT_RECURSE_ONE
|
|
Packit |
534379 |
|| flags & FPGA_OBJECT_RECURSE_ALL) {
|
|
Packit |
534379 |
ptr = sysfspath + pathlen;
|
|
Packit |
534379 |
*ptr++ = '/';
|
|
Packit |
534379 |
group->objects = calloc(n, sizeof(fpga_object));
|
|
Packit |
534379 |
if (!group->objects) {
|
|
Packit |
534379 |
res = FPGA_NO_MEMORY;
|
|
Packit |
534379 |
goto out_free_group;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
group->size = 0;
|
|
Packit |
534379 |
while (n--) {
|
|
Packit |
534379 |
strncpy(ptr, namelist[n]->d_name,
|
|
Packit |
534379 |
SYSFS_PATH_MAX - pathlen + 1);
|
|
Packit |
534379 |
if (flags & FPGA_OBJECT_RECURSE_ONE) {
|
|
Packit |
534379 |
flags &= ~FPGA_OBJECT_RECURSE_ONE;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (!make_sysfs_object(
|
|
Packit |
534379 |
sysfspath, namelist[n]->d_name,
|
|
Packit |
534379 |
&subobj, flags, handle)) {
|
|
Packit |
534379 |
group->objects[group->size++] = subobj;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
free(namelist[n]);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
free(namelist);
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
while (n--) {
|
|
Packit |
534379 |
free(namelist[n]);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
free(namelist);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
*object = (fpga_object)group;
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_free_group:
|
|
Packit |
534379 |
if (destroy_fpga_object(group)) {
|
|
Packit |
534379 |
OPAE_ERR("Error destroying object");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_free_namelist:
|
|
Packit |
534379 |
while (n--)
|
|
Packit |
534379 |
free(namelist[n]);
|
|
Packit |
534379 |
free(namelist);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result make_sysfs_array(char *sysfspath, const char *name,
|
|
Packit |
534379 |
fpga_object *object, int flags, fpga_handle handle,
|
|
Packit |
534379 |
char *objects[], size_t num_objects)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
size_t i = 0;
|
|
Packit |
534379 |
struct _fpga_object *array = alloc_fpga_object(sysfspath, name);
|
|
Packit |
534379 |
char *oname = NULL;
|
|
Packit |
534379 |
if (!array) {
|
|
Packit |
534379 |
OPAE_ERR(
|
|
Packit |
534379 |
"Error allocating memory for container of fpga_objects");
|
|
Packit |
534379 |
return FPGA_NO_MEMORY;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
array->objects = calloc(num_objects, sizeof(fpga_object));
|
|
Packit |
534379 |
if (!array->objects) {
|
|
Packit |
534379 |
OPAE_ERR("Error allocating memory for array of fpga_objects");
|
|
Packit |
534379 |
destroy_fpga_object(array);
|
|
Packit |
534379 |
return FPGA_NO_MEMORY;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
array->handle = handle;
|
|
Packit |
534379 |
array->type = FPGA_SYSFS_LIST;
|
|
Packit |
534379 |
array->size = num_objects;
|
|
Packit |
534379 |
for (i = 0; i < num_objects; ++i) {
|
|
Packit |
534379 |
oname = strrchr(objects[i], '/');
|
|
Packit |
534379 |
if (!oname) {
|
|
Packit |
534379 |
OPAE_ERR("Error with sysfs path: %s", objects[i]);
|
|
Packit |
534379 |
res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
goto out_err;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
res = make_sysfs_object(objects[i], oname+1, &array->objects[i],
|
|
Packit |
534379 |
flags & ~FPGA_OBJECT_GLOB, handle);
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
goto out_err;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
*object = (fpga_object)array;
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
out_err:
|
|
Packit |
534379 |
if (destroy_fpga_object(array)) {
|
|
Packit |
534379 |
OPAE_ERR("Error destroying object");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define MAX_SYSOBJECT_GLOB 128
|
|
Packit |
534379 |
fpga_result make_sysfs_object(char *sysfspath, const char *name,
|
|
Packit |
534379 |
fpga_object *object, int flags,
|
|
Packit |
534379 |
fpga_handle handle)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
uint64_t pg_size = (uint64_t)sysconf(_SC_PAGE_SIZE);
|
|
Packit |
534379 |
struct _fpga_object *obj = NULL;
|
|
Packit |
534379 |
struct stat objstat;
|
|
Packit |
534379 |
int statres;
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
char *object_paths[MAX_SYSOBJECT_GLOB] = { NULL };
|
|
Packit |
534379 |
size_t found = 0;
|
|
Packit |
534379 |
size_t len;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (flags & FPGA_OBJECT_GLOB) {
|
|
Packit |
534379 |
res = opae_glob_paths(sysfspath, MAX_SYSOBJECT_GLOB,
|
|
Packit |
534379 |
object_paths, &found);
|
|
Packit |
534379 |
if (res) {
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (found == 1) {
|
|
Packit |
534379 |
len = strnlen(object_paths[0], SYSFS_PATH_MAX - 1);
|
|
Packit |
534379 |
memcpy(sysfspath, object_paths[0], len);
|
|
Packit |
534379 |
sysfspath[len] = '\0';
|
|
Packit |
534379 |
res = make_sysfs_object(sysfspath, name, object,
|
|
Packit |
534379 |
flags & ~FPGA_OBJECT_GLOB,
|
|
Packit |
534379 |
handle);
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
res = make_sysfs_array(sysfspath, name, object, flags,
|
|
Packit |
534379 |
handle, object_paths, found);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
// opae_glob_paths allocates memory for each path found
|
|
Packit |
534379 |
// let's free it here since we don't need it any longer
|
|
Packit |
534379 |
while (found) {
|
|
Packit |
534379 |
free(object_paths[--found]);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
statres = stat(sysfspath, &objstat);
|
|
Packit |
534379 |
if (statres < 0) {
|
|
Packit |
534379 |
OPAE_MSG("Error accessing %s: %s", sysfspath, strerror(errno));
|
|
Packit |
534379 |
switch (errno) {
|
|
Packit |
534379 |
case ENOENT:
|
|
Packit |
534379 |
res = FPGA_NOT_FOUND;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
case ENOMEM:
|
|
Packit |
534379 |
res = FPGA_NO_MEMORY;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
case EACCES:
|
|
Packit |
534379 |
res = FPGA_NO_ACCESS;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
res = FPGA_EXCEPTION;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (S_ISDIR(objstat.st_mode)) {
|
|
Packit |
534379 |
return make_sysfs_group(sysfspath, name, object, flags, handle);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
obj = alloc_fpga_object(sysfspath, name);
|
|
Packit |
534379 |
if (!obj) {
|
|
Packit |
534379 |
return FPGA_NO_MEMORY;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
obj->handle = handle;
|
|
Packit |
534379 |
obj->type = FPGA_SYSFS_FILE;
|
|
Packit |
534379 |
obj->buffer = calloc(pg_size, sizeof(uint8_t));
|
|
Packit |
534379 |
obj->max_size = pg_size;
|
|
Packit |
534379 |
if (handle && (objstat.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) {
|
|
Packit |
534379 |
if ((objstat.st_mode & (S_IRUSR | S_IRGRP | S_IROTH))) {
|
|
Packit |
534379 |
obj->perm = O_RDWR;
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
obj->perm = O_WRONLY;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
obj->perm = O_RDONLY;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
*object = (fpga_object)obj;
|
|
Packit |
534379 |
if (obj->perm == O_RDONLY || obj->perm == O_RDWR) {
|
|
Packit |
534379 |
return sync_object((fpga_object)obj);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
out_free:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
free(obj);
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|