# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.562   -> 1.563  
#	drivers/usb/image/mdc800.c	1.16    -> 1.17   
#	drivers/usb/media/dabusb.h	1.4     -> 1.5    
#	drivers/usb/class/printer.c	1.20    -> 1.21   
#	drivers/usb/image/scanner.c	1.18    -> 1.19   
#	include/linux/brlvger.h	1.2     -> 1.3    
#	drivers/usb/image/scanner.h	1.14    -> 1.15   
#	drivers/usb/misc/auerswald.c	1.11    -> 1.12   
#	drivers/usb/input/hiddev.c	1.10    -> 1.11   
#	drivers/usb/usb-skeleton.c	1.10    -> 1.11   
#	drivers/usb/misc/brlvger.c	1.1     -> 1.2    
#	drivers/usb/media/dabusb.c	1.14    -> 1.15   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/04/25	greg@kroah.com	1.563
# added support for USB_DYNAMIC_MINORS to the usb drivers that can use it.
# --------------------------------------------
#
diff -Nru a/drivers/usb/class/printer.c b/drivers/usb/class/printer.c
--- a/drivers/usb/class/printer.c	Thu Apr 25 16:26:53 2002
+++ b/drivers/usb/class/printer.c	Thu Apr 25 16:26:53 2002
@@ -107,7 +107,11 @@
 #define USBLP_REQ_RESET				0x02
 #define USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST	0x00	/* HP Vendor-specific */
 
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define USBLP_MINORS		256
+#else
 #define USBLP_MINORS		16
+#endif
 #define USBLP_MINOR_BASE	0
 
 #define USBLP_WRITE_TIMEOUT	(5*HZ)			/* 5 seconds */
@@ -208,6 +212,8 @@
 static int usblp_set_protocol(struct usblp *usblp, int protocol);
 static int usblp_cache_device_id_string(struct usblp *usblp);
 
