/*
 * Copyright 2014 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Ben Skeggs <bskeggs@redhat.com>
 */

#include "nouveau_drv.h"
#include "nouveau_usif.h"
#include "nouveau_abi16.h"

#include <nvif/notify.h>
#include <nvif/unpack.h>
#include <nvif/client.h>
#include <nvif/event.h>
#include <nvif/ioctl.h>

struct usif_notify_p {
	struct drm_pending_event base;
	struct {
		struct drm_event base;
		u8 data[];
	} e;
};

struct usif_notify {
	struct list_head head;
	atomic_t enabled;
	u32 handle;
	u16 reply;
	u8  route;
	u64 token;
	struct usif_notify_p *p;
};

static inline struct usif_notify *
usif_notify_find(struct drm_file *filp, u32 handle)
{
	struct nouveau_cli *cli = nouveau_cli(filp);
	struct usif_notify *ntfy;
	list_for_each_entry(ntfy, &cli->notifys, head) {
		if (ntfy->handle == handle)
			return ntfy;
	}
	return NULL;
}

static inline void
usif_notify_dtor(struct usif_notify *ntfy)
{
	list_del(&ntfy->head);
	kfree(ntfy);
}

int
usif_notify(const void *header, u32 length, const void *data, u32 size)
{
	struct usif_notify *ntfy = NULL;
	const union {
		struct nvif_notify_rep_v0 v0;
	} *rep = header;
	struct drm_device *dev;
	struct drm_file *filp;
	unsigned long flags;

	if (length == sizeof(rep->v0) && rep->v0.version == 0) {
		if (WARN_ON(!(ntfy = (void *)(unsigned long)rep->v0.token)))
			return NVIF_NOTIFY_DROP;
		BUG_ON(rep->v0.route != NVDRM_NOTIFY_USIF);
	} else
	if (WARN_ON(1))
		return NVIF_NOTIFY_DROP;

	if (WARN_ON(!ntfy->p || ntfy->reply != (length + size)))
		return NVIF_NOTIFY_DROP;
	filp = ntfy->p->base.file_priv;
	dev = filp->minor->dev;

	memcpy(&ntfy->p->e.data[0], header, length);
	memcpy(&ntfy->p->e.data[length], data, size);
	switch (rep->v0.version) {
	case 0: {
		struct nvif_notify_rep_v0 *rep = (void *)ntfy->p->e.data;
		rep->route = ntfy->route;
		rep->token = ntfy->token;
	}
		break;
	default:
		BUG();
		break;
	}

	spin_lock_irqsave(&dev->event_lock, flags);
	if (!WARN_ON(filp->event_space < ntfy->p->e.base.length)) {
		list_add_tail(&ntfy->p->base.link, &filp->event_list);
		filp->event_space -= ntfy->p->e.base.length;
	}
	wake_up_interruptible(&filp->event_wait);
	spin_unlock_irqrestore(&dev->event_lock, flags);
	atomic_set(&ntfy->enabled, 0);
	return NVIF_NOTIFY_DROP;
}

static int
usif_notify_new(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
{
	struct nouveau_cli *cli = nouveau_cli(f);
	struct nvif_client *client = &cli->base;
	union {
		struct nvif_ioctl_ntfy_new_v0 v0;
	} *args = data;
	union {
		struct nvif_notify_req_v0 v0;
	} *req;
	struct usif_notify *ntfy;
	int ret = -ENOSYS;

	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		if (usif_notify_find(f, args->v0.index))
			return -EEXIST;
	} else
		return ret;
	req = data;
	ret = -ENOSYS;

	if (!(ntfy = kmalloc(sizeof(*ntfy), GFP_KERNEL)))
		return -ENOMEM;
	atomic_set(&ntfy->enabled, 0);

	if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, true))) {
		ntfy->reply = sizeof(struct nvif_notify_rep_v0) + req->v0.reply;
		ntfy->route = req->v0.route;
		ntfy->token = req->v0.token;
		req->v0.route = NVDRM_NOTIFY_USIF;
		req->v0.token = (unsigned long)(void *)ntfy;
		ret = nvif_client_ioctl(client, argv, argc);
		req->v0.token = ntfy->token;
		req->v0.route = ntfy->route;
		ntfy->handle = args->v0.index;
	}

	if (ret == 0)
		list_add(&ntfy->head, &cli->notifys);
	if (ret)
		kfree(ntfy);
	return ret;
}

static int
usif_notify_del(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
{
	struct nouveau_cli *cli = nouveau_cli(f);
	struct nvif_client *client = &cli->base;
	union {
		struct nvif_ioctl_ntfy_del_v0 v0;
	} *args = data;
	struct usif_notify *ntfy;
	int ret = -ENOSYS;

	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		if (!(ntfy = usif_notify_find(f, args->v0.index)))
			return -ENOENT;
	} else
		return ret;

	ret = nvif_client_ioctl(client, argv, argc);
	if (ret == 0)
		usif_notify_dtor(ntfy);
	return ret;
}

static int
usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
{
	struct nouveau_cli *cli = nouveau_cli(f);
	struct nvif_client *client = &cli->base;
	union {
		struct nvif_ioctl_ntfy_del_v0 v0;
	} *args = data;
	struct usif_notify *ntfy;
	int ret = -ENOSYS;

	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		if (!(ntfy = usif_notify_find(f, args->v0.index)))
			return -ENOENT;
	} else
		return ret;

	if (atomic_xchg(&ntfy->enabled, 1))
		return 0;

	ntfy->p = kmalloc(sizeof(*ntfy->p) + ntfy->reply, GFP_KERNEL);
	if (ret = -ENOMEM, !ntfy->p)
		goto done;
	ntfy->p->base.event = &ntfy->p->e.base;
	ntfy->p->base.file_priv = f;
	ntfy->p->base.pid = current->pid;
	ntfy->p->e.base.type = DRM_NOUVEAU_EVENT_NVIF;
	ntfy->p->e.base.length = sizeof(ntfy->p->e.base) + ntfy->reply;

	ret = nvif_client_ioctl(client, argv, argc);
