aboutsummaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorIan Romanick <idr@us.ibm.com>2007-08-09 15:30:36 -0700
committerIan Romanick <idr@us.ibm.com>2007-08-09 15:30:36 -0700
commitaea6b4dea9708f66f5fc2068fe84407682570aca (patch)
treed2a4e20c903edc89ddb8e49847be309f6451a224 /linux-core
parent25cb876f8513d02d4d189371eaa8b7b9a88e860d (diff)
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.
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/xgi_drv.c7
-rw-r--r--linux-core/xgi_drv.h14
-rw-r--r--linux-core/xgi_fb.c65
-rw-r--r--linux-core/xgi_pcie.c21
4 files changed, 49 insertions, 58 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