+/* forward reference to make our lives easier */
+extern struct usb_driver usblp_driver;
 
 /*
  * Functions for usblp control messages.
@@ -366,6 +372,7 @@
 {
 	devfs_unregister (usblp->devfs);
 	usblp_table [usblp->minor] = NULL;
+	usb_deregister_dev (&usblp_driver, 1, usblp->minor);
 	info("usblp%d: removed", usblp->minor);
 
 	kfree (usblp->writeurb->transfer_buffer);
@@ -801,12 +808,14 @@
 	init_waitqueue_head(&usblp->wait);
 	usblp->ifnum = ifnum;
 
-	/* Look for a free usblp_table entry. */
-	while (usblp_table[usblp->minor]) {
-		usblp->minor++;
-		if (usblp->minor >= USBLP_MINORS) {
-			err("no more free usblp devices");
-			goto abort;
+	if (usb_register_dev(&usblp_driver, 1, &usblp->minor)) {
+		/* Look for a free usblp_table entry on our own. */
+		while (usblp_table[usblp->minor]) {
+			usblp->minor++;
+			if (usblp->minor >= USBLP_MINORS) {
+				err("no more free usblp devices");
+				goto abort;
+			}
 		}
 	}
 
diff -Nru a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
--- a/drivers/usb/image/mdc800.c	Thu Apr 25 16:26:53 2002
+++ b/drivers/usb/image/mdc800.c	Thu Apr 25 16:26:53 2002
@@ -119,8 +119,12 @@
 #define TO_READ_FROM_IRQ 		TO_DEFAULT_COMMAND
 #define TO_GET_READY			TO_DEFAULT_COMMAND
 
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define MDC800_DEVICE_MINOR_BASE 0
+#else
 /* Minor Number of the device (create with mknod /dev/mustek c 180 32) */
 #define MDC800_DEVICE_MINOR_BASE 32
+#endif
 
 
 /**************************************************************************
@@ -176,6 +180,7 @@
 
 	int			pic_index;	// Cache for the Imagesize (-1 for nothing cached )
 	int			pic_len;
+	int			minor;
 };
 
 
@@ -470,6 +475,8 @@
 
 	down (&mdc800->io_lock);
 
+	usb_register_dev (&mdc800_usb_driver, 1, &mdc800->minor);
+
 	mdc800->dev=dev;
 	mdc800->open=0;
 
@@ -525,6 +532,8 @@
 	if (mdc800->state == NOT_CONNECTED)
 		return;
 	
+	usb_deregister_dev (&mdc800_usb_driver, 1, mdc800->minor);
+
 	mdc800->state=NOT_CONNECTED;
 
 	usb_unlink_urb (mdc800->irq_urb);
diff -Nru a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c
--- a/drivers/usb/image/scanner.c	Thu Apr 25 16:26:53 2002
+++ b/drivers/usb/image/scanner.c	Thu Apr 25 16:26:53 2002
@@ -953,9 +953,11 @@
 	
 	down(&scn_mutex);
 
-	for (scn_minor = 0; scn_minor < SCN_MAX_MNR; scn_minor++) {
-		if (!p_scn_table[scn_minor])
-			break;
+	if (usb_register_dev(&scanner_driver, 1, &scn_minor)) {
+		for (scn_minor = 0; scn_minor < SCN_MAX_MNR; scn_minor++) {
+			if (!p_scn_table[scn_minor])
+				break;
+		}
 	}
 
 /* Check to make sure that the last slot isn't already taken */
@@ -1086,6 +1088,7 @@
 
 	dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor);
 	devfs_unregister(scn->devfs);
+	usb_deregister_dev(&scanner_driver, 1, scn->scn_minor);
 	p_scn_table[scn->scn_minor] = NULL;
 	usb_free_urb(scn->scn_irq);
 	up (&(scn->sem));
diff -Nru a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h
--- a/drivers/usb/image/scanner.h	Thu Apr 25 16:26:53 2002
+++ b/drivers/usb/image/scanner.h	Thu Apr 25 16:26:53 2002
@@ -233,8 +233,13 @@
 #define SCANNER_IOCTL_CTRLMSG _IOWR('U', 0x22, struct usb_ctrlrequest)
 
 
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define SCN_MAX_MNR 256
+#define SCN_BASE_MNR 0
+#else
 #define SCN_MAX_MNR 16		/* We're allocated 16 minors */
 #define SCN_BASE_MNR 48		/* USB Scanners start at minor 48 */
+#endif
 
 static DECLARE_MUTEX (scn_mutex); /* Initializes to unlocked */
 
diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	Thu Apr 25 16:26:53 2002
+++ b/drivers/usb/input/hiddev.c	Thu Apr 25 16:26:53 2002
@@ -25,10 +25,7 @@
  * e-mail - mail your message to Paul Stewart <stewart@wetlogic.net>
  */
 
-#define HIDDEV_MINOR_BASE	96
-#define HIDDEV_MINORS		16
-#define HIDDEV_BUFFER_SIZE	64
-
+#include <linux/config.h>
 #include <linux/poll.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -39,6 +36,15 @@
 #include "hid.h"
 #include <linux/hiddev.h>
 
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define HIDDEV_MINOR_BASE	0
+#define HIDDEV_MINORS		256
+#else
+#define HIDDEV_MINOR_BASE	96
+#define HIDDEV_MINORS		16
+#endif
+#define HIDDEV_BUFFER_SIZE	64
+
 struct hiddev {
 	int exist;
 	int open;
@@ -62,6 +68,9 @@
 static struct hiddev *hiddev_table[HIDDEV_MINORS];
 static devfs_handle_t hiddev_devfs_handle;
 
+/* forward reference to make our lives easier */
+extern struct usb_driver hiddev_driver;
+
 /*
  * Find a report, given the report's type and ID.  The ID can be specified
  * indirectly by REPORT_ID_FIRST (which returns the first report of the given
@@ -184,6 +193,7 @@
 static void hiddev_cleanup(struct hiddev *hiddev)
 {
 	devfs_unregister(hiddev->devfs);
+	usb_deregister_dev(&hiddev_driver, 1, hiddev->minor);
 	hiddev_table[hiddev->minor] = NULL;
 	kfree(hiddev);
 }
@@ -605,10 +615,12 @@
 	if (i == hid->maxapplication)
 		return -1;
 
-	for (minor = 0; minor < HIDDEV_MINORS && hiddev_table[minor]; minor++);
-	if (minor == HIDDEV_MINORS) {
-		printk(KERN_ERR "hiddev: no more free hiddev devices\n");
-		return -1;
+	if (usb_register_dev (&hiddev_driver, 1, &minor)) {
+		for (minor = 0; minor < HIDDEV_MINORS && hiddev_table[minor]; minor++);
+		if (minor == HIDDEV_MINORS) {
+			printk(KERN_ERR "hiddev: no more free hiddev devices\n");
+			return -1;
+		}
 	}
 
 	if (!(hiddev = kmalloc(sizeof(struct hiddev), GFP_KERNEL)))
diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
--- a/drivers/usb/media/dabusb.c	Thu Apr 25 16:26:53 2002
+++ b/drivers/usb/media/dabusb.c	Thu Apr 25 16:26:53 2002
@@ -52,12 +52,17 @@
 
 /* --------------------------------------------------------------------- */
 
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define NRDABUSB 256
+#else
 #define NRDABUSB 4
+#endif
 
 /*-------------------------------------------------------------------*/
 
 static dabusb_t dabusb[NRDABUSB];
 static int buffers = 256;
+extern struct usb_driver dabusb_driver;
 
 /*-------------------------------------------------------------------*/
 
@@ -734,15 +739,18 @@
 	if (ifnum != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999)
 		return NULL;
 
-	devnum = dabusb_find_struct ();
-	if (devnum == -1)
-		return NULL;
+	if (usb_register_dev (&dabusb_driver, 1, &devnum)) {
+		devnum = dabusb_find_struct ();
+		if (devnum == -1)
+			return NULL;
+	}
 
 	s = &dabusb[devnum];
 
 	down (&s->mutex);
 	s->remove_pending = 0;
 	s->usbdev = usbdev;
+	s->devnum = devnum;
 
 	if (usb_set_configuration (usbdev, usbdev->config[0].bConfigurationValue) < 0) {
 		err("set_configuration failed");
@@ -777,6 +785,7 @@
 
 	dbg("dabusb_disconnect");
 
+	usb_deregister_dev (&dabusb_driver, 1, s->devnum);
 	s->remove_pending = 1;
 	wake_up (&s->wait);
 	if (s->state == _started)
diff -Nru a/drivers/usb/media/dabusb.h b/drivers/usb/media/dabusb.h
--- a/drivers/usb/media/dabusb.h	Thu Apr 25 16:26:53 2002
+++ b/drivers/usb/media/dabusb.h	Thu Apr 25 16:26:53 2002
@@ -6,7 +6,11 @@
 	unsigned int pipe;
 }bulk_transfer_t,*pbulk_transfer_t;
 
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define DABUSB_MINOR 0
+#else
 #define DABUSB_MINOR 240		/* some unassigned USB minor */
+#endif
 #define DABUSB_VERSION 0x1000
 #define IOCTL_DAB_BULK              _IOWR('d', 0x30, bulk_transfer_t)
 #define IOCTL_DAB_OVERRUNS	    _IOR('d',  0x15, int)
@@ -31,6 +35,7 @@
 	unsigned int overruns;
 	int readptr;
 	int opened;
+	int devnum;
 	struct list_head free_buff_list;
 	struct list_head rec_buff_list;
 } dabusb_t,*pdabusb_t;
diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
--- a/drivers/usb/misc/auerswald.c	Thu Apr 25 16:26:53 2002
+++ b/drivers/usb/misc/auerswald.c	Thu Apr 25 16:26:53 2002
@@ -60,12 +60,17 @@
 /* Auerswald Vendor ID */
 #define ID_AUERSWALD  	0x09BF
 
-#ifndef AUER_MINOR_BASE		/* allow external override */
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+/* we can have up to 256 devices at once */
+#define AUER_MINOR_BASE	0
+#define AUER_MAX_DEVICES 256
+#else
 #define AUER_MINOR_BASE	112	/* auerswald driver minor number */
-#endif
 
 /* we can have up to this number of device plugged in at once */
 #define AUER_MAX_DEVICES 16
+#endif
+
 
 /* prefix for the device descriptors in /dev/usb */
 #define AU_PREFIX	"auer"
@@ -284,6 +289,7 @@
 /* Forwards */
 static void auerswald_ctrlread_complete (struct urb * urb);
 static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp);
