// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2018 Google, Inc. */
#include "gasket_sysfs.h"

#include "gasket_core.h"

#include <linux/device.h>
#include <linux/printk.h>

/*
 * Pair of kernel device and user-specified pointer. Used in lookups in sysfs
 * "show" functions to return user data.
 */

struct gasket_sysfs_mapping {
	/*
	 * The device bound to this mapping. If this is NULL, then this mapping
	 * is free.
	 */
	struct device *device;

	/* The Gasket descriptor for this device. */
	struct gasket_dev *gasket_dev;

	/* This device's set of sysfs attributes/nodes. */
	struct gasket_sysfs_attribute *attributes;

	/* The number of live elements in "attributes". */
	int attribute_count;

	/* Protects structure from simultaneous access. */
	struct mutex mutex;

	/* Tracks active users of this mapping. */
	struct kref refcount;
};

/*
 * Data needed to manage users of this sysfs utility.
 * Currently has a fixed size; if space is a concern, this can be dynamically
 * allocated.
 */
/*
 * 'Global' (file-scoped) list of mappings between devices and gasket_data
 * pointers. This removes the requirement to have a gasket_sysfs_data
 * handle in all files.
 */
static struct gasket_sysfs_mapping dev_mappings[GASKET_SYSFS_NUM_MAPPINGS];

/* Callback when a mapping's refcount goes to zero. */
static void release_entry(struct kref *ref)
{
	/* All work is done after the return from kref_put. */
}

/* Look up mapping information for the given device. */
static struct gasket_sysfs_mapping *get_mapping(struct device *device)
{
	int i;

	for (i = 0; i < GASKET_SYSFS_NUM_MAPPINGS; i++) {
		mutex_lock(&dev_mappings[i].mutex);
		if (dev_mappings[i].device == device) {
			kref_get(&dev_mappings[i].refcount);
			mutex_unlock(&dev_mappings[i].mutex);
			return &dev_mappings[i];
		}
		mutex_unlock(&dev_mappings[i].mutex);
	}

	dev_dbg(device, "%s: Mapping to device %s not found\n",
		__func__, device->kobj.name);
	return NULL;
}

/* Put a reference to a mapping. */
static void put_mapping(struct gasket_sysfs_mapping *mapping)
{
	int i;
	int num_files_to_remove = 0;
	struct device_attribute *files_to_remove;
	struct device *device;

	if (!mapping) {
		pr_debug("%s: Mapping should not be NULL\n", __func__);
		return;
	}

	mutex_lock(&mapping->mutex);
	if (kref_put(&mapping->refcount, release_entry)) {
		dev_dbg(mapping->device, "Removing Gasket sysfs mapping\n");
		/*
		 * We can't remove the sysfs nodes in the kref callback, since
		 * device_remove_file() blocks until the node is free.
		 * Readers/writers of sysfs nodes, though, will be blocked on
		 * the mapping mutex, resulting in deadlock. To fix this, the
		 * sysfs nodes are removed outside the lock.
		 */
		device = mapping->device;
		num_files_to_remove = mapping->attribute_count;
		files_to_remove = kcalloc(num_files_to_remove,
					  sizeof(*files_to_remove),
					  GFP_KERNEL);
		if (files_to_remove)
			for (i = 0; i < num_files_to_remove; i++)
				files_to_remove[i] =
				    mapping->attributes[i].attr;
		else
			num_files_to_remove = 0;

		kfree(mapping->attributes);
		mapping->attributes = NULL;
		mapping->attribute_count = 0;
		put_device(mapping->device);
		mapping->device = NULL;
		mapping->gasket_dev = NULL;
	}
	mutex_unlock(&mapping->mutex);

	if (num_files_to_remove != 0) {
		for (i = 0; i < num_files_to_remove; ++i)
			device_remove_file(device, &files_to_remove[i]);
		kfree(files_to_remove);
	}
}

/*
 * Put a reference to a mapping N times.
 *
 * In higher-level resource acquire/release function pairs, the release function
 * will need to release a mapping 2x - once for the refcount taken in the
 * release function itself, and once for the count taken in the acquire call.
 */
