I'm just starting to look at the bug, but the code involved has been
rewritten in a patch that isn't checked in yet. You might want to give
the new code a try.

=====
Jon Smirl
[EMAIL PROTECTED]


                
__________________________________
Do you Yahoo!?
Yahoo! Mail is new and improved - Check it out!
http://promotions.yahoo.com/new_mail
===== linux/drmP.h 1.9 vs edited =====
--- 1.9/linux/drmP.h	Wed Aug 25 16:55:12 2004
+++ edited/linux/drmP.h	Sat Aug 28 12:15:16 2004
@@ -682,12 +682,23 @@
 	sigset_t          sigmask;
 	
 	int               need_reset;	/**< secondary device needing reset */
+
+	struct file_operations *fops;	/**< file operations */
+	struct proc_dir_entry  *dev_root; /**< proc directory entry */
+ 
 	struct drm_driver_fn fn_tbl;
 	drm_local_map_t   *agp_buffer_map;
 	int               dev_priv_size;
 	u32               driver_features;
 } drm_device_t;
 
+typedef struct drm_global {
+	unsigned int cards_limit;
+	drm_device_t **devices;
+	struct class_simple *drm_class;
+	struct proc_dir_entry *proc_root;
+} drm_global_t;
+
 extern void DRM(driver_register_fns)(struct drm_device *dev);
 
 /******************************************************************/
