diff options
-rw-r--r-- | drivers/usb/core/devio.c | 41 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 2 |
3 files changed, 34 insertions, 11 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 9222b7a13430..2bd742ba812d 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/usb.h> | 46 | #include <linux/usb.h> |
47 | #include <linux/usbdevice_fs.h> | 47 | #include <linux/usbdevice_fs.h> |
48 | #include <linux/cdev.h> | 48 | #include <linux/cdev.h> |
49 | #include <linux/notifier.h> | ||
49 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
50 | #include <asm/byteorder.h> | 51 | #include <asm/byteorder.h> |
51 | #include <linux/moduleparam.h> | 52 | #include <linux/moduleparam.h> |
@@ -1550,7 +1551,7 @@ struct file_operations usbfs_device_file_operations = { | |||
1550 | .release = usbdev_release, | 1551 | .release = usbdev_release, |
1551 | }; | 1552 | }; |
1552 | 1553 | ||
1553 | void usbdev_add(struct usb_device *dev) | 1554 | static void usbdev_add(struct usb_device *dev) |
1554 | { | 1555 | { |
1555 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); | 1556 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); |
1556 | 1557 | ||
@@ -1561,11 +1562,29 @@ void usbdev_add(struct usb_device *dev) | |||
1561 | dev->class_dev->class_data = dev; | 1562 | dev->class_dev->class_data = dev; |
1562 | } | 1563 | } |
1563 | 1564 | ||
1564 | void usbdev_remove(struct usb_device *dev) | 1565 | static void usbdev_remove(struct usb_device *dev) |
1565 | { | 1566 | { |
1566 | class_device_unregister(dev->class_dev); | 1567 | class_device_unregister(dev->class_dev); |
1567 | } | 1568 | } |
1568 | 1569 | ||
1570 | static int usbdev_notify(struct notifier_block *self, unsigned long action, | ||
1571 | void *dev) | ||
1572 | { | ||
1573 | switch (action) { | ||
1574 | case USB_DEVICE_ADD: | ||
1575 | usbdev_add(dev); | ||
1576 | break; | ||
1577 | case USB_DEVICE_REMOVE: | ||
1578 | usbdev_remove(dev); | ||
1579 | break; | ||
1580 | } | ||
1581 | return NOTIFY_OK; | ||
1582 | } | ||
1583 | |||
1584 | static struct notifier_block usbdev_nb = { | ||
1585 | .notifier_call = usbdev_notify, | ||
1586 | }; | ||
1587 | |||
1569 | static struct cdev usb_device_cdev = { | 1588 | static struct cdev usb_device_cdev = { |
1570 | .kobj = {.name = "usb_device", }, | 1589 | .kobj = {.name = "usb_device", }, |
1571 | .owner = THIS_MODULE, | 1590 | .owner = THIS_MODULE, |
@@ -1585,24 +1604,32 @@ int __init usbdev_init(void) | |||
1585 | retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX); | 1604 | retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX); |
1586 | if (retval) { | 1605 | if (retval) { |
1587 | err("unable to get usb_device major %d", USB_DEVICE_MAJOR); | 1606 | err("unable to get usb_device major %d", USB_DEVICE_MAJOR); |
1588 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | 1607 | goto error_cdev; |
1589 | goto out; | ||
1590 | } | 1608 | } |
1591 | usb_device_class = class_create(THIS_MODULE, "usb_device"); | 1609 | usb_device_class = class_create(THIS_MODULE, "usb_device"); |
1592 | if (IS_ERR(usb_device_class)) { | 1610 | if (IS_ERR(usb_device_class)) { |
1593 | err("unable to register usb_device class"); | 1611 | err("unable to register usb_device class"); |
1594 | retval = PTR_ERR(usb_device_class); | 1612 | retval = PTR_ERR(usb_device_class); |
1595 | usb_device_class = NULL; | 1613 | goto error_class; |
1596 | cdev_del(&usb_device_cdev); | ||
1597 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | ||
1598 | } | 1614 | } |
1599 | 1615 | ||
1616 | usb_register_notify(&usbdev_nb); | ||
1617 | |||
1600 | out: | 1618 | out: |
1601 | return retval; | 1619 | return retval; |
1620 | |||
1621 | error_class: | ||
1622 | usb_device_class = NULL; | ||
1623 | cdev_del(&usb_device_cdev); | ||
1624 | |||
1625 | error_cdev: | ||
1626 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | ||
1627 | goto out; | ||
1602 | } | 1628 | } |
1603 | 1629 | ||
1604 | void usbdev_cleanup(void) | 1630 | void usbdev_cleanup(void) |
1605 | { | 1631 | { |
1632 | usb_unregister_notify(&usbdev_nb); | ||
1606 | class_destroy(usb_device_class); | 1633 | class_destroy(usb_device_class); |
1607 | cdev_del(&usb_device_cdev); | 1634 | cdev_del(&usb_device_cdev); |
1608 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | 1635 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 4f1a8c8cf92b..a9d16aff5de5 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1137,7 +1137,6 @@ void usb_disconnect(struct usb_device **pdev) | |||
1137 | dev_dbg (&udev->dev, "unregistering device\n"); | 1137 | dev_dbg (&udev->dev, "unregistering device\n"); |
1138 | release_address(udev); | 1138 | release_address(udev); |
1139 | usbfs_remove_device(udev); | 1139 | usbfs_remove_device(udev); |
1140 | usbdev_remove(udev); | ||
1141 | usb_remove_sysfs_dev_files(udev); | 1140 | usb_remove_sysfs_dev_files(udev); |
1142 | 1141 | ||
1143 | /* Avoid races with recursively_mark_NOTATTACHED() */ | 1142 | /* Avoid races with recursively_mark_NOTATTACHED() */ |
@@ -1376,7 +1375,6 @@ int usb_new_device(struct usb_device *udev) | |||
1376 | usb_notify_add_device(udev); | 1375 | usb_notify_add_device(udev); |
1377 | 1376 | ||
1378 | /* add a /proc/bus/usb entry */ | 1377 | /* add a /proc/bus/usb entry */ |
1379 | usbdev_add(udev); | ||
1380 | usbfs_add_device(udev); | 1378 | usbfs_add_device(udev); |
1381 | return 0; | 1379 | return 0; |
1382 | 1380 | ||
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 811cf4482e0d..888dbe443695 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -62,8 +62,6 @@ extern void usbfs_conn_disc_event(void); | |||
62 | 62 | ||
63 | extern int usbdev_init(void); | 63 | extern int usbdev_init(void); |
64 | extern void usbdev_cleanup(void); | 64 | extern void usbdev_cleanup(void); |
65 | extern void usbdev_add(struct usb_device *dev); | ||
66 | extern void usbdev_remove(struct usb_device *dev); | ||
67 | 65 | ||
68 | struct dev_state { | 66 | struct dev_state { |
69 | struct list_head list; /* state list */ | 67 | struct list_head list; /* state list */ |