From 4f8f02a1922653b2ce5c115c4469e927b5d826fa Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 3 Aug 2004 09:21:11 +0000 Subject: fix for drm in /proc - from Jon Smirl --- linux-core/drmP.h | 8 ++++---- linux-core/drm_drv.c | 3 ++- linux-core/drm_proc.c | 17 ++++------------- linux-core/drm_stub.c | 36 +++++++++++++++++++++++------------- linux/drmP.h | 8 ++++---- linux/drm_drv.h | 3 ++- linux/drm_proc.h | 17 ++++------------- linux/drm_stub.h | 36 +++++++++++++++++++++++------------- 8 files changed, 66 insertions(+), 62 deletions(-) diff --git a/linux-core/drmP.h b/linux-core/drmP.h index dfa56d90..7b136dfe 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -927,10 +927,10 @@ int DRM(stub_register)(const char *name, int DRM(stub_unregister)(int minor); /* Proc support (drm_proc.h) */ -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_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); diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index a6e745f3..a75566e8 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -153,6 +153,7 @@ struct drm_stub_info { int (*info_unregister)(int minor); struct class_simple *drm_class; int *info_count; + struct proc_dir_entry *proc_root; }; extern struct drm_stub_info DRM(stub_info); @@ -775,7 +776,7 @@ static void __exit drm_cleanup( drm_device_t *dev ) } #endif - class_simple_device_remove(MKDEV(DRM_MAJOR, 0)); + class_simple_device_remove(MKDEV(DRM_MAJOR, dev->minor)); } static void __exit drm_exit (void) diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index dc6e1bb2..a9affc5a 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c @@ -87,7 +87,7 @@ struct drm_proc_list { * "/proc/dri/%minor%/", and each entry in proc_list as * "/proc/dri/%minor%/%name%". */ -struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, +int DRM(proc_init)(drm_device_t *dev, int minor, struct proc_dir_entry *root, struct proc_dir_entry **dev_root) { @@ -95,17 +95,11 @@ struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, int i, j; char name[64]; - if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL); - if (!root) { - DRM_ERROR("Cannot create /proc/dri\n"); - return NULL; - } - sprintf(name, "%d", minor); *dev_root = create_proc_entry(name, S_IFDIR, root); if (!*dev_root) { DRM_ERROR("Cannot create /proc/dri/%s\n", name); - return NULL; + return -1; } for (i = 0; i < DRM_PROC_ENTRIES; i++) { @@ -118,14 +112,12 @@ struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, remove_proc_entry(DRM(proc_list)[i].name, *dev_root); remove_proc_entry(name, root); - if (!minor) remove_proc_entry("dri", NULL); - return NULL; + return -1; } ent->read_proc = DRM(proc_list)[i].f; ent->data = dev; } - - return root; + return 0; } @@ -151,7 +143,6 @@ int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root, 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); return 0; } diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index a1b45a92..d61f73ee 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -43,8 +43,6 @@ static struct drm_stub_list { struct proc_dir_entry *dev_root; /**< proc directory entry */ } *DRM(stub_list); -static struct proc_dir_entry *DRM(stub_root); - /** * File \c open operation. * @@ -175,9 +173,8 @@ static int DRM(stub_getminor)(const char *name, struct file_operations *fops, 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); + DRM(proc_init)(dev, i, DRM(stub_info).proc_root, + &DRM(stub_list)[i].dev_root); (*DRM(stub_info).info_count)++; DRM_DEBUG("info count increased %d\n", *DRM(stub_info).info_count); return i; @@ -201,13 +198,13 @@ 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(proc_cleanup)(minor, DRM(stub_info).proc_root, DRM(stub_list)[minor].dev_root); (*DRM(stub_info).info_count)--; - if ((*DRM(stub_info).info_count)!=0) { - if (DRM(numdevs)==0) { + if ((*DRM(stub_info).info_count) != 0) { + if (DRM(numdevs) == 0) { DRM_DEBUG("inter_module_put called %d\n", *DRM(stub_info).info_count); inter_module_put("drm"); } @@ -217,6 +214,7 @@ static int DRM(stub_putminor)(int minor) DRM(free)(DRM(stub_list), sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS, DRM_MEM_STUB); + remove_proc_entry("dri", NULL); class_simple_destroy(DRM(stub_info).drm_class); unregister_chrdev(DRM_MAJOR, "drm"); } @@ -269,27 +267,38 @@ int DRM(stub_register)(const char *name, struct file_operations *fops, } DRM(stub_info).drm_class = class_simple_create(THIS_MODULE, "drm"); - class_simple_set_hotplug(DRM(stub_info).drm_class, drm_hotplug); if (IS_ERR(DRM(stub_info).drm_class)) { printk (KERN_ERR "Error creating drm class.\n"); unregister_chrdev(DRM_MAJOR, "drm"); return PTR_ERR(DRM(stub_info).drm_class); } + class_simple_set_hotplug(DRM(stub_info).drm_class, drm_hotplug); + DRM_DEBUG("calling inter_module_register\n"); inter_module_register("drm", THIS_MODULE, &DRM(stub_info)); + + DRM(stub_info).proc_root = create_proc_entry("dri", S_IFDIR, NULL); + if (!DRM(stub_info).proc_root) { + DRM_ERROR("Cannot create /proc/dri\n"); + inter_module_unregister("drm"); + unregister_chrdev(DRM_MAJOR, "drm"); + class_simple_destroy(DRM(stub_info).drm_class); + return -1; + } + } - } - else + } else DRM_DEBUG("already retrieved inter_module information\n"); if (DRM(stub_info).info_register) { ret2 = DRM(stub_info).info_register(name, fops, dev); if (ret2 < 0) { - if (DRM(numdevs)==0 && !i) { + if (DRM(numdevs) == 0 && !i) { inter_module_unregister("drm"); unregister_chrdev(DRM_MAJOR, "drm"); class_simple_destroy(DRM(stub_info).drm_class); - DRM_DEBUG("info_register failed deregistered everything\n"); + remove_proc_entry("dri", NULL); + DRM_DEBUG("info_register failed, deregistered everything\n"); } DRM_DEBUG("info_register failed\n"); } @@ -321,4 +330,5 @@ struct drm_stub_info DRM(stub_info) = { .info_unregister = DRM(stub_putminor), .drm_class = NULL, .info_count = &DRM(stub_count), + .proc_root = NULL, }; diff --git a/linux/drmP.h b/linux/drmP.h index dfa56d90..7b136dfe 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -927,10 +927,10 @@ int DRM(stub_register)(const char *name, int DRM(stub_unregister)(int minor); /* Proc support (drm_proc.h) */ -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_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); diff --git a/linux/drm_drv.h b/linux/drm_drv.h index a6e745f3..a75566e8 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -153,6 +153,7 @@ struct drm_stub_info { int (*info_unregister)(int minor); struct class_simple *drm_class; int *info_count; + struct proc_dir_entry *proc_root; }; extern struct drm_stub_info DRM(stub_info); @@ -775,7 +776,7 @@ static void __exit drm_cleanup( drm_device_t *dev ) } #endif - class_simple_device_remove(MKDEV(DRM_MAJOR, 0)); + class_simple_device_remove(MKDEV(DRM_MAJOR, dev->minor)); } static void __exit drm_exit (void) diff --git a/linux/drm_proc.h b/linux/drm_proc.h index dc6e1bb2..a9affc5a 100644 --- a/linux/drm_proc.h +++ b/linux/drm_proc.h @@ -87,7 +87,7 @@ struct drm_proc_list { * "/proc/dri/%minor%/", and each entry in proc_list as * "/proc/dri/%minor%/%name%". */ -struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, +int DRM(proc_init)(drm_device_t *dev, int minor, struct proc_dir_entry *root, struct proc_dir_entry **dev_root) { @@ -95,17 +95,11 @@ struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, int i, j; char name[64]; - if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL); - if (!root) { - DRM_ERROR("Cannot create /proc/dri\n"); - return NULL; - } - sprintf(name, "%d", minor); *dev_root = create_proc_entry(name, S_IFDIR, root); if (!*dev_root) { DRM_ERROR("Cannot create /proc/dri/%s\n", name); - return NULL; + return -1; } for (i = 0; i < DRM_PROC_ENTRIES; i++) { @@ -118,14 +112,12 @@ struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, remove_proc_entry(DRM(proc_list)[i].name, *dev_root); remove_proc_entry(name, root); - if (!minor) remove_proc_entry("dri", NULL); - return NULL; + return -1; } ent->read_proc = DRM(proc_list)[i].f; ent->data = dev; } - - return root; + return 0; } @@ -151,7 +143,6 @@ int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root, 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); return 0; } diff --git a/linux/drm_stub.h b/linux/drm_stub.h index a1b45a92..d61f73ee 100644 --- a/linux/drm_stub.h +++ b/linux/drm_stub.h @@ -43,8 +43,6 @@ static struct drm_stub_list { struct proc_dir_entry *dev_root; /**< proc directory entry */ } *DRM(stub_list); -static struct proc_dir_entry *DRM(stub_root); - /** * File \c open operation. * @@ -175,9 +173,8 @@ static int DRM(stub_getminor)(const char *name, struct file_operations *fops, 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); + DRM(proc_init)(dev, i, DRM(stub_info).proc_root, + &DRM(stub_list)[i].dev_root); (*DRM(stub_info).info_count)++; DRM_DEBUG("info count increased %d\n", *DRM(stub_info).info_count); return i; @@ -201,13 +198,13 @@ 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(proc_cleanup)(minor, DRM(stub_info).proc_root, DRM(stub_list)[minor].dev_root); (*DRM(stub_info).info_count)--; - if ((*DRM(stub_info).info_count)!=0) { - if (DRM(numdevs)==0) { + if ((*DRM(stub_info).info_count) != 0) { + if (DRM(numdevs) == 0) { DRM_DEBUG("inter_module_put called %d\n", *DRM(stub_info).info_count); inter_module_put("drm"); } @@ -217,6 +214,7 @@ static int DRM(stub_putminor)(int minor) DRM(free)(DRM(stub_list), sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS, DRM_MEM_STUB); + remove_proc_entry("dri", NULL); class_simple_destroy(DRM(stub_info).drm_class); unregister_chrdev(DRM_MAJOR, "drm"); } @@ -269,27 +267,38 @@ int DRM(stub_register)(const char *name, struct file_operations *fops, } DRM(stub_info).drm_class = class_simple_create(THIS_MODULE, "drm"); - class_simple_set_hotplug(DRM(stub_info).drm_class, drm_hotplug); if (IS_ERR(DRM(stub_info).drm_class)) { printk (KERN_ERR "Error creating drm class.\n"); unregister_chrdev(DRM_MAJOR, "drm"); return PTR_ERR(DRM(stub_info).drm_class); } + class_simple_set_hotplug(DRM(stub_info).drm_class, drm_hotplug); + DRM_DEBUG("calling inter_module_register\n"); inter_module_register("drm", THIS_MODULE, &DRM(stub_info)); + + DRM(stub_info).proc_root = create_proc_entry("dri", S_IFDIR, NULL); + if (!DRM(stub_info).proc_root) { + DRM_ERROR("Cannot create /proc/dri\n"); + inter_module_unregister("drm"); + unregister_chrdev(DRM_MAJOR, "drm"); + class_simple_destroy(DRM(stub_info).drm_class); + return -1; + } + } - } - else + } else DRM_DEBUG("already retrieved inter_module information\n"); if (DRM(stub_info).info_register) { ret2 = DRM(stub_info).info_register(name, fops, dev); if (ret2 < 0) { - if (DRM(numdevs)==0 && !i) { + if (DRM(numdevs) == 0 && !i) { inter_module_unregister("drm"); unregister_chrdev(DRM_MAJOR, "drm"); class_simple_destroy(DRM(stub_info).drm_class); - DRM_DEBUG("info_register failed deregistered everything\n"); + remove_proc_entry("dri", NULL); + DRM_DEBUG("info_register failed, deregistered everything\n"); } DRM_DEBUG("info_register failed\n"); } @@ -321,4 +330,5 @@ struct drm_stub_info DRM(stub_info) = { .info_unregister = DRM(stub_putminor), .drm_class = NULL, .info_count = &DRM(stub_count), + .proc_root = NULL, }; -- cgit v1.2.3