// SPDX-License-Identifier: GPL-2.0
/*
 * SCLP Store Data support and sysfs interface
 *
 * Copyright IBM Corp. 2017
 */

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

#include <linux/completion.h>
#include <linux/kobject.h>
#include <linux/list.h>
#include <linux/printk.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/async.h>
#include <linux/export.h>
#include <linux/mutex.h>

#include <asm/pgalloc.h>

#include "sclp.h"

#define SD_EQ_STORE_DATA	0
#define SD_EQ_HALT		1
#define SD_EQ_SIZE		2

#define SD_DI_CONFIG		3

struct sclp_sd_evbuf {
	struct evbuf_header hdr;
	u8 eq;
	u8 di;
	u8 rflags;
	u64 :56;
	u32 id;
	u16 :16;
	u8 fmt;
	u8 status;
	u64 sat;
	u64 sa;
	u32 esize;
	u32 dsize;
} __packed;

struct sclp_sd_sccb {
	struct sccb_header hdr;
	struct sclp_sd_evbuf evbuf;
} __packed __aligned(PAGE_SIZE);

/**
 * struct sclp_sd_data - Result of a Store Data request
 * @esize_bytes: Resulting esize in bytes
 * @dsize_bytes: Resulting dsize in bytes
 * @data: Pointer to data - must be released using vfree()
 */
struct sclp_sd_data {
	size_t esize_bytes;
	size_t dsize_bytes;
	void *data;
};

/**
 * struct sclp_sd_listener - Listener for asynchronous Store Data response
 * @list: For enqueueing this struct
 * @id: Event ID of response to listen for
 * @completion: Can be used to wait for response
 * @evbuf: Contains the resulting Store Data response after completion
 */
struct sclp_sd_listener {
	struct list_head list;
	u32 id;
	struct completion completion;
	struct sclp_sd_evbuf evbuf;
};

/**
 * struct sclp_sd_file - Sysfs representation of a Store Data entity
 * @kobj: Kobject
 * @data_attr: Attribute for accessing data contents
 * @data_mutex: Mutex to serialize access and updates to @data
 * @data: Data associated with this entity
 * @di: DI value associated with this entity
 */
struct sclp_sd_file {
	struct kobject kobj;
	struct bin_attribute data_attr;
	struct mutex data_mutex;
	struct sclp_sd_data data;
	u8 di;
};
#define to_sd_file(x) container_of(x, struct sclp_sd_file, kobj)

static struct kset *sclp_sd_kset;
static struct sclp_sd_file *config_file;

static LIST_HEAD(sclp_sd_queue);
static DEFINE_SPINLOCK(sclp_sd_queue_lock);

/**
 * sclp_sd_listener_add() - Add listener for Store Data responses
 * @listener: Listener to add
 */
static void sclp_sd_listener_add(struct sclp_sd_listener *listener)
{
	spin_lock_irq(&sclp_sd_queue_lock);
	list_add_tail(&listener->list, &sclp_sd_queue);
	spin_unlock_irq(&sclp_sd_queue_lock);
}

/**
 * sclp_sd_listener_remove() - Remove listener for Store Data responses
 * @listener: Listener to remove
 */
static void sclp_sd_listener_remove(struct sclp_sd_listener *listener)
{
	spin_lock_irq(&sclp_sd_queue_lock);
	list_del(&listener->list);
	spin_unlock_irq(&sclp_sd_queue_lock);
}

/**
 * sclp_sd_listener_init() - Initialize a Store Data response listener
 * @listener: Response listener to initialize
 * @id: Event ID to listen for
 *
 * Initialize a listener for asynchronous Store Data responses. This listener
 * can afterwards be used to wait for a specific response and to retrieve
 * the associated response data.
 */
static void sclp_sd_listener_init(struct sclp_sd_listener *listener, u32 id)
{
	memset(listener, 0, sizeof(*listener));
	listener->id = id;
	init_completion(&listener->completion);
}

/**
 * sclp_sd_receiver() - Receiver for Store Data events
 * @evbuf_hdr: Header of received events
 *
 * Process Store Data events and complete listeners with matching event IDs.
 */
