Hi all,
Here's a patch that finishes off my previous patch that enabled us to
use less than 16 minor numbers per USB device that uses the USB major
number. This patch allows all such devices to share all 256 minor
numbers at once, much like the usbserial core shares the USB serial
major with all usb-serial drivers. This also solves Oliver's problem of
having 30 printers :)
Right now there isn't a "simple" way for userspace to realize what minor
is assigned to each device, but I will work on that tomorrow, as it's
late (hint, /sbin/hotplug will be involved :)
This patch is against 2.5.10.
Comments?
thanks,
greg k-h
diff -Nru a/drivers/usb/Config.help b/drivers/usb/Config.help
--- a/drivers/usb/Config.help Thu Apr 25 00:01:15 2002
+++ b/drivers/usb/Config.help Thu Apr 25 00:01:15 2002
@@ -69,3 +69,11 @@
If you say N here, these conditions will cause warning messages
about USB bandwidth usage to be logged and some devices or
drivers may not work correctly.
+
+CONFIG_USB_DYNAMIC_MINORS
+ If you say Y here, the USB subsystem will use dynamic minor
+ allocation for any device that uses the USB major number.
+ This means that you can have more than 16 of a single type
+ of device (like USB printers).
+
+ If you are unsure about this, say N here.
diff -Nru a/drivers/usb/class/printer.c b/drivers/usb/class/printer.c
--- a/drivers/usb/class/printer.c Thu Apr 25 00:01:15 2002
+++ b/drivers/usb/class/printer.c Thu Apr 25 00:01:15 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/core/Config.in b/drivers/usb/core/Config.in
--- a/drivers/usb/core/Config.in Thu Apr 25 00:01:15 2002
+++ b/drivers/usb/core/Config.in Thu Apr 25 00:01:15 2002
@@ -4,11 +4,8 @@
bool ' USB verbose debug messages' CONFIG_USB_DEBUG
comment 'Miscellaneous USB options'
-bool ' USB device filesystem' CONFIG_USB_DEVICEFS
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool ' Enforce USB bandwidth allocation (EXPERIMENTAL)' CONFIG_USB_BANDWIDTH
-else
- define_bool CONFIG_USB_BANDWIDTH n
-fi
-bool ' Long timeout for slow-responding devices (some MGE Ellipse UPSes)'
CONFIG_USB_LONG_TIMEOUT
+ bool ' USB device filesystem' CONFIG_USB_DEVICEFS
+ bool ' Long timeout for slow-responding devices (some MGE Ellipse UPSes)'
+CONFIG_USB_LONG_TIMEOUT
+dep_bool ' Enforce USB bandwidth allocation (EXPERIMENTAL)' CONFIG_USB_BANDWIDTH
+$CONFIG_EXPERIMENTAL
+dep_bool ' Dynamic USB minor allocation (EXPERIMENTAL)' CONFIG_USB_DYNAMIC_MINORS
+$CONFIG_EXPERIMENTAL
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c Thu Apr 25 00:01:15 2002
+++ b/drivers/usb/core/usb.c Thu Apr 25 00:01:15 2002
@@ -11,6 +11,7 @@
more docs, etc)
* (C) Copyright Yggdrasil Computing, Inc. 2000
* (usb_device_id matching changes by Adam J. Richter)
+ * (C) Copyright Greg Kroah-Hartman 2002
*
* NOTE! This is not actually a driver at all, rather this is
* just a collection of helper routines that implement the
@@ -59,7 +60,41 @@
devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */
-static struct usb_driver *usb_minors[256];
+#define MAX_USB_MINORS 256
+static struct usb_driver *usb_minors[MAX_USB_MINORS];
+
+
+static int usb_register_minors (struct usb_driver *driver, int num_minors, int
+start_minor)
+{
+ int i;
+
+ dbg("registering %d minors, starting at %d", num_minors, start_minor);
+
+ if (start_minor + num_minors >= MAX_USB_MINORS)
+ return -EINVAL;
+
+ for (i = start_minor; i < (start_minor + num_minors); ++i)
+ if (usb_minors[i]) {
+ err("minor %d is already in use, error registering %s driver",
+ i, driver->name);
+ return -EINVAL;
+ }
+
+ for (i = start_minor; i < (start_minor + num_minors); ++i)
+ usb_minors[i] = driver;
+ return 0;
+}
+
+static void usb_deregister_minors (struct usb_driver *driver, int num_minors, int
+start_minor)
+{
+ int i;
+
+ dbg ("%s is removing %d minors starting at %d", driver->name,
+ num_minors, start_minor);
+
+ for (i = start_minor; i < (start_minor + num_minors); ++i)
+ usb_minors[i] = NULL;
+}
/**
* usb_register - register a USB driver
@@ -72,18 +107,15 @@
*/
int usb_register(struct usb_driver *new_driver)
{
- int i;
-
+ int retval = 0;
+
+#ifndef CONFIG_USB_DYNAMIC_MINORS
if (new_driver->fops != NULL) {
- for (i = new_driver->minor; i < new_driver->minor +
new_driver->num_minors; ++i) {
- if (usb_minors[i]) {
- err("error registering %s driver", new_driver->name);
- return -EINVAL;
- }
- }
- for (i = new_driver->minor; i < new_driver->minor +
new_driver->num_minors; ++i)
- usb_minors[i] = new_driver;
+ retval = usb_register_minors (new_driver, new_driver->num_minors,
+new_driver->minor);
+ if (retval)
+ return retval;
}
+#endif
info("registered new driver %s", new_driver->name);
@@ -96,10 +128,83 @@
usbfs_update_special();
- return 0;
+ return retval;
+}
+
+
+/**
+ * usb_register_dev - register a USB device, and ask for a minor number
+ * @new_driver: USB operations for the driver
+ * @num_minors: number of minor numbers requested for this device
+ * @start_minor: place to put the new starting minor number
+ *
+ * Used to ask the USB core for a new minor number for a device that has
+ * just showed up. This is used to dynamically allocate minor numbers
+ * from the pool of USB reserved minor numbers.
+ *
+ * This should be called by all drivers that use the USB major number.
+ * This only returns a good value of CONFIG_USB_DYNAMIC_MINORS is
+ * selected by the user.
+ *
+ * usb_deregister_dev() should be called when the driver is done with
+ * the minor numbers given out by this function.
+ *
+ * Returns a negative error code on failure and 0 on success, alone with
+ * a value that the driver should use in start_minor.
+ */
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+int usb_register_dev (struct usb_driver *new_driver, int num_minors, int *start_minor)
+{
+ int i;
+ int j;
+ int good_spot;
+
+ dbg ("%s is asking for %d minors", new_driver->name, num_minors);
+
+ if (new_driver->fops == NULL)
+ return -EINVAL;
+
+ *start_minor = 0;
+ for (i = 0; i < MAX_USB_MINORS; ++i) {
+ if (usb_minors[i])
+ continue;
+
+ good_spot = 1;
+ for (j = 1; j <= num_minors-1; ++j)
+ if (usb_minors[i+j]) {
+ good_spot = 0;
+ break;
+ }
+ if (good_spot == 0)
+ continue;
+
+ *start_minor = i;
+ return usb_register_minors (new_driver, num_minors, *start_minor);
+ }
+ return -ENODEV;
}
/**
+ * usb_deregister_dev - deregister a USB device's dynamic minor.
+ * @driver: USB operations for the driver
+ * @num_minors: number of minor numbers to put back.
+ * @start_minor: the starting minor number
+ *
+ * Used in conjunction with usb_register_dev(). This function is called
+ * when the USB driver is finished with the minor numbers gotten from a
+ * call to usb_register_dev() (usually when the device is disconnected
+ * from the system.)
+ *
+ * This should be called by all drivers that use the USB major number.
+ */
+void usb_deregister_dev (struct usb_driver *driver, int num_minors, int start_minor)
+{
+ usb_deregister_minors (driver, num_minors, start_minor);
+}
+#endif /* CONFIG_USB_DYNAMIC_MINORS */
+
+
+/**
* usb_scan_devices - scans all unclaimed USB interfaces
* Context: !in_interrupt ()
*
@@ -177,12 +282,13 @@
void usb_deregister(struct usb_driver *driver)
{
struct list_head *tmp;
- int i;
info("deregistering driver %s", driver->name);
+
+#ifndef CONFIG_USB_DYNAMIC_MINORS
if (driver->fops != NULL)
- for (i = driver->minor; i < driver->minor + driver->num_minors; ++i)
- usb_minors[i] = NULL;
+ usb_deregister_minors (driver, driver->num_minors, driver->minor);
+#endif
/*
* first we remove the driver, to be sure it doesn't get used by
@@ -2622,6 +2728,11 @@
EXPORT_SYMBOL(usb_register);
EXPORT_SYMBOL(usb_deregister);
EXPORT_SYMBOL(usb_scan_devices);
+
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+EXPORT_SYMBOL(usb_register_dev);
+EXPORT_SYMBOL(usb_deregister_dev);
+#endif
EXPORT_SYMBOL(usb_alloc_dev);
EXPORT_SYMBOL(usb_free_dev);
diff -Nru a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
--- a/drivers/usb/image/mdc800.c Thu Apr 25 00:01:15 2002
+++ b/drivers/usb/image/mdc800.c Thu Apr 25 00:01:15 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 00:01:15 2002
+++ b/drivers/usb/image/scanner.c Thu Apr 25 00:01:15 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 00:01:15 2002
+++ b/drivers/usb/image/scanner.h Thu Apr 25 00:01:15 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 00:01:15 2002
+++ b/drivers/usb/input/hiddev.c Thu Apr 25 00:01:15 2002
@@ -25,8 +25,13 @@
* e-mail - mail your message to Paul Stewart <[EMAIL PROTECTED]>
*/
+#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
#include <linux/poll.h>
@@ -62,6 +67,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 +192,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 +614,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 00:01:15 2002
+++ b/drivers/usb/media/dabusb.c Thu Apr 25 00:01:15 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 00:01:15 2002
+++ b/drivers/usb/media/dabusb.h Thu Apr 25 00:01:15 2002
@@ -6,7 +6,11 @@
unsigned int pipe;
}bulk_transfer_t,*pbulk_transfer_t;
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define DABUSB_MINOR 256
+#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 00:01:15 2002
+++ b/drivers/usb/misc/auerswald.c Thu Apr 25 00:01:15 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 00:01:15 2002
+++ b/drivers/usb/misc/brlvger.c Thu Apr 25 00:01:15 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 00:01:15 2002
+++ b/drivers/usb/usb-skeleton.c Thu Apr 25 00:01:15 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 00:01:15 2002
+++ b/include/linux/brlvger.h Thu Apr 25 00:01:15 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
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h Thu Apr 25 00:01:15 2002
+++ b/include/linux/usb.h Thu Apr 25 00:01:15 2002
@@ -2,6 +2,7 @@
#define __LINUX_USB_H
#include <linux/device.h>
+#include <linux/errno.h>
/* USB constants */
@@ -558,6 +559,14 @@
*/
extern int usb_register(struct usb_driver *);
extern void usb_deregister(struct usb_driver *);
+
+#ifndef CONFIG_USB_DYNAMIC_MINORS
+static inline int usb_register_dev(struct usb_driver *new_driver, int num_minors, int
+*start_minor) { return -ENODEV; }
+static inline void usb_deregister_dev(struct usb_driver *driver, int num_minors, int
+start_minor) {}
+#else
+extern int usb_register_dev(struct usb_driver *new_driver, int num_minors, int
+*start_minor);
+extern void usb_deregister_dev(struct usb_driver *driver, int num_minors, int
+start_minor);
+#endif
/* -------------------------------------------------------------------------- */
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel