// SPDX-License-Identifier: GPL-2.0+
/*
 * Provides user-space access to the SSAM EC via the /dev/surface/aggregator
 * misc device. Intended for debugging and development.
 *
 * Copyright (C) 2020-2022 Maximilian Luz <luzmaximilian@gmail.com>
 */

#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/kernel.h>
#include <linux/kfifo.h>
#include <linux/kref.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/rwsem.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>

#include <linux/surface_aggregator/cdev.h>
#include <linux/surface_aggregator/controller.h>
#include <linux/surface_aggregator/serial_hub.h>

#define SSAM_CDEV_DEVICE_NAME	"surface_aggregator_cdev"


/* -- Main structures. ------------------------------------------------------ */

enum ssam_cdev_device_state {
	SSAM_CDEV_DEVICE_SHUTDOWN_BIT = BIT(0),
};

struct ssam_cdev {
	struct kref kref;
	struct rw_semaphore lock;

	struct device *dev;
	struct ssam_controller *ctrl;
	struct miscdevice mdev;
	unsigned long flags;

	struct rw_semaphore client_lock;  /* Guards client list. */
	struct list_head client_list;
};

struct ssam_cdev_client;

struct ssam_cdev_notifier {
	struct ssam_cdev_client *client;
	struct ssam_event_notifier nf;
};

struct ssam_cdev_client {
	struct ssam_cdev *cdev;
	struct list_head node;

	struct mutex notifier_lock;	/* Guards notifier access for registration */
	struct ssam_cdev_notifier *notifier[SSH_NUM_EVENTS];

	struct mutex read_lock;		/* Guards FIFO buffer read access */
	struct mutex write_lock;	/* Guards FIFO buffer write access */
	DECLARE_KFIFO(buffer, u8, 4096);

	wait_queue_head_t waitq;
	struct fasync_struct *fasync;
};

static void __ssam_cdev_release(struct kref *kref)
{
	kfree(container_of(kref, struct ssam_cdev, kref));
}

static struct ssam_cdev *ssam_cdev_get(struct ssam_cdev *cdev)
{
	if (cdev)
		kref_get(&cdev->kref);

	return cdev;
}

static void ssam_cdev_put(struct ssam_cdev *cdev)
{
	if (cdev)
		kref_put(&cdev->kref, __ssam_cdev_release);
}


/* -- Notifier handling. ---------------------------------------------------- */

static u32 ssam_cdev_notifier(struct ssam_event_notifier *nf, const struct ssam_event *in)
{
	struct ssam_cdev_notifier *cdev_nf = container_of(nf, struct ssam_cdev_notifier, nf);
	struct ssam_cdev_client *client = cdev_nf->client;
	struct ssam_cdev_event event;
	size_t n = struct_size(&event, data, in->length);

	/* Translate event. */
	event.target_category = in->target_category;
	event.target_id = in->target_id;
	event.command_id = in->command_id;
	event.instance_id = in->instance_id;
	event.length = in->length;

	mutex_lock(&client->write_lock);

	/* Make sure we have enough space. */
	if (kfifo_avail(&client->buffer) < n) {
		dev_warn(client->cdev->dev,
			 "buffer full, dropping event (tc: %#04x, tid: %#04x, cid: %#04x, iid: %#04x)\n",
			 in->target_category, in->target_id, in->command_id, in->instance_id);
		mutex_unlock(&client->write_lock);
		return 0;
	}

	/* Copy event header and payload. */
	kfifo_in(&client->buffer, (const u8 *)&event, struct_size(&event, data, 0));
	kfifo_in(&client->buffer, &in->data[0], in->length);

	mutex_unlock(&client->write_lock);

	/* Notify waiting readers. */
	kill_fasync(&client->fasync, SIGIO, POLL_IN);
	wake_up_interruptible(&client->waitq);

	/*
	 * Don't mark events as handled, this is the job of a proper driver and
	 * not the debugging interface.
	 */
	return 0;
}

