/*
 * Copyright 2012 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
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>

#include <xf86drm.h>
#include <xf86atomic.h>
#include "libdrm_macros.h"
#include "libdrm_lists.h"
#include "nouveau_drm.h"

#include "nouveau.h"
#include "private.h"

#include "nvif/class.h"
#include "nvif/cl0080.h"
#include "nvif/ioctl.h"
#include "nvif/unpack.h"

#ifdef DEBUG
drm_private uint32_t nouveau_debug = 0;

static void
debug_init(char *args)
{
	if (args) {
		int n = strtol(args, NULL, 0);
		if (n >= 0)
			nouveau_debug = n;
	}
}
#endif

static int
nouveau_object_ioctl(struct nouveau_object *obj, void *data, uint32_t size)
{
	struct nouveau_drm *drm = nouveau_drm(obj);
	union {
		struct nvif_ioctl_v0 v0;
	} *args = data;
	uint32_t argc = size;
	int ret = -ENOSYS;

	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		if (!obj->length) {
			if (obj != &drm->client)
				args->v0.object = (unsigned long)(void *)obj;
			else
				args->v0.object = 0;
			args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
			args->v0.route = 0x00;
		} else {
			args->v0.route = 0xff;
			args->v0.token = obj->handle;
		}
	} else
		return ret;

	return drmCommandWriteRead(drm->fd, DRM_NOUVEAU_NVIF, args, argc);
}

int
nouveau_object_mthd(struct nouveau_object *obj,
		    uint32_t mthd, void *data, uint32_t size)
{
	struct nouveau_drm *drm = nouveau_drm(obj);
	struct {
		struct nvif_ioctl_v0 ioctl;
		struct nvif_ioctl_mthd_v0 mthd;
	} *args;
	uint32_t argc = sizeof(*args) + size;
	uint8_t stack[128];
	int ret;

	if (!drm->nvif)
		return -ENOSYS;

	if (argc > sizeof(stack)) {
		if (!(args = malloc(argc)))
			return -ENOMEM;
	} else {
		args = (void *)stack;
	}
	args->ioctl.version = 0;
	args->ioctl.type = NVIF_IOCTL_V0_MTHD;
	args->mthd.version = 0;
	args->mthd.method = mthd;

	memcpy(args->mthd.data, data, size);
	ret = nouveau_object_ioctl(obj, args, argc);
	memcpy(data, args->mthd.data, size);
	if (args != (void *)stack)
		free(args);
	return ret;
}

void
nouveau_object_sclass_put(struct nouveau_sclass **psclass)
{
	free(*psclass);
	*psclass = NULL;
}

int
nouveau_object_sclass_get(struct nouveau_object *obj,
			  struct nouveau_sclass **psclass)
{
	struct nouveau_drm *drm = nouveau_drm(obj);
	struct {
		struct nvif_ioctl_v0 ioctl;
		struct nvif_ioctl_sclass_v0 sclass;
	} *args = NULL;
	struct nouveau_sclass *sclass;
	int ret, cnt = 0, i;
	uint32_t size;

	if (!drm->nvif)
		return abi16_sclass(obj, psclass);

	while (1) {
		size = sizeof(*args) + cnt * sizeof(args->sclass.oclass[0]);
		if (!(args = malloc(size)))
			return -ENOMEM;
		args->ioctl.version = 0;
		args->ioctl.type = NVIF_IOCTL_V0_SCLASS;
		args->sclass.version = 0;
		args->sclass.count = cnt;

		ret = nouveau_object_ioctl(obj, args, size);
		if (ret == 0 && args->sclass.count <= cnt)
			break;
		cnt = args->sclass.count;
		free(args);
		if (ret != 0)
			return ret;
	}

	if ((sclass = calloc(args->sclass.count, sizeof(*sclass)))) {
		for (i = 0; i < args->sclass.count; i++) {
			sclass[i].oclass = args->sclass.oclass[i].oclass;
			sclass[i].minver = args->sclass.oclass[i].minver;
			sclass[i].maxver = args->sclass.oclass[i].maxver;
		}
		*psclass = sclass;
		ret = args->sclass.count;
	} else {
		ret = -ENOMEM;
	}

	free(args);
	return ret;
}

int
nouveau_object_mclass(struct nouveau_object *obj,
		      const struct nouveau_mclass *mclass)
{
	struct nouveau_sclass *sclass;
	int ret = -ENODEV;
	int cnt, i, j;

	cnt = nouveau_object_sclass_get(obj, &sclass);
	if (cnt < 0)
		return cnt;

	for (i = 0; ret < 0 && mclass[i].oclass; i++) {
		for (j = 0; j < cnt; j++) {
			if (mclass[i].oclass  == sclass[j].oclass &&
			    mclass[i].version >= sclass[j].minver &&
			    mclass[i].version <= sclass[j].maxver) {
				ret = i;
				break;
			}
		}
	}

	nouveau_object_sclass_put(&sclass);
	return ret;
}

static void
nouveau_object_fini(struct nouveau_object *obj)
{
	struct {
		struct nvif_ioctl_v0 ioctl;
		struct nvif_ioctl_del del;
	} args = {
		.ioctl.type = NVIF_IOCTL_V0_DEL,
	};

	if (obj->data) {
		abi16_delete(obj);
		free(obj->data);
		obj->data = NULL;
		return;
	}

	nouveau_object_ioctl(obj, &args, sizeof(args));
}

static int
nouveau_object_init(struct nouveau_object *parent, uint32_t handle,
		    int32_t oclass, void *data, uint32_t size,
		    struct nouveau_object *obj)
{
	struct nouveau_drm *drm = nouveau_drm(parent);
	struct {
		struct nvif_ioctl_v0 ioctl;
		struct nvif_ioctl_new_v0 new;
	} *args;
	uint32_t argc = sizeof(*args) + size;
	int (*func)(struct nouveau_object *);
	int ret = -ENOSYS;

	obj->parent = parent;
	obj->handle = handle;
	obj->oclass = oclass;
	obj->length = 0;
	obj->data = NULL;

	if (!abi16_object(obj, &func) && drm->nvif) {
		if (!(args = malloc(argc)))
			return -ENOMEM;
		args->ioctl.version = 0;
		args->ioctl.type = NVIF_IOCTL_V0_NEW;
		args->new.version = 0;
		args->new.route = NVIF_IOCTL_V0_ROUTE_NVIF;
		args->new.token = (unsigned long)(void *)obj;
		args->new.object = (unsigned long)(void *)obj;
		args->new.handle = handle;
		args->new.oclass = oclass;
		memcpy(args->new.data, data, size);
		ret = nouveau_object_ioctl(parent, args, argc);
		memcpy(data, args->new.data, size);
		free(args);
	} else
	if (func) {
		obj->length = size ? size : sizeof(struct nouveau_object *);
		if (!(obj->data = malloc(obj->length)))
			return -ENOMEM;
		if (data)
			memcpy(obj->data, data, obj->length);
		*(struct nouveau_object **)obj->data = obj;

		ret = func(obj);
	}

	if (ret) {
		nouveau_object_fini(obj);
		return ret;
	}

	return 0;
}

int
nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
		   uint32_t oclass, void *data, uint32_t length,
		   struct nouveau_object **pobj)
{
	struct nouveau_object *obj;
	int ret;

	if (!(obj = malloc(sizeof(*obj))))
		return -ENOMEM;

	ret = nouveau_object_init(parent, handle, oclass, data, length, obj);
	if (ret) {
		free(obj);
		return ret;
	}

	*pobj = obj;
	return 0;
}

void
nouveau_object_del(struct nouveau_object **pobj)
{
	struct nouveau_object *obj = *pobj;
	if (obj) {
		nouveau_object_fini(obj);
		free(obj);
		*pobj = NULL;
	}
}

void
nouveau_drm_del(struct nouveau_drm **pdrm)
{
	free(*pdrm);
	*pdrm = NULL;
}

int
nouveau_drm_new(int fd, struct nouveau_drm **pdrm)
{
	struct nouveau_drm *drm;
	drmVersionPtr ver;

#ifdef DEBUG
	debug_init(getenv("NOUVEAU_LIBDRM_DEBUG"));
#endif

	if (!(drm = calloc(1, sizeof(*drm))))
		return -ENOMEM;
	drm->fd = fd;

	if (!(ver = drmGetVersion(fd))) {
		nouveau_drm_del(&drm);
		return -EINVAL;
	}
	*pdrm = drm;

	drm->version = (ver->version_major << 24) |
		       (ver->version_minor << 8) |
		        ver->version_patchlevel;
	drm->nvif = (drm->version >= 0x01000301);
	drmFreeVersion(ver);
	return 0;
}

/* this is the old libdrm's version of nouveau_device_wrap(), the symbol
 * is kept here to prevent AIGLX from crashing if the DDX is linked against
 * the new libdrm, but the DRI driver against the old
 */
