diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2008-06-12 19:14:54 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2008-06-12 19:14:54 +0000 |
commit | 016d76b42f5668a3ec87b0eaae5db4dbdd895ac0 (patch) | |
tree | 5634e51ee8865331a381cb90df6b8be150505a61 /sys/dev/pci/drm/drm_bufs.c | |
parent | 3d3206644e64e89ec391bfc42c96961e1bb9b527 (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.c | 24 |
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; |