notify.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * All the USB notify logic
  3. *
  4. * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de>
  5. *
  6. * notifier functions originally based on those in kernel/sys.c
  7. * but fixed up to not be so broken.
  8. *
  9. */
  10. #include <linux/config.h>
  11. #include <linux/kernel.h>
  12. #include <linux/notifier.h>
  13. #ifdef CONFIG_USB_DEBUG
  14. #define DEBUG
  15. #else
  16. #undef DEBUG
  17. #endif
  18. #include <linux/usb.h>
  19. #include "usb.h"
  20. static struct notifier_block *usb_notifier_list;
  21. static DECLARE_MUTEX(usb_notifier_lock);
  22. static void usb_notifier_chain_register(struct notifier_block **list,
  23. struct notifier_block *n)
  24. {
  25. down(&usb_notifier_lock);
  26. while (*list) {
  27. if (n->priority > (*list)->priority)
  28. break;
  29. list = &((*list)->next);
  30. }
  31. n->next = *list;
  32. *list = n;
  33. up(&usb_notifier_lock);
  34. }
  35. static void usb_notifier_chain_unregister(struct notifier_block **nl,
  36. struct notifier_block *n)
  37. {
  38. down(&usb_notifier_lock);
  39. while ((*nl)!=NULL) {
  40. if ((*nl)==n) {
  41. *nl = n->next;
  42. goto exit;
  43. }
  44. nl=&((*nl)->next);
  45. }
  46. exit:
  47. up(&usb_notifier_lock);
  48. }
  49. static int usb_notifier_call_chain(struct notifier_block **n,
  50. unsigned long val, void *v)
  51. {
  52. int ret=NOTIFY_DONE;
  53. struct notifier_block *nb = *n;
  54. down(&usb_notifier_lock);
  55. while (nb) {
  56. ret = nb->notifier_call(nb,val,v);
  57. if (ret&NOTIFY_STOP_MASK) {
  58. goto exit;
  59. }
  60. nb = nb->next;
  61. }
  62. exit:
  63. up(&usb_notifier_lock);
  64. return ret;
  65. }
  66. /**
  67. * usb_register_notify - register a notifier callback whenever a usb change happens
  68. * @nb: pointer to the notifier block for the callback events.
  69. *
  70. * These changes are either USB devices or busses being added or removed.
  71. */
  72. void usb_register_notify(struct notifier_block *nb)
  73. {
  74. usb_notifier_chain_register(&usb_notifier_list, nb);
  75. }
  76. EXPORT_SYMBOL_GPL(usb_register_notify);
  77. /**
  78. * usb_unregister_notify - unregister a notifier callback
  79. * @nb: pointer to the notifier block for the callback events.
  80. *
  81. * usb_register_notifier() must have been previously called for this function
  82. * to work properly.
  83. */
  84. void usb_unregister_notify(struct notifier_block *nb)
  85. {
  86. usb_notifier_chain_unregister(&usb_notifier_list, nb);
  87. }
  88. EXPORT_SYMBOL_GPL(usb_unregister_notify);
  89. void usb_notify_add_device(struct usb_device *udev)
  90. {
  91. usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev);
  92. }
  93. void usb_notify_remove_device(struct usb_device *udev)
  94. {
  95. usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_REMOVE, udev);
  96. }
  97. void usb_notify_add_bus(struct usb_bus *ubus)
  98. {
  99. usb_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus);
  100. }
  101. void usb_notify_remove_bus(struct usb_bus *ubus)
  102. {
  103. usb_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus);
  104. }