1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include <drm/drmP.h>
37#include <drm/drm_core.h>
38
39#include <linux/pci.h>
40#include <linux/export.h>
41#ifdef CONFIG_X86
42#include <asm/mtrr.h>
43#endif
44
45
46
47
48
49
50
51
52
53
54
55
56int drm_getunique(struct drm_device *dev, void *data,
57 struct drm_file *file_priv)
58{
59 struct drm_unique *u = data;
60 struct drm_master *master = file_priv->master;
61
62 if (u->unique_len >= master->unique_len) {
63 if (copy_to_user(u->unique, master->unique, master->unique_len))
64 return -EFAULT;
65 }
66 u->unique_len = master->unique_len;
67
68 return 0;
69}
70
71static void
72drm_unset_busid(struct drm_device *dev,
73 struct drm_master *master)
74{
75 kfree(dev->devname);
76 dev->devname = NULL;
77
78 kfree(master->unique);
79 master->unique = NULL;
80 master->unique_len = 0;
81 master->unique_size = 0;
82}
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98int drm_setunique(struct drm_device *dev, void *data,
99 struct drm_file *file_priv)
100{
101 struct drm_unique *u = data;
102 struct drm_master *master = file_priv->master;
103 int ret;
104
105 if (master->unique_len || master->unique)
106 return -EBUSY;
107
108 if (!u->unique_len || u->unique_len > 1024)
109 return -EINVAL;
110
111 if (!dev->driver->bus->set_unique)
112 return -EINVAL;
113
114 ret = dev->driver->bus->set_unique(dev, master, u);
115 if (ret)
116 goto err;
117
118 return 0;
119
120err:
121 drm_unset_busid(dev, master);
122 return ret;
123}
124
125static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
126{
127 struct drm_master *master = file_priv->master;
128 int ret;
129
130 if (master->unique != NULL)
131 drm_unset_busid(dev, master);
132
133 ret = dev->driver->bus->set_busid(dev, master);
134 if (ret)
135 goto err;
136 return 0;
137err:
138 drm_unset_busid(dev, master);
139 return ret;
140}
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155int drm_getmap(struct drm_device *dev, void *data,
156 struct drm_file *file_priv)
157{
158 struct drm_map *map = data;
159 struct drm_map_list *r_list = NULL;
160 struct list_head *list;
161 int idx;
162 int i;
163
164 idx = map->offset;
165 if (idx < 0)
166 return -EINVAL;
167
168 i = 0;
169 mutex_lock(&dev->struct_mutex);
170 list_for_each(list, &dev->maplist) {
171 if (i == idx) {
172 r_list = list_entry(list, struct drm_map_list, head);
173 break;
174 }
175 i++;
176 }
177 if (!r_list || !r_list->map) {
178 mutex_unlock(&dev->struct_mutex);
179 return -EINVAL;
180 }
181
182 map->offset = r_list->map->offset;
183 map->size = r_list->map->size;
184 map->type = r_list->map->type;
185 map->flags = r_list->map->flags;
186 map->handle = (void *)(unsigned long) r_list->user_token;
187
188#ifdef CONFIG_X86
189
190
191
192
193 map->mtrr = phys_wc_to_mtrr_index(r_list->map->mtrr);
194#else
195 map->mtrr = -1;
196#endif
197
198 mutex_unlock(&dev->struct_mutex);
199
200 return 0;
201}
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216int drm_getclient(struct drm_device *dev, void *data,
217 struct drm_file *file_priv)
218{
219 struct drm_client *client = data;
220
221
222
223
224
225
226
227
228
229
230
231
232 if (client->idx == 0) {
233 client->auth = file_priv->authenticated;
234 client->pid = pid_vnr(file_priv->pid);
235 client->uid = from_kuid_munged(current_user_ns(),
236 file_priv->uid);
237 client->magic = 0;
238 client->iocs = 0;
239
240 return 0;
241 } else {
242 return -EINVAL;
243 }
244}
245
246
247
248
249
250
251
252
253
254
255
256int drm_getstats(struct drm_device *dev, void *data,
257 struct drm_file *file_priv)
258{
259 struct drm_stats *stats = data;
260
261
262 memset(stats, 0, sizeof(*stats));
263
264 return 0;
265}
266
267
268
269
270int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
271{
272 struct drm_get_cap *req = data;
273
274 req->value = 0;
275 switch (req->capability) {
276 case DRM_CAP_DUMB_BUFFER:
277 if (dev->driver->dumb_create)
278 req->value = 1;
279 break;
280 case DRM_CAP_VBLANK_HIGH_CRTC:
281 req->value = 1;
282 break;
283 case DRM_CAP_DUMB_PREFERRED_DEPTH:
284 req->value = dev->mode_config.preferred_depth;
285 break;
286 case DRM_CAP_DUMB_PREFER_SHADOW:
287 req->value = dev->mode_config.prefer_shadow;
288 break;
289 case DRM_CAP_PRIME:
290 req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0;
291 req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0;
292 break;
293 case DRM_CAP_TIMESTAMP_MONOTONIC:
294 req->value = drm_timestamp_monotonic;
295 break;
296 case DRM_CAP_ASYNC_PAGE_FLIP:
297 req->value = dev->mode_config.async_page_flip;
298 break;
299 default:
300 return -EINVAL;
301 }
302 return 0;
303}
304
305
306
307
308
309
310
311
312
313
314
315
316int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
317{
318 struct drm_set_version *sv = data;
319 int if_version, retcode = 0;
320
321 if (sv->drm_di_major != -1) {
322 if (sv->drm_di_major != DRM_IF_MAJOR ||
323 sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
324 retcode = -EINVAL;
325 goto done;
326 }
327 if_version = DRM_IF_VERSION(sv->drm_di_major,
328 sv->drm_di_minor);
329 dev->if_version = max(if_version, dev->if_version);
330 if (sv->drm_di_minor >= 1) {
331
332
333
334
335 retcode = drm_set_busid(dev, file_priv);
336 if (retcode)
337 goto done;
338 }
339 }
340
341 if (sv->drm_dd_major != -1) {
342 if (sv->drm_dd_major != dev->driver->major ||
343 sv->drm_dd_minor < 0 || sv->drm_dd_minor >
344 dev->driver->minor) {
345 retcode = -EINVAL;
346 goto done;
347 }
348 }
349
350done:
351 sv->drm_di_major = DRM_IF_MAJOR;
352 sv->drm_di_minor = DRM_IF_MINOR;
353 sv->drm_dd_major = dev->driver->major;
354 sv->drm_dd_minor = dev->driver->minor;
355
356 return retcode;
357}
358
359
360int drm_noop(struct drm_device *dev, void *data,
361 struct drm_file *file_priv)
362{
363 DRM_DEBUG("\n");
364 return 0;
365}
366EXPORT_SYMBOL(drm_noop);
367