static void put_mapping_n(struct gasket_sysfs_mapping *mapping, int times)
{
	int i;

	for (i = 0; i < times; i++)
		put_mapping(mapping);
}

void gasket_sysfs_init(void)
{
	int i;

	for (i = 0; i < GASKET_SYSFS_NUM_MAPPINGS; i++) {
		dev_mappings[i].device = NULL;
		mutex_init(&dev_mappings[i].mutex);
	}
}

int gasket_sysfs_create_mapping(struct device *device,
				struct gasket_dev *gasket_dev)
{
	struct gasket_sysfs_mapping *mapping;
	int map_idx = -1;

	/*
	 * We need a function-level mutex to protect against the same device
	 * being added [multiple times] simultaneously.
	 */
	static DEFINE_MUTEX(function_mutex);

	mutex_lock(&function_mutex);
	dev_dbg(device, "Creating sysfs entries for device\n");

	/* Check that the device we're adding hasn't already been added. */
	mapping = get_mapping(device);
	if (mapping) {
		dev_err(device,
			"Attempting to re-initialize sysfs mapping for device\n");
		put_mapping(mapping);
		mutex_unlock(&function_mutex);
		return -EBUSY;
	}

	/* Find the first empty entry in the array. */
	for (map_idx = 0; map_idx < GASKET_SYSFS_NUM_MAPPINGS; ++map_idx) {
		mutex_lock(&dev_mappings[map_idx].mutex);
		if (!dev_mappings[map_idx].device)
			/* Break with the mutex held! */
			break;
		mutex_unlock(&dev_mappings[map_idx].mutex);
	}

	if (map_idx == GASKET_SYSFS_NUM_MAPPINGS) {
		dev_err(device, "All mappings have been exhausted\n");
		mutex_unlock(&function_mutex);
		return -ENOMEM;
	}

	dev_dbg(device, "Creating sysfs mapping for device %s\n",
		device->kobj.name);

	mapping = &dev_mappings[map_idx];
	mapping->attributes = kcalloc(GASKET_SYSFS_MAX_NODES,
				      sizeof(*mapping->attributes),
				      GFP_KERNEL);
	if (!mapping->attributes) {
		dev_dbg(device, "Unable to allocate sysfs attribute array\n");
		mutex_unlock(&mapping->mutex);
		mutex_unlock(&function_mutex);
		return -ENOMEM;
	}

	kref_init(&mapping->refcount);
	mapping->device = get_device(device);
	mapping->gasket_dev = gasket_dev;
	mapping->attribute_count = 0;
	mutex_unlock(&mapping->mutex);
	mutex_unlock(&function_mutex);

	/* Don't decrement the refcount here! One open count keeps it alive! */
	return 0;
}

int gasket_sysfs_create_entries(struct device *device,
				const struct gasket_sysfs_attribute *attrs)
{
	int i;
	int ret;
	struct gasket_sysfs_mapping *mapping = get_mapping(device);

	if (!mapping) {
		dev_dbg(device,
			"Creating entries for device without first "
			"initializing mapping\n");
		return -EINVAL;
	}

	mutex_lock(&mapping->mutex);
	for (i = 0; strcmp(attrs[i].attr.attr.name, GASKET_ARRAY_END_MARKER);
		i++) {
		if (mapping->attribute_count == GASKET_SYSFS_MAX_NODES) {
			dev_err(device,
				"Maximum number of sysfs nodes reached for "
				"device\n");
			mutex_unlock(&mapping->mutex);
			put_mapping(mapping);
			return -ENOMEM;
		}

		ret = device_create_file(device, &attrs[i].attr);
		if (ret) {
			dev_dbg(device, "Unable to create device entries\n");
			mutex_unlock(&mapping->mutex);
			put_mapping(mapping);
			return ret;
		}

		mapping->attributes[mapping->attribute_count] = attrs[i];
		++mapping->attribute_count;
	}

	mutex_unlock(&mapping->mutex);
	put_mapping(mapping);
	return 0;
}
EXPORT_SYMBOL(gasket_sysfs_create_entries);

