drm_stub.c revision b78315f051de8d207bead90470aa216c0617572b
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> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "drmP.h" 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "drm_core.h" 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlieunsigned int drm_debug = 0; /* 1 to enable debug output */ 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(drm_debug); 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42b5e89ed53ed8d24f83ba1941c07382af00ed238eDave AirlieMODULE_AUTHOR(CORE_AUTHOR); 43b5e89ed53ed8d24f83ba1941c07382af00ed238eDave AirlieMODULE_DESCRIPTION(CORE_DESC); 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL and additional rights"); 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(debug, "Enable debug output"); 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47c0758146adbe39514e75ac860ce7e49f865c2297Dave Jonesmodule_param_named(debug, drm_debug, int, 0600); 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 492c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airliestruct idr drm_minors_idr; 502c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 510650fd5824e07570f0c43980b81bb23ae917f1d7Greg Kroah-Hartmanstruct class *drm_class; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct proc_dir_entry *drm_proc_root; 53955b12def42e83287c1bdb1411d99451753c1391Ben Gamaristruct dentry *drm_debugfs_root; 544fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhaovoid drm_ut_debug_printk(unsigned int request_level, 554fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao const char *prefix, 564fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao const char *function_name, 574fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao const char *format, ...) 584fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao{ 594fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao va_list args; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 614fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao if (drm_debug & request_level) { 624fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao if (function_name) 634fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao printk(KERN_DEBUG "[%s:%s], ", prefix, function_name); 644fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao va_start(args, format); 654fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao vprintk(format, args); 664fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao va_end(args); 674fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao } 684fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhao} 694fefcb27050b98c97b1c32bc710fc2f874449deeyakui_zhaoEXPORT_SYMBOL(drm_ut_debug_printk); 702c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airliestatic int drm_minor_get_id(struct drm_device *dev, int type) 712c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie{ 722c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie int new_id; 732c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie int ret; 742c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie int base = 0, limit = 63; 752c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 76f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie if (type == DRM_MINOR_CONTROL) { 77f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie base += 64; 78f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie limit = base + 127; 79f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie } else if (type == DRM_MINOR_RENDER) { 80f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie base += 128; 81f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie limit = base + 255; 82f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie } 83f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie 842c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlieagain: 852c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) { 862c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie DRM_ERROR("Out of memory expanding drawable idr\n"); 872c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return -ENOMEM; 882c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } 892c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie mutex_lock(&dev->struct_mutex); 902c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie ret = idr_get_new_above(&drm_minors_idr, NULL, 912c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie base, &new_id); 922c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie mutex_unlock(&dev->struct_mutex); 932c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (ret == -EAGAIN) { 942c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie goto again; 952c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } else if (ret) { 962c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return ret; 972c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } 982c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 992c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (new_id >= limit) { 1002c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie idr_remove(&drm_minors_idr, new_id); 1012c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return -EINVAL; 1022c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } 1032c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return new_id; 1042c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie} 1052c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 1067c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airliestruct drm_master *drm_master_create(struct drm_minor *minor) 1077c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 1087c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_master *master; 1097c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1109a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt master = kzalloc(sizeof(*master), GFP_KERNEL); 1117c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (!master) 1127c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return NULL; 1137c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1147c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie kref_init(&master->refcount); 1157c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie spin_lock_init(&master->lock.spinlock); 1167c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie init_waitqueue_head(&master->lock.lock_queue); 1177c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER); 1187c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie INIT_LIST_HEAD(&master->magicfree); 1197c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master->minor = minor; 1207c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1217c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie list_add_tail(&master->head, &minor->master_list); 1227c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1237c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return master; 1247c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 1257c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1267c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airliestruct drm_master *drm_master_get(struct drm_master *master) 1277c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 1287c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie kref_get(&master->refcount); 1297c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return master; 1307c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 13185bb0c377f259100d049937e30c85f7a8dea0fa0Thomas HellstromEXPORT_SYMBOL(drm_master_get); 1327c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1337c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airliestatic void drm_master_destroy(struct kref *kref) 1347c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 1357c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_master *master = container_of(kref, struct drm_master, refcount); 1367c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_magic_entry *pt, *next; 1377c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_device *dev = master->minor->dev; 138c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie struct drm_map_list *r_list, *list_temp; 1397c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1407c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie list_del(&master->head); 1417c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1427c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (dev->driver->master_destroy) 1437c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie dev->driver->master_destroy(dev, master); 1447c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 145c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) { 146c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie if (r_list->master == master) { 147c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie drm_rmmap_locked(dev, r_list->map); 148c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie r_list = NULL; 149c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie } 150c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie } 151c1ff85d97708550e634fb6fa099c463db90fc40dDave Airlie 1527c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (master->unique) { 1539a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(master->unique); 1547c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master->unique = NULL; 1557c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master->unique_len = 0; 1567c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie } 1577c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1587c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie list_for_each_entry_safe(pt, next, &master->magicfree, head) { 1597c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie list_del(&pt->head); 1607c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie drm_ht_remove_item(&master->magiclist, &pt->hash_item); 1619a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(pt); 1627c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie } 1637c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1647c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie drm_ht_remove(&master->magiclist); 1657c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1669a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(master); 1677c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 1687c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1697c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlievoid drm_master_put(struct drm_master **master) 1707c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 1717c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie kref_put(&(*master)->refcount, drm_master_destroy); 1727c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie *master = NULL; 1737c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 17485bb0c377f259100d049937e30c85f7a8dea0fa0Thomas HellstromEXPORT_SYMBOL(drm_master_put); 1757c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1767c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlieint drm_setmaster_ioctl(struct drm_device *dev, void *data, 1777c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_file *file_priv) 1787c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 179862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom int ret = 0; 180862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom 1816b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn if (file_priv->is_master) 1826b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn return 0; 1836b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn 1847c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (file_priv->minor->master && file_priv->minor->master != file_priv->master) 1857c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return -EINVAL; 1867c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1877c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (!file_priv->master) 1887c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return -EINVAL; 1897c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1907c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (!file_priv->minor->master && 1917c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie file_priv->minor->master != file_priv->master) { 1927c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie mutex_lock(&dev->struct_mutex); 1937c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie file_priv->minor->master = drm_master_get(file_priv->master); 1946b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn file_priv->is_master = 1; 195862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom if (dev->driver->master_set) { 196862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom ret = dev->driver->master_set(dev, file_priv, false); 197862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom if (unlikely(ret != 0)) { 198862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom file_priv->is_master = 0; 199862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom drm_master_put(&file_priv->minor->master); 200862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom } 201862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom } 2025ad8b7d12605e88d1e532061699102797fdefe08Helge Bahmann mutex_unlock(&dev->struct_mutex); 2037c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie } 2047c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 2057c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return 0; 2067c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 2077c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 2087c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlieint drm_dropmaster_ioctl(struct drm_device *dev, void *data, 2097c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_file *file_priv) 2107c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 2116b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn if (!file_priv->is_master) 2127c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return -EINVAL; 2136b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn 21407f1c7a7f6736d9ec2eba57d209c5f48888d841eDave Airlie if (!file_priv->minor->master) 21507f1c7a7f6736d9ec2eba57d209c5f48888d841eDave Airlie return -EINVAL; 21607f1c7a7f6736d9ec2eba57d209c5f48888d841eDave Airlie 2177c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie mutex_lock(&dev->struct_mutex); 218862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom if (dev->driver->master_drop) 219862302ffe422378a5213f558fc5cdf62c37050a9Thomas Hellstrom dev->driver->master_drop(dev, file_priv, false); 2207c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie drm_master_put(&file_priv->minor->master); 2216b0084266c1d4917ad9259759a1e7bd623cb3888Jonas Bonn file_priv->is_master = 0; 2227c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie mutex_unlock(&dev->struct_mutex); 2237c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return 0; 2247c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 2257c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 22684b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, 227b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie const struct pci_device_id *ent, 228b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie struct drm_driver *driver) 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retcode; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 232bd1b331fae2813d9f03ceee649296f02edc0b893Dave Airlie INIT_LIST_HEAD(&dev->filelist); 2337c158acef8f0e51c3a5f71133aaf402628370a64Dave Airlie INIT_LIST_HEAD(&dev->ctxlist); 2347c158acef8f0e51c3a5f71133aaf402628370a64Dave Airlie INIT_LIST_HEAD(&dev->vmalist); 2357c158acef8f0e51c3a5f71133aaf402628370a64Dave Airlie INIT_LIST_HEAD(&dev->maplist); 236c9a9c5e02aedc1a2815877b0268f886d2640b771Kristian Høgsberg INIT_LIST_HEAD(&dev->vblank_event_list); 2377c158acef8f0e51c3a5f71133aaf402628370a64Dave Airlie 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&dev->count_lock); 239bea5679f9cb97b7e41786c8500df56665cd21e56Michel Dänzer spin_lock_init(&dev->drw_lock); 240c9a9c5e02aedc1a2815877b0268f886d2640b771Kristian Høgsberg spin_lock_init(&dev->event_lock); 241b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie init_timer(&dev->timer); 24230e2fb188194908e48d3f27a53ccea6740eb1e98Dave Airlie mutex_init(&dev->struct_mutex); 24330e2fb188194908e48d3f27a53ccea6740eb1e98Dave Airlie mutex_init(&dev->ctxlist_mutex); 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24545ea5dcde62db8eccc8503defae3c3353256975dDave Airlie idr_init(&dev->drw_idr); 24645ea5dcde62db8eccc8503defae3c3353256975dDave Airlie 247b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->pdev = pdev; 2482f02cc3fb8960754a2a5df6a33f53528e0d830beEric Anholt dev->pci_device = pdev->device; 2492f02cc3fb8960754a2a5df6a33f53528e0d830beEric Anholt dev->pci_vendor = pdev->vendor; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __alpha__ 252b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->hose = pdev->sysdata; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2558d153f7107ff2c5d6e32053ae377c961187ab6b9Thomas Hellstrom if (drm_ht_create(&dev->map_hash, 12)) { 2568d153f7107ff2c5d6e32053ae377c961187ab6b9Thomas Hellstrom return -ENOMEM; 2578d153f7107ff2c5d6e32053ae377c961187ab6b9Thomas Hellstrom } 258836cf0465c422ee6d654060edd7c620d9cf0c09cDave Airlie 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* the DRM has 6 basic counters */ 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->counters = 6; 261b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[0] = _DRM_STAT_LOCK; 262b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[1] = _DRM_STAT_OPENS; 263b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[2] = _DRM_STAT_CLOSES; 264b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[3] = _DRM_STAT_IOCTLS; 265b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[4] = _DRM_STAT_LOCKS; 266b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->types[5] = _DRM_STAT_UNLOCKS; 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->driver = driver; 269b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drm_core_has_AGP(dev)) { 271cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie if (drm_device_is_agp(dev)) 272cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie dev->agp = drm_agp_init(dev); 273b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) 274b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie && (dev->agp == NULL)) { 275b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_ERROR("Cannot initialize the agpgart module.\n"); 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retcode = -EINVAL; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error_out_unreg; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drm_core_has_MTRR(dev)) { 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->agp) 281b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->agp->agp_mtrr = 282b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie mtrr_add(dev->agp->agp_info.aper_base, 283b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev->agp->agp_info.aper_size * 284b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 1024 * 1024, MTRR_TYPE_WRCOMB, 1); 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2882716a02f607c964ccaa6fa7266abd3acd73d9033Dave Airlie 289b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie retcode = drm_ctxbitmap_init(dev); 290b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (retcode) { 291b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_ERROR("Cannot allocate memory for context bitmap.\n"); 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error_out_unreg; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 295673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt if (driver->driver_features & DRIVER_GEM) { 296673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt retcode = drm_gem_init(dev); 297673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt if (retcode) { 298673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt DRM_ERROR("Cannot initialize graphics execution " 299673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt "manager (GEM)\n"); 300673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt goto error_out_unreg; 301673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt } 302673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt } 303673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 305b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 306b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie error_out_unreg: 30722eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie drm_lastclose(dev); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retcode; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Get a secondary minor number. 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \param dev device data structure 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \param sec-minor structure to hold the assigned minor 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \return negative number on failure. 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Search an empty entry and initialize it to the given parameters, and 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * create the proc init entry via proc_init(). This routines assigns 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * minor numbers to secondary heads of multi-headed cards 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3232c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airliestatic int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3252c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie struct drm_minor *new_minor; 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 3272c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie int minor_id; 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_DEBUG("\n"); 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3312c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie minor_id = drm_minor_get_id(dev, type); 3322c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (minor_id < 0) 3332c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return minor_id; 3342c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3352c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL); 3362c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (!new_minor) { 3372c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie ret = -ENOMEM; 3382c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie goto err_idr; 3392c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } 3402c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3412c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie new_minor->type = type; 3422c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie new_minor->device = MKDEV(DRM_MAJOR, minor_id); 3432c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie new_minor->dev = dev; 3442c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie new_minor->index = minor_id; 3457c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie INIT_LIST_HEAD(&new_minor->master_list); 3462c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3472c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie idr_replace(&drm_minors_idr, new_minor, minor_id); 3482c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3492c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (type == DRM_MINOR_LEGACY) { 3502c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie ret = drm_proc_init(new_minor, minor_id, drm_proc_root); 3512c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (ret) { 3522c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); 3532c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie goto err_mem; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3552c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie } else 356955b12def42e83287c1bdb1411d99451753c1391Ben Gamari new_minor->proc_root = NULL; 357955b12def42e83287c1bdb1411d99451753c1391Ben Gamari 358955b12def42e83287c1bdb1411d99451753c1391Ben Gamari#if defined(CONFIG_DEBUG_FS) 359955b12def42e83287c1bdb1411d99451753c1391Ben Gamari ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root); 360955b12def42e83287c1bdb1411d99451753c1391Ben Gamari if (ret) { 361156f5a7801195fa2ce44aeeb62d6cf8468f3332aGeunSik Lim DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n"); 362955b12def42e83287c1bdb1411d99451753c1391Ben Gamari goto err_g2; 363955b12def42e83287c1bdb1411d99451753c1391Ben Gamari } 364955b12def42e83287c1bdb1411d99451753c1391Ben Gamari#endif 3652c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3662c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie ret = drm_sysfs_device_add(new_minor); 3672c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (ret) { 3682c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie printk(KERN_ERR 3692c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie "DRM: Error sysfs_device_add.\n"); 3702c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie goto err_g2; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3722c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie *minor = new_minor; 3732c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3742c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie DRM_DEBUG("new minor assigned %d\n", minor_id); 3752c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie return 0; 3762c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3772c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie 3782c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlieerr_g2: 3792c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (new_minor->type == DRM_MINOR_LEGACY) 3802c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie drm_proc_cleanup(new_minor, drm_proc_root); 3812c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlieerr_mem: 3822c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie kfree(new_minor); 3832c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlieerr_idr: 3842c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie idr_remove(&drm_minors_idr, minor_id); 3852c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie *minor = NULL; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 388b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 389c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie/** 390c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie * Register. 391c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie * 392c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie * \param pdev - PCI device structure 393c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie * \param ent entry from the PCI ID table with device type flags 394c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie * \return zero on success or a negative number on failure. 395c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie * 396c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie * Attempt to gets inter module "drm" information. If we are first 397c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie * then register the character device and inter module information. 398c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie * Try and register, if we fail to register, backout previous work. 399c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie */ 400c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlieint drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, 401b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie struct drm_driver *driver) 402c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie{ 40384b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlie struct drm_device *dev; 404c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie int ret; 405c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie 406c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie DRM_DEBUG("\n"); 407c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie 4089a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt dev = kzalloc(sizeof(*dev), GFP_KERNEL); 409c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie if (!dev) 410c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie return -ENOMEM; 411c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie 4122c3f0eddfbd7f5c7a5450de287bad805722888c3Jeff Garzik ret = pci_enable_device(pdev); 4132c3f0eddfbd7f5c7a5450de287bad805722888c3Jeff Garzik if (ret) 4142c3f0eddfbd7f5c7a5450de287bad805722888c3Jeff Garzik goto err_g1; 415c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie 41619a8f59ab8ceee751ea720085098355d53f727d6Dave Airlie pci_set_master(pdev); 417c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { 418c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); 4192c3f0eddfbd7f5c7a5450de287bad805722888c3Jeff Garzik goto err_g2; 420c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie } 421f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie 422f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie if (drm_core_check_feature(dev, DRIVER_MODESET)) { 423112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg pci_set_drvdata(pdev, dev); 424f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); 425f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie if (ret) 426f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie goto err_g2; 427f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie } 428f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie 4292c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) 430f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie goto err_g3; 431bc5f4523f772cc7629c5c5a46cf4f2a07a5500b8Dave Airlie 432f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie if (dev->driver->load) { 433f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie ret = dev->driver->load(dev, ent->driver_data); 434f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie if (ret) 4353788f48a0fad246dbab826e8b2f07b403b0e3279Ben Skeggs goto err_g4; 436f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie } 437f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie 438f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie /* setup the grouping for the legacy output */ 439f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie if (drm_core_check_feature(dev, DRIVER_MODESET)) { 440f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group); 441f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie if (ret) 4423788f48a0fad246dbab826e8b2f07b403b0e3279Ben Skeggs goto err_g4; 443f453ba0460742ad027ae0c4c7d61e62817b3e7efDave Airlie } 444a9d51a5ad1154b5b20add1e8d30a5564f8aabbe9Dave Airlie 445e7f7ab45ebcb54fd5f814ea15ea079e079662f67Dave Airlie list_add_tail(&dev->driver_item, &driver->device_list); 446e7f7ab45ebcb54fd5f814ea15ea079e079662f67Dave Airlie 447cd00f95aff6b4cfeccb261fd4100cceb4f5270eaBenjamin Herrenschmidt DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", 44822eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie driver->name, driver->major, driver->minor, driver->patchlevel, 449cd00f95aff6b4cfeccb261fd4100cceb4f5270eaBenjamin Herrenschmidt driver->date, pci_name(pdev), dev->primary->index); 450c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie 451c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie return 0; 452c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie 4533788f48a0fad246dbab826e8b2f07b403b0e3279Ben Skeggserr_g4: 454a9d51a5ad1154b5b20add1e8d30a5564f8aabbe9Dave Airlie drm_put_minor(&dev->primary); 4553788f48a0fad246dbab826e8b2f07b403b0e3279Ben Skeggserr_g3: 4563788f48a0fad246dbab826e8b2f07b403b0e3279Ben Skeggs if (drm_core_check_feature(dev, DRIVER_MODESET)) 4573788f48a0fad246dbab826e8b2f07b403b0e3279Ben Skeggs drm_put_minor(&dev->control); 4582c3f0eddfbd7f5c7a5450de287bad805722888c3Jeff Garzikerr_g2: 4592c3f0eddfbd7f5c7a5450de287bad805722888c3Jeff Garzik pci_disable_device(pdev); 4602c3f0eddfbd7f5c7a5450de287bad805722888c3Jeff Garzikerr_g1: 4619a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(dev); 462c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie return ret; 463c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie} 464112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian HøgsbergEXPORT_SYMBOL(drm_get_dev); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Put a secondary minor number. 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \param sec_minor - structure to be released 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * \return always zero 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Cleans up the proc resources. Not legal for this to be the 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * last minor released. 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4762c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlieint drm_put_minor(struct drm_minor **minor_p) 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4782c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie struct drm_minor *minor = *minor_p; 479673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 4802c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie DRM_DEBUG("release secondary minor %d\n", minor->index); 481b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 4822c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie if (minor->type == DRM_MINOR_LEGACY) 4832c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie drm_proc_cleanup(minor, drm_proc_root); 484955b12def42e83287c1bdb1411d99451753c1391Ben Gamari#if defined(CONFIG_DEBUG_FS) 485955b12def42e83287c1bdb1411d99451753c1391Ben Gamari drm_debugfs_cleanup(minor); 486955b12def42e83287c1bdb1411d99451753c1391Ben Gamari#endif 487955b12def42e83287c1bdb1411d99451753c1391Ben Gamari 4882c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie drm_sysfs_device_remove(minor); 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4902c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie idr_remove(&drm_minors_idr, minor->index); 491b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 4922c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie kfree(minor); 4932c14f28be2a3f2a2e9861b156d64fbe2bc7000c3Dave Airlie *minor_p = NULL; 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 496112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 497112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg/** 498112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * Called via drm_exit() at module unload time or when pci device is 499112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * unplugged. 500112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * 501112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * Cleans up all DRM device, calling drm_lastclose(). 502112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * 503112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg * \sa drm_init 504112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg */ 505112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsbergvoid drm_put_dev(struct drm_device *dev) 506112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg{ 507ecca0683230b83e8f830ff157911fad20bc43015Julia Lawall struct drm_driver *driver; 508112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg struct drm_map_list *r_list, *list_temp; 509112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 510112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg DRM_DEBUG("\n"); 511112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 512112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (!dev) { 513112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg DRM_ERROR("cleanup called no dev\n"); 514112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg return; 515112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg } 516ecca0683230b83e8f830ff157911fad20bc43015Julia Lawall driver = dev->driver; 517112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 518112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg drm_lastclose(dev); 519112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 520112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && 521112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->agp && dev->agp->agp_mtrr >= 0) { 522112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg int retval; 523112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg retval = mtrr_del(dev->agp->agp_mtrr, 524112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->agp->agp_info.aper_base, 525112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->agp->agp_info.aper_size * 1024 * 1024); 526112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg DRM_DEBUG("mtrr_del=%d\n", retval); 527112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg } 528112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 529112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (dev->driver->unload) 530112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->driver->unload(dev); 531112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 532112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (drm_core_has_AGP(dev) && dev->agp) { 5339a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(dev->agp); 534112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->agp = NULL; 535112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg } 536112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 537b78315f051de8d207bead90470aa216c0617572bJesse Barnes drm_vblank_cleanup(dev); 538b78315f051de8d207bead90470aa216c0617572bJesse Barnes 539112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) 540112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg drm_rmmap(dev, r_list->map); 54130ddbd94401a132f4d932775d1902b3c9a8c41b5Ben Skeggs drm_ht_remove(&dev->map_hash); 54230ddbd94401a132f4d932775d1902b3c9a8c41b5Ben Skeggs 54330ddbd94401a132f4d932775d1902b3c9a8c41b5Ben Skeggs drm_ctxbitmap_cleanup(dev); 544112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 545112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (drm_core_check_feature(dev, DRIVER_MODESET)) 546112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg drm_put_minor(&dev->control); 547112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 548112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (driver->driver_features & DRIVER_GEM) 549112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg drm_gem_destroy(dev); 550112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 551112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg drm_put_minor(&dev->primary); 552112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg 553112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg if (dev->devname) { 5549a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(dev->devname); 555112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg dev->devname = NULL; 556112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg } 5579a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(dev); 558112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian Høgsberg} 559112b715e8e2f9ef7b96930888bb099ce10b4c3ccKristian HøgsbergEXPORT_SYMBOL(drm_put_dev); 560