drm/nouveau/abi16: implement limited interoperability with usif/nvif

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs 2015-11-03 11:21:43 +10:00
parent 786a57ef2c
commit 2621a41647
3 changed files with 53 additions and 2 deletions

View file

@ -25,6 +25,7 @@
#include <nvif/driver.h>
#include <nvif/ioctl.h>
#include <nvif/class.h>
#include <nvif/unpack.h>
#include "nouveau_drm.h"
#include "nouveau_dma.h"
@ -346,6 +347,44 @@ nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel)
return NULL;
}
int
nouveau_abi16_usif(struct drm_file *file_priv, void *data, u32 size)
{
union {
struct nvif_ioctl_v0 v0;
} *args = data;
struct nouveau_abi16_chan *chan;
struct nouveau_abi16 *abi16;
int ret;
if (nvif_unpack(args->v0, 0, 0, true)) {
switch (args->v0.type) {
case NVIF_IOCTL_V0_NEW:
case NVIF_IOCTL_V0_MTHD:
case NVIF_IOCTL_V0_SCLASS:
break;
default:
return -EACCES;
}
} else
return ret;
if (!(abi16 = nouveau_abi16(file_priv)))
return -ENOMEM;
if (args->v0.token != ~0ULL) {
if (!(chan = nouveau_abi16_chan(abi16, args->v0.token)))
return -EINVAL;
args->v0.object = nvif_handle(&chan->chan->user);
args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
return 0;
}
args->v0.object = nvif_handle(&abi16->device.object);
args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
return 0;
}
int
nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
{

View file

@ -37,6 +37,7 @@ struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *);
int nouveau_abi16_put(struct nouveau_abi16 *, int);
void nouveau_abi16_fini(struct nouveau_abi16 *);
s32 nouveau_abi16_swclass(struct nouveau_drm *);
int nouveau_abi16_usif(struct drm_file *, void *data, u32 size);
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)

View file

@ -24,6 +24,7 @@
#include "nouveau_drm.h"
#include "nouveau_usif.h"
#include "nouveau_abi16.h"
#include <nvif/notify.h>
#include <nvif/unpack.h>
@ -316,11 +317,21 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
} 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:
/* ... except if we're creating children */
argv->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
ret = usif_object_new(filp, data, size, argv, argc);
break;
case NVIF_IOCTL_V0_NTFY_NEW: