]>
Commit | Line | Data |
---|---|---|
635816e1 AC |
1 | /************************************************************************** |
2 | * Copyright (c) 2011, Intel Corporation. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms and conditions of the GNU General Public License, | |
7 | * version 2, as published by the Free Software Foundation. | |
8 | * | |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
12 | * more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along with | |
15 | * this program; if not, write to the Free Software Foundation, Inc., | |
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | |
17 | * | |
18 | **************************************************************************/ | |
19 | ||
20 | #include <drm/drmP.h> | |
21 | #include <drm/drm.h> | |
22 | ||
635816e1 AC |
23 | void drm_gem_object_release_wrap(struct drm_gem_object *obj) |
24 | { | |
5338afdf AC |
25 | /* Remove the list map if one is present */ |
26 | if (obj->map_list.map) { | |
27 | struct drm_gem_mm *mm = obj->dev->mm_private; | |
28 | struct drm_map_list *list = &obj->map_list; | |
29 | drm_ht_remove_item(&mm->offset_hash, &list->hash); | |
30 | drm_mm_put_block(list->file_offset_node); | |
31 | kfree(list->map); | |
32 | list->map = NULL; | |
33 | } | |
ab04fc58 | 34 | drm_gem_object_release(obj); |
635816e1 | 35 | } |
eee9b52e AC |
36 | |
37 | /** | |
38 | * gem_create_mmap_offset - invent an mmap offset | |
39 | * @obj: our object | |
40 | * | |
41 | * Standard implementation of offset generation for mmap as is | |
42 | * duplicated in several drivers. This belongs in GEM. | |
43 | */ | |
44 | int gem_create_mmap_offset(struct drm_gem_object *obj) | |
45 | { | |
46 | struct drm_device *dev = obj->dev; | |
47 | struct drm_gem_mm *mm = dev->mm_private; | |
48 | struct drm_map_list *list; | |
49 | struct drm_local_map *map; | |
50 | int ret; | |
51 | ||
52 | list = &obj->map_list; | |
53 | list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); | |
54 | if (list->map == NULL) | |
55 | return -ENOMEM; | |
56 | map = list->map; | |
57 | map->type = _DRM_GEM; | |
58 | map->size = obj->size; | |
59 | map->handle = obj; | |
60 | ||
61 | list->file_offset_node = drm_mm_search_free(&mm->offset_manager, | |
62 | obj->size / PAGE_SIZE, 0, 0); | |
63 | if (!list->file_offset_node) { | |
64 | dev_err(dev->dev, "failed to allocate offset for bo %d\n", | |
65 | obj->name); | |
66 | ret = -ENOSPC; | |
67 | goto free_it; | |
68 | } | |
69 | list->file_offset_node = drm_mm_get_block(list->file_offset_node, | |
70 | obj->size / PAGE_SIZE, 0); | |
71 | if (!list->file_offset_node) { | |
72 | ret = -ENOMEM; | |
73 | goto free_it; | |
74 | } | |
75 | list->hash.key = list->file_offset_node->start; | |
76 | ret = drm_ht_insert_item(&mm->offset_hash, &list->hash); | |
77 | if (ret) { | |
78 | dev_err(dev->dev, "failed to add to map hash\n"); | |
79 | goto free_mm; | |
80 | } | |
81 | return 0; | |
82 | ||
83 | free_mm: | |
84 | drm_mm_put_block(list->file_offset_node); | |
85 | free_it: | |
86 | kfree(list->map); | |
87 | list->map = NULL; | |
88 | return ret; | |
89 | } |