Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
#include <linux/cdev.h>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
#include <linux/cdev.h>
+#include <linux/notifier.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <linux/moduleparam.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <linux/moduleparam.h>
.release = usbdev_release,
};
.release = usbdev_release,
};
-void usbdev_add(struct usb_device *dev)
+static void usbdev_add(struct usb_device *dev)
{
int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
{
int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
dev->class_dev->class_data = dev;
}
dev->class_dev->class_data = dev;
}
-void usbdev_remove(struct usb_device *dev)
+static void usbdev_remove(struct usb_device *dev)
{
class_device_unregister(dev->class_dev);
}
{
class_device_unregister(dev->class_dev);
}
+static int usbdev_notify(struct notifier_block *self, unsigned long action,
+ void *dev)
+{
+ switch (action) {
+ case USB_DEVICE_ADD:
+ usbdev_add(dev);
+ break;
+ case USB_DEVICE_REMOVE:
+ usbdev_remove(dev);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block usbdev_nb = {
+ .notifier_call = usbdev_notify,
+};
+
static struct cdev usb_device_cdev = {
.kobj = {.name = "usb_device", },
.owner = THIS_MODULE,
static struct cdev usb_device_cdev = {
.kobj = {.name = "usb_device", },
.owner = THIS_MODULE,
retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
if (retval) {
err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
if (retval) {
err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
- unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
- goto out;
}
usb_device_class = class_create(THIS_MODULE, "usb_device");
if (IS_ERR(usb_device_class)) {
err("unable to register usb_device class");
retval = PTR_ERR(usb_device_class);
}
usb_device_class = class_create(THIS_MODULE, "usb_device");
if (IS_ERR(usb_device_class)) {
err("unable to register usb_device class");
retval = PTR_ERR(usb_device_class);
- usb_device_class = NULL;
- cdev_del(&usb_device_cdev);
- unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+ usb_register_notify(&usbdev_nb);
+
+
+error_class:
+ usb_device_class = NULL;
+ cdev_del(&usb_device_cdev);
+
+error_cdev:
+ unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+ goto out;
}
void usbdev_cleanup(void)
{
}
void usbdev_cleanup(void)
{
+ usb_unregister_notify(&usbdev_nb);
class_destroy(usb_device_class);
cdev_del(&usb_device_cdev);
unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
class_destroy(usb_device_class);
cdev_del(&usb_device_cdev);
unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
dev_dbg (&udev->dev, "unregistering device\n");
release_address(udev);
usbfs_remove_device(udev);
dev_dbg (&udev->dev, "unregistering device\n");
release_address(udev);
usbfs_remove_device(udev);
usb_remove_sysfs_dev_files(udev);
/* Avoid races with recursively_mark_NOTATTACHED() */
usb_remove_sysfs_dev_files(udev);
/* Avoid races with recursively_mark_NOTATTACHED() */
usb_notify_add_device(udev);
/* add a /proc/bus/usb entry */
usb_notify_add_device(udev);
/* add a /proc/bus/usb entry */
usbfs_add_device(udev);
return 0;
usbfs_add_device(udev);
return 0;
extern int usbdev_init(void);
extern void usbdev_cleanup(void);
extern int usbdev_init(void);
extern void usbdev_cleanup(void);
-extern void usbdev_add(struct usb_device *dev);
-extern void usbdev_remove(struct usb_device *dev);
struct dev_state {
struct list_head list; /* state list */
struct dev_state {
struct list_head list; /* state list */