patch-2.3.99-pre3 linux/drivers/char/misc.c

Next file: linux/drivers/char/rtc.c
Previous file: linux/drivers/char/busmouse.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre2/linux/drivers/char/misc.c linux/drivers/char/misc.c
@@ -57,6 +57,7 @@
  * Head entry for the doubly linked miscdevice list
  */
 static struct miscdevice misc_list = { 0, "head", NULL, &misc_list, &misc_list };
+static DECLARE_MUTEX(misc_sem);
 
 /*
  * Assigned numbers, used for dynamic minors
@@ -96,32 +97,42 @@
 static int misc_open(struct inode * inode, struct file * file)
 {
 	int minor = MINOR(inode->i_rdev);
-	struct miscdevice *c = misc_list.next;
+	struct miscdevice *c;
+	int err = -ENODEV;
+	
 	file->f_op = NULL;
+	
+	down(&misc_sem);
+	
+	c = misc_list.next;
 
 	while ((c != &misc_list) && (c->minor != minor))
 		c = c->next;
 	if (c == &misc_list) {
 		char modname[20];
+		up(&misc_sem);
 		sprintf(modname, "char-major-%d-%d", MISC_MAJOR, minor);
 		request_module(modname);
+		down(&misc_sem);
 		c = misc_list.next;
 		while ((c != &misc_list) && (c->minor != minor))
 			c = c->next;
 		if (c == &misc_list)
-			return -ENODEV;
+			goto fail;
 	}
 
 	if ((file->f_op = c->fops) && file->f_op->open)
-		return file->f_op->open(inode,file);
-	else
-		return -ENODEV;
+		err=file->f_op->open(inode,file);
+fail:
+	up(&misc_sem);
+	return err;
 }
 
 static struct file_operations misc_fops = {
 	open:		misc_open,
 };
 
+
 /**
  *	misc_register	-	register a miscellaneous device
  *	@misc: device structure
@@ -144,12 +155,17 @@
 
 	if (misc->next || misc->prev)
 		return -EBUSY;
+	down(&misc_sem);
 	if (misc->minor == MISC_DYNAMIC_MINOR) {
 		int i = DYNAMIC_MINORS;
 		while (--i >= 0)
 			if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
 				break;
-		if (i<0) return -EBUSY;
+		if (i<0)
+		{
+			up(&misc_sem);
+			return -EBUSY;
+		}
 		misc->minor = i;
 	}
 	if (misc->minor < DYNAMIC_MINORS)
@@ -170,6 +186,7 @@
 	misc->next = misc_list.next;
 	misc->prev->next = misc;
 	misc->next->prev = misc;
+	up(&misc_sem);
 	return 0;
 }
 
@@ -188,6 +205,7 @@
 	int i = misc->minor;
 	if (!misc->next || !misc->prev)
 		return -EINVAL;
+	down(&misc_sem);
 	misc->prev->next = misc->next;
 	misc->next->prev = misc->prev;
 	misc->next = NULL;
@@ -196,6 +214,7 @@
 	if (i < DYNAMIC_MINORS && i>0) {
 		misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
 	}
+	up(&misc_sem);
 	return 0;
 }
 
@@ -205,9 +224,6 @@
 int __init misc_init(void)
 {
 	create_proc_read_entry("misc", 0, 0, misc_read_proc, NULL);
-#ifdef CONFIG_BUSMOUSE
-	bus_mouse_init();
-#endif
 #if defined CONFIG_82C710_MOUSE
 	qpmouse_init();
 #endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)