// 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
 * @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, (u32) (addr_t) 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
 */
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
 *
 * 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 "read" sysfs attribute
 * @kobj: Kobject of sclp_sd_file object
 * @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);
