blob: ae86db50d7baa3b78fb2f1f6ac378e14d4ac29a4 [file] [log] [blame]
kz15163460405de2006-09-28 01:41:18 -07001/*
kz15163460405de2006-09-28 01:41:18 -07002 * drm_drv.h -- Generic driver template -*- linux-c -*-
3 * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
4 */
5/*
6 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
7 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +08008 * Copyright (c) 2009, Intel Corporation.
kz15163460405de2006-09-28 01:41:18 -07009 * All Rights Reserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 *
30 * Authors:
31 * Rickard E. (Rik) Faith <faith@valinux.com>
32 * Gareth Hughes <gareth@valinux.com>
33 *
34 */
35
zw161486e92e3a82007-05-09 19:58:49 -070036/*
miao chen - Sun Microsystems - Beijing Chinad0231072009-02-17 16:22:10 +080037 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
zw161486e92e3a82007-05-09 19:58:49 -070038 * Use is subject to license terms.
39 */
40
kz15163460405de2006-09-28 01:41:18 -070041#include "drmP.h"
42#include "drm.h"
43#include "drm_sarea.h"
44
45int drm_debug_flag = 1;
46
47#define DRIVER_IOCTL_COUNT 256
miao chen - Sun Microsystems - Beijing Chinaee33b1b2008-11-06 13:34:06 +080048drm_ioctl_desc_t drm_ioctls[DRIVER_IOCTL_COUNT] = {
49 [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] =
50 {drm_version, 0},
51 [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] =
52 {drm_getunique, 0},
53 [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] =
54 {drm_getmagic, 0},
55 [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] =
56 {drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY},
57 [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] =
58 {drm_getmap, 0},
59 [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] =
60 {drm_getclient, 0},
61 [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] =
62 {drm_getstats, 0},
63 [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] =
64 {drm_setversion, DRM_MASTER|DRM_ROOT_ONLY},
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +080065 [DRM_IOCTL_NR(DRM_IOCTL_MODESET_CTL)] =
66 {drm_modeset_ctl, 0},
67 [DRM_IOCTL_NR(DRM_IOCTL_GEM_CLOSE)] =
68 {drm_gem_close_ioctl, 0},
69 [DRM_IOCTL_NR(DRM_IOCTL_GEM_FLINK)] =
70 {drm_gem_flink_ioctl, DRM_AUTH},
71 [DRM_IOCTL_NR(DRM_IOCTL_GEM_OPEN)] =
72 {drm_gem_open_ioctl, DRM_AUTH},
miao chen - Sun Microsystems - Beijing Chinaee33b1b2008-11-06 13:34:06 +080073 [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] =
74 {drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
75 [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] =
76 {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
77 [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] =
78 {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
79 [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] =
80 {drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
81 [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] =
82 {drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
83 [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] =
84 {drm_rmmap_ioctl, DRM_AUTH},
85 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] =
86 {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
87 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] =
88 {drm_getsareactx, DRM_AUTH},
89 [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] =
90 {drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
91 [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] =
92 {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
93 [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] =
94 {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
95 [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] =
96 {drm_getctx, DRM_AUTH},
97 [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] =
98 {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
99 [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] =
100 {drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
101 [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] =
102 {drm_resctx, DRM_AUTH},
103 [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] =
104 {drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
105 [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] =
106 {drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
107 [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] =
108 {drm_lock, DRM_AUTH},
109 [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] =
110 {drm_unlock, DRM_AUTH},
111 [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] =
112 {drm_noop, DRM_AUTH},
113 [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] =
114 {drm_addbufs_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
115 [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] =
116 {drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
117 [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] =
118 {drm_infobufs, DRM_AUTH},
119 [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] =
120 {drm_mapbufs, DRM_AUTH},
121 [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] =
122 {drm_freebufs, DRM_AUTH},
123 [DRM_IOCTL_NR(DRM_IOCTL_DMA)] =
124 {drm_dma, DRM_AUTH},
125 [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] =
126 {drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
127 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] =
128 {drm_agp_acquire, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
129 [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] =
130 {drm_agp_release, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
131 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] =
132 {drm_agp_enable, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
133 [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] =
134 {drm_agp_info, DRM_AUTH},
135 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] =
136 {drm_agp_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
137 [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] =
138 {drm_agp_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
139 [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] =
140 {drm_agp_bind, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
141 [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] =
142 {drm_agp_unbind, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
143 [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] =
144 {drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
145 [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] =
146 {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
147 [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] =
148 {drm_wait_vblank, 0},
miao chen - Sun Microsystems - Beijing Chinad0231072009-02-17 16:22:10 +0800149 [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] =
150 {drm_update_draw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
miao chen - Sun Microsystems - Beijing Chinaee33b1b2008-11-06 13:34:06 +0800151};
kz15163460405de2006-09-28 01:41:18 -0700152
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +0800153extern void idr_list_free(struct idr_list *head);
154
kz15163460405de2006-09-28 01:41:18 -0700155const char *
156drm_find_description(int vendor, int device, drm_pci_id_list_t *idlist)
157{
158 int i = 0;
159 for (i = 0; idlist[i].vendor != 0; i++) {
160 if ((idlist[i].vendor == vendor) &&
cg149915d0538f62008-01-09 19:45:15 -0800161 (idlist[i].device == device)) {
kz15163460405de2006-09-28 01:41:18 -0700162 return (idlist[i].name);
163 }
164 }
165 return ((char *)NULL);
166}
167
168static int
cg149915d0538f62008-01-09 19:45:15 -0800169drm_firstopen(drm_device_t *dev)
kz15163460405de2006-09-28 01:41:18 -0700170{
171 int i;
cg149915d0538f62008-01-09 19:45:15 -0800172 int retval;
173 drm_local_map_t *map;
kz15163460405de2006-09-28 01:41:18 -0700174
cg149915d0538f62008-01-09 19:45:15 -0800175 /* prebuild the SAREA */
176 retval = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM,
177 _DRM_CONTAINS_LOCK, &map);
178 if (retval != 0) {
179 DRM_ERROR("firstopen: failed to prebuild SAREA");
180 return (retval);
181 }
182
183 if (dev->driver->use_agp) {
184 DRM_DEBUG("drm_firstopen: use_agp=%d", dev->driver->use_agp);
185 if (drm_device_is_agp(dev))
186 dev->agp = drm_agp_init(dev);
187 if (dev->driver->require_agp && dev->agp == NULL) {
188 DRM_ERROR("couldn't initialize AGP");
189 return (EIO);
190 }
191 }
192
193 if (dev->driver->firstopen)
194 retval = dev->driver->firstopen(dev);
195
196 if (retval != 0) {
197 DRM_ERROR("drm_firstopen: driver-specific firstopen failed");
198 return (retval);
199 }
kz15163460405de2006-09-28 01:41:18 -0700200
201 dev->buf_use = 0;
202
cg149915d0538f62008-01-09 19:45:15 -0800203 if (dev->driver->use_dma) {
kz15163460405de2006-09-28 01:41:18 -0700204 i = drm_dma_setup(dev);
205 if (i != 0)
206 return (i);
207 }
208 dev->counters = 6;
209 dev->types[0] = _DRM_STAT_LOCK;
210 dev->types[1] = _DRM_STAT_OPENS;
211 dev->types[2] = _DRM_STAT_CLOSES;
212 dev->types[3] = _DRM_STAT_IOCTLS;
213 dev->types[4] = _DRM_STAT_LOCKS;
214 dev->types[5] = _DRM_STAT_UNLOCKS;
215
216 for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++)
217 *(&dev->counts[i]) = 0;
218
219 for (i = 0; i < DRM_HASH_SIZE; i++) {
220 dev->magiclist[i].head = NULL;
221 dev->magiclist[i].tail = NULL;
222 }
223
kz15163460405de2006-09-28 01:41:18 -0700224 dev->irq_enabled = 0;
225 dev->context_flag = 0;
226 dev->last_context = 0;
227 dev->if_version = 0;
228
cg149915d0538f62008-01-09 19:45:15 -0800229 return (0);
kz15163460405de2006-09-28 01:41:18 -0700230}
231
232/* Free resources associated with the DRM on the last close. */
233static int
cg149915d0538f62008-01-09 19:45:15 -0800234drm_lastclose(drm_device_t *dev)
kz15163460405de2006-09-28 01:41:18 -0700235{
236 drm_magic_entry_t *pt, *next;
237 drm_local_map_t *map, *mapsave;
238 int i;
239
240 DRM_SPINLOCK_ASSERT(&dev->dev_lock);
kz15163460405de2006-09-28 01:41:18 -0700241
cg149915d0538f62008-01-09 19:45:15 -0800242 if (dev->driver->lastclose != NULL)
243 dev->driver->lastclose(dev);
kz15163460405de2006-09-28 01:41:18 -0700244
245 if (dev->irq_enabled)
246 (void) drm_irq_uninstall(dev);
247
248 if (dev->unique) {
249 drm_free(dev->unique, dev->unique_len + 1, DRM_MEM_DRIVER);
250 dev->unique = NULL;
251 dev->unique_len = 0;
252 }
253
254 /* Clear pid list */
255 for (i = 0; i < DRM_HASH_SIZE; i++) {
256 for (pt = dev->magiclist[i].head; pt; pt = next) {
257 next = pt->next;
258 drm_free(pt, sizeof (*pt), DRM_MEM_MAGIC);
259 }
260 dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
261 }
262
263 /* Clear AGP information */
264 if (dev->agp) {
265 drm_agp_mem_t *entry;
266 drm_agp_mem_t *nexte;
267
268 /*
269 * Remove AGP resources, but leave dev->agp
270 * intact until drm_cleanup is called.
271 */
272 for (entry = dev->agp->memory; entry; entry = nexte) {
273 nexte = entry->next;
274 if (entry->bound)
275 (void) drm_agp_unbind_memory(
cg149915d0538f62008-01-09 19:45:15 -0800276 (unsigned long)entry->handle, dev);
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +0800277 (void) drm_agp_free_memory(entry->handle, dev);
kz15163460405de2006-09-28 01:41:18 -0700278 drm_free(entry, sizeof (*entry), DRM_MEM_AGPLISTS);
279 }
280 dev->agp->memory = NULL;
281
282 if (dev->agp->acquired)
283 (void) drm_agp_do_release(dev);
284
285 dev->agp->acquired = 0;
286 dev->agp->enabled = 0;
cg149915d0538f62008-01-09 19:45:15 -0800287 drm_agp_fini(dev);
kz15163460405de2006-09-28 01:41:18 -0700288 }
cg149915d0538f62008-01-09 19:45:15 -0800289
kz15163460405de2006-09-28 01:41:18 -0700290 if (dev->sg != NULL) {
cg149915d0538f62008-01-09 19:45:15 -0800291 drm_sg_mem_t *entry;
292 entry = dev->sg;
kz15163460405de2006-09-28 01:41:18 -0700293 dev->sg = NULL;
cg149915d0538f62008-01-09 19:45:15 -0800294 drm_sg_cleanup(dev, entry);
kz15163460405de2006-09-28 01:41:18 -0700295 }
296
cg149915d0538f62008-01-09 19:45:15 -0800297
kz15163460405de2006-09-28 01:41:18 -0700298 /* Clean up maps that weren't set up by the driver. */
299 TAILQ_FOREACH_SAFE(map, &dev->maplist, link, mapsave) {
300 if (!map->kernel_owned)
301 drm_rmmap(dev, map);
302 }
303
304 drm_dma_takedown(dev);
305 if (dev->lock.hw_lock) {
306 dev->lock.hw_lock = NULL; /* SHM removed */
307 dev->lock.filp = NULL;
308
309 mutex_enter(&(dev->lock.lock_mutex));
310 cv_broadcast(&(dev->lock.lock_cv));
311 mutex_exit(&(dev->lock.lock_mutex));
312 }
313
314 return (0);
315}
316
317static int
cg149915d0538f62008-01-09 19:45:15 -0800318drm_load(drm_device_t *dev)
kz15163460405de2006-09-28 01:41:18 -0700319{
320 int retcode;
321
kz15163460405de2006-09-28 01:41:18 -0700322 cv_init(&(dev->lock.lock_cv), NULL, CV_DRIVER, NULL);
323 mutex_init(&(dev->lock.lock_mutex), NULL, MUTEX_DRIVER, NULL);
miao chen - Sun Microsystems - Beijing Chinad0231072009-02-17 16:22:10 +0800324 mutex_init(&(dev->dev_lock), "drmdev", MUTEX_DRIVER, NULL);
325 mutex_init(&dev->irq_lock, "drmirq", MUTEX_DRIVER,
326 (void *)dev->intr_block);
327 mutex_init(&dev->drw_lock, "drmdrw", MUTEX_DRIVER, NULL);
328 mutex_init(&dev->tasklet_lock, "drmtsk", MUTEX_DRIVER, NULL);
zw161486e92e3a82007-05-09 19:58:49 -0700329
miao chen - Sun Microsystems - Beijing Chinad0231072009-02-17 16:22:10 +0800330 dev->irq = pci_get_irq(dev);
zw161486e92e3a82007-05-09 19:58:49 -0700331 dev->pci_vendor = pci_get_vendor(dev);
332 dev->pci_device = pci_get_device(dev);
kz15163460405de2006-09-28 01:41:18 -0700333
kz15163460405de2006-09-28 01:41:18 -0700334 TAILQ_INIT(&dev->maplist);
cg149915fca314a2008-02-28 20:09:48 -0800335 TAILQ_INIT(&dev->minordevs);
kz15163460405de2006-09-28 01:41:18 -0700336 TAILQ_INIT(&dev->files);
cg149915d0538f62008-01-09 19:45:15 -0800337 if (dev->driver->load != NULL) {
338 retcode = dev->driver->load(dev, 0);
kz15163460405de2006-09-28 01:41:18 -0700339 if (retcode != 0) {
cg149915d0538f62008-01-09 19:45:15 -0800340 DRM_ERROR("drm_load: failed\n");
kz15163460405de2006-09-28 01:41:18 -0700341 goto error;
342 }
343 }
344
345 retcode = drm_ctxbitmap_init(dev);
346 if (retcode != 0) {
347 DRM_ERROR("drm_load: Cannot allocate memory for ctx bitmap");
348 goto error;
349 }
350
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +0800351 if (dev->driver->use_gem == 1) {
352 retcode = drm_gem_init(dev);
353 if (retcode) {
354 DRM_ERROR("Cannot initialize graphics execution "
355 "manager (GEM)\n");
356 goto error;
357 }
358 }
359
kz15163460405de2006-09-28 01:41:18 -0700360 if (drm_init_kstats(dev)) {
361 DRM_ERROR("drm_attach => drm_load: init kstats error");
cg149915d0538f62008-01-09 19:45:15 -0800362 retcode = EFAULT;
kz15163460405de2006-09-28 01:41:18 -0700363 goto error;
364 }
365
366 DRM_INFO("!drm: Initialized %s %d.%d.%d %s ",
cg149915d0538f62008-01-09 19:45:15 -0800367 dev->driver->driver_name,
368 dev->driver->driver_major,
369 dev->driver->driver_minor,
370 dev->driver->driver_patchlevel,
371 dev->driver->driver_date);
372 return (0);
kz15163460405de2006-09-28 01:41:18 -0700373
374error:
375 DRM_LOCK();
376 (void) drm_lastclose(dev);
377 DRM_UNLOCK();
378 cv_destroy(&(dev->lock.lock_cv));
379 mutex_destroy(&(dev->lock.lock_mutex));
miao chen - Sun Microsystems - Beijing Chinad0231072009-02-17 16:22:10 +0800380 mutex_destroy(&dev->irq_lock);
kz15163460405de2006-09-28 01:41:18 -0700381 mutex_destroy(&(dev->dev_lock));
zw161486e92e3a82007-05-09 19:58:49 -0700382 mutex_destroy(&dev->drw_lock);
miao chen - Sun Microsystems - Beijing Chinad0231072009-02-17 16:22:10 +0800383 mutex_destroy(&dev->tasklet_lock);
kz15163460405de2006-09-28 01:41:18 -0700384
385 return (retcode);
386}
387
388/* called when cleanup this module */
389static void
cg149915d0538f62008-01-09 19:45:15 -0800390drm_unload(drm_device_t *dev)
kz15163460405de2006-09-28 01:41:18 -0700391{
392 drm_local_map_t *map;
393
Edward Shu85664792009-03-30 08:56:42 +0800394 drm_vblank_cleanup(dev);
395
kz15163460405de2006-09-28 01:41:18 -0700396 drm_ctxbitmap_cleanup(dev);
397
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +0800398 if (dev->driver->use_gem == 1) {
399 idr_list_free(&dev->object_name_idr);
400 mutex_destroy(&dev->object_name_lock);
401 }
402
kz15163460405de2006-09-28 01:41:18 -0700403 DRM_LOCK();
404 (void) drm_lastclose(dev);
405 DRM_UNLOCK();
406
407 while ((map = TAILQ_FIRST(&dev->maplist)) != NULL) {
408 drm_rmmap(dev, map);
409 }
410
cg149915d0538f62008-01-09 19:45:15 -0800411 if (dev->driver->unload != NULL)
412 dev->driver->unload(dev);
kz15163460405de2006-09-28 01:41:18 -0700413
414 drm_mem_uninit();
415 cv_destroy(&dev->lock.lock_cv);
416 mutex_destroy(&dev->lock.lock_mutex);
miao chen - Sun Microsystems - Beijing Chinad0231072009-02-17 16:22:10 +0800417 mutex_destroy(&dev->irq_lock);
kz15163460405de2006-09-28 01:41:18 -0700418 mutex_destroy(&dev->dev_lock);
zw161486e92e3a82007-05-09 19:58:49 -0700419 mutex_destroy(&dev->drw_lock);
miao chen - Sun Microsystems - Beijing Chinad0231072009-02-17 16:22:10 +0800420 mutex_destroy(&dev->tasklet_lock);
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +0800421
422 dev->gtt_total = 0;
423 atomic_set(&dev->pin_memory, 0);
424 DRM_ERROR("drm_unload");
kz15163460405de2006-09-28 01:41:18 -0700425}
426
427
428/*ARGSUSED*/
429int
cg149915fca314a2008-02-28 20:09:48 -0800430drm_open(drm_device_t *dev, drm_cminor_t *mp, int openflags,
kz15163460405de2006-09-28 01:41:18 -0700431 int otyp, cred_t *credp)
432{
433 int retcode;
kz15163460405de2006-09-28 01:41:18 -0700434
cg149915fca314a2008-02-28 20:09:48 -0800435 retcode = drm_open_helper(dev, mp, openflags, otyp, credp);
kz15163460405de2006-09-28 01:41:18 -0700436
437 if (!retcode) {
438 atomic_inc_32(&dev->counts[_DRM_STAT_OPENS]);
439 DRM_LOCK();
440 if (!dev->open_count ++)
441 retcode = drm_firstopen(dev);
442 DRM_UNLOCK();
443 }
444
445 return (retcode);
446}
447
448/*ARGSUSED*/
449int
cg149915fca314a2008-02-28 20:09:48 -0800450drm_close(drm_device_t *dev, int minor, int flag, int otyp,
kz15163460405de2006-09-28 01:41:18 -0700451 cred_t *credp)
452{
cg149915fca314a2008-02-28 20:09:48 -0800453 drm_cminor_t *mp;
454 drm_file_t *fpriv;
455 int retcode = 0;
kz15163460405de2006-09-28 01:41:18 -0700456
457 DRM_LOCK();
cg149915fca314a2008-02-28 20:09:48 -0800458 mp = drm_find_file_by_minor(dev, minor);
459 if (!mp) {
kz15163460405de2006-09-28 01:41:18 -0700460 DRM_UNLOCK();
461 DRM_ERROR("drm_close: can't find authenticator");
cg149915d0538f62008-01-09 19:45:15 -0800462 return (EACCES);
kz15163460405de2006-09-28 01:41:18 -0700463 }
464
cg149915fca314a2008-02-28 20:09:48 -0800465 fpriv = mp->fpriv;
466 ASSERT(fpriv);
467
cg149915d0538f62008-01-09 19:45:15 -0800468 if (--fpriv->refs != 0)
469 goto done;
470
471 if (dev->driver->preclose != NULL)
472 dev->driver->preclose(dev, fpriv);
kz15163460405de2006-09-28 01:41:18 -0700473
474 /*
475 * Begin inline drm_release
476 */
477 DRM_DEBUG("drm_close :pid = %d , open_count = %d",
cg149915d0538f62008-01-09 19:45:15 -0800478 DRM_CURRENTPID, dev->open_count);
kz15163460405de2006-09-28 01:41:18 -0700479
480 if (dev->lock.hw_lock &&
cg149915d0538f62008-01-09 19:45:15 -0800481 _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
482 dev->lock.filp == fpriv) {
kz15163460405de2006-09-28 01:41:18 -0700483 DRM_DEBUG("Process %d dead, freeing lock for context %d",
484 DRM_CURRENTPID,
485 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
cg149915d0538f62008-01-09 19:45:15 -0800486 if (dev->driver->reclaim_buffers_locked != NULL)
487 dev->driver->reclaim_buffers_locked(dev, fpriv);
kz15163460405de2006-09-28 01:41:18 -0700488 (void) drm_lock_free(dev, &dev->lock.hw_lock->lock,
489 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
cg149915d0538f62008-01-09 19:45:15 -0800490 } else if (dev->driver->reclaim_buffers_locked != NULL &&
kz15163460405de2006-09-28 01:41:18 -0700491 dev->lock.hw_lock != NULL) {
492 DRM_ERROR("drm_close: "
493 "retake lock not implemented yet");
494 }
495
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +0800496 if (dev->driver->use_dma) {
cg149915d0538f62008-01-09 19:45:15 -0800497 drm_reclaim_buffers(dev, fpriv);
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +0800498 }
kz15163460405de2006-09-28 01:41:18 -0700499
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +0800500 if (dev->driver->use_gem == 1) {
501 drm_gem_release(dev, fpriv);
502 }
kz15163460405de2006-09-28 01:41:18 -0700503
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +0800504 if (dev->driver->postclose != NULL) {
cg149915d0538f62008-01-09 19:45:15 -0800505 dev->driver->postclose(dev, fpriv);
miao chen - Sun Microsystems - Beijing China0035d212009-12-05 13:25:40 +0800506 }
cg149915d0538f62008-01-09 19:45:15 -0800507 TAILQ_REMOVE(&dev->files, fpriv, link);
508 drm_free(fpriv, sizeof (*fpriv), DRM_MEM_FILES);
kz15163460405de2006-09-28 01:41:18 -0700509
cg149915d0538f62008-01-09 19:45:15 -0800510done:
kz15163460405de2006-09-28 01:41:18 -0700511 atomic_inc_32(&dev->counts[_DRM_STAT_CLOSES]);
512
cg149915fca314a2008-02-28 20:09:48 -0800513 TAILQ_REMOVE(&dev->minordevs, mp, link);
514 drm_free(mp, sizeof (*mp), DRM_MEM_FILES);
515
kz15163460405de2006-09-28 01:41:18 -0700516 if (--dev->open_count == 0) {
517 retcode = drm_lastclose(dev);
518 }
519 DRM_UNLOCK();
520
521 return (retcode);
522}
523
kz15163460405de2006-09-28 01:41:18 -0700524int
cg149915d0538f62008-01-09 19:45:15 -0800525drm_attach(drm_device_t *dev)
kz15163460405de2006-09-28 01:41:18 -0700526{
kz15163460405de2006-09-28 01:41:18 -0700527 return (drm_load(dev));
528}
529
530int
cg149915d0538f62008-01-09 19:45:15 -0800531drm_detach(drm_device_t *dev)
kz15163460405de2006-09-28 01:41:18 -0700532{
533 drm_unload(dev);
534 drm_fini_kstats(dev);
535 return (DDI_SUCCESS);
536}
537
538static int
cg149915d0538f62008-01-09 19:45:15 -0800539drm_get_businfo(drm_device_t *dev)
kz15163460405de2006-09-28 01:41:18 -0700540{
541 dev->irq = pci_get_irq(dev);
542 if (dev->irq == -1) {
543 DRM_ERROR("drm_get_businfo: get irq error");
544 return (DDI_FAILURE);
545 }
546 /* XXX Fix domain number (alpha hoses) */
547 dev->pci_domain = 0;
548 if (pci_get_info(dev, &dev->pci_bus,
549 &dev->pci_slot, &dev->pci_func) != DDI_SUCCESS) {
550 DRM_ERROR("drm_get_businfo: get bus slot func error ");
551 return (DDI_FAILURE);
552 }
553 DRM_DEBUG("drm_get_businfo: pci bus: %d, pci slot :%d pci func %d",
554 dev->pci_bus, dev->pci_slot, dev->pci_func);
555 return (DDI_SUCCESS);
556}
557
558int
cg149915d0538f62008-01-09 19:45:15 -0800559drm_probe(drm_device_t *dev, drm_pci_id_list_t *idlist)
kz15163460405de2006-09-28 01:41:18 -0700560{
561 const char *s = NULL;
562 int vendor, device;
563
564 vendor = pci_get_vendor(dev);
565 device = pci_get_device(dev);
kz15163460405de2006-09-28 01:41:18 -0700566
567 s = drm_find_description(vendor, device, idlist);
568 if (s != NULL) {
569 dev->desc = s;
kz15163460405de2006-09-28 01:41:18 -0700570 if (drm_get_businfo(dev) != DDI_SUCCESS) {
571 DRM_ERROR("drm_probe: drm get bus info error");
572 return (DDI_FAILURE);
573 }
574 return (DDI_SUCCESS);
575 }
576 return (DDI_FAILURE);
577}