ChangeSet 1.876, 2002/12/12 14:49:26-08:00, greg@kroah.com

[PATCH] USB: usb-skeleton: removed static array of devices.

This allowed a lock to be removed.
Also removed the MOD_* functions, and some remove logic was cleaned
up by Oliver Neukum.


diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c	Fri Dec 13 17:18:45 2002
+++ b/drivers/usb/usb-skeleton.c	Fri Dec 13 17:18:45 2002
@@ -1,5 +1,5 @@
 /*
- * USB Skeleton driver - 0.8
+ * USB Skeleton driver - 0.9
  *
  * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
  *
@@ -17,10 +17,10 @@
  *
  * TODO:
  *	- fix urb->status race condition in write sequence
- *	- move minor_table to a dynamic list.
  *
  * History:
  *
+ * 2002_12_12 - 0.9 - compile fixes and got rid of fixed minor array.
  * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device
  *			driver.
  * 2002_02_12 - 0.7 - zero out dev in probe function for devices that do
@@ -83,18 +83,10 @@
 
 
 #ifdef CONFIG_USB_DYNAMIC_MINORS
-/* 
- * if the user wants to use dynamic minor numbers, then we can have up to 256
- * devices
- */
 #define USB_SKEL_MINOR_BASE	0
-#define MAX_DEVICES		256
 #else
 /* Get a minor range for your devices from the usb maintainer */
 #define USB_SKEL_MINOR_BASE	200
-
-/* we can have up to this number of device plugged in at once */
-#define MAX_DEVICES		16
 #endif
 
 /* Structure to hold all of our device specific stuff */
@@ -117,8 +109,8 @@
 	struct urb *		write_urb;		/* the urb used to send data */
 	__u8			bulk_out_endpointAddr;	/* the address of the bulk out endpoint */
 
-	struct work_struct			work;			/* work queue entry for line discipline waking up */
-	int			open_count;		/* number of times this port has been opened */
+	struct work_struct	work;			/* work queue entry for line discipline waking up */
+	int			open;			/* if the port is open or not */
 	struct semaphore	sem;			/* locks this structure */
 };
 
@@ -139,13 +131,6 @@
 
 static void skel_write_bulk_callback	(struct urb *urb, struct pt_regs *regs);
 
