]> git.hungrycats.org Git - linux/commitdiff
USB: removed file ops from usb device structure
authorGreg Kroah-Hartman <greg@kroah.com>
Fri, 5 Jul 2002 07:30:41 +0000 (00:30 -0700)
committerGreg Kroah-Hartman <greg@kroah.com>
Fri, 5 Jul 2002 07:30:41 +0000 (00:30 -0700)
Moved the file ops and minor number stuff out of the usb structure,
Now usb_register_dev() and usb_deregister_dev() must be called if
you want to use the USB major number.

drivers/usb/core/Makefile
drivers/usb/core/file.c [new file with mode: 0644]
drivers/usb/core/inode.c
drivers/usb/core/usb.c
include/linux/usb.h

index 506dfecc19d2ab3c71d153561a9bed31b7eb54b0..11a56285c9eee82e4bb9cf6c7ae53f0f7ad9bc1f 100644 (file)
@@ -2,17 +2,17 @@
 # Makefile for USB Core files and filesystem
 #
 
-export-objs    := usb.o hcd.o hcd-pci.o urb.o message.o config.o
+export-objs    := usb.o hcd.o hcd-pci.o urb.o message.o config.o file.o
 
 usbcore-objs   := usb.o usb-debug.o hub.o hcd.o urb.o message.o \
-                       config.o
+                       config.o file.o
 
 ifeq ($(CONFIG_PCI),y)
        usbcore-objs    += hcd-pci.o
 endif
 
 ifeq ($(CONFIG_USB_DEVICEFS),y)
