From ed165a25292740d5d3ef7e78dc04a6a3402562aa Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Sat, 1 Jan 2005 20:03:15 +0000 Subject: Added a new DRM map type _DRM_CONSISTENT for consistent PCI memory. It uses drm_pci_alloc/free for allocating/freeing the memory. Only implemented in the Linux DRM so far. --- libdrm/xf86drm.h | 3 ++- linux-core/drm_bufs.c | 19 ++++++++++++++++++- linux-core/drm_drv.c | 5 +++++ linux-core/drm_pci.c | 1 - linux-core/drm_proc.c | 8 ++++---- linux-core/drm_vm.c | 7 +++++++ shared-core/drm.h | 3 ++- 7 files changed, 38 insertions(+), 8 deletions(-) diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index b44e4281..b33d525e 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -104,7 +104,8 @@ typedef enum { DRM_REGISTERS = 1, /**< no caching, no core dump */ DRM_SHM = 2, /**< shared, cached */ DRM_AGP = 3, /**< AGP/GART */ - DRM_SCATTER_GATHER = 4 /**< PCI scatter/gather */ + DRM_SCATTER_GATHER = 4, /**< PCI scatter/gather */ + DRM_CONSISTENT = 5 /**< PCI consistent */ } drmMapType; typedef enum { diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 947042bf..ce51397a 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -244,7 +244,21 @@ int drm_addmap(struct inode *inode, struct file *filp, } map->offset += dev->sg->handle; break; - + case _DRM_CONSISTENT: { + /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G. + * As we're limiting the address to 2^32-1 (or less), + * casting it down to 32 bits is no problem, but we + * need to point to a 64bit variable first. */ + dma_addr_t bus_addr; + map->handle = drm_pci_alloc(dev, map->size, map->size, + 0xffffffffUL, &bus_addr); + map->offset = (unsigned long)bus_addr; + if (!map->handle) { + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + return -ENOMEM; + } + break; + } default: drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; @@ -348,6 +362,9 @@ int drm_rmmap(struct inode *inode, struct file *filp, case _DRM_AGP: case _DRM_SCATTER_GATHER: break; + case _DRM_CONSISTENT: + drm_pci_free(dev, map->size, map->handle, map->offset); + break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); } diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index fbebe23c..c720f94b 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -227,6 +227,10 @@ int drm_takedown(drm_device_t * dev) dev->sg = NULL; } break; + case _DRM_CONSISTENT: + drm_pci_free(dev, map->size, + map->handle, map->offset); + break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); } @@ -396,6 +400,7 @@ static void __exit drm_cleanup(drm_device_t * dev) case _DRM_SHM: case _DRM_AGP: case _DRM_SCATTER_GATHER: + case _DRM_CONSISTENT: DRM_DEBUG("Extra maplist item\n"); break; } diff --git a/linux-core/drm_pci.c b/linux-core/drm_pci.c index 1ed0783a..30e1ba8d 100644 --- a/linux-core/drm_pci.c +++ b/linux-core/drm_pci.c @@ -6,7 +6,6 @@ * \warning These interfaces aren't stable yet. * * \todo Implement the remaining ioctl's for the PCI pools. - * \todo Add support to map these buffers. * \todo The wrappers here are so thin that they would be better off inlined.. * * \author Jose Fonseca diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index 5a92fb30..b385df5f 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c @@ -211,9 +211,9 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request, struct list_head *list; /* Hardcoded from _DRM_FRAME_BUFFER, - _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and - _DRM_SCATTER_GATHER. */ - const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" }; + _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, + _DRM_SCATTER_GATHER, and _DRM_CONSISTENT. */ + const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; const char *type; int i; @@ -234,7 +234,7 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request, map = r_list->map; if (!map) continue; - if (map->type < 0 || map->type > 4) + if (map->type < 0 || map->type > 5) type = "??"; else type = types[map->type]; diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 9b49efdc..3372498b 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -232,6 +232,10 @@ void drm_vm_shm_close(struct vm_area_struct *vma) case _DRM_AGP: case _DRM_SCATTER_GATHER: break; + case _DRM_CONSISTENT: + drm_pci_free(dev, map->size, map->handle, + map->offset); + break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); } @@ -658,6 +662,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_ops = &drm_vm_ops; break; case _DRM_SHM: + case _DRM_CONSISTENT: + /* Consistent memory is really like shared memory. It's only + * allocated in a different way. */ vma->vm_ops = &drm_vm_shm_ops; vma->vm_private_data = (void *)map; /* Don't let this area swap. Change when diff --git a/shared-core/drm.h b/shared-core/drm.h index 0d907629..f223542e 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -246,7 +246,8 @@ typedef enum drm_map_type { _DRM_REGISTERS = 1, /**< no caching, no core dump */ _DRM_SHM = 2, /**< shared, cached */ _DRM_AGP = 3, /**< AGP/GART */ - _DRM_SCATTER_GATHER = 4 /**< Scatter/gather memory for PCI DMA */ + _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ + _DRM_CONSISTENT = 5 /**< Consistent memory for PCI DMA */ } drm_map_type_t; /** -- cgit v1.2.3