@@ -896,10 +907,9 @@
 #endif
 
 				/* 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);
+extern int 	      DRM(probe)(struct pci_dev *pdev, const struct pci_device_id *ent);
+extern int 	      DRM(putminor)(drm_device_t *dev);
+extern drm_global_t   *DRM(global);
 
 				/* Proc support (drm_proc.h) */
 extern int 	      DRM(proc_init)(drm_device_t *dev,
===== linux/drm_drv.h 1.10 vs edited =====
--- 1.10/linux/drm_drv.h	Fri Aug 27 18:33:53 2004
+++ edited/linux/drm_drv.h	Sat Aug 28 12:27:49 2004
@@ -64,17 +64,6 @@
 
 static void __exit drm_cleanup( drm_device_t *dev );
 
-/** Stub information */
-struct drm_stub_info {
-	int (*info_register)(const char *name, struct file_operations *fops,
-			     drm_device_t *dev);
-	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);
-
 #ifndef MODULE
 /** Use an additional macro to avoid preprocessor troubles */
 #define DRM_OPTIONS_FUNC DRM(options)
@@ -93,9 +82,6 @@
 #undef DRM_OPTIONS_FUNC
 #endif
 
-#define MAX_DEVICES 4
-drm_device_t            DRM(device)[MAX_DEVICES];
-int DRM(numdevs) = 0;
 int DRM(fb_loaded) = 0;
 
 struct file_operations	DRM(fops) = {
@@ -175,15 +161,6 @@
 
 #define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( DRM(ioctls) )
 
-#ifdef MODULE
-static char *drm_opts = NULL;
-#endif
-
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_PARM( drm_opts, "s" );
-MODULE_LICENSE("GPL and additional rights");
-
 static int DRM(setup)( drm_device_t *dev )
 {
 	int i;
@@ -457,30 +434,18 @@
 	DRM(PCI_IDS)
 };
 
-static int drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+int DRM(fill_in_dev)(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	drm_device_t *dev;
 	int retcode;
 
-	DRM_DEBUG( "\n" );
-
-	if (DRM(numdevs) >= MAX_DEVICES)
-		return -ENODEV;
-
-	dev = &(DRM(device)[DRM(numdevs)]);
-	if (DRM(fb_loaded)==0)
-		pci_set_drvdata(pdev, dev);
-
-	memset( (void *)dev, 0, sizeof(*dev) );
 	dev->count_lock = SPIN_LOCK_UNLOCKED;
 	init_timer( &dev->timer );
 	sema_init( &dev->struct_sem, 1 );
 	sema_init( &dev->ctxlist_sem, 1 );
 
 	dev->name   = DRIVER_NAME;
-
 	dev->pdev   = pdev;
-	pci_enable_device(pdev);
+
 #ifdef __alpha__
 	dev->hose   = pdev->sysdata;
 	dev->pci_domain = dev->hose->bus->number;
@@ -492,9 +457,8 @@
 	dev->pci_func = PCI_FUNC(pdev->devfn);
 	dev->irq = pdev->irq;
 
-	dev->maplist = DRM(alloc)(sizeof(*dev->maplist), DRM_MEM_MAPS);
+	dev->maplist = DRM(calloc)(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
 	if(dev->maplist == NULL) return -ENOMEM;
-	memset(dev->maplist, 0, sizeof(*dev->maplist));
 	INIT_LIST_HEAD(&dev->maplist->head);
 
 	/* dev_priv_size can be changed by a driver in driver_register_fns */
@@ -537,15 +501,7 @@
 	  goto error_out_unreg;
 	}
 
-	if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
-	{
-		retcode = -EPERM;
-		goto error_out;
-	}
-			
 	dev->device = MKDEV(DRM_MAJOR, dev->minor );
-	
-	DRM(numdevs)++; /* no errors, mark it reserved */
 
 	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
 		DRIVER_NAME,
@@ -565,27 +521,31 @@
 	return 0;
 
  error_out_unreg:
-	DRM(stub_unregister)(dev->minor);
 	DRM(takedown)(dev);
- error_out:
 	return retcode;
 }
 
 static void __exit drm_cleanup_pci(struct pci_dev *pdev)
 {
 	drm_device_t *dev = pci_get_drvdata(pdev);
-
-	pci_set_drvdata(pdev, NULL);
-	drm_cleanup(dev);
+	if (dev) {
+		pci_set_drvdata(pdev, NULL);
+		drm_cleanup(dev);
+	}
 }
 
 static struct pci_driver drm_driver = {
 	.name          = DRIVER_NAME,
 	.id_table      = DRM(pciidlist),
-	.probe         = drm_probe,
+	.probe         = DRM(probe),
 	.remove        = __devexit_p(drm_cleanup_pci),
 };
 
+#ifdef MODULE
+static char *drm_opts = NULL;
+#endif
+MODULE_PARM( drm_opts, "s" );
+
 /**
  * Module initialization. Called via init_module at module load time, or via
  * linux/init/main.c (this is not currently supported).
@@ -641,7 +601,7 @@
 			/* pass back in pdev to account for multiple identical cards */
 			while ((pdev = pci_get_subsys(pid->vendor, pid->device, pid->subvendor, pid->subdevice, pdev))) {
 				/* stealth mode requires a manual probe */
-				drm_probe(pdev, &DRM(pciidlist[i]));
+				DRM(probe)(pdev, &DRM(pciidlist[i]));
 			}
 		}
 		DRM_INFO("Used old pci detect: framebuffer loaded\n");
@@ -661,7 +621,7 @@
 	drm_map_t *map;
 	drm_map_list_t *r_list;
 	struct list_head *list, *list_next;
-	
+
 	DRM_DEBUG( "\n" );
 	if (!dev) {
 		DRM_ERROR("cleanup called no dev\n");
@@ -711,13 +671,6 @@
 	if (DRM(fb_loaded)==0)
 		pci_disable_device(dev->pdev);
 
-	DRM(numdevs)--;
-	if ( DRM(stub_unregister)(dev->minor) ) {
-		DRM_ERROR( "Cannot unload module\n" );
-	} else {
-		DRM_DEBUG( "minor %d unregistered\n", dev->minor);
-	}
-
 	DRM(ctxbitmap_cleanup)( dev );
 
 #if __OS_HAS_AGP
@@ -738,25 +691,33 @@
 #endif
 	if (dev->fn_tbl.postcleanup)
 		dev->fn_tbl.postcleanup(dev);
+
+	if ( DRM(putminor)(dev) )
+		DRM_ERROR( "Cannot unload module\n" );
+	else
+		DRM_DEBUG( "minor %d unregistered\n", dev->minor);
 }
 
 static void __exit drm_exit (void)
 {
+	int i;
+	drm_device_t *dev;
+	
 	DRM_DEBUG( "\n" );
-	if (DRM(fb_loaded)==1)
-	{
-		int i;
-		drm_device_t *dev;
-
-		for (i = DRM(numdevs) - 1; i >= 0; i--) {
-			dev = &(DRM(device)[i]);
-			/* release the pci driver */
-			if (dev->pdev)
-				pci_dev_put(dev->pdev);
-			drm_cleanup(dev);
+	if (DRM(fb_loaded)) {
+		if (DRM(global)) {
+			for (i = 0; i < DRM(global)->cards_limit; i++) {
+				dev = DRM(global)->devices[i];
+				DRM_DEBUG("fb loaded release minor %d\n", dev->minor);
+				if (dev && (dev->fops == &DRM(fops))) {
+					/* release the pci driver */
+					if (dev->pdev)
+						pci_dev_put(dev->pdev);
+					drm_cleanup(dev);
+				}
+			}
 		}
-	}
-	else
+	} else
 		pci_unregister_driver(&drm_driver);
 	DRM_INFO( "Module unloaded\n" );
 }
@@ -823,18 +784,15 @@
 int DRM(open)( struct inode *inode, struct file *filp )
 {
 	drm_device_t *dev = NULL;
+	int minor = iminor(inode);
 	int retcode = 0;
-	int i;
 
-	for (i = 0; i < DRM(numdevs); i++) {
-		if (iminor(inode) == DRM(device)[i].minor) {
-			dev = &(DRM(device)[i]);
-			break;
-		}
-	}
-	if (!dev) {
+	if (!((minor >= 0) && (minor < DRM(global)->cards_limit)))
+		return -ENODEV;
+		
+	dev = DRM(global)->devices[minor];
+	if (!dev)
 		return -ENODEV;
-	}
 
 	retcode = DRM(open_helper)( inode, filp, dev );
 	if ( !retcode ) {
===== linux/drm_stub.h 1.11 vs edited =====
--- 1.11/linux/drm_stub.h	Fri Aug 27 18:33:53 2004
+++ edited/linux/drm_stub.h	Sat Aug 28 12:14:26 2004
@@ -33,14 +33,18 @@
 
 #include "drmP.h"
 
-#define DRM_STUB_MAXCARDS 16	/* Enough for one machine */
+static unsigned int cards_limit = 16;	/* Enough for one machine */
+static unsigned int debug = 0;		/* 1 to enable debug output */
 
-/** Stub list. One for each minor. */
-static struct drm_stub_list {
-	const char             *name;
-	struct file_operations *fops;	/**< file operations */
-	struct proc_dir_entry  *dev_root;	/**< proc directory entry */
-} *DRM(stub_list);
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
+module_param(cards_limit, int, 0444);
+MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards");
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable debug output");
+
+drm_global_t *DRM(global);
 
 /**
  * File \c open operation.
@@ -53,13 +57,22 @@
  */
 static int DRM(stub_open)(struct inode *inode, struct file *filp)
 {
-	int                    minor = iminor(inode);
-	int                    err   = -ENODEV;
+	drm_device_t *dev = NULL;
+	int minor = iminor(inode);
+	int err = -ENODEV;
 	struct file_operations *old_fops;
+	
+	DRM_DEBUG("\n");
+
+	if (!((minor >= 0) && (minor < DRM(global)->cards_limit)))
+		return -ENODEV;
+
+	dev = DRM(global)->devices[minor];
+	if (!dev)
+		return -ENODEV;
 
-	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);
+	old_fops = filp->f_op;
+	filp->f_op = fops_get(dev->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);
@@ -76,19 +89,20 @@
 };
 
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
-static int drm_hotplug (struct class_device *dev, char **envp, int num_envp,
+static int drm_hotplug (struct class_device *cdev, char **envp, int num_envp,
 				char *buffer, int buffer_size)
 {
+	drm_device_t *dev;
 	struct pci_dev *pdev;
 	char *scratch;
 	int i = 0;
 	int length = 0;
-	
+
 	DRM_DEBUG("\n");
-	if (!dev)
+	if (!cdev)
 		return -ENODEV;
 
-	pdev = to_pci_dev(dev->dev);
+	pdev = to_pci_dev(cdev->dev);
 	if (!pdev)
 		return -ENODEV;
 
@@ -127,19 +141,17 @@
 		return -ENOMEM;
 	++length;
 	scratch += length;
-#if 0	
-	drm_device_t *ddev;
-	ddev = pci_get_drvdata(pdev);
-	if (ddev) {
+
+	dev = pci_get_drvdata(pdev);
+	if (dev) {
 		envp[i++] = scratch;
 		length += snprintf (scratch, buffer_size - length, 
-							"RESET=%s", (ddev->need_reset ? "true" : "false"));
+							"RESET=%s", (dev->need_reset ? "true" : "false"));
 		if ((buffer_size - length <= 0) || (i >= num_envp))
 			return -ENOMEM;
 	}
-#endif	
 	envp[i] = 0;
-	
+
 	return 0;
 }
 #endif
@@ -156,33 +168,56 @@
  * empty entry and initialize it to the given parameters, and create the proc
  * init entry via proc_init().
  */
-static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
-			      drm_device_t *dev)
+static int DRM(getminor)(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	int i;
+	struct class_device *dev_class;
+	drm_device_t *dev;
+	int ret;
+	int minor;
 
-	if (!DRM(stub_list)) {
-		DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list))
-					    * DRM_STUB_MAXCARDS, DRM_MEM_STUB);
-		if(!DRM(stub_list)) return -1;
-		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(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;
+	DRM_DEBUG("\n");
+
+	for (minor = 0; minor < DRM(global)->cards_limit; minor++) {
+		if (!DRM(global)->devices[minor]) {
+
+			dev = DRM(calloc)(1, sizeof(*dev), DRM_MEM_STUB);
+			if(!dev) 
+				return -ENOMEM;
+
+			dev->minor = minor;
+			if ((ret = DRM(fill_in_dev)(dev, pdev, ent))) {
+				printk (KERN_ERR "DRM: Fill_in_dev failed.\n");
+				goto err_g1;
+			}
+			if ((ret = DRM(proc_init)(dev, minor, DRM(global)->proc_root, &dev->dev_root))) {
+				printk (KERN_ERR "DRM: Failed to initialize /proc/dri.\n");
+				goto err_g1;
+			}
+			DRM(global)->devices[minor] = dev;
+
+			if (!DRM(fb_loaded))	/* set this before device_add hotplug uses it */
+				pci_set_drvdata(pdev, dev);
+
+			dev_class = class_simple_device_add(DRM(global)->drm_class, 
+					MKDEV(DRM_MAJOR, minor), &pdev->dev, "card%d", minor);
+			if (IS_ERR(dev_class)) {
+				printk (KERN_ERR "DRM: Error class_simple_device_add.\n");
+				ret = PTR_ERR(dev_class);
+				goto err_g2;
+			}
+			pci_enable_device(pdev);
+
+			DRM_DEBUG("new minor assigned %d\n", minor);
+			return 0;
 		}
 	}
-	return -1;
+	DRM_DEBUG("out of minors\n");
+	return -ENOMEM;
+err_g2:
+	class_simple_device_remove(MKDEV(DRM_MAJOR, minor));
+err_g1:
+	DRM(free)(dev, sizeof(*dev), DRM_MEM_STUB);
+	return ret;
 }
 
 /**
@@ -195,31 +230,37 @@
  * "drm" data, otherwise unregisters the "drm" data, frees the stub list and
  * unregisters the character device. 
  */
-static int DRM(stub_putminor)(int minor)
+int DRM(putminor)(drm_device_t *dev)
 {
-	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_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) {
-			DRM_DEBUG("inter_module_put called %d\n", *DRM(stub_info).info_count);
+	int i;
+	
+	DRM_DEBUG("release minor %d\n", dev->minor);
+
+	DRM(proc_cleanup)(dev->minor, DRM(global)->proc_root, dev->dev_root);
+	class_simple_device_remove(MKDEV(DRM_MAJOR, dev->minor));
+
+	DRM(global)->devices[dev->minor] = NULL;
+	DRM(free)(dev, sizeof(*dev), DRM_MEM_STUB);
+
+	/* if any device pointers are non-NULL we are not the last module */
+	for (i = 0; i < DRM(global)->cards_limit; i++) {
+		if (DRM(global)->devices[i]) {
+			DRM_DEBUG("inter_module_put called\n");
 			inter_module_put("drm");
+			return 0;
 		}
-	} else {
-		DRM_DEBUG("unregistering inter_module \n");
-		inter_module_unregister("drm");
-		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");
 	}
+	DRM_DEBUG("unregistering inter_module \n");
+	inter_module_unregister("drm");
+	remove_proc_entry("dri", NULL);
+	class_simple_destroy(DRM(global)->drm_class);
+	unregister_chrdev(DRM_MAJOR, "drm");
+
+	DRM(free)(DRM(global)->devices, sizeof(*DRM(global)->devices) *
+				DRM(global)->cards_limit, DRM_MEM_STUB);
+	DRM(free)(DRM(global), sizeof(*DRM(global)), DRM_MEM_STUB);
+	DRM(global) = NULL;
+
 	return 0;
 }
 
@@ -237,104 +278,71 @@
  *
  * Finally calls stub_info::info_register.
  */
-int DRM(stub_register)(const char *name, struct file_operations *fops,
-		       drm_device_t *dev)
+int DRM(probe)(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	struct drm_stub_info *i = NULL;
-	int ret1;
-	int ret2;
+	drm_global_t *global;
+	int ret = -ENOMEM;
 
 	DRM_DEBUG("\n");
 
-	/* if we are registering a second device we don't need to worry
-	   about inter module get/put and other things as they've been
-	   done already */
-	if (DRM(numdevs) == 0) {
-		/* use the inter_module_get to check - as if the same module
-		   registers chrdev twice it succeeds */
-		i = (struct drm_stub_info *)inter_module_get("drm");
-		if (i) {
-			/* Already registered */
-			DRM(stub_info).info_register   = i->info_register;
-			DRM(stub_info).info_unregister = i->info_unregister;
-			DRM(stub_info).drm_class = i->drm_class;
-			DRM(stub_info).info_count = i->info_count;
-			DRM_DEBUG("already registered %d\n", *i->info_count);
-		} else if (*DRM(stub_info).info_count == 0) {
-
-			ret1 = register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops));
-			if (ret1 < 0) {
-				printk (KERN_ERR "Error registering drm major number.\n");
-				return ret1;
-			}
+	/* use the inter_module_get to check - as if the same module
+		registers chrdev twice it succeeds */
+	global = (drm_global_t *)inter_module_get("drm");
+	if (global) {
+		DRM(global) = global;
+		global = NULL;
+	} else {
+		DRM_DEBUG("first probe\n");
 
-			DRM(stub_info).drm_class = class_simple_create(THIS_MODULE, "drm");
-			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);
+		global = DRM(calloc)(1, sizeof(*global), DRM_MEM_STUB);
+		if(!global) 
+			return -ENOMEM;
 
-			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;
-			}
-		
+		global->cards_limit = cards_limit;
+		global->devices = DRM(calloc)(global->cards_limit, 
+					sizeof(*global->devices), DRM_MEM_STUB);
+		if(!global->devices) 
+			goto err_p1;
+
+		ret = register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops));
+		if (ret < 0) {
+			printk (KERN_ERR "DRM: Error registering drm major number.\n");
+			goto err_p2;
 		}
