// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright IBM Corp. 2012
 *
 * Author(s):
 *   Jan Glauber <jang@linux.vnet.ibm.com>
 */

#define KMSG_COMPONENT "zpci"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/kernel.h>
#include <linux/stat.h>
#include <linux/pci.h>

#include "../../../drivers/pci/pci.h"

#include <asm/sclp.h>

#define zpci_attr(name, fmt, member)					\
static ssize_t name##_show(struct device *dev,				\
			   struct device_attribute *attr, char *buf)	\
{									\
	struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));		\
									\
	return sprintf(buf, fmt, zdev->member);				\
}									\
static DEVICE_ATTR_RO(name)

zpci_attr(function_id, "0x%08x\n", fid);
zpci_attr(function_handle, "0x%08x\n", fh);
zpci_attr(pchid, "0x%04x\n", pchid);
zpci_attr(pfgid, "0x%02x\n", pfgid);
zpci_attr(vfn, "0x%04x\n", vfn);
zpci_attr(pft, "0x%02x\n", pft);
zpci_attr(port, "%d\n", port);
zpci_attr(uid, "0x%x\n", uid);
zpci_attr(segment0, "0x%02x\n", pfip[0]);
zpci_attr(segment1, "0x%02x\n", pfip[1]);
zpci_attr(segment2, "0x%02x\n", pfip[2]);
zpci_attr(segment3, "0x%02x\n", pfip[3]);

static ssize_t mio_enabled_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));

	return sprintf(buf, zpci_use_mio(zdev) ? "1\n" : "0\n");
}
static DEVICE_ATTR_RO(mio_enabled);

static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
			     const char *buf, size_t count)
{
	struct kernfs_node *kn;
	struct pci_dev *pdev = to_pci_dev(dev);
	struct zpci_dev *zdev = to_zpci(pdev);
	int ret = 0;

	/* Can't use device_remove_self() here as that would lead us to lock
	 * the pci_rescan_remove_lock while holding the device' kernfs lock.
	 * This would create a possible deadlock with disable_slot() which is
	 * not directly protected by the device' kernfs lock but takes it
	 * during the device removal which happens under
	 * pci_rescan_remove_lock.
	 *
	 * This is analogous to sdev_store_delete() in
	 * drivers/scsi/scsi_sysfs.c
	 */
	kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
	WARN_ON_ONCE(!kn);
	/* device_remove_file() serializes concurrent calls ignoring all but
	 * the first
	 */
	device_remove_file(dev, attr);

	/* A concurrent call to recover_store() may slip between
	 * sysfs_break_active_protection() and the sysfs file removal.
	 * Once it unblocks from pci_lock_rescan_remove() the original pdev
	 * will already be removed.
	 */
	pci_lock_rescan_remove();
	if (pci_dev_is_added(pdev)) {
		pci_stop_and_remove_bus_device(pdev);
		if (zdev->dma_table) {
			ret = zpci_dma_exit_device(zdev);
			if (ret)
				goto out;
		}

		if (zdev_enabled(zdev)) {
			ret = zpci_disable_device(zdev);
			if (ret)
				goto out;
		}

		ret = zpci_enable_device(zdev);
		if (ret)
			goto out;
		ret = zpci_dma_init_device(zdev);
		if (ret) {
			zpci_disable_device(zdev);
			goto out;
		}
		pci_rescan_bus(zdev->zbus->bus);
	}
out:
	pci_unlock_rescan_remove();
	if (kn)
		sysfs_unbreak_active_protection(kn);
	return ret ? ret : count;
}
static DEVICE_ATTR_WO(recover);

static ssize_t util_string_read(struct file *filp, struct kobject *kobj,
				struct bin_attribute *attr, char *buf,
				loff_t off, size_t count)
{
	struct device *dev = kobj_to_dev(kobj);
	struct pci_dev *pdev = to_pci_dev(dev);
	struct zpci_dev *zdev = to_zpci(pdev);

	return memory_read_from_buffer(buf, count, &off, zdev->util_str,
				       sizeof(zdev->util_str));
}
static BIN_ATTR_RO(util_string, CLP_UTIL_STR_LEN);

static ssize_t report_error_write(struct file *filp, struct kobject *kobj,
				  struct bin_attribute *attr, char *buf,
				  loff_t off, size_t count)
{
	struct zpci_report_error_header *report = (void *) buf;
	struct device *dev = kobj_to_dev(kobj);
	struct pci_dev *pdev = to_pci_dev(dev);
	struct zpci_dev *zdev = to_zpci(pdev);
	int ret;

	if (off || (count < sizeof(*report)))
		return -EINVAL;

	ret = sclp_pci_report(report, zdev->fh, zdev->fid);

	return ret ? ret : count;
}
static BIN_ATTR(report_error, S_IWUSR, NULL, report_error_write, PAGE_SIZE);

static ssize_t uid_is_unique_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{
	return sysfs_emit(buf, "%d\n", zpci_unique_uid ? 1 : 0);
}
static DEVICE_ATTR_RO(uid_is_unique);

#ifndef CONFIG_DMI
/* analogous to smbios index */
static ssize_t index_show(struct device *dev,
			  struct device_attribute *attr, char *buf)
{
	struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
	u32 index = ~0;

	if (zpci_unique_uid)
		index = zdev->uid;

	return sysfs_emit(buf, "%u\n", index);
}
static DEVICE_ATTR_RO(index);

static umode_t zpci_index_is_visible(struct kobject *kobj,
				     struct attribute *attr, int n)
{
	return zpci_unique_uid ? attr->mode : 0;
}

static struct attribute *zpci_ident_attrs[] = {
	&dev_attr_index.attr,
	NULL,
};

static struct attribute_group zpci_ident_attr_group = {
	.attrs = zpci_ident_attrs,
	.is_visible = zpci_index_is_visible,
};
#endif

static struct bin_attribute *zpci_bin_attrs[] = {
	&bin_attr_util_string,
	&bin_attr_report_error,
	NULL,
};

static struct attribute *zpci_dev_attrs[] = {
	&dev_attr_function_id.attr,
	&dev_attr_function_handle.attr,
	&dev_attr_pchid.attr,
	&dev_attr_pfgid.attr,
	&dev_attr_pft.attr,
	&dev_attr_port.attr,
	&dev_attr_vfn.attr,
	&dev_attr_uid.attr,
	&dev_attr_recover.attr,
	&dev_attr_mio_enabled.attr,
	&dev_attr_uid_is_unique.attr,
	NULL,
};

static struct attribute_group zpci_attr_group = {
	.attrs = zpci_dev_attrs,
	.bin_attrs = zpci_bin_attrs,
};

static struct attribute *pfip_attrs[] = {
	&dev_attr_segment0.attr,
	&dev_attr_segment1.attr,
	&dev_attr_segment2.attr,
	&dev_attr_segment3.attr,
	NULL,
};
static struct attribute_group pfip_attr_group = {
	.name = "pfip",
	.attrs = pfip_attrs,
};

const struct attribute_group *zpci_attr_groups[] = {
	&zpci_attr_group,
	&pfip_attr_group,
#ifndef CONFIG_DMI
	&zpci_ident_attr_group,
#endif
	NULL,
};