static int ssam_cdev_notifier_register(struct ssam_cdev_client *client, u8 tc, int priority)
{
	const u16 rqid = ssh_tc_to_rqid(tc);
	const u16 event = ssh_rqid_to_event(rqid);
	struct ssam_cdev_notifier *nf;
	int status;

	lockdep_assert_held_read(&client->cdev->lock);

	/* Validate notifier target category. */
	if (!ssh_rqid_is_event(rqid))
		return -EINVAL;

	mutex_lock(&client->notifier_lock);

	/* Check if the notifier has already been registered. */
	if (client->notifier[event]) {
		mutex_unlock(&client->notifier_lock);
		return -EEXIST;
	}

	/* Allocate new notifier. */
	nf = kzalloc_obj(*nf);
	if (!nf) {
		mutex_unlock(&client->notifier_lock);
		return -ENOMEM;
	}

	/*
	 * Create a dummy notifier with the minimal required fields for
	 * observer registration. Note that we can skip fully specifying event
	 * and registry here as we do not need any matching and use silent
	 * registration, which does not enable the corresponding event.
	 */
	nf->client = client;
	nf->nf.base.fn = ssam_cdev_notifier;
	nf->nf.base.priority = priority;
	nf->nf.event.id.target_category = tc;
	nf->nf.event.mask = 0;	/* Do not do any matching. */
	nf->nf.flags = SSAM_EVENT_NOTIFIER_OBSERVER;

	/* Register notifier. */
	status = ssam_notifier_register(client->cdev->ctrl, &nf->nf);
	if (status)
		kfree(nf);
	else
		client->notifier[event] = nf;

	mutex_unlock(&client->notifier_lock);
	return status;
}

static int ssam_cdev_notifier_unregister(struct ssam_cdev_client *client, u8 tc)
{
	const u16 rqid = ssh_tc_to_rqid(tc);
	const u16 event = ssh_rqid_to_event(rqid);
	int status;

	lockdep_assert_held_read(&client->cdev->lock);

	/* Validate notifier target category. */
	if (!ssh_rqid_is_event(rqid))
		return -EINVAL;

	mutex_lock(&client->notifier_lock);

	/* Check if the notifier is currently registered. */
	if (!client->notifier[event]) {
		mutex_unlock(&client->notifier_lock);
		return -ENOENT;
	}

	/* Unregister and free notifier. */
	status = ssam_notifier_unregister(client->cdev->ctrl, &client->notifier[event]->nf);
	kfree(client->notifier[event]);
	client->notifier[event] = NULL;

	mutex_unlock(&client->notifier_lock);
	return status;
}

static void ssam_cdev_notifier_unregister_all(struct ssam_cdev_client *client)
{
	int i;

	down_read(&client->cdev->lock);

	/*
	 * This function may be used during shutdown, thus we need to test for
	 * cdev->ctrl instead of the SSAM_CDEV_DEVICE_SHUTDOWN_BIT bit.
	 */
	if (client->cdev->ctrl) {
		for (i = 0; i < SSH_NUM_EVENTS; i++)
			ssam_cdev_notifier_unregister(client, i + 1);

	} else {
		int count = 0;

		/*
		 * Device has been shut down. Any notifier remaining is a bug,
		 * so warn about that as this would otherwise hardly be
		 * noticeable. Nevertheless, free them as well.
		 */
		mutex_lock(&client->notifier_lock);
		for (i = 0; i < SSH_NUM_EVENTS; i++) {
			count += !!(client->notifier[i]);
			kfree(client->notifier[i]);
			client->notifier[i] = NULL;
		}
		mutex_unlock(&client->notifier_lock);

		WARN_ON(count > 0);
	}

	up_read(&client->cdev->lock);
}


/* -- IOCTL functions. ------------------------------------------------------ */