static void sclp_sd_receiver(struct evbuf_header *evbuf_hdr)
{
	struct sclp_sd_evbuf *evbuf = (struct sclp_sd_evbuf *) evbuf_hdr;
	struct sclp_sd_listener *listener;
	int found = 0;

	pr_debug("received event (id=0x%08x)\n", evbuf->id);
	spin_lock(&sclp_sd_queue_lock);
	list_for_each_entry(listener, &sclp_sd_queue, list) {
		if (listener->id != evbuf->id)
			continue;

		listener->evbuf = *evbuf;
		complete(&listener->completion);
		found = 1;
		break;
	}
	spin_unlock(&sclp_sd_queue_lock);

	if (!found)
		pr_debug("unsolicited event (id=0x%08x)\n", evbuf->id);
}

static struct sclp_register sclp_sd_register = {
	.send_mask = EVTYP_STORE_DATA_MASK,
	.receive_mask = EVTYP_STORE_DATA_MASK,
	.receiver_fn = sclp_sd_receiver,
};

/**
 * sclp_sd_sync() - Perform Store Data request synchronously
 * @page: Address of work page - must be below 2GB
 * @eq: Input EQ value
 * @di: Input DI value
 * @sat: Input SAT value
 * @sa: Input SA value used to specify the address of the target buffer
 * @dsize_ptr: Optional pointer to input and output DSIZE value
 * @esize_ptr: Optional pointer to output ESIZE value
 *
 * Perform Store Data request with specified parameters and wait for completion.
 *
 * Return %0 on success and store resulting DSIZE and ESIZE values in
 * @dsize_ptr and @esize_ptr (if provided). Return non-zero on error.
 */
static int sclp_sd_sync(unsigned long page, u8 eq, u8 di, u64 sat, u64 sa,
			u32 *dsize_ptr, u32 *esize_ptr)
{
	struct sclp_sd_sccb *sccb = (void *) page;
	struct sclp_sd_listener listener;
	struct sclp_sd_evbuf *evbuf;
	int rc;

	sclp_sd_listener_init(&listener, __pa(sccb));
	sclp_sd_listener_add(&listener);

	/* Prepare SCCB */
	memset(sccb, 0, PAGE_SIZE);
	sccb->hdr.length = sizeof(sccb->hdr) + sizeof(sccb->evbuf);
	evbuf = &sccb->evbuf;
	evbuf->hdr.length = sizeof(*evbuf);
	evbuf->hdr.type = EVTYP_STORE_DATA;
	evbuf->eq = eq;
	evbuf->di = di;
	evbuf->id = listener.id;
	evbuf->fmt = 1;
	evbuf->sat = sat;
	evbuf->sa = sa;
	if (dsize_ptr)
		evbuf->dsize = *dsize_ptr;

	/* Perform command */
	pr_debug("request (eq=%d, di=%d, id=0x%08x)\n", eq, di, listener.id);
	rc = sclp_sync_request(SCLP_CMDW_WRITE_EVENT_DATA, sccb);
	pr_debug("request done (rc=%d)\n", rc);
	if (rc)
		goto out;

	/* Evaluate response */
	if (sccb->hdr.response_code == 0x73f0) {
		pr_debug("event not supported\n");
		rc = -EIO;
		goto out_remove;
	}
	if (sccb->hdr.response_code != 0x0020 || !(evbuf->hdr.flags & 0x80)) {
		rc = -EIO;
		goto out;
	}
	if (!(evbuf->rflags & 0x80)) {
		rc = wait_for_completion_interruptible(&listener.completion);
		if (rc)
			goto out;
		evbuf = &listener.evbuf;
	}
	switch (evbuf->status) {
	case 0:
		if (dsize_ptr)
			*dsize_ptr = evbuf->dsize;
		if (esize_ptr)
			*esize_ptr = evbuf->esize;
		pr_debug("success (dsize=%u, esize=%u)\n", evbuf->dsize,
			 evbuf->esize);
		break;
	case 3:
		rc = -ENOENT;
		break;
	default:
		rc = -EIO;
		break;

	}

out:
	if (rc && rc != -ENOENT) {
		/* Provide some information about what went wrong */
		pr_warn("Store Data request failed (eq=%d, di=%d, "
			"response=0x%04x, flags=0x%02x, status=%d, rc=%d)\n",
			eq, di, sccb->hdr.response_code, evbuf->hdr.flags,
			evbuf->status, rc);
	}

out_remove:
	sclp_sd_listener_remove(&listener);

	return rc;
}

/**
 * sclp_sd_store_data() - Obtain data for specified Store Data entity
 * @result: Resulting data
 * @di: DI value associated with this entity
 *
 * Perform a series of Store Data requests to obtain the size and contents of
 * the specified Store Data entity.
 *
 * Return:
 *   %0:       Success - result is stored in @result. @result->data must be
 *	       released using vfree() after use.
 *   %-ENOENT: No data available for this entity
 *   %<0:      Other error
 */
