11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \file drm_stub.h 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Stub support 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \author Rickard E. (Rik) Faith <faith@valinux.com> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All Rights Reserved. 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Permission is hereby granted, free of charge, to any person obtaining a 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * copy of this software and associated documentation files (the "Software"), 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to deal in the Software without restriction, including without limitation 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the rights to use, copy, modify, merge, publish, distribute, sublicense, 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and/or sell copies of the Software, and to permit persons to whom the 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Software is furnished to do so, subject to the following conditions: 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The above copyright notice and this permission notice (including the next 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * paragraph) shall be included in all copies or substantial portions of the 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Software. 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DEALINGS IN THE SOFTWARE. 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/moduleparam.h> 365a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "drmP.h" 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "drm_core.h" 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlieunsigned int drm_debug = 0; /* 1 to enable debug output */ 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(drm_debug); 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4327641c3f003e7f3b6585c01d8a788883603eb262Mario Kleinerunsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ 4427641c3f003e7f3b6585c01d8a788883603eb262Mario KleinerEXPORT_SYMBOL(drm_vblank_offdelay); 4527641c3f003e7f3b6585c01d8a788883603eb262Mario Kleiner 4627641c3f003e7f3b6585c01d8a788883603eb262Mario Kleinerunsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ 4727641c3f003e7f3b6585c01d8a788883603eb262Mario KleinerEXPORT_SYMBOL(drm_timestamp_precision); 4827641c3f003e7f3b6585c01d8a788883603eb262Mario Kleiner 49b5e89ed53ed8d24f83ba1941c07382af00ed238eDave AirlieMODULE_AUTHOR(CORE_AUTHOR); 50b5e89ed53ed8d24f83ba1941c07382af00ed238eDave AirlieMODULE_DESCRIPTION(CORE_DESC); 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL and additional rights"); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(debug, "Enable debug output"); 5327641c3f003e7f3b6585c01d8a788883603eb262Mario KleinerMODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]"); 5427641c3f003e7f3b6585c01d8a788883603eb262Mario KleinerMODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56c0758146adbe39514e75ac860ce7e49f865c2297Dave Jonesmodule_param_named(debug, drm_debug, int, 0600); 5727641c3f003e7f3b6585c01d8a788883603eb262Mario Kleinermodule_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); 5827641c3f003e7f3b6585c01d8a788883603eb262Mario Kleinermodule_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 602c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airliestruct idr drm_minors_idr; 612c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 620650fd5824e07570f0c43980b81bb23ae917f1d7Greg Kroah-Hartmanstruct class *drm_class; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct proc_dir_entry *drm_proc_root; 64955b12def42e83287c1bdb1411d99451753c1391Ben Gamaristruct dentry *drm_debugfs_root; 655ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches 665ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perchesint drm_err(const char *func, const char *format, ...) 675ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches{ 685ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches struct va_format vaf; 695ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches va_list args; 705ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches int r; 715ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches 725ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches va_start(args, format); 735ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches 745ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches vaf.fmt = format; 755ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches vaf.va = &args; 765ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches 775ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches r = printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* %pV", func, &vaf); 785ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches 795ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches va_end(args); 805ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches 815ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches return r; 825ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches} 835ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe PerchesEXPORT_SYMBOL(drm_err); 845ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches 854fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhaovoid drm_ut_debug_printk(unsigned int request_level, 864fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao const char *prefix, 874fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao const char *function_name, 884fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao const char *format, ...) 894fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao{ 904fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao va_list args; 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 924fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao if (drm_debug & request_level) { 934fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao if (function_name) 944fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao printk(KERN_DEBUG "[%s:%s], ", prefix, function_name); 954fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao va_start(args, format); 964fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao vprintk(format, args); 974fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao va_end(args); 984fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao } 994fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao} 1004fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhaoEXPORT_SYMBOL(drm_ut_debug_printk); 1015ad3d8831f0c97257460c11ddcc1cc0466c762d4Joe Perches 1022c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airliestatic int drm_minor_get_id(struct drm_device *dev, int type) 1032c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie{ 1042c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie int new_id; 1052c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie int ret; 1062c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie int base = 0, limit = 63; 1072c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 108f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie if (type == DRM_MINOR_CONTROL) { 109f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie base += 64; 110f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie limit = base + 127; 111f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie } else if (type == DRM_MINOR_RENDER) { 112f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie base += 128; 113f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie limit = base + 255; 114f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie } 115f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie 1162c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlieagain: 1172c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) { 1182c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie DRM_ERROR("Out of memory expanding drawable idr\n"); 1192c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return -ENOMEM; 1202c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } 1212c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie mutex_lock(&dev->struct_mutex); 1222c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie ret = idr_get_new_above(&drm_minors_idr, NULL, 1232c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie base, &new_id); 1242c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie mutex_unlock(&dev->struct_mutex); 1252c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (ret == -EAGAIN) { 1262c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie goto again; 1272c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } else if (ret) { 1282c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return ret; 1292c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } 1302c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 1312c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (new_id >= limit) { 1322c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie idr_remove(&drm_minors_idr, new_id); 1332c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return -EINVAL; 1342c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } 1352c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return new_id; 1362c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie} 1372c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 1387c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airliestruct drm_master *drm_master_create(struct drm_minor *minor) 1397c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 1407c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_master *master; 1417c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1429a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt master = kzalloc(sizeof(*master), GFP_KERNEL); 1437c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (!master) 1447c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return NULL; 1457c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1467c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie kref_init(&master->refcount); 1477c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie spin_lock_init(&master->lock.spinlock); 1487c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie init_waitqueue_head(&master->lock.lock_queue); 1497c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER); 1507c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie INIT_LIST_HEAD(&master->magicfree); 1517c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master->minor = minor; 1527c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1537c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie list_add_tail(&master->head, &minor->master_list); 1547c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1557c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return master; 1567c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 1577c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1587c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airliestruct drm_master *drm_master_get(struct drm_master *master) 1597c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 1607c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie kref_get(&master->refcount); 1617c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return master; 1627c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 16385bb0c377f259100d049937e30c85f7a8dea0fa0Thomas HellstromEXPORT_SYMBOL(drm_master_get); 1647c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1657c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airliestatic void drm_master_destroy(struct kref *kref) 1667c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 1677c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_master *master = container_of(kref, struct drm_master, refcount); 1687c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_magic_entry *pt, *next; 1697c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_device *dev = master->minor->dev; 170c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie struct drm_map_list *r_list, *list_temp; 1717c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1727c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie list_del(&master->head); 1737c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1747c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (dev->driver->master_destroy) 1757c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie dev->driver->master_destroy(dev, master); 1767c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 177c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) { 178c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie if (r_list->master == master) { 179c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie drm_rmmap_locked(dev, r_list->map); 180c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie r_list = NULL; 181c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie } 182c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie } 183c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie 1847c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (master->unique) { 1859a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(master->unique); 1867c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master->unique = NULL; 1877c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master->unique_len = 0; 1887c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie } 1897c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1906e35023ffad0ee74689710f0e81ee80c1019f93bChris Wilson kfree(dev->devname); 1916e35023ffad0ee74689710f0e81ee80c1019f93bChris Wilson dev->devname = NULL; 1926e35023ffad0ee74689710f0e81ee80c1019f93bChris Wilson 1937c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie list_for_each_entry_safe(pt, next, &master->magicfree, head) { 1947c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie list_del(&pt->head); 1957c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie drm_ht_remove_item(&master->magiclist, &pt->hash_item); 1969a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(pt); 1977c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie } 1987c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1997c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie drm_ht_remove(&master->magiclist); 2007c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 2019a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(master); 2027c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 2037c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 2047c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlievoid drm_master_put(struct drm_master **master) 2057c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 2067c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie kref_put(&(*master)->refcount, drm_master_destroy); 2077c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie *master = NULL; 2087c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 20985bb0c377f259100d049937e30c85f7a8dea0fa0Thomas HellstromEXPORT_SYMBOL(drm_master_put); 2107c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 2117c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlieint drm_setmaster_ioctl(struct drm_device *dev, void *data, 2127c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_file *file_priv) 2137c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 214862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom int ret = 0; 215862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom 2166b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn if (file_priv->is_master) 2176b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn return 0; 2186b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn 2197c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (file_priv->minor->master && file_priv->minor->master != file_priv->master) 2207c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return -EINVAL; 2217c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 2227c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (!file_priv->master) 2237c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return -EINVAL; 2247c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 2257c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (!file_priv->minor->master && 2267c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie file_priv->minor->master != file_priv->master) { 2277c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie mutex_lock(&dev->struct_mutex); 2287c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie file_priv->minor->master = drm_master_get(file_priv->master); 2296b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn file_priv->is_master = 1; 230862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom if (dev->driver->master_set) { 231862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom ret = dev->driver->master_set(dev, file_priv, false); 232862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom if (unlikely(ret != 0)) { 233862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom file_priv->is_master = 0; 234862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom drm_master_put(&file_priv->minor->master); 235862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom } 236862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom } 2375ad8b7d12605e88d1e532061699102797fdefe08Helge Bahmann mutex_unlock(&dev->struct_mutex); 2387c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie } 2397c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 2407c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return 0; 2417c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 2427c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 2437c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlieint drm_dropmaster_ioctl(struct drm_device *dev, void *data, 2447c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_file *file_priv) 2457c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 2466b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn if (!file_priv->is_master) 2477c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return -EINVAL; 2486b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn 24907f1c7a7f6736d9ec2eba57d209c5f48888d841eDave Airlie if (!file_priv->minor->master) 25007f1c7a7f6736d9ec2eba57d209c5f48888d841eDave Airlie return -EINVAL; 25107f1c7a7f6736d9ec2eba57d209c5f48888d841eDave Airlie 2527c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie mutex_lock(&dev->struct_mutex); 253862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom if (dev->driver->master_drop) 254862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom dev->driver->master_drop(dev, file_priv, false); 2557c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie drm_master_put(&file_priv->minor->master); 2566b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn file_priv->is_master = 0; 2577c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie mutex_unlock(&dev->struct_mutex); 2587c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return 0; 2597c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 2607c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 261dcdb167402cbdca1d021bdfa5f63995ee0a79317Jordan Crouseint drm_fill_in_dev(struct drm_device *dev, 262b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie const struct pci_device_id *ent, 263b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie struct drm_driver *driver) 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retcode; 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 267bd1b331fae2813d9f03ceee649296f02edc0b893Dave Airlie INIT_LIST_HEAD(&dev->filelist); 2687c158acef8f0e51c3a5f71133aaf402628370a64Dave Airlie INIT_LIST_HEAD(&dev->ctxlist); 2697c158acef8f0e51c3a5f71133aaf402628370a64Dave Airlie INIT_LIST_HEAD(&dev->vmalist); 2707c158acef8f0e51c3a5f71133aaf402628370a64Dave Airlie INIT_LIST_HEAD(&dev->maplist); 271c9a9c5e02aedc1a2815877b0268f886d2640b771Kristian Høgsberg INIT_LIST_HEAD(&dev->vblank_event_list); 2727c158acef8f0e51c3a5f71133aaf402628370a64Dave Airlie 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&dev->count_lock); 274c9a9c5e02aedc1a2815877b0268f886d2640b771Kristian Høgsberg spin_lock_init(&dev->event_lock); 27530e2fb188194908e48d3f27a53ccea6740eb1e98Dave Airlie mutex_init(&dev->struct_mutex); 27630e2fb188194908e48d3f27a53ccea6740eb1e98Dave Airlie mutex_init(&dev->ctxlist_mutex); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2788d153f7107ff2c5d6e32053ae377c961187ab6b9Thomas Hellstrom if (drm_ht_create(&dev->map_hash, 12)) { 2798d153f7107ff2c5d6e32053ae377c961187ab6b9Thomas Hellstrom return -ENOMEM; 2808d153f7107ff2c5d6e32053ae377c961187ab6b9Thomas Hellstrom } 281836cf0465c422ee6d654060edd7c620d9cf0c09cDave Airlie 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* the DRM has 6 basic counters */ 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->counters = 6; 284b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[0] = _DRM_STAT_LOCK; 285b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[1] = _DRM_STAT_OPENS; 286b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[2] = _DRM_STAT_CLOSES; 287b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[3] = _DRM_STAT_IOCTLS; 288b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[4] = _DRM_STAT_LOCKS; 289b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[5] = _DRM_STAT_UNLOCKS; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->driver = driver; 292b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 2938410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie if (dev->driver->bus->agp_init) { 2948410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie retcode = dev->driver->bus->agp_init(dev); 2958410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie if (retcode) 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error_out_unreg; 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2992716a02f607c964ccaa6fa7266abd3acd73d9033Dave Airlie 3008410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie 301b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie retcode = drm_ctxbitmap_init(dev); 302b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (retcode) { 303b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_ERROR("Cannot allocate memory for context bitmap.\n"); 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error_out_unreg; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 307673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt if (driver->driver_features & DRIVER_GEM) { 308673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt retcode = drm_gem_init(dev); 309673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt if (retcode) { 310673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt DRM_ERROR("Cannot initialize graphics execution " 311673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt "manager (GEM)\n"); 312673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt goto error_out_unreg; 313673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt } 314673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt } 315673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 317b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 318b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie error_out_unreg: 31922eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie drm_lastclose(dev); 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retcode; 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3229c1dfc5574a7f7115c0fe5bd8f838a8b7a52ee6dDave AirlieEXPORT_SYMBOL(drm_fill_in_dev); 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Get a secondary minor number. 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \param dev device data structure 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \param sec-minor structure to hold the assigned minor 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \return negative number on failure. 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Search an empty entry and initialize it to the given parameters, and 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * create the proc init entry via proc_init(). This routines assigns 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * minor numbers to secondary heads of multi-headed cards 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 336dcdb167402cbdca1d021bdfa5f63995ee0a79317Jordan Crouseint drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3382c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie struct drm_minor *new_minor; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 3402c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie int minor_id; 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_DEBUG("\n"); 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3442c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie minor_id = drm_minor_get_id(dev, type); 3452c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (minor_id < 0) 3462c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return minor_id; 3472c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3482c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL); 3492c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (!new_minor) { 3502c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie ret = -ENOMEM; 3512c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie goto err_idr; 3522c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } 3532c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3542c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie new_minor->type = type; 3552c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie new_minor->device = MKDEV(DRM_MAJOR, minor_id); 3562c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie new_minor->dev = dev; 3572c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie new_minor->index = minor_id; 3587c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie INIT_LIST_HEAD(&new_minor->master_list); 3592c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3602c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie idr_replace(&drm_minors_idr, new_minor, minor_id); 3612c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3622c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (type == DRM_MINOR_LEGACY) { 3632c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie ret = drm_proc_init(new_minor, minor_id, drm_proc_root); 3642c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (ret) { 3652c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); 3662c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie goto err_mem; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3682c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } else 369955b12def42e83287c1bdb1411d99451753c1391Ben Gamari new_minor->proc_root = NULL; 370955b12def42e83287c1bdb1411d99451753c1391Ben Gamari 371955b12def42e83287c1bdb1411d99451753c1391Ben Gamari#if defined(CONFIG_DEBUG_FS) 372955b12def42e83287c1bdb1411d99451753c1391Ben Gamari ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root); 373955b12def42e83287c1bdb1411d99451753c1391Ben Gamari if (ret) { 374156f5a7801195fa2ce44aeeb62d6cf8468f3332aGeunSik Lim DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n"); 375955b12def42e83287c1bdb1411d99451753c1391Ben Gamari goto err_g2; 376955b12def42e83287c1bdb1411d99451753c1391Ben Gamari } 377955b12def42e83287c1bdb1411d99451753c1391Ben Gamari#endif 3782c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3792c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie ret = drm_sysfs_device_add(new_minor); 3802c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (ret) { 3812c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie printk(KERN_ERR 3822c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie "DRM: Error sysfs_device_add.\n"); 3832c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie goto err_g2; 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3852c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie *minor = new_minor; 3862c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3872c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie DRM_DEBUG("new minor assigned %d\n", minor_id); 3882c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return 0; 3892c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3902c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3912c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlieerr_g2: 3922c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (new_minor->type == DRM_MINOR_LEGACY) 3932c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie drm_proc_cleanup(new_minor, drm_proc_root); 3942c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlieerr_mem: 3952c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie kfree(new_minor); 3962c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlieerr_idr: 3972c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie idr_remove(&drm_minors_idr, minor_id); 3982c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie *minor = NULL; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4019c1dfc5574a7f7115c0fe5bd8f838a8b7a52ee6dDave AirlieEXPORT_SYMBOL(drm_get_minor); 402b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 403c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie/** 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Put a secondary minor number. 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \param sec_minor - structure to be released 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \return always zero 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Cleans up the proc resources. Not legal for this to be the 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * last minor released. 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4132c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlieint drm_put_minor(struct drm_minor **minor_p) 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4152c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie struct drm_minor *minor = *minor_p; 416673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 4172c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie DRM_DEBUG("release secondary minor %d\n", minor->index); 418b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 4192c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (minor->type == DRM_MINOR_LEGACY) 4202c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie drm_proc_cleanup(minor, drm_proc_root); 421955b12def42e83287c1bdb1411d99451753c1391Ben Gamari#if defined(CONFIG_DEBUG_FS) 422955b12def42e83287c1bdb1411d99451753c1391Ben Gamari drm_debugfs_cleanup(minor); 423955b12def42e83287c1bdb1411d99451753c1391Ben Gamari#endif 424955b12def42e83287c1bdb1411d99451753c1391Ben Gamari 4252c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie drm_sysfs_device_remove(minor); 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4272c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie idr_remove(&drm_minors_idr, minor->index); 428b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 4292c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie kfree(minor); 4302c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie *minor_p = NULL; 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4339c1dfc5574a7f7115c0fe5bd8f838a8b7a52ee6dDave AirlieEXPORT_SYMBOL(drm_put_minor); 434112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 4352c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airliestatic void drm_unplug_minor(struct drm_minor *minor) 4362c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie{ 4372c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie drm_sysfs_device_remove(minor); 4382c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie} 4392c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie 440112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg/** 441112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * Called via drm_exit() at module unload time or when pci device is 442112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * unplugged. 443112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * 444112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * Cleans up all DRM device, calling drm_lastclose(). 445112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * 446112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg */ 447112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsbergvoid drm_put_dev(struct drm_device *dev) 448112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg{ 449ecca0683230b83e8f830ff157911fad20bc43015Julia Lawall struct drm_driver *driver; 450112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg struct drm_map_list *r_list, *list_temp; 451112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 452112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg DRM_DEBUG("\n"); 453112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 454112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (!dev) { 455112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg DRM_ERROR("cleanup called no dev\n"); 456112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg return; 457112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg } 458ecca0683230b83e8f830ff157911fad20bc43015Julia Lawall driver = dev->driver; 459112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 460112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg drm_lastclose(dev); 461112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 462112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && 463112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->agp && dev->agp->agp_mtrr >= 0) { 464112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg int retval; 465112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg retval = mtrr_del(dev->agp->agp_mtrr, 466112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->agp->agp_info.aper_base, 467112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->agp->agp_info.aper_size * 1024 * 1024); 468112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg DRM_DEBUG("mtrr_del=%d\n", retval); 469112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg } 470112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 471112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (dev->driver->unload) 472112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->driver->unload(dev); 473112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 474112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (drm_core_has_AGP(dev) && dev->agp) { 4759a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(dev->agp); 476112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->agp = NULL; 477112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg } 478112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 479b78315f051de8d207bead90470aa216c0617572bJesse Barnes drm_vblank_cleanup(dev); 480b78315f051de8d207bead90470aa216c0617572bJesse Barnes 481112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) 482112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg drm_rmmap(dev, r_list->map); 48330ddbd94401a132f4d932775d1902b3c9a8c41b5Ben Skeggs drm_ht_remove(&dev->map_hash); 48430ddbd94401a132f4d932775d1902b3c9a8c41b5Ben Skeggs 48530ddbd94401a132f4d932775d1902b3c9a8c41b5Ben Skeggs drm_ctxbitmap_cleanup(dev); 486112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 487112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (drm_core_check_feature(dev, DRIVER_MODESET)) 488112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg drm_put_minor(&dev->control); 489112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 490112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (driver->driver_features & DRIVER_GEM) 491112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg drm_gem_destroy(dev); 492112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 493112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg drm_put_minor(&dev->primary); 494112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 495a250b9fdc53a286d32e22f21170382a46b3a3ef5Dave Airlie list_del(&dev->driver_item); 496112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (dev->devname) { 4979a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(dev->devname); 498112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->devname = NULL; 499112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg } 5009a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(dev); 501112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg} 502112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian HøgsbergEXPORT_SYMBOL(drm_put_dev); 5032c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie 5042c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlievoid drm_unplug_dev(struct drm_device *dev) 5052c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie{ 5062c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie /* for a USB device */ 5072c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie if (drm_core_check_feature(dev, DRIVER_MODESET)) 5082c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie drm_unplug_minor(dev->control); 5092c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie drm_unplug_minor(dev->primary); 5102c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie 5112c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie mutex_lock(&drm_global_mutex); 5122c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie 5132c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie drm_device_set_unplugged(dev); 5142c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie 5152c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie if (dev->open_count == 0) { 5162c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie drm_put_dev(dev); 5172c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie } 5182c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie mutex_unlock(&drm_global_mutex); 5192c07a21d6fb0be47fda696a618b726ea258ed1ddDave Airlie} 5202c07a21d6fb0be47fda696a618b726ea258ed1ddDave AirlieEXPORT_SYMBOL(drm_unplug_dev); 521