static long ssam_cdev_request(struct ssam_cdev_client *client, struct ssam_cdev_request __user *r)
{
	struct ssam_cdev_request rqst;
	struct ssam_request spec = {};
	struct ssam_response rsp = {};
	const void __user *plddata;
	void __user *rspdata;
	int status = 0, ret = 0, tmp;

	lockdep_assert_held_read(&client->cdev->lock);

	ret = copy_struct_from_user(&rqst, sizeof(rqst), r, sizeof(*r));
	if (ret)
		goto out;

	plddata = u64_to_user_ptr(rqst.payload.data);
	rspdata = u64_to_user_ptr(rqst.response.data);

	/* Setup basic request fields. */
	spec.target_category = rqst.target_category;
	spec.target_id = rqst.target_id;
	spec.command_id = rqst.command_id;
	spec.instance_id = rqst.instance_id;
	spec.flags = 0;
	spec.length = rqst.payload.length;
	spec.payload = NULL;

	if (rqst.flags & SSAM_CDEV_REQUEST_HAS_RESPONSE)
		spec.flags |= SSAM_REQUEST_HAS_RESPONSE;

	if (rqst.flags & SSAM_CDEV_REQUEST_UNSEQUENCED)
		spec.flags |= SSAM_REQUEST_UNSEQUENCED;

	rsp.capacity = rqst.response.length;
	rsp.length = 0;
	rsp.pointer = NULL;

	/* Get request payload from user-space. */
	if (spec.length) {
		if (!plddata) {
			ret = -EINVAL;
			goto out;
		}

		/*
		 * Note: spec.length is limited to U16_MAX bytes via struct
		 * ssam_cdev_request. This is slightly larger than the
		 * theoretical maximum (SSH_COMMAND_MAX_PAYLOAD_SIZE) of the
		 * underlying protocol (note that nothing remotely this size
		 * should ever be allocated in any normal case). This size is
		 * validated later in ssam_request_do_sync(), for allocation
		 * the bound imposed by u16 should be enough.
		 */
		spec.payload = kzalloc(spec.length, GFP_KERNEL);
		if (!spec.payload) {
			ret = -ENOMEM;
			goto out;
		}

		if (copy_from_user((void *)spec.payload, plddata, spec.length)) {
			ret = -EFAULT;
			goto out;
		}
	}

	/* Allocate response buffer. */
	if (rsp.capacity) {
		if (!rspdata) {
			ret = -EINVAL;
			goto out;
		}

		/*
		 * Note: rsp.capacity is limited to U16_MAX bytes via struct
		 * ssam_cdev_request. This is slightly larger than the
		 * theoretical maximum (SSH_COMMAND_MAX_PAYLOAD_SIZE) of the
		 * underlying protocol (note that nothing remotely this size
		 * should ever be allocated in any normal case). In later use,
		 * this capacity does not have to be strictly bounded, as it
		 * is only used as an output buffer to be written to. For
		 * allocation the bound imposed by u16 should be enough.
		 */
		rsp.pointer = kzalloc(rsp.capacity, GFP_KERNEL);
		if (!rsp.pointer) {
			ret = -ENOMEM;
			goto out;
		}
	}

	/* Perform request. */
	status = ssam_request_do_sync(client->cdev->ctrl, &spec, &rsp);
	if (status)
		goto out;

	/* Copy response to user-space. */
	if (rsp.length && copy_to_user(rspdata, rsp.pointer, rsp.length))
		ret = -EFAULT;

out:
	/* Always try to set response-length and status. */
	tmp = put_user(rsp.length, &r->response.length);
	if (tmp)
		ret = tmp;

	tmp = put_user(status, &r->status);
	if (tmp)
		ret = tmp;

	/* Cleanup. */
	kfree(spec.payload);
	kfree(rsp.pointer);

	return ret;
}

static long ssam_cdev_notif_register(struct ssam_cdev_client *client,
				     const struct ssam_cdev_notifier_desc __user *d)
{
	struct ssam_cdev_notifier_desc desc;
	long ret;

	lockdep_assert_held_read(&client->cdev->lock);

	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
	if (ret)
		return ret;

	return ssam_cdev_notifier_register(client, desc.target_category, desc.priority);
}

static long ssam_cdev_notif_unregister(struct ssam_cdev_client *client,
				       const struct ssam_cdev_notifier_desc __user *d)
{
	struct ssam_cdev_notifier_desc desc;
	long ret;

	lockdep_assert_held_read(&client->cdev->lock);

	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
	if (ret)
		return ret;

	return ssam_cdev_notifier_unregister(client, desc.target_category);
}