-       usbcore-objs    += devio.o inode.o drivers.o devices.o
+       usbcore-objs    += devio.o inode.o devices.o
 endif
 
 obj-$(CONFIG_USB)      += usbcore.o
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
new file mode 100644 (file)
index 0000000..eba43f1
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * drivers/usb/file.c
+ *
+ * (C) Copyright Linus Torvalds 1999
+ * (C) Copyright Johannes Erdfelt 1999-2001
+ * (C) Copyright Andreas Gal 1999
+ * (C) Copyright Gregory P. Smith 1999
+ * (C) Copyright Deti Fliegl 1999 (new USB architecture)
+ * (C) Copyright Randy Dunlap 2000
+ * (C) Copyright David Brownell 2000-2001 (kernel hotplug, usb_device_id,
+       more docs, etc)
+ * (C) Copyright Yggdrasil Computing, Inc. 2000
+ *     (usb_device_id matching changes by Adam J. Richter)
+ * (C) Copyright Greg Kroah-Hartman 2002
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+
+#ifdef CONFIG_USB_DEBUG
+       #define DEBUG
+#else
+       #undef DEBUG
+#endif
+#include <linux/usb.h>
+
+devfs_handle_t usb_devfs_handle;       /* /dev/usb dir. */
+EXPORT_SYMBOL(usb_devfs_handle);
+
+#define MAX_USB_MINORS 256
+static struct file_operations *usb_minors[MAX_USB_MINORS];
+static spinlock_t minor_lock = SPIN_LOCK_UNLOCKED;
+
+static int usb_open(struct inode * inode, struct file * file)
+{
+       int minor = minor(inode->i_rdev);
+       struct file_operations *c;
+       int err = -ENODEV;
+       struct file_operations *old_fops, *new_fops = NULL;
+
+       spin_lock (&minor_lock);
+       c = usb_minors[minor];
+       spin_unlock (&minor_lock);
+
+       if (!c || !(new_fops = fops_get(c)))
+               return err;
+       old_fops = file->f_op;
+       file->f_op = new_fops;
+       /* Curiouser and curiouser... NULL ->open() as "no device" ? */
+       if (file->f_op->open)
+               err = file->f_op->open(inode,file);
+       if (err) {
+               fops_put(file->f_op);
+               file->f_op = fops_get(old_fops);
+       }
+       fops_put(old_fops);
+       return err;
+}
+
+static struct file_operations usb_fops = {
+       owner:          THIS_MODULE,
+       open:           usb_open,
+};
+
+int usb_major_init(void)
+{
+       if (devfs_register_chrdev(USB_MAJOR, "usb", &usb_fops)) {
+               err("unable to get major %d for usb devices", USB_MAJOR);
+               return -EBUSY;
+       }
+
+       usb_devfs_handle = devfs_mk_dir(NULL, "usb", NULL);
+
+       return 0;
+}
+
+void usb_major_cleanup(void)
+{
+       devfs_unregister(usb_devfs_handle);
+       devfs_unregister_chrdev(USB_MAJOR, "usb");
+}
+
+/**
+ * usb_register_dev - register a USB device, and ask for a minor number
+ * @fops: the file operations for this USB device
+ * @minor: the requested starting minor for this device.
+ * @num_minors: number of minor numbers requested for this device
+ * @start_minor: place to put the new starting minor number
+ *
+ * This should be called by all USB drivers that use the USB major number.
+ * If CONFIG_USB_DYNAMIC_MINORS is enabled, the minor number will be
+ * dynamically allocated out of the list of available ones.  If it is not
+ * enabled, the minor number will be based on the next available free minor,
+ * starting at the requested @minor.
+ *
+ * usb_deregister_dev() must be called when the driver is done with
+ * the minor numbers given out by this function.
+ *
+ * Returns -EINVAL if something bad happens with trying to register a
+ * device, and 0 on success, alone with a value that the driver should
+ * use in start_minor.
+ */
+int usb_register_dev (struct file_operations *fops, int minor, int num_minors, int *start_minor)
+{
+       int i;
+       int j;
+       int good_spot;
+       int retval = -EINVAL;
+
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+       /* 
+        * We don't care what the device tries to start at, we want to start
+        * at zero to pack the devices into the smallest available space with
+        * no holes in the minor range.
+        */
+       minor = 0;
+#endif
+
+       dbg ("asking for %d minors, starting at %d", num_minors, minor);
+
+       if (fops == NULL)
+               goto exit;
+
+       *start_minor = 0; 
+       spin_lock (&minor_lock);
+       for (i = minor; 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;
+               dbg("found a minor chunk free, starting at %d", i);
+               for (i = *start_minor; i < (*start_minor + num_minors); ++i)
+                       usb_minors[i] = fops;
+
+               retval = 0;
+               goto exit;
+       }
+exit:
+       spin_unlock (&minor_lock);
+       return retval;
+}
+EXPORT_SYMBOL(usb_register_dev);
+
+/**
+ * usb_deregister_dev - deregister a USB device's dynamic minor.
+ * @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 (int num_minors, int start_minor)
+{
+       int i;
+
+       dbg ("removing %d minors starting at %d", num_minors, start_minor);
+
+       spin_lock (&minor_lock);
+       for (i = start_minor; i < (start_minor + num_minors); ++i)
+               usb_minors[i] = NULL;
+       spin_unlock (&minor_lock);
+}
+EXPORT_SYMBOL(usb_deregister_dev);
+
+
index 8d31640ff966349a80b2a5cebcbde53ded761e15..c637805a47053b71528ee392b5c20d7f6f0c7e72 100644 (file)
@@ -48,7 +48,6 @@ static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED;
 static int mount_count;        /* = 0 */
 
 static struct dentry *devices_dentry;
-static struct dentry *drivers_dentry;
 static int num_buses;  /* = 0 */
 
 static uid_t devuid;   /* = 0 */
@@ -548,16 +547,6 @@ static int create_special_files (void)
                return -ENODEV;
        }
 
-       drivers_dentry = fs_create_file ("drivers",
-                                        listmode | S_IFREG,
-                                        NULL, NULL,
-                                        &usbdevfs_drivers_fops,
-                                        listuid, listgid);
-       if (drivers_dentry == NULL) {
-               err ("Unable to create drivers usbfs file");
-               return -ENODEV;
-       }
-
        return 0;
 }
 
@@ -565,10 +554,7 @@ static void remove_special_files (void)
 {
        if (devices_dentry)
                fs_remove_file (devices_dentry);
-       if (drivers_dentry)
-               fs_remove_file (drivers_dentry);
        devices_dentry = NULL;
-       drivers_dentry = NULL;
        remove_mount();
 }
 
@@ -581,11 +567,6 @@ void usbfs_update_special (void)
                if (inode)
                        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        }
-       if (drivers_dentry) {
-               inode = devices_dentry->d_inode;
-               if (inode)
-                       inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-       }
 }
 
 void usbfs_add_bus(struct usb_bus *bus)