int
nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd,
			     drm_context_t ctx)
{
	return -EACCES;
}

int
nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
		   void *data, uint32_t size, struct nouveau_device **pdev)
{
	struct nv_device_info_v0 info = {};
	union {
		struct nv_device_v0 v0;
	} *args = data;
	uint32_t argc = size;
	struct nouveau_drm *drm = nouveau_drm(parent);
	struct nouveau_device_priv *nvdev;
	struct nouveau_device *dev;
	uint64_t v;
	char *tmp;
	int ret = -ENOSYS;

	if (oclass != NV_DEVICE ||
	    nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))
		return ret;

	if (!(nvdev = calloc(1, sizeof(*nvdev))))
		return -ENOMEM;
	dev = *pdev = &nvdev->base;
	dev->fd = -1;

	if (drm->nvif) {
		ret = nouveau_object_init(parent, 0, oclass, args, argc,
					  &dev->object);
		if (ret)
			goto done;

		info.version = 0;

		ret = nouveau_object_mthd(&dev->object, NV_DEVICE_V0_INFO,
					  &info, sizeof(info));
		if (ret)
			goto done;

		nvdev->base.chipset = info.chipset;
		nvdev->have_bo_usage = true;
	} else
	if (args->v0.device == ~0ULL) {
		nvdev->base.object.parent = &drm->client;
		nvdev->base.object.handle = ~0ULL;
		nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
		nvdev->base.object.length = ~0;

		ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &v);
		if (ret)
			goto done;
		nvdev->base.chipset = v;

		ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &v);
		if (ret == 0)
			nvdev->have_bo_usage = (v != 0);
	} else
		return -ENOSYS;

	ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &v);
	if (ret)
		goto done;
	nvdev->base.vram_size = v;

	ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &v);
	if (ret)
		goto done;
	nvdev->base.gart_size = v;

	tmp = getenv("NOUVEAU_LIBDRM_VRAM_LIMIT_PERCENT");
	if (tmp)
		nvdev->vram_limit_percent = atoi(tmp);
	else
		nvdev->vram_limit_percent = 80;

	nvdev->base.vram_limit =
		(nvdev->base.vram_size * nvdev->vram_limit_percent) / 100;

	tmp = getenv("NOUVEAU_LIBDRM_GART_LIMIT_PERCENT");
	if (tmp)
		nvdev->gart_limit_percent = atoi(tmp);
	else
		nvdev->gart_limit_percent = 80;

	nvdev->base.gart_limit =
		(nvdev->base.gart_size * nvdev->gart_limit_percent) / 100;

	ret = pthread_mutex_init(&nvdev->lock, NULL);
	DRMINITLISTHEAD(&nvdev->bo_list);
