2 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
3 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
26 * Rickard E. (Rik) Faith <faith@valinux.com>
27 * Gareth Hughes <gareth@valinux.com>
32 * The catch-all file for DRM device support, including module setup/teardown,
33 * open/close, and ioctl dispatch.
37 #if defined(__FreeBSD__)
38 #include <sys/limits.h>
39 #elif defined(__NetBSD__)
40 #include <sys/module.h>
44 #include "drm_sarea.h"
46 #ifdef DRM_DEBUG_DEFAULT_ON
47 int drm_debug_flag
= 1;
49 int drm_debug_flag
= 0;
52 static int drm_load(struct drm_device
*dev
);
53 static void drm_unload(struct drm_device
*dev
);
54 static drm_pci_id_list_t
*drm_find_description(int vendor
, int device
,
55 drm_pci_id_list_t
*idlist
);
57 #if defined(__FreeBSD__)
58 #define DRIVER_SOFTC(unit) \
59 ((struct drm_device *)devclass_get_softc(drm_devclass, unit))
61 MODULE_VERSION(drm
, 1);
62 MODULE_DEPEND(drm
, agp
, 1, 1, 1);
63 MODULE_DEPEND(drm
, pci
, 1, 1, 1);
64 MODULE_DEPEND(drm
, mem
, 1, 1, 1);
65 #elif defined(__NetBSD__)
66 #define DRIVER_SOFTC(kdev) drm_get_device_from_kdev(kdev)
69 static drm_ioctl_desc_t drm_ioctls
[256] = {
70 DRM_IOCTL_DEF(DRM_IOCTL_VERSION
, drm_version
, 0),
71 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE
, drm_getunique
, 0),
72 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC
, drm_getmagic
, 0),
73 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID
, drm_irq_by_busid
, DRM_MASTER
|DRM_ROOT_ONLY
),
74 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP
, drm_getmap
, 0),
75 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT
, drm_getclient
, 0),
76 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS
, drm_getstats
, 0),
77 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION
, drm_setversion
, DRM_MASTER
|DRM_ROOT_ONLY
),
79 DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE
, drm_setunique
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
80 DRM_IOCTL_DEF(DRM_IOCTL_BLOCK
, drm_noop
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
81 DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK
, drm_noop
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
82 DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC
, drm_authmagic
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
84 DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP
, drm_addmap_ioctl
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
85 DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP
, drm_rmmap_ioctl
, DRM_AUTH
),
87 DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX
, drm_setsareactx
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
88 DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX
, drm_getsareactx
, DRM_AUTH
),
90 DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX
, drm_addctx
, DRM_AUTH
|DRM_ROOT_ONLY
),
91 DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX
, drm_rmctx
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
92 DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX
, drm_modctx
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
93 DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX
, drm_getctx
, DRM_AUTH
),
94 DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX
, drm_switchctx
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
95 DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX
, drm_newctx
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
96 DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX
, drm_resctx
, DRM_AUTH
),
98 DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW
, drm_adddraw
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
99 DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW
, drm_rmdraw
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
101 DRM_IOCTL_DEF(DRM_IOCTL_LOCK
, drm_lock
, DRM_AUTH
),
102 DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK
, drm_unlock
, DRM_AUTH
),
104 DRM_IOCTL_DEF(DRM_IOCTL_FINISH
, drm_noop
, DRM_AUTH
),
106 DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS
, drm_addbufs
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
107 DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS
, drm_markbufs
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
108 DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS
, drm_infobufs
, DRM_AUTH
),
109 DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS
, drm_mapbufs
, DRM_AUTH
),
110 DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS
, drm_freebufs
, DRM_AUTH
),
111 DRM_IOCTL_DEF(DRM_IOCTL_DMA
, drm_dma
, DRM_AUTH
),
113 DRM_IOCTL_DEF(DRM_IOCTL_CONTROL
, drm_control
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
115 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE
, drm_agp_acquire_ioctl
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
116 DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE
, drm_agp_release_ioctl
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
117 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE
, drm_agp_enable_ioctl
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
118 DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO
, drm_agp_info_ioctl
, DRM_AUTH
),
119 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC
, drm_agp_alloc_ioctl
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
120 DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE
, drm_agp_free_ioctl
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
121 DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND
, drm_agp_bind_ioctl
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
122 DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND
, drm_agp_unbind_ioctl
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
124 DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC
, drm_sg_alloc_ioctl
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
125 DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE
, drm_sg_free
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
126 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK
, drm_wait_vblank
, 0),
127 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL
, drm_modeset_ctl
, 0),
128 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW
, drm_update_draw
, DRM_AUTH
|DRM_MASTER
|DRM_ROOT_ONLY
),
131 #if defined(__FreeBSD__)
132 static struct cdevsw drm_cdevsw
= {
133 .d_version
= D_VERSION
,
136 .d_ioctl
= drm_ioctl
,
140 .d_flags
= D_TRACKCLOSE
143 int drm_msi
= 1; /* Enable by default. */
144 TUNABLE_INT("hw.drm.msi", &drm_msi
);
146 static struct drm_msi_blacklist_entry drm_msi_blacklist
[] = {
147 {0x8086, 0x2772}, /* Intel i945G */ \
148 {0x8086, 0x27A2}, /* Intel i945GM */ \
149 {0x8086, 0x27AE}, /* Intel i945GME */ \
153 static int drm_msi_is_blacklisted(int vendor
, int device
)
157 for (i
= 0; drm_msi_blacklist
[i
].vendor
!= 0; i
++) {
158 if ((drm_msi_blacklist
[i
].vendor
== vendor
) &&
159 (drm_msi_blacklist
[i
].device
== device
)) {
167 int drm_probe(device_t kdev
, drm_pci_id_list_t
*idlist
)
169 drm_pci_id_list_t
*id_entry
;
171 #if __FreeBSD_version < 700010
174 if (!strcmp(device_get_name(kdev
), "drmsub"))
175 realdev
= device_get_parent(kdev
);
178 vendor
= pci_get_vendor(realdev
);
179 device
= pci_get_device(realdev
);
181 vendor
= pci_get_vendor(kdev
);
182 device
= pci_get_device(kdev
);
185 if (pci_get_class(kdev
) != PCIC_DISPLAY
186 || pci_get_subclass(kdev
) != PCIS_DISPLAY_VGA
)
189 id_entry
= drm_find_description(vendor
, device
, idlist
);
190 if (id_entry
!= NULL
) {
191 if (!device_get_desc(kdev
)) {
192 DRM_DEBUG("desc : %s\n", device_get_desc(kdev
));
193 device_set_desc(kdev
, id_entry
->name
);
201 int drm_attach(device_t kdev
, drm_pci_id_list_t
*idlist
)
203 struct drm_device
*dev
;
204 drm_pci_id_list_t
*id_entry
;
207 unit
= device_get_unit(kdev
);
208 dev
= device_get_softc(kdev
);
210 #if __FreeBSD_version < 700010
211 if (!strcmp(device_get_name(kdev
), "drmsub"))
212 dev
->device
= device_get_parent(kdev
);
218 dev
->devnode
= make_dev(&drm_cdevsw
,
225 #if __FreeBSD_version >= 700053
226 dev
->pci_domain
= pci_get_domain(dev
->device
);
230 dev
->pci_bus
= pci_get_bus(dev
->device
);
231 dev
->pci_slot
= pci_get_slot(dev
->device
);
232 dev
->pci_func
= pci_get_function(dev
->device
);
234 dev
->pci_vendor
= pci_get_vendor(dev
->device
);
235 dev
->pci_device
= pci_get_device(dev
->device
);
238 !drm_msi_is_blacklisted(dev
->pci_vendor
, dev
->pci_device
)) {
239 msicount
= pci_msi_count(dev
->device
);
240 DRM_DEBUG("MSI count = %d\n", msicount
);
244 if (pci_alloc_msi(dev
->device
, &msicount
) == 0) {
245 DRM_INFO("MSI enabled %d message(s)\n", msicount
);
246 dev
->msi_enabled
= 1;
251 dev
->irqr
= bus_alloc_resource_any(dev
->device
, SYS_RES_IRQ
,
252 &dev
->irqrid
, RF_SHAREABLE
);
257 dev
->irq
= (int) rman_get_start(dev
->irqr
);
259 mtx_init(&dev
->dev_lock
, "drmdev", NULL
, MTX_DEF
);
260 mtx_init(&dev
->irq_lock
, "drmirq", NULL
, MTX_DEF
);
261 mtx_init(&dev
->vbl_lock
, "drmvbl", NULL
, MTX_DEF
);
262 mtx_init(&dev
->drw_lock
, "drmdrw", NULL
, MTX_DEF
);
264 id_entry
= drm_find_description(dev
->pci_vendor
,
265 dev
->pci_device
, idlist
);
266 dev
->id_entry
= id_entry
;
268 return drm_load(dev
);
271 int drm_detach(device_t kdev
)
273 struct drm_device
*dev
;
275 dev
= device_get_softc(kdev
);
279 bus_release_resource(dev
->device
, SYS_RES_IRQ
, dev
->irqrid
, dev
->irqr
);
281 if (dev
->msi_enabled
) {
282 pci_release_msi(dev
->device
);
283 DRM_INFO("MSI released\n");
290 #define DRM_DEV_NAME "drm"
293 devclass_t drm_devclass
;
295 #elif defined(__NetBSD__)
298 * Mapping from device minor to struct drm_device.
299 * This is needed, because each driver (radeon, i915, etc.) has its own
300 * _cd structure, so we can't just lookup from _cd with minor.
302 struct drm_device
*drm_units
[DRM_MAXUNITS
];
304 struct cdevsw drm_cdevsw
= {
321 drm_probe(struct pci_attach_args
*pa
, drm_pci_id_list_t
*idlist
)
323 drm_pci_id_list_t
*id_entry
;
325 id_entry
= drm_find_description(PCI_VENDOR(pa
->pa_id
),
326 PCI_PRODUCT(pa
->pa_id
), idlist
);
327 if (id_entry
!= NULL
) {
335 drm_attach(device_t kdev
, struct pci_attach_args
*pa
, drm_pci_id_list_t
*idlist
)
338 struct drm_device
*dev
;
339 int unit
, parent_unit
;
341 unit
= device_unit(kdev
);
342 if (unit
< 0 || unit
>= DRM_MAXUNITS
)
343 panic("drm_attach: device unit %d invalid", unit
);
344 if (drm_units
[unit
] != NULL
)
345 panic("drm_attach: unit %d already attached", unit
);
348 * this is kind of ugly but we fake up the pci "domain" by using
349 * our pci unit number, so, find our parent pci device's unit...
353 parent_dev
= device_parent(parent_dev
);
354 } while (parent_dev
&& !device_is_a(parent_dev
, "pci"));
355 parent_unit
= device_unit(parent_dev
);
357 panic("drm_attach: device parent_unit %d invalid", parent_unit
);
359 dev
= device_private(kdev
);
361 drm_units
[unit
] = dev
;
363 for (unit
= 0; unit
< DRM_MAX_PCI_RESOURCE
; unit
++)
365 dev
->pci_map_data
[unit
].mapped
= 0;
366 dev
->pci_map_data
[unit
].maptype
=
367 pci_mapreg_type(pa
->pa_pc
, pa
->pa_tag
,
368 PCI_MAPREG_START
+ unit
*4);
369 if (pci_mapreg_info(pa
->pa_pc
, pa
->pa_tag
,
370 PCI_MAPREG_START
+ unit
*4,
371 dev
->pci_map_data
[unit
].maptype
,
372 &(dev
->pci_map_data
[unit
].base
),
373 &(dev
->pci_map_data
[unit
].size
),
374 &(dev
->pci_map_data
[unit
].flags
)))
376 DRM_DEBUG("pci_mapreg info for %d failed\n",
377 PCI_MAPREG_START
+ unit
*4);
378 dev
->pci_map_data
[unit
].base
= 0;
379 dev
->pci_map_data
[unit
].size
= 0;
381 if (dev
->pci_map_data
[unit
].maptype
== PCI_MAPREG_TYPE_MEM
)
382 dev
->pci_map_data
[unit
].flags
|= BUS_SPACE_MAP_LINEAR
;
383 if (dev
->pci_map_data
[unit
].maptype
==
384 (PCI_MAPREG_TYPE_MEM
| PCI_MAPREG_MEM_TYPE_64BIT
))
385 dev
->pci_map_data
[unit
].flags
|= BUS_SPACE_MAP_LINEAR
;
386 DRM_DEBUG("pci resource %d: type=%d, base=%lx, size=%zx, flags=%x\n",
387 unit
, dev
->pci_map_data
[unit
].maptype
,
388 (unsigned long)dev
->pci_map_data
[unit
].base
,
389 dev
->pci_map_data
[unit
].size
,
390 dev
->pci_map_data
[unit
].flags
);
392 for (unit
= 0; unit
< DRM_MAX_PCI_RESOURCE
; unit
++) {
393 dev
->agp_map_data
[unit
].mapped
= 0;
394 dev
->agp_map_data
[unit
].maptype
= PCI_MAPREG_TYPE_MEM
;
397 mutex_init(&dev
->dev_lock
, MUTEX_DEFAULT
, IPL_NONE
);
398 mutex_init(&dev
->irq_lock
, MUTEX_DEFAULT
, IPL_VM
);
399 mutex_init(&dev
->vbl_lock
, MUTEX_DEFAULT
, IPL_NONE
);
400 mutex_init(&dev
->drw_lock
, MUTEX_DEFAULT
, IPL_NONE
);
402 memcpy(&dev
->pa
, pa
, sizeof(dev
->pa
));
404 dev
->irq
= pa
->pa_intrline
;
405 dev
->pci_domain
= parent_unit
;
406 dev
->pci_bus
= pa
->pa_bus
;
407 dev
->pci_slot
= pa
->pa_device
;
408 dev
->pci_func
= pa
->pa_function
;
409 dev
->pci_vendor
= PCI_VENDOR(pa
->pa_id
);
410 dev
->pci_device
= PCI_PRODUCT(pa
->pa_id
);
412 dev
->id_entry
= drm_find_description(PCI_VENDOR(pa
->pa_id
),
413 PCI_PRODUCT(pa
->pa_id
), idlist
);
415 aprint_normal(": %s\n", dev
->id_entry
->name
);
420 drm_detach(device_t self
, int flags
)
422 struct drm_device
*dev
= device_private(self
);
430 drm_units
[device_unit(self
)] = NULL
;
432 free(dev
->driver
, DRM_MEM_DRIVER
);
439 drm_pci_id_list_t
*drm_find_description(int vendor
, int device
,
440 drm_pci_id_list_t
*idlist
)
444 for (i
= 0; idlist
[i
].vendor
!= 0; i
++) {
445 if ((idlist
[i
].vendor
== vendor
) &&
446 ((idlist
[i
].device
== device
) ||
447 (idlist
[i
].device
== 0))) {
454 static int drm_firstopen(struct drm_device
*dev
)
456 drm_local_map_t
*map
;
459 DRM_SPINLOCK_ASSERT(&dev
->dev_lock
);
461 /* prebuild the SAREA */
462 i
= drm_addmap(dev
, 0, SAREA_MAX
, _DRM_SHM
,
463 _DRM_CONTAINS_LOCK
, &map
);
467 if (dev
->driver
->firstopen
)
468 dev
->driver
->firstopen(dev
);
472 if (drm_core_check_feature(dev
, DRIVER_HAVE_DMA
)) {
473 i
= drm_dma_setup(dev
);
478 for (i
= 0; i
< DRM_HASH_SIZE
; i
++) {
479 dev
->magiclist
[i
].head
= NULL
;
480 dev
->magiclist
[i
].tail
= NULL
;
483 dev
->lock
.lock_queue
= 0;
484 dev
->irq_enabled
= 0;
485 dev
->context_flag
= 0;
486 dev
->last_context
= 0;
489 #if defined(__FreeBSD__)
490 dev
->buf_sigio
= NULL
;
491 #elif defined(__NetBSD__)
500 static int drm_lastclose(struct drm_device
*dev
)
502 drm_magic_entry_t
*pt
, *next
;
503 drm_local_map_t
*map
, *mapsave
;
506 DRM_SPINLOCK_ASSERT(&dev
->dev_lock
);
510 if (dev
->driver
->lastclose
!= NULL
)
511 dev
->driver
->lastclose(dev
);
513 if (dev
->irq_enabled
)
514 drm_irq_uninstall(dev
);
517 free(dev
->unique
, DRM_MEM_DRIVER
);
522 for (i
= 0; i
< DRM_HASH_SIZE
; i
++) {
523 for (pt
= dev
->magiclist
[i
].head
; pt
; pt
= next
) {
525 free(pt
, DRM_MEM_MAGIC
);
527 dev
->magiclist
[i
].head
= dev
->magiclist
[i
].tail
= NULL
;
531 drm_drawable_free_all(dev
);
534 /* Clear AGP information */
536 drm_agp_mem_t
*entry
;
537 drm_agp_mem_t
*nexte
;
539 /* Remove AGP resources, but leave dev->agp intact until
540 * drm_unload is called.
542 for (entry
= dev
->agp
->memory
; entry
; entry
= nexte
) {
545 drm_agp_unbind_memory(entry
->handle
);
546 drm_agp_free_memory(entry
->handle
);
547 free(entry
, DRM_MEM_AGPLISTS
);
549 dev
->agp
->memory
= NULL
;
551 if (dev
->agp
->acquired
)
552 drm_agp_release(dev
);
554 dev
->agp
->acquired
= 0;
555 dev
->agp
->enabled
= 0;
557 if (dev
->sg
!= NULL
) {
558 drm_sg_cleanup(dev
->sg
);
562 TAILQ_FOREACH_SAFE(map
, &dev
->maplist
, link
, mapsave
) {
563 if (!(map
->flags
& _DRM_DRIVER
))
567 drm_dma_takedown(dev
);
568 if (dev
->lock
.hw_lock
) {
569 dev
->lock
.hw_lock
= NULL
; /* SHM removed */
570 dev
->lock
.file_priv
= NULL
;
571 DRM_WAKEUP_INT((void *)&dev
->lock
.lock_queue
);
577 static int drm_load(struct drm_device
*dev
)
583 TAILQ_INIT(&dev
->maplist
);
586 drm_sysctl_init(dev
);
587 TAILQ_INIT(&dev
->files
);
590 dev
->types
[0] = _DRM_STAT_LOCK
;
591 dev
->types
[1] = _DRM_STAT_OPENS
;
592 dev
->types
[2] = _DRM_STAT_CLOSES
;
593 dev
->types
[3] = _DRM_STAT_IOCTLS
;
594 dev
->types
[4] = _DRM_STAT_LOCKS
;
595 dev
->types
[5] = _DRM_STAT_UNLOCKS
;
597 for (i
= 0; i
< DRM_ARRAY_SIZE(dev
->counts
); i
++)
598 atomic_set(&dev
->counts
[i
], 0);
600 if (dev
->driver
->load
!= NULL
) {
602 /* Shared code returns -errno. */
603 retcode
= -dev
->driver
->load(dev
,
604 dev
->id_entry
->driver_private
);
605 #if defined(__FreeBSD__)
606 if (pci_enable_busmaster(dev
->device
))
607 DRM_ERROR("Request to enable bus-master failed.\n");
614 if (drm_core_has_AGP(dev
)) {
615 if (drm_device_is_agp(dev
))
616 dev
->agp
= drm_agp_init(dev
);
617 if (drm_core_check_feature(dev
, DRIVER_REQUIRE_AGP
) &&
619 DRM_ERROR("Card isn't AGP, or couldn't initialize "
624 if (dev
->agp
!= NULL
) {
625 if (drm_mtrr_add(dev
->agp
->info
.ai_aperture_base
,
626 dev
->agp
->info
.ai_aperture_size
, DRM_MTRR_WC
) == 0)
631 retcode
= drm_ctxbitmap_init(dev
);
633 DRM_ERROR("Cannot allocate memory for context bitmap.\n");
637 #if defined(__FreeBSD__)
638 dev
->drw_unrhdr
= new_unrhdr(1, INT_MAX
, NULL
);
639 if (dev
->drw_unrhdr
== NULL
) {
640 DRM_ERROR("Couldn't allocate drawable number allocator\n");
647 #if defined(__NetBSD__)
648 aprint_normal_dev(dev
->device
,
652 "Initialized %s %d.%d.%d %s\n",
656 dev
->driver
->patchlevel
,
662 #if defined(__FreeBSD__)
663 drm_sysctl_cleanup(dev
);
668 #if defined(__FreeBSD__)
669 destroy_dev(dev
->devnode
);
672 DRM_SPINUNINIT(&dev
->drw_lock
);
673 DRM_SPINUNINIT(&dev
->vbl_lock
);
674 DRM_SPINUNINIT(&dev
->irq_lock
);
675 DRM_SPINUNINIT(&dev
->dev_lock
);
680 static void drm_unload(struct drm_device
*dev
)
682 #if defined(__FreeBSD__)
688 #if defined(__FreeBSD__)
689 drm_sysctl_cleanup(dev
);
690 destroy_dev(dev
->devnode
);
693 drm_ctxbitmap_cleanup(dev
);
695 if (dev
->agp
&& dev
->agp
->mtrr
) {
696 int __unused retcode
;
698 retcode
= drm_mtrr_del(0,
699 dev
->agp
->info
.ai_aperture_base
,
700 dev
->agp
->info
.ai_aperture_size
, DRM_MTRR_WC
);
701 DRM_DEBUG("mtrr_del = %d", retcode
);
708 drm_vblank_cleanup(dev
);
710 #if defined(__FreeBSD__)
711 /* Clean up PCI resources allocated by drm_bufs.c. We're not really
712 * worried about resource consumption while the DRM is inactive (between
713 * lastclose and firstopen or unload) because these aren't actually
714 * taking up KVA, just keeping the PCI resource allocated.
716 for (i
= 0; i
< DRM_MAX_PCI_RESOURCE
; i
++) {
717 if (dev
->pcir
[i
] == NULL
)
719 bus_release_resource(dev
->device
, SYS_RES_MEMORY
,
720 dev
->pcirid
[i
], dev
->pcir
[i
]);
726 free(dev
->agp
, DRM_MEM_AGPLISTS
);
730 if (dev
->driver
->unload
!= NULL
) {
732 dev
->driver
->unload(dev
);
736 #if defined(__FreeBSD__)
737 delete_unrhdr(dev
->drw_unrhdr
);
742 #if defined(__FreeBSD__)
743 if (pci_disable_busmaster(dev
->device
))
744 DRM_ERROR("Request to disable bus-master failed.\n");
747 DRM_SPINUNINIT(&dev
->drw_lock
);
748 DRM_SPINUNINIT(&dev
->vbl_lock
);
749 DRM_SPINUNINIT(&dev
->irq_lock
);
750 DRM_SPINUNINIT(&dev
->dev_lock
);
753 int drm_version(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
755 struct drm_version
*drmvers
= data
;
758 #define DRM_COPY( name, value ) \
759 len = strlen( value ); \
760 if ( len > name##_len ) len = name##_len; \
761 name##_len = strlen( value ); \
762 if ( len && name ) { \
763 if ( DRM_COPY_TO_USER( name, value, len ) ) \
767 drmvers
->version_major
= dev
->driver
->major
;
768 drmvers
->version_minor
= dev
->driver
->minor
;
769 drmvers
->version_patchlevel
= dev
->driver
->patchlevel
;
771 DRM_COPY(drmvers
->name
, dev
->driver
->name
);
772 DRM_COPY(drmvers
->date
, dev
->driver
->date
);
773 DRM_COPY(drmvers
->desc
, dev
->driver
->desc
);
778 int drm_open(DRM_CDEV kdev
, int flags
, int fmt
, DRM_STRUCTCDEVPROC
*p
)
780 struct drm_device
*dev
= NULL
;
783 #if defined(__FreeBSD__)
784 dev
= DRIVER_SOFTC(dev2unit(kdev
));
785 #elif defined(__NetBSD__)
786 dev
= DRIVER_SOFTC(kdev
);
792 DRM_DEBUG("open_count = %d\n", dev
->open_count
);
794 retcode
= drm_open_helper(kdev
, flags
, fmt
, DRM_CDEVPROC_REAL(p
), dev
);
797 atomic_inc(&dev
->counts
[_DRM_STAT_OPENS
]);
799 #if defined(__FreeBSD__)
800 device_busy(dev
->device
);
802 if (!dev
->open_count
++)
803 retcode
= drm_firstopen(dev
);
810 #if defined(__FreeBSD__)
811 void drm_close(void *data
)
812 #elif defined(__NetBSD__)
814 drm_close(dev_t kdev
, int flags
, int fmt
, struct lwp
*l
)
817 struct drm_file
*file_priv
;
818 struct drm_device
*dev
;
821 #if defined(__FreeBSD__)
823 dev
= file_priv
->dev
;
824 #elif defined(__NetBSD__)
825 dev
= DRIVER_SOFTC(kdev
);
828 DRM_DEBUG("open_count = %d\n", dev
->open_count
);
832 #if defined(__NetBSD__)
833 file_priv
= drm_find_file_by_proc(dev
, l
->l_proc
);
834 if (file_priv
== NULL
) {
836 DRM_ERROR("can't find authenticator\n");
841 if (dev
->driver
->preclose
!= NULL
)
842 dev
->driver
->preclose(dev
, file_priv
);
844 /* ========================================================
845 * Begin inline drm_release
848 #if defined(__FreeBSD__)
849 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
850 DRM_CURRENTPID
, (long)dev
->device
, dev
->open_count
);
851 #elif defined(__NetBSD__)
852 DRM_DEBUG("pid = %d, device = 0x%p, open_count = %d\n",
853 DRM_CURRENTPID
, dev
->device
, dev
->open_count
);
856 if (dev
->lock
.hw_lock
&& _DRM_LOCK_IS_HELD(dev
->lock
.hw_lock
->lock
)
857 && dev
->lock
.file_priv
== file_priv
) {
858 DRM_DEBUG("Process %d dead, freeing lock for context %d\n",
860 _DRM_LOCKING_CONTEXT(dev
->lock
.hw_lock
->lock
));
861 if (dev
->driver
->reclaim_buffers_locked
!= NULL
)
862 dev
->driver
->reclaim_buffers_locked(dev
, file_priv
);
864 drm_lock_free(&dev
->lock
,
865 _DRM_LOCKING_CONTEXT(dev
->lock
.hw_lock
->lock
));
867 /* FIXME: may require heavy-handed reset of
868 hardware at this point, possibly
869 processed via a callback to the X
871 } else if (dev
->driver
->reclaim_buffers_locked
!= NULL
&&
872 dev
->lock
.hw_lock
!= NULL
) {
873 /* The lock is required to reclaim buffers */
875 if (!dev
->lock
.hw_lock
) {
876 /* Device has been unregistered */
880 if (drm_lock_take(&dev
->lock
, DRM_KERNEL_CONTEXT
)) {
881 dev
->lock
.file_priv
= file_priv
;
882 dev
->lock
.lock_time
= jiffies
;
883 atomic_inc(&dev
->counts
[_DRM_STAT_LOCKS
]);
884 break; /* Got lock */
887 #if defined(__FreeBSD__)
888 retcode
= mtx_sleep((void *)&dev
->lock
.lock_queue
,
889 &dev
->dev_lock
, PCATCH
, "drmlk2", 0);
890 #elif defined(__NetBSD__)
891 retcode
= mtsleep((void *)&dev
->lock
.lock_queue
,
892 PCATCH
, "drmlk2", 0, &dev
->dev_lock
);
898 dev
->driver
->reclaim_buffers_locked(dev
, file_priv
);
899 drm_lock_free(&dev
->lock
, DRM_KERNEL_CONTEXT
);
903 if (drm_core_check_feature(dev
, DRIVER_HAVE_DMA
) &&
904 !dev
->driver
->reclaim_buffers_locked
)
905 drm_reclaim_buffers(dev
, file_priv
);
907 #if defined(__FreeBSD__)
908 funsetown(&dev
->buf_sigio
);
913 if (dev
->driver
->postclose
!= NULL
)
914 dev
->driver
->postclose(dev
, file_priv
);
915 TAILQ_REMOVE(&dev
->files
, file_priv
, link
);
916 free(file_priv
, DRM_MEM_FILES
);
918 /* ========================================================
919 * End inline drm_release
922 atomic_inc(&dev
->counts
[_DRM_STAT_CLOSES
]);
923 #if defined(__FreeBSD__)
924 device_unbusy(dev
->device
);
926 #if defined(__NetBSD__)
927 /* On NetBSD, close will only be called once */
928 DRM_DEBUG("setting open_count %d to 1\n", (int)dev
->open_count
);
929 while (dev
->open_count
!= 1) {
931 * XXXMRG probably should assert that we are freeing
932 * one of these each time. i think.
934 if (!TAILQ_EMPTY(&dev
->files
)) {
935 file_priv
= TAILQ_FIRST(&dev
->files
);
936 TAILQ_REMOVE(&dev
->files
, file_priv
, link
);
941 if (--dev
->open_count
== 0) {
942 retcode
= drm_lastclose(dev
);
947 #if defined(__NetBSD__)
952 /* drm_ioctl is called whenever a process performs an ioctl on /dev/drm.
954 int drm_ioctl(DRM_CDEV kdev
, u_long cmd
, DRM_IOCTL_DATA data
, int flags
,
955 DRM_STRUCTCDEVPROC
*p
)
957 struct drm_device
*dev
= drm_get_device_from_kdev(kdev
);
959 drm_ioctl_desc_t
*ioctl
;
960 int (*func
)(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
);
961 int nr
= DRM_IOCTL_NR(cmd
);
962 int is_driver_ioctl
= 0;
963 struct drm_file
*file_priv
;
965 #if defined(__FreeBSD__)
966 retcode
= devfs_get_cdevpriv((void **)&file_priv
);
968 DRM_ERROR("can't find authenticator\n");
971 #elif defined(__NetBSD__)
973 file_priv
= drm_find_file_by_proc(dev
, p
->l_proc
);
975 if (file_priv
== NULL
) {
976 DRM_ERROR("can't find authenticator\n");
981 atomic_inc(&dev
->counts
[_DRM_STAT_IOCTLS
]);
982 ++file_priv
->ioctl_count
;
984 #if defined(__FreeBSD__)
985 DRM_DEBUG("pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n",
986 DRM_CURRENTPID
, cmd
, nr
, (long)dev
->device
,
987 file_priv
->authenticated
);
988 #elif defined(__NetBSD__)
989 DRM_DEBUG("pid=%d, cmd=0x%02lx, nr=0x%02x, dev %p, auth=%d\n",
990 DRM_CURRENTPID
, cmd
, nr
, dev
->device
,
991 file_priv
->authenticated
);
999 #if defined(__FreeBSD__)
1001 return fsetown(*(int *)data
, &dev
->buf_sigio
);
1004 *(int *) data
= fgetown(&dev
->buf_sigio
);
1007 #if defined(__NetBSD__)
1011 return fsetown(&dev
->buf_pgid
, cmd
, data
);
1016 return fgetown(dev
->buf_pgid
, cmd
, data
);
1020 if (IOCGROUP(cmd
) != DRM_IOCTL_BASE
) {
1021 DRM_DEBUG("Bad ioctl group 0x%x\n", (int)IOCGROUP(cmd
));
1025 ioctl
= &drm_ioctls
[nr
];
1026 /* It's not a core DRM ioctl, try driver-specific. */
1027 if (ioctl
->func
== NULL
&& nr
>= DRM_COMMAND_BASE
) {
1028 /* The array entries begin at DRM_COMMAND_BASE ioctl nr */
1029 nr
-= DRM_COMMAND_BASE
;
1030 if (nr
> dev
->driver
->max_ioctl
) {
1031 DRM_DEBUG("Bad driver ioctl number, 0x%x (of 0x%x)\n",
1032 nr
, dev
->driver
->max_ioctl
);
1035 ioctl
= &dev
->driver
->ioctls
[nr
];
1036 is_driver_ioctl
= 1;
1041 DRM_DEBUG("no function\n");
1045 if (((ioctl
->flags
& DRM_ROOT_ONLY
) && !DRM_SUSER(DRM_CDEVPROC_REAL(p
))) ||
1046 ((ioctl
->flags
& DRM_AUTH
) && !file_priv
->authenticated
) ||
1047 ((ioctl
->flags
& DRM_MASTER
) && !file_priv
->master
))
1050 if (is_driver_ioctl
) {
1052 /* shared code returns -errno */
1053 retcode
= -func(dev
, data
, file_priv
);
1056 retcode
= func(dev
, data
, file_priv
);
1060 DRM_DEBUG(" returning %d\n", retcode
);
1065 drm_local_map_t
*drm_getsarea(struct drm_device
*dev
)
1067 drm_local_map_t
*map
;
1069 DRM_SPINLOCK_ASSERT(&dev
->dev_lock
);
1070 TAILQ_FOREACH(map
, &dev
->maplist
, link
) {
1071 if (map
->type
== _DRM_SHM
&& (map
->flags
& _DRM_CONTAINS_LOCK
))
1080 #include <sys/sysproto.h>
1082 MODULE_DEPEND(DRIVER_NAME
, linux
, 1, 1, 1);
1084 #define LINUX_IOCTL_DRM_MIN 0x6400
1085 #define LINUX_IOCTL_DRM_MAX 0x64ff
1087 static linux_ioctl_function_t drm_linux_ioctl
;
1088 static struct linux_ioctl_handler drm_handler
= {drm_linux_ioctl
,
1089 LINUX_IOCTL_DRM_MIN
, LINUX_IOCTL_DRM_MAX
};
1091 SYSINIT(drm_register
, SI_SUB_KLD
, SI_ORDER_MIDDLE
,
1092 linux_ioctl_register_handler
, &drm_handler
);
1093 SYSUNINIT(drm_unregister
, SI_SUB_KLD
, SI_ORDER_MIDDLE
,
1094 linux_ioctl_unregister_handler
, &drm_handler
);
1096 /* The bits for in/out are switched on Linux */
1097 #define LINUX_IOC_IN IOC_OUT
1098 #define LINUX_IOC_OUT IOC_IN
1101 drm_linux_ioctl(DRM_STRUCTPROC
*p
, struct linux_ioctl_args
* args
)
1104 int cmd
= args
->cmd
;
1106 args
->cmd
&= ~(LINUX_IOC_IN
| LINUX_IOC_OUT
);
1107 if (cmd
& LINUX_IOC_IN
)
1108 args
->cmd
|= IOC_IN
;
1109 if (cmd
& LINUX_IOC_OUT
)
1110 args
->cmd
|= IOC_OUT
;
1112 error
= ioctl(p
, (struct ioctl_args
*)args
);
1116 #endif /* DRM_LINUX */
1118 #if defined(__NetBSD__)
1119 /* Module support */
1121 MODULE(MODULE_CLASS_MISC
, drm
, NULL
);
1124 drm_modcmd(modcmd_t cmd
, void *arg
)
1127 int bmajor
= -1, cmajor
= -1;
1130 case MODULE_CMD_INIT
:
1131 return devsw_attach("drm", NULL
, &bmajor
, &drm_cdevsw
, &cmajor
);
1132 case MODULE_CMD_FINI
:
1133 devsw_detach(NULL
, &drm_cdevsw
);
1139 if (cmd
== MODULE_CMD_INIT
)
1145 #endif /* __NetBSD__ */