diff options
-rw-r--r-- | Documentation/DocBook/drm.tmpl | 69 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fops.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_pci.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_platform.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_stub.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_usb.c | 9 | ||||
-rw-r--r-- | include/drm/drmP.h | 9 |
8 files changed, 129 insertions, 13 deletions
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 9fc8ed4ac0f4..ed1d6d289022 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl | |||
@@ -205,6 +205,12 @@ | |||
205 | Driver implements DRM PRIME buffer sharing. | 205 | Driver implements DRM PRIME buffer sharing. |
206 | </para></listitem> | 206 | </para></listitem> |
207 | </varlistentry> | 207 | </varlistentry> |
208 | <varlistentry> | ||
209 | <term>DRIVER_RENDER</term> | ||
210 | <listitem><para> | ||
211 | Driver supports dedicated render nodes. | ||
212 | </para></listitem> | ||
213 | </varlistentry> | ||
208 | </variablelist> | 214 | </variablelist> |
209 | </sect3> | 215 | </sect3> |
210 | <sect3> | 216 | <sect3> |
@@ -2644,6 +2650,69 @@ int (*resume) (struct drm_device *);</synopsis> | |||
2644 | info, since man pages should cover the rest. | 2650 | info, since man pages should cover the rest. |
2645 | </para> | 2651 | </para> |
2646 | 2652 | ||
2653 | <!-- External: render nodes --> | ||
2654 | |||
2655 | <sect1> | ||
2656 | <title>Render nodes</title> | ||
2657 | <para> | ||
2658 | DRM core provides multiple character-devices for user-space to use. | ||
2659 | Depending on which device is opened, user-space can perform a different | ||
2660 | set of operations (mainly ioctls). The primary node is always created | ||
2661 | and called <term>card<num></term>. Additionally, a currently | ||
2662 | unused control node, called <term>controlD<num></term> is also | ||
2663 | created. The primary node provides all legacy operations and | ||
2664 | historically was the only interface used by userspace. With KMS, the | ||
2665 | control node was introduced. However, the planned KMS control interface | ||
2666 | has never been written and so the control node stays unused to date. | ||
2667 | </para> | ||
2668 | <para> | ||
2669 | With the increased use of offscreen renderers and GPGPU applications, | ||
2670 | clients no longer require running compositors or graphics servers to | ||
2671 | make use of a GPU. But the DRM API required unprivileged clients to | ||
2672 | authenticate to a DRM-Master prior to getting GPU access. To avoid this | ||
2673 | step and to grant clients GPU access without authenticating, render | ||
2674 | nodes were introduced. Render nodes solely serve render clients, that | ||
2675 | is, no modesetting or privileged ioctls can be issued on render nodes. | ||
2676 | Only non-global rendering commands are allowed. If a driver supports | ||
2677 | render nodes, it must advertise it via the <term>DRIVER_RENDER</term> | ||
2678 | DRM driver capability. If not supported, the primary node must be used | ||
2679 | for render clients together with the legacy drmAuth authentication | ||
2680 | procedure. | ||
2681 | </para> | ||
2682 | <para> | ||
2683 | If a driver advertises render node support, DRM core will create a | ||
2684 | separate render node called <term>renderD<num></term>. There will | ||
2685 | be one render node per device. No ioctls except PRIME-related ioctls | ||
2686 | will be allowed on this node. Especially <term>GEM_OPEN</term> will be | ||
2687 | explicitly prohibited. Render nodes are designed to avoid the | ||
2688 | buffer-leaks, which occur if clients guess the flink names or mmap | ||
2689 | offsets on the legacy interface. Additionally to this basic interface, | ||
2690 | drivers must mark their driver-dependent render-only ioctls as | ||
2691 | <term>DRM_RENDER_ALLOW</term> so render clients can use them. Driver | ||
2692 | authors must be careful not to allow any privileged ioctls on render | ||
2693 | nodes. | ||
2694 | </para> | ||
2695 | <para> | ||
2696 | With render nodes, user-space can now control access to the render node | ||
2697 | via basic file-system access-modes. A running graphics server which | ||
2698 | authenticates clients on the privileged primary/legacy node is no longer | ||
2699 | required. Instead, a client can open the render node and is immediately | ||
2700 | granted GPU access. Communication between clients (or servers) is done | ||
2701 | via PRIME. FLINK from render node to legacy node is not supported. New | ||
2702 | clients must not use the insecure FLINK interface. | ||
2703 | </para> | ||
2704 | <para> | ||
2705 | Besides dropping all modeset/global ioctls, render nodes also drop the | ||
2706 | DRM-Master concept. There is no reason to associate render clients with | ||
2707 | a DRM-Master as they are independent of any graphics server. Besides, | ||
2708 | they must work without any running master, anyway. | ||
2709 | Drivers must be able to run without a master object if they support | ||
2710 | render nodes. If, on the other hand, a driver requires shared state | ||
2711 | between clients which is visible to user-space and accessible beyond | ||
2712 | open-file boundaries, they cannot support render nodes. | ||
2713 | </para> | ||
2714 | </sect1> | ||
2715 | |||
2647 | <!-- External: vblank handling --> | 2716 | <!-- External: vblank handling --> |
2648 | 2717 | ||
2649 | <sect1> | 2718 | <sect1> |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 288da3dc2a09..e572dd20bdee 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -68,7 +68,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = { | |||
68 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED), | 68 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED), |
69 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 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), | 70 | DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED), |
71 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED), | 71 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW), |
72 | DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), | 72 | DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), |
73 | 73 | ||
74 | DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 74 | DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
@@ -130,14 +130,14 @@ static const struct drm_ioctl_desc drm_ioctls[] = { | |||
130 | 130 | ||
131 | DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 131 | DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
132 | 132 | ||
133 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED), | 133 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), |
134 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), | 134 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), |
135 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), | 135 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), |
136 | 136 | ||
137 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 137 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
138 | 138 | ||
139 | DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), | 139 | DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), |
140 | DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), | 140 | DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), |
141 | 141 | ||
142 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 142 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
143 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 143 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
@@ -420,9 +420,10 @@ long drm_ioctl(struct file *filp, | |||
420 | DRM_DEBUG("no function\n"); | 420 | DRM_DEBUG("no function\n"); |
421 | retcode = -EINVAL; | 421 | retcode = -EINVAL; |
422 | } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) || | 422 | } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) || |
423 | ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) || | 423 | ((ioctl->flags & DRM_AUTH) && !drm_is_render_client(file_priv) && !file_priv->authenticated) || |
424 | ((ioctl->flags & DRM_MASTER) && !file_priv->is_master) || | 424 | ((ioctl->flags & DRM_MASTER) && !file_priv->is_master) || |
425 | (!(ioctl->flags & DRM_CONTROL_ALLOW) && (file_priv->minor->type == DRM_MINOR_CONTROL))) { | 425 | (!(ioctl->flags & DRM_CONTROL_ALLOW) && (file_priv->minor->type == DRM_MINOR_CONTROL)) || |
426 | (!(ioctl->flags & DRM_RENDER_ALLOW) && drm_is_render_client(file_priv))) { | ||
426 | retcode = -EACCES; | 427 | retcode = -EACCES; |
427 | } else { | 428 | } else { |
428 | if (cmd & (IOC_IN | IOC_OUT)) { | 429 | if (cmd & (IOC_IN | IOC_OUT)) { |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 136c949307ba..4be8e09a32ef 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -262,10 +262,10 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
262 | goto out_prime_destroy; | 262 | goto out_prime_destroy; |
263 | } | 263 | } |
264 | 264 | ||
265 | 265 | /* if there is no current master make this fd it, but do not create | |
266 | /* if there is no current master make this fd it */ | 266 | * any master object for render clients */ |
267 | mutex_lock(&dev->struct_mutex); | 267 | mutex_lock(&dev->struct_mutex); |
268 | if (!priv->minor->master) { | 268 | if (!priv->minor->master && !drm_is_render_client(priv)) { |
269 | /* create a new master */ | 269 | /* create a new master */ |
270 | priv->minor->master = drm_master_create(priv->minor); | 270 | priv->minor->master = drm_master_create(priv->minor); |
271 | if (!priv->minor->master) { | 271 | if (!priv->minor->master) { |
@@ -303,12 +303,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
303 | goto out_close; | 303 | goto out_close; |
304 | } | 304 | } |
305 | } | 305 | } |
306 | mutex_unlock(&dev->struct_mutex); | 306 | } else if (!drm_is_render_client(priv)) { |
307 | } else { | ||
308 | /* get a reference to the master */ | 307 | /* get a reference to the master */ |
309 | priv->master = drm_master_get(priv->minor->master); | 308 | priv->master = drm_master_get(priv->minor->master); |
310 | mutex_unlock(&dev->struct_mutex); | ||
311 | } | 309 | } |
310 | mutex_unlock(&dev->struct_mutex); | ||
312 | 311 | ||
313 | mutex_lock(&dev->struct_mutex); | 312 | mutex_lock(&dev->struct_mutex); |
314 | list_add(&priv->lhead, &dev->filelist); | 313 | list_add(&priv->lhead, &dev->filelist); |
@@ -478,7 +477,8 @@ int drm_release(struct inode *inode, struct file *filp) | |||
478 | iput(container_of(dev->dev_mapping, struct inode, i_data)); | 477 | iput(container_of(dev->dev_mapping, struct inode, i_data)); |
479 | 478 | ||
480 | /* drop the reference held my the file priv */ | 479 | /* drop the reference held my the file priv */ |
481 | drm_master_put(&file_priv->master); | 480 | if (file_priv->master) |
481 | drm_master_put(&file_priv->master); | ||
482 | file_priv->is_master = 0; | 482 | file_priv->is_master = 0; |
483 | list_del(&file_priv->lhead); | 483 | list_del(&file_priv->lhead); |
484 | mutex_unlock(&dev->struct_mutex); | 484 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 3fca2db1c40c..1f96cee6eee8 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
@@ -354,6 +354,12 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
354 | goto err_g2; | 354 | goto err_g2; |
355 | } | 355 | } |
356 | 356 | ||
357 | if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) { | ||
358 | ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER); | ||
359 | if (ret) | ||
360 | goto err_g21; | ||
361 | } | ||
362 | |||
357 | if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) | 363 | if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) |
358 | goto err_g3; | 364 | goto err_g3; |
359 | 365 | ||
@@ -383,6 +389,9 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
383 | err_g4: | 389 | err_g4: |
384 | drm_put_minor(&dev->primary); | 390 | drm_put_minor(&dev->primary); |
385 | err_g3: | 391 | err_g3: |
392 | if (dev->render) | ||
393 | drm_put_minor(&dev->render); | ||
394 | err_g21: | ||
386 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 395 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
387 | drm_put_minor(&dev->control); | 396 | drm_put_minor(&dev->control); |
388 | err_g2: | 397 | err_g2: |
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 400024b6d512..f7a18c6ba4c4 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c | |||
@@ -69,6 +69,12 @@ static int drm_get_platform_dev(struct platform_device *platdev, | |||
69 | goto err_g1; | 69 | goto err_g1; |
70 | } | 70 | } |
71 | 71 | ||
72 | if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) { | ||
73 | ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER); | ||
74 | if (ret) | ||
75 | goto err_g11; | ||
76 | } | ||
77 | |||
72 | ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); | 78 | ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); |
73 | if (ret) | 79 | if (ret) |
74 | goto err_g2; | 80 | goto err_g2; |
@@ -100,6 +106,9 @@ static int drm_get_platform_dev(struct platform_device *platdev, | |||
100 | err_g3: | 106 | err_g3: |
101 | drm_put_minor(&dev->primary); | 107 | drm_put_minor(&dev->primary); |
102 | err_g2: | 108 | err_g2: |
109 | if (dev->render) | ||
110 | drm_put_minor(&dev->render); | ||
111 | err_g11: | ||
103 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 112 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
104 | drm_put_minor(&dev->control); | 113 | drm_put_minor(&dev->control); |
105 | err_g1: | 114 | err_g1: |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index e30bb0d7c67a..e7eb0276f7f1 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -40,6 +40,9 @@ | |||
40 | unsigned int drm_debug = 0; /* 1 to enable debug output */ | 40 | unsigned int drm_debug = 0; /* 1 to enable debug output */ |
41 | EXPORT_SYMBOL(drm_debug); | 41 | EXPORT_SYMBOL(drm_debug); |
42 | 42 | ||
43 | unsigned int drm_rnodes = 0; /* 1 to enable experimental render nodes API */ | ||
44 | EXPORT_SYMBOL(drm_rnodes); | ||
45 | |||
43 | unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ | 46 | unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ |
44 | EXPORT_SYMBOL(drm_vblank_offdelay); | 47 | EXPORT_SYMBOL(drm_vblank_offdelay); |
45 | 48 | ||
@@ -56,11 +59,13 @@ MODULE_AUTHOR(CORE_AUTHOR); | |||
56 | MODULE_DESCRIPTION(CORE_DESC); | 59 | MODULE_DESCRIPTION(CORE_DESC); |
57 | MODULE_LICENSE("GPL and additional rights"); | 60 | MODULE_LICENSE("GPL and additional rights"); |
58 | MODULE_PARM_DESC(debug, "Enable debug output"); | 61 | MODULE_PARM_DESC(debug, "Enable debug output"); |
62 | MODULE_PARM_DESC(rnodes, "Enable experimental render nodes API"); | ||
59 | MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]"); | 63 | MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]"); |
60 | MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); | 64 | MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); |
61 | MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); | 65 | MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); |
62 | 66 | ||
63 | module_param_named(debug, drm_debug, int, 0600); | 67 | module_param_named(debug, drm_debug, int, 0600); |
68 | module_param_named(rnodes, drm_rnodes, int, 0600); | ||
64 | module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); | 69 | module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); |
65 | module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); | 70 | module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); |
66 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); | 71 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); |
@@ -446,6 +451,9 @@ void drm_put_dev(struct drm_device *dev) | |||
446 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 451 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
447 | drm_put_minor(&dev->control); | 452 | drm_put_minor(&dev->control); |
448 | 453 | ||
454 | if (dev->render) | ||
455 | drm_put_minor(&dev->render); | ||
456 | |||
449 | if (driver->driver_features & DRIVER_GEM) | 457 | if (driver->driver_features & DRIVER_GEM) |
450 | drm_gem_destroy(dev); | 458 | drm_gem_destroy(dev); |
451 | 459 | ||
@@ -462,6 +470,8 @@ void drm_unplug_dev(struct drm_device *dev) | |||
462 | /* for a USB device */ | 470 | /* for a USB device */ |
463 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 471 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
464 | drm_unplug_minor(dev->control); | 472 | drm_unplug_minor(dev->control); |
473 | if (dev->render) | ||
474 | drm_unplug_minor(dev->render); | ||
465 | drm_unplug_minor(dev->primary); | 475 | drm_unplug_minor(dev->primary); |
466 | 476 | ||
467 | mutex_lock(&drm_global_mutex); | 477 | mutex_lock(&drm_global_mutex); |
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index 34a156f0c336..87664723b9ce 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c | |||
@@ -33,6 +33,12 @@ int drm_get_usb_dev(struct usb_interface *interface, | |||
33 | if (ret) | 33 | if (ret) |
34 | goto err_g1; | 34 | goto err_g1; |
35 | 35 | ||
36 | if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) { | ||
37 | ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER); | ||
38 | if (ret) | ||
39 | goto err_g11; | ||
40 | } | ||
41 | |||
36 | ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); | 42 | ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); |
37 | if (ret) | 43 | if (ret) |
38 | goto err_g2; | 44 | goto err_g2; |
@@ -62,6 +68,9 @@ int drm_get_usb_dev(struct usb_interface *interface, | |||
62 | err_g3: | 68 | err_g3: |
63 | drm_put_minor(&dev->primary); | 69 | drm_put_minor(&dev->primary); |
64 | err_g2: | 70 | err_g2: |
71 | if (dev->render) | ||
72 | drm_put_minor(&dev->render); | ||
73 | err_g11: | ||
65 | drm_put_minor(&dev->control); | 74 | drm_put_minor(&dev->control); |
66 | err_g1: | 75 | err_g1: |
67 | kfree(dev); | 76 | kfree(dev); |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 0e3d51793b65..290734191f72 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -145,6 +145,7 @@ int drm_err(const char *func, const char *format, ...); | |||
145 | #define DRIVER_GEM 0x1000 | 145 | #define DRIVER_GEM 0x1000 |
146 | #define DRIVER_MODESET 0x2000 | 146 | #define DRIVER_MODESET 0x2000 |
147 | #define DRIVER_PRIME 0x4000 | 147 | #define DRIVER_PRIME 0x4000 |
148 | #define DRIVER_RENDER 0x8000 | ||
148 | 149 | ||
149 | #define DRIVER_BUS_PCI 0x1 | 150 | #define DRIVER_BUS_PCI 0x1 |
150 | #define DRIVER_BUS_PLATFORM 0x2 | 151 | #define DRIVER_BUS_PLATFORM 0x2 |
@@ -290,6 +291,7 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, | |||
290 | #define DRM_ROOT_ONLY 0x4 | 291 | #define DRM_ROOT_ONLY 0x4 |
291 | #define DRM_CONTROL_ALLOW 0x8 | 292 | #define DRM_CONTROL_ALLOW 0x8 |
292 | #define DRM_UNLOCKED 0x10 | 293 | #define DRM_UNLOCKED 0x10 |
294 | #define DRM_RENDER_ALLOW 0x20 | ||
293 | 295 | ||
294 | struct drm_ioctl_desc { | 296 | struct drm_ioctl_desc { |
295 | unsigned int cmd; | 297 | unsigned int cmd; |
@@ -1204,6 +1206,7 @@ struct drm_device { | |||
1204 | unsigned int agp_buffer_token; | 1206 | unsigned int agp_buffer_token; |
1205 | struct drm_minor *control; /**< Control node for card */ | 1207 | struct drm_minor *control; /**< Control node for card */ |
1206 | struct drm_minor *primary; /**< render type primary screen head */ | 1208 | struct drm_minor *primary; /**< render type primary screen head */ |
1209 | struct drm_minor *render; /**< render node for card */ | ||
1207 | 1210 | ||
1208 | struct drm_mode_config mode_config; /**< Current mode config */ | 1211 | struct drm_mode_config mode_config; /**< Current mode config */ |
1209 | 1212 | ||
@@ -1251,6 +1254,11 @@ static inline bool drm_modeset_is_locked(struct drm_device *dev) | |||
1251 | return mutex_is_locked(&dev->mode_config.mutex); | 1254 | return mutex_is_locked(&dev->mode_config.mutex); |
1252 | } | 1255 | } |
1253 | 1256 | ||
1257 | static inline bool drm_is_render_client(struct drm_file *file_priv) | ||
1258 | { | ||
1259 | return file_priv->minor->type == DRM_MINOR_RENDER; | ||
1260 | } | ||
1261 | |||
1254 | /******************************************************************/ | 1262 | /******************************************************************/ |
1255 | /** \name Internal function definitions */ | 1263 | /** \name Internal function definitions */ |
1256 | /*@{*/ | 1264 | /*@{*/ |
@@ -1450,6 +1458,7 @@ extern void drm_put_dev(struct drm_device *dev); | |||
1450 | extern int drm_put_minor(struct drm_minor **minor); | 1458 | extern int drm_put_minor(struct drm_minor **minor); |
1451 | extern void drm_unplug_dev(struct drm_device *dev); | 1459 | extern void drm_unplug_dev(struct drm_device *dev); |
1452 | extern unsigned int drm_debug; | 1460 | extern unsigned int drm_debug; |
1461 | extern unsigned int drm_rnodes; | ||
1453 | 1462 | ||
1454 | extern unsigned int drm_vblank_offdelay; | 1463 | extern unsigned int drm_vblank_offdelay; |
1455 | extern unsigned int drm_timestamp_precision; | 1464 | extern unsigned int drm_timestamp_precision; |