index 4842fbf0673785dca89dca942868c99dfca6d7f3..10591d54aebb370b67026f9ed62015f29d7d2028 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/interrupt.h>  /* for in_interrupt() */
 #include <linux/kmod.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 
@@ -45,6 +44,8 @@
 
 extern int  usb_hub_init(void);
 extern void usb_hub_cleanup(void);
+extern int usb_major_init(void);
+extern void usb_major_cleanup(void);
 
 /*
  * Prototypes for the device driver probing/loading functions
@@ -58,75 +59,23 @@ static void usb_check_support(struct usb_device *);
  */
 LIST_HEAD(usb_driver_list);
 
-devfs_handle_t usb_devfs_handle;       /* /dev/usb dir. */
-
-#define MAX_USB_MINORS 256
-static struct usb_driver *usb_minors[MAX_USB_MINORS];
-static spinlock_t minor_lock = SPIN_LOCK_UNLOCKED;
-
-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;
-
-       spin_lock (&minor_lock);
-       for (i = start_minor; i < (start_minor + num_minors); ++i)
-               if (usb_minors[i]) {
-                       spin_unlock (&minor_lock);
-                       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;
-
-       spin_unlock (&minor_lock);
-       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);
-
-       spin_lock (&minor_lock);
-       for (i = start_minor; i < (start_minor + num_minors); ++i)
-               usb_minors[i] = NULL;
-       spin_unlock (&minor_lock);
-}
 
 /**
- *     usb_register - register a USB driver
- *     @new_driver: USB operations for the driver
+ * usb_register - register a USB driver
+ * @new_driver: USB operations for the driver
  *
- *     Registers a USB driver with the USB core.  The list of unattached
- *     interfaces will be rescanned whenever a new driver is added, allowing
- *     the new driver to attach to any recognized devices.
- *     Returns a negative error code on failure and 0 on success.
+ * Registers a USB driver with the USB core.  The list of unattached
+ * interfaces will be rescanned whenever a new driver is added, allowing
+ * the new driver to attach to any recognized devices.
+ * Returns a negative error code on failure and 0 on success.
+ * 
+ * NOTE: if you want your driver to use the USB major number, you must call
+ * usb_register_dev() to enable that functionality.  This function no longer
+ * takes care of that.
  */
 int usb_register(struct usb_driver *new_driver)
 {
        int retval = 0;
-       
-       if ((new_driver->fops) && (new_driver->num_minors == 0)) {
-               err ("%s driver must specify num_minors", new_driver->name);
-               return -EINVAL;
-       }
-
-#ifndef CONFIG_USB_DYNAMIC_MINORS
-       if (new_driver->fops != NULL) {
-               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);
 
@@ -143,92 +92,6 @@ int usb_register(struct usb_driver *new_driver)
 }
 
 