void gasket_sysfs_remove_mapping(struct device *device)
{
	struct gasket_sysfs_mapping *mapping = get_mapping(device);

	if (!mapping) {
		dev_err(device,
			"Attempted to remove non-existent sysfs mapping to "
			"device\n");
		return;
	}

	put_mapping_n(mapping, 2);
}

struct gasket_dev *gasket_sysfs_get_device_data(struct device *device)
{
	struct gasket_sysfs_mapping *mapping = get_mapping(device);

	if (!mapping) {
		dev_err(device, "device not registered\n");
		return NULL;
	}

	return mapping->gasket_dev;
}
EXPORT_SYMBOL(gasket_sysfs_get_device_data);

void gasket_sysfs_put_device_data(struct device *device, struct gasket_dev *dev)
{
	struct gasket_sysfs_mapping *mapping = get_mapping(device);

	if (!mapping)
		return;

	/* See comment of put_mapping_n() for why the '2' is necessary. */
	put_mapping_n(mapping, 2);
}
EXPORT_SYMBOL(gasket_sysfs_put_device_data);

struct gasket_sysfs_attribute *
gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr)
{
	int i;
	int num_attrs;
	struct gasket_sysfs_mapping *mapping = get_mapping(device);
	struct gasket_sysfs_attribute *attrs = NULL;

	if (!mapping)
		return NULL;

	attrs = mapping->attributes;
	num_attrs = mapping->attribute_count;
	for (i = 0; i < num_attrs; ++i) {
		if (!strcmp(attrs[i].attr.attr.name, attr->attr.name))
			return &attrs[i];
	}

	dev_err(device, "Unable to find match for device_attribute %s\n",
		attr->attr.name);
	return NULL;
}
EXPORT_SYMBOL(gasket_sysfs_get_attr);

void gasket_sysfs_put_attr(struct device *device,
			   struct gasket_sysfs_attribute *attr)
{
	int i;
	int num_attrs;
	struct gasket_sysfs_mapping *mapping = get_mapping(device);
	struct gasket_sysfs_attribute *attrs = NULL;

	if (!mapping)
		return;

	attrs = mapping->attributes;
	num_attrs = mapping->attribute_count;
	for (i = 0; i < num_attrs; ++i) {
		if (&attrs[i] == attr) {
			put_mapping_n(mapping, 2);
			return;
		}
	}

	dev_err(device, "Unable to put unknown attribute: %s\n",
		attr->attr.attr.name);
}
EXPORT_SYMBOL(gasket_sysfs_put_attr);

ssize_t gasket_sysfs_register_store(struct device *device,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	ulong parsed_value = 0;
	struct gasket_sysfs_mapping *mapping;
	struct gasket_dev *gasket_dev;
	struct gasket_sysfs_attribute *gasket_attr;

	if (count < 3 || buf[0] != '0' || buf[1] != 'x') {
		dev_err(device,
			"sysfs register write format: \"0x<hex value>\"\n");
		return -EINVAL;
	}

	if (kstrtoul(buf, 16, &parsed_value) != 0) {
		dev_err(device,
			"Unable to parse input as 64-bit hex value: %s\n", buf);
		return -EINVAL;
	}

	mapping = get_mapping(device);
	if (!mapping) {
		dev_err(device, "Device driver may have been removed\n");
		return 0;
	}

	gasket_dev = mapping->gasket_dev;
	if (!gasket_dev) {
		dev_err(device, "Device driver may have been removed\n");
		return 0;
	}

	gasket_attr = gasket_sysfs_get_attr(device, attr);
	if (!gasket_attr) {
		put_mapping(mapping);
		return count;
	}

	gasket_dev_write_64(gasket_dev, parsed_value,
			    gasket_attr->data.bar_address.bar,
			    gasket_attr->data.bar_address.offset);

	if (gasket_attr->write_callback)
		gasket_attr->write_callback(gasket_dev, gasket_attr,
					    parsed_value);

	gasket_sysfs_put_attr(device, gasket_attr);
	put_mapping(mapping);
	return count;
}
EXPORT_SYMBOL(gasket_sysfs_register_store);
