diff options
Diffstat (limited to 'linux-core/drm_compat.c')
-rw-r--r-- | linux-core/drm_compat.c | 272 |
1 files changed, 2 insertions, 270 deletions
diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c index ff4085de..fb396494 100644 --- a/linux-core/drm_compat.c +++ b/linux-core/drm_compat.c @@ -27,31 +27,7 @@ #include "drmP.h" -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) - -/* - * The protection map was exported in 2.6.19 - */ - -pgprot_t vm_get_page_prot(unsigned long vm_flags) -{ -#ifdef MODULE - static pgprot_t drm_protection_map[16] = { - __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111, - __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111 - }; - - return drm_protection_map[vm_flags & 0x0F]; -#else - extern pgprot_t protection_map[]; - return protection_map[vm_flags & 0x0F]; -#endif -}; -#endif - - -#if !defined(DRM_FULL_MM_COMPAT) && \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) +#if !defined(DRM_FULL_MM_COMPAT) static int drm_pte_is_clear(struct vm_area_struct *vma, unsigned long addr) @@ -193,14 +169,6 @@ out_unlock: return NULL; } -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) && \ - !defined(DRM_FULL_MM_COMPAT) - -/** - */ - unsigned long drm_bo_vm_nopfn(struct vm_area_struct * vma, unsigned long address) { @@ -219,243 +187,7 @@ unsigned long drm_bo_vm_nopfn(struct vm_area_struct * vma, return 0; } -#endif - - -#ifdef DRM_ODD_MM_COMPAT - -/* - * VM compatibility code for 2.6.15-2.6.18. This code implements a complicated - * workaround for a single BUG statement in do_no_page in these versions. The - * tricky thing is that we need to take the mmap_sem in exclusive mode for _all_ - * vmas mapping the ttm, before dev->struct_mutex is taken. The way we do this is to - * check first take the dev->struct_mutex, and then trylock all mmap_sems. If this - * fails for a single mmap_sem, we have to release all sems and the dev->struct_mutex, - * release the cpu and retry. We also need to keep track of all vmas mapping the ttm. - * phew. - */ - -typedef struct p_mm_entry { - struct list_head head; - struct mm_struct *mm; - atomic_t refcount; - int locked; -} p_mm_entry_t; - -typedef struct vma_entry { - struct list_head head; - struct vm_area_struct *vma; -} vma_entry_t; - - -struct page *drm_bo_vm_nopage(struct vm_area_struct *vma, - unsigned long address, - int *type) -{ - struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data; - unsigned long page_offset; - struct page *page; - struct drm_ttm *ttm; - struct drm_device *dev; - - mutex_lock(&bo->mutex); - - if (type) - *type = VM_FAULT_MINOR; - - if (address > vma->vm_end) { - page = NOPAGE_SIGBUS; - goto out_unlock; - } - - dev = bo->dev; - - if (drm_mem_reg_is_pci(dev, &bo->mem)) { - DRM_ERROR("Invalid compat nopage.\n"); - page = NOPAGE_SIGBUS; - goto out_unlock; - } - - ttm = bo->ttm; - drm_ttm_fixup_caching(ttm); - page_offset = (address - vma->vm_start) >> PAGE_SHIFT; - page = drm_ttm_get_page(ttm, page_offset); - if (!page) { - page = NOPAGE_OOM; - goto out_unlock; - } - - get_page(page); -out_unlock: - mutex_unlock(&bo->mutex); - return page; -} - - - - -int drm_bo_map_bound(struct vm_area_struct *vma) -{ - struct drm_buffer_object *bo = (struct drm_buffer_object *)vma->vm_private_data; - int ret = 0; - unsigned long bus_base; - unsigned long bus_offset; - unsigned long bus_size; - - ret = drm_bo_pci_offset(bo->dev, &bo->mem, &bus_base, - &bus_offset, &bus_size); - BUG_ON(ret); - - if (bus_size) { - struct drm_mem_type_manager *man = &bo->dev->bm.man[bo->mem.mem_type]; - unsigned long pfn = (bus_base + bus_offset) >> PAGE_SHIFT; - pgprot_t pgprot = drm_io_prot(man->drm_bus_maptype, vma); - ret = io_remap_pfn_range(vma, vma->vm_start, pfn, - vma->vm_end - vma->vm_start, - pgprot); - } - - return ret; -} - - -int drm_bo_add_vma(struct drm_buffer_object * bo, struct vm_area_struct *vma) -{ - p_mm_entry_t *entry, *n_entry; - vma_entry_t *v_entry; - struct mm_struct *mm = vma->vm_mm; - - v_entry = drm_ctl_alloc(sizeof(*v_entry), DRM_MEM_BUFOBJ); - if (!v_entry) { - DRM_ERROR("Allocation of vma pointer entry failed\n"); - return -ENOMEM; - } - v_entry->vma = vma; - - list_add_tail(&v_entry->head, &bo->vma_list); - - list_for_each_entry(entry, &bo->p_mm_list, head) { - if (mm == entry->mm) { - atomic_inc(&entry->refcount); - return 0; - } else if ((unsigned long)mm < (unsigned long)entry->mm) ; - } - - n_entry = drm_ctl_alloc(sizeof(*n_entry), DRM_MEM_BUFOBJ); - if (!n_entry) { - DRM_ERROR("Allocation of process mm pointer entry failed\n"); - return -ENOMEM; - } - INIT_LIST_HEAD(&n_entry->head); - n_entry->mm = mm; - n_entry->locked = 0; - atomic_set(&n_entry->refcount, 0); - list_add_tail(&n_entry->head, &entry->head); - - return 0; -} - -void drm_bo_delete_vma(struct drm_buffer_object * bo, struct vm_area_struct *vma) -{ - p_mm_entry_t *entry, *n; - vma_entry_t *v_entry, *v_n; - int found = 0; - struct mm_struct *mm = vma->vm_mm; - - list_for_each_entry_safe(v_entry, v_n, &bo->vma_list, head) { - if (v_entry->vma == vma) { - found = 1; - list_del(&v_entry->head); - drm_ctl_free(v_entry, sizeof(*v_entry), DRM_MEM_BUFOBJ); - break; - } - } - BUG_ON(!found); - - list_for_each_entry_safe(entry, n, &bo->p_mm_list, head) { - if (mm == entry->mm) { - if (atomic_add_negative(-1, &entry->refcount)) { - list_del(&entry->head); - BUG_ON(entry->locked); - drm_ctl_free(entry, sizeof(*entry), DRM_MEM_BUFOBJ); - } - return; - } - } - BUG_ON(1); -} - - - -int drm_bo_lock_kmm(struct drm_buffer_object * bo) -{ - p_mm_entry_t *entry; - int lock_ok = 1; - - list_for_each_entry(entry, &bo->p_mm_list, head) { - BUG_ON(entry->locked); - if (!down_write_trylock(&entry->mm->mmap_sem)) { - lock_ok = 0; - break; - } - entry->locked = 1; - } - - if (lock_ok) - return 0; - - list_for_each_entry(entry, &bo->p_mm_list, head) { - if (!entry->locked) - break; - up_write(&entry->mm->mmap_sem); - entry->locked = 0; - } - - /* - * Possible deadlock. Try again. Our callers should handle this - * and restart. - */ - - return -EAGAIN; -} - -void drm_bo_unlock_kmm(struct drm_buffer_object * bo) -{ - p_mm_entry_t *entry; - - list_for_each_entry(entry, &bo->p_mm_list, head) { - BUG_ON(!entry->locked); - up_write(&entry->mm->mmap_sem); - entry->locked = 0; - } -} - -int drm_bo_remap_bound(struct drm_buffer_object *bo) -{ - vma_entry_t *v_entry; - int ret = 0; - - if (drm_mem_reg_is_pci(bo->dev, &bo->mem)) { - list_for_each_entry(v_entry, &bo->vma_list, head) { - ret = drm_bo_map_bound(v_entry->vma); - if (ret) - break; - } - } - - return ret; -} - -void drm_bo_finish_unmap(struct drm_buffer_object *bo) -{ - vma_entry_t *v_entry; - - list_for_each_entry(v_entry, &bo->vma_list, head) { - v_entry->vma->vm_flags &= ~VM_PFNMAP; - } -} - -#endif +#endif /* !defined(DRM_FULL_MM_COMPAT) */ #ifdef DRM_IDR_COMPAT_FN /* only called when idp->lock is held */ |