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:
Rik Faith 2001-02-01 20:54:01 +00:00
parent 6fc31e043a
commit 95bb76c7de
12 changed files with 691 additions and 427 deletions

View file

@ -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

View file

@ -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" );

View file

@ -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",

View file

@ -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
View 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;
}

View file

@ -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

View file

@ -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

View file

@ -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" );

View file

@ -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",

View file

@ -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
View 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;
}

View file

@ -64,3 +64,5 @@
#include "drm_proc.h"
#include "drm_vm.h"
#include "drm_stub.h"