int xgi_cmdlist_initialize(struct xgi_info * info, size_t size)
{
struct xgi_mem_alloc mem_alloc = {
+ .location = XGI_MEMLOC_NON_LOCAL,
.size = size,
};
int err;
- err = xgi_pcie_alloc(info, &mem_alloc, 0);
+ err = xgi_alloc(info, &mem_alloc, 0);
if (err) {
return err;
}
#define DRIVER_MAJOR 0
#define DRIVER_MINOR 10
-#define DRIVER_PATCHLEVEL 2
+#define DRIVER_PATCHLEVEL 3
#include "xgi_cmdlist.h"
#include "xgi_drm.h"
};
extern struct kmem_cache *xgi_mem_block_cache;
-extern struct xgi_mem_block *xgi_mem_alloc(struct xgi_mem_heap * heap,
- unsigned long size);
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,
extern int xgi_fb_heap_init(struct xgi_info * info);
-extern int xgi_fb_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
+extern int xgi_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
struct drm_file * filp);
extern int xgi_fb_free(struct xgi_info * info, unsigned long offset,
extern int xgi_pcie_heap_init(struct xgi_info * info);
extern void xgi_pcie_lut_cleanup(struct xgi_info * info);
-extern int xgi_pcie_alloc(struct xgi_info * info,
- struct xgi_mem_alloc * alloc, struct drm_file * filp);
-
extern int xgi_pcie_free(struct xgi_info * info, unsigned long offset,
struct drm_file * filp);
}
-struct xgi_mem_block *xgi_mem_alloc(struct xgi_mem_heap * heap,
- unsigned long originalSize)
+static struct xgi_mem_block *xgi_mem_alloc(struct xgi_mem_heap * heap,
+ unsigned long originalSize)
{
struct xgi_mem_block *block, *free_block, *used_block;
unsigned long size = (originalSize + PAGE_SIZE - 1) & PAGE_MASK;
}
-int xgi_fb_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
+int xgi_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
struct drm_file * filp)
{
struct xgi_mem_block *block;
down(&info->fb_sem);
- block = xgi_mem_alloc(&info->fb_heap, alloc->size);
+ block = xgi_mem_alloc((alloc->location == XGI_MEMLOC_LOCAL)
+ ? &info->fb_heap : &info->pcie_heap,
+ alloc->size);
up(&info->fb_sem);
if (block == NULL) {
} else {
DRM_INFO("Video RAM allocation succeeded: 0x%p\n",
(char *)block->offset);
- alloc->location = XGI_MEMLOC_LOCAL;
alloc->size = block->size;
alloc->offset = block->offset;
alloc->hw_addr = block->offset;
+ if (alloc->location == XGI_MEMLOC_NON_LOCAL) {
+ alloc->hw_addr += info->pcie.base;
+ }
+
block->filp = filp;
}
(struct xgi_mem_alloc *) data;
struct xgi_info *info = dev->dev_private;
- return xgi_fb_alloc(info, alloc, filp);
+ alloc->location = XGI_MEMLOC_LOCAL;
+ return xgi_alloc(info, alloc, filp);
}
}
-int xgi_pcie_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
- struct drm_file * filp)
-{
- struct xgi_mem_block *block;
-
- down(&info->pcie_sem);
- block = xgi_mem_alloc(&info->pcie_heap, alloc->size);
- up(&info->pcie_sem);
-
- if (block == NULL) {
- alloc->location = XGI_MEMLOC_INVALID;
- alloc->size = 0;
- DRM_ERROR("PCIE RAM allocation failed\n");
- return -ENOMEM;
- } else {
- DRM_INFO("PCIE RAM allocation succeeded: offset = 0x%lx\n",
- block->offset);
- alloc->location = XGI_MEMLOC_NON_LOCAL;
- alloc->size = block->size;
- alloc->hw_addr = block->offset + info->pcie.base;
- alloc->offset = block->offset;
-
- block->filp = filp;
- return 0;
- }
-}
-
-
int xgi_pcie_alloc_ioctl(struct drm_device * dev, void * data,
struct drm_file * filp)
{
(struct xgi_mem_alloc *) data;
struct xgi_info *info = dev->dev_private;
- return xgi_pcie_alloc(info, alloc, filp);
+ alloc->location = XGI_MEMLOC_NON_LOCAL;
+ return xgi_alloc(info, alloc, filp);
}