#define PCIE_ECAP_OFFSET 0x100 /* ECAP always begin at offset 0x100 */
typedef struct pcie_config_s {
- _Bool use_sysfs;
- _Bool notif_masked;
- _Bool persistent;
+ bool use_sysfs;
+ bool notif_masked;
+ bool persistent;
char access_dir[PATH_MAX];
- _Bool config_error;
} pcie_config_t;
typedef struct pcie_device_s {
} pcie_error_t;
static llist_t *pcie_dev_list;
-static pcie_config_t pcie_config = {.access_dir = "", .use_sysfs = 1};
+static pcie_config_t pcie_config = {.access_dir = "", .use_sysfs = true};
static pcie_fops_t pcie_fops;
/* Device Error Status */
-static pcie_error_t pcie_base_errors[] = {
+static const pcie_error_t pcie_base_errors[] = {
{PCI_EXP_DEVSTA_CED, "Correctable Error"},
{PCI_EXP_DEVSTA_NFED, "Non-Fatal Error"},
{PCI_EXP_DEVSTA_FED, "Fatal Error"},
static const int pcie_base_errors_num = STATIC_ARRAY_SIZE(pcie_base_errors);
/* Uncorrectable Error Status */
-static pcie_error_t pcie_aer_ues[] = {
+static const pcie_error_t pcie_aer_ues[] = {
#ifdef PCI_ERR_UNC_DLP
{PCI_ERR_UNC_DLP, "Data Link Protocol"},
#endif
static const int pcie_aer_ues_num = STATIC_ARRAY_SIZE(pcie_aer_ues);
/* Correctable Error Status */
-static pcie_error_t pcie_aer_ces[] = {
+static const pcie_error_t pcie_aer_ces[] = {
#ifdef PCI_ERR_COR_RCVR
{PCI_ERR_COR_RCVR, "Receiver Error Status"},
#endif
if (dev_list == NULL)
return -EINVAL;
- snprintf(file_name, sizeof(file_name), "%s/devices", pcie_config.access_dir);
+ ret = snprintf(file_name, sizeof(file_name), "%s/devices",
+ pcie_config.access_dir);
+ if (ret < 1 || (size_t)ret >= sizeof(file_name)) {
+ ERROR(PCIE_ERRORS_PLUGIN ": Access dir `%s' is too long (%d)",
+ pcie_config.access_dir, ret);
+ return -EINVAL;
+ }
fd = fopen(file_name, "r");
if (!fd) {
char errbuf[PCIE_BUFF_SIZE];
while (fgets(buf, sizeof(buf), fd)) {
unsigned int slot;
- uint8_t bus, dev, fn;
if (sscanf(buf, "%x", &slot) != 1) {
ERROR(PCIE_ERRORS_PLUGIN ": Failed to read line %u from %s", i + 1,
continue;
}
- bus = slot >> 8U;
- dev = PCIE_DEV(slot);
- fn = PCIE_FN(slot);
+ uint8_t bus = slot >> 8U;
+ uint8_t dev = PCIE_DEV(slot);
+ uint8_t fn = PCIE_FN(slot);
ret = pcie_add_device(dev_list, 0, bus, dev, fn);
if (ret)
break;
if (dev_list == NULL)
return -EINVAL;
- snprintf(dir_name, sizeof(dir_name), "%s/devices", pcie_config.access_dir);
+ ret = snprintf(dir_name, sizeof(dir_name), "%s/devices",
+ pcie_config.access_dir);
+ if (ret < 1 || (size_t)ret >= sizeof(dir_name)) {
+ ERROR(PCIE_ERRORS_PLUGIN ": Access dir `%s' is too long (%d)",
+ pcie_config.access_dir, ret);
+ return -EINVAL;
+ }
dir = opendir(dir_name);
if (!dir) {
char errbuf[PCIE_BUFF_SIZE];
static int pcie_open_proc(pcie_device_t *dev) {
char file_name[PCIE_NAME_LEN];
- snprintf(file_name, sizeof(file_name), "%s/%02x/%02x.%d",
- pcie_config.access_dir, dev->bus, dev->device, dev->function);
+ int ret =
+ snprintf(file_name, sizeof(file_name), "%s/%02x/%02x.%d",
+ pcie_config.access_dir, dev->bus, dev->device, dev->function);
+ if (ret < 1 || (size_t)ret >= sizeof(file_name)) {
+ ERROR(PCIE_ERRORS_PLUGIN ": Access dir `%s' is too long (%d)",
+ pcie_config.access_dir, ret);
+ return -EINVAL;
+ }
return pcie_open(dev, file_name);
}
static int pcie_open_sysfs(pcie_device_t *dev) {
char file_name[PCIE_NAME_LEN];
- snprintf(file_name, sizeof(file_name), "%s/devices/%04x:%02x:%02x.%d/config",
- pcie_config.access_dir, dev->domain, dev->bus, dev->device,
- dev->function);
+ int ret =
+ snprintf(file_name, sizeof(file_name),
+ "%s/devices/%04x:%02x:%02x.%d/config", pcie_config.access_dir,
+ dev->domain, dev->bus, dev->device, dev->function);
+ if (ret < 1 || (size_t)ret >= sizeof(file_name)) {
+ ERROR(PCIE_ERRORS_PLUGIN ": Access dir `%s' is too long (%d)",
+ pcie_config.access_dir, ret);
+ return -EINVAL;
+ }
return pcie_open(dev, file_name);
}
static void pcie_dispatch_correctable_errors(pcie_device_t *dev,
uint32_t errors, uint32_t masked) {
for (int i = 0; i < pcie_aer_ces_num; i++) {
- pcie_error_t *err = pcie_aer_ces + i;
+ const pcie_error_t *err = pcie_aer_ces + i;
notification_t n = {.severity = NOTIF_WARNING,
.time = cdtime(),
.plugin = PCIE_ERRORS_PLUGIN,
uint32_t errors, uint32_t masked,
uint32_t severity) {
for (int i = 0; i < pcie_aer_ues_num; i++) {
- pcie_error_t *err = pcie_aer_ues + i;
+ const pcie_error_t *err = pcie_aer_ues + i;
const char *type_instance =
(severity & err->mask) ? PCIE_SEV_FATAL : PCIE_SEV_NOFATAL;
notification_t n = {
/* Report errors found in Device Status register */
for (int i = 0; i < pcie_base_errors_num; i++) {
- pcie_error_t *err = pcie_base_errors + i;
+ const pcie_error_t *err = pcie_base_errors + i;
const char *type_instance = (err->mask == PCI_EXP_DEVSTA_FED)
? PCIE_SEV_FATAL
: (err->mask == PCI_EXP_DEVSTA_CED)
? PCIE_SEV_CE
: PCIE_SEV_NOFATAL;
- const int severity =
+ int severity =
(err->mask == PCI_EXP_DEVSTA_FED) ? NOTIF_FAILURE : NOTIF_WARNING;
notification_t n = {.severity = severity,
.time = cdtime(),
for (llentry_t *e = llist_head(devs); e != NULL; e = e_next) {
pcie_device_t *dev = e->value;
- _Bool del = 0;
+ bool del = false;
if (pcie_fops.open(dev) == 0) {
uint16_t status = pcie_read16(dev, PCI_STATUS);
if (dev->cap_exp == -1) {
DEBUG(PCIE_ERRORS_PLUGIN ": Not PCI Express device: %04x:%02x:%02x.%d",
dev->domain, dev->bus, dev->device, dev->function);
- del = 1;
+ del = true;
} else {
dev->ecap_aer = pcie_find_ecap_aer(dev);
if (dev->ecap_aer == -1)
} else {
ERROR(PCIE_ERRORS_PLUGIN ": %04x:%02x:%02x.%d: failed to open",
dev->domain, dev->bus, dev->device, dev->function);
- del = 1;
+ del = true;
}
e_next = e->next;
}
static int pcie_plugin_config(oconfig_item_t *ci) {
+ int status = 0;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
- int status = 0;
if (strcasecmp("Source", child->key) == 0) {
if ((child->values_num != 1) ||
(child->values[0].type != OCONFIG_TYPE_STRING)) {
status = -1;
} else if (strcasecmp("proc", child->values[0].value.string) == 0) {
- pcie_config.use_sysfs = 0;
+ pcie_config.use_sysfs = false;
} else if (strcasecmp("sysfs", child->values[0].value.string) != 0) {
ERROR(PCIE_ERRORS_PLUGIN ": Allowed sources are 'proc' or 'sysfs'.");
status = -1;
} else {
ERROR(PCIE_ERRORS_PLUGIN ": Invalid configuration option \"%s\".",
child->key);
- pcie_config.config_error = 1;
+ status = -1;
break;
}
if (status) {
ERROR(PCIE_ERRORS_PLUGIN ": Invalid configuration parameter \"%s\".",
child->key);
- pcie_config.config_error = 1;
break;
}
}
- return 0;
+ return status;
}
static int pcie_shutdown(void) {
}
static int pcie_init(void) {
- if (pcie_config.config_error) {
- ERROR(PCIE_ERRORS_PLUGIN
- ": Error in configuration, failed to init plugin.");
- return -1;
- }
pcie_access_config();
pcie_dev_list = llist_create();
* Kamil Wiatrowski <kamilx.wiatrowski@intel.com>
**/
+#define plugin_dispatch_notification plugin_dispatch_notification_pcie_test
+
#include "pcie_errors.c" /* sic */
#include "testing.h"
static char g_buff[G_BUFF_LEN];
/* mock functions */
-int plugin_dispatch_notification(const notification_t *notif) {
+int plugin_dispatch_notification_pcie_test(const notification_t *notif) {
last_notif = *notif;
return ENOTSUP;
}
llist_append(test_list, entry);
for (llentry_t *e = llist_head(test_list); e != NULL; e = e->next) {
- EXPECT_EQ_UINT64(dev, e->value);
+ EXPECT_EQ_PTR(dev, e->value);
}
pcie_clear_list(test_list);
DEF_TEST(access_config) {
pcie_config.use_sysfs = 0;
pcie_access_config();
- EXPECT_EQ_UINT64(pcie_list_devices_proc, pcie_fops.list_devices);
- EXPECT_EQ_UINT64(pcie_open_proc, pcie_fops.open);
- EXPECT_EQ_UINT64(pcie_close, pcie_fops.close);
- EXPECT_EQ_UINT64(pcie_read, pcie_fops.read);
+ EXPECT_EQ_PTR(pcie_list_devices_proc, pcie_fops.list_devices);
+ EXPECT_EQ_PTR(pcie_open_proc, pcie_fops.open);
+ EXPECT_EQ_PTR(pcie_close, pcie_fops.close);
+ EXPECT_EQ_PTR(pcie_read, pcie_fops.read);
EXPECT_EQ_STR(PCIE_DEFAULT_PROCDIR, pcie_config.access_dir);
sstrncpy(pcie_config.access_dir, "Test", sizeof(pcie_config.access_dir));
pcie_config.use_sysfs = 1;
pcie_access_config();
- EXPECT_EQ_UINT64(pcie_list_devices_sysfs, pcie_fops.list_devices);
- EXPECT_EQ_UINT64(pcie_open_sysfs, pcie_fops.open);
- EXPECT_EQ_UINT64(pcie_close, pcie_fops.close);
- EXPECT_EQ_UINT64(pcie_read, pcie_fops.read);
+ EXPECT_EQ_PTR(pcie_list_devices_sysfs, pcie_fops.list_devices);
+ EXPECT_EQ_PTR(pcie_open_sysfs, pcie_fops.open);
+ EXPECT_EQ_PTR(pcie_close, pcie_fops.close);
+ EXPECT_EQ_PTR(pcie_read, pcie_fops.read);
EXPECT_EQ_STR("Test", pcie_config.access_dir);
pcie_config.access_dir[0] = '\0';
test_cfg_parent.children_num = 1;
int ret = pcie_plugin_config(&test_cfg_parent);
- EXPECT_EQ_INT(0, ret);
- EXPECT_EQ_INT(1, pcie_config.config_error);
- pcie_config.config_error = 0;
+ EXPECT_EQ_INT(-1, ret);
sstrncpy(key_buff, "Source", sizeof(key_buff));
ret = pcie_plugin_config(&test_cfg_parent);
- EXPECT_EQ_INT(0, ret);
- EXPECT_EQ_INT(1, pcie_config.config_error);
- pcie_config.config_error = 0;
+ EXPECT_EQ_INT(-1, ret);
sstrncpy(value_buff, "proc", sizeof(value_buff));
test_cfg_value.type = OCONFIG_TYPE_NUMBER;
ret = pcie_plugin_config(&test_cfg_parent);
- EXPECT_EQ_INT(0, ret);
- EXPECT_EQ_INT(1, pcie_config.config_error);
- pcie_config.config_error = 0;
+ EXPECT_EQ_INT(-1, ret);
sstrncpy(key_buff, "AccessDir", sizeof(key_buff));
ret = pcie_plugin_config(&test_cfg_parent);
- EXPECT_EQ_INT(0, ret);
- EXPECT_EQ_INT(1, pcie_config.config_error);
- pcie_config.config_error = 0;
+ EXPECT_EQ_INT(-1, ret);
return 0;
}
pcie_config.use_sysfs = 1;
int ret = pcie_plugin_config(&test_cfg_parent);
EXPECT_EQ_INT(0, ret);
- EXPECT_EQ_INT(0, pcie_config.config_error);
EXPECT_EQ_INT(0, pcie_config.use_sysfs);
pcie_config.use_sysfs = 1;
sstrncpy(value_buff, "sysfs", sizeof(value_buff));
ret = pcie_plugin_config(&test_cfg_parent);
EXPECT_EQ_INT(0, ret);
- EXPECT_EQ_INT(0, pcie_config.config_error);
EXPECT_EQ_INT(1, pcie_config.use_sysfs);
sstrncpy(key_buff, "AccessDir", sizeof(key_buff));
sstrncpy(value_buff, "some/test/value", sizeof(value_buff));
ret = pcie_plugin_config(&test_cfg_parent);
EXPECT_EQ_INT(0, ret);
- EXPECT_EQ_INT(0, pcie_config.config_error);
EXPECT_EQ_STR("some/test/value", pcie_config.access_dir);
memset(&test_cfg_value.value, 0, sizeof(test_cfg_value.value));
sstrncpy(key_buff, "ReportMasked", sizeof(key_buff));
ret = pcie_plugin_config(&test_cfg_parent);
EXPECT_EQ_INT(0, ret);
- EXPECT_EQ_INT(0, pcie_config.config_error);
EXPECT_EQ_INT(1, pcie_config.notif_masked);
sstrncpy(key_buff, "PersistentNotifications", sizeof(key_buff));
ret = pcie_plugin_config(&test_cfg_parent);
EXPECT_EQ_INT(0, ret);
- EXPECT_EQ_INT(0, pcie_config.config_error);
EXPECT_EQ_INT(1, pcie_config.persistent);
return 0;