xref: /openbsd-src/sys/dev/pci/drm/drm_drv.c (revision 43003dfe3ad45d1698bed8a37f2b0f5b14f20d4f)
1 /*-
2  * Copyright 2003 Eric Anholt
3  * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
4  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5  * All Rights Reserved.
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 (including the next
15  * paragraph) shall be included in all copies or substantial portions of the
16  * Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24  * OTHER DEALINGS IN THE SOFTWARE.
25  *
26  * Authors:
27  *    Rickard E. (Rik) Faith <faith@valinux.com>
28  *    Daryll Strauss <daryll@valinux.com>
29  *    Gareth Hughes <gareth@valinux.com>
30  *
31  */
32 
33 /** @file drm_drv.c
34  * The catch-all file for DRM device support, including module setup/teardown,
35  * open/close, and ioctl dispatch.
36  */
37 
38 #include <sys/limits.h>
39 #include <sys/ttycom.h> /* for TIOCSGRP */
40 
41 #include "drmP.h"
42 #include "drm.h"
43 #include "drm_sarea.h"
44 
45 #ifdef DRM_DEBUG_DEFAULT_ON
46 int drm_debug_flag = 1;
47 #else
48 int drm_debug_flag = 0;
49 #endif
50 
51 int	 drm_firstopen(struct drm_device *);
52 int	 drm_lastclose(struct drm_device *);
53 void	 drm_attach(struct device *, struct device *, void *);
54 int	 drm_probe(struct device *, void *, void *);
55 int	 drm_detach(struct device *, int);
56 int	 drm_activate(struct device *, enum devact);
57 int	 drmprint(void *, const char *);
58 
59 int	 drm_getunique(struct drm_device *, void *, struct drm_file *);
60 int	 drm_version(struct drm_device *, void *, struct drm_file *);
61 int	 drm_setversion(struct drm_device *, void *, struct drm_file *);
62 int	 drm_getmagic(struct drm_device *, void *, struct drm_file *);
63 int	 drm_authmagic(struct drm_device *, void *, struct drm_file *);
64 int	 drm_file_cmp(struct drm_file *, struct drm_file *);
65 SPLAY_PROTOTYPE(drm_file_tree, drm_file, link, drm_file_cmp);
66 
67 /*
68  * attach drm to a pci-based driver.
69  *
70  * This function does all the pci-specific calculations for the
71  * drm_attach_args.
72  */
73 struct device *
74 drm_attach_pci(const struct drm_driver_info *driver, struct pci_attach_args *pa,
75     int is_agp, struct device *dev)
76 {
77 	struct drm_attach_args arg;
78 
79 	arg.driver = driver;
80 	arg.dmat = pa->pa_dmat;
81 	arg.bst = pa->pa_memt;
82 	arg.irq = pa->pa_intrline;
83 	arg.is_agp = is_agp;
84 
85 	arg.busid_len = 20;
86 	arg.busid = malloc(arg.busid_len + 1, M_DRM, M_NOWAIT);
87 	if (arg.busid == NULL) {
88 		printf("%s: no memory for drm\n", dev->dv_xname);
89 		return (NULL);
90 	}
91 	snprintf(arg.busid, arg.busid_len, "pci:%04x:%02x:%02x.%1x",
92 	    pa->pa_domain, pa->pa_bus, pa->pa_device, pa->pa_function);
93 
94 	return (config_found(dev, &arg, drmprint));
95 }
96 
97 int
98 drmprint(void *aux, const char *pnp)
99 {
100 	if (pnp != NULL)
101 		printf("drm at %s", pnp);
102 	return (UNCONF);
103 }
104 
105 int
106 drm_pciprobe(struct pci_attach_args *pa, const struct drm_pcidev *idlist)
107 {
108 	const struct drm_pcidev *id_entry;
109 
110 	id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
111 	    PCI_PRODUCT(pa->pa_id), idlist);
112 	if (id_entry != NULL)
113 		return 1;
114 
115 	return 0;
116 }
117 
118 int
119 drm_probe(struct device *parent, void *match, void *aux)
120 {
121 	struct drm_attach_args *da = aux;
122 
123 	return (da->driver != NULL ? 1 : 0);
124 }
125 
126 void
127 drm_attach(struct device *parent, struct device *self, void *aux)
128 {
129 	struct drm_device	*dev = (struct drm_device *)self;
130 	struct drm_attach_args	*da = aux;
131 
132 	dev->dev_private = parent;
133 	dev->driver = da->driver;
134 
135 	dev->dmat = da->dmat;
136 	dev->bst = da->bst;
137 	dev->irq = da->irq;
138 	dev->unique = da->busid;
139 	dev->unique_len = da->busid_len;
140 
141 	rw_init(&dev->dev_lock, "drmdevlk");
142 	mtx_init(&dev->lock.spinlock, IPL_NONE);
143 
144 	TAILQ_INIT(&dev->maplist);
145 	SPLAY_INIT(&dev->files);
146 
147 	if (dev->driver->vblank_pipes != 0 && drm_vblank_init(dev,
148 	    dev->driver->vblank_pipes)) {
149 		printf(": failed to allocate vblank data\n");
150 		goto error;
151 	}
152 
153 	/*
154 	 * the dma buffers api is just weird. offset 1Gb to ensure we don't
155 	 * conflict with it.
156 	 */
157 	dev->handle_ext = extent_create("drmext", 1024*1024*1024, LONG_MAX,
158 	    M_DRM, NULL, NULL, EX_NOWAIT | EX_NOCOALESCE);
159 	if (dev->handle_ext == NULL) {
160 		DRM_ERROR("Failed to initialise handle extent\n");
161 		goto error;
162 	}
163 
164 	if (dev->driver->flags & DRIVER_AGP) {
165 		if (da->is_agp)
166 			dev->agp = drm_agp_init();
167 		if (dev->driver->flags & DRIVER_AGP_REQUIRE &&
168 		    dev->agp == NULL) {
169 			printf(": couldn't find agp\n");
170 			goto error;
171 		}
172 		if (dev->agp != NULL) {
173 			if (drm_mtrr_add(dev->agp->info.ai_aperture_base,
174 			    dev->agp->info.ai_aperture_size, DRM_MTRR_WC) == 0)
175 				dev->agp->mtrr = 1;
176 		}
177 	}
178 
179 	if (drm_ctxbitmap_init(dev) != 0) {
180 		printf(": couldn't allocate memory for context bitmap.\n");
181 		goto error;
182 	}
183 	printf("\n");
184 	return;
185 
186 error:
187 	drm_lastclose(dev);
188 }
189 
190 int
191 drm_detach(struct device *self, int flags)
192 {
193 	struct drm_device *dev = (struct drm_device *)self;
194 
195 	drm_lastclose(dev);
196 
197 	drm_ctxbitmap_cleanup(dev);
198 
199 	extent_destroy(dev->handle_ext);
200 
201 	drm_vblank_cleanup(dev);
202 
203 	if (dev->agp && dev->agp->mtrr) {
204 		int retcode;
205 
206 		retcode = drm_mtrr_del(0, dev->agp->info.ai_aperture_base,
207 		    dev->agp->info.ai_aperture_size, DRM_MTRR_WC);
208 		DRM_DEBUG("mtrr_del = %d", retcode);
209 	}
210 
211 
212 	if (dev->agp != NULL) {
213 		drm_free(dev->agp);
214 		dev->agp = NULL;
215 	}
216 
217 	return 0;
218 }
219 
220 int
221 drm_activate(struct device *self, enum devact act)
222 {
223 	switch (act) {
224 	case DVACT_ACTIVATE:
225 		break;
226 
227 	case DVACT_DEACTIVATE:
228 		/* FIXME */
229 		break;
230 	}
231 	return (0);
232 }
233 
234 struct cfattach drm_ca = {
235 	sizeof(struct drm_device), drm_probe, drm_attach,
236 	drm_detach, drm_activate
237 };
238 
239 struct cfdriver drm_cd = {
240 	0, "drm", DV_DULL
241 };
242 
243 const struct drm_pcidev *
244 drm_find_description(int vendor, int device, const struct drm_pcidev *idlist)
245 {
246 	int i = 0;
247 
248 	for (i = 0; idlist[i].vendor != 0; i++) {
249 		if ((idlist[i].vendor == vendor) &&
250 		    (idlist[i].device == device))
251 			return &idlist[i];
252 	}
253 	return NULL;
254 }
255 
256 int
257 drm_file_cmp(struct drm_file *f1, struct drm_file *f2)
258 {
259 	return (f1->minor < f2->minor ? -1 : f1->minor > f2->minor);
260 }
261 
262 SPLAY_GENERATE(drm_file_tree, drm_file, link, drm_file_cmp);
263 
264 struct drm_file *
265 drm_find_file_by_minor(struct drm_device *dev, int minor)
266 {
267 	struct drm_file	key;
268 
269 	key.minor = minor;
270 	return (SPLAY_FIND(drm_file_tree, &dev->files, &key));
271 }
272 
273 int
274 drm_firstopen(struct drm_device *dev)
275 {
276 	struct drm_local_map	*map;
277 	int			 i;
278 
279 	/* prebuild the SAREA */
280 	i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM,
281 	    _DRM_CONTAINS_LOCK, &map);
282 	if (i != 0)
283 		return i;
284 
285 	if (dev->driver->firstopen)
286 		dev->driver->firstopen(dev);
287 
288 	if (dev->driver->flags & DRIVER_DMA) {
289 		if ((i = drm_dma_setup(dev)) != 0)
290 			return (i);
291 	}
292 
293 	dev->magicid = 1;
294 
295 	dev->irq_enabled = 0;
296 	dev->if_version = 0;
297 
298 	dev->buf_pgid = 0;
299 
300 	DRM_DEBUG("\n");
301 
302 	return 0;
303 }
304 
305 int
306 drm_lastclose(struct drm_device *dev)
307 {
308 	struct drm_local_map	*map, *mapsave;
309 
310 	DRM_DEBUG("\n");
311 
312 	if (dev->driver->lastclose != NULL)
313 		dev->driver->lastclose(dev);
314 
315 	if (dev->irq_enabled)
316 		drm_irq_uninstall(dev);
317 
318 	drm_agp_takedown(dev);
319 	drm_dma_takedown(dev);
320 
321 	DRM_LOCK();
322 	if (dev->sg != NULL) {
323 		struct drm_sg_mem *sg = dev->sg;
324 		dev->sg = NULL;
325 
326 		DRM_UNLOCK();
327 		drm_sg_cleanup(dev, sg);
328 		DRM_LOCK();
329 	}
330 
331 	for (map = TAILQ_FIRST(&dev->maplist); map != TAILQ_END(&dev->maplist);
332 	    map = mapsave) {
333 		mapsave = TAILQ_NEXT(map, link);
334 		if ((map->flags & _DRM_DRIVER) == 0)
335 			drm_rmmap_locked(dev, map);
336 	}
337 
338 	if (dev->lock.hw_lock != NULL) {
339 		dev->lock.hw_lock = NULL; /* SHM removed */
340 		dev->lock.file_priv = NULL;
341 		wakeup(&dev->lock); /* there should be nothing sleeping on it */
342 	}
343 	DRM_UNLOCK();
344 
345 	return 0;
346 }
347 
348 int
349 drmopen(dev_t kdev, int flags, int fmt, struct proc *p)
350 {
351 	struct drm_device	*dev = NULL;
352 	struct drm_file		*file_priv;
353 	int			 ret = 0;
354 
355 	dev = drm_get_device_from_kdev(kdev);
356 	if (dev == NULL)
357 		return (ENXIO);
358 
359 	DRM_DEBUG("open_count = %d\n", dev->open_count);
360 
361 	if (flags & O_EXCL)
362 		return (EBUSY); /* No exclusive opens */
363 
364 	DRM_LOCK();
365 	if (dev->open_count++ == 0) {
366 		DRM_UNLOCK();
367 		if ((ret = drm_firstopen(dev)) != 0)
368 			goto err;
369 	} else {
370 		DRM_UNLOCK();
371 	}
372 
373 	/* always allocate at least enough space for our data */
374 	file_priv = drm_calloc(1, max(dev->driver->file_priv_size,
375 	    sizeof(*file_priv)));
376 	if (file_priv == NULL) {
377 		ret = ENOMEM;
378 		goto err;
379 	}
380 
381 	file_priv->kdev = kdev;
382 	file_priv->flags = flags;
383 	file_priv->minor = minor(kdev);
384 	DRM_DEBUG("minor = %d\n", file_priv->minor);
385 
386 	/* for compatibility root is always authenticated */
387 	file_priv->authenticated = DRM_SUSER(p);
388 
389 	if (dev->driver->open) {
390 		ret = dev->driver->open(dev, file_priv);
391 		if (ret != 0) {
392 			goto free_priv;
393 		}
394 	}
395 
396 	DRM_LOCK();
397 	/* first opener automatically becomes master if root */
398 	if (SPLAY_EMPTY(&dev->files) && !DRM_SUSER(p)) {
399 		DRM_UNLOCK();
400 		ret = EPERM;
401 		goto free_priv;
402 	}
403 
404 	file_priv->master = SPLAY_EMPTY(&dev->files);
405 
406 	SPLAY_INSERT(drm_file_tree, &dev->files, file_priv);
407 	DRM_UNLOCK();
408 
409 	return (0);
410 
411 free_priv:
412 	drm_free(file_priv);
413 err:
414 	DRM_LOCK();
415 	--dev->open_count;
416 	DRM_UNLOCK();
417 	return (ret);
418 }
419 
420 int
421 drmclose(dev_t kdev, int flags, int fmt, struct proc *p)
422 {
423 	struct drm_device *dev = drm_get_device_from_kdev(kdev);
424 	struct drm_file *file_priv;
425 	int retcode = 0;
426 
427 	if (dev == NULL)
428 		return (ENXIO);
429 
430 	DRM_DEBUG("open_count = %d\n", dev->open_count);
431 
432 	DRM_LOCK();
433 	file_priv = drm_find_file_by_minor(dev, minor(kdev));
434 	if (file_priv == NULL) {
435 		DRM_ERROR("can't find authenticator\n");
436 		retcode = EINVAL;
437 		goto done;
438 	}
439 	DRM_UNLOCK();
440 
441 	if (dev->driver->close != NULL)
442 		dev->driver->close(dev, file_priv);
443 
444 	DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
445 	    DRM_CURRENTPID, (long)&dev->device, dev->open_count);
446 
447 	if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
448 	    && dev->lock.file_priv == file_priv) {
449 		DRM_DEBUG("Process %d dead, freeing lock for context %d\n",
450 		    DRM_CURRENTPID,
451 		    _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
452 		if (dev->driver->reclaim_buffers_locked != NULL)
453 			dev->driver->reclaim_buffers_locked(dev, file_priv);
454 
455 		drm_lock_free(&dev->lock,
456 		    _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
457 	} else if (dev->driver->reclaim_buffers_locked != NULL &&
458 	    dev->lock.hw_lock != NULL) {
459 		mtx_enter(&dev->lock.spinlock);
460 		/* The lock is required to reclaim buffers */
461 		for (;;) {
462 			if (dev->lock.hw_lock == NULL) {
463 				/* Device has been unregistered */
464 				retcode = EINTR;
465 				break;
466 			}
467 			if (drm_lock_take(&dev->lock, DRM_KERNEL_CONTEXT)) {
468 				dev->lock.file_priv = file_priv;
469 				break;	/* Got lock */
470 			}
471 				/* Contention */
472 			retcode = msleep(&dev->lock,
473 			    &dev->lock.spinlock, PZERO | PCATCH, "drmlk2", 0);
474 			if (retcode)
475 				break;
476 		}
477 		mtx_leave(&dev->lock.spinlock);
478 		if (retcode == 0) {
479 			dev->driver->reclaim_buffers_locked(dev, file_priv);
480 			drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT);
481 		}
482 	}
483 
484 	if (dev->driver->flags & DRIVER_DMA &&
485 	    !dev->driver->reclaim_buffers_locked)
486 		drm_reclaim_buffers(dev, file_priv);
487 
488 	dev->buf_pgid = 0;
489 
490 	DRM_LOCK();
491 	SPLAY_REMOVE(drm_file_tree, &dev->files, file_priv);
492 	drm_free(file_priv);
493 
494 done:
495 	if (--dev->open_count == 0) {
496 		DRM_UNLOCK();
497 		retcode = drm_lastclose(dev);
498 	}
499 
500 	DRM_UNLOCK();
501 
502 	return (retcode);
503 }
504 
505 /* drmioctl is called whenever a process performs an ioctl on /dev/drm.
506  */
507 int
508 drmioctl(dev_t kdev, u_long cmd, caddr_t data, int flags,
509     struct proc *p)
510 {
511 	struct drm_device *dev = drm_get_device_from_kdev(kdev);
512 	struct drm_file *file_priv;
513 
514 	if (dev == NULL)
515 		return ENODEV;
516 
517 	DRM_LOCK();
518 	file_priv = drm_find_file_by_minor(dev, minor(kdev));
519 	DRM_UNLOCK();
520 	if (file_priv == NULL) {
521 		DRM_ERROR("can't find authenticator\n");
522 		return EINVAL;
523 	}
524 
525 	++file_priv->ioctl_count;
526 
527 	DRM_DEBUG("pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n",
528 	    DRM_CURRENTPID, cmd, DRM_IOCTL_NR(cmd), (long)&dev->device,
529 	    file_priv->authenticated);
530 
531 	switch (cmd) {
532 	case FIONBIO:
533 	case FIOASYNC:
534 		return 0;
535 
536 	case TIOCSPGRP:
537 		dev->buf_pgid = *(int *)data;
538 		return 0;
539 
540 	case TIOCGPGRP:
541 		*(int *)data = dev->buf_pgid;
542 		return 0;
543 	case DRM_IOCTL_VERSION:
544 		return (drm_version(dev, data, file_priv));
545 	case DRM_IOCTL_GET_UNIQUE:
546 		return (drm_getunique(dev, data, file_priv));
547 	case DRM_IOCTL_GET_MAGIC:
548 		return (drm_getmagic(dev, data, file_priv));
549 	case DRM_IOCTL_WAIT_VBLANK:
550 		return (drm_wait_vblank(dev, data, file_priv));
551 	case DRM_IOCTL_MODESET_CTL:
552 		return (drm_modeset_ctl(dev, data, file_priv));
553 
554 	/* removed */
555 	case DRM_IOCTL_GET_MAP:
556 		/* FALLTHROUGH */
557 	case DRM_IOCTL_GET_CLIENT:
558 		/* FALLTHROUGH */
559 	case DRM_IOCTL_GET_STATS:
560 		return (EINVAL);
561 	/*
562 	 * no-oped ioctls, we don't check permissions on them because
563 	 * they do nothing. they'll be removed as soon as userland is
564 	 * definitely purged
565 	 */
566 	case DRM_IOCTL_SET_SAREA_CTX:
567 	case DRM_IOCTL_BLOCK:
568 	case DRM_IOCTL_UNBLOCK:
569 	case DRM_IOCTL_MOD_CTX:
570 	case DRM_IOCTL_MARK_BUFS:
571 	case DRM_IOCTL_FINISH:
572 	case DRM_IOCTL_INFO_BUFS:
573 	case DRM_IOCTL_SWITCH_CTX:
574 	case DRM_IOCTL_NEW_CTX:
575 	case DRM_IOCTL_GET_SAREA_CTX:
576 		return (0);
577 	}
578 
579 	if (file_priv->authenticated == 1) {
580 		switch (cmd) {
581 		case DRM_IOCTL_RM_MAP:
582 			return (drm_rmmap_ioctl(dev, data, file_priv));
583 		case DRM_IOCTL_GET_CTX:
584 			return (drm_getctx(dev, data, file_priv));
585 		case DRM_IOCTL_RES_CTX:
586 			return (drm_resctx(dev, data, file_priv));
587 		case DRM_IOCTL_LOCK:
588 			return (drm_lock(dev, data, file_priv));
589 		case DRM_IOCTL_UNLOCK:
590 			return (drm_unlock(dev, data, file_priv));
591 		case DRM_IOCTL_MAP_BUFS:
592 			return (drm_mapbufs(dev, data, file_priv));
593 		case DRM_IOCTL_FREE_BUFS:
594 			return (drm_freebufs(dev, data, file_priv));
595 		case DRM_IOCTL_DMA:
596 			return (drm_dma(dev, data, file_priv));
597 		case DRM_IOCTL_AGP_INFO:
598 			return (drm_agp_info_ioctl(dev, data, file_priv));
599 		}
600 	}
601 
602 	/* master is always root */
603 	if (file_priv->master == 1) {
604 		switch(cmd) {
605 		case DRM_IOCTL_SET_VERSION:
606 			return (drm_setversion(dev, data, file_priv));
607 		case DRM_IOCTL_IRQ_BUSID:
608 			return (drm_irq_by_busid(dev, data, file_priv));
609 		case DRM_IOCTL_AUTH_MAGIC:
610 			return (drm_authmagic(dev, data, file_priv));
611 		case DRM_IOCTL_ADD_MAP:
612 			return (drm_addmap_ioctl(dev, data, file_priv));
613 		case DRM_IOCTL_ADD_CTX:
614 			return (drm_addctx(dev, data, file_priv));
615 		case DRM_IOCTL_RM_CTX:
616 			return (drm_rmctx(dev, data, file_priv));
617 		case DRM_IOCTL_ADD_BUFS:
618 			return (drm_addbufs(dev, (struct drm_buf_desc *)data));
619 		case DRM_IOCTL_CONTROL:
620 			return (drm_control(dev, data, file_priv));
621 		case DRM_IOCTL_AGP_ACQUIRE:
622 			return (drm_agp_acquire_ioctl(dev, data, file_priv));
623 		case DRM_IOCTL_AGP_RELEASE:
624 			return (drm_agp_release_ioctl(dev, data, file_priv));
625 		case DRM_IOCTL_AGP_ENABLE:
626 			return (drm_agp_enable_ioctl(dev, data, file_priv));
627 		case DRM_IOCTL_AGP_ALLOC:
628 			return (drm_agp_alloc_ioctl(dev, data, file_priv));
629 		case DRM_IOCTL_AGP_FREE:
630 			return (drm_agp_free_ioctl(dev, data, file_priv));
631 		case DRM_IOCTL_AGP_BIND:
632 			return (drm_agp_bind_ioctl(dev, data, file_priv));
633 		case DRM_IOCTL_AGP_UNBIND:
634 			return (drm_agp_unbind_ioctl(dev, data, file_priv));
635 		case DRM_IOCTL_SG_ALLOC:
636 			return (drm_sg_alloc_ioctl(dev, data, file_priv));
637 		case DRM_IOCTL_SG_FREE:
638 			return (drm_sg_free(dev, data, file_priv));
639 		case DRM_IOCTL_ADD_DRAW:
640 		case DRM_IOCTL_RM_DRAW:
641 		case DRM_IOCTL_UPDATE_DRAW:
642 			/*
643 			 * Support removed from kernel since it's not used.
644 			 * just return zero until userland stops calling this
645 			 * ioctl.
646 			 */
647 			return (0);
648 		case DRM_IOCTL_SET_UNIQUE:
649 		/*
650 		 * Deprecated in DRM version 1.1, and will return EBUSY
651 		 * when setversion has
652 		 * requested version 1.1 or greater.
653 		 */
654 			return (EBUSY);
655 		}
656 	}
657 	if (dev->driver->ioctl != NULL)
658 		return (dev->driver->ioctl(dev, cmd, data, file_priv));
659 	else
660 		return (EINVAL);
661 }
662 
663 struct drm_local_map *
664 drm_getsarea(struct drm_device *dev)
665 {
666 	struct drm_local_map	*map;
667 
668 	DRM_LOCK();
669 	TAILQ_FOREACH(map, &dev->maplist, link) {
670 		if (map->type == _DRM_SHM && (map->flags & _DRM_CONTAINS_LOCK))
671 			break;
672 	}
673 	DRM_UNLOCK();
674 	return (map);
675 }
676 
677 paddr_t
678 drmmmap(dev_t kdev, off_t offset, int prot)
679 {
680 	struct drm_device	*dev = drm_get_device_from_kdev(kdev);
681 	struct drm_local_map	*map;
682 	struct drm_file		*file_priv;
683 	enum drm_map_type	 type;
684 
685 	if (dev == NULL)
686 		return (-1);
687 
688 	DRM_LOCK();
689 	file_priv = drm_find_file_by_minor(dev, minor(kdev));
690 	DRM_UNLOCK();
691 	if (file_priv == NULL) {
692 		DRM_ERROR("can't find authenticator\n");
693 		return (-1);
694 	}
695 
696 	if (!file_priv->authenticated)
697 		return (-1);
698 
699 	if (dev->dma && offset >= 0 && offset < ptoa(dev->dma->page_count)) {
700 		struct drm_device_dma *dma = dev->dma;
701 		paddr_t	phys = -1;
702 
703 		rw_enter_write(&dma->dma_lock);
704 		if (dma->pagelist != NULL)
705 			phys = atop(dma->pagelist[offset >> PAGE_SHIFT]);
706 		rw_exit_write(&dma->dma_lock);
707 
708 		return (phys);
709 	}
710 
711 	/*
712 	 * A sequential search of a linked list is
713  	 * fine here because: 1) there will only be
714 	 * about 5-10 entries in the list and, 2) a
715 	 * DRI client only has to do this mapping
716 	 * once, so it doesn't have to be optimized
717 	 * for performance, even if the list was a
718 	 * bit longer.
719 	 */
720 	DRM_LOCK();
721 	TAILQ_FOREACH(map, &dev->maplist, link) {
722 		if (offset >= map->ext &&
723 		    offset < map->ext + map->size) {
724 			offset -= map->ext;
725 			break;
726 		}
727 	}
728 
729 	if (map == NULL) {
730 		DRM_UNLOCK();
731 		DRM_DEBUG("can't find map\n");
732 		return (-1);
733 	}
734 	if (((map->flags & _DRM_RESTRICTED) && file_priv->master == 0)) {
735 		DRM_UNLOCK();
736 		DRM_DEBUG("restricted map\n");
737 		return (-1);
738 	}
739 	type = map->type;
740 	DRM_UNLOCK();
741 
742 	switch (type) {
743 	case _DRM_FRAME_BUFFER:
744 	case _DRM_REGISTERS:
745 	case _DRM_AGP:
746 		return (atop(offset + map->offset));
747 		break;
748 	/* XXX unify all the bus_dmamem_mmap bits */
749 	case _DRM_SCATTER_GATHER:
750 		return (bus_dmamem_mmap(dev->dmat, dev->sg->mem->segs,
751 		    dev->sg->mem->nsegs, map->offset - dev->sg->handle +
752 		    offset, prot, BUS_DMA_NOWAIT));
753 	case _DRM_SHM:
754 	case _DRM_CONSISTENT:
755 		return (bus_dmamem_mmap(dev->dmat, map->dmamem->segs,
756 		    map->dmamem->nsegs, offset, prot, BUS_DMA_NOWAIT));
757 	default:
758 		DRM_ERROR("bad map type %d\n", type);
759 		return (-1);	/* This should never happen. */
760 	}
761 	/* NOTREACHED */
762 }
763 
764 /*
765  * Beginning in revision 1.1 of the DRM interface, getunique will return
766  * a unique in the form pci:oooo:bb:dd.f (o=domain, b=bus, d=device, f=function)
767  * before setunique has been called.  The format for the bus-specific part of
768  * the unique is not defined for any other bus.
769  */
770 int
771 drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv)
772 {
773 	struct drm_unique	 *u = data;
774 
775 	if (u->unique_len >= dev->unique_len) {
776 		if (DRM_COPY_TO_USER(u->unique, dev->unique, dev->unique_len))
777 			return EFAULT;
778 	}
779 	u->unique_len = dev->unique_len;
780 
781 	return 0;
782 }
783 
784 #define DRM_IF_MAJOR	1
785 #define DRM_IF_MINOR	2
786 
787 int
788 drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv)
789 {
790 	struct drm_version	*version = data;
791 	int			 len;
792 
793 #define DRM_COPY(name, value)						\
794 	len = strlen( value );						\
795 	if ( len > name##_len ) len = name##_len;			\
796 	name##_len = strlen( value );					\
797 	if ( len && name ) {						\
798 		if ( DRM_COPY_TO_USER( name, value, len ) )		\
799 			return EFAULT;				\
800 	}
801 
802 	version->version_major = dev->driver->major;
803 	version->version_minor = dev->driver->minor;
804 	version->version_patchlevel = dev->driver->patchlevel;
805 
806 	DRM_COPY(version->name, dev->driver->name);
807 	DRM_COPY(version->date, dev->driver->date);
808 	DRM_COPY(version->desc, dev->driver->desc);
809 
810 	return 0;
811 }
812 
813 int
814 drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
815 {
816 	struct drm_set_version	ver, *sv = data;
817 	int			if_version;
818 
819 	/* Save the incoming data, and set the response before continuing
820 	 * any further.
821 	 */
822 	ver = *sv;
823 	sv->drm_di_major = DRM_IF_MAJOR;
824 	sv->drm_di_minor = DRM_IF_MINOR;
825 	sv->drm_dd_major = dev->driver->major;
826 	sv->drm_dd_minor = dev->driver->minor;
827 
828 	/*
829 	 * We no longer support interface versions less than 1.1, so error
830 	 * out if the xserver is too old. 1.1 always ties the drm to a
831 	 * certain busid, this was done on attach
832 	 */
833 	if (ver.drm_di_major != -1) {
834 		if (ver.drm_di_major != DRM_IF_MAJOR || ver.drm_di_minor < 1 ||
835 		    ver.drm_di_minor > DRM_IF_MINOR) {
836 			return EINVAL;
837 		}
838 		if_version = DRM_IF_VERSION(ver.drm_di_major, ver.drm_dd_minor);
839 		dev->if_version = imax(if_version, dev->if_version);
840 	}
841 
842 	if (ver.drm_dd_major != -1) {
843 		if (ver.drm_dd_major != dev->driver->major ||
844 		    ver.drm_dd_minor < 0 ||
845 		    ver.drm_dd_minor > dev->driver->minor)
846 			return EINVAL;
847 	}
848 
849 	return 0;
850 }
851 
852 struct drm_dmamem *
853 drm_dmamem_alloc(bus_dma_tag_t dmat, bus_size_t size, bus_size_t alignment,
854     int nsegments, bus_size_t maxsegsz, int mapflags, int loadflags)
855 {
856 	struct drm_dmamem	*mem;
857 	size_t			 strsize;
858 	/*
859 	 * segs is the last member of the struct since we modify the size
860 	 * to allow extra segments if more than one are allowed.
861 	 */
862 	strsize = sizeof(*mem) + (sizeof(bus_dma_segment_t) * (nsegments - 1));
863 	mem = malloc(strsize, M_DRM, M_NOWAIT | M_ZERO);
864 	if (mem == NULL)
865 		return (NULL);
866 
867 	mem->size = size;
868 
869 	if (bus_dmamap_create(dmat, size, nsegments, maxsegsz, 0,
870 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mem->map) != 0)
871 		goto strfree;
872 
873 	if (bus_dmamem_alloc(dmat, size, alignment, 0, mem->segs, nsegments,
874 	    &mem->nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO) != 0)
875 		goto destroy;
876 
877 	if (bus_dmamem_map(dmat, mem->segs, mem->nsegs, size,
878 	    &mem->kva, BUS_DMA_NOWAIT | mapflags) != 0)
879 		goto free;
880 
881 	if (bus_dmamap_load(dmat, mem->map, mem->kva, size,
882 	    NULL, BUS_DMA_NOWAIT | loadflags) != 0)
883 		goto unmap;
884 
885 	return (mem);
886 
887 unmap:
888 	bus_dmamem_unmap(dmat, mem->kva, size);
889 free:
890 	bus_dmamem_free(dmat, mem->segs, mem->nsegs);
891 destroy:
892 	bus_dmamap_destroy(dmat, mem->map);
893 strfree:
894 	free(mem, M_DRM);
895 
896 	return (NULL);
897 }
898 
899 void
900 drm_dmamem_free(bus_dma_tag_t dmat, struct drm_dmamem *mem)
901 {
902 	if (mem == NULL)
903 		return;
904 
905 	bus_dmamap_unload(dmat, mem->map);
906 	bus_dmamem_unmap(dmat, mem->kva, mem->size);
907 	bus_dmamem_free(dmat, mem->segs, mem->nsegs);
908 	bus_dmamap_destroy(dmat, mem->map);
909 	free(mem, M_DRM);
910 }
911 
912 /**
913  * Called by the client, this returns a unique magic number to be authorized
914  * by the master.
915  *
916  * The master may use its own knowledge of the client (such as the X
917  * connection that the magic is passed over) to determine if the magic number
918  * should be authenticated.
919  */
920 int
921 drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
922 {
923 	struct drm_auth		*auth = data;
924 
925 	if (dev->magicid == 0)
926 		dev->magicid = 1;
927 
928 	/* Find unique magic */
929 	if (file_priv->magic) {
930 		auth->magic = file_priv->magic;
931 	} else {
932 		DRM_LOCK();
933 		file_priv->magic = auth->magic = dev->magicid++;
934 		DRM_UNLOCK();
935 		DRM_DEBUG("%d\n", auth->magic);
936 	}
937 
938 	DRM_DEBUG("%u\n", auth->magic);
939 
940 	return (0);
941 }
942 
943 /**
944  * Marks the client associated with the given magic number as authenticated.
945  */
946 int
947 drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
948 {
949 	struct drm_file	*p;
950 	struct drm_auth	*auth = data;
951 	int		 ret = EINVAL;
952 
953 	DRM_DEBUG("%u\n", auth->magic);
954 
955 	if (auth->magic == 0)
956 		return (ret);
957 
958 	DRM_LOCK();
959 	SPLAY_FOREACH(p, drm_file_tree, &dev->files) {
960 		if (p->magic == auth->magic) {
961 			p->authenticated = 1;
962 			p->magic = 0;
963 			ret = 0;
964 			break;
965 		}
966 	}
967 	DRM_UNLOCK();
968 
969 	return (ret);
970 }
971