fix for drm in /proc - from Jon Smirl
authorDave Airlie <airlied@linux.ie>
Tue, 3 Aug 2004 09:21:11 +0000 (09:21 +0000)
committerDave Airlie <airlied@linux.ie>
Tue, 3 Aug 2004 09:21:11 +0000 (09:21 +0000)
linux-core/drmP.h
linux-core/drm_drv.c
linux-core/drm_proc.c
linux-core/drm_stub.c
linux/drmP.h
linux/drm_drv.h
linux/drm_proc.h
linux/drm_stub.h

index dfa56d9..7b136df 100644 (file)
@@ -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);
index a6e745f..a75566e 100644 (file)
@@ -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)
index dc6e1bb..a9affc5 100644 (file)
@@ -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;
 }
index a1b45a9..d61f73e 100644 (file)
@@ -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,
 };
index dfa56d9..7b136df 100644 (file)
@@ -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);
index a6e745f..a75566e 100644 (file)
@@ -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)
index dc6e1bb..a9affc5 100644 (file)
@@ -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;
 }
index a1b45a9..d61f73e 100644 (file)
@@ -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,
 };