static int sclp_sd_store_data(struct sclp_sd_data *result, u8 di)
{
	u32 dsize = 0, esize = 0;
	unsigned long page, asce = 0;
	void *data = NULL;
	int rc;

	page = __get_free_page(GFP_KERNEL | GFP_DMA);
	if (!page)
		return -ENOMEM;

	/* Get size */
	rc = sclp_sd_sync(page, SD_EQ_SIZE, di, 0, 0, &dsize, &esize);
	if (rc)
		goto out;
	if (dsize == 0)
		goto out_result;

	/* Allocate memory */
	data = vzalloc(array_size((size_t)dsize, PAGE_SIZE));
	if (!data) {
		rc = -ENOMEM;
		goto out;
	}

	/* Get translation table for buffer */
	asce = base_asce_alloc((unsigned long) data, dsize);
	if (!asce) {
		vfree(data);
		rc = -ENOMEM;
		goto out;
	}

	/* Get data */
	rc = sclp_sd_sync(page, SD_EQ_STORE_DATA, di, asce, (u64) data, &dsize,
			  &esize);
	if (rc) {
		/* Cancel running request if interrupted */
		if (rc == -ERESTARTSYS)
			sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL);
		vfree(data);
		goto out;
	}

out_result:
	result->esize_bytes = (size_t) esize * PAGE_SIZE;
	result->dsize_bytes = (size_t) dsize * PAGE_SIZE;
	result->data = data;

out:
	base_asce_free(asce);
	free_page(page);

	return rc;
}

/**
 * sclp_sd_data_reset() - Reset Store Data result buffer
 * @data: Data buffer to reset
 *
 * Reset @data to initial state and release associated memory.
 */
static void sclp_sd_data_reset(struct sclp_sd_data *data)
{
	vfree(data->data);
	data->data = NULL;
	data->dsize_bytes = 0;
	data->esize_bytes = 0;
}

/**
 * sclp_sd_file_release() - Release function for sclp_sd_file object
 * @kobj: Kobject embedded in sclp_sd_file object
 */
static void sclp_sd_file_release(struct kobject *kobj)
{
	struct sclp_sd_file *sd_file = to_sd_file(kobj);

	sclp_sd_data_reset(&sd_file->data);
	kfree(sd_file);
}

/**
 * sclp_sd_file_update() - Update contents of sclp_sd_file object
 * @sd_file: Object to update
 *
 * Obtain the current version of data associated with the Store Data entity
 * @sd_file.
 *
 * On success, return %0 and generate a KOBJ_CHANGE event to indicate that the
 * data may have changed. Return non-zero otherwise.
 */
static int sclp_sd_file_update(struct sclp_sd_file *sd_file)
{
	const char *name = kobject_name(&sd_file->kobj);
	struct sclp_sd_data data;
	int rc;

	rc = sclp_sd_store_data(&data, sd_file->di);
	if (rc) {
		if (rc == -ENOENT) {
			pr_info("No data is available for the %s data entity\n",
				 name);
		}
		return rc;
	}

	mutex_lock(&sd_file->data_mutex);
	sclp_sd_data_reset(&sd_file->data);
	sd_file->data = data;
	mutex_unlock(&sd_file->data_mutex);

	pr_info("A %zu-byte %s data entity was retrieved\n", data.dsize_bytes,
		name);
	kobject_uevent(&sd_file->kobj, KOBJ_CHANGE);

	return 0;
}

/**
 * sclp_sd_file_update_async() - Wrapper for asynchronous update call
 * @data: Object to update
 * @cookie: Unused
 */
static void sclp_sd_file_update_async(void *data, async_cookie_t cookie)
{
	struct sclp_sd_file *sd_file = data;

	sclp_sd_file_update(sd_file);
}

/**
 * reload_store() - Store function for "reload" sysfs attribute
 * @kobj: Kobject of sclp_sd_file object
 * @attr: Reload attribute
 * @buf: Data written to sysfs attribute
 * @count: Count of bytes written
 *
 * Initiate a reload of the data associated with an sclp_sd_file object.
 */
static ssize_t reload_store(struct kobject *kobj, struct kobj_attribute *attr,
			    const char *buf, size_t count)
{
	struct sclp_sd_file *sd_file = to_sd_file(kobj);

	sclp_sd_file_update(sd_file);

	return count;
}

