summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm/drm_bufs.c
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2008-06-12 19:14:54 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2008-06-12 19:14:54 +0000
commit016d76b42f5668a3ec87b0eaae5db4dbdd895ac0 (patch)
tree5634e51ee8865331a381cb90df6b8be150505a61 /sys/dev/pci/drm/drm_bufs.c
parent3d3206644e64e89ec391bfc42c96961e1bb9b527 (diff)
The mmap offsets for memory buffers currently are the kernel virtual
address. This is just plain wrong. scatter/gather on amd64 didn't work here, since char device mmap doesn't take negative offsets so higher kvas fail. Instead, prematurely import drm_memrange which is needed for the memory managers (GEM or TTM), and is used to manage GART space. Then, horribly abuse it to allocate mmap offsets, fixes up the issues. "just commit it" art@.
Diffstat (limited to 'sys/dev/pci/drm/drm_bufs.c')
-rw-r--r--sys/dev/pci/drm/drm_bufs.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/sys/dev/pci/drm/drm_bufs.c b/sys/dev/pci/drm/drm_bufs.c
index 83e0c71f1ae..ae3a50fb351 100644
--- a/sys/dev/pci/drm/drm_bufs.c
+++ b/sys/dev/pci/drm/drm_bufs.c
@@ -191,6 +191,22 @@ drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
map->type = type;
map->flags = flags;
+
+ map->mm = drm_memrange_search_free(&dev->handle_mm, map->size,
+ PAGE_SIZE, 0);
+ if (map->mm == NULL) {
+ DRM_ERROR("can't find free offset\n");
+ free(map, M_DRM);
+ return ENOMEM;
+ }
+ map->mm = drm_memrange_get_block(map->mm, map->size,
+ PAGE_SIZE);
+ if (map->mm == NULL) {
+ DRM_ERROR("can't get block\n");
+ free(map, M_DRM);
+ return ENOMEM;
+ }
+
switch ( map->type ) {
case _DRM_REGISTERS:
map->handle = drm_ioremap(dev, map);
@@ -365,7 +381,7 @@ drm_addmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
#ifndef __OpenBSD__
if (request->type != _DRM_SHM)
#endif
- request->handle = (void *)request->offset;
+ request->handle = (void *)map->mm->start;
return 0;
}
@@ -421,6 +437,8 @@ drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
}
#endif
+ drm_memrange_put_block(map->mm);
+
free(map, M_DRM);
}
@@ -676,7 +694,7 @@ drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
free(entry->buflist, M_DRM);
return ENOMEM;
}
-
+
memcpy(temp_pagelist, dma->pagelist, dma->page_count *
sizeof(*dma->pagelist));
@@ -1184,7 +1202,7 @@ drm_mapbufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
goto done;
}
size = round_page(map->size);
- foff = map->offset;
+ foff = map->mm->start;
} else {
size = round_page(dma->byte_count),
foff = 0;