diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2015-11-02 20:21:43 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-11-03 00:02:18 -0500 |
commit | 2621a41647fe783be809e789faa5d8b6b06c8072 (patch) | |
tree | bd0be934e8d49441e16506f6d9bf6980924cc7a3 | |
parent | 786a57ef2cebb2d09d7f152b0ed4f1da1d368073 (diff) |
drm/nouveau/abi16: implement limited interoperability with usif/nvif
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_abi16.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_abi16.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_usif.c | 15 |
3 files changed, 53 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 998f5cb2dfac..7f50cf5f929e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <nvif/driver.h> | 25 | #include <nvif/driver.h> |
26 | #include <nvif/ioctl.h> | 26 | #include <nvif/ioctl.h> |
27 | #include <nvif/class.h> | 27 | #include <nvif/class.h> |
28 | #include <nvif/unpack.h> | ||
28 | 29 | ||
29 | #include "nouveau_drm.h" | 30 | #include "nouveau_drm.h" |
30 | #include "nouveau_dma.h" | 31 | #include "nouveau_dma.h" |
@@ -347,6 +348,44 @@ nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel) | |||
347 | } | 348 | } |
348 | 349 | ||
349 | int | 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 | |||
388 | int | ||
350 | nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS) | 389 | nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS) |
351 | { | 390 | { |
352 | struct drm_nouveau_channel_free *req = data; | 391 | struct drm_nouveau_channel_free *req = data; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.h b/drivers/gpu/drm/nouveau/nouveau_abi16.h index fa1d856d2ac4..841cc556fad8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.h +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.h | |||
@@ -37,6 +37,7 @@ struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *); | |||
37 | int nouveau_abi16_put(struct nouveau_abi16 *, int); | 37 | int nouveau_abi16_put(struct nouveau_abi16 *, int); |
38 | void nouveau_abi16_fini(struct nouveau_abi16 *); | 38 | void nouveau_abi16_fini(struct nouveau_abi16 *); |
39 | s32 nouveau_abi16_swclass(struct nouveau_drm *); | 39 | s32 nouveau_abi16_swclass(struct nouveau_drm *); |
40 | int nouveau_abi16_usif(struct drm_file *, void *data, u32 size); | ||
40 | 41 | ||
41 | #define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1) | 42 | #define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1) |
42 | #define NOUVEAU_GEM_DOMAIN_GART (1 << 2) | 43 | #define NOUVEAU_GEM_DOMAIN_GART (1 << 2) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c index cb1182d7e80e..89dc4ce63490 100644 --- a/drivers/gpu/drm/nouveau/nouveau_usif.c +++ b/drivers/gpu/drm/nouveau/nouveau_usif.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "nouveau_drm.h" | 25 | #include "nouveau_drm.h" |
26 | #include "nouveau_usif.h" | 26 | #include "nouveau_usif.h" |
27 | #include "nouveau_abi16.h" | ||
27 | 28 | ||
28 | #include <nvif/notify.h> | 29 | #include <nvif/notify.h> |
29 | #include <nvif/unpack.h> | 30 | #include <nvif/unpack.h> |
@@ -316,11 +317,21 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc) | |||
316 | } else | 317 | } else |
317 | goto done; | 318 | goto done; |
318 | 319 | ||
320 | /* USIF slightly abuses some return-only ioctl members in order | ||
321 | * to provide interoperability with the older ABI16 objects | ||
322 | */ | ||
319 | mutex_lock(&cli->mutex); | 323 | 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 | |||
320 | switch (argv->v0.type) { | 333 | switch (argv->v0.type) { |
321 | case NVIF_IOCTL_V0_NEW: | 334 | case NVIF_IOCTL_V0_NEW: |
322 | /* ... except if we're creating children */ | ||
323 | argv->v0.owner = NVIF_IOCTL_V0_OWNER_ANY; | ||
324 | ret = usif_object_new(filp, data, size, argv, argc); | 335 | ret = usif_object_new(filp, data, size, argv, argc); |
325 | break; | 336 | break; |
326 | case NVIF_IOCTL_V0_NTFY_NEW: | 337 | case NVIF_IOCTL_V0_NTFY_NEW: |