-	} 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) {
-				inter_module_unregister("drm");
-				unregister_chrdev(DRM_MAJOR, "drm");
-				class_simple_destroy(DRM(stub_info).drm_class);
-				remove_proc_entry("dri", NULL);
-				DRM_DEBUG("info_register failed, deregistered everything\n");
-			}
-			DRM_DEBUG("info_register failed\n");
-			return ret2;
+		global->drm_class = class_simple_create(THIS_MODULE, "drm");
+		if (IS_ERR(global->drm_class)) {
+			printk (KERN_ERR "DRM: Error creating drm class.\n");
+			ret = PTR_ERR(global->drm_class);
+			goto err_p3;
 		}
-		class_simple_device_add(DRM(stub_info).drm_class, 
-				MKDEV(DRM_MAJOR, ret2), &dev->pdev->dev, "card%d", ret2);
-		return ret2;
-	}
-	return -1;
-}
+		class_simple_set_hotplug(global->drm_class, drm_hotplug);
 
-/**
- * Unregister.
- *
- * \param minor
- *
- * Calls drm_stub_info::unregister.
- */
-int DRM(stub_unregister)(int minor)
-{
-	DRM_DEBUG("%d\n", minor);
-	class_simple_device_remove(MKDEV(DRM_MAJOR, minor));
-	if (DRM(stub_info).info_unregister)
-		return DRM(stub_info).info_unregister(minor);
-	return -1;
+		global->proc_root = create_proc_entry("dri", S_IFDIR, NULL);
+		if (!global->proc_root) {
+			DRM_ERROR("Cannot create /proc/dri\n");
+			ret = -1;
+			goto err_p4;
+		}
+		DRM_DEBUG("calling inter_module_register\n");
+		inter_module_register("drm", THIS_MODULE, global);
+		
+		DRM(global) = global;
+	}
+	if ((ret = DRM(getminor)(pdev, ent))) {
+		if (global)
+			goto err_p4;
+		return ret;
+	}
+	return 0;
+err_p4:
+	class_simple_destroy(global->drm_class);
+err_p3:
+	unregister_chrdev(DRM_MAJOR, "drm");
+err_p2:
+	DRM(free)(global->devices, sizeof(*global->devices) * global->cards_limit, DRM_MEM_STUB);
+err_p1:	
+	DRM(free)(global, sizeof(*global), DRM_MEM_STUB);
+	DRM(global) = NULL;
+	return ret;
 }
-
-int DRM(stub_count);
-
-/** Stub information */
-struct drm_stub_info DRM(stub_info) = {
-	.info_register   = DRM(stub_getminor),
-	.info_unregister = DRM(stub_putminor),
-	.drm_class = NULL,
-	.info_count = &DRM(stub_count),
-	.proc_root = NULL,
-};

Reply via email to