done:
	if (ret)
		nouveau_device_del(pdev);
	return ret;
}

int
nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
{
	struct nouveau_drm *drm;
	struct nouveau_device_priv *nvdev;
	int ret;

	ret = nouveau_drm_new(fd, &drm);
	if (ret)
		return ret;
	drm->nvif = false;

	ret = nouveau_device_new(&drm->client, NV_DEVICE,
				 &(struct nv_device_v0) {
					.device = ~0ULL,
				 }, sizeof(struct nv_device_v0), pdev);
	if (ret) {
		nouveau_drm_del(&drm);
		return ret;
	}

	nvdev = nouveau_device(*pdev);
	nvdev->base.fd = drm->fd;
	nvdev->base.drm_version = drm->version;
	nvdev->close = close;
	return 0;
}

int
nouveau_device_open(const char *busid, struct nouveau_device **pdev)
{
	int ret = -ENODEV, fd = drmOpen("nouveau", busid);
	if (fd >= 0) {
		ret = nouveau_device_wrap(fd, 1, pdev);
		if (ret)
			drmClose(fd);
	}
	return ret;
}

void
nouveau_device_del(struct nouveau_device **pdev)
{
	struct nouveau_device_priv *nvdev = nouveau_device(*pdev);
	if (nvdev) {
		free(nvdev->client);
		pthread_mutex_destroy(&nvdev->lock);
		if (nvdev->base.fd >= 0) {
			struct nouveau_drm *drm =
				nouveau_drm(&nvdev->base.object);
			nouveau_drm_del(&drm);
			if (nvdev->close)
				drmClose(nvdev->base.fd);
		}
		free(nvdev);
		*pdev = NULL;
	}
}