static long ssam_cdev_event_enable(struct ssam_cdev_client *client,
				   const struct ssam_cdev_event_desc __user *d)
{
	struct ssam_cdev_event_desc desc;
	struct ssam_event_registry reg;
	struct ssam_event_id id;
	long ret;

	lockdep_assert_held_read(&client->cdev->lock);

	/* Read descriptor from user-space. */
	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
	if (ret)
		return ret;

	/* Translate descriptor. */
	reg.target_category = desc.reg.target_category;
	reg.target_id = desc.reg.target_id;
	reg.cid_enable = desc.reg.cid_enable;
	reg.cid_disable = desc.reg.cid_disable;

	id.target_category = desc.id.target_category;
	id.instance = desc.id.instance;

	/* Disable event. */
	return ssam_controller_event_enable(client->cdev->ctrl, reg, id, desc.flags);
}

static long ssam_cdev_event_disable(struct ssam_cdev_client *client,
				    const struct ssam_cdev_event_desc __user *d)
{
	struct ssam_cdev_event_desc desc;
	struct ssam_event_registry reg;
	struct ssam_event_id id;
	long ret;

	lockdep_assert_held_read(&client->cdev->lock);

	/* Read descriptor from user-space. */
	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
	if (ret)
		return ret;

	/* Translate descriptor. */
	reg.target_category = desc.reg.target_category;
	reg.target_id = desc.reg.target_id;
	reg.cid_enable = desc.reg.cid_enable;
	reg.cid_disable = desc.reg.cid_disable;

	id.target_category = desc.id.target_category;
	id.instance = desc.id.instance;

	/* Disable event. */
	return ssam_controller_event_disable(client->cdev->ctrl, reg, id, desc.flags);
}


/* -- File operations. ------------------------------------------------------ */

static int ssam_cdev_device_open(struct inode *inode, struct file *filp)
{
	struct miscdevice *mdev = filp->private_data;
	struct ssam_cdev_client *client;
	struct ssam_cdev *cdev = container_of(mdev, struct ssam_cdev, mdev);

	/* Initialize client */
	client = vzalloc(sizeof(*client));
	if (!client)
		return -ENOMEM;

	client->cdev = ssam_cdev_get(cdev);

	INIT_LIST_HEAD(&client->node);

	mutex_init(&client->notifier_lock);

	mutex_init(&client->read_lock);
	mutex_init(&client->write_lock);
	INIT_KFIFO(client->buffer);
	init_waitqueue_head(&client->waitq);

	filp->private_data = client;

	/* Attach client. */
	down_write(&cdev->client_lock);

	if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags)) {
		up_write(&cdev->client_lock);
		mutex_destroy(&client->write_lock);
		mutex_destroy(&client->read_lock);
		mutex_destroy(&client->notifier_lock);
		ssam_cdev_put(client->cdev);
		vfree(client);
		return -ENODEV;
	}
	list_add_tail(&client->node, &cdev->client_list);

	up_write(&cdev->client_lock);

	stream_open(inode, filp);
	return 0;
}

static int ssam_cdev_device_release(struct inode *inode, struct file *filp)
{
	struct ssam_cdev_client *client = filp->private_data;

	/* Force-unregister all remaining notifiers of this client. */
	ssam_cdev_notifier_unregister_all(client);

	/* Detach client. */
	down_write(&client->cdev->client_lock);
	list_del(&client->node);
	up_write(&client->cdev->client_lock);

	/* Free client. */
	mutex_destroy(&client->write_lock);
	mutex_destroy(&client->read_lock);

	mutex_destroy(&client->notifier_lock);

	ssam_cdev_put(client->cdev);
	vfree(client);

	return 0;
}