static struct kobj_attribute reload_attr = __ATTR_WO(reload);

static struct attribute *sclp_sd_file_default_attrs[] = {
	&reload_attr.attr,
	NULL,
};

static struct kobj_type sclp_sd_file_ktype = {
	.sysfs_ops = &kobj_sysfs_ops,
	.release = sclp_sd_file_release,
	.default_attrs = sclp_sd_file_default_attrs,
};

/**
 * data_read() - Read function for "data" sysfs attribute
 * @file: Open file pointer
 * @kobj: Kobject of sclp_sd_file object
 * @attr: Data attribute
 * @buffer: Target buffer
 * @off: Requested file offset
 * @size: Requested number of bytes
 *
 * Store the requested portion of the Store Data entity contents into the
 * specified buffer. Return the number of bytes stored on success, or %0
 * on EOF.
 */
static ssize_t data_read(struct file *file, struct kobject *kobj,
			 struct bin_attribute *attr, char *buffer,
			 loff_t off, size_t size)
{
	struct sclp_sd_file *sd_file = to_sd_file(kobj);
	size_t data_size;
	char *data;

	mutex_lock(&sd_file->data_mutex);

	data = sd_file->data.data;
	data_size = sd_file->data.dsize_bytes;
	if (!data || off >= data_size) {
		size = 0;
	} else {
		if (off + size > data_size)
			size = data_size - off;
		memcpy(buffer, data + off, size);
	}

	mutex_unlock(&sd_file->data_mutex);

	return size;
}

/**
 * sclp_sd_file_create() - Add a sysfs file representing a Store Data entity
 * @name: Name of file
 * @di: DI value associated with this entity
 *
 * Create a sysfs directory with the given @name located under
 *
 *   /sys/firmware/sclp_sd/
 *
 * The files in this directory can be used to access the contents of the Store
 * Data entity associated with @DI.
 *
 * Return pointer to resulting sclp_sd_file object on success, %NULL otherwise.
 * The object must be freed by calling kobject_put() on the embedded kobject
 * pointer after use.
 */
static __init struct sclp_sd_file *sclp_sd_file_create(const char *name, u8 di)
{
	struct sclp_sd_file *sd_file;
	int rc;

	sd_file = kzalloc(sizeof(*sd_file), GFP_KERNEL);
	if (!sd_file)
		return NULL;
	sd_file->di = di;
	mutex_init(&sd_file->data_mutex);

	/* Create kobject located under /sys/firmware/sclp_sd/ */
	sd_file->kobj.kset = sclp_sd_kset;
	rc = kobject_init_and_add(&sd_file->kobj, &sclp_sd_file_ktype, NULL,
				  "%s", name);
	if (rc) {
		kobject_put(&sd_file->kobj);
		return NULL;
	}

	sysfs_bin_attr_init(&sd_file->data_attr);
	sd_file->data_attr.attr.name = "data";
	sd_file->data_attr.attr.mode = 0444;
	sd_file->data_attr.read = data_read;

	rc = sysfs_create_bin_file(&sd_file->kobj, &sd_file->data_attr);
	if (rc) {
		kobject_put(&sd_file->kobj);
		return NULL;
	}

	/*
	 * For completeness only - users interested in entity data should listen
	 * for KOBJ_CHANGE instead.
	 */
	kobject_uevent(&sd_file->kobj, KOBJ_ADD);

	/* Don't let a slow Store Data request delay further initialization */
	async_schedule(sclp_sd_file_update_async, sd_file);

	return sd_file;
}

/**
 * sclp_sd_init() - Initialize sclp_sd support and register sysfs files
 */
static __init int sclp_sd_init(void)
{
	int rc;

	rc = sclp_register(&sclp_sd_register);
	if (rc)
		return rc;

	/* Create kset named "sclp_sd" located under /sys/firmware/ */
	rc = -ENOMEM;
	sclp_sd_kset = kset_create_and_add("sclp_sd", NULL, firmware_kobj);
	if (!sclp_sd_kset)
		goto err_kset;

	rc = -EINVAL;
	config_file = sclp_sd_file_create("config", SD_DI_CONFIG);
	if (!config_file)
		goto err_config;

	return 0;

err_config:
	kset_unregister(sclp_sd_kset);
err_kset:
	sclp_unregister(&sclp_sd_register);

	return rc;
}
device_initcall(sclp_sd_init);