int
nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value)
{
	struct nouveau_drm *drm = nouveau_drm(&dev->object);
	struct drm_nouveau_getparam r = { .param = param };
	int fd = drm->fd, ret =
		drmCommandWriteRead(fd, DRM_NOUVEAU_GETPARAM, &r, sizeof(r));
	*value = r.value;
	return ret;
}

int
nouveau_setparam(struct nouveau_device *dev, uint64_t param, uint64_t value)
{
	struct nouveau_drm *drm = nouveau_drm(&dev->object);
	struct drm_nouveau_setparam r = { .param = param, .value = value };
	return drmCommandWrite(drm->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r));
}

int
nouveau_client_new(struct nouveau_device *dev, struct nouveau_client **pclient)
{
	struct nouveau_device_priv *nvdev = nouveau_device(dev);
	struct nouveau_client_priv *pcli;
	int id = 0, i, ret = -ENOMEM;
	uint32_t *clients;

	pthread_mutex_lock(&nvdev->lock);

	for (i = 0; i < nvdev->nr_client; i++) {
		id = ffs(nvdev->client[i]) - 1;
		if (id >= 0)
			goto out;
	}

	clients = realloc(nvdev->client, sizeof(uint32_t) * (i + 1));
	if (!clients)
		goto unlock;
	nvdev->client = clients;
	nvdev->client[i] = 0;
	nvdev->nr_client++;

out:
	pcli = calloc(1, sizeof(*pcli));
	if (pcli) {
		nvdev->client[i] |= (1 << id);
		pcli->base.device = dev;
		pcli->base.id = (i * 32) + id;
		ret = 0;
	}

	*pclient = &pcli->base;

unlock:
	pthread_mutex_unlock(&nvdev->lock);
	return ret;
}

void
nouveau_client_del(struct nouveau_client **pclient)
{
	struct nouveau_client_priv *pcli = nouveau_client(*pclient);
	struct nouveau_device_priv *nvdev;
	if (pcli) {
		int id = pcli->base.id;
		nvdev = nouveau_device(pcli->base.device);
		pthread_mutex_lock(&nvdev->lock);
		nvdev->client[id / 32] &= ~(1 << (id % 32));
		pthread_mutex_unlock(&nvdev->lock);
		free(pcli->kref);
		free(pcli);
	}
}