-
-/* array of pointers to our devices that are currently connected */
-static struct usb_skel		*minor_table[MAX_DEVICES];
-
-/* lock to protect the minor_table structure */
-static DECLARE_MUTEX (minor_table_mutex);
-
 /*
  * File operations needed when we register this driver.
  * This assumes that this driver NEEDS file operations,
@@ -218,7 +203,6 @@
  */
 static inline void skel_delete (struct usb_skel *dev)
 {
-	minor_table[dev->minor] = NULL;
 	if (dev->bulk_in_buffer != NULL)
 		kfree (dev->bulk_in_buffer);
 	if (dev->bulk_out_buffer != NULL)
@@ -235,41 +219,31 @@
 static int skel_open (struct inode *inode, struct file *file)
 {
 	struct usb_skel *dev = NULL;
+	struct usb_interface *interface;
 	int subminor;
 	int retval = 0;
 	
 	dbg("%s", __FUNCTION__);
 
-	subminor = minor (inode->i_rdev) - USB_SKEL_MINOR_BASE;
-	if ((subminor < 0) ||
-	    (subminor >= MAX_DEVICES)) {
-		return -ENODEV;
-	}
+	subminor = minor (inode->i_rdev);
 
-	/* Increment our usage count for the module.
-	 * This is redundant here, because "struct file_operations"
-	 * has an "owner" field. This line is included here soley as
-	 * a reference for drivers using lesser structures... ;-)
-	 */
-	MOD_INC_USE_COUNT;
-
-	/* lock our minor table and get our local data for this minor */
-	down (&minor_table_mutex);
-	dev = minor_table[subminor];
-	if (dev == NULL) {
-		up (&minor_table_mutex);
-		MOD_DEC_USE_COUNT;
+	interface = usb_find_interface (&skel_driver,
+					mk_kdev(USB_MAJOR, subminor));
+	if (!interface) {
+		err ("%s - error, can't find device for minor %d",
+		     __FUNCTION__, subminor);
 		return -ENODEV;
 	}
+			
+	dev = dev_get_drvdata (&interface->dev);
+	if (!dev)
+		return -ENODEV;
 
 	/* lock this device */
 	down (&dev->sem);
 
-	/* unlock the minor table */
-	up (&minor_table_mutex);
-
 	/* increment our usage count for the driver */
-	++dev->open_count;
+	++dev->open;
 
 	/* save our object in the file's private structure */
 	file->private_data = dev;
@@ -297,13 +271,10 @@
 
 	dbg("%s - minor %d", __FUNCTION__, dev->minor);
 
-	/* lock our minor table */
-	down (&minor_table_mutex);
-
 	/* lock our device */
 	down (&dev->sem);
 
-	if (dev->open_count <= 0) {
+	if (dev->open <= 0) {
 		dbg ("%s - device not opened", __FUNCTION__);
 		retval = -ENODEV;
 		goto exit_not_opened;
@@ -313,25 +284,16 @@
 		/* the device was unplugged before the file was released */
 		up (&dev->sem);
 		skel_delete (dev);
-		up (&minor_table_mutex);
-		MOD_DEC_USE_COUNT;
 		return 0;
 	}
 
-	/* decrement our usage count for the device */
-	--dev->open_count;
-	if (dev->open_count <= 0) {
-		/* shutdown any bulk writes that might be going on */
-		usb_unlink_urb (dev->write_urb);
-		dev->open_count = 0;
-	}
+	/* shutdown any bulk writes that might be going on */
+	usb_unlink_urb (dev->write_urb);
 
-	/* decrement our usage count for the module */
-	MOD_DEC_USE_COUNT;
+	dev->open = 0;
 
 exit_not_opened:
 	up (&dev->sem);
-	up (&minor_table_mutex);
 
 	return retval;
 }
@@ -529,7 +491,6 @@
 		return -ENODEV;
 	}
 
-	down (&minor_table_mutex);
 	retval = usb_register_dev (&skel_fops, USB_SKEL_MINOR_BASE, 1, &minor);
 	if (retval) {
 		/* something prevented us from registering this driver */
@@ -544,7 +505,6 @@
 		goto exit_minor;
 	}
 	memset (dev, 0x00, sizeof (*dev));
-	minor_table[minor] = dev;
 
 	init_MUTEX (&dev->sem);
 	dev->udev = udev;
@@ -600,13 +560,17 @@
 	
 	dev->devfs = devfs_register (usb_devfs_handle, name,
 				     DEVFS_FL_DEFAULT, USB_MAJOR,
-				     USB_SKEL_MINOR_BASE + dev->minor,
+				     dev->minor,
 				     S_IFCHR | S_IRUSR | S_IWUSR | 
 				     S_IRGRP | S_IWGRP | S_IROTH, 
 				     &skel_fops, NULL);
 
 	/* let the user know what node this device is now attached to */
 	info ("USB Skeleton device now attached to USBSkel%d", dev->minor);
+
+	/* add device id so the device works when advertised */
+	interface->kdev = mk_kdev(USB_MAJOR, dev->minor);
+
 	goto exit;
 	
 error:
@@ -617,7 +581,6 @@
 	usb_deregister_dev (1, minor);
 
 exit:
-	up (&minor_table_mutex);
 	if (dev) {
 		dev_set_drvdata (&interface->dev, dev);
 		return 0;
@@ -642,9 +605,11 @@
 	if (!dev)
 		return;
 
-	down (&minor_table_mutex);
 	down (&dev->sem);
 		
+	/* remove device id to disable open() */
+	interface->kdev = NODEV;
+
 	minor = dev->minor;
 
 	/* remove our devfs node */
@@ -654,7 +619,7 @@
 	usb_deregister_dev (1, minor);
 	
 	/* if the device is not opened, then we clean up right now */
-	if (!dev->open_count) {
+	if (!dev->open) {
 		up (&dev->sem);
 		skel_delete (dev);
 	} else {
@@ -663,7 +628,6 @@
 	}
 
 	info("USB Skeleton #%d now disconnected", minor);
-	up (&minor_table_mutex);
 }
 
 
