diff options
author | Dave Airlie <airlied@redhat.com> | 2014-08-06 03:21:13 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-08-06 03:21:13 -0400 |
commit | acf8294fecd4b805b408d02c321a0fd7eef95555 (patch) | |
tree | 1bf751f65495b72c626b5318fc33adbb1f7b5979 | |
parent | 5b215bcff50d549d73e43c09bcccf8eebcc95bac (diff) | |
parent | e7b96070dd9e51a8b16340411a8643d8c7d5a001 (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~dvdhrm/linux into drm-next
bunch of cleanups
* 'drm-next' of git://people.freedesktop.org/~dvdhrm/linux:
drm: mark drm_context support as legacy
drm: make sysfs device always available for minors
drm: make minor->index available early
drm: merge drm_drv.c into drm_ioctl.c
drm: move module initialization to drm_stub.c
drm: don't de-authenticate clients on master-close
drm: drop redundant drm_file->is_master
drm: extract legacy ctxbitmap flushing
-rw-r--r-- | drivers/gpu/drm/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_context.c | 102 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 471 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fops.c | 77 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_ioctl.c | 370 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_legacy.h | 51 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_lock.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_stub.c | 238 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_sysfs.c | 90 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 | ||||
-rw-r--r-- | drivers/staging/imx-drm/imx-drm-core.c | 2 | ||||
-rw-r--r-- | include/drm/drmP.h | 61 |
14 files changed, 727 insertions, 748 deletions
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 60eb5d425df2..1f6f40cecf5c 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
@@ -6,7 +6,7 @@ ccflags-y := -Iinclude/drm | |||
6 | 6 | ||
7 | drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ | 7 | drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ |
8 | drm_context.o drm_dma.o \ | 8 | drm_context.o drm_dma.o \ |
9 | drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ | 9 | drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ |
10 | drm_lock.o drm_memory.o drm_stub.o drm_vm.o \ | 10 | drm_lock.o drm_memory.o drm_stub.o drm_vm.o \ |
11 | drm_agpsupport.o drm_scatter.o drm_pci.o \ | 11 | drm_agpsupport.o drm_scatter.o drm_pci.o \ |
12 | drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ | 12 | drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ |
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c index a4b017b6849e..9b23525c0ed0 100644 --- a/drivers/gpu/drm/drm_context.c +++ b/drivers/gpu/drm/drm_context.c | |||
@@ -1,18 +1,13 @@ | |||
1 | /** | ||
2 | * \file drm_context.c | ||
3 | * IOCTLs for generic contexts | ||
4 | * | ||
5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> | ||
6 | * \author Gareth Hughes <gareth@valinux.com> | ||
7 | */ | ||
8 | |||
9 | /* | 1 | /* |
10 | * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com | 2 | * Legacy: Generic DRM Contexts |
11 | * | 3 | * |
12 | * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. | 4 | * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. |
13 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
14 | * All Rights Reserved. | 6 | * All Rights Reserved. |
15 | * | 7 | * |
8 | * Author: Rickard E. (Rik) Faith <faith@valinux.com> | ||
9 | * Author: Gareth Hughes <gareth@valinux.com> | ||
10 | * | ||
16 | * Permission is hereby granted, free of charge, to any person obtaining a | 11 | * Permission is hereby granted, free of charge, to any person obtaining a |
17 | * copy of this software and associated documentation files (the "Software"), | 12 | * copy of this software and associated documentation files (the "Software"), |
18 | * to deal in the Software without restriction, including without limitation | 13 | * to deal in the Software without restriction, including without limitation |
@@ -33,14 +28,14 @@ | |||
33 | * OTHER DEALINGS IN THE SOFTWARE. | 28 | * OTHER DEALINGS IN THE SOFTWARE. |
34 | */ | 29 | */ |
35 | 30 | ||
36 | /* | ||
37 | * ChangeLog: | ||
38 | * 2001-11-16 Torsten Duwe <duwe@caldera.de> | ||
39 | * added context constructor/destructor hooks, | ||
40 | * needed by SiS driver's memory management. | ||
41 | */ | ||
42 | |||
43 | #include <drm/drmP.h> | 31 | #include <drm/drmP.h> |
32 | #include "drm_legacy.h" | ||
33 | |||
34 | struct drm_ctx_list { | ||
35 | struct list_head head; | ||
36 | drm_context_t handle; | ||
37 | struct drm_file *tag; | ||
38 | }; | ||
44 | 39 | ||
45 | /******************************************************************/ | 40 | /******************************************************************/ |
46 | /** \name Context bitmap support */ | 41 | /** \name Context bitmap support */ |
@@ -56,7 +51,7 @@ | |||
56 | * in drm_device::ctx_idr, while holding the drm_device::struct_mutex | 51 | * in drm_device::ctx_idr, while holding the drm_device::struct_mutex |
57 | * lock. | 52 | * lock. |
58 | */ | 53 | */ |
59 | void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle) | 54 | void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle) |
60 | { | 55 | { |
61 | mutex_lock(&dev->struct_mutex); | 56 | mutex_lock(&dev->struct_mutex); |
62 | idr_remove(&dev->ctx_idr, ctx_handle); | 57 | idr_remove(&dev->ctx_idr, ctx_handle); |
@@ -72,7 +67,7 @@ void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle) | |||
72 | * Allocate a new idr from drm_device::ctx_idr while holding the | 67 | * Allocate a new idr from drm_device::ctx_idr while holding the |
73 | * drm_device::struct_mutex lock. | 68 | * drm_device::struct_mutex lock. |
74 | */ | 69 | */ |
75 | static int drm_ctxbitmap_next(struct drm_device * dev) | 70 | static int drm_legacy_ctxbitmap_next(struct drm_device * dev) |
76 | { | 71 | { |
77 | int ret; | 72 | int ret; |
78 | 73 | ||
@@ -90,7 +85,7 @@ static int drm_ctxbitmap_next(struct drm_device * dev) | |||
90 | * | 85 | * |
91 | * Initialise the drm_device::ctx_idr | 86 | * Initialise the drm_device::ctx_idr |
92 | */ | 87 | */ |
93 | int drm_ctxbitmap_init(struct drm_device * dev) | 88 | int drm_legacy_ctxbitmap_init(struct drm_device * dev) |
94 | { | 89 | { |
95 | idr_init(&dev->ctx_idr); | 90 | idr_init(&dev->ctx_idr); |
96 | return 0; | 91 | return 0; |
@@ -104,13 +99,43 @@ int drm_ctxbitmap_init(struct drm_device * dev) | |||
104 | * Free all idr members using drm_ctx_sarea_free helper function | 99 | * Free all idr members using drm_ctx_sarea_free helper function |
105 | * while holding the drm_device::struct_mutex lock. | 100 | * while holding the drm_device::struct_mutex lock. |
106 | */ | 101 | */ |
107 | void drm_ctxbitmap_cleanup(struct drm_device * dev) | 102 | void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev) |
108 | { | 103 | { |
109 | mutex_lock(&dev->struct_mutex); | 104 | mutex_lock(&dev->struct_mutex); |
110 | idr_destroy(&dev->ctx_idr); | 105 | idr_destroy(&dev->ctx_idr); |
111 | mutex_unlock(&dev->struct_mutex); | 106 | mutex_unlock(&dev->struct_mutex); |
112 | } | 107 | } |
113 | 108 | ||
109 | /** | ||
110 | * drm_ctxbitmap_flush() - Flush all contexts owned by a file | ||
111 | * @dev: DRM device to operate on | ||
112 | * @file: Open file to flush contexts for | ||
113 | * | ||
114 | * This iterates over all contexts on @dev and drops them if they're owned by | ||
115 | * @file. Note that after this call returns, new contexts might be added if | ||
116 | * the file is still alive. | ||
117 | */ | ||
118 | void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file) | ||
119 | { | ||
120 | struct drm_ctx_list *pos, *tmp; | ||
121 | |||
122 | mutex_lock(&dev->ctxlist_mutex); | ||
123 | |||
124 | list_for_each_entry_safe(pos, tmp, &dev->ctxlist, head) { | ||
125 | if (pos->tag == file && | ||
126 | pos->handle != DRM_KERNEL_CONTEXT) { | ||
127 | if (dev->driver->context_dtor) | ||
128 | dev->driver->context_dtor(dev, pos->handle); | ||
129 | |||
130 | drm_legacy_ctxbitmap_free(dev, pos->handle); | ||
131 | list_del(&pos->head); | ||
132 | kfree(pos); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | mutex_unlock(&dev->ctxlist_mutex); | ||
137 | } | ||
138 | |||
114 | /*@}*/ | 139 | /*@}*/ |
115 | 140 | ||
116 | /******************************************************************/ | 141 | /******************************************************************/ |
@@ -129,8 +154,8 @@ void drm_ctxbitmap_cleanup(struct drm_device * dev) | |||
129 | * Gets the map from drm_device::ctx_idr with the handle specified and | 154 | * Gets the map from drm_device::ctx_idr with the handle specified and |
130 | * returns its handle. | 155 | * returns its handle. |
131 | */ | 156 | */ |
132 | int drm_getsareactx(struct drm_device *dev, void *data, | 157 | int drm_legacy_getsareactx(struct drm_device *dev, void *data, |
133 | struct drm_file *file_priv) | 158 | struct drm_file *file_priv) |
134 | { | 159 | { |
135 | struct drm_ctx_priv_map *request = data; | 160 | struct drm_ctx_priv_map *request = data; |
136 | struct drm_local_map *map; | 161 | struct drm_local_map *map; |
@@ -173,8 +198,8 @@ int drm_getsareactx(struct drm_device *dev, void *data, | |||
173 | * Searches the mapping specified in \p arg and update the entry in | 198 | * Searches the mapping specified in \p arg and update the entry in |
174 | * drm_device::ctx_idr with it. | 199 | * drm_device::ctx_idr with it. |
175 | */ | 200 | */ |
176 | int drm_setsareactx(struct drm_device *dev, void *data, | 201 | int drm_legacy_setsareactx(struct drm_device *dev, void *data, |
177 | struct drm_file *file_priv) | 202 | struct drm_file *file_priv) |
178 | { | 203 | { |
179 | struct drm_ctx_priv_map *request = data; | 204 | struct drm_ctx_priv_map *request = data; |
180 | struct drm_local_map *map = NULL; | 205 | struct drm_local_map *map = NULL; |
@@ -273,8 +298,8 @@ static int drm_context_switch_complete(struct drm_device *dev, | |||
273 | * \param arg user argument pointing to a drm_ctx_res structure. | 298 | * \param arg user argument pointing to a drm_ctx_res structure. |
274 | * \return zero on success or a negative number on failure. | 299 | * \return zero on success or a negative number on failure. |
275 | */ | 300 | */ |
276 | int drm_resctx(struct drm_device *dev, void *data, | 301 | int drm_legacy_resctx(struct drm_device *dev, void *data, |
277 | struct drm_file *file_priv) | 302 | struct drm_file *file_priv) |
278 | { | 303 | { |
279 | struct drm_ctx_res *res = data; | 304 | struct drm_ctx_res *res = data; |
280 | struct drm_ctx ctx; | 305 | struct drm_ctx ctx; |
@@ -304,16 +329,16 @@ int drm_resctx(struct drm_device *dev, void *data, | |||
304 | * | 329 | * |
305 | * Get a new handle for the context and copy to userspace. | 330 | * Get a new handle for the context and copy to userspace. |
306 | */ | 331 | */ |
307 | int drm_addctx(struct drm_device *dev, void *data, | 332 | int drm_legacy_addctx(struct drm_device *dev, void *data, |
308 | struct drm_file *file_priv) | 333 | struct drm_file *file_priv) |
309 | { | 334 | { |
310 | struct drm_ctx_list *ctx_entry; | 335 | struct drm_ctx_list *ctx_entry; |
311 | struct drm_ctx *ctx = data; | 336 | struct drm_ctx *ctx = data; |
312 | 337 | ||
313 | ctx->handle = drm_ctxbitmap_next(dev); | 338 | ctx->handle = drm_legacy_ctxbitmap_next(dev); |
314 | if (ctx->handle == DRM_KERNEL_CONTEXT) { | 339 | if (ctx->handle == DRM_KERNEL_CONTEXT) { |
315 | /* Skip kernel's context and get a new one. */ | 340 | /* Skip kernel's context and get a new one. */ |
316 | ctx->handle = drm_ctxbitmap_next(dev); | 341 | ctx->handle = drm_legacy_ctxbitmap_next(dev); |
317 | } | 342 | } |
318 | DRM_DEBUG("%d\n", ctx->handle); | 343 | DRM_DEBUG("%d\n", ctx->handle); |
319 | if (ctx->handle == -1) { | 344 | if (ctx->handle == -1) { |
@@ -348,7 +373,8 @@ int drm_addctx(struct drm_device *dev, void *data, | |||
348 | * \param arg user argument pointing to a drm_ctx structure. | 373 | * \param arg user argument pointing to a drm_ctx structure. |
349 | * \return zero on success or a negative number on failure. | 374 | * \return zero on success or a negative number on failure. |
350 | */ | 375 | */ |
351 | int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv) | 376 | int drm_legacy_getctx(struct drm_device *dev, void *data, |
377 | struct drm_file *file_priv) | ||
352 | { | 378 | { |
353 | struct drm_ctx *ctx = data; | 379 | struct drm_ctx *ctx = data; |
354 | 380 | ||
@@ -369,8 +395,8 @@ int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
369 | * | 395 | * |
370 | * Calls context_switch(). | 396 | * Calls context_switch(). |
371 | */ | 397 | */ |
372 | int drm_switchctx(struct drm_device *dev, void *data, | 398 | int drm_legacy_switchctx(struct drm_device *dev, void *data, |
373 | struct drm_file *file_priv) | 399 | struct drm_file *file_priv) |
374 | { | 400 | { |
375 | struct drm_ctx *ctx = data; | 401 | struct drm_ctx *ctx = data; |
376 | 402 | ||
@@ -389,8 +415,8 @@ int drm_switchctx(struct drm_device *dev, void *data, | |||
389 | * | 415 | * |
390 | * Calls context_switch_complete(). | 416 | * Calls context_switch_complete(). |
391 | */ | 417 | */ |
392 | int drm_newctx(struct drm_device *dev, void *data, | 418 | int drm_legacy_newctx(struct drm_device *dev, void *data, |
393 | struct drm_file *file_priv) | 419 | struct drm_file *file_priv) |
394 | { | 420 | { |
395 | struct drm_ctx *ctx = data; | 421 | struct drm_ctx *ctx = data; |
396 | 422 | ||
@@ -411,8 +437,8 @@ int drm_newctx(struct drm_device *dev, void *data, | |||
411 | * | 437 | * |
412 | * If not the special kernel context, calls ctxbitmap_free() to free the specified context. | 438 | * If not the special kernel context, calls ctxbitmap_free() to free the specified context. |
413 | */ | 439 | */ |
414 | int drm_rmctx(struct drm_device *dev, void *data, | 440 | int drm_legacy_rmctx(struct drm_device *dev, void *data, |
415 | struct drm_file *file_priv) | 441 | struct drm_file *file_priv) |
416 | { | 442 | { |
417 | struct drm_ctx *ctx = data; | 443 | struct drm_ctx *ctx = data; |
418 | 444 | ||
@@ -420,7 +446,7 @@ int drm_rmctx(struct drm_device *dev, void *data, | |||
420 | if (ctx->handle != DRM_KERNEL_CONTEXT) { | 446 | if (ctx->handle != DRM_KERNEL_CONTEXT) { |
421 | if (dev->driver->context_dtor) | 447 | if (dev->driver->context_dtor) |
422 | dev->driver->context_dtor(dev, ctx->handle); | 448 | dev->driver->context_dtor(dev, ctx->handle); |
423 | drm_ctxbitmap_free(dev, ctx->handle); | 449 | drm_legacy_ctxbitmap_free(dev, ctx->handle); |
424 | } | 450 | } |
425 | 451 | ||
426 | mutex_lock(&dev->ctxlist_mutex); | 452 | mutex_lock(&dev->ctxlist_mutex); |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fa2be249999c..ca8bb1bc92a0 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -3244,7 +3244,7 @@ int drm_mode_getfb(struct drm_device *dev, | |||
3244 | r->bpp = fb->bits_per_pixel; | 3244 | r->bpp = fb->bits_per_pixel; |
3245 | r->pitch = fb->pitches[0]; | 3245 | r->pitch = fb->pitches[0]; |
3246 | if (fb->funcs->create_handle) { | 3246 | if (fb->funcs->create_handle) { |
3247 | if (file_priv->is_master || capable(CAP_SYS_ADMIN) || | 3247 | if (drm_is_master(file_priv) || capable(CAP_SYS_ADMIN) || |
3248 | drm_is_control_client(file_priv)) { | 3248 | drm_is_control_client(file_priv)) { |
3249 | ret = fb->funcs->create_handle(fb, file_priv, | 3249 | ret = fb->funcs->create_handle(fb, file_priv, |
3250 | &r->handle); | 3250 | &r->handle); |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c deleted file mode 100644 index 0cc182745e31..000000000000 --- a/drivers/gpu/drm/drm_drv.c +++ /dev/null | |||
@@ -1,471 +0,0 @@ | |||
1 | /** | ||
2 | * \file drm_drv.c | ||
3 | * Generic driver template | ||
4 | * | ||
5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> | ||
6 | * \author Gareth Hughes <gareth@valinux.com> | ||
7 | * | ||
8 | * To use this template, you must at least define the following (samples | ||
9 | * given for the MGA driver): | ||
10 | * | ||
11 | * \code | ||
12 | * #define DRIVER_AUTHOR "VA Linux Systems, Inc." | ||
13 | * | ||
14 | * #define DRIVER_NAME "mga" | ||
15 | * #define DRIVER_DESC "Matrox G200/G400" | ||
16 | * #define DRIVER_DATE "20001127" | ||
17 | * | ||
18 | * #define drm_x mga_##x | ||
19 | * \endcode | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com | ||
24 | * | ||
25 | * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. | ||
26 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | ||
27 | * All Rights Reserved. | ||
28 | * | ||
29 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
30 | * copy of this software and associated documentation files (the "Software"), | ||
31 | * to deal in the Software without restriction, including without limitation | ||
32 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
33 | * and/or sell copies of the Software, and to permit persons to whom the | ||
34 | * Software is furnished to do so, subject to the following conditions: | ||
35 | * | ||
36 | * The above copyright notice and this permission notice (including the next | ||
37 | * paragraph) shall be included in all copies or substantial portions of the | ||
38 | * Software. | ||
39 | * | ||
40 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
41 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
42 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
43 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
44 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
45 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
46 | * OTHER DEALINGS IN THE SOFTWARE. | ||
47 | */ | ||
48 | |||
49 | #include <linux/debugfs.h> | ||
50 | #include <linux/slab.h> | ||
51 | #include <linux/export.h> | ||
52 | #include <drm/drmP.h> | ||
53 | #include <drm/drm_core.h> | ||
54 | |||
55 | |||
56 | static int drm_version(struct drm_device *dev, void *data, | ||
57 | struct drm_file *file_priv); | ||
58 | |||
59 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ | ||
60 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl} | ||
61 | |||
62 | /** Ioctl table */ | ||
63 | static const struct drm_ioctl_desc drm_ioctls[] = { | ||
64 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
65 | DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), | ||
66 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), | ||
67 | DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), | ||
68 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED), | ||
69 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED), | ||
70 | DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED), | ||
71 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
72 | DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0), | ||
73 | DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), | ||
74 | |||
75 | DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
76 | DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
77 | DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
78 | DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER), | ||
79 | |||
80 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
81 | DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH), | ||
82 | |||
83 | DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
84 | DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH), | ||
85 | |||
86 | DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY), | ||
87 | DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY), | ||
88 | |||
89 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY), | ||
90 | DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
91 | DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
92 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH), | ||
93 | DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
94 | DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
95 | DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH), | ||
96 | |||
97 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
98 | DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
99 | |||
100 | DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH), | ||
101 | DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH), | ||
102 | |||
103 | DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH), | ||
104 | |||
105 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
106 | DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
107 | DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH), | ||
108 | DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH), | ||
109 | DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH), | ||
110 | DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_dma_ioctl, DRM_AUTH), | ||
111 | |||
112 | DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
113 | |||
114 | #if __OS_HAS_AGP | ||
115 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
116 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
117 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
118 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH), | ||
119 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
120 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
121 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
122 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
123 | #endif | ||
124 | |||
125 | DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
126 | DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
127 | |||
128 | DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED), | ||
129 | |||
130 | DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), | ||
131 | |||
132 | DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
133 | |||
134 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
135 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), | ||
136 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), | ||
137 | |||
138 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
139 | |||
140 | DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
141 | DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
142 | |||
143 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
144 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
145 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
146 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
147 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
148 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
149 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED), | ||
150 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), | ||
151 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
152 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
153 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
154 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
155 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
156 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
157 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
158 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
159 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
160 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
161 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
162 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
163 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
164 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
165 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
166 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
167 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
168 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
169 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
170 | }; | ||
171 | |||
172 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) | ||
173 | |||
174 | /** File operations structure */ | ||
175 | static const struct file_operations drm_stub_fops = { | ||
176 | .owner = THIS_MODULE, | ||
177 | .open = drm_stub_open, | ||
178 | .llseek = noop_llseek, | ||
179 | }; | ||
180 | |||
181 | static int __init drm_core_init(void) | ||
182 | { | ||
183 | int ret = -ENOMEM; | ||
184 | |||
185 | drm_global_init(); | ||
186 | drm_connector_ida_init(); | ||
187 | idr_init(&drm_minors_idr); | ||
188 | |||
189 | if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) | ||
190 | goto err_p1; | ||
191 | |||
192 | drm_class = drm_sysfs_create(THIS_MODULE, "drm"); | ||
193 | if (IS_ERR(drm_class)) { | ||
194 | printk(KERN_ERR "DRM: Error creating drm class.\n"); | ||
195 | ret = PTR_ERR(drm_class); | ||
196 | goto err_p2; | ||
197 | } | ||
198 | |||
199 | drm_debugfs_root = debugfs_create_dir("dri", NULL); | ||
200 | if (!drm_debugfs_root) { | ||
201 | DRM_ERROR("Cannot create /sys/kernel/debug/dri\n"); | ||
202 | ret = -1; | ||
203 | goto err_p3; | ||
204 | } | ||
205 | |||
206 | DRM_INFO("Initialized %s %d.%d.%d %s\n", | ||
207 | CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); | ||
208 | return 0; | ||
209 | err_p3: | ||
210 | drm_sysfs_destroy(); | ||
211 | err_p2: | ||
212 | unregister_chrdev(DRM_MAJOR, "drm"); | ||
213 | |||
214 | idr_destroy(&drm_minors_idr); | ||
215 | err_p1: | ||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | static void __exit drm_core_exit(void) | ||
220 | { | ||
221 | debugfs_remove(drm_debugfs_root); | ||
222 | drm_sysfs_destroy(); | ||
223 | |||
224 | unregister_chrdev(DRM_MAJOR, "drm"); | ||
225 | |||
226 | drm_connector_ida_destroy(); | ||
227 | idr_destroy(&drm_minors_idr); | ||
228 | } | ||
229 | |||
230 | module_init(drm_core_init); | ||
231 | module_exit(drm_core_exit); | ||
232 | |||
233 | /** | ||
234 | * Copy and IOCTL return string to user space | ||
235 | */ | ||
236 | static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value) | ||
237 | { | ||
238 | int len; | ||
239 | |||
240 | /* don't overflow userbuf */ | ||
241 | len = strlen(value); | ||
242 | if (len > *buf_len) | ||
243 | len = *buf_len; | ||
244 | |||
245 | /* let userspace know exact length of driver value (which could be | ||
246 | * larger than the userspace-supplied buffer) */ | ||
247 | *buf_len = strlen(value); | ||
248 | |||
249 | /* finally, try filling in the userbuf */ | ||
250 | if (len && buf) | ||
251 | if (copy_to_user(buf, value, len)) | ||
252 | return -EFAULT; | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * Get version information | ||
258 | * | ||
259 | * \param inode device inode. | ||
260 | * \param filp file pointer. | ||
261 | * \param cmd command. | ||
262 | * \param arg user argument, pointing to a drm_version structure. | ||
263 | * \return zero on success or negative number on failure. | ||
264 | * | ||
265 | * Fills in the version information in \p arg. | ||
266 | */ | ||
267 | static int drm_version(struct drm_device *dev, void *data, | ||
268 | struct drm_file *file_priv) | ||
269 | { | ||
270 | struct drm_version *version = data; | ||
271 | int err; | ||
272 | |||
273 | version->version_major = dev->driver->major; | ||
274 | version->version_minor = dev->driver->minor; | ||
275 | version->version_patchlevel = dev->driver->patchlevel; | ||
276 | err = drm_copy_field(version->name, &version->name_len, | ||
277 | dev->driver->name); | ||
278 | if (!err) | ||
279 | err = drm_copy_field(version->date, &version->date_len, | ||
280 | dev->driver->date); | ||
281 | if (!err) | ||
282 | err = drm_copy_field(version->desc, &version->desc_len, | ||
283 | dev->driver->desc); | ||
284 | |||
285 | return err; | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * drm_ioctl_permit - Check ioctl permissions against caller | ||
290 | * | ||
291 | * @flags: ioctl permission flags. | ||
292 | * @file_priv: Pointer to struct drm_file identifying the caller. | ||
293 | * | ||
294 | * Checks whether the caller is allowed to run an ioctl with the | ||
295 | * indicated permissions. If so, returns zero. Otherwise returns an | ||
296 | * error code suitable for ioctl return. | ||
297 | */ | ||
298 | static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv) | ||
299 | { | ||
300 | /* ROOT_ONLY is only for CAP_SYS_ADMIN */ | ||
301 | if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN))) | ||
302 | return -EACCES; | ||
303 | |||
304 | /* AUTH is only for authenticated or render client */ | ||
305 | if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) && | ||
306 | !file_priv->authenticated)) | ||
307 | return -EACCES; | ||
308 | |||
309 | /* MASTER is only for master or control clients */ | ||
310 | if (unlikely((flags & DRM_MASTER) && !file_priv->is_master && | ||
311 | !drm_is_control_client(file_priv))) | ||
312 | return -EACCES; | ||
313 | |||
314 | /* Control clients must be explicitly allowed */ | ||
315 | if (unlikely(!(flags & DRM_CONTROL_ALLOW) && | ||
316 | drm_is_control_client(file_priv))) | ||
317 | return -EACCES; | ||
318 | |||
319 | /* Render clients must be explicitly allowed */ | ||
320 | if (unlikely(!(flags & DRM_RENDER_ALLOW) && | ||
321 | drm_is_render_client(file_priv))) | ||
322 | return -EACCES; | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | /** | ||
328 | * Called whenever a process performs an ioctl on /dev/drm. | ||
329 | * | ||
330 | * \param inode device inode. | ||
331 | * \param file_priv DRM file private. | ||
332 | * \param cmd command. | ||
333 | * \param arg user argument. | ||
334 | * \return zero on success or negative number on failure. | ||
335 | * | ||
336 | * Looks up the ioctl function in the ::ioctls table, checking for root | ||
337 | * previleges if so required, and dispatches to the respective function. | ||
338 | */ | ||
339 | long drm_ioctl(struct file *filp, | ||
340 | unsigned int cmd, unsigned long arg) | ||
341 | { | ||
342 | struct drm_file *file_priv = filp->private_data; | ||
343 | struct drm_device *dev; | ||
344 | const struct drm_ioctl_desc *ioctl = NULL; | ||
345 | drm_ioctl_t *func; | ||
346 | unsigned int nr = DRM_IOCTL_NR(cmd); | ||
347 | int retcode = -EINVAL; | ||
348 | char stack_kdata[128]; | ||
349 | char *kdata = NULL; | ||
350 | unsigned int usize, asize; | ||
351 | |||
352 | dev = file_priv->minor->dev; | ||
353 | |||
354 | if (drm_device_is_unplugged(dev)) | ||
355 | return -ENODEV; | ||
356 | |||
357 | if ((nr >= DRM_CORE_IOCTL_COUNT) && | ||
358 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) | ||
359 | goto err_i1; | ||
360 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && | ||
361 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { | ||
362 | u32 drv_size; | ||
363 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; | ||
364 | drv_size = _IOC_SIZE(ioctl->cmd_drv); | ||
365 | usize = asize = _IOC_SIZE(cmd); | ||
366 | if (drv_size > asize) | ||
367 | asize = drv_size; | ||
368 | cmd = ioctl->cmd_drv; | ||
369 | } | ||
370 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { | ||
371 | u32 drv_size; | ||
372 | |||
373 | ioctl = &drm_ioctls[nr]; | ||
374 | |||
375 | drv_size = _IOC_SIZE(ioctl->cmd); | ||
376 | usize = asize = _IOC_SIZE(cmd); | ||
377 | if (drv_size > asize) | ||
378 | asize = drv_size; | ||
379 | |||
380 | cmd = ioctl->cmd; | ||
381 | } else | ||
382 | goto err_i1; | ||
383 | |||
384 | DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n", | ||
385 | task_pid_nr(current), | ||
386 | (long)old_encode_dev(file_priv->minor->kdev->devt), | ||
387 | file_priv->authenticated, ioctl->name); | ||
388 | |||
389 | /* Do not trust userspace, use our own definition */ | ||
390 | func = ioctl->func; | ||
391 | |||
392 | if (unlikely(!func)) { | ||
393 | DRM_DEBUG("no function\n"); | ||
394 | retcode = -EINVAL; | ||
395 | goto err_i1; | ||
396 | } | ||
397 | |||
398 | retcode = drm_ioctl_permit(ioctl->flags, file_priv); | ||
399 | if (unlikely(retcode)) | ||
400 | goto err_i1; | ||
401 | |||
402 | if (cmd & (IOC_IN | IOC_OUT)) { | ||
403 | if (asize <= sizeof(stack_kdata)) { | ||
404 | kdata = stack_kdata; | ||
405 | } else { | ||
406 | kdata = kmalloc(asize, GFP_KERNEL); | ||
407 | if (!kdata) { | ||
408 | retcode = -ENOMEM; | ||
409 | goto err_i1; | ||
410 | } | ||
411 | } | ||
412 | if (asize > usize) | ||
413 | memset(kdata + usize, 0, asize - usize); | ||
414 | } | ||
415 | |||
416 | if (cmd & IOC_IN) { | ||
417 | if (copy_from_user(kdata, (void __user *)arg, | ||
418 | usize) != 0) { | ||
419 | retcode = -EFAULT; | ||
420 | goto err_i1; | ||
421 | } | ||
422 | } else if (cmd & IOC_OUT) { | ||
423 | memset(kdata, 0, usize); | ||
424 | } | ||
425 | |||
426 | if (ioctl->flags & DRM_UNLOCKED) | ||
427 | retcode = func(dev, kdata, file_priv); | ||
428 | else { | ||
429 | mutex_lock(&drm_global_mutex); | ||
430 | retcode = func(dev, kdata, file_priv); | ||
431 | mutex_unlock(&drm_global_mutex); | ||
432 | } | ||
433 | |||
434 | if (cmd & IOC_OUT) { | ||
435 | if (copy_to_user((void __user *)arg, kdata, | ||
436 | usize) != 0) | ||
437 | retcode = -EFAULT; | ||
438 | } | ||
439 | |||
440 | err_i1: | ||
441 | if (!ioctl) | ||
442 | DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n", | ||
443 | task_pid_nr(current), | ||
444 | (long)old_encode_dev(file_priv->minor->kdev->devt), | ||
445 | file_priv->authenticated, cmd, nr); | ||
446 | |||
447 | if (kdata != stack_kdata) | ||
448 | kfree(kdata); | ||
449 | if (retcode) | ||
450 | DRM_DEBUG("ret = %d\n", retcode); | ||
451 | return retcode; | ||
452 | } | ||
453 | EXPORT_SYMBOL(drm_ioctl); | ||
454 | |||
455 | /** | ||
456 | * drm_ioctl_flags - Check for core ioctl and return ioctl permission flags | ||
457 | * | ||
458 | * @nr: Ioctl number. | ||
459 | * @flags: Where to return the ioctl permission flags | ||
460 | */ | ||
461 | bool drm_ioctl_flags(unsigned int nr, unsigned int *flags) | ||
462 | { | ||
463 | if ((nr >= DRM_COMMAND_END && nr < DRM_CORE_IOCTL_COUNT) || | ||
464 | (nr < DRM_COMMAND_BASE)) { | ||
465 | *flags = drm_ioctls[nr].flags; | ||
466 | return true; | ||
467 | } | ||
468 | |||
469 | return false; | ||
470 | } | ||
471 | EXPORT_SYMBOL(drm_ioctl_flags); | ||
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 8f91062db5b6..4b060942cb3c 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
41 | #include "drm_legacy.h" | ||
41 | 42 | ||
42 | /* from BKL pushdown */ | 43 | /* from BKL pushdown */ |
43 | DEFINE_MUTEX(drm_global_mutex); | 44 | DEFINE_MUTEX(drm_global_mutex); |
@@ -112,45 +113,6 @@ err_undo: | |||
112 | EXPORT_SYMBOL(drm_open); | 113 | EXPORT_SYMBOL(drm_open); |
113 | 114 | ||
114 | /** | 115 | /** |
115 | * File \c open operation. | ||
116 | * | ||
117 | * \param inode device inode. | ||
118 | * \param filp file pointer. | ||
119 | * | ||
120 | * Puts the dev->fops corresponding to the device minor number into | ||
121 | * \p filp, call the \c open method, and restore the file operations. | ||
122 | */ | ||
123 | int drm_stub_open(struct inode *inode, struct file *filp) | ||
124 | { | ||
125 | struct drm_device *dev; | ||
126 | struct drm_minor *minor; | ||
127 | int err = -ENODEV; | ||
128 | const struct file_operations *new_fops; | ||
129 | |||
130 | DRM_DEBUG("\n"); | ||
131 | |||
132 | mutex_lock(&drm_global_mutex); | ||
133 | minor = drm_minor_acquire(iminor(inode)); | ||
134 | if (IS_ERR(minor)) | ||
135 | goto out_unlock; | ||
136 | |||
137 | dev = minor->dev; | ||
138 | new_fops = fops_get(dev->driver->fops); | ||
139 | if (!new_fops) | ||
140 | goto out_release; | ||
141 | |||
142 | replace_fops(filp, new_fops); | ||
143 | if (filp->f_op->open) | ||
144 | err = filp->f_op->open(inode, filp); | ||
145 | |||
146 | out_release: | ||
147 | drm_minor_release(minor); | ||
148 | out_unlock: | ||
149 | mutex_unlock(&drm_global_mutex); | ||
150 | return err; | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * Check whether DRI will run on this CPU. | 116 | * Check whether DRI will run on this CPU. |
155 | * | 117 | * |
156 | * \return non-zero if the DRI will run on this CPU, or zero otherwise. | 118 | * \return non-zero if the DRI will run on this CPU, or zero otherwise. |
@@ -199,8 +161,7 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) | |||
199 | priv->minor = minor; | 161 | priv->minor = minor; |
200 | 162 | ||
201 | /* for compatibility root is always authenticated */ | 163 | /* for compatibility root is always authenticated */ |
202 | priv->always_authenticated = capable(CAP_SYS_ADMIN); | 164 | priv->authenticated = capable(CAP_SYS_ADMIN); |
203 | priv->authenticated = priv->always_authenticated; | ||
204 | priv->lock_count = 0; | 165 | priv->lock_count = 0; |
205 | 166 | ||
206 | INIT_LIST_HEAD(&priv->lhead); | 167 | INIT_LIST_HEAD(&priv->lhead); |
@@ -233,7 +194,6 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) | |||
233 | goto out_close; | 194 | goto out_close; |
234 | } | 195 | } |
235 | 196 | ||
236 | priv->is_master = 1; | ||
237 | /* take another reference for the copy in the local file priv */ | 197 | /* take another reference for the copy in the local file priv */ |
238 | priv->master = drm_master_get(priv->minor->master); | 198 | priv->master = drm_master_get(priv->minor->master); |
239 | priv->authenticated = 1; | 199 | priv->authenticated = 1; |
@@ -461,44 +421,18 @@ int drm_release(struct inode *inode, struct file *filp) | |||
461 | if (dev->driver->driver_features & DRIVER_GEM) | 421 | if (dev->driver->driver_features & DRIVER_GEM) |
462 | drm_gem_release(dev, file_priv); | 422 | drm_gem_release(dev, file_priv); |
463 | 423 | ||
464 | mutex_lock(&dev->ctxlist_mutex); | 424 | drm_legacy_ctxbitmap_flush(dev, file_priv); |
465 | if (!list_empty(&dev->ctxlist)) { | ||
466 | struct drm_ctx_list *pos, *n; | ||
467 | |||
468 | list_for_each_entry_safe(pos, n, &dev->ctxlist, head) { | ||
469 | if (pos->tag == file_priv && | ||
470 | pos->handle != DRM_KERNEL_CONTEXT) { | ||
471 | if (dev->driver->context_dtor) | ||
472 | dev->driver->context_dtor(dev, | ||
473 | pos->handle); | ||
474 | |||
475 | drm_ctxbitmap_free(dev, pos->handle); | ||
476 | |||
477 | list_del(&pos->head); | ||
478 | kfree(pos); | ||
479 | } | ||
480 | } | ||
481 | } | ||
482 | mutex_unlock(&dev->ctxlist_mutex); | ||
483 | 425 | ||
484 | mutex_lock(&dev->master_mutex); | 426 | mutex_lock(&dev->master_mutex); |
485 | 427 | ||
486 | if (file_priv->is_master) { | 428 | if (drm_is_master(file_priv)) { |
487 | struct drm_master *master = file_priv->master; | 429 | struct drm_master *master = file_priv->master; |
488 | struct drm_file *temp; | ||
489 | |||
490 | mutex_lock(&dev->struct_mutex); | ||
491 | list_for_each_entry(temp, &dev->filelist, lhead) { | ||
492 | if ((temp->master == file_priv->master) && | ||
493 | (temp != file_priv)) | ||
494 | temp->authenticated = temp->always_authenticated; | ||
495 | } | ||
496 | 430 | ||
497 | /** | 431 | /** |
498 | * Since the master is disappearing, so is the | 432 | * Since the master is disappearing, so is the |
499 | * possibility to lock. | 433 | * possibility to lock. |
500 | */ | 434 | */ |
501 | 435 | mutex_lock(&dev->struct_mutex); | |
502 | if (master->lock.hw_lock) { | 436 | if (master->lock.hw_lock) { |
503 | if (dev->sigdata.lock == master->lock.hw_lock) | 437 | if (dev->sigdata.lock == master->lock.hw_lock) |
504 | dev->sigdata.lock = NULL; | 438 | dev->sigdata.lock = NULL; |
@@ -519,7 +453,6 @@ int drm_release(struct inode *inode, struct file *filp) | |||
519 | /* drop the master reference held by the file priv */ | 453 | /* drop the master reference held by the file priv */ |
520 | if (file_priv->master) | 454 | if (file_priv->master) |
521 | drm_master_put(&file_priv->master); | 455 | drm_master_put(&file_priv->master); |
522 | file_priv->is_master = 0; | ||
523 | mutex_unlock(&dev->master_mutex); | 456 | mutex_unlock(&dev->master_mutex); |
524 | 457 | ||
525 | if (dev->driver->postclose) | 458 | if (dev->driver->postclose) |
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index ad66f961170e..d3d1a8c72e98 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c | |||
@@ -1,11 +1,3 @@ | |||
1 | /** | ||
2 | * \file drm_ioctl.c | ||
3 | * IOCTL processing for DRM | ||
4 | * | ||
5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> | ||
6 | * \author Gareth Hughes <gareth@valinux.com> | ||
7 | */ | ||
8 | |||
9 | /* | 1 | /* |
10 | * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com | 2 | * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com |
11 | * | 3 | * |
@@ -13,6 +5,9 @@ | |||
13 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
14 | * All Rights Reserved. | 6 | * All Rights Reserved. |
15 | * | 7 | * |
8 | * Author Rickard E. (Rik) Faith <faith@valinux.com> | ||
9 | * Author Gareth Hughes <gareth@valinux.com> | ||
10 | * | ||
16 | * Permission is hereby granted, free of charge, to any person obtaining a | 11 | * Permission is hereby granted, free of charge, to any person obtaining a |
17 | * copy of this software and associated documentation files (the "Software"), | 12 | * copy of this software and associated documentation files (the "Software"), |
18 | * to deal in the Software without restriction, including without limitation | 13 | * to deal in the Software without restriction, including without limitation |
@@ -35,6 +30,7 @@ | |||
35 | 30 | ||
36 | #include <drm/drmP.h> | 31 | #include <drm/drmP.h> |
37 | #include <drm/drm_core.h> | 32 | #include <drm/drm_core.h> |
33 | #include "drm_legacy.h" | ||
38 | 34 | ||
39 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
40 | #include <linux/export.h> | 36 | #include <linux/export.h> |
@@ -42,6 +38,124 @@ | |||
42 | #include <asm/mtrr.h> | 38 | #include <asm/mtrr.h> |
43 | #endif | 39 | #endif |
44 | 40 | ||
41 | static int drm_version(struct drm_device *dev, void *data, | ||
42 | struct drm_file *file_priv); | ||
43 | |||
44 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ | ||
45 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl} | ||
46 | |||
47 | /** Ioctl table */ | ||
48 | static const struct drm_ioctl_desc drm_ioctls[] = { | ||
49 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
50 | DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), | ||
51 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), | ||
52 | DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), | ||
53 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED), | ||
54 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED), | ||
55 | DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED), | ||
56 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
57 | DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0), | ||
58 | DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), | ||
59 | |||
60 | DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
61 | DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
62 | DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
63 | DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER), | ||
64 | |||
65 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
66 | DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH), | ||
67 | |||
68 | DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
69 | DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH), | ||
70 | |||
71 | DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY), | ||
72 | DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY), | ||
73 | |||
74 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY), | ||
75 | DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
76 | DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
77 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_legacy_getctx, DRM_AUTH), | ||
78 | DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_legacy_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
79 | DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_legacy_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
80 | DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_legacy_resctx, DRM_AUTH), | ||
81 | |||
82 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
83 | DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
84 | |||
85 | DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH), | ||
86 | DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH), | ||
87 | |||
88 | DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH), | ||
89 | |||
90 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
91 | DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
92 | DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH), | ||
93 | DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH), | ||
94 | DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH), | ||
95 | DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_dma_ioctl, DRM_AUTH), | ||
96 | |||
97 | DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
98 | |||
99 | #if __OS_HAS_AGP | ||
100 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
101 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
102 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
103 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH), | ||
104 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
105 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
106 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
107 | DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
108 | #endif | ||
109 | |||
110 | DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
111 | DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
112 | |||
113 | DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED), | ||
114 | |||
115 | DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), | ||
116 | |||
117 | DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
118 | |||
119 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
120 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), | ||
121 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), | ||
122 | |||
123 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
124 | |||
125 | DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
126 | DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
127 | |||
128 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
129 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
130 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
131 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
132 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
133 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
134 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED), | ||
135 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), | ||
136 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
137 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
138 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
139 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
140 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
141 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
142 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
143 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
144 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
145 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
146 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
147 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
148 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
149 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
150 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
151 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
152 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
153 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
154 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
155 | }; | ||
156 | |||
157 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) | ||
158 | |||
45 | /** | 159 | /** |
46 | * Get the bus id. | 160 | * Get the bus id. |
47 | * | 161 | * |
@@ -415,3 +529,243 @@ int drm_noop(struct drm_device *dev, void *data, | |||
415 | return 0; | 529 | return 0; |
416 | } | 530 | } |
417 | EXPORT_SYMBOL(drm_noop); | 531 | EXPORT_SYMBOL(drm_noop); |
532 | |||
533 | /** | ||
534 | * Copy and IOCTL return string to user space | ||
535 | */ | ||
536 | static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value) | ||
537 | { | ||
538 | int len; | ||
539 | |||
540 | /* don't overflow userbuf */ | ||
541 | len = strlen(value); | ||
542 | if (len > *buf_len) | ||
543 | len = *buf_len; | ||
544 | |||
545 | /* let userspace know exact length of driver value (which could be | ||
546 | * larger than the userspace-supplied buffer) */ | ||
547 | *buf_len = strlen(value); | ||
548 | |||
549 | /* finally, try filling in the userbuf */ | ||
550 | if (len && buf) | ||
551 | if (copy_to_user(buf, value, len)) | ||
552 | return -EFAULT; | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | /** | ||
557 | * Get version information | ||
558 | * | ||
559 | * \param inode device inode. | ||
560 | * \param filp file pointer. | ||
561 | * \param cmd command. | ||
562 | * \param arg user argument, pointing to a drm_version structure. | ||
563 | * \return zero on success or negative number on failure. | ||
564 | * | ||
565 | * Fills in the version information in \p arg. | ||
566 | */ | ||
567 | static int drm_version(struct drm_device *dev, void *data, | ||
568 | struct drm_file *file_priv) | ||
569 | { | ||
570 | struct drm_version *version = data; | ||
571 | int err; | ||
572 | |||
573 | version->version_major = dev->driver->major; | ||
574 | version->version_minor = dev->driver->minor; | ||
575 | version->version_patchlevel = dev->driver->patchlevel; | ||
576 | err = drm_copy_field(version->name, &version->name_len, | ||
577 | dev->driver->name); | ||
578 | if (!err) | ||
579 | err = drm_copy_field(version->date, &version->date_len, | ||
580 | dev->driver->date); | ||
581 | if (!err) | ||
582 | err = drm_copy_field(version->desc, &version->desc_len, | ||
583 | dev->driver->desc); | ||
584 | |||
585 | return err; | ||
586 | } | ||
587 | |||
588 | /** | ||
589 | * drm_ioctl_permit - Check ioctl permissions against caller | ||
590 | * | ||
591 | * @flags: ioctl permission flags. | ||
592 | * @file_priv: Pointer to struct drm_file identifying the caller. | ||
593 | * | ||
594 | * Checks whether the caller is allowed to run an ioctl with the | ||
595 | * indicated permissions. If so, returns zero. Otherwise returns an | ||
596 | * error code suitable for ioctl return. | ||
597 | */ | ||
598 | static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv) | ||
599 | { | ||
600 | /* ROOT_ONLY is only for CAP_SYS_ADMIN */ | ||
601 | if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN))) | ||
602 | return -EACCES; | ||
603 | |||
604 | /* AUTH is only for authenticated or render client */ | ||
605 | if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) && | ||
606 | !file_priv->authenticated)) | ||
607 | return -EACCES; | ||
608 | |||
609 | /* MASTER is only for master or control clients */ | ||
610 | if (unlikely((flags & DRM_MASTER) && !drm_is_master(file_priv) && | ||
611 | !drm_is_control_client(file_priv))) | ||
612 | return -EACCES; | ||
613 | |||
614 | /* Control clients must be explicitly allowed */ | ||
615 | if (unlikely(!(flags & DRM_CONTROL_ALLOW) && | ||
616 | drm_is_control_client(file_priv))) | ||
617 | return -EACCES; | ||
618 | |||
619 | /* Render clients must be explicitly allowed */ | ||
620 | if (unlikely(!(flags & DRM_RENDER_ALLOW) && | ||
621 | drm_is_render_client(file_priv))) | ||
622 | return -EACCES; | ||
623 | |||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | /** | ||
628 | * Called whenever a process performs an ioctl on /dev/drm. | ||
629 | * | ||
630 | * \param inode device inode. | ||
631 | * \param file_priv DRM file private. | ||
632 | * \param cmd command. | ||
633 | * \param arg user argument. | ||
634 | * \return zero on success or negative number on failure. | ||
635 | * | ||
636 | * Looks up the ioctl function in the ::ioctls table, checking for root | ||
637 | * previleges if so required, and dispatches to the respective function. | ||
638 | */ | ||
639 | long drm_ioctl(struct file *filp, | ||
640 | unsigned int cmd, unsigned long arg) | ||
641 | { | ||
642 | struct drm_file *file_priv = filp->private_data; | ||
643 | struct drm_device *dev; | ||
644 | const struct drm_ioctl_desc *ioctl = NULL; | ||
645 | drm_ioctl_t *func; | ||
646 | unsigned int nr = DRM_IOCTL_NR(cmd); | ||
647 | int retcode = -EINVAL; | ||
648 | char stack_kdata[128]; | ||
649 | char *kdata = NULL; | ||
650 | unsigned int usize, asize; | ||
651 | |||
652 | dev = file_priv->minor->dev; | ||
653 | |||
654 | if (drm_device_is_unplugged(dev)) | ||
655 | return -ENODEV; | ||
656 | |||
657 | if ((nr >= DRM_CORE_IOCTL_COUNT) && | ||
658 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) | ||
659 | goto err_i1; | ||
660 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && | ||
661 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { | ||
662 | u32 drv_size; | ||
663 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; | ||
664 | drv_size = _IOC_SIZE(ioctl->cmd_drv); | ||
665 | usize = asize = _IOC_SIZE(cmd); | ||
666 | if (drv_size > asize) | ||
667 | asize = drv_size; | ||
668 | cmd = ioctl->cmd_drv; | ||
669 | } | ||
670 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { | ||
671 | u32 drv_size; | ||
672 | |||
673 | ioctl = &drm_ioctls[nr]; | ||
674 | |||
675 | drv_size = _IOC_SIZE(ioctl->cmd); | ||
676 | usize = asize = _IOC_SIZE(cmd); | ||
677 | if (drv_size > asize) | ||
678 | asize = drv_size; | ||
679 | |||
680 | cmd = ioctl->cmd; | ||
681 | } else | ||
682 | goto err_i1; | ||
683 | |||
684 | DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n", | ||
685 | task_pid_nr(current), | ||
686 | (long)old_encode_dev(file_priv->minor->kdev->devt), | ||
687 | file_priv->authenticated, ioctl->name); | ||
688 | |||
689 | /* Do not trust userspace, use our own definition */ | ||
690 | func = ioctl->func; | ||
691 | |||
692 | if (unlikely(!func)) { | ||
693 | DRM_DEBUG("no function\n"); | ||
694 | retcode = -EINVAL; | ||
695 | goto err_i1; | ||
696 | } | ||
697 | |||
698 | retcode = drm_ioctl_permit(ioctl->flags, file_priv); | ||
699 | if (unlikely(retcode)) | ||
700 | goto err_i1; | ||
701 | |||
702 | if (cmd & (IOC_IN | IOC_OUT)) { | ||
703 | if (asize <= sizeof(stack_kdata)) { | ||
704 | kdata = stack_kdata; | ||
705 | } else { | ||
706 | kdata = kmalloc(asize, GFP_KERNEL); | ||
707 | if (!kdata) { | ||
708 | retcode = -ENOMEM; | ||
709 | goto err_i1; | ||
710 | } | ||
711 | } | ||
712 | if (asize > usize) | ||
713 | memset(kdata + usize, 0, asize - usize); | ||
714 | } | ||
715 | |||
716 | if (cmd & IOC_IN) { | ||
717 | if (copy_from_user(kdata, (void __user *)arg, | ||
718 | usize) != 0) { | ||
719 | retcode = -EFAULT; | ||
720 | goto err_i1; | ||
721 | } | ||
722 | } else if (cmd & IOC_OUT) { | ||
723 | memset(kdata, 0, usize); | ||
724 | } | ||
725 | |||
726 | if (ioctl->flags & DRM_UNLOCKED) | ||
727 | retcode = func(dev, kdata, file_priv); | ||
728 | else { | ||
729 | mutex_lock(&drm_global_mutex); | ||
730 | retcode = func(dev, kdata, file_priv); | ||
731 | mutex_unlock(&drm_global_mutex); | ||
732 | } | ||
733 | |||
734 | if (cmd & IOC_OUT) { | ||
735 | if (copy_to_user((void __user *)arg, kdata, | ||
736 | usize) != 0) | ||
737 | retcode = -EFAULT; | ||
738 | } | ||
739 | |||
740 | err_i1: | ||
741 | if (!ioctl) | ||
742 | DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n", | ||
743 | task_pid_nr(current), | ||
744 | (long)old_encode_dev(file_priv->minor->kdev->devt), | ||
745 | file_priv->authenticated, cmd, nr); | ||
746 | |||
747 | if (kdata != stack_kdata) | ||
748 | kfree(kdata); | ||
749 | if (retcode) | ||
750 | DRM_DEBUG("ret = %d\n", retcode); | ||
751 | return retcode; | ||
752 | } | ||
753 | EXPORT_SYMBOL(drm_ioctl); | ||
754 | |||
755 | /** | ||
756 | * drm_ioctl_flags - Check for core ioctl and return ioctl permission flags | ||
757 | * | ||
758 | * @nr: Ioctl number. | ||
759 | * @flags: Where to return the ioctl permission flags | ||
760 | */ | ||
761 | bool drm_ioctl_flags(unsigned int nr, unsigned int *flags) | ||
762 | { | ||
763 | if ((nr >= DRM_COMMAND_END && nr < DRM_CORE_IOCTL_COUNT) || | ||
764 | (nr < DRM_COMMAND_BASE)) { | ||
765 | *flags = drm_ioctls[nr].flags; | ||
766 | return true; | ||
767 | } | ||
768 | |||
769 | return false; | ||
770 | } | ||
771 | EXPORT_SYMBOL(drm_ioctl_flags); | ||
diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h new file mode 100644 index 000000000000..d34f20a79b7c --- /dev/null +++ b/drivers/gpu/drm/drm_legacy.h | |||
@@ -0,0 +1,51 @@ | |||
1 | #ifndef __DRM_LEGACY_H__ | ||
2 | #define __DRM_LEGACY_H__ | ||
3 | |||
4 | /* | ||
5 | * Copyright (c) 2014 David Herrmann <dh.herrmann@gmail.com> | ||
6 | * | ||
7 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
8 | * copy of this software and associated documentation files (the "Software"), | ||
9 | * to deal in the Software without restriction, including without limitation | ||
10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
11 | * and/or sell copies of the Software, and to permit persons to whom the | ||
12 | * Software is furnished to do so, subject to the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice shall be included in | ||
15 | * all copies or substantial portions of the Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
20 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
23 | * OTHER DEALINGS IN THE SOFTWARE. | ||
24 | */ | ||
25 | |||
26 | struct drm_device; | ||
27 | struct drm_file; | ||
28 | |||
29 | /* | ||
30 | * Generic DRM Contexts | ||
31 | */ | ||
32 | |||
33 | #define DRM_KERNEL_CONTEXT 0 | ||
34 | #define DRM_RESERVED_CONTEXTS 1 | ||
35 | |||
36 | int drm_legacy_ctxbitmap_init(struct drm_device *dev); | ||
37 | void drm_legacy_ctxbitmap_cleanup(struct drm_device *dev); | ||
38 | void drm_legacy_ctxbitmap_free(struct drm_device *dev, int ctx_handle); | ||
39 | void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file); | ||
40 | |||
41 | int drm_legacy_resctx(struct drm_device *d, void *v, struct drm_file *f); | ||
42 | int drm_legacy_addctx(struct drm_device *d, void *v, struct drm_file *f); | ||
43 | int drm_legacy_getctx(struct drm_device *d, void *v, struct drm_file *f); | ||
44 | int drm_legacy_switchctx(struct drm_device *d, void *v, struct drm_file *f); | ||
45 | int drm_legacy_newctx(struct drm_device *d, void *v, struct drm_file *f); | ||
46 | int drm_legacy_rmctx(struct drm_device *d, void *v, struct drm_file *f); | ||
47 | |||
48 | int drm_legacy_setsareactx(struct drm_device *d, void *v, struct drm_file *f); | ||
49 | int drm_legacy_getsareactx(struct drm_device *d, void *v, struct drm_file *f); | ||
50 | |||
51 | #endif /* __DRM_LEGACY_H__ */ | ||
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index f6452682141b..ea1572596578 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include <linux/export.h> | 36 | #include <linux/export.h> |
37 | #include <drm/drmP.h> | 37 | #include <drm/drmP.h> |
38 | #include "drm_legacy.h" | ||
38 | 39 | ||
39 | static int drm_notifier(void *priv); | 40 | static int drm_notifier(void *priv); |
40 | 41 | ||
@@ -111,7 +112,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
111 | /* don't set the block all signals on the master process for now | 112 | /* don't set the block all signals on the master process for now |
112 | * really probably not the correct answer but lets us debug xkb | 113 | * really probably not the correct answer but lets us debug xkb |
113 | * xserver for now */ | 114 | * xserver for now */ |
114 | if (!file_priv->is_master) { | 115 | if (!drm_is_master(file_priv)) { |
115 | sigemptyset(&dev->sigmask); | 116 | sigemptyset(&dev->sigmask); |
116 | sigaddset(&dev->sigmask, SIGSTOP); | 117 | sigaddset(&dev->sigmask, SIGSTOP); |
117 | sigaddset(&dev->sigmask, SIGTSTP); | 118 | sigaddset(&dev->sigmask, SIGTSTP); |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 233ea208c9fe..92bc6b1d9646 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -26,6 +26,7 @@ | |||
26 | * DEALINGS IN THE SOFTWARE. | 26 | * DEALINGS IN THE SOFTWARE. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/debugfs.h> | ||
29 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
31 | #include <linux/moduleparam.h> | 32 | #include <linux/moduleparam.h> |
@@ -33,6 +34,7 @@ | |||
33 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
34 | #include <drm/drmP.h> | 35 | #include <drm/drmP.h> |
35 | #include <drm/drm_core.h> | 36 | #include <drm/drm_core.h> |
37 | #include "drm_legacy.h" | ||
36 | 38 | ||
37 | unsigned int drm_debug = 0; /* 1 to enable debug output */ | 39 | unsigned int drm_debug = 0; /* 1 to enable debug output */ |
38 | EXPORT_SYMBOL(drm_debug); | 40 | EXPORT_SYMBOL(drm_debug); |
@@ -61,10 +63,10 @@ module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600) | |||
61 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); | 63 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); |
62 | 64 | ||
63 | static DEFINE_SPINLOCK(drm_minor_lock); | 65 | static DEFINE_SPINLOCK(drm_minor_lock); |
64 | struct idr drm_minors_idr; | 66 | static struct idr drm_minors_idr; |
65 | 67 | ||
66 | struct class *drm_class; | 68 | struct class *drm_class; |
67 | struct dentry *drm_debugfs_root; | 69 | static struct dentry *drm_debugfs_root; |
68 | 70 | ||
69 | int drm_err(const char *func, const char *format, ...) | 71 | int drm_err(const char *func, const char *format, ...) |
70 | { | 72 | { |
@@ -177,7 +179,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, | |||
177 | int ret = 0; | 179 | int ret = 0; |
178 | 180 | ||
179 | mutex_lock(&dev->master_mutex); | 181 | mutex_lock(&dev->master_mutex); |
180 | if (file_priv->is_master) | 182 | if (drm_is_master(file_priv)) |
181 | goto out_unlock; | 183 | goto out_unlock; |
182 | 184 | ||
183 | if (file_priv->minor->master) { | 185 | if (file_priv->minor->master) { |
@@ -191,13 +193,10 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, | |||
191 | } | 193 | } |
192 | 194 | ||
193 | file_priv->minor->master = drm_master_get(file_priv->master); | 195 | file_priv->minor->master = drm_master_get(file_priv->master); |
194 | file_priv->is_master = 1; | ||
195 | if (dev->driver->master_set) { | 196 | if (dev->driver->master_set) { |
196 | ret = dev->driver->master_set(dev, file_priv, false); | 197 | ret = dev->driver->master_set(dev, file_priv, false); |
197 | if (unlikely(ret != 0)) { | 198 | if (unlikely(ret != 0)) |
198 | file_priv->is_master = 0; | ||
199 | drm_master_put(&file_priv->minor->master); | 199 | drm_master_put(&file_priv->minor->master); |
200 | } | ||
201 | } | 200 | } |
202 | 201 | ||
203 | out_unlock: | 202 | out_unlock: |
@@ -211,7 +210,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | |||
211 | int ret = -EINVAL; | 210 | int ret = -EINVAL; |
212 | 211 | ||
213 | mutex_lock(&dev->master_mutex); | 212 | mutex_lock(&dev->master_mutex); |
214 | if (!file_priv->is_master) | 213 | if (!drm_is_master(file_priv)) |
215 | goto out_unlock; | 214 | goto out_unlock; |
216 | 215 | ||
217 | if (!file_priv->minor->master) | 216 | if (!file_priv->minor->master) |
@@ -221,7 +220,6 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | |||
221 | if (dev->driver->master_drop) | 220 | if (dev->driver->master_drop) |
222 | dev->driver->master_drop(dev, file_priv, false); | 221 | dev->driver->master_drop(dev, file_priv, false); |
223 | drm_master_put(&file_priv->minor->master); | 222 | drm_master_put(&file_priv->minor->master); |
224 | file_priv->is_master = 0; | ||
225 | 223 | ||
226 | out_unlock: | 224 | out_unlock: |
227 | mutex_unlock(&dev->master_mutex); | 225 | mutex_unlock(&dev->master_mutex); |
@@ -259,6 +257,8 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev, | |||
259 | static int drm_minor_alloc(struct drm_device *dev, unsigned int type) | 257 | static int drm_minor_alloc(struct drm_device *dev, unsigned int type) |
260 | { | 258 | { |
261 | struct drm_minor *minor; | 259 | struct drm_minor *minor; |
260 | unsigned long flags; | ||
261 | int r; | ||
262 | 262 | ||
263 | minor = kzalloc(sizeof(*minor), GFP_KERNEL); | 263 | minor = kzalloc(sizeof(*minor), GFP_KERNEL); |
264 | if (!minor) | 264 | if (!minor) |
@@ -267,77 +267,92 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type) | |||
267 | minor->type = type; | 267 | minor->type = type; |
268 | minor->dev = dev; | 268 | minor->dev = dev; |
269 | 269 | ||
270 | idr_preload(GFP_KERNEL); | ||
271 | spin_lock_irqsave(&drm_minor_lock, flags); | ||
272 | r = idr_alloc(&drm_minors_idr, | ||
273 | NULL, | ||
274 | 64 * type, | ||
275 | 64 * (type + 1), | ||
276 | GFP_NOWAIT); | ||
277 | spin_unlock_irqrestore(&drm_minor_lock, flags); | ||
278 | idr_preload_end(); | ||
279 | |||
280 | if (r < 0) | ||
281 | goto err_free; | ||
282 | |||
283 | minor->index = r; | ||
284 | |||
285 | minor->kdev = drm_sysfs_minor_alloc(minor); | ||
286 | if (IS_ERR(minor->kdev)) { | ||
287 | r = PTR_ERR(minor->kdev); | ||
288 | goto err_index; | ||
289 | } | ||
290 | |||
270 | *drm_minor_get_slot(dev, type) = minor; | 291 | *drm_minor_get_slot(dev, type) = minor; |
271 | return 0; | 292 | return 0; |
293 | |||
294 | err_index: | ||
295 | spin_lock_irqsave(&drm_minor_lock, flags); | ||
296 | idr_remove(&drm_minors_idr, minor->index); | ||
297 | spin_unlock_irqrestore(&drm_minor_lock, flags); | ||
298 | err_free: | ||
299 | kfree(minor); | ||
300 | return r; | ||
272 | } | 301 | } |
273 | 302 | ||
274 | static void drm_minor_free(struct drm_device *dev, unsigned int type) | 303 | static void drm_minor_free(struct drm_device *dev, unsigned int type) |
275 | { | 304 | { |
276 | struct drm_minor **slot; | 305 | struct drm_minor **slot, *minor; |
306 | unsigned long flags; | ||
277 | 307 | ||
278 | slot = drm_minor_get_slot(dev, type); | 308 | slot = drm_minor_get_slot(dev, type); |
279 | if (*slot) { | 309 | minor = *slot; |
280 | drm_mode_group_destroy(&(*slot)->mode_group); | 310 | if (!minor) |
281 | kfree(*slot); | 311 | return; |
282 | *slot = NULL; | 312 | |
283 | } | 313 | drm_mode_group_destroy(&minor->mode_group); |
314 | put_device(minor->kdev); | ||
315 | |||
316 | spin_lock_irqsave(&drm_minor_lock, flags); | ||
317 | idr_remove(&drm_minors_idr, minor->index); | ||
318 | spin_unlock_irqrestore(&drm_minor_lock, flags); | ||
319 | |||
320 | kfree(minor); | ||
321 | *slot = NULL; | ||
284 | } | 322 | } |
285 | 323 | ||
286 | static int drm_minor_register(struct drm_device *dev, unsigned int type) | 324 | static int drm_minor_register(struct drm_device *dev, unsigned int type) |
287 | { | 325 | { |
288 | struct drm_minor *new_minor; | 326 | struct drm_minor *minor; |
289 | unsigned long flags; | 327 | unsigned long flags; |
290 | int ret; | 328 | int ret; |
291 | int minor_id; | ||
292 | 329 | ||
293 | DRM_DEBUG("\n"); | 330 | DRM_DEBUG("\n"); |
294 | 331 | ||
295 | new_minor = *drm_minor_get_slot(dev, type); | 332 | minor = *drm_minor_get_slot(dev, type); |
296 | if (!new_minor) | 333 | if (!minor) |
297 | return 0; | 334 | return 0; |
298 | 335 | ||
299 | idr_preload(GFP_KERNEL); | 336 | ret = drm_debugfs_init(minor, minor->index, drm_debugfs_root); |
300 | spin_lock_irqsave(&drm_minor_lock, flags); | ||
301 | minor_id = idr_alloc(&drm_minors_idr, | ||
302 | NULL, | ||
303 | 64 * type, | ||
304 | 64 * (type + 1), | ||
305 | GFP_NOWAIT); | ||
306 | spin_unlock_irqrestore(&drm_minor_lock, flags); | ||
307 | idr_preload_end(); | ||
308 | |||
309 | if (minor_id < 0) | ||
310 | return minor_id; | ||
311 | |||
312 | new_minor->index = minor_id; | ||
313 | |||
314 | ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root); | ||
315 | if (ret) { | 337 | if (ret) { |
316 | DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n"); | 338 | DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n"); |
317 | goto err_id; | 339 | return ret; |
318 | } | 340 | } |
319 | 341 | ||
320 | ret = drm_sysfs_device_add(new_minor); | 342 | ret = device_add(minor->kdev); |
321 | if (ret) { | 343 | if (ret) |
322 | DRM_ERROR("DRM: Error sysfs_device_add.\n"); | ||
323 | goto err_debugfs; | 344 | goto err_debugfs; |
324 | } | ||
325 | 345 | ||
326 | /* replace NULL with @minor so lookups will succeed from now on */ | 346 | /* replace NULL with @minor so lookups will succeed from now on */ |
327 | spin_lock_irqsave(&drm_minor_lock, flags); | 347 | spin_lock_irqsave(&drm_minor_lock, flags); |
328 | idr_replace(&drm_minors_idr, new_minor, new_minor->index); | 348 | idr_replace(&drm_minors_idr, minor, minor->index); |
329 | spin_unlock_irqrestore(&drm_minor_lock, flags); | 349 | spin_unlock_irqrestore(&drm_minor_lock, flags); |
330 | 350 | ||
331 | DRM_DEBUG("new minor assigned %d\n", minor_id); | 351 | DRM_DEBUG("new minor registered %d\n", minor->index); |
332 | return 0; | 352 | return 0; |
333 | 353 | ||
334 | err_debugfs: | 354 | err_debugfs: |
335 | drm_debugfs_cleanup(new_minor); | 355 | drm_debugfs_cleanup(minor); |
336 | err_id: | ||
337 | spin_lock_irqsave(&drm_minor_lock, flags); | ||
338 | idr_remove(&drm_minors_idr, minor_id); | ||
339 | spin_unlock_irqrestore(&drm_minor_lock, flags); | ||
340 | new_minor->index = 0; | ||
341 | return ret; | 356 | return ret; |
342 | } | 357 | } |
343 | 358 | ||
@@ -347,16 +362,17 @@ static void drm_minor_unregister(struct drm_device *dev, unsigned int type) | |||
347 | unsigned long flags; | 362 | unsigned long flags; |
348 | 363 | ||
349 | minor = *drm_minor_get_slot(dev, type); | 364 | minor = *drm_minor_get_slot(dev, type); |
350 | if (!minor || !minor->kdev) | 365 | if (!minor || !device_is_registered(minor->kdev)) |
351 | return; | 366 | return; |
352 | 367 | ||
368 | /* replace @minor with NULL so lookups will fail from now on */ | ||
353 | spin_lock_irqsave(&drm_minor_lock, flags); | 369 | spin_lock_irqsave(&drm_minor_lock, flags); |
354 | idr_remove(&drm_minors_idr, minor->index); | 370 | idr_replace(&drm_minors_idr, NULL, minor->index); |
355 | spin_unlock_irqrestore(&drm_minor_lock, flags); | 371 | spin_unlock_irqrestore(&drm_minor_lock, flags); |
356 | minor->index = 0; | ||
357 | 372 | ||
373 | device_del(minor->kdev); | ||
374 | dev_set_drvdata(minor->kdev, NULL); /* safety belt */ | ||
358 | drm_debugfs_cleanup(minor); | 375 | drm_debugfs_cleanup(minor); |
359 | drm_sysfs_device_remove(minor); | ||
360 | } | 376 | } |
361 | 377 | ||
362 | /** | 378 | /** |
@@ -589,7 +605,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver, | |||
589 | if (drm_ht_create(&dev->map_hash, 12)) | 605 | if (drm_ht_create(&dev->map_hash, 12)) |
590 | goto err_minors; | 606 | goto err_minors; |
591 | 607 | ||
592 | ret = drm_ctxbitmap_init(dev); | 608 | ret = drm_legacy_ctxbitmap_init(dev); |
593 | if (ret) { | 609 | if (ret) { |
594 | DRM_ERROR("Cannot allocate memory for context bitmap.\n"); | 610 | DRM_ERROR("Cannot allocate memory for context bitmap.\n"); |
595 | goto err_ht; | 611 | goto err_ht; |
@@ -606,7 +622,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver, | |||
606 | return dev; | 622 | return dev; |
607 | 623 | ||
608 | err_ctxbitmap: | 624 | err_ctxbitmap: |
609 | drm_ctxbitmap_cleanup(dev); | 625 | drm_legacy_ctxbitmap_cleanup(dev); |
610 | err_ht: | 626 | err_ht: |
611 | drm_ht_remove(&dev->map_hash); | 627 | drm_ht_remove(&dev->map_hash); |
612 | err_minors: | 628 | err_minors: |
@@ -628,7 +644,7 @@ static void drm_dev_release(struct kref *ref) | |||
628 | if (dev->driver->driver_features & DRIVER_GEM) | 644 | if (dev->driver->driver_features & DRIVER_GEM) |
629 | drm_gem_destroy(dev); | 645 | drm_gem_destroy(dev); |
630 | 646 | ||
631 | drm_ctxbitmap_cleanup(dev); | 647 | drm_legacy_ctxbitmap_cleanup(dev); |
632 | drm_ht_remove(&dev->map_hash); | 648 | drm_ht_remove(&dev->map_hash); |
633 | drm_fs_inode_free(dev->anon_inode); | 649 | drm_fs_inode_free(dev->anon_inode); |
634 | 650 | ||
@@ -791,3 +807,115 @@ int drm_dev_set_unique(struct drm_device *dev, const char *fmt, ...) | |||
791 | return dev->unique ? 0 : -ENOMEM; | 807 | return dev->unique ? 0 : -ENOMEM; |
792 | } | 808 | } |
793 | EXPORT_SYMBOL(drm_dev_set_unique); | 809 | EXPORT_SYMBOL(drm_dev_set_unique); |
810 | |||
811 | /* | ||
812 | * DRM Core | ||
813 | * The DRM core module initializes all global DRM objects and makes them | ||
814 | * available to drivers. Once setup, drivers can probe their respective | ||
815 | * devices. | ||
816 | * Currently, core management includes: | ||
817 | * - The "DRM-Global" key/value database | ||
818 | * - Global ID management for connectors | ||
819 | * - DRM major number allocation | ||
820 | * - DRM minor management | ||
821 | * - DRM sysfs class | ||
822 | * - DRM debugfs root | ||
823 | * | ||
824 | * Furthermore, the DRM core provides dynamic char-dev lookups. For each | ||
825 | * interface registered on a DRM device, you can request minor numbers from DRM | ||
826 | * core. DRM core takes care of major-number management and char-dev | ||
827 | * registration. A stub ->open() callback forwards any open() requests to the | ||
828 | * registered minor. | ||
829 | */ | ||
830 | |||
831 | static int drm_stub_open(struct inode *inode, struct file *filp) | ||
832 | { | ||
833 | const struct file_operations *new_fops; | ||
834 | struct drm_minor *minor; | ||
835 | int err; | ||
836 | |||
837 | DRM_DEBUG("\n"); | ||
838 | |||
839 | mutex_lock(&drm_global_mutex); | ||
840 | minor = drm_minor_acquire(iminor(inode)); | ||
841 | if (IS_ERR(minor)) { | ||
842 | err = PTR_ERR(minor); | ||
843 | goto out_unlock; | ||
844 | } | ||
845 | |||
846 | new_fops = fops_get(minor->dev->driver->fops); | ||
847 | if (!new_fops) { | ||
848 | err = -ENODEV; | ||
849 | goto out_release; | ||
850 | } | ||
851 | |||
852 | replace_fops(filp, new_fops); | ||
853 | if (filp->f_op->open) | ||
854 | err = filp->f_op->open(inode, filp); | ||
855 | else | ||
856 | err = 0; | ||
857 | |||
858 | out_release: | ||
859 | drm_minor_release(minor); | ||
860 | out_unlock: | ||
861 | mutex_unlock(&drm_global_mutex); | ||
862 | return err; | ||
863 | } | ||
864 | |||
865 | static const struct file_operations drm_stub_fops = { | ||
866 | .owner = THIS_MODULE, | ||
867 | .open = drm_stub_open, | ||
868 | .llseek = noop_llseek, | ||
869 | }; | ||
870 | |||
871 | static int __init drm_core_init(void) | ||
872 | { | ||
873 | int ret = -ENOMEM; | ||
874 | |||
875 | drm_global_init(); | ||
876 | drm_connector_ida_init(); | ||
877 | idr_init(&drm_minors_idr); | ||
878 | |||
879 | if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) | ||
880 | goto err_p1; | ||
881 | |||
882 | drm_class = drm_sysfs_create(THIS_MODULE, "drm"); | ||
883 | if (IS_ERR(drm_class)) { | ||
884 | printk(KERN_ERR "DRM: Error creating drm class.\n"); | ||
885 | ret = PTR_ERR(drm_class); | ||
886 | goto err_p2; | ||
887 | } | ||
888 | |||
889 | drm_debugfs_root = debugfs_create_dir("dri", NULL); | ||
890 | if (!drm_debugfs_root) { | ||
891 | DRM_ERROR("Cannot create /sys/kernel/debug/dri\n"); | ||
892 | ret = -1; | ||
893 | goto err_p3; | ||
894 | } | ||
895 | |||
896 | DRM_INFO("Initialized %s %d.%d.%d %s\n", | ||
897 | CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); | ||
898 | return 0; | ||
899 | err_p3: | ||
900 | drm_sysfs_destroy(); | ||
901 | err_p2: | ||
902 | unregister_chrdev(DRM_MAJOR, "drm"); | ||
903 | |||
904 | idr_destroy(&drm_minors_idr); | ||
905 | err_p1: | ||
906 | return ret; | ||
907 | } | ||
908 | |||
909 | static void __exit drm_core_exit(void) | ||
910 | { | ||
911 | debugfs_remove(drm_debugfs_root); | ||
912 | drm_sysfs_destroy(); | ||
913 | |||
914 | unregister_chrdev(DRM_MAJOR, "drm"); | ||
915 | |||
916 | drm_connector_ida_destroy(); | ||
917 | idr_destroy(&drm_minors_idr); | ||
918 | } | ||
919 | |||
920 | module_init(drm_core_init); | ||
921 | module_exit(drm_core_exit); | ||
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 7827dad8fcf4..ab1a5f6dde8a 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -493,71 +493,55 @@ static void drm_sysfs_release(struct device *dev) | |||
493 | } | 493 | } |
494 | 494 | ||
495 | /** | 495 | /** |
496 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver | 496 | * drm_sysfs_minor_alloc() - Allocate sysfs device for given minor |
497 | * @dev: DRM device to be added | 497 | * @minor: minor to allocate sysfs device for |
498 | * @head: DRM head in question | ||
499 | * | 498 | * |
500 | * Add a DRM device to the DRM's device model class. We use @dev's PCI device | 499 | * This allocates a new sysfs device for @minor and returns it. The device is |
501 | * as the parent for the Linux device, and make sure it has a file containing | 500 | * not registered nor linked. The caller has to use device_add() and |
502 | * the driver we're using (for userspace compatibility). | 501 | * device_del() to register and unregister it. |
502 | * | ||
503 | * Note that dev_get_drvdata() on the new device will return the minor. | ||
504 | * However, the device does not hold a ref-count to the minor nor to the | ||
505 | * underlying drm_device. This is unproblematic as long as you access the | ||
506 | * private data only in sysfs callbacks. device_del() disables those | ||
507 | * synchronously, so they cannot be called after you cleanup a minor. | ||
503 | */ | 508 | */ |
504 | int drm_sysfs_device_add(struct drm_minor *minor) | 509 | struct device *drm_sysfs_minor_alloc(struct drm_minor *minor) |
505 | { | 510 | { |
506 | char *minor_str; | 511 | const char *minor_str; |
512 | struct device *kdev; | ||
507 | int r; | 513 | int r; |
508 | 514 | ||
509 | if (minor->type == DRM_MINOR_CONTROL) | 515 | if (minor->type == DRM_MINOR_CONTROL) |
510 | minor_str = "controlD%d"; | 516 | minor_str = "controlD%d"; |
511 | else if (minor->type == DRM_MINOR_RENDER) | 517 | else if (minor->type == DRM_MINOR_RENDER) |
512 | minor_str = "renderD%d"; | 518 | minor_str = "renderD%d"; |
513 | else | 519 | else |
514 | minor_str = "card%d"; | 520 | minor_str = "card%d"; |
515 | 521 | ||
516 | minor->kdev = kzalloc(sizeof(*minor->kdev), GFP_KERNEL); | 522 | kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); |
517 | if (!minor->kdev) { | 523 | if (!kdev) |
518 | r = -ENOMEM; | 524 | return ERR_PTR(-ENOMEM); |
519 | goto error; | 525 | |
520 | } | 526 | device_initialize(kdev); |
521 | 527 | kdev->devt = MKDEV(DRM_MAJOR, minor->index); | |
522 | device_initialize(minor->kdev); | 528 | kdev->class = drm_class; |
523 | minor->kdev->devt = MKDEV(DRM_MAJOR, minor->index); | 529 | kdev->type = &drm_sysfs_device_minor; |
524 | minor->kdev->class = drm_class; | 530 | kdev->parent = minor->dev->dev; |
525 | minor->kdev->type = &drm_sysfs_device_minor; | 531 | kdev->release = drm_sysfs_release; |
526 | minor->kdev->parent = minor->dev->dev; | 532 | dev_set_drvdata(kdev, minor); |
527 | minor->kdev->release = drm_sysfs_release; | 533 | |
528 | dev_set_drvdata(minor->kdev, minor); | 534 | r = dev_set_name(kdev, minor_str, minor->index); |
529 | |||
530 | r = dev_set_name(minor->kdev, minor_str, minor->index); | ||
531 | if (r < 0) | 535 | if (r < 0) |
532 | goto error; | 536 | goto err_free; |
533 | |||
534 | r = device_add(minor->kdev); | ||
535 | if (r < 0) | ||
536 | goto error; | ||
537 | |||
538 | return 0; | ||
539 | 537 | ||
540 | error: | 538 | return kdev; |
541 | DRM_ERROR("device create failed %d\n", r); | ||
542 | put_device(minor->kdev); | ||
543 | return r; | ||
544 | } | ||
545 | 539 | ||
546 | /** | 540 | err_free: |
547 | * drm_sysfs_device_remove - remove DRM device | 541 | put_device(kdev); |
548 | * @dev: DRM device to remove | 542 | return ERR_PTR(r); |
549 | * | ||
550 | * This call unregisters and cleans up a class device that was created with a | ||
551 | * call to drm_sysfs_device_add() | ||
552 | */ | ||
553 | void drm_sysfs_device_remove(struct drm_minor *minor) | ||
554 | { | ||
555 | if (minor->kdev) | ||
556 | device_unregister(minor->kdev); | ||
557 | minor->kdev = NULL; | ||
558 | } | 543 | } |
559 | 544 | ||
560 | |||
561 | /** | 545 | /** |
562 | * drm_class_device_register - Register a struct device in the drm class. | 546 | * drm_class_device_register - Register a struct device in the drm class. |
563 | * | 547 | * |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 60998fc4e5b2..2dd19da6b4b3 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -1260,7 +1260,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1260 | 1260 | ||
1261 | flags = 0; | 1261 | flags = 0; |
1262 | if (args->flags & I915_EXEC_SECURE) { | 1262 | if (args->flags & I915_EXEC_SECURE) { |
1263 | if (!file->is_master || !capable(CAP_SYS_ADMIN)) | 1263 | if (!drm_is_master(file) || !capable(CAP_SYS_ADMIN)) |
1264 | return -EPERM; | 1264 | return -EPERM; |
1265 | 1265 | ||
1266 | flags |= I915_DISPATCH_SECURE; | 1266 | flags |= I915_DISPATCH_SECURE; |
@@ -1369,7 +1369,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1369 | ret = i915_parse_cmds(ring, | 1369 | ret = i915_parse_cmds(ring, |
1370 | batch_obj, | 1370 | batch_obj, |
1371 | args->batch_start_offset, | 1371 | args->batch_start_offset, |
1372 | file->is_master); | 1372 | drm_is_master(file)); |
1373 | if (ret) | 1373 | if (ret) |
1374 | goto err; | 1374 | goto err; |
1375 | 1375 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 18b54acacfbb..63c4d6f0281e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -990,7 +990,7 @@ static struct vmw_master *vmw_master_check(struct drm_device *dev, | |||
990 | if (unlikely(ret != 0)) | 990 | if (unlikely(ret != 0)) |
991 | return ERR_PTR(-ERESTARTSYS); | 991 | return ERR_PTR(-ERESTARTSYS); |
992 | 992 | ||
993 | if (file_priv->is_master) { | 993 | if (drm_is_master(file_priv)) { |
994 | mutex_unlock(&dev->master_mutex); | 994 | mutex_unlock(&dev->master_mutex); |
995 | return NULL; | 995 | return NULL; |
996 | } | 996 | } |
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 6f54ff4f9372..72913b299047 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c | |||
@@ -182,7 +182,7 @@ static void imx_drm_driver_preclose(struct drm_device *drm, | |||
182 | { | 182 | { |
183 | int i; | 183 | int i; |
184 | 184 | ||
185 | if (!file->is_master) | 185 | if (!drm_is_master(file)) |
186 | return; | 186 | return; |
187 | 187 | ||
188 | for (i = 0; i < MAX_CRTC; i++) | 188 | for (i = 0; i < MAX_CRTC; i++) |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d3d9be6b83ef..a57646382086 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -151,8 +151,6 @@ int drm_err(const char *func, const char *format, ...); | |||
151 | also include looping detection. */ | 151 | also include looping detection. */ |
152 | 152 | ||
153 | #define DRM_MAGIC_HASH_ORDER 4 /**< Size of key hash table. Must be power of 2. */ | 153 | #define DRM_MAGIC_HASH_ORDER 4 /**< Size of key hash table. Must be power of 2. */ |
154 | #define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */ | ||
155 | #define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */ | ||
156 | 154 | ||
157 | #define DRM_MAP_HASH_OFFSET 0x10000000 | 155 | #define DRM_MAP_HASH_OFFSET 0x10000000 |
158 | 156 | ||
@@ -385,10 +383,7 @@ struct drm_prime_file_private { | |||
385 | 383 | ||
386 | /** File private data */ | 384 | /** File private data */ |
387 | struct drm_file { | 385 | struct drm_file { |
388 | unsigned always_authenticated :1; | ||
389 | unsigned authenticated :1; | 386 | unsigned authenticated :1; |
390 | /* Whether we're master for a minor. Protected by master_mutex */ | ||
391 | unsigned is_master :1; | ||
392 | /* true when the client has asked us to expose stereo 3D mode flags */ | 387 | /* true when the client has asked us to expose stereo 3D mode flags */ |
393 | unsigned stereo_allowed :1; | 388 | unsigned stereo_allowed :1; |
394 | /* | 389 | /* |
@@ -538,15 +533,6 @@ struct drm_map_list { | |||
538 | struct drm_master *master; | 533 | struct drm_master *master; |
539 | }; | 534 | }; |
540 | 535 | ||
541 | /** | ||
542 | * Context handle list | ||
543 | */ | ||
544 | struct drm_ctx_list { | ||
545 | struct list_head head; /**< list head */ | ||
546 | drm_context_t handle; /**< context handle */ | ||
547 | struct drm_file *tag; /**< associated fd private data */ | ||
548 | }; | ||
549 | |||
550 | /* location of GART table */ | 536 | /* location of GART table */ |
551 | #define DRM_ATI_GART_MAIN 1 | 537 | #define DRM_ATI_GART_MAIN 1 |
552 | #define DRM_ATI_GART_FB 2 | 538 | #define DRM_ATI_GART_FB 2 |
@@ -1034,7 +1020,7 @@ struct drm_device { | |||
1034 | /** \name Locks */ | 1020 | /** \name Locks */ |
1035 | /*@{ */ | 1021 | /*@{ */ |
1036 | struct mutex struct_mutex; /**< For others */ | 1022 | struct mutex struct_mutex; /**< For others */ |
1037 | struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */ | 1023 | struct mutex master_mutex; /**< For drm_minor::master */ |
1038 | /*@} */ | 1024 | /*@} */ |
1039 | 1025 | ||
1040 | /** \name Usage Counters */ | 1026 | /** \name Usage Counters */ |
@@ -1172,6 +1158,21 @@ static inline bool drm_is_primary_client(const struct drm_file *file_priv) | |||
1172 | return file_priv->minor->type == DRM_MINOR_LEGACY; | 1158 | return file_priv->minor->type == DRM_MINOR_LEGACY; |
1173 | } | 1159 | } |
1174 | 1160 | ||
1161 | /** | ||
1162 | * drm_is_master() - Check whether a DRM open-file is DRM-Master | ||
1163 | * @file: DRM open-file context | ||
1164 | * | ||
1165 | * This checks whether a DRM open-file context is owner of the master context | ||
1166 | * attached to it. If a file owns a master context, it's called DRM-Master. | ||
1167 | * Per DRM device, only one such file can be DRM-Master at a time. | ||
1168 | * | ||
1169 | * Returns: True if the file is DRM-Master, otherwise false. | ||
1170 | */ | ||
1171 | static inline bool drm_is_master(const struct drm_file *file) | ||
1172 | { | ||
1173 | return file->master && file->master == file->minor->master; | ||
1174 | } | ||
1175 | |||
1175 | /******************************************************************/ | 1176 | /******************************************************************/ |
1176 | /** \name Internal function definitions */ | 1177 | /** \name Internal function definitions */ |
1177 | /*@{*/ | 1178 | /*@{*/ |
@@ -1187,7 +1188,6 @@ extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags); | |||
1187 | /* Device support (drm_fops.h) */ | 1188 | /* Device support (drm_fops.h) */ |
1188 | extern struct mutex drm_global_mutex; | 1189 | extern struct mutex drm_global_mutex; |
1189 | extern int drm_open(struct inode *inode, struct file *filp); | 1190 | extern int drm_open(struct inode *inode, struct file *filp); |
1190 | extern int drm_stub_open(struct inode *inode, struct file *filp); | ||
1191 | extern ssize_t drm_read(struct file *filp, char __user *buffer, | 1191 | extern ssize_t drm_read(struct file *filp, char __user *buffer, |
1192 | size_t count, loff_t *offset); | 1192 | size_t count, loff_t *offset); |
1193 | extern int drm_release(struct inode *inode, struct file *filp); | 1193 | extern int drm_release(struct inode *inode, struct file *filp); |
@@ -1225,29 +1225,6 @@ extern int drm_setversion(struct drm_device *dev, void *data, | |||
1225 | extern int drm_noop(struct drm_device *dev, void *data, | 1225 | extern int drm_noop(struct drm_device *dev, void *data, |
1226 | struct drm_file *file_priv); | 1226 | struct drm_file *file_priv); |
1227 | 1227 | ||
1228 | /* Context IOCTL support (drm_context.h) */ | ||
1229 | extern int drm_resctx(struct drm_device *dev, void *data, | ||
1230 | struct drm_file *file_priv); | ||
1231 | extern int drm_addctx(struct drm_device *dev, void *data, | ||
1232 | struct drm_file *file_priv); | ||
1233 | extern int drm_getctx(struct drm_device *dev, void *data, | ||
1234 | struct drm_file *file_priv); | ||
1235 | extern int drm_switchctx(struct drm_device *dev, void *data, | ||
1236 | struct drm_file *file_priv); | ||
1237 | extern int drm_newctx(struct drm_device *dev, void *data, | ||
1238 | struct drm_file *file_priv); | ||
1239 | extern int drm_rmctx(struct drm_device *dev, void *data, | ||
1240 | struct drm_file *file_priv); | ||
1241 | |||
1242 | extern int drm_ctxbitmap_init(struct drm_device *dev); | ||
1243 | extern void drm_ctxbitmap_cleanup(struct drm_device *dev); | ||
1244 | extern void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle); | ||
1245 | |||
1246 | extern int drm_setsareactx(struct drm_device *dev, void *data, | ||
1247 | struct drm_file *file_priv); | ||
1248 | extern int drm_getsareactx(struct drm_device *dev, void *data, | ||
1249 | struct drm_file *file_priv); | ||
1250 | |||
1251 | /* Authentication IOCTL support (drm_auth.h) */ | 1228 | /* Authentication IOCTL support (drm_auth.h) */ |
1252 | extern int drm_getmagic(struct drm_device *dev, void *data, | 1229 | extern int drm_getmagic(struct drm_device *dev, void *data, |
1253 | struct drm_file *file_priv); | 1230 | struct drm_file *file_priv); |
@@ -1373,9 +1350,6 @@ extern unsigned int drm_timestamp_precision; | |||
1373 | extern unsigned int drm_timestamp_monotonic; | 1350 | extern unsigned int drm_timestamp_monotonic; |
1374 | 1351 | ||
1375 | extern struct class *drm_class; | 1352 | extern struct class *drm_class; |
1376 | extern struct dentry *drm_debugfs_root; | ||
1377 | |||
1378 | extern struct idr drm_minors_idr; | ||
1379 | 1353 | ||
1380 | extern struct drm_local_map *drm_getsarea(struct drm_device *dev); | 1354 | extern struct drm_local_map *drm_getsarea(struct drm_device *dev); |
1381 | 1355 | ||
@@ -1493,9 +1467,8 @@ extern int drm_pci_set_unique(struct drm_device *dev, | |||
1493 | struct drm_sysfs_class; | 1467 | struct drm_sysfs_class; |
1494 | extern struct class *drm_sysfs_create(struct module *owner, char *name); | 1468 | extern struct class *drm_sysfs_create(struct module *owner, char *name); |
1495 | extern void drm_sysfs_destroy(void); | 1469 | extern void drm_sysfs_destroy(void); |
1496 | extern int drm_sysfs_device_add(struct drm_minor *minor); | 1470 | extern struct device *drm_sysfs_minor_alloc(struct drm_minor *minor); |
1497 | extern void drm_sysfs_hotplug_event(struct drm_device *dev); | 1471 | extern void drm_sysfs_hotplug_event(struct drm_device *dev); |
1498 | extern void drm_sysfs_device_remove(struct drm_minor *minor); | ||
1499 | extern int drm_sysfs_connector_add(struct drm_connector *connector); | 1472 | extern int drm_sysfs_connector_add(struct drm_connector *connector); |
1500 | extern void drm_sysfs_connector_remove(struct drm_connector *connector); | 1473 | extern void drm_sysfs_connector_remove(struct drm_connector *connector); |
1501 | 1474 | ||