static long __ssam_cdev_device_ioctl(struct ssam_cdev_client *client, unsigned int cmd,
				     unsigned long arg)
{
	lockdep_assert_held_read(&client->cdev->lock);

	switch (cmd) {
	case SSAM_CDEV_REQUEST:
		return ssam_cdev_request(client, (struct ssam_cdev_request __user *)arg);

	case SSAM_CDEV_NOTIF_REGISTER:
		return ssam_cdev_notif_register(client,
						(struct ssam_cdev_notifier_desc __user *)arg);

	case SSAM_CDEV_NOTIF_UNREGISTER:
		return ssam_cdev_notif_unregister(client,
						  (struct ssam_cdev_notifier_desc __user *)arg);

	case SSAM_CDEV_EVENT_ENABLE:
		return ssam_cdev_event_enable(client, (struct ssam_cdev_event_desc __user *)arg);

	case SSAM_CDEV_EVENT_DISABLE:
		return ssam_cdev_event_disable(client, (struct ssam_cdev_event_desc __user *)arg);

	default:
		return -ENOTTY;
	}
}

static long ssam_cdev_device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct ssam_cdev_client *client = file->private_data;
	long status;

	/* Ensure that controller is valid for as long as we need it. */
	if (down_read_killable(&client->cdev->lock))
		return -ERESTARTSYS;

	if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &client->cdev->flags)) {
		up_read(&client->cdev->lock);
		return -ENODEV;
	}

	status = __ssam_cdev_device_ioctl(client, cmd, arg);

	up_read(&client->cdev->lock);
	return status;
}

static ssize_t ssam_cdev_read(struct file *file, char __user *buf, size_t count, loff_t *offs)
{
	struct ssam_cdev_client *client = file->private_data;
	struct ssam_cdev *cdev = client->cdev;
	unsigned int copied;
	int status = 0;

	if (down_read_killable(&cdev->lock))
		return -ERESTARTSYS;

	/* Make sure we're not shut down. */
	if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags)) {
		up_read(&cdev->lock);
		return -ENODEV;
	}

	do {
		/* Check availability, wait if necessary. */
		if (kfifo_is_empty(&client->buffer)) {
			up_read(&cdev->lock);

			if (file->f_flags & O_NONBLOCK)
				return -EAGAIN;

			status = wait_event_interruptible(client->waitq,
							  !kfifo_is_empty(&client->buffer) ||
							  test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT,
								   &cdev->flags));
			if (status < 0)
				return status;

			if (down_read_killable(&cdev->lock))
				return -ERESTARTSYS;

			/* Need to check that we're not shut down again. */
			if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags)) {
				up_read(&cdev->lock);
				return -ENODEV;
			}
		}

		/* Try to read from FIFO. */
		if (mutex_lock_interruptible(&client->read_lock)) {
			up_read(&cdev->lock);
			return -ERESTARTSYS;
		}

		status = kfifo_to_user(&client->buffer, buf, count, &copied);
		mutex_unlock(&client->read_lock);

		if (status < 0) {
			up_read(&cdev->lock);
			return status;
		}

		/* We might not have gotten anything, check this here. */
		if (copied == 0 && (file->f_flags & O_NONBLOCK)) {
			up_read(&cdev->lock);
			return -EAGAIN;
		}
	} while (copied == 0);

	up_read(&cdev->lock);
	return copied;
}

static __poll_t ssam_cdev_poll(struct file *file, struct poll_table_struct *pt)
{
	struct ssam_cdev_client *client = file->private_data;
	__poll_t events = 0;

	if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &client->cdev->flags))
		return EPOLLHUP | EPOLLERR;

	poll_wait(file, &client->waitq, pt);

	if (!kfifo_is_empty(&client->buffer))
		events |= EPOLLIN | EPOLLRDNORM;

	return events;
}

static int ssam_cdev_fasync(int fd, struct file *file, int on)
{
	struct ssam_cdev_client *client = file->private_data;

	return fasync_helper(fd, file, on, &client->fasync);
}

