118 lines
2.9 KiB
C
118 lines
2.9 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/* Copyright(c) 2023 Intel Corporation */
|
|
|
|
#include <linux/sysfs.h>
|
|
#include <linux/pci.h>
|
|
#include <linux/string.h>
|
|
|
|
#include "adf_common_drv.h"
|
|
#include "adf_sysfs_ras_counters.h"
|
|
|
|
static ssize_t errors_correctable_show(struct device *dev,
|
|
struct device_attribute *dev_attr,
|
|
char *buf)
|
|
{
|
|
struct adf_accel_dev *accel_dev;
|
|
unsigned long counter;
|
|
|
|
accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
|
|
if (!accel_dev)
|
|
return -EINVAL;
|
|
|
|
counter = ADF_RAS_ERR_CTR_READ(accel_dev->ras_errors, ADF_RAS_CORR);
|
|
return scnprintf(buf, PAGE_SIZE, "%ld\n", counter);
|
|
}
|
|
|
|
static ssize_t errors_nonfatal_show(struct device *dev,
|
|
struct device_attribute *dev_attr,
|
|
char *buf)
|
|
{
|
|
struct adf_accel_dev *accel_dev;
|
|
unsigned long counter;
|
|
|
|
accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
|
|
if (!accel_dev)
|
|
return -EINVAL;
|
|
|
|
counter = ADF_RAS_ERR_CTR_READ(accel_dev->ras_errors, ADF_RAS_UNCORR);
|
|
return scnprintf(buf, PAGE_SIZE, "%ld\n", counter);
|
|
}
|
|
|
|
static ssize_t errors_fatal_show(struct device *dev,
|
|
struct device_attribute *dev_attr,
|
|
char *buf)
|
|
{
|
|
struct adf_accel_dev *accel_dev;
|
|
unsigned long counter;
|
|
|
|
accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
|
|
if (!accel_dev)
|
|
return -EINVAL;
|
|
|
|
counter = ADF_RAS_ERR_CTR_READ(accel_dev->ras_errors, ADF_RAS_FATAL);
|
|
return scnprintf(buf, PAGE_SIZE, "%ld\n", counter);
|
|
}
|
|
|
|
static ssize_t reset_error_counters_store(struct device *dev,
|
|
struct device_attribute *dev_attr,
|
|
const char *buf, size_t count)
|
|
{
|
|
struct adf_accel_dev *accel_dev;
|
|
|
|
if (buf[0] != '1' || count != 2)
|
|
return -EINVAL;
|
|
|
|
accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
|
|
if (!accel_dev)
|
|
return -EINVAL;
|
|
|
|
ADF_RAS_ERR_CTR_CLEAR(accel_dev->ras_errors);
|
|
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR_RO(errors_correctable);
|
|
static DEVICE_ATTR_RO(errors_nonfatal);
|
|
static DEVICE_ATTR_RO(errors_fatal);
|
|
static DEVICE_ATTR_WO(reset_error_counters);
|
|
|
|
static struct attribute *qat_ras_attrs[] = {
|
|
&dev_attr_errors_correctable.attr,
|
|
&dev_attr_errors_nonfatal.attr,
|
|
&dev_attr_errors_fatal.attr,
|
|
&dev_attr_reset_error_counters.attr,
|
|
NULL,
|
|
};
|
|
|
|
static struct attribute_group qat_ras_group = {
|
|
.attrs = qat_ras_attrs,
|
|
.name = "qat_ras",
|
|
};
|
|
|
|
void adf_sysfs_start_ras(struct adf_accel_dev *accel_dev)
|
|
{
|
|
if (!accel_dev->ras_errors.enabled)
|
|
return;
|
|
|
|
ADF_RAS_ERR_CTR_CLEAR(accel_dev->ras_errors);
|
|
|
|
if (device_add_group(&GET_DEV(accel_dev), &qat_ras_group))
|
|
dev_err(&GET_DEV(accel_dev),
|
|
"Failed to create qat_ras attribute group.\n");
|
|
|
|
accel_dev->ras_errors.sysfs_added = true;
|
|
}
|
|
|
|
void adf_sysfs_stop_ras(struct adf_accel_dev *accel_dev)
|
|
{
|
|
if (!accel_dev->ras_errors.enabled)
|
|
return;
|
|
|
|
if (accel_dev->ras_errors.sysfs_added) {
|
|
device_remove_group(&GET_DEV(accel_dev), &qat_ras_group);
|
|
accel_dev->ras_errors.sysfs_added = false;
|
|
}
|
|
|
|
ADF_RAS_ERR_CTR_CLEAR(accel_dev->ras_errors);
|
|
}
|