-/**
- * 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 -ENODEV if CONFIG_USB_DYNAMIC_MINORS is not enabled in this
- * kernel, -EINVAL if something bad happens with trying to register a
- * device, 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;
-       int retval = -EINVAL;
-
-       dbg ("%s is asking for %d minors", new_driver->name, num_minors);
-
-       if (new_driver->fops == NULL)
-               goto exit;
-
-       *start_minor = 0; 
-       spin_lock (&minor_lock);
-       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;
-               spin_unlock (&minor_lock);
-               retval = usb_register_minors (new_driver, num_minors, *start_minor);
-               if (retval) {
-                       /* someone snuck in here, so let's start looking all over again */
-                       spin_lock (&minor_lock);
-                       i = 0;
-                       continue;
-               }
-               goto exit;
-       }
-       spin_unlock (&minor_lock);
-exit:
-       return retval;
-}
-
-/**
- * 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 ()
@@ -298,11 +161,15 @@ static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev)
 }
 
 /**
- *     usb_deregister - unregister a USB driver
- *     @driver: USB operations of the driver to unregister
- *     Context: !in_interrupt ()
+ * usb_deregister - unregister a USB driver
+ * @driver: USB operations of the driver to unregister
+ * Context: !in_interrupt ()
  *
- *     Unlinks the specified driver from the internal USB driver list.
+ * Unlinks the specified driver from the internal USB driver list.
+ * 
+ * NOTE: If you called usb_register_dev(), you still need to call
+ * usb_deregister_dev() to clean up your driver's allocated minor numbers,
+ * this * call will no longer do it for you.
  */
 void usb_deregister(struct usb_driver *driver)
 {
@@ -310,11 +177,6 @@ void usb_deregister(struct usb_driver *driver)
 
        info("deregistering driver %s", driver->name);
 
-#ifndef CONFIG_USB_DYNAMIC_MINORS
-       if (driver->fops != 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
         * another thread while we are stepping through removing entries
@@ -1357,55 +1219,6 @@ int usb_new_device(struct usb_device *dev)
        return 0;
 }
 
-static int usb_open(struct inode * inode, struct file * file)
-{
-       int minor = minor(inode->i_rdev);
-       struct usb_driver *c;
-       int err = -ENODEV;
-       struct file_operations *old_fops, *new_fops = NULL;
-
-       spin_lock (&minor_lock);
-       c = usb_minors[minor];
-       spin_unlock (&minor_lock);
-
-       if (!c || !(new_fops = fops_get(c->fops)))
-               return err;
-       old_fops = file->f_op;
-       file->f_op = new_fops;
-       /* Curiouser and curiouser... NULL ->open() as "no device" ? */
-       if (file->f_op->open)
-               err = file->f_op->open(inode,file);
-       if (err) {
-               fops_put(file->f_op);
-               file->f_op = fops_get(old_fops);
-       }
-       fops_put(old_fops);
-       return err;
-}
-
-static struct file_operations usb_fops = {
-       owner:          THIS_MODULE,
-       open:           usb_open,
-};
-
-int usb_major_init(void)
-{
-       if (devfs_register_chrdev(USB_MAJOR, "usb", &usb_fops)) {
-               err("unable to get major %d for usb devices", USB_MAJOR);
-               return -EBUSY;
-       }
-
-       usb_devfs_handle = devfs_mk_dir(NULL, "usb", NULL);
-
-       return 0;
-}
-
-void usb_major_cleanup(void)
-{
-       devfs_unregister(usb_devfs_handle);
-       devfs_unregister_chrdev(USB_MAJOR, "usb");
-}
-
 
 #ifdef CONFIG_PROC_FS
 struct list_head *usb_driver_get_list(void)
@@ -1463,11 +1276,6 @@ 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);
 EXPORT_SYMBOL(usb_get_dev);
@@ -1489,5 +1297,4 @@ EXPORT_SYMBOL(__usb_get_extra_descriptor);
 
 EXPORT_SYMBOL(usb_get_current_frame_number);
 
-EXPORT_SYMBOL(usb_devfs_handle);
 MODULE_LICENSE("GPL");
index d31eb7e942b3318486ed4a437f2e30b9e4e33d40..b1c39c99e75f7c5e3f47997b568352e698ad73b2 100644 (file)
 #include <linux/interrupt.h>   /* for in_interrupt() */
 #include <linux/list.h>                /* for struct list_head */
 #include <linux/device.h>      /* for struct device */
+#include <linux/fs.h>          /* for struct file_operations */
 
 
 static __inline__ void wait_ms(unsigned int ms)
@@ -648,14 +649,6 @@ struct usb_device_id {
  *     because its device has been (or is being) disconnected.  The
  *     handle passed is what was returned by probe(), or was provided
  *     to usb_driver_claim_interface().
- * @fops: USB drivers can reuse some character device framework in
- *     the USB subsystem by providing a file operations vector and
- *     a minor number.
- * @minor: Used with fops to simplify creating USB character devices.
- *     Such drivers have sixteen character devices, using the USB
- *     major number and starting with this minor number.
- * @num_minors: Used with minor to specify how many minors are used by
- *     this driver.
  * @ioctl: Used for drivers that want to talk to userspace through
  *     the "usbfs" filesystem.  This lets devices provide ways to
  *     expose information to user space regardless of where they
@@ -694,11 +687,6 @@ struct usb_driver {
            );
 
        struct list_head driver_list;
-
-       struct file_operations *fops;
-       int minor;
-       int num_minors;
-
        struct semaphore serialize;
 
        /* ioctl -- userspace apps can talk to drivers through usbfs */
@@ -722,13 +710,8 @@ extern struct bus_type usb_bus_type;
 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
+extern int usb_register_dev(struct file_operations *fops, int minor, int num_minors, int *start_minor);
+extern void usb_deregister_dev(int num_minors, int start_minor);
 
 /* -------------------------------------------------------------------------- */