From aea6b4dea9708f66f5fc2068fe84407682570aca Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 9 Aug 2007 15:30:36 -0700 Subject: Unify alloc and free ioctls. The DRM_XGI_PCIE_ALLOC and DRM_XGI_FB_ALLOC ioctls (and the matching free ioctls) are unified to DRM_XGI_ALLOC. The desired memory region is selected by xgi_mem_alloc::location. The region is magically encoded in xgi_mem_alloc::index, which is used to release the memory. Bump to version 0.11.0. This update requires a new DDX. --- linux-core/xgi_drv.c | 7 ++---- linux-core/xgi_drv.h | 14 +++++------ linux-core/xgi_fb.c | 65 ++++++++++++++++++++++++++++++++------------------- linux-core/xgi_pcie.c | 21 ----------------- shared-core/xgi_drm.h | 46 ++++++++++++++++++++++-------------- 5 files changed, 78 insertions(+), 75 deletions(-) diff --git a/linux-core/xgi_drv.c b/linux-core/xgi_drv.c index 9aaeb467..997051fb 100644 --- a/linux-core/xgi_drv.c +++ b/linux-core/xgi_drv.c @@ -42,11 +42,8 @@ static int xgi_bootstrap(struct drm_device *, void *, struct drm_file *); static struct drm_ioctl_desc xgi_ioctls[] = { DRM_IOCTL_DEF(DRM_XGI_BOOTSTRAP, xgi_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_XGI_FB_ALLOC, xgi_fb_alloc_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_XGI_FB_FREE, xgi_fb_free_ioctl, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_XGI_PCIE_ALLOC, xgi_pcie_alloc_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_XGI_PCIE_FREE, xgi_pcie_free_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_XGI_ALLOC, xgi_alloc_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_XGI_FREE, xgi_free_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_XGI_GE_RESET, xgi_ge_reset_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_XGI_DUMP_REGISTER, xgi_dump_register_ioctl, DRM_AUTH), diff --git a/linux-core/xgi_drv.h b/linux-core/xgi_drv.h index 9c0f5a28..e56d00bb 100644 --- a/linux-core/xgi_drv.h +++ b/linux-core/xgi_drv.h @@ -37,8 +37,8 @@ #define DRIVER_DATE "20070809" #define DRIVER_MAJOR 0 -#define DRIVER_MINOR 10 -#define DRIVER_PATCHLEVEL 6 +#define DRIVER_MINOR 11 +#define DRIVER_PATCHLEVEL 0 #include "xgi_cmdlist.h" #include "xgi_drm.h" @@ -89,6 +89,8 @@ struct xgi_info { }; extern struct kmem_cache *xgi_mem_block_cache; +extern int xgi_mem_free(struct xgi_mem_heap * heap, unsigned long offset, + struct drm_file * filp); extern int xgi_mem_heap_init(struct xgi_mem_heap * heap, unsigned int start, unsigned int end); extern void xgi_mem_heap_cleanup(struct xgi_mem_heap * heap); @@ -109,13 +111,9 @@ extern void *xgi_find_pcie_virt(struct xgi_info * info, u32 address); extern void xgi_free_all(struct xgi_info *, struct xgi_mem_heap *, struct drm_file *); -extern int xgi_fb_alloc_ioctl(struct drm_device * dev, void * data, - struct drm_file * filp); -extern int xgi_fb_free_ioctl(struct drm_device * dev, void * data, - struct drm_file * filp); -extern int xgi_pcie_alloc_ioctl(struct drm_device * dev, void * data, +extern int xgi_alloc_ioctl(struct drm_device * dev, void * data, struct drm_file * filp); -extern int xgi_pcie_free_ioctl(struct drm_device * dev, void * data, +extern int xgi_free_ioctl(struct drm_device * dev, void * data, struct drm_file * filp); extern int xgi_ge_reset_ioctl(struct drm_device * dev, void * data, struct drm_file * filp); diff --git a/linux-core/xgi_fb.c b/linux-core/xgi_fb.c index 26e6fc4e..d0182831 100644 --- a/linux-core/xgi_fb.c +++ b/linux-core/xgi_fb.c @@ -169,8 +169,8 @@ static struct xgi_mem_block *xgi_mem_alloc(struct xgi_mem_heap * heap, return (used_block); } -static int xgi_mem_free(struct xgi_mem_heap * heap, unsigned long offset, - struct drm_file * filp) +int xgi_mem_free(struct xgi_mem_heap * heap, unsigned long offset, + struct drm_file * filp) { struct xgi_mem_block *used_block = NULL, *block; struct xgi_mem_block *prev, *next; @@ -243,26 +243,45 @@ static int xgi_mem_free(struct xgi_mem_heap * heap, unsigned long offset, int xgi_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc, - struct drm_file * filp) + struct drm_file * filp) { struct xgi_mem_block *block; + struct xgi_mem_heap *heap; + const char *const mem_name = (alloc->location == XGI_MEMLOC_LOCAL) + ? "on-card" : "GART"; + + + if ((alloc->location != XGI_MEMLOC_LOCAL) + && (alloc->location != XGI_MEMLOC_NON_LOCAL)) { + DRM_ERROR("Invalid memory pool (0x%08x) specified.\n", + alloc->location); + return -EINVAL; + } + + heap = (alloc->location == XGI_MEMLOC_LOCAL) + ? &info->fb_heap : &info->pcie_heap; + + if (!heap->initialized) { + DRM_ERROR("Attempt to allocate from uninitialized memory " + "pool (0x%08x).\n", alloc->location); + return -EINVAL; + } mutex_lock(&info->dev->struct_mutex); - block = xgi_mem_alloc((alloc->location == XGI_MEMLOC_LOCAL) - ? &info->fb_heap : &info->pcie_heap, - alloc->size); + block = xgi_mem_alloc(heap, alloc->size); mutex_unlock(&info->dev->struct_mutex); if (block == NULL) { alloc->size = 0; - DRM_ERROR("Video RAM allocation failed\n"); + DRM_ERROR("%s memory allocation failed\n", mem_name); return -ENOMEM; } else { - DRM_INFO("Video RAM allocation succeeded: 0x%p\n", - (char *)block->offset); + DRM_DEBUG("%s memory allocation succeeded: 0x%p\n", + mem_name, (char *)block->offset); alloc->size = block->size; alloc->offset = block->offset; alloc->hw_addr = block->offset; + alloc->index = alloc->offset | alloc->location; if (alloc->location == XGI_MEMLOC_NON_LOCAL) { alloc->hw_addr += info->pcie.base; @@ -275,47 +294,45 @@ int xgi_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc, } -int xgi_fb_alloc_ioctl(struct drm_device * dev, void * data, - struct drm_file * filp) +int xgi_alloc_ioctl(struct drm_device * dev, void * data, + struct drm_file * filp) { - struct xgi_mem_alloc *alloc = - (struct xgi_mem_alloc *) data; struct xgi_info *info = dev->dev_private; - alloc->location = XGI_MEMLOC_LOCAL; - return xgi_alloc(info, alloc, filp); + return xgi_alloc(info, (struct xgi_mem_alloc *) data, filp); } int xgi_free(struct xgi_info * info, unsigned long index, struct drm_file * filp) { - int err = 0; - const unsigned heap = index & 0x03; + int err; + struct xgi_mem_heap *const heap = + ((index & 0x03) == XGI_MEMLOC_NON_LOCAL) + ? &info->pcie_heap : &info->fb_heap; + const u32 offset = (index & ~0x03); mutex_lock(&info->dev->struct_mutex); - err = xgi_mem_free((heap == XGI_MEMLOC_NON_LOCAL) - ? &info->pcie_heap : &info->fb_heap, - (index & ~0x03), filp); + err = xgi_mem_free(heap, offset, filp); mutex_unlock(&info->dev->struct_mutex); return err; } -int xgi_fb_free_ioctl(struct drm_device * dev, void * data, - struct drm_file * filp) +int xgi_free_ioctl(struct drm_device * dev, void * data, + struct drm_file * filp) { struct xgi_info *info = dev->dev_private; - return xgi_free(info, XGI_MEMLOC_LOCAL | *(u32 *) data, filp); + return xgi_free(info, *(unsigned long *) data, filp); } int xgi_fb_heap_init(struct xgi_info * info) { return xgi_mem_heap_init(&info->fb_heap, XGI_FB_HEAP_START, - info->fb.size); + info->fb.size - XGI_FB_HEAP_START); } /** diff --git a/linux-core/xgi_pcie.c b/linux-core/xgi_pcie.c index 281223b3..4ec9b6ff 100644 --- a/linux-core/xgi_pcie.c +++ b/linux-core/xgi_pcie.c @@ -140,27 +140,6 @@ int xgi_pcie_heap_init(struct xgi_info * info) } -int xgi_pcie_alloc_ioctl(struct drm_device * dev, void * data, - struct drm_file * filp) -{ - struct xgi_mem_alloc *const alloc = - (struct xgi_mem_alloc *) data; - struct xgi_info *info = dev->dev_private; - - alloc->location = XGI_MEMLOC_NON_LOCAL; - return xgi_alloc(info, alloc, filp); -} - - -int xgi_pcie_free_ioctl(struct drm_device * dev, void * data, - struct drm_file * filp) -{ - struct xgi_info *info = dev->dev_private; - - return xgi_free(info, XGI_MEMLOC_NON_LOCAL | *(u32 *) data, filp); -} - - /** * xgi_find_pcie_virt * @address: GE HW address diff --git a/shared-core/xgi_drm.h b/shared-core/xgi_drm.h index adce7066..c980a35a 100644 --- a/shared-core/xgi_drm.h +++ b/shared-core/xgi_drm.h @@ -60,10 +60,20 @@ enum xgi_mem_location { }; struct xgi_mem_alloc { + /** + * Memory region to be used for allocation. + * + * Must be one of XGI_MEMLOC_NON_LOCAL or XGI_MEMLOC_LOCAL. + */ unsigned int location; + + /** + * Number of bytes request. + * + * On successful allocation, set to the actual number of bytes + * allocated. + */ unsigned int size; - unsigned int is_front; - unsigned int owner; /** * Address of the memory from the graphics hardware's point of view. @@ -74,6 +84,13 @@ struct xgi_mem_alloc { * Offset of the allocation in the mapping. */ __u32 offset; + + /** + * Magic handle used to release memory. + * + * See also DRM_XGI_FREE ioctl. + */ + unsigned long index; }; enum xgi_batch_type { @@ -102,24 +119,19 @@ struct xgi_state_info { */ #define DRM_XGI_BOOTSTRAP 0 -#define DRM_XGI_FB_ALLOC 1 -#define DRM_XGI_FB_FREE 2 -#define DRM_XGI_PCIE_ALLOC 3 -#define DRM_XGI_PCIE_FREE 4 -#define DRM_XGI_SUBMIT_CMDLIST 5 -#define DRM_XGI_GE_RESET 6 -#define DRM_XGI_DUMP_REGISTER 7 -#define DRM_XGI_DEBUG_INFO 8 -#define DRM_XGI_TEST_RWINKERNEL 9 -#define DRM_XGI_STATE_CHANGE 10 +#define DRM_XGI_ALLOC 1 +#define DRM_XGI_FREE 2 +#define DRM_XGI_SUBMIT_CMDLIST 3 +#define DRM_XGI_GE_RESET 4 +#define DRM_XGI_DUMP_REGISTER 5 +#define DRM_XGI_DEBUG_INFO 6 +#define DRM_XGI_TEST_RWINKERNEL 7 +#define DRM_XGI_STATE_CHANGE 8 #define XGI_IOCTL_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_BOOTSTRAP, struct xgi_bootstrap) -#define XGI_IOCTL_FB_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_FB_ALLOC, struct xgi_mem_alloc) -#define XGI_IOCTL_FB_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_FB_FREE, __u32) - -#define XGI_IOCTL_PCIE_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_PCIE_ALLOC, struct xgi_mem_alloc) -#define XGI_IOCTL_PCIE_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_PCIE_FREE, __u32) +#define XGI_IOCTL_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_ALLOC, struct xgi_mem_alloc) +#define XGI_IOCTL_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_FREE, __u32) #define XGI_IOCTL_GE_RESET DRM_IO(DRM_COMMAND_BASE + DRM_XGI_GE_RESET) #define XGI_IOCTL_DUMP_REGISTER DRM_IO(DRM_COMMAND_BASE + DRM_XGI_DUMP_REGISTER) -- cgit v1.2.3