+extern struct usb_driver auerswald_driver;
 
 
 /*-------------------------------------------------------------------*/
@@ -1941,16 +1947,18 @@
         auerbuf_init (&cp->bufctl);
 	init_waitqueue_head (&cp->bufferwait);
 
-	/* find a free slot in the device table */
 	down (&dev_table_mutex);
-	for (dtindex = 0; dtindex < AUER_MAX_DEVICES; ++dtindex) {
-		if (dev_table[dtindex] == NULL)
-			break;
-	}
-	if ( dtindex >= AUER_MAX_DEVICES) {
-		err ("more than %d devices plugged in, can not handle this device", AUER_MAX_DEVICES);
-		up (&dev_table_mutex);
-		goto pfail;
+	if (usb_register_dev (&auerswald_driver, 1, &dtindex)) {
+		/* find a free slot in the device table */
+		for (dtindex = 0; dtindex < AUER_MAX_DEVICES; ++dtindex) {
+			if (dev_table[dtindex] == NULL)
+				break;
+		}
+		if ( dtindex >= AUER_MAX_DEVICES) {
+			err ("more than %d devices plugged in, can not handle this device", AUER_MAX_DEVICES);
+			up (&dev_table_mutex);
+			goto pfail;
+		}
 	}
 
 	/* Give the device a name */
@@ -2080,6 +2088,9 @@
 	/* remove our devfs node */
 	/* Nobody can see this device any more */
 	devfs_unregister (cp->devfs);
+
+	/* give back our USB minor number */
+	usb_deregister_dev (&auerswald_driver, 1, cp->dtindex);
 
 	/* Stop the interrupt endpoint */
 	auerswald_int_release (cp);
diff -Nru a/drivers/usb/misc/brlvger.c b/drivers/usb/misc/brlvger.c
--- a/drivers/usb/misc/brlvger.c	Thu Apr 25 16:26:53 2002
+++ b/drivers/usb/misc/brlvger.c	Thu Apr 25 16:26:53 2002
@@ -315,14 +315,16 @@
 
 	down(&reserve_sem);
 
-	for( i = 0; i < MAX_NR_BRLVGER_DEVS; i++ )
-		if( display_table[i] == NULL )
-			break;
-
-	if( i == MAX_NR_BRLVGER_DEVS ) {
-		err( "This driver cannot handle more than %d "
-				"braille displays", MAX_NR_BRLVGER_DEVS);
-		goto error;
+	if (usb_register_dev(&brlvger_driver, 1, &i)) {
+		for( i = 0; i < MAX_NR_BRLVGER_DEVS; i++ )
+			if( display_table[i] == NULL )
+				break;
+
+		if( i == MAX_NR_BRLVGER_DEVS ) {
+			err( "This driver cannot handle more than %d "
+					"braille displays", MAX_NR_BRLVGER_DEVS);
+			goto error;
+		}
 	}
 
 	if( !(priv = kmalloc (sizeof *priv, GFP_KERNEL)) ){
@@ -423,7 +425,8 @@
 		info("Display %d disconnecting", priv->subminor);
 
 		devfs_unregister(priv->devfs);
-		
+		usb_deregister_dev(&brlvger_driver, 1, priv->subminor);
+
 		down(&disconnect_sem);
 		display_table[priv->subminor] = NULL;
 		up(&disconnect_sem);
diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c	Thu Apr 25 16:26:53 2002
+++ b/drivers/usb/usb-skeleton.c	Thu Apr 25 16:26:53 2002
@@ -85,12 +85,20 @@
 MODULE_DEVICE_TABLE (usb, skel_table);
 
 
-
+#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	
+#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 */
 struct usb_skel {
@@ -192,9 +200,6 @@
 };
 
 
-
-
-
 /**
  *	usb_skel_debug_data
  */
@@ -529,15 +534,17 @@
 		return NULL;
 	}
 
-	/* select a "subminor" number (part of a minor number) */
 	down (&minor_table_mutex);
-	for (minor = 0; minor < MAX_DEVICES; ++minor) {
-		if (minor_table[minor] == NULL)
-			break;
-	}
-	if (minor >= MAX_DEVICES) {
-		info ("Too many devices plugged in, can not handle this device.");
-		goto exit;
+	if (usb_register_dev (&skel_driver, 1, &minor)) {
+		/* we could not get a dynamic minor, so lets find one of our own */
+		for (minor = 0; minor < MAX_DEVICES; ++minor) {
+			if (minor_table[minor] == NULL)
+				break;
+		}
+		if (minor >= MAX_DEVICES) {
+			info ("Too many devices plugged in, can not handle this device.");
+			goto exit;
+		}
 	}
 
 	/* allocate memory for our device state and intialize it */
@@ -642,8 +649,11 @@
 	minor = dev->minor;
 
 	/* remove our devfs node */
-	devfs_unregister(dev->devfs);
+	devfs_unregister (dev->devfs);
 
+	/* give back our dynamic minor */
+	usb_deregister_dev (&skel_driver, 1, minor);
+	
 	/* if the device is not opened, then we clean up right now */
 	if (!dev->open_count) {
 		up (&dev->sem);
diff -Nru a/include/linux/brlvger.h b/include/linux/brlvger.h
--- a/include/linux/brlvger.h	Thu Apr 25 16:26:53 2002
+++ b/include/linux/brlvger.h	Thu Apr 25 16:26:53 2002
@@ -30,11 +30,16 @@
 #define BRLVGER_DISPLAY_OFF	3
 #define BRLVGER_BUZZ		4
 
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define MAX_NR_BRLVGER_DEVS	256
+#define BRLVGER_MINOR		0
+#else
 /* Number of supported devices, and range of covered minors */
 #define MAX_NR_BRLVGER_DEVS	4
 
 /* Base minor for the char devices */
 #define BRLVGER_MINOR		128
+#endif
 
 /* Size of some fields */
 #define BRLVGER_HWVER_SIZE	2
