mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-07 22:48:30 +02:00
Add drm_stub.h support This allows proper handling of /proc entries when
multiple drivers are loaded. This also paves the way for a fixed MAJOR
number and the eventual deprecation of /proc dependencies.
This commit is contained in:
parent
6fc31e043a
commit
95bb76c7de
12 changed files with 691 additions and 427 deletions
|
|
@ -135,6 +135,7 @@
|
|||
#define DRM_MEM_TOTALAGP 16
|
||||
#define DRM_MEM_BOUNDAGP 17
|
||||
#define DRM_MEM_CTXBITMAP 18
|
||||
#define DRM_MEM_STUB 19
|
||||
|
||||
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
|
||||
|
||||
|
|
@ -285,7 +286,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||
printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg)
|
||||
#define DRM_MEM_ERROR(area, fmt, arg...) \
|
||||
printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ ":%s] *ERROR* " fmt , \
|
||||
drm_mem_stats[area].name , ##arg)
|
||||
DRM(mem_stats)[area].name , ##arg)
|
||||
#define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
|
||||
|
||||
#if DRM_DEBUG_CODE
|
||||
|
|
@ -689,8 +690,13 @@ extern int DRM(mmap)(struct file *filp, struct vm_area_struct *vma);
|
|||
|
||||
|
||||
/* Proc support (proc.c) */
|
||||
extern int DRM(proc_init)(drm_device_t *dev);
|
||||
extern int DRM(proc_cleanup)(void);
|
||||
extern struct proc_dir_entry *drm_proc_init(drm_device_t *dev,
|
||||
int minor,
|
||||
struct proc_dir_entry *root,
|
||||
struct proc_dir_entry **dev_root);
|
||||
extern int drm_proc_cleanup(int minor,
|
||||
struct proc_dir_entry *root,
|
||||
struct proc_dir_entry *dev_root);
|
||||
|
||||
/* Memory management support (memory.c) */
|
||||
extern void DRM(mem_init)(void);
|
||||
|
|
@ -864,6 +870,13 @@ extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type);
|
|||
extern int DRM(agp_free_memory)(agp_memory *handle);
|
||||
extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start);
|
||||
extern int DRM(agp_unbind_memory)(agp_memory *handle);
|
||||
|
||||
/* Stub support (drm_stub.h) */
|
||||
int DRM(stub_register)(const char *name,
|
||||
struct file_operations *fops,
|
||||
drm_device_t *dev);
|
||||
int DRM(stub_unregister)(int minor);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@
|
|||
|
||||
|
||||
static drm_device_t DRM(device);
|
||||
static int DRM(minor);
|
||||
|
||||
static struct file_operations DRM(fops) = {
|
||||
#if LINUX_VERSION_CODE >= 0x020400
|
||||
|
|
@ -107,12 +108,6 @@ static struct file_operations DRM(fops) = {
|
|||
poll: DRM(poll),
|
||||
};
|
||||
|
||||
static struct miscdevice DRM(misc) = {
|
||||
minor: MISC_DYNAMIC_MINOR,
|
||||
name: DRIVER_NAME,
|
||||
fops: &DRM(fops),
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
static char *drm_opts = NULL;
|
||||
#endif
|
||||
|
|
@ -367,24 +362,19 @@ static int __init drm_init( void )
|
|||
#endif
|
||||
DRIVER_PREINIT();
|
||||
|
||||
retcode = misc_register( &DRM(misc) );
|
||||
if ( retcode ) {
|
||||
DRM_ERROR( "Cannot register \"%s\"\n", DRIVER_NAME );
|
||||
return retcode;
|
||||
}
|
||||
dev->device = MKDEV( MISC_MAJOR, DRM(misc).minor );
|
||||
dev->name = DRIVER_NAME;
|
||||
|
||||
DRM(mem_init)();
|
||||
DRM(proc_init)( dev );
|
||||
|
||||
if ((DRM(minor) = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
|
||||
return -EPERM;
|
||||
dev->device = MKDEV(DRM_MAJOR, DRM(minor) );
|
||||
dev->name = DRIVER_NAME;
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
dev->agp = DRM(agp_init)();
|
||||
#if __MUST_HAVE_AGP
|
||||
if ( dev->agp == NULL ) {
|
||||
DRM_ERROR( "Cannot initialize the agpgart module.\n" );
|
||||
DRM(proc_cleanup)();
|
||||
misc_deregister( &DRM(misc) );
|
||||
DRM(stub_unregister)(DRM(minor));
|
||||
DRM(takedown)( dev );
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -401,8 +391,7 @@ static int __init drm_init( void )
|
|||
retcode = DRM(ctxbitmap_init)( dev );
|
||||
if( retcode ) {
|
||||
DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
|
||||
DRM(proc_cleanup)();
|
||||
misc_deregister( &DRM(misc) );
|
||||
DRM(stub_unregister)(DRM(minor));
|
||||
DRM(takedown)( dev );
|
||||
return retcode;
|
||||
}
|
||||
|
|
@ -416,7 +405,7 @@ static int __init drm_init( void )
|
|||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
DRM(misc).minor );
|
||||
DRM(minor) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -429,8 +418,7 @@ static void __exit drm_cleanup( void )
|
|||
|
||||
DRM_DEBUG( "\n" );
|
||||
|
||||
DRM(proc_cleanup)();
|
||||
if ( misc_deregister( &DRM(misc) ) ) {
|
||||
if ( DRM(stub_unregister)(DRM(minor)) ) {
|
||||
DRM_ERROR( "Cannot unload module\n" );
|
||||
} else {
|
||||
DRM_INFO( "Module unloaded\n" );
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ typedef struct drm_mem_stats {
|
|||
unsigned long bytes_freed;
|
||||
} drm_mem_stats_t;
|
||||
|
||||
static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED;
|
||||
static unsigned long drm_ram_available = 0; /* In pages */
|
||||
static unsigned long drm_ram_used = 0;
|
||||
static drm_mem_stats_t drm_mem_stats[] = {
|
||||
static spinlock_t DRM(mem_lock) = SPIN_LOCK_UNLOCKED;
|
||||
static unsigned long DRM(ram_available) = 0; /* In pages */
|
||||
static unsigned long DRM(ram_used) = 0;
|
||||
static drm_mem_stats_t DRM(mem_stats)[] = {
|
||||
[DRM_MEM_DMA] = { "dmabufs" },
|
||||
[DRM_MEM_SAREA] = { "sareas" },
|
||||
[DRM_MEM_DRIVER] = { "driver" },
|
||||
|
|
@ -66,6 +66,7 @@ static drm_mem_stats_t drm_mem_stats[] = {
|
|||
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
||||
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
||||
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
||||
[DRM_MEM_STUB] = { "stub" },
|
||||
{ NULL, 0, } /* Last entry must be null */
|
||||
};
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ void DRM(mem_init)(void)
|
|||
drm_mem_stats_t *mem;
|
||||
struct sysinfo si;
|
||||
|
||||
for (mem = drm_mem_stats; mem->name; ++mem) {
|
||||
for (mem = DRM(mem_stats); mem->name; ++mem) {
|
||||
mem->succeed_count = 0;
|
||||
mem->free_count = 0;
|
||||
mem->fail_count = 0;
|
||||
|
|
@ -85,17 +86,17 @@ void DRM(mem_init)(void)
|
|||
si_meminfo(&si);
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
/* Changed to page count in 2.3.23 */
|
||||
drm_ram_available = si.totalram >> PAGE_SHIFT;
|
||||
DRM(ram_available) = si.totalram >> PAGE_SHIFT;
|
||||
#else
|
||||
drm_ram_available = si.totalram;
|
||||
DRM(ram_available) = si.totalram;
|
||||
#endif
|
||||
drm_ram_used = 0;
|
||||
DRM(ram_used) = 0;
|
||||
}
|
||||
|
||||
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
|
||||
|
||||
static int _drm_mem_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data)
|
||||
static int DRM(_mem_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data)
|
||||
{
|
||||
drm_mem_stats_t *pt;
|
||||
|
||||
|
|
@ -108,11 +109,11 @@ static int _drm_mem_info(char *buf, char **start, off_t offset,
|
|||
" | allocs bytes\n\n");
|
||||
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
|
||||
"system", 0, 0, 0,
|
||||
drm_ram_available << (PAGE_SHIFT - 10));
|
||||
DRM(ram_available) << (PAGE_SHIFT - 10));
|
||||
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
|
||||
"locked", 0, 0, 0, drm_ram_used >> 10);
|
||||
"locked", 0, 0, 0, DRM(ram_used) >> 10);
|
||||
DRM_PROC_PRINT("\n");
|
||||
for (pt = drm_mem_stats; pt->name; pt++) {
|
||||
for (pt = DRM(mem_stats); pt->name; pt++) {
|
||||
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
|
||||
pt->name,
|
||||
pt->succeed_count,
|
||||
|
|
@ -133,9 +134,9 @@ int DRM(mem_info)(char *buf, char **start, off_t offset,
|
|||
{
|
||||
int ret;
|
||||
|
||||
spin_lock(&drm_mem_lock);
|
||||
ret = _drm_mem_info(buf, start, offset, len, eof, data);
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
ret = DRM(_mem_info)(buf, start, offset, len, eof, data);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -149,15 +150,15 @@ void *DRM(alloc)(size_t size, int area)
|
|||
}
|
||||
|
||||
if (!(pt = kmalloc(size, GFP_KERNEL))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[area].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[area].fail_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return NULL;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[area].succeed_count;
|
||||
drm_mem_stats[area].bytes_allocated += size;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[area].succeed_count;
|
||||
DRM(mem_stats)[area].bytes_allocated += size;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
|
@ -200,11 +201,11 @@ void DRM(free)(void *pt, size_t size, int area)
|
|||
|
||||
if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
|
||||
else kfree(pt);
|
||||
spin_lock(&drm_mem_lock);
|
||||
drm_mem_stats[area].bytes_freed += size;
|
||||
free_count = ++drm_mem_stats[area].free_count;
|
||||
alloc_count = drm_mem_stats[area].succeed_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
DRM(mem_stats)[area].bytes_freed += size;
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
|
||||
free_count, alloc_count);
|
||||
|
|
@ -218,26 +219,26 @@ unsigned long DRM(alloc_pages)(int order, int area)
|
|||
unsigned long addr;
|
||||
unsigned int sz;
|
||||
|
||||
spin_lock(&drm_mem_lock);
|
||||
if ((drm_ram_used >> PAGE_SHIFT)
|
||||
> (DRM_RAM_PERCENT * drm_ram_available) / 100) {
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
if ((DRM(ram_used) >> PAGE_SHIFT)
|
||||
> (DRM_RAM_PERCENT * DRM(ram_available)) / 100) {
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return 0;
|
||||
}
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
|
||||
address = __get_free_pages(GFP_KERNEL, order);
|
||||
if (!address) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[area].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[area].fail_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return 0;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[area].succeed_count;
|
||||
drm_mem_stats[area].bytes_allocated += bytes;
|
||||
drm_ram_used += bytes;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[area].succeed_count;
|
||||
DRM(mem_stats)[area].bytes_allocated += bytes;
|
||||
DRM(ram_used) += bytes;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
|
||||
|
||||
/* Zero outside the lock */
|
||||
|
|
@ -283,12 +284,12 @@ void DRM(free_pages)(unsigned long address, int order, int area)
|
|||
free_pages(address, order);
|
||||
}
|
||||
|
||||
spin_lock(&drm_mem_lock);
|
||||
free_count = ++drm_mem_stats[area].free_count;
|
||||
alloc_count = drm_mem_stats[area].succeed_count;
|
||||
drm_mem_stats[area].bytes_freed += bytes;
|
||||
drm_ram_used -= bytes;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
DRM(mem_stats)[area].bytes_freed += bytes;
|
||||
DRM(ram_used) -= bytes;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(area,
|
||||
"Excess frees: %d frees, %d allocs\n",
|
||||
|
|
@ -307,15 +308,15 @@ void *DRM(ioremap)(unsigned long offset, unsigned long size)
|
|||
}
|
||||
|
||||
if (!(pt = ioremap(offset, size))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return NULL;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
|
@ -330,11 +331,11 @@ void DRM(ioremapfree)(void *pt, unsigned long size)
|
|||
else
|
||||
iounmap(pt);
|
||||
|
||||
spin_lock(&drm_mem_lock);
|
||||
drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size;
|
||||
free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count;
|
||||
alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||
"Excess frees: %d frees, %d allocs\n",
|
||||
|
|
@ -354,16 +355,16 @@ agp_memory *DRM(alloc_agp)(int pages, u32 type)
|
|||
}
|
||||
|
||||
if ((handle = DRM(agp_allocate_memory)(pages, type))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
|
||||
+= pages << PAGE_SHIFT;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return handle;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -380,12 +381,12 @@ int DRM(free_agp)(agp_memory *handle, int pages)
|
|||
}
|
||||
|
||||
if (DRM(agp_free_memory)(handle)) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count;
|
||||
alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
|
||||
+= pages << PAGE_SHIFT;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
|
||||
"Excess frees: %d frees, %d allocs\n",
|
||||
|
|
@ -407,16 +408,16 @@ int DRM(bind_agp)(agp_memory *handle, unsigned int start)
|
|||
}
|
||||
|
||||
if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return retcode;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
|
@ -433,12 +434,12 @@ int DRM(unbind_agp)(agp_memory *handle)
|
|||
}
|
||||
|
||||
if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode;
|
||||
spin_lock(&drm_mem_lock);
|
||||
free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count;
|
||||
alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
|
||||
"Excess frees: %d frees, %d allocs\n",
|
||||
|
|
|
|||
|
|
@ -32,118 +32,105 @@
|
|||
#define __NO_VERSION__
|
||||
#include "drmP.h"
|
||||
|
||||
static struct proc_dir_entry *drm_root = NULL;
|
||||
static struct proc_dir_entry *drm_dev_root = NULL;
|
||||
static char drm_slot_name[64];
|
||||
|
||||
static int drm_name_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int drm_vm_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int drm_clients_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int drm_queues_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int drm_bufs_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
#if DRM_DEBUG_CODE
|
||||
static int drm_vma_info(char *buf, char **start, off_t offset,
|
||||
static int DRM(name_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int DRM(vm_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int DRM(clients_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int DRM(queues_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int DRM(bufs_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
#if DRM_DEBUG_CODE
|
||||
static int DRM(vma_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
#endif
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
static int drm_histo_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int DRM(histo_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
#endif
|
||||
|
||||
struct drm_proc_list {
|
||||
const char *name;
|
||||
int (*f)(char *, char **, off_t, int, int *, void *);
|
||||
} drm_proc_list[] = {
|
||||
{ "name", drm_name_info },
|
||||
{ "mem", DRM(mem_info) },
|
||||
{ "vm", drm_vm_info },
|
||||
{ "clients", drm_clients_info },
|
||||
{ "queues", drm_queues_info },
|
||||
{ "bufs", drm_bufs_info },
|
||||
} DRM(proc_list)[] = {
|
||||
{ "name", DRM(name_info) },
|
||||
{ "mem", DRM(mem_info) },
|
||||
{ "vm", DRM(vm_info) },
|
||||
{ "clients", DRM(clients_info) },
|
||||
{ "queues", DRM(queues_info) },
|
||||
{ "bufs", DRM(bufs_info) },
|
||||
#if DRM_DEBUG_CODE
|
||||
{ "vma", drm_vma_info },
|
||||
{ "vma", DRM(vma_info) },
|
||||
#endif
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
{ "histo", drm_histo_info },
|
||||
{ "histo", DRM(histo_info) },
|
||||
#endif
|
||||
};
|
||||
#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
|
||||
#define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0]))
|
||||
|
||||
int DRM(proc_init)(drm_device_t *dev)
|
||||
struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
|
||||
struct proc_dir_entry *root,
|
||||
struct proc_dir_entry **dev_root)
|
||||
{
|
||||
struct proc_dir_entry *ent;
|
||||
int i, j;
|
||||
char name[64];
|
||||
|
||||
drm_root = create_proc_entry("dri", S_IFDIR, NULL);
|
||||
if (!drm_root) {
|
||||
if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL);
|
||||
if (!root) {
|
||||
DRM_ERROR("Cannot create /proc/dri\n");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Instead of doing this search, we should
|
||||
add some global support for /proc/dri. */
|
||||
for (i = 0; i < 8; i++) {
|
||||
sprintf(drm_slot_name, "dri/%d", i);
|
||||
drm_dev_root = create_proc_entry(drm_slot_name, S_IFDIR, NULL);
|
||||
if (!drm_dev_root) {
|
||||
DRM_ERROR("Cannot create /proc/%s\n", drm_slot_name);
|
||||
remove_proc_entry("dri", NULL);
|
||||
}
|
||||
if (drm_dev_root->nlink == 2) break;
|
||||
drm_dev_root = NULL;
|
||||
}
|
||||
if (!drm_dev_root) {
|
||||
DRM_ERROR("Cannot find slot in /proc/dri\n");
|
||||
return -1;
|
||||
sprintf(name, "%d", minor);
|
||||
*dev_root = create_proc_entry(name, S_IFDIR, root);
|
||||
if (!*dev_root) {
|
||||
DRM_ERROR("Cannot create /proc/%s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < DRM_PROC_ENTRIES; i++) {
|
||||
ent = create_proc_entry(drm_proc_list[i].name,
|
||||
S_IFREG|S_IRUGO, drm_dev_root);
|
||||
ent = create_proc_entry(DRM(proc_list)[i].name,
|
||||
S_IFREG|S_IRUGO, *dev_root);
|
||||
if (!ent) {
|
||||
DRM_ERROR("Cannot create /proc/%s/%s\n",
|
||||
drm_slot_name, drm_proc_list[i].name);
|
||||
DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
|
||||
name, DRM(proc_list)[i].name);
|
||||
for (j = 0; j < i; j++)
|
||||
remove_proc_entry(drm_proc_list[i].name,
|
||||
drm_dev_root);
|
||||
remove_proc_entry(drm_slot_name, NULL);
|
||||
remove_proc_entry("dri", NULL);
|
||||
return -1;
|
||||
remove_proc_entry(DRM(proc_list)[i].name,
|
||||
*dev_root);
|
||||
remove_proc_entry(name, root);
|
||||
if (!minor) remove_proc_entry("dri", NULL);
|
||||
return NULL;
|
||||
}
|
||||
ent->read_proc = drm_proc_list[i].f;
|
||||
ent->read_proc = DRM(proc_list)[i].f;
|
||||
ent->data = dev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
int DRM(proc_cleanup)(void)
|
||||
int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
|
||||
struct proc_dir_entry *dev_root)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
char name[64];
|
||||
|
||||
if (!root || !dev_root) return 0;
|
||||
|
||||
for (i = 0; i < DRM_PROC_ENTRIES; i++)
|
||||
remove_proc_entry(DRM(proc_list)[i].name, dev_root);
|
||||
sprintf(name, "%d", minor);
|
||||
remove_proc_entry(name, root);
|
||||
if (!minor) remove_proc_entry("dri", NULL);
|
||||
|
||||
if (drm_root) {
|
||||
if (drm_dev_root) {
|
||||
for (i = 0; i < DRM_PROC_ENTRIES; i++) {
|
||||
remove_proc_entry(drm_proc_list[i].name,
|
||||
drm_dev_root);
|
||||
}
|
||||
remove_proc_entry(drm_slot_name, NULL);
|
||||
}
|
||||
remove_proc_entry("dri", NULL);
|
||||
remove_proc_entry(DRM_NAME, NULL);
|
||||
}
|
||||
drm_root = drm_dev_root = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_name_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(name_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
|
||||
|
|
@ -160,8 +147,8 @@ static int drm_name_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_vm_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_map_t *map;
|
||||
|
|
@ -198,21 +185,21 @@ static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_vm_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(vm_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_vm_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_vm_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int _drm_queues_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_queues_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int i;
|
||||
|
|
@ -250,23 +237,23 @@ static int _drm_queues_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_queues_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(queues_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_queues_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_queues_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* drm_bufs_info is called whenever a process reads
|
||||
/dev/drm/<dev>/bufs. */
|
||||
/dev/dri/<dev>/bufs. */
|
||||
|
||||
static int _drm_bufs_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
|
@ -302,21 +289,21 @@ static int _drm_bufs_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_bufs_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(bufs_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_bufs_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_bufs_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int _drm_clients_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_clients_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_file_t *priv;
|
||||
|
|
@ -338,14 +325,14 @@ static int _drm_clients_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_clients_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(clients_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_clients_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_clients_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -354,8 +341,8 @@ static int drm_clients_info(char *buf, char **start, off_t offset, int len,
|
|||
|
||||
#define DRM_VMA_VERBOSE 0
|
||||
|
||||
static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_vma_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_vma_entry_t *pt;
|
||||
|
|
@ -432,14 +419,14 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_vma_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(vma_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_vma_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_vma_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -447,8 +434,8 @@ static int drm_vma_info(char *buf, char **start, off_t offset, int len,
|
|||
|
||||
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_histo_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
|
@ -564,14 +551,14 @@ static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_histo_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(histo_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_histo_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_histo_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
142
linux-core/drm_stub.c
Normal file
142
linux-core/drm_stub.c
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* drm_stub.c -- -*- linux-c -*-
|
||||
* Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
|
||||
*
|
||||
* Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#define DRM_STUB_MAXCARDS 16 /* Enough for one machine */
|
||||
|
||||
static struct drm_stub_list {
|
||||
const char *name;
|
||||
struct file_operations *fops;
|
||||
struct proc_dir_entry *dev_root;
|
||||
} *DRM(stub_list);
|
||||
|
||||
static struct proc_dir_entry *DRM(stub_root);
|
||||
|
||||
static struct drm_stub_info {
|
||||
int (*info_register)(const char *name, struct file_operations *fops,
|
||||
drm_device_t *dev);
|
||||
int (*info_unregister)(int minor);
|
||||
} DRM(stub_info);
|
||||
|
||||
static int DRM(stub_open)(struct inode *inode, struct file *filp)
|
||||
{
|
||||
int minor = MINOR(inode->i_rdev);
|
||||
int err = -ENODEV;
|
||||
struct file_operations *old_fops;
|
||||
|
||||
if (!DRM(stub_list) || !DRM(stub_list)[minor].fops) return -ENODEV;
|
||||
old_fops = filp->f_op;
|
||||
filp->f_op = fops_get(DRM(stub_list)[minor].fops);
|
||||
if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
|
||||
fops_put(filp->f_op);
|
||||
filp->f_op = fops_get(old_fops);
|
||||
}
|
||||
fops_put(old_fops);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct file_operations DRM(stub_fops) = {
|
||||
#if LINUX_VERSION_CODE >= 0x020400
|
||||
owner: THIS_MODULE,
|
||||
#endif
|
||||
open: DRM(stub_open)
|
||||
};
|
||||
|
||||
static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
|
||||
drm_device_t *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!DRM(stub_list)) {
|
||||
DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list))
|
||||
* DRM_STUB_MAXCARDS, DRM_MEM_STUB);
|
||||
for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
|
||||
DRM(stub_list)[i].name = NULL;
|
||||
DRM(stub_list)[i].fops = NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
|
||||
if (!DRM(stub_list)[i].fops) {
|
||||
DRM(stub_list)[i].name = name;
|
||||
DRM(stub_list)[i].fops = fops;
|
||||
DRM(stub_root) = DRM(proc_init)(dev, i, DRM(stub_root),
|
||||
&DRM(stub_list)[i]
|
||||
.dev_root);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int DRM(stub_putminor)(int minor)
|
||||
{
|
||||
if (minor < 0 || minor >= DRM_STUB_MAXCARDS) return -1;
|
||||
DRM(stub_list)[minor].name = NULL;
|
||||
DRM(stub_list)[minor].fops = NULL;
|
||||
DRM(proc_cleanup)(minor, DRM(stub_root),
|
||||
DRM(stub_list)[minor].dev_root);
|
||||
if (minor) {
|
||||
inter_module_put("drm");
|
||||
} else {
|
||||
inter_module_unregister("drm");
|
||||
DRM(free)(DRM(stub_list),
|
||||
sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS,
|
||||
DRM_MEM_STUB);
|
||||
unregister_chrdev(DRM_MAJOR, "drm");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DRM(stub_register)(const char *name, struct file_operations *fops,
|
||||
drm_device_t *dev)
|
||||
{
|
||||
if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) {
|
||||
/* Already registered */
|
||||
struct drm_stub_info *i;
|
||||
i = (struct drm_stub_info *)inter_module_get("drm");
|
||||
DRM(stub_info).info_register = i->info_register;
|
||||
DRM(stub_info).info_unregister = i->info_unregister;
|
||||
} else {
|
||||
DRM(stub_info).info_register = DRM(stub_getminor);
|
||||
DRM(stub_info).info_unregister = DRM(stub_putminor);
|
||||
inter_module_register("drm", THIS_MODULE, &DRM(stub_info));
|
||||
}
|
||||
if (DRM(stub_info).info_register)
|
||||
return DRM(stub_info).info_register(name, fops, dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DRM(stub_unregister)(int minor)
|
||||
{
|
||||
DRM_DEBUG("%d\n", minor);
|
||||
if (DRM(stub_info).info_unregister)
|
||||
return DRM(stub_info).info_unregister(minor);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ LIBS=
|
|||
DRMOBS=
|
||||
DRMTEMPLATES= drm_init.h drm_memory.h drm_proc.h drm_auth.h drm_context.h \
|
||||
drm_drawable.h drm_bufs.h drm_lists.h drm_lock.h drm_ioctl.h \
|
||||
drm_fops.h drm_vm.h drm_dma.h
|
||||
drm_fops.h drm_vm.h drm_dma.h drm_stub.h
|
||||
DRMHEADERS= drm.h drmP.h compat-pre24.h
|
||||
|
||||
GAMMAOBJS= gamma_drv.o gamma_dma.o
|
||||
|
|
|
|||
19
linux/drmP.h
19
linux/drmP.h
|
|
@ -135,6 +135,7 @@
|
|||
#define DRM_MEM_TOTALAGP 16
|
||||
#define DRM_MEM_BOUNDAGP 17
|
||||
#define DRM_MEM_CTXBITMAP 18
|
||||
#define DRM_MEM_STUB 19
|
||||
|
||||
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
|
||||
|
||||
|
|
@ -285,7 +286,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||
printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg)
|
||||
#define DRM_MEM_ERROR(area, fmt, arg...) \
|
||||
printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ ":%s] *ERROR* " fmt , \
|
||||
drm_mem_stats[area].name , ##arg)
|
||||
DRM(mem_stats)[area].name , ##arg)
|
||||
#define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
|
||||
|
||||
#if DRM_DEBUG_CODE
|
||||
|
|
@ -689,8 +690,13 @@ extern int DRM(mmap)(struct file *filp, struct vm_area_struct *vma);
|
|||
|
||||
|
||||
/* Proc support (proc.c) */
|
||||
extern int DRM(proc_init)(drm_device_t *dev);
|
||||
extern int DRM(proc_cleanup)(void);
|
||||
extern struct proc_dir_entry *drm_proc_init(drm_device_t *dev,
|
||||
int minor,
|
||||
struct proc_dir_entry *root,
|
||||
struct proc_dir_entry **dev_root);
|
||||
extern int drm_proc_cleanup(int minor,
|
||||
struct proc_dir_entry *root,
|
||||
struct proc_dir_entry *dev_root);
|
||||
|
||||
/* Memory management support (memory.c) */
|
||||
extern void DRM(mem_init)(void);
|
||||
|
|
@ -864,6 +870,13 @@ extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type);
|
|||
extern int DRM(agp_free_memory)(agp_memory *handle);
|
||||
extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start);
|
||||
extern int DRM(agp_unbind_memory)(agp_memory *handle);
|
||||
|
||||
/* Stub support (drm_stub.h) */
|
||||
int DRM(stub_register)(const char *name,
|
||||
struct file_operations *fops,
|
||||
drm_device_t *dev);
|
||||
int DRM(stub_unregister)(int minor);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@
|
|||
|
||||
|
||||
static drm_device_t DRM(device);
|
||||
static int DRM(minor);
|
||||
|
||||
static struct file_operations DRM(fops) = {
|
||||
#if LINUX_VERSION_CODE >= 0x020400
|
||||
|
|
@ -107,12 +108,6 @@ static struct file_operations DRM(fops) = {
|
|||
poll: DRM(poll),
|
||||
};
|
||||
|
||||
static struct miscdevice DRM(misc) = {
|
||||
minor: MISC_DYNAMIC_MINOR,
|
||||
name: DRIVER_NAME,
|
||||
fops: &DRM(fops),
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
static char *drm_opts = NULL;
|
||||
#endif
|
||||
|
|
@ -367,24 +362,19 @@ static int __init drm_init( void )
|
|||
#endif
|
||||
DRIVER_PREINIT();
|
||||
|
||||
retcode = misc_register( &DRM(misc) );
|
||||
if ( retcode ) {
|
||||
DRM_ERROR( "Cannot register \"%s\"\n", DRIVER_NAME );
|
||||
return retcode;
|
||||
}
|
||||
dev->device = MKDEV( MISC_MAJOR, DRM(misc).minor );
|
||||
dev->name = DRIVER_NAME;
|
||||
|
||||
DRM(mem_init)();
|
||||
DRM(proc_init)( dev );
|
||||
|
||||
if ((DRM(minor) = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
|
||||
return -EPERM;
|
||||
dev->device = MKDEV(DRM_MAJOR, DRM(minor) );
|
||||
dev->name = DRIVER_NAME;
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
dev->agp = DRM(agp_init)();
|
||||
#if __MUST_HAVE_AGP
|
||||
if ( dev->agp == NULL ) {
|
||||
DRM_ERROR( "Cannot initialize the agpgart module.\n" );
|
||||
DRM(proc_cleanup)();
|
||||
misc_deregister( &DRM(misc) );
|
||||
DRM(stub_unregister)(DRM(minor));
|
||||
DRM(takedown)( dev );
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -401,8 +391,7 @@ static int __init drm_init( void )
|
|||
retcode = DRM(ctxbitmap_init)( dev );
|
||||
if( retcode ) {
|
||||
DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
|
||||
DRM(proc_cleanup)();
|
||||
misc_deregister( &DRM(misc) );
|
||||
DRM(stub_unregister)(DRM(minor));
|
||||
DRM(takedown)( dev );
|
||||
return retcode;
|
||||
}
|
||||
|
|
@ -416,7 +405,7 @@ static int __init drm_init( void )
|
|||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
DRM(misc).minor );
|
||||
DRM(minor) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -429,8 +418,7 @@ static void __exit drm_cleanup( void )
|
|||
|
||||
DRM_DEBUG( "\n" );
|
||||
|
||||
DRM(proc_cleanup)();
|
||||
if ( misc_deregister( &DRM(misc) ) ) {
|
||||
if ( DRM(stub_unregister)(DRM(minor)) ) {
|
||||
DRM_ERROR( "Cannot unload module\n" );
|
||||
} else {
|
||||
DRM_INFO( "Module unloaded\n" );
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ typedef struct drm_mem_stats {
|
|||
unsigned long bytes_freed;
|
||||
} drm_mem_stats_t;
|
||||
|
||||
static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED;
|
||||
static unsigned long drm_ram_available = 0; /* In pages */
|
||||
static unsigned long drm_ram_used = 0;
|
||||
static drm_mem_stats_t drm_mem_stats[] = {
|
||||
static spinlock_t DRM(mem_lock) = SPIN_LOCK_UNLOCKED;
|
||||
static unsigned long DRM(ram_available) = 0; /* In pages */
|
||||
static unsigned long DRM(ram_used) = 0;
|
||||
static drm_mem_stats_t DRM(mem_stats)[] = {
|
||||
[DRM_MEM_DMA] = { "dmabufs" },
|
||||
[DRM_MEM_SAREA] = { "sareas" },
|
||||
[DRM_MEM_DRIVER] = { "driver" },
|
||||
|
|
@ -66,6 +66,7 @@ static drm_mem_stats_t drm_mem_stats[] = {
|
|||
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
||||
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
||||
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
||||
[DRM_MEM_STUB] = { "stub" },
|
||||
{ NULL, 0, } /* Last entry must be null */
|
||||
};
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ void DRM(mem_init)(void)
|
|||
drm_mem_stats_t *mem;
|
||||
struct sysinfo si;
|
||||
|
||||
for (mem = drm_mem_stats; mem->name; ++mem) {
|
||||
for (mem = DRM(mem_stats); mem->name; ++mem) {
|
||||
mem->succeed_count = 0;
|
||||
mem->free_count = 0;
|
||||
mem->fail_count = 0;
|
||||
|
|
@ -85,17 +86,17 @@ void DRM(mem_init)(void)
|
|||
si_meminfo(&si);
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
/* Changed to page count in 2.3.23 */
|
||||
drm_ram_available = si.totalram >> PAGE_SHIFT;
|
||||
DRM(ram_available) = si.totalram >> PAGE_SHIFT;
|
||||
#else
|
||||
drm_ram_available = si.totalram;
|
||||
DRM(ram_available) = si.totalram;
|
||||
#endif
|
||||
drm_ram_used = 0;
|
||||
DRM(ram_used) = 0;
|
||||
}
|
||||
|
||||
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
|
||||
|
||||
static int _drm_mem_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data)
|
||||
static int DRM(_mem_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data)
|
||||
{
|
||||
drm_mem_stats_t *pt;
|
||||
|
||||
|
|
@ -108,11 +109,11 @@ static int _drm_mem_info(char *buf, char **start, off_t offset,
|
|||
" | allocs bytes\n\n");
|
||||
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
|
||||
"system", 0, 0, 0,
|
||||
drm_ram_available << (PAGE_SHIFT - 10));
|
||||
DRM(ram_available) << (PAGE_SHIFT - 10));
|
||||
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
|
||||
"locked", 0, 0, 0, drm_ram_used >> 10);
|
||||
"locked", 0, 0, 0, DRM(ram_used) >> 10);
|
||||
DRM_PROC_PRINT("\n");
|
||||
for (pt = drm_mem_stats; pt->name; pt++) {
|
||||
for (pt = DRM(mem_stats); pt->name; pt++) {
|
||||
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
|
||||
pt->name,
|
||||
pt->succeed_count,
|
||||
|
|
@ -133,9 +134,9 @@ int DRM(mem_info)(char *buf, char **start, off_t offset,
|
|||
{
|
||||
int ret;
|
||||
|
||||
spin_lock(&drm_mem_lock);
|
||||
ret = _drm_mem_info(buf, start, offset, len, eof, data);
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
ret = DRM(_mem_info)(buf, start, offset, len, eof, data);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -149,15 +150,15 @@ void *DRM(alloc)(size_t size, int area)
|
|||
}
|
||||
|
||||
if (!(pt = kmalloc(size, GFP_KERNEL))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[area].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[area].fail_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return NULL;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[area].succeed_count;
|
||||
drm_mem_stats[area].bytes_allocated += size;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[area].succeed_count;
|
||||
DRM(mem_stats)[area].bytes_allocated += size;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
|
@ -200,11 +201,11 @@ void DRM(free)(void *pt, size_t size, int area)
|
|||
|
||||
if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
|
||||
else kfree(pt);
|
||||
spin_lock(&drm_mem_lock);
|
||||
drm_mem_stats[area].bytes_freed += size;
|
||||
free_count = ++drm_mem_stats[area].free_count;
|
||||
alloc_count = drm_mem_stats[area].succeed_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
DRM(mem_stats)[area].bytes_freed += size;
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
|
||||
free_count, alloc_count);
|
||||
|
|
@ -218,26 +219,26 @@ unsigned long DRM(alloc_pages)(int order, int area)
|
|||
unsigned long addr;
|
||||
unsigned int sz;
|
||||
|
||||
spin_lock(&drm_mem_lock);
|
||||
if ((drm_ram_used >> PAGE_SHIFT)
|
||||
> (DRM_RAM_PERCENT * drm_ram_available) / 100) {
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
if ((DRM(ram_used) >> PAGE_SHIFT)
|
||||
> (DRM_RAM_PERCENT * DRM(ram_available)) / 100) {
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return 0;
|
||||
}
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
|
||||
address = __get_free_pages(GFP_KERNEL, order);
|
||||
if (!address) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[area].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[area].fail_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return 0;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[area].succeed_count;
|
||||
drm_mem_stats[area].bytes_allocated += bytes;
|
||||
drm_ram_used += bytes;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[area].succeed_count;
|
||||
DRM(mem_stats)[area].bytes_allocated += bytes;
|
||||
DRM(ram_used) += bytes;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
|
||||
|
||||
/* Zero outside the lock */
|
||||
|
|
@ -283,12 +284,12 @@ void DRM(free_pages)(unsigned long address, int order, int area)
|
|||
free_pages(address, order);
|
||||
}
|
||||
|
||||
spin_lock(&drm_mem_lock);
|
||||
free_count = ++drm_mem_stats[area].free_count;
|
||||
alloc_count = drm_mem_stats[area].succeed_count;
|
||||
drm_mem_stats[area].bytes_freed += bytes;
|
||||
drm_ram_used -= bytes;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
DRM(mem_stats)[area].bytes_freed += bytes;
|
||||
DRM(ram_used) -= bytes;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(area,
|
||||
"Excess frees: %d frees, %d allocs\n",
|
||||
|
|
@ -307,15 +308,15 @@ void *DRM(ioremap)(unsigned long offset, unsigned long size)
|
|||
}
|
||||
|
||||
if (!(pt = ioremap(offset, size))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return NULL;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
|
@ -330,11 +331,11 @@ void DRM(ioremapfree)(void *pt, unsigned long size)
|
|||
else
|
||||
iounmap(pt);
|
||||
|
||||
spin_lock(&drm_mem_lock);
|
||||
drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size;
|
||||
free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count;
|
||||
alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||
"Excess frees: %d frees, %d allocs\n",
|
||||
|
|
@ -354,16 +355,16 @@ agp_memory *DRM(alloc_agp)(int pages, u32 type)
|
|||
}
|
||||
|
||||
if ((handle = DRM(agp_allocate_memory)(pages, type))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
|
||||
+= pages << PAGE_SHIFT;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return handle;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -380,12 +381,12 @@ int DRM(free_agp)(agp_memory *handle, int pages)
|
|||
}
|
||||
|
||||
if (DRM(agp_free_memory)(handle)) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count;
|
||||
alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
|
||||
+= pages << PAGE_SHIFT;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
|
||||
"Excess frees: %d frees, %d allocs\n",
|
||||
|
|
@ -407,16 +408,16 @@ int DRM(bind_agp)(agp_memory *handle, unsigned int start)
|
|||
}
|
||||
|
||||
if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return retcode;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
|
@ -433,12 +434,12 @@ int DRM(unbind_agp)(agp_memory *handle)
|
|||
}
|
||||
|
||||
if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode;
|
||||
spin_lock(&drm_mem_lock);
|
||||
free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count;
|
||||
alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
|
||||
"Excess frees: %d frees, %d allocs\n",
|
||||
|
|
|
|||
197
linux/drm_proc.h
197
linux/drm_proc.h
|
|
@ -32,118 +32,105 @@
|
|||
#define __NO_VERSION__
|
||||
#include "drmP.h"
|
||||
|
||||
static struct proc_dir_entry *drm_root = NULL;
|
||||
static struct proc_dir_entry *drm_dev_root = NULL;
|
||||
static char drm_slot_name[64];
|
||||
|
||||
static int drm_name_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int drm_vm_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int drm_clients_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int drm_queues_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int drm_bufs_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
#if DRM_DEBUG_CODE
|
||||
static int drm_vma_info(char *buf, char **start, off_t offset,
|
||||
static int DRM(name_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int DRM(vm_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int DRM(clients_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int DRM(queues_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int DRM(bufs_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
#if DRM_DEBUG_CODE
|
||||
static int DRM(vma_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
#endif
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
static int drm_histo_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
static int DRM(histo_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data);
|
||||
#endif
|
||||
|
||||
struct drm_proc_list {
|
||||
const char *name;
|
||||
int (*f)(char *, char **, off_t, int, int *, void *);
|
||||
} drm_proc_list[] = {
|
||||
{ "name", drm_name_info },
|
||||
{ "mem", DRM(mem_info) },
|
||||
{ "vm", drm_vm_info },
|
||||
{ "clients", drm_clients_info },
|
||||
{ "queues", drm_queues_info },
|
||||
{ "bufs", drm_bufs_info },
|
||||
} DRM(proc_list)[] = {
|
||||
{ "name", DRM(name_info) },
|
||||
{ "mem", DRM(mem_info) },
|
||||
{ "vm", DRM(vm_info) },
|
||||
{ "clients", DRM(clients_info) },
|
||||
{ "queues", DRM(queues_info) },
|
||||
{ "bufs", DRM(bufs_info) },
|
||||
#if DRM_DEBUG_CODE
|
||||
{ "vma", drm_vma_info },
|
||||
{ "vma", DRM(vma_info) },
|
||||
#endif
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
{ "histo", drm_histo_info },
|
||||
{ "histo", DRM(histo_info) },
|
||||
#endif
|
||||
};
|
||||
#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
|
||||
#define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0]))
|
||||
|
||||
int DRM(proc_init)(drm_device_t *dev)
|
||||
struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
|
||||
struct proc_dir_entry *root,
|
||||
struct proc_dir_entry **dev_root)
|
||||
{
|
||||
struct proc_dir_entry *ent;
|
||||
int i, j;
|
||||
char name[64];
|
||||
|
||||
drm_root = create_proc_entry("dri", S_IFDIR, NULL);
|
||||
if (!drm_root) {
|
||||
if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL);
|
||||
if (!root) {
|
||||
DRM_ERROR("Cannot create /proc/dri\n");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Instead of doing this search, we should
|
||||
add some global support for /proc/dri. */
|
||||
for (i = 0; i < 8; i++) {
|
||||
sprintf(drm_slot_name, "dri/%d", i);
|
||||
drm_dev_root = create_proc_entry(drm_slot_name, S_IFDIR, NULL);
|
||||
if (!drm_dev_root) {
|
||||
DRM_ERROR("Cannot create /proc/%s\n", drm_slot_name);
|
||||
remove_proc_entry("dri", NULL);
|
||||
}
|
||||
if (drm_dev_root->nlink == 2) break;
|
||||
drm_dev_root = NULL;
|
||||
}
|
||||
if (!drm_dev_root) {
|
||||
DRM_ERROR("Cannot find slot in /proc/dri\n");
|
||||
return -1;
|
||||
sprintf(name, "%d", minor);
|
||||
*dev_root = create_proc_entry(name, S_IFDIR, root);
|
||||
if (!*dev_root) {
|
||||
DRM_ERROR("Cannot create /proc/%s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < DRM_PROC_ENTRIES; i++) {
|
||||
ent = create_proc_entry(drm_proc_list[i].name,
|
||||
S_IFREG|S_IRUGO, drm_dev_root);
|
||||
ent = create_proc_entry(DRM(proc_list)[i].name,
|
||||
S_IFREG|S_IRUGO, *dev_root);
|
||||
if (!ent) {
|
||||
DRM_ERROR("Cannot create /proc/%s/%s\n",
|
||||
drm_slot_name, drm_proc_list[i].name);
|
||||
DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
|
||||
name, DRM(proc_list)[i].name);
|
||||
for (j = 0; j < i; j++)
|
||||
remove_proc_entry(drm_proc_list[i].name,
|
||||
drm_dev_root);
|
||||
remove_proc_entry(drm_slot_name, NULL);
|
||||
remove_proc_entry("dri", NULL);
|
||||
return -1;
|
||||
remove_proc_entry(DRM(proc_list)[i].name,
|
||||
*dev_root);
|
||||
remove_proc_entry(name, root);
|
||||
if (!minor) remove_proc_entry("dri", NULL);
|
||||
return NULL;
|
||||
}
|
||||
ent->read_proc = drm_proc_list[i].f;
|
||||
ent->read_proc = DRM(proc_list)[i].f;
|
||||
ent->data = dev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
int DRM(proc_cleanup)(void)
|
||||
int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
|
||||
struct proc_dir_entry *dev_root)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
char name[64];
|
||||
|
||||
if (!root || !dev_root) return 0;
|
||||
|
||||
for (i = 0; i < DRM_PROC_ENTRIES; i++)
|
||||
remove_proc_entry(DRM(proc_list)[i].name, dev_root);
|
||||
sprintf(name, "%d", minor);
|
||||
remove_proc_entry(name, root);
|
||||
if (!minor) remove_proc_entry("dri", NULL);
|
||||
|
||||
if (drm_root) {
|
||||
if (drm_dev_root) {
|
||||
for (i = 0; i < DRM_PROC_ENTRIES; i++) {
|
||||
remove_proc_entry(drm_proc_list[i].name,
|
||||
drm_dev_root);
|
||||
}
|
||||
remove_proc_entry(drm_slot_name, NULL);
|
||||
}
|
||||
remove_proc_entry("dri", NULL);
|
||||
remove_proc_entry(DRM_NAME, NULL);
|
||||
}
|
||||
drm_root = drm_dev_root = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_name_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(name_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
|
||||
|
|
@ -160,8 +147,8 @@ static int drm_name_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_vm_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_map_t *map;
|
||||
|
|
@ -198,21 +185,21 @@ static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_vm_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(vm_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_vm_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_vm_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int _drm_queues_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_queues_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int i;
|
||||
|
|
@ -250,23 +237,23 @@ static int _drm_queues_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_queues_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(queues_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_queues_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_queues_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* drm_bufs_info is called whenever a process reads
|
||||
/dev/drm/<dev>/bufs. */
|
||||
/dev/dri/<dev>/bufs. */
|
||||
|
||||
static int _drm_bufs_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
|
@ -302,21 +289,21 @@ static int _drm_bufs_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_bufs_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(bufs_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_bufs_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_bufs_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int _drm_clients_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_clients_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_file_t *priv;
|
||||
|
|
@ -338,14 +325,14 @@ static int _drm_clients_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_clients_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(clients_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_clients_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_clients_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -354,8 +341,8 @@ static int drm_clients_info(char *buf, char **start, off_t offset, int len,
|
|||
|
||||
#define DRM_VMA_VERBOSE 0
|
||||
|
||||
static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_vma_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_vma_entry_t *pt;
|
||||
|
|
@ -432,14 +419,14 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_vma_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(vma_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_vma_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_vma_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -447,8 +434,8 @@ static int drm_vma_info(char *buf, char **start, off_t offset, int len,
|
|||
|
||||
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(_histo_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
|
@ -564,14 +551,14 @@ static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
|
|||
return len;
|
||||
}
|
||||
|
||||
static int drm_histo_info(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
static int DRM(histo_info)(char *buf, char **start, off_t offset, int len,
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = _drm_histo_info(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_histo_info)(buf, start, offset, len, eof, data);
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
142
linux/drm_stub.h
Normal file
142
linux/drm_stub.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* drm_stub.c -- -*- linux-c -*-
|
||||
* Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
|
||||
*
|
||||
* Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#define DRM_STUB_MAXCARDS 16 /* Enough for one machine */
|
||||
|
||||
static struct drm_stub_list {
|
||||
const char *name;
|
||||
struct file_operations *fops;
|
||||
struct proc_dir_entry *dev_root;
|
||||
} *DRM(stub_list);
|
||||
|
||||
static struct proc_dir_entry *DRM(stub_root);
|
||||
|
||||
static struct drm_stub_info {
|
||||
int (*info_register)(const char *name, struct file_operations *fops,
|
||||
drm_device_t *dev);
|
||||
int (*info_unregister)(int minor);
|
||||
} DRM(stub_info);
|
||||
|
||||
static int DRM(stub_open)(struct inode *inode, struct file *filp)
|
||||
{
|
||||
int minor = MINOR(inode->i_rdev);
|
||||
int err = -ENODEV;
|
||||
struct file_operations *old_fops;
|
||||
|
||||
if (!DRM(stub_list) || !DRM(stub_list)[minor].fops) return -ENODEV;
|
||||
old_fops = filp->f_op;
|
||||
filp->f_op = fops_get(DRM(stub_list)[minor].fops);
|
||||
if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
|
||||
fops_put(filp->f_op);
|
||||
filp->f_op = fops_get(old_fops);
|
||||
}
|
||||
fops_put(old_fops);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct file_operations DRM(stub_fops) = {
|
||||
#if LINUX_VERSION_CODE >= 0x020400
|
||||
owner: THIS_MODULE,
|
||||
#endif
|
||||
open: DRM(stub_open)
|
||||
};
|
||||
|
||||
static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
|
||||
drm_device_t *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!DRM(stub_list)) {
|
||||
DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list))
|
||||
* DRM_STUB_MAXCARDS, DRM_MEM_STUB);
|
||||
for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
|
||||
DRM(stub_list)[i].name = NULL;
|
||||
DRM(stub_list)[i].fops = NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
|
||||
if (!DRM(stub_list)[i].fops) {
|
||||
DRM(stub_list)[i].name = name;
|
||||
DRM(stub_list)[i].fops = fops;
|
||||
DRM(stub_root) = DRM(proc_init)(dev, i, DRM(stub_root),
|
||||
&DRM(stub_list)[i]
|
||||
.dev_root);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int DRM(stub_putminor)(int minor)
|
||||
{
|
||||
if (minor < 0 || minor >= DRM_STUB_MAXCARDS) return -1;
|
||||
DRM(stub_list)[minor].name = NULL;
|
||||
DRM(stub_list)[minor].fops = NULL;
|
||||
DRM(proc_cleanup)(minor, DRM(stub_root),
|
||||
DRM(stub_list)[minor].dev_root);
|
||||
if (minor) {
|
||||
inter_module_put("drm");
|
||||
} else {
|
||||
inter_module_unregister("drm");
|
||||
DRM(free)(DRM(stub_list),
|
||||
sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS,
|
||||
DRM_MEM_STUB);
|
||||
unregister_chrdev(DRM_MAJOR, "drm");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DRM(stub_register)(const char *name, struct file_operations *fops,
|
||||
drm_device_t *dev)
|
||||
{
|
||||
if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) {
|
||||
/* Already registered */
|
||||
struct drm_stub_info *i;
|
||||
i = (struct drm_stub_info *)inter_module_get("drm");
|
||||
DRM(stub_info).info_register = i->info_register;
|
||||
DRM(stub_info).info_unregister = i->info_unregister;
|
||||
} else {
|
||||
DRM(stub_info).info_register = DRM(stub_getminor);
|
||||
DRM(stub_info).info_unregister = DRM(stub_putminor);
|
||||
inter_module_register("drm", THIS_MODULE, &DRM(stub_info));
|
||||
}
|
||||
if (DRM(stub_info).info_register)
|
||||
return DRM(stub_info).info_register(name, fops, dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DRM(stub_unregister)(int minor)
|
||||
{
|
||||
DRM_DEBUG("%d\n", minor);
|
||||
if (DRM(stub_info).info_unregister)
|
||||
return DRM(stub_info).info_unregister(minor);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -64,3 +64,5 @@
|
|||
#include "drm_proc.h"
|
||||
|
||||
#include "drm_vm.h"
|
||||
|
||||
#include "drm_stub.h"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue