Wed Jul 24 03:22:42 2013 UTC ()
Reject drm ioctls through control minors unless explicitly allowed.


(riastradh)
diff -r1.1.2.8 -r1.1.2.9 src/sys/external/bsd/drm2/drm/drm_drv.c

cvs diff -r1.1.2.8 -r1.1.2.9 src/sys/external/bsd/drm2/drm/Attic/drm_drv.c (switch to unified diff)

--- src/sys/external/bsd/drm2/drm/Attic/drm_drv.c 2013/07/24 03:22:26 1.1.2.8
+++ src/sys/external/bsd/drm2/drm/Attic/drm_drv.c 2013/07/24 03:22:42 1.1.2.9
@@ -1,584 +1,588 @@ @@ -1,584 +1,588 @@
1/* $NetBSD: drm_drv.c,v 1.1.2.8 2013/07/24 03:22:26 riastradh Exp $ */ 1/* $NetBSD: drm_drv.c,v 1.1.2.9 2013/07/24 03:22:42 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2013 The NetBSD Foundation, Inc. 4 * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R. Campbell. 8 * by Taylor R. Campbell.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.1.2.8 2013/07/24 03:22:26 riastradh Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.1.2.9 2013/07/24 03:22:42 riastradh Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/types.h> 36#include <sys/types.h>
37#include <sys/conf.h> 37#include <sys/conf.h>
38#include <sys/device.h> 38#include <sys/device.h>
39#include <sys/file.h> 39#include <sys/file.h>
40#include <sys/filedesc.h> 40#include <sys/filedesc.h>
41#include <sys/ioccom.h> 41#include <sys/ioccom.h>
42#include <sys/kauth.h> 42#include <sys/kauth.h>
43#if 0 /* XXX drm event poll */ 43#if 0 /* XXX drm event poll */
44#include <sys/poll.h> 44#include <sys/poll.h>
45#include <sys/select.h> 45#include <sys/select.h>
46#endif 46#endif
47 47
48#include <drm/drmP.h> 48#include <drm/drmP.h>
49 49
50static int drm_minor_types[] = { 50static int drm_minor_types[] = {
51 DRM_MINOR_LEGACY, 51 DRM_MINOR_LEGACY,
52 DRM_MINOR_CONTROL, 52 DRM_MINOR_CONTROL,
53#if 0 /* XXX Nothing seems to use this? */ 53#if 0 /* XXX Nothing seems to use this? */
54 DRM_MINOR_RENDER, 54 DRM_MINOR_RENDER,
55#endif 55#endif
56}; 56};
57 57
58struct drm_softc { 58struct drm_softc {
59 struct drm_device *sc_drm_dev; 59 struct drm_device *sc_drm_dev;
60 struct drm_minor sc_minor[__arraycount(drm_minor_types)]; 60 struct drm_minor sc_minor[__arraycount(drm_minor_types)];
61}; 61};
62 62
63static int drm_match(device_t, cfdata_t, void *); 63static int drm_match(device_t, cfdata_t, void *);
64static void drm_attach(device_t, device_t, void *); 64static void drm_attach(device_t, device_t, void *);
65#if 0 /* XXX drm detach */ 65#if 0 /* XXX drm detach */
66static int drm_detach(device_t, int); 66static int drm_detach(device_t, int);
67#endif 67#endif
68 68
69static struct drm_softc *drm_dev_softc(dev_t); 69static struct drm_softc *drm_dev_softc(dev_t);
70static struct drm_minor *drm_dev_minor(dev_t); 70static struct drm_minor *drm_dev_minor(dev_t);
71 71
72static dev_type_open(drm_open); 72static dev_type_open(drm_open);
73 73
74static int drm_close(struct file *); 74static int drm_close(struct file *);
75static int drm_read(struct file *, off_t *, struct uio *, kauth_cred_t, 75static int drm_read(struct file *, off_t *, struct uio *, kauth_cred_t,
76 int); 76 int);
77static int drm_poll(struct file *, int); 77static int drm_poll(struct file *, int);
78static int drm_stat(struct file *, struct stat *); 78static int drm_stat(struct file *, struct stat *);
79static int drm_ioctl(struct file *, unsigned long, void *); 79static int drm_ioctl(struct file *, unsigned long, void *);
80static int drm_version_string(char *, size_t *, const char *); 80static int drm_version_string(char *, size_t *, const char *);
81 81
82static drm_ioctl_t drm_version; 82static drm_ioctl_t drm_version;
83 83
84/* XXX Can this be pushed into struct drm_device? */ 84/* XXX Can this be pushed into struct drm_device? */
85struct mutex drm_global_mutex; 85struct mutex drm_global_mutex;
86 86
87#define DRM_IOCTL_DEF(IOCTL, FUNC, FLAGS) \ 87#define DRM_IOCTL_DEF(IOCTL, FUNC, FLAGS) \
88 [DRM_IOCTL_NR(IOCTL)] = { \ 88 [DRM_IOCTL_NR(IOCTL)] = { \
89 .cmd = (IOCTL), \ 89 .cmd = (IOCTL), \
90 .flags = (FLAGS), \ 90 .flags = (FLAGS), \
91 .func = (FUNC), \ 91 .func = (FUNC), \
92 .cmd_drv = 0, \ 92 .cmd_drv = 0, \
93 } 93 }
94 94
95/* Table copied verbatim from dist/drm/drm_drv.c. */ 95/* Table copied verbatim from dist/drm/drm_drv.c. */
96static const struct drm_ioctl_desc drm_ioctls[] = { 96static const struct drm_ioctl_desc drm_ioctls[] = {
97 DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED), 97 DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED),
98 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), 98 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
99 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), 99 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
100 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), 100 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
101 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED), 101 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
102 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED), 102 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
103 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED), 103 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
104 DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED), 104 DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED),
105 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), 105 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
106 106
107 DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 107 DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
108 DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 108 DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
109 DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 109 DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
110 DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER), 110 DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
111 111
112 DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 112 DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
113 DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH), 113 DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
114 114
115 DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 115 DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
116 DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH), 116 DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
117 117
118 DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY), 118 DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY),
119 DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY), 119 DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY),
120 120
121 DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY), 121 DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY),
122 DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 122 DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
123 DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 123 DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
124 DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH), 124 DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
125 DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 125 DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
126 DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 126 DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
127 DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH), 127 DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH),
128 128
129 DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 129 DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
130 DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 130 DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
131 131
132 DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH), 132 DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
133 DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH), 133 DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
134 134
135 DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH), 135 DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
136 136
137 DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 137 DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
138 DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 138 DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
139 DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH), 139 DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
140 DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH), 140 DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
141 DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH), 141 DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
142 /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ 142 /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
143 DRM_IOCTL_DEF(DRM_IOCTL_DMA, NULL, DRM_AUTH), 143 DRM_IOCTL_DEF(DRM_IOCTL_DMA, NULL, DRM_AUTH),
144 144
145 DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 145 DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
146 146
147#if __OS_HAS_AGP 147#if __OS_HAS_AGP
148 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 148 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
149 DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 149 DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
150 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 150 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
151 DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH), 151 DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
152 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 152 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
153 DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 153 DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
154 DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 154 DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
155 DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 155 DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
156#endif 156#endif
157 157
158 DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 158 DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
159 DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 159 DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
160 160
161 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED), 161 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
162 162
163 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), 163 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
164 164
165 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 165 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
166 166
167 DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED), 167 DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED),
168 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), 168 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
169 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), 169 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
170 170
171 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 171 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
172 172
173#ifndef __NetBSD__ /* XXX drm prime */ 173#ifndef __NetBSD__ /* XXX drm prime */
174 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), 174 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED),
175 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), 175 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED),
176#endif 176#endif
177 177
178 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 178 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
179 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 179 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
180 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 180 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
181 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 181 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
182 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 182 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
183 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 183 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
184 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED), 184 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
185 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), 185 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
186 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 186 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
187 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 187 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
188 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 188 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
189 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 189 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
190 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 190 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
191 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 191 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
192 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 192 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
193 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 193 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
194 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 194 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
195 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 195 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
196 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 196 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
197 DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 197 DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
198 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 198 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
199 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 199 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
200 DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 200 DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
201 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 201 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
202 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 202 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
203 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 203 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
204}; 204};
205 205
206const struct cdevsw drm_cdevsw = { 206const struct cdevsw drm_cdevsw = {
207 .d_open = drm_open, 207 .d_open = drm_open,
208 .d_close = noclose, 208 .d_close = noclose,
209 .d_read = noread, 209 .d_read = noread,
210 .d_write = nowrite, 210 .d_write = nowrite,
211 .d_ioctl = noioctl, 211 .d_ioctl = noioctl,
212 .d_stop = nostop, 212 .d_stop = nostop,
213 .d_tty = notty, 213 .d_tty = notty,
214 .d_poll = nopoll, 214 .d_poll = nopoll,
215 .d_mmap = nommap, 215 .d_mmap = nommap,
216 .d_kqfilter = nokqfilter, 216 .d_kqfilter = nokqfilter,
217 /* XXX was D_TTY | D_NEGOFFSAFE */ 217 /* XXX was D_TTY | D_NEGOFFSAFE */
218 /* XXX Add D_MPSAFE some day... */ 218 /* XXX Add D_MPSAFE some day... */
219 .d_flag = D_NEGOFFSAFE, 219 .d_flag = D_NEGOFFSAFE,
220}; 220};
221 221
222/* XXX Does this get declared automatically by config? */ 222/* XXX Does this get declared automatically by config? */
223extern struct cfdriver drm_cd; 223extern struct cfdriver drm_cd;
224 224
225static const struct fileops drm_fileops = { 225static const struct fileops drm_fileops = {
226 .fo_read = drm_read, 226 .fo_read = drm_read,
227 .fo_write = fbadop_write, 227 .fo_write = fbadop_write,
228 .fo_ioctl = drm_ioctl, 228 .fo_ioctl = drm_ioctl,
229 .fo_fcntl = fnullop_fcntl, 229 .fo_fcntl = fnullop_fcntl,
230 .fo_poll = drm_poll, 230 .fo_poll = drm_poll,
231 .fo_stat = drm_stat, 231 .fo_stat = drm_stat,
232 .fo_close = drm_close, 232 .fo_close = drm_close,
233 .fo_kqfilter = fnullop_kqfilter, 233 .fo_kqfilter = fnullop_kqfilter,
234 .fo_restart = fnullop_restart, 234 .fo_restart = fnullop_restart,
235}; 235};
236 236
237CFATTACH_DECL_NEW(drm, sizeof(struct drm_minor), 237CFATTACH_DECL_NEW(drm, sizeof(struct drm_minor),
238 drm_match, drm_attach, NULL /* XXX drm_detach */, NULL); 238 drm_match, drm_attach, NULL /* XXX drm_detach */, NULL);
239 239
240static int 240static int
241drm_match(device_t parent __unused, cfdata_t match __unused, 241drm_match(device_t parent __unused, cfdata_t match __unused,
242 void *aux __unused) 242 void *aux __unused)
243{ 243{
244 244
245 return 1; 245 return 1;
246} 246}
247 247
248static void 248static void
249drm_attach(device_t parent, device_t self, void *aux) 249drm_attach(device_t parent, device_t self, void *aux)
250{ 250{
251 struct drm_softc *sc = device_private(self); 251 struct drm_softc *sc = device_private(self);
252 struct drm_device *dev = aux; 252 struct drm_device *dev = aux;
253 unsigned int i; 253 unsigned int i;
254 254
255 KASSERT(sc != NULL); 255 KASSERT(sc != NULL);
256 KASSERT(dev != NULL); 256 KASSERT(dev != NULL);
257 KASSERT(dev->driver != NULL); 257 KASSERT(dev->driver != NULL);
258 KASSERT(device_unit(self) >= 0); 258 KASSERT(device_unit(self) >= 0);
259 259
260 if (device_unit(self) >= 64) /* XXX Need to do something here! */ 260 if (device_unit(self) >= 64) /* XXX Need to do something here! */
261 return; 261 return;
262 262
263 for (i = 0; i < __arraycount(drm_minor_types); i++) { 263 for (i = 0; i < __arraycount(drm_minor_types); i++) {
264 sc->sc_minor[i].index = (i * 64) + device_unit(self); 264 sc->sc_minor[i].index = (i * 64) + device_unit(self);
265 sc->sc_minor[i].type = drm_minor_types[i]; 265 sc->sc_minor[i].type = drm_minor_types[i];
266 sc->sc_minor[i].device = 266 sc->sc_minor[i].device =
267 makedev(cdevsw_lookup_major(&drm_cdevsw), 267 makedev(cdevsw_lookup_major(&drm_cdevsw),
268 sc->sc_minor[i].index); 268 sc->sc_minor[i].index);
269 sc->sc_minor[i].kdev = self; 269 sc->sc_minor[i].kdev = self;
270 sc->sc_minor[i].dev = dev; 270 sc->sc_minor[i].dev = dev;
271 sc->sc_minor[i].master = NULL; 271 sc->sc_minor[i].master = NULL;
272 INIT_LIST_HEAD(&sc->sc_minor[i].master_list); 272 INIT_LIST_HEAD(&sc->sc_minor[i].master_list);
273 (void)memset(&sc->sc_minor[i].mode_group, 0, 273 (void)memset(&sc->sc_minor[i].mode_group, 0,
274 sizeof(sc->sc_minor[i].mode_group)); 274 sizeof(sc->sc_minor[i].mode_group));
275 } 275 }
276 276
277#if 0 /* XXX drm wsdisplay */ 277#if 0 /* XXX drm wsdisplay */
278 attach wsdisplay; 278 attach wsdisplay;
279#endif 279#endif
280} 280}
281 281
282#if 0 /* XXX drm detach */ 282#if 0 /* XXX drm detach */
283static int 283static int
284drm_detach(device_t self, int flags) 284drm_detach(device_t self, int flags)
285{ 285{
286 struct drm_softc *const sc = device_private(self); 286 struct drm_softc *const sc = device_private(self);
287 KASSERT(sc != NULL); 287 KASSERT(sc != NULL);
288 struct drm_device *const dev = sc->sc_minor.dev; 288 struct drm_device *const dev = sc->sc_minor.dev;
289 KASSERT(dev != NULL); 289 KASSERT(dev != NULL);
290 290
291 drm_sysctl_cleanup(dev); 291 drm_sysctl_cleanup(dev);
292 drm_ctxbitmap_cleanup(dev); 292 drm_ctxbitmap_cleanup(dev);
293 clean up mtrr crap; 293 clean up mtrr crap;
294 do the last close; 294 do the last close;
295 unload it all; 295 unload it all;
296 vblank clenaup; 296 vblank clenaup;
297 kill hash tables; 297 kill hash tables;
298 and more; 298 and more;
299 in a different order; 299 in a different order;
300} 300}
301#endif 301#endif
302 302
303static struct drm_softc * 303static struct drm_softc *
304drm_dev_softc(dev_t d) 304drm_dev_softc(dev_t d)
305{ 305{
306 return device_lookup_private(&drm_cd, (minor(d) % 64)); 306 return device_lookup_private(&drm_cd, (minor(d) % 64));
307} 307}
308 308
309static struct drm_minor * 309static struct drm_minor *
310drm_dev_minor(dev_t d) 310drm_dev_minor(dev_t d)
311{ 311{
312 struct drm_softc *const sc = drm_dev_softc(d); 312 struct drm_softc *const sc = drm_dev_softc(d);
313 313
314 if (sc == NULL) 314 if (sc == NULL)
315 return NULL; 315 return NULL;
316 316
317 const unsigned int i = minor(d) / 64; 317 const unsigned int i = minor(d) / 64;
318 if (i >= __arraycount(drm_minor_types)) 318 if (i >= __arraycount(drm_minor_types))
319 return NULL; 319 return NULL;
320 320
321 return &sc->sc_minor[i]; 321 return &sc->sc_minor[i];
322} 322}
323 323
324static int 324static int
325drm_open(dev_t d, int flags, int fmt, struct lwp *l) 325drm_open(dev_t d, int flags, int fmt, struct lwp *l)
326{ 326{
327 struct drm_minor *const dminor = drm_dev_minor(d); 327 struct drm_minor *const dminor = drm_dev_minor(d);
328 int fd; 328 int fd;
329 struct file *fp; 329 struct file *fp;
330 int error; 330 int error;
331 331
332 if (dminor == NULL) { 332 if (dminor == NULL) {
333 error = ENXIO; 333 error = ENXIO;
334 goto fail0; 334 goto fail0;
335 } 335 }
336 336
337 if (flags & O_EXCL) { 337 if (flags & O_EXCL) {
338 error = EBUSY; 338 error = EBUSY;
339 goto fail0; 339 goto fail0;
340 } 340 }
341 341
342 if (dminor->dev->switch_power_state != DRM_SWITCH_POWER_ON) { 342 if (dminor->dev->switch_power_state != DRM_SWITCH_POWER_ON) {
343 error = EINVAL; 343 error = EINVAL;
344 goto fail0; 344 goto fail0;
345 } 345 }
346 346
347 error = fd_allocfile(&fp, &fd); 347 error = fd_allocfile(&fp, &fd);
348 if (error) 348 if (error)
349 goto fail0; 349 goto fail0;
350 350
351 struct drm_file *const file = kmem_zalloc(sizeof(*file), KM_SLEEP); 351 struct drm_file *const file = kmem_zalloc(sizeof(*file), KM_SLEEP);
352 352
353 /* XXX errno Linux->NetBSD */ 353 /* XXX errno Linux->NetBSD */
354 error = -drm_open_file(file, fp, dminor); 354 error = -drm_open_file(file, fp, dminor);
355 if (error) 355 if (error)
356 goto fail2; 356 goto fail2;
357 357
358 error = fd_clone(fp, fd, flags, &drm_fileops, file); 358 error = fd_clone(fp, fd, flags, &drm_fileops, file);
359 KASSERT(error == EMOVEFD); /* XXX */ 359 KASSERT(error == EMOVEFD); /* XXX */
360 360
361 /* Success! (But error has to be EMOVEFD, not 0.) */ 361 /* Success! (But error has to be EMOVEFD, not 0.) */
362 return error; 362 return error;
363 363
364fail2: 364fail2:
365 kmem_free(file, sizeof(*file)); 365 kmem_free(file, sizeof(*file));
366 366
367fail1: __unused 367fail1: __unused
368 fd_abort(curproc, fp, fd); 368 fd_abort(curproc, fp, fd);
369 369
370fail0: 370fail0:
371 return error; 371 return error;
372} 372}
373 373
374static int 374static int
375drm_close(struct file *fp) 375drm_close(struct file *fp)
376{ 376{
377 struct drm_file *const file = fp->f_data; 377 struct drm_file *const file = fp->f_data;
378 378
379 /* XXX errno Linux->NetBSD */ 379 /* XXX errno Linux->NetBSD */
380 return -drm_close_file(file); 380 return -drm_close_file(file);
381} 381}
382 382
383/* 383/*
384 * XXX According to the old drm port, doing nothing but succeeding in 384 * XXX According to the old drm port, doing nothing but succeeding in
385 * drm_read and drm_poll is a kludge for compatibility with old X 385 * drm_read and drm_poll is a kludge for compatibility with old X
386 * servers. However, it's not clear to me from the drm2 code that this 386 * servers. However, it's not clear to me from the drm2 code that this
387 * is the right thing; in fact, it looks like a load of bollocks. 387 * is the right thing; in fact, it looks like a load of bollocks.
388 */ 388 */
389 389
390static int 390static int
391drm_read(struct file *fp __unused, off_t *off __unused, 391drm_read(struct file *fp __unused, off_t *off __unused,
392 struct uio *uio __unused, kauth_cred_t cred __unused, int flags __unused) 392 struct uio *uio __unused, kauth_cred_t cred __unused, int flags __unused)
393{ 393{
394#if 1 /* XXX drm event poll */ 394#if 1 /* XXX drm event poll */
395 return 0; 395 return 0;
396#else 396#else
397 /* XXX How do flags figure into this? */ 397 /* XXX How do flags figure into this? */
398 struct drm_file *const file = fp->f_data; 398 struct drm_file *const file = fp->f_data;
399 struct drm_pending_event *event; 399 struct drm_pending_event *event;
400 int error; 400 int error;
401 401
402 if (off != 0) 402 if (off != 0)
403 return EINVAL; 403 return EINVAL;
404 404
405 for (;;) { 405 for (;;) {
406 error = drm_dequeue_event(file, uio->uio_resid, &event); 406 error = drm_dequeue_event(file, uio->uio_resid, &event);
407 if (error) { 407 if (error) {
408 /* XXX errno Linux->NetBSD */ 408 /* XXX errno Linux->NetBSD */
409 return -error; 409 return -error;
410 } 410 }
411 411
412 if (event == NULL) 412 if (event == NULL)
413 break; 413 break;
414 414
415 error = uiomove(event->event, event->event->length, uio); 415 error = uiomove(event->event, event->event->length, uio);
416 if (error) /* XXX Requeue the event? */ 416 if (error) /* XXX Requeue the event? */
417 return error; 417 return error;
418 } 418 }
419 419
420 /* Success! */ 420 /* Success! */
421 return 0; 421 return 0;
422#endif 422#endif
423} 423}
424 424
425static int 425static int
426drm_poll(struct file *fp __unused, int events __unused) 426drm_poll(struct file *fp __unused, int events __unused)
427{ 427{
428#if 1 /* XXX drm event poll */ 428#if 1 /* XXX drm event poll */
429 /* 429 /*
430 * XXX Let's worry about this later. Notifiers need to be 430 * XXX Let's worry about this later. Notifiers need to be
431 * modified to call selnotify. 431 * modified to call selnotify.
432 */ 432 */
433 return 0; 433 return 0;
434#else 434#else
435 struct drm_file *const file = fp->f_data; 435 struct drm_file *const file = fp->f_data;
436 int revents = 0; 436 int revents = 0;
437 unsigned long flags; 437 unsigned long flags;
438 438
439 spin_lock_irqsave(&file->minor->dev->event_lock, flags); 439 spin_lock_irqsave(&file->minor->dev->event_lock, flags);
440 440
441 if (events & (POLLIN | POLLRDNORM)) { 441 if (events & (POLLIN | POLLRDNORM)) {
442 if (!list_empty(&file->event_list)) 442 if (!list_empty(&file->event_list))
443 revents |= (events & (POLLIN | POLLRDNORM)); 443 revents |= (events & (POLLIN | POLLRDNORM));
444 } 444 }
445 445
446 if (revents == 0) { 446 if (revents == 0) {
447 if (events & (POLLIN | POLLRDNORM)) 447 if (events & (POLLIN | POLLRDNORM))
448 selrecord(curlwp, &file->event_sel); 448 selrecord(curlwp, &file->event_sel);
449 } 449 }
450 450
451 spin_unlock_irqrestore(&file->minor->dev->event_lock, flags); 451 spin_unlock_irqrestore(&file->minor->dev->event_lock, flags);
452 452
453 return revents; 453 return revents;
454#endif 454#endif
455} 455}
456 456
457static int 457static int
458drm_stat(struct file *fp, struct stat *st) 458drm_stat(struct file *fp, struct stat *st)
459{ 459{
460 struct drm_file *const file = fp->f_data; 460 struct drm_file *const file = fp->f_data;
461 461
462 (void)memset(st, 0, sizeof(*st)); 462 (void)memset(st, 0, sizeof(*st));
463 463
464 st->st_dev = file->minor->device; 464 st->st_dev = file->minor->device;
465 st->st_ino = 0; /* XXX (dev,ino) uniqueness bleh */ 465 st->st_ino = 0; /* XXX (dev,ino) uniqueness bleh */
466 st->st_uid = kauth_cred_geteuid(fp->f_cred); 466 st->st_uid = kauth_cred_geteuid(fp->f_cred);
467 st->st_gid = kauth_cred_getegid(fp->f_cred); 467 st->st_gid = kauth_cred_getegid(fp->f_cred);
468 st->st_mode = S_IFCHR; /* XXX what? */ 468 st->st_mode = S_IFCHR; /* XXX what? */
469 /* XXX what else? */ 469 /* XXX what else? */
470 470
471 return 0; 471 return 0;
472} 472}
473 473
474static int 474static int
475drm_ioctl(struct file *fp, unsigned long cmd, void *data) 475drm_ioctl(struct file *fp, unsigned long cmd, void *data)
476{ 476{
477 struct drm_file *const file = fp->f_data; 477 struct drm_file *const file = fp->f_data;
478 const unsigned int nr = DRM_IOCTL_NR(cmd); 478 const unsigned int nr = DRM_IOCTL_NR(cmd);
479 int error; 479 int error;
480 480
481 switch (cmd) { 481 switch (cmd) {
482 case FIONBIO: 482 case FIONBIO:
483 case FIOASYNC: 483 case FIOASYNC:
484 return 0; 484 return 0;
485 485
486#if 0 /* XXX why? */ 486#if 0 /* XXX why? */
487 case SIOCSPGRP: 487 case SIOCSPGRP:
488 case TIOCSPGRP: 488 case TIOCSPGRP:
489 case FIOSETOWN: 489 case FIOSETOWN:
490 return fsetown(&dev->buf_pgid, cmd, data); 490 return fsetown(&dev->buf_pgid, cmd, data);
491 491
492 case SIOCGPGRP: 492 case SIOCGPGRP:
493 case TIOCGPGRP: 493 case TIOCGPGRP:
494 case FIOGETOWN: 494 case FIOGETOWN:
495 return fgetown(&dev->buf_pgid, cmd, data); 495 return fgetown(&dev->buf_pgid, cmd, data);
496#endif 496#endif
497 497
498 default: 498 default:
499 break; 499 break;
500 } 500 }
501 501
502 if (IOCGROUP(cmd) != DRM_IOCTL_BASE) 502 if (IOCGROUP(cmd) != DRM_IOCTL_BASE)
503 return EINVAL; 503 return EINVAL;
504 504
505 KASSERT(file != NULL); 505 KASSERT(file != NULL);
506 KASSERT(file->minor != NULL); 506 KASSERT(file->minor != NULL);
507 KASSERT(file->minor->dev != NULL); 507 KASSERT(file->minor->dev != NULL);
508 struct drm_device *const dev = file->minor->dev; 508 struct drm_device *const dev = file->minor->dev;
509 const struct drm_ioctl_desc *ioctl; 509 const struct drm_ioctl_desc *ioctl;
510 510
511 if ((DRM_COMMAND_BASE <= nr) && (nr < DRM_COMMAND_END)) { 511 if ((DRM_COMMAND_BASE <= nr) && (nr < DRM_COMMAND_END)) {
512 const unsigned int driver_nr = nr - DRM_COMMAND_BASE; 512 const unsigned int driver_nr = nr - DRM_COMMAND_BASE;
513 if (driver_nr >= dev->driver->num_ioctls) 513 if (driver_nr >= dev->driver->num_ioctls)
514 return EINVAL; 514 return EINVAL;
515 ioctl = &dev->driver->ioctls[driver_nr]; 515 ioctl = &dev->driver->ioctls[driver_nr];
516 } else if (nr < __arraycount(drm_ioctls)) { 516 } else if (nr < __arraycount(drm_ioctls)) {
517 ioctl = &drm_ioctls[nr]; 517 ioctl = &drm_ioctls[nr];
518 } else { 518 } else {
519 ioctl = NULL; 519 ioctl = NULL;
520 } 520 }
521 521
522 if ((ioctl == NULL) || (ioctl->func == NULL)) 522 if ((ioctl == NULL) || (ioctl->func == NULL))
523 return EINVAL; 523 return EINVAL;
524 524
525 if (ISSET(ioctl->flags, DRM_ROOT_ONLY) && !DRM_SUSER()) 525 if (ISSET(ioctl->flags, DRM_ROOT_ONLY) && !DRM_SUSER())
526 return EACCES; 526 return EACCES;
527 527
528 if (ISSET(ioctl->flags, DRM_AUTH) && !file->authenticated) 528 if (ISSET(ioctl->flags, DRM_AUTH) && !file->authenticated)
529 return EACCES; 529 return EACCES;
530 530
531 if (ISSET(ioctl->flags, DRM_MASTER) && (file->master == NULL)) 531 if (ISSET(ioctl->flags, DRM_MASTER) && (file->master == NULL))
532 return EACCES; 532 return EACCES;
533 533
 534 if (!ISSET(ioctl->flags, DRM_CONTROL_ALLOW) &&
 535 (file->minor->type == DRM_MINOR_CONTROL))
 536 return EACCES;
 537
534 atomic_inc(&dev->ioctl_count); 538 atomic_inc(&dev->ioctl_count);
535 if (!ISSET(ioctl->flags, DRM_UNLOCKED)) 539 if (!ISSET(ioctl->flags, DRM_UNLOCKED))
536 mutex_lock(&drm_global_mutex); 540 mutex_lock(&drm_global_mutex);
537 541
538 /* XXX errno Linux->NetBSD */ 542 /* XXX errno Linux->NetBSD */
539 error = -(*ioctl->func)(dev, data, file); 543 error = -(*ioctl->func)(dev, data, file);
540 544
541 if (!ISSET(ioctl->flags, DRM_UNLOCKED)) 545 if (!ISSET(ioctl->flags, DRM_UNLOCKED))
542 mutex_unlock(&drm_global_mutex); 546 mutex_unlock(&drm_global_mutex);
543 atomic_dec(&dev->ioctl_count); 547 atomic_dec(&dev->ioctl_count);
544 548
545 return error; 549 return error;
546} 550}
547 551
548static int 552static int
549drm_version_string(char *target, size_t *lenp, const char *source) 553drm_version_string(char *target, size_t *lenp, const char *source)
550{ 554{
551 const size_t len = strlen(source); 555 const size_t len = strlen(source);
552 const size_t trunc_len = MIN(len, *lenp); 556 const size_t trunc_len = MIN(len, *lenp);
553 557
554 *lenp = len; 558 *lenp = len;
555 if ((trunc_len > 0) && (target != NULL)) 559 if ((trunc_len > 0) && (target != NULL))
556 return copyoutstr(source, target, trunc_len, NULL); 560 return copyoutstr(source, target, trunc_len, NULL);
557 561
558 return 0; 562 return 0;
559} 563}
560 564
561static int 565static int
562drm_version(struct drm_device *dev, void *data, struct drm_file *file) 566drm_version(struct drm_device *dev, void *data, struct drm_file *file)
563{ 567{
564 struct drm_version *v = data; 568 struct drm_version *v = data;
565 int error; 569 int error;
566 570
567 v->version_major = dev->driver->major; 571 v->version_major = dev->driver->major;
568 v->version_minor = dev->driver->minor; 572 v->version_minor = dev->driver->minor;
569 v->version_patchlevel = dev->driver->patchlevel; 573 v->version_patchlevel = dev->driver->patchlevel;
570 574
571 error = drm_version_string(v->name, &v->name_len, dev->driver->name); 575 error = drm_version_string(v->name, &v->name_len, dev->driver->name);
572 if (error) 576 if (error)
573 goto out; 577 goto out;
574 578
575 error = drm_version_string(v->date, &v->date_len, dev->driver->date); 579 error = drm_version_string(v->date, &v->date_len, dev->driver->date);
576 if (error) 580 if (error)
577 goto out; 581 goto out;
578 582
579 error = drm_version_string(v->desc, &v->desc_len, dev->driver->desc); 583 error = drm_version_string(v->desc, &v->desc_len, dev->driver->desc);
580 if (error) 584 if (error)
581 goto out; 585 goto out;
582out: 586out:
583 return error; 587 return error;
584} 588}