static const struct file_operations ssam_controller_fops = {
	.owner          = THIS_MODULE,
	.open           = ssam_cdev_device_open,
	.release        = ssam_cdev_device_release,
	.read           = ssam_cdev_read,
	.poll           = ssam_cdev_poll,
	.fasync         = ssam_cdev_fasync,
	.unlocked_ioctl = ssam_cdev_device_ioctl,
	.compat_ioctl   = ssam_cdev_device_ioctl,
};


/* -- Device and driver setup ----------------------------------------------- */

static int ssam_dbg_device_probe(struct platform_device *pdev)
{
	struct ssam_controller *ctrl;
	struct ssam_cdev *cdev;
	int status;

	ctrl = ssam_client_bind(&pdev->dev);
	if (IS_ERR(ctrl))
		return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl);

	cdev = kzalloc_obj(*cdev);
	if (!cdev)
		return -ENOMEM;

	kref_init(&cdev->kref);
	init_rwsem(&cdev->lock);
	cdev->ctrl = ctrl;
	cdev->dev = &pdev->dev;

	cdev->mdev.parent   = &pdev->dev;
	cdev->mdev.minor    = MISC_DYNAMIC_MINOR;
	cdev->mdev.name     = "surface_aggregator";
	cdev->mdev.nodename = "surface/aggregator";
	cdev->mdev.fops     = &ssam_controller_fops;

	init_rwsem(&cdev->client_lock);
	INIT_LIST_HEAD(&cdev->client_list);

	status = misc_register(&cdev->mdev);
	if (status) {
		kfree(cdev);
		return status;
	}

	platform_set_drvdata(pdev, cdev);
	return 0;
}

static void ssam_dbg_device_remove(struct platform_device *pdev)
{
	struct ssam_cdev *cdev = platform_get_drvdata(pdev);
	struct ssam_cdev_client *client;

	/*
	 * Mark device as shut-down. Prevent new clients from being added and
	 * new operations from being executed.
	 */
	set_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags);

	down_write(&cdev->client_lock);

	/* Remove all notifiers registered by us. */
	list_for_each_entry(client, &cdev->client_list, node) {
		ssam_cdev_notifier_unregister_all(client);
	}

	/* Wake up async clients. */
	list_for_each_entry(client, &cdev->client_list, node) {
		kill_fasync(&client->fasync, SIGIO, POLL_HUP);
	}

	/* Wake up blocking clients. */
	list_for_each_entry(client, &cdev->client_list, node) {
		wake_up_interruptible(&client->waitq);
	}

	up_write(&cdev->client_lock);

	/*
	 * The controller is only guaranteed to be valid for as long as the
	 * driver is bound. Remove controller so that any lingering open files
	 * cannot access it any more after we're gone.
	 */
	down_write(&cdev->lock);
	cdev->ctrl = NULL;
	cdev->dev = NULL;
	up_write(&cdev->lock);

	misc_deregister(&cdev->mdev);

	ssam_cdev_put(cdev);
}

static struct platform_device *ssam_cdev_device;

static struct platform_driver ssam_cdev_driver = {
	.probe = ssam_dbg_device_probe,
	.remove = ssam_dbg_device_remove,
	.driver = {
		.name = SSAM_CDEV_DEVICE_NAME,
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
	},
};

static int __init ssam_debug_init(void)
{
	int status;

	ssam_cdev_device = platform_device_alloc(SSAM_CDEV_DEVICE_NAME,
						 PLATFORM_DEVID_NONE);
	if (!ssam_cdev_device)
		return -ENOMEM;

	status = platform_device_add(ssam_cdev_device);
	if (status)
		goto err_device;

	status = platform_driver_register(&ssam_cdev_driver);
	if (status)
		goto err_driver;

	return 0;

err_driver:
	platform_device_del(ssam_cdev_device);
err_device:
	platform_device_put(ssam_cdev_device);
	return status;
}
module_init(ssam_debug_init);

static void __exit ssam_debug_exit(void)
{
	platform_driver_unregister(&ssam_cdev_driver);
	platform_device_unregister(ssam_cdev_device);
}
module_exit(ssam_debug_exit);

MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
MODULE_DESCRIPTION("User-space interface for Surface System Aggregator Module");
MODULE_LICENSE("GPL");
