summaryrefslogtreecommitdiff
path: root/drivers/char/drm/drm_vm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-09-30 11:29:54 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-30 11:29:54 -0700
commite823aff2d6eb43083abcc75a32ddfb167c324089 (patch)
tree60b67f3f2f088d6741a5af8488b4a565fb4c4cfe /drivers/char/drm/drm_vm.c
parent77ed74da26f50fa28471571ee7a2251b77526d84 (diff)
parent3e14a2867d8ccf555fe6e318eac0f8200399fe1c (diff)
Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (36 commits) drm: Use register writes instead of BITBLT_MULTI packets for buffer swap blits drm: use radeon specific names for radeon flags drm: add device/vendor id to drm_device_t for compat with FreeBSD drivers drm: allow multiple addMaps with the same 32-bit map offsset. drm: fd.o Bug #7595: Avoid u32 overflows in radeon_check_and_fixup_offset(). drm: Fix hashtab implementation leaking illegal error codes to user space. drm: domain changes broke ppc r200 drm: fixup setversion return codes.. drm: fixup i915 error codes drm: realign sosme radeon code with drm git tree drm: realign via driver with drm git tree drm: remove hash tables on drm exit drm: cleanups drm: i810_dma.c: fix pointer arithmetic for 64-bit target drm: avoid kernel oops in some error paths calling drm_lastclose drm: allow detection of new VIA chipsets drm: fix i965 build bug drm: remove FALSE/TRUE that snuck in with simple memory manager changes. drm: Add support for Intel i965G chipsets. drm: add better explanation for i830/i915 ...
Diffstat (limited to 'drivers/char/drm/drm_vm.c')
-rw-r--r--drivers/char/drm/drm_vm.c45
1 files changed, 15 insertions, 30 deletions
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index ffd0800ed601..b40ae438f531 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -59,7 +59,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
drm_device_t *dev = priv->head->dev;
drm_map_t *map = NULL;
drm_map_list_t *r_list;
- struct list_head *list;
+ drm_hash_item_t *hash;
/*
* Find the right map
@@ -70,14 +70,11 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
if (!dev->agp || !dev->agp->cant_use_aperture)
goto vm_nopage_error;
- list_for_each(list, &dev->maplist->head) {
- r_list = list_entry(list, drm_map_list_t, head);
- map = r_list->map;
- if (!map)
- continue;
- if (r_list->user_token == VM_OFFSET(vma))
- break;
- }
+ if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash))
+ goto vm_nopage_error;
+
+ r_list = drm_hash_entry(hash, drm_map_list_t, hash);
+ map = r_list->map;
if (map && map->type == _DRM_AGP) {
unsigned long offset = address - vma->vm_start;
@@ -467,7 +464,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
dev = priv->head->dev;
dma = dev->dma;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
- vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+ vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT);
/* Length must match exact page count */
if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
@@ -521,12 +518,11 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_map_t *map = NULL;
- drm_map_list_t *r_list;
unsigned long offset = 0;
- struct list_head *list;
+ drm_hash_item_t *hash;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
- vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+ vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT);
if (!priv->authenticated)
return -EACCES;
@@ -535,7 +531,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
* the AGP mapped at physical address 0
* --BenH.
*/
- if (!VM_OFFSET(vma)
+ if (!(vma->vm_pgoff << PAGE_SHIFT)
#if __OS_HAS_AGP
&& (!dev->agp
|| dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
@@ -543,23 +539,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
)
return drm_mmap_dma(filp, vma);
- /* A sequential search of a linked list is
- fine here because: 1) there will only be
- about 5-10 entries in the list and, 2) a
- DRI client only has to do this mapping
- once, so it doesn't have to be optimized
- for performance, even if the list was a
- bit longer. */
- list_for_each(list, &dev->maplist->head) {
-
- r_list = list_entry(list, drm_map_list_t, head);
- map = r_list->map;
- if (!map)
- continue;
- if (r_list->user_token == VM_OFFSET(vma))
- break;
+ if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) {
+ DRM_ERROR("Could not find map\n");
+ return -EINVAL;
}
+ map = drm_hash_entry(hash, drm_map_list_t, hash)->map;
if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
return -EPERM;
@@ -620,7 +605,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
offset = dev->driver->get_reg_ofs(dev);
#ifdef __sparc__
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
+ if (io_remap_pfn_range(vma, vma->vm_start,
(map->offset + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))