done:
	if (ret) {
		atomic_set(&ntfy->enabled, 0);
		kfree(ntfy->p);
	}
	return ret;
}

static int
usif_notify_put(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
{
	struct nouveau_cli *cli = nouveau_cli(f);
	struct nvif_client *client = &cli->base;
	union {
		struct nvif_ioctl_ntfy_put_v0 v0;
	} *args = data;
	struct usif_notify *ntfy;
	int ret = -ENOSYS;

	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		if (!(ntfy = usif_notify_find(f, args->v0.index)))
			return -ENOENT;
	} else
		return ret;

	ret = nvif_client_ioctl(client, argv, argc);
	if (ret == 0 && atomic_xchg(&ntfy->enabled, 0))
		kfree(ntfy->p);
	return ret;
}

struct usif_object {
	struct list_head head;
	struct list_head ntfy;
	u8  route;
	u64 token;
};

static void
usif_object_dtor(struct usif_object *object)
{
	list_del(&object->head);
	kfree(object);
}

static int
usif_object_new(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
{
	struct nouveau_cli *cli = nouveau_cli(f);
	struct nvif_client *client = &cli->base;
	union {
		struct nvif_ioctl_new_v0 v0;
	} *args = data;
	struct usif_object *object;
	int ret = -ENOSYS;

	if (!(object = kmalloc(sizeof(*object), GFP_KERNEL)))
		return -ENOMEM;
	list_add(&object->head, &cli->objects);

	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		object->route = args->v0.route;
		object->token = args->v0.token;
		args->v0.route = NVDRM_OBJECT_USIF;
		args->v0.token = (unsigned long)(void *)object;
		ret = nvif_client_ioctl(client, argv, argc);
		args->v0.token = object->token;
		args->v0.route = object->route;
	}

	if (ret)
		usif_object_dtor(object);
	return ret;
}

int
usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
{
	struct nouveau_cli *cli = nouveau_cli(filp);
	struct nvif_client *client = &cli->base;
	void *data = kmalloc(argc, GFP_KERNEL);
	u32   size = argc;
	union {
		struct nvif_ioctl_v0 v0;
	} *argv = data;
	struct usif_object *object;
	u8 owner;
	int ret;

	if (ret = -ENOMEM, !argv)
		goto done;
	if (ret = -EFAULT, copy_from_user(argv, user, size))
		goto done;

	if (!(ret = nvif_unpack(-ENOSYS, &data, &size, argv->v0, 0, 0, true))) {
		/* block access to objects not created via this interface */
		owner = argv->v0.owner;
		if (argv->v0.object == 0ULL &&
		    argv->v0.type != NVIF_IOCTL_V0_DEL)
			argv->v0.owner = NVDRM_OBJECT_ANY; /* except client */
		else
			argv->v0.owner = NVDRM_OBJECT_USIF;
	} else
		goto done;

	/* USIF slightly abuses some return-only ioctl members in order
	 * to provide interoperability with the older ABI16 objects
	 */
	mutex_lock(&cli->mutex);
	if (argv->v0.route) {
		if (ret = -EINVAL, argv->v0.route == 0xff)
			ret = nouveau_abi16_usif(filp, argv, argc);
		if (ret) {
			mutex_unlock(&cli->mutex);
			goto done;
		}
	}

	switch (argv->v0.type) {
	case NVIF_IOCTL_V0_NEW:
		ret = usif_object_new(filp, data, size, argv, argc);
		break;
	case NVIF_IOCTL_V0_NTFY_NEW:
		ret = usif_notify_new(filp, data, size, argv, argc);
		break;
	case NVIF_IOCTL_V0_NTFY_DEL:
		ret = usif_notify_del(filp, data, size, argv, argc);
		break;
	case NVIF_IOCTL_V0_NTFY_GET:
		ret = usif_notify_get(filp, data, size, argv, argc);
		break;
	case NVIF_IOCTL_V0_NTFY_PUT:
		ret = usif_notify_put(filp, data, size, argv, argc);
		break;
	default:
		ret = nvif_client_ioctl(client, argv, argc);
		break;
	}
	if (argv->v0.route == NVDRM_OBJECT_USIF) {
		object = (void *)(unsigned long)argv->v0.token;
		argv->v0.route = object->route;
		argv->v0.token = object->token;
		if (ret == 0 && argv->v0.type == NVIF_IOCTL_V0_DEL) {
			list_del(&object->head);
			kfree(object);
		}
	} else {
		argv->v0.route = NVIF_IOCTL_V0_ROUTE_HIDDEN;
		argv->v0.token = 0;
	}
	argv->v0.owner = owner;
	mutex_unlock(&cli->mutex);

	if (copy_to_user(user, argv, argc))
		ret = -EFAULT;
done:
	kfree(argv);
	return ret;
}

void
usif_client_fini(struct nouveau_cli *cli)
{
	struct usif_object *object, *otemp;
	struct usif_notify *notify, *ntemp;

	list_for_each_entry_safe(notify, ntemp, &cli->notifys, head) {
		usif_notify_dtor(notify);
	}

	list_for_each_entry_safe(object, otemp, &cli->objects, head) {
		usif_object_dtor(object);
	}
}

void
usif_client_init(struct nouveau_cli *cli)
{
	INIT_LIST_HEAD(&cli->objects);
	INIT_LIST_HEAD(&cli->notifys);
}
