Unify alloc and free ioctls.
authorIan Romanick <idr@us.ibm.com>
Thu, 9 Aug 2007 22:30:36 +0000 (15:30 -0700)
committerIan Romanick <idr@us.ibm.com>
Thu, 9 Aug 2007 22:30:36 +0000 (15:30 -0700)
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
linux-core/xgi_drv.h
linux-core/xgi_fb.c
linux-core/xgi_pcie.c
shared-core/xgi_drm.h

index 9aaeb46..997051f 100644 (file)
@@ -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),
index 9c0f5a2..e56d00b 100644 (file)
@@ -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);
index 26e6fc4..d018283 100644 (file)
@@ -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);
 }
 
 /**
index 281223b..4ec9b6f 100644 (file)
@@ -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
index adce706..c980a35 100644 (file)
@@ -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)