diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 193bee8f..9063e2bb 100644 --- a/linux-core/drmP.h +++ b/linux-core/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 diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 1c940179..a6829794 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -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" ); diff --git a/linux-core/drm_memory.h b/linux-core/drm_memory.h index e8fed66f..9dcd9d9a 100644 --- a/linux-core/drm_memory.h +++ b/linux-core/drm_memory.h @@ -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", diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index 468115fa..0467f89f 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c @@ -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//bufs. */ + /dev/dri//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; } diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c new file mode 100644 index 00000000..ed37af4d --- /dev/null +++ b/linux-core/drm_stub.c @@ -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 + * + */ + +#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; +} diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 24a03b64..fd0cac61 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -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 diff --git a/linux/drmP.h b/linux/drmP.h index 193bee8f..9063e2bb 100644 --- a/linux/drmP.h +++ b/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 diff --git a/linux/drm_drv.h b/linux/drm_drv.h index 1c940179..a6829794 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -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" ); diff --git a/linux/drm_memory.h b/linux/drm_memory.h index e8fed66f..9dcd9d9a 100644 --- a/linux/drm_memory.h +++ b/linux/drm_memory.h @@ -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", diff --git a/linux/drm_proc.h b/linux/drm_proc.h index 468115fa..0467f89f 100644 --- a/linux/drm_proc.h +++ b/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//bufs. */ + /dev/dri//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; } diff --git a/linux/drm_stub.h b/linux/drm_stub.h new file mode 100644 index 00000000..ed37af4d --- /dev/null +++ b/linux/drm_stub.h @@ -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 + * + */ + +#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; +} diff --git a/linux/mga_drm.c b/linux/mga_drm.c index 97e4548b..4ce2b49e 100644 --- a/linux/mga_drm.c +++ b/linux/mga_drm.c @@ -64,3 +64,5 @@ #include "drm_proc.h" #include "drm_vm.h" + +#include "drm_stub.h"