patch-2.4.0-test4 linux/drivers/char/ppdev.c

Next file: linux/drivers/char/qpmouse.c
Previous file: linux/drivers/char/pcwd.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/ppdev.c linux/drivers/char/ppdev.c
@@ -52,6 +52,7 @@
 #include <linux/poll.h>
 #include <asm/uaccess.h>
 #include <linux/ppdev.h>
+#include <linux/smp_lock.h>
 
 #define PP_VERSION "ppdev: user-space parallel port driver"
 #define CHRDEV "ppdev"
@@ -83,64 +84,6 @@
 /* ROUND_UP macro from fs/select.c */
 #define ROUND_UP(x,y) (((x)+(y)-1)/(y))
 
-struct pp_port_list_struct {
-	struct parport *port;
-	struct pp_port_list_struct *next;
-};
-static struct pp_port_list_struct *pp_port_list;
-static DECLARE_MUTEX(pp_port_list_lock);
-
-/* pp_attach and pp_detach are for keeping a list of currently
- * available ports, held under a mutex.  We do this rather than
- * using parport_enumerate because it stops a load of races.
- */
-
-static void pp_attach (struct parport *port)
-{
-	struct pp_port_list_struct *add;
-
-	add = kmalloc (sizeof (struct pp_port_list_struct), GFP_KERNEL);
-	if (!add) {
-		printk (KERN_WARNING CHRDEV ": memory squeeze\n");
-		return;
-	}
-
-	add->port = port;
-	down (&pp_port_list_lock);
-	add->next = pp_port_list;
-	pp_port_list = add;
-	up (&pp_port_list_lock);
-}
-
-static void pp_detach (struct parport *port)
-{
-	struct pp_port_list_struct *del;
-
-	down (&pp_port_list_lock);
-	del = pp_port_list;
-	if (del->port == port)
-		pp_port_list = del->next;
-	else {
-		struct pp_port_list_struct *prev;
-		do {
-			prev = del;
-			del = del->next;
-		} while (del && del->port != port);
-		if (del)
-			prev->next = del->next;
-	}
-	up (&pp_port_list_lock);
-
-	if (del)
-		kfree (del);
-}
-
-static struct parport_driver ppdev_driver = {
-	name:	CHRDEV,
-	attach:	pp_attach,
-	detach:	pp_detach
-};
-
 static inline void pp_enable_irq (struct pp_struct *pp)
 {
 	struct parport *port = pp->pdev->port;
@@ -274,7 +217,7 @@
 
 static int register_device (int minor, struct pp_struct *pp)
 {
-	struct pp_port_list_struct *ports;
+	struct parport *port;
 	struct pardevice * pdev = NULL;
 	char *name;
 	int fl;
@@ -285,23 +228,17 @@
 
 	sprintf (name, CHRDEV "%x", minor);
 
-	down (&pp_port_list_lock);
-	ports = pp_port_list;
-	while (ports && ports->port->number != minor)
-		ports = ports->next;
-	if (ports->port) {
-		fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
-		pdev = parport_register_device (ports->port, name, NULL,
-						NULL, pp_irq, fl, pp);
-	}
-	up (&pp_port_list_lock);
-
-	if (!ports->port) {
+	port = parport_find_number (minor);
+	if (!port) {
 		printk (KERN_WARNING "%s: no associated port!\n", name);
 		kfree (name);
 		return -ENXIO;
 	}
 
+	fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
+	pdev = parport_register_device (port, name, NULL,
+					NULL, pp_irq, fl, pp);
+	parport_put_port (port);
 
 	if (!pdev) {
 		printk (KERN_WARNING "%s: failed to register device!\n", name);
@@ -595,6 +532,7 @@
 	unsigned int minor = MINOR (inode->i_rdev);
 	struct pp_struct *pp = file->private_data;
 
+	lock_kernel();
 	if (pp->pdev && pp->pdev->port->ieee1284.mode != IEEE1284_MODE_COMPAT) {
 		if (!(pp->flags & PP_CLAIMED)) {
 			parport_claim_or_block (pp->pdev);
@@ -620,6 +558,7 @@
 		printk (KERN_DEBUG CHRDEV "%x: unregistered pardevice\n",
 			minor);
 	}
+	unlock_kernel();
 
 	kfree (pp);
 
@@ -654,10 +593,6 @@
 
 static int __init ppdev_init (void)
 {
-	if (parport_register_driver (&ppdev_driver)) {
-		printk (KERN_WARNING CHRDEV ": unable to register driver\n");
-		return -EIO;
-	}
 	if (devfs_register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) {
 		printk (KERN_WARNING CHRDEV ": unable to get major %d\n",
 			PP_MAJOR);
@@ -678,7 +613,6 @@
 	/* Clean up all parport stuff */
 	devfs_unregister (devfs_handle);
 	devfs_unregister_chrdev (PP_MAJOR, CHRDEV);
-	parport_unregister_driver (&ppdev_driver);
 }
 
 module_init(ppdev_init);

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