static void
nouveau_bo_del(struct nouveau_bo *bo)
{
	struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
	struct nouveau_device_priv *nvdev = nouveau_device(bo->device);
	struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
	struct drm_gem_close req = { .handle = bo->handle };

	if (nvbo->head.next) {
		pthread_mutex_lock(&nvdev->lock);
		if (atomic_read(&nvbo->refcnt) == 0) {
			DRMLISTDEL(&nvbo->head);
			/*
			 * This bo has to be closed with the lock held because
			 * gem handles are not refcounted. If a shared bo is
			 * closed and re-opened in another thread a race
			 * against DRM_IOCTL_GEM_OPEN or drmPrimeFDToHandle
			 * might cause the bo to be closed accidentally while
			 * re-importing.
			 */
			drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &req);
		}
		pthread_mutex_unlock(&nvdev->lock);
	} else {
		drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &req);
	}
	if (bo->map)
		drm_munmap(bo->map, bo->size);
	free(nvbo);
}

int
nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, uint32_t align,
	       uint64_t size, union nouveau_bo_config *config,
	       struct nouveau_bo **pbo)
{
	struct nouveau_bo_priv *nvbo = calloc(1, sizeof(*nvbo));
	struct nouveau_bo *bo = &nvbo->base;
	int ret;

	if (!nvbo)
		return -ENOMEM;
	atomic_set(&nvbo->refcnt, 1);
	bo->device = dev;
	bo->flags = flags;
	bo->size = size;

	ret = abi16_bo_init(bo, align, config);
	if (ret) {
		free(nvbo);
		return ret;
	}

	*pbo = bo;
	return 0;
}

static int
nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle,
		       struct nouveau_bo **pbo, int name)
{
	struct nouveau_drm *drm = nouveau_drm(&dev->object);
	struct nouveau_device_priv *nvdev = nouveau_device(dev);
	struct drm_nouveau_gem_info req = { .handle = handle };
	struct nouveau_bo_priv *nvbo;
	int ret;

	DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) {
		if (nvbo->base.handle == handle) {
			if (atomic_inc_return(&nvbo->refcnt) == 1) {
				/*
				 * Uh oh, this bo is dead and someone else
				 * will free it, but because refcnt is
				 * now non-zero fortunately they won't
				 * call the ioctl to close the bo.
				 *
				 * Remove this bo from the list so other
				 * calls to nouveau_bo_wrap_locked will
				 * see our replacement nvbo.
				 */
				DRMLISTDEL(&nvbo->head);
				if (!name)
					name = nvbo->name;
				break;
			}

			*pbo = &nvbo->base;
			return 0;
		}
	}

	ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_INFO,
				  &req, sizeof(req));
	if (ret)
		return ret;

	nvbo = calloc(1, sizeof(*nvbo));
	if (nvbo) {
		atomic_set(&nvbo->refcnt, 1);
		nvbo->base.device = dev;
		abi16_bo_info(&nvbo->base, &req);
		nvbo->name = name;
		DRMLISTADD(&nvbo->head, &nvdev->bo_list);
		*pbo = &nvbo->base;
		return 0;
	}

	return -ENOMEM;
}

static void
nouveau_bo_make_global(struct nouveau_bo_priv *nvbo)
{
	if (!nvbo->head.next) {
		struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device);
		pthread_mutex_lock(&nvdev->lock);
		if (!nvbo->head.next)
			DRMLISTADD(&nvbo->head, &nvdev->bo_list);
		pthread_mutex_unlock(&nvdev->lock);
	}
}

int
nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle,
		struct nouveau_bo **pbo)
{
	struct nouveau_device_priv *nvdev = nouveau_device(dev);
	int ret;
	pthread_mutex_lock(&nvdev->lock);
	ret = nouveau_bo_wrap_locked(dev, handle, pbo, 0);
	pthread_mutex_unlock(&nvdev->lock);
	return ret;
}

int
nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
		    struct nouveau_bo **pbo)
{
	struct nouveau_drm *drm = nouveau_drm(&dev->object);
	struct nouveau_device_priv *nvdev = nouveau_device(dev);
	struct nouveau_bo_priv *nvbo;
	struct drm_gem_open req = { .name = name };
	int ret;

