summaryrefslogtreecommitdiff
path: root/linux-core/drm_vm.c
diff options
context:
space:
mode:
authorJeff Hartmann <jhartmann@valinux.com>2001-08-10 16:29:21 +0000
committerJeff Hartmann <jhartmann@valinux.com>2001-08-10 16:29:21 +0000
commit97b8aa52bba602d5babe225983f7e4c7cb4d7492 (patch)
tree922882797ea335549c01849c4dd2cdc350938be0 /linux-core/drm_vm.c
parentb6923b39539c34c2a589197def5eee72a9d719bf (diff)
Commit Keith Owens kernel Makefile changes, merge and commit alpha patch
set from Jay Estabrook (sans some mga modifications which broke other arch's.)
Diffstat (limited to 'linux-core/drm_vm.c')
-rw-r--r--linux-core/drm_vm.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c
index d8e77f79..2a5ee146 100644
--- a/linux-core/drm_vm.c
+++ b/linux-core/drm_vm.c
@@ -67,6 +67,64 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
int write_access)
#endif
{
+#if defined(__alpha__) && __REALLY_HAVE_AGP
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_map_t *map = NULL;
+ drm_map_list_t *r_list;
+ struct list_head *list;
+
+ /*
+ * Find the right map
+ */
+ list_for_each(list, &dev->maplist->head) {
+ r_list = (drm_map_list_t *)list;
+ map = r_list->map;
+ if (!map) continue;
+ if (map->offset == VM_OFFSET(vma)) break;
+ }
+
+ if (map && map->type == _DRM_AGP) {
+ unsigned long offset = address - vma->vm_start;
+ unsigned long baddr = VM_OFFSET(vma) + offset;
+ struct drm_agp_mem *agpmem;
+ struct page *page;
+
+ /*
+ * Make it a bus-relative address
+ */
+ baddr -= dev->hose->mem_space->start;
+
+ /*
+ * It's AGP memory - find the real physical page to map
+ */
+ for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
+ if (agpmem->bound <= baddr &&
+ agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
+ break;
+ }
+
+ if (!agpmem) {
+ /*
+ * Oops - no memory found
+ */
+ return NOPAGE_SIGBUS; /* couldn't find it */
+ }
+
+ /*
+ * Get the page, inc the use count, and return it
+ */
+ offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
+ agpmem->memory->memory[offset] &= ~1UL; /* HACK */
+ page = virt_to_page(__va(agpmem->memory->memory[offset]));
+#if 0
+DRM_ERROR("baddr = 0x%lx page = 0x%lx, offset = 0x%lx\n",
+ baddr, __va(agpmem->memory->memory[offset]), offset);
+#endif
+ get_page(page);
+ return page;
+ }
+#endif
return NOPAGE_SIGBUS; /* Disallow mremap */
}
@@ -434,9 +492,20 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
}
switch (map->type) {
+ case _DRM_AGP:
+#if defined(__alpha__)
+ /*
+ * On Alpha we can't talk to bus dma address from the
+ * CPU, so for memory of type DRM_AGP, we'll deal with
+ * sorting out the real physical pages and mappings
+ * in nopage()
+ */
+ vma->vm_ops = &DRM(vm_ops);
+ break;
+#endif
+ /* fall through to _DRM_FRAME_BUFFER... */
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
- case _DRM_AGP:
if (VM_OFFSET(vma) >= __pa(high_memory)) {
#if defined(__i386__)
if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {