1 /**************************************************************************
3 * This kernel module is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License as
5 * published by the Free Software Foundation; either version 2 of the
6 * License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 **************************************************************************/
19 * This code provides access to unexported mm kernel features. It is necessary
20 * to use the new DRM memory manager code with kernels that don't support it
23 * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
24 * Linux kernel mm subsystem authors.
25 * (Most code taken from there).
30 #ifdef DRM_IDR_COMPAT_FN
31 /* only called when idp->lock is held */
32 static void __free_layer(struct idr *idp, struct idr_layer *p)
34 p->ary[0] = idp->id_free;
39 static void free_layer(struct idr *idp, struct idr_layer *p)
44 * Depends on the return element being zeroed.
46 spin_lock_irqsave(&idp->lock, flags);
48 spin_unlock_irqrestore(&idp->lock, flags);
52 * idr_for_each - iterate through all stored pointers
54 * @fn: function to be called for each pointer
55 * @data: data passed back to callback function
57 * Iterate over the pointers registered with the given idr. The
58 * callback function will be called for each pointer currently
59 * registered, passing the id, the pointer and the data pointer passed
60 * to this function. It is not safe to modify the idr tree while in
61 * the callback, so functions such as idr_get_new and idr_remove are
64 * We check the return of @fn each time. If it returns anything other
65 * than 0, we break out and return that value.
67 * The caller must serialize idr_find() vs idr_get_new() and idr_remove().
69 int idr_for_each(struct idr *idp,
70 int (*fn)(int id, void *p, void *data), void *data)
72 int n, id, max, error = 0;
74 struct idr_layer *pa[MAX_LEVEL];
75 struct idr_layer **paa = &pa[0];
77 n = idp->layers * IDR_BITS;
86 p = p->ary[(id >> n) & IDR_MASK];
90 error = fn(id, (void *)p, data);
104 EXPORT_SYMBOL(idr_for_each);
107 * idr_remove_all - remove all ids from the given idr tree
110 * idr_destroy() only frees up unused, cached idp_layers, but this
111 * function will remove all id mappings and leave all idp_layers
114 * A typical clean-up sequence for objects stored in an idr tree, will
115 * use idr_for_each() to free all objects, if necessay, then
116 * idr_remove_all() to remove all ids, and idr_destroy() to free
117 * up the cached idr_layers.
119 void idr_remove_all(struct idr *idp)
121 int n, id, max, error = 0;
123 struct idr_layer *pa[MAX_LEVEL];
124 struct idr_layer **paa = &pa[0];
126 n = idp->layers * IDR_BITS;
131 while (id < max && !error) {
132 while (n > IDR_BITS && p) {
135 p = p->ary[(id >> n) & IDR_MASK];
139 while (n < fls(id)) {
141 memset(p, 0, sizeof *p);
151 EXPORT_SYMBOL(idr_remove_all);
153 #endif /* DRM_IDR_COMPAT_FN */
157 unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
158 unsigned long address)
160 struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data;
161 unsigned long page_offset;
162 struct page *page = NULL;
164 struct drm_device *dev;
167 unsigned long bus_base;
168 unsigned long bus_offset;
169 unsigned long bus_size;
170 unsigned long ret = NOPFN_REFAULT;
172 if (address > vma->vm_end)
176 err = drm_bo_read_lock(&dev->bm.bm_lock, 1);
178 return NOPFN_REFAULT;
180 err = mutex_lock_interruptible(&bo->mutex);
182 drm_bo_read_unlock(&dev->bm.bm_lock);
183 return NOPFN_REFAULT;
186 err = drm_bo_wait(bo, 0, 1, 0, 1);
188 ret = (err != -EAGAIN) ? NOPFN_SIGBUS : NOPFN_REFAULT;
189 bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED;
193 bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED;
196 * If buffer happens to be in a non-mappable location,
197 * move it to a mappable.
200 if (!(bo->mem.flags & DRM_BO_FLAG_MAPPABLE)) {
201 uint32_t new_flags = bo->mem.proposed_flags |
202 DRM_BO_FLAG_MAPPABLE |
203 DRM_BO_FLAG_FORCE_MAPPABLE;
204 err = drm_bo_move_buffer(bo, new_flags, 0, 0);
206 ret = (err != -EAGAIN) ? NOPFN_SIGBUS : NOPFN_REFAULT;
211 err = drm_bo_pci_offset(dev, &bo->mem, &bus_base, &bus_offset,
219 page_offset = (address - vma->vm_start) >> PAGE_SHIFT;
222 struct drm_mem_type_manager *man = &dev->bm.man[bo->mem.mem_type];
224 pfn = ((bus_base + bus_offset) >> PAGE_SHIFT) + page_offset;
225 vma->vm_page_prot = drm_io_prot(man->drm_bus_maptype, vma);
229 drm_ttm_fixup_caching(ttm);
230 page = drm_ttm_get_page(ttm, page_offset);
235 pfn = page_to_pfn(page);
236 vma->vm_page_prot = (bo->mem.flags & DRM_BO_FLAG_CACHED) ?
237 vm_get_page_prot(vma->vm_flags) :
238 drm_io_prot(_DRM_TTM, vma);
241 err = vm_insert_pfn(vma, address, pfn);
243 ret = (err != -EAGAIN) ? NOPFN_OOM : NOPFN_REFAULT;
247 BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED);
248 mutex_unlock(&bo->mutex);
249 drm_bo_read_unlock(&dev->bm.bm_lock);