	pthread_mutex_lock(&nvdev->lock);
	DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) {
		if (nvbo->name == name) {
			ret = nouveau_bo_wrap_locked(dev, nvbo->base.handle,
						     pbo, name);
			pthread_mutex_unlock(&nvdev->lock);
			return ret;
		}
	}

	ret = drmIoctl(drm->fd, DRM_IOCTL_GEM_OPEN, &req);
	if (ret == 0) {
		ret = nouveau_bo_wrap_locked(dev, req.handle, pbo, name);
	}

	pthread_mutex_unlock(&nvdev->lock);
	return ret;
}

int
nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name)
{
	struct drm_gem_flink req = { .handle = bo->handle };
	struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
	struct nouveau_bo_priv *nvbo = nouveau_bo(bo);

	*name = nvbo->name;
	if (!*name) {
		int ret = drmIoctl(drm->fd, DRM_IOCTL_GEM_FLINK, &req);

		if (ret) {
			*name = 0;
			return ret;
		}
		nvbo->name = *name = req.name;

		nouveau_bo_make_global(nvbo);
	}
	return 0;
}

void
nouveau_bo_ref(struct nouveau_bo *bo, struct nouveau_bo **pref)
{
	struct nouveau_bo *ref = *pref;
	if (bo) {
		atomic_inc(&nouveau_bo(bo)->refcnt);
	}
	if (ref) {
		if (atomic_dec_and_test(&nouveau_bo(ref)->refcnt))
			nouveau_bo_del(ref);
	}
	*pref = bo;
}

int
nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
			    struct nouveau_bo **bo)
{
	struct nouveau_drm *drm = nouveau_drm(&dev->object);
	struct nouveau_device_priv *nvdev = nouveau_device(dev);
	int ret;
	unsigned int handle;

	nouveau_bo_ref(NULL, bo);

	pthread_mutex_lock(&nvdev->lock);
	ret = drmPrimeFDToHandle(drm->fd, prime_fd, &handle);
	if (ret == 0) {
		ret = nouveau_bo_wrap_locked(dev, handle, bo, 0);
	}
	pthread_mutex_unlock(&nvdev->lock);
	return ret;
}

int
nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd)
{
	struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
	struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
	int ret;

	ret = drmPrimeHandleToFD(drm->fd, nvbo->base.handle, DRM_CLOEXEC, prime_fd);
	if (ret)
		return ret;

	nouveau_bo_make_global(nvbo);
	return 0;
}

int
nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
		struct nouveau_client *client)
{
	struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
	struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
	struct drm_nouveau_gem_cpu_prep req;
	struct nouveau_pushbuf *push;
	int ret = 0;

	if (!(access & NOUVEAU_BO_RDWR))
		return 0;

	push = cli_push_get(client, bo);
	if (push && push->channel)
		nouveau_pushbuf_kick(push, push->channel);

	if (!nvbo->head.next && !(nvbo->access & NOUVEAU_BO_WR) &&
				!(access & NOUVEAU_BO_WR))
		return 0;

	req.handle = bo->handle;
	req.flags = 0;
	if (access & NOUVEAU_BO_WR)
		req.flags |= NOUVEAU_GEM_CPU_PREP_WRITE;
	if (access & NOUVEAU_BO_NOBLOCK)
		req.flags |= NOUVEAU_GEM_CPU_PREP_NOWAIT;

	ret = drmCommandWrite(drm->fd, DRM_NOUVEAU_GEM_CPU_PREP,
			      &req, sizeof(req));
	if (ret == 0)
		nvbo->access = 0;
	return ret;
}

int
nouveau_bo_map(struct nouveau_bo *bo, uint32_t access,
	       struct nouveau_client *client)
{
	struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
	struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
	if (bo->map == NULL) {
		bo->map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE,
			       MAP_SHARED, drm->fd, nvbo->map_handle);
		if (bo->map == MAP_FAILED) {
			bo->map = NULL;
			return -errno;
		}
	}
	return nouveau_bo_wait(bo, access, client);
}
