Skip to content

Commit 2621a41

Browse files
author
Ben Skeggs
committed
drm/nouveau/abi16: implement limited interoperability with usif/nvif
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
1 parent 786a57e commit 2621a41

3 files changed

Lines changed: 53 additions & 2 deletions

File tree

drivers/gpu/drm/nouveau/nouveau_abi16.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <nvif/driver.h>
2626
#include <nvif/ioctl.h>
2727
#include <nvif/class.h>
28+
#include <nvif/unpack.h>
2829

2930
#include "nouveau_drm.h"
3031
#include "nouveau_dma.h"
@@ -346,6 +347,44 @@ nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel)
346347
return NULL;
347348
}
348349

350+
int
351+
nouveau_abi16_usif(struct drm_file *file_priv, void *data, u32 size)
352+
{
353+
union {
354+
struct nvif_ioctl_v0 v0;
355+
} *args = data;
356+
struct nouveau_abi16_chan *chan;
357+
struct nouveau_abi16 *abi16;
358+
int ret;
359+
360+
if (nvif_unpack(args->v0, 0, 0, true)) {
361+
switch (args->v0.type) {
362+
case NVIF_IOCTL_V0_NEW:
363+
case NVIF_IOCTL_V0_MTHD:
364+
case NVIF_IOCTL_V0_SCLASS:
365+
break;
366+
default:
367+
return -EACCES;
368+
}
369+
} else
370+
return ret;
371+
372+
if (!(abi16 = nouveau_abi16(file_priv)))
373+
return -ENOMEM;
374+
375+
if (args->v0.token != ~0ULL) {
376+
if (!(chan = nouveau_abi16_chan(abi16, args->v0.token)))
377+
return -EINVAL;
378+
args->v0.object = nvif_handle(&chan->chan->user);
379+
args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
380+
return 0;
381+
}
382+
383+
args->v0.object = nvif_handle(&abi16->device.object);
384+
args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
385+
return 0;
386+
}
387+
349388
int
350389
nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
351390
{

drivers/gpu/drm/nouveau/nouveau_abi16.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *);
3737
int nouveau_abi16_put(struct nouveau_abi16 *, int);
3838
void nouveau_abi16_fini(struct nouveau_abi16 *);
3939
s32 nouveau_abi16_swclass(struct nouveau_drm *);
40+
int nouveau_abi16_usif(struct drm_file *, void *data, u32 size);
4041

4142
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
4243
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)

drivers/gpu/drm/nouveau/nouveau_usif.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "nouveau_drm.h"
2626
#include "nouveau_usif.h"
27+
#include "nouveau_abi16.h"
2728

2829
#include <nvif/notify.h>
2930
#include <nvif/unpack.h>
@@ -316,11 +317,21 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
316317
} else
317318
goto done;
318319

320+
/* USIF slightly abuses some return-only ioctl members in order
321+
* to provide interoperability with the older ABI16 objects
322+
*/
319323
mutex_lock(&cli->mutex);
324+
if (argv->v0.route) {
325+
if (ret = -EINVAL, argv->v0.route == 0xff)
326+
ret = nouveau_abi16_usif(filp, argv, argc);
327+
if (ret) {
328+
mutex_unlock(&cli->mutex);
329+
goto done;
330+
}
331+
}
332+
320333
switch (argv->v0.type) {
321334
case NVIF_IOCTL_V0_NEW:
322-
/* ... except if we're creating children */
323-
argv->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
324335
ret = usif_object_new(filp, data, size, argv, argc);
325336
break;
326337
case NVIF_IOCTL_V0_NTFY_NEW:

0 commit comments

Comments
 (0)