// 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((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);
