notify.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. #include <linux/usb.h>
  14. #include <linux/mutex.h>
  15. #include "usb.h"
  16. static struct notifier_block *usb_notifier_list;
  17. static DEFINE_MUTEX(usb_notifier_lock);
  18. static void usb_notifier_chain_register(struct notifier_block **list,
  19. struct notifier_block *n)
  20. {
  21. mutex_lock(&usb_notifier_lock);
  22. while (*list) {
  23. if (n->priority > (*list)->priority)
  24. break;
  25. list = &((*list)->next);
  26. }
  27. n->next = *list;
  28. *list = n;
  29. mutex_unlock(&usb_notifier_lock);
  30. }
  31. static void usb_notifier_chain_unregister(struct notifier_block **nl,
  32. struct notifier_block *n)
  33. {
  34. mutex_lock(&usb_notifier_lock);
  35. while ((*nl)!=NULL) {
  36. if ((*nl)==n) {
  37. *nl = n->next;
  38. goto exit;
  39. }
  40. nl=&((*nl)->next);
  41. }
  42. exit:
  43. mutex_unlock(&usb_notifier_lock);
  44. }
  45. static int usb_notifier_call_chain(struct notifier_block **n,
  46. unsigned long val, void *v)
  47. {
  48. int ret=NOTIFY_DONE;
  49. struct notifier_block *nb = *n;
  50. mutex_lock(&usb_notifier_lock);
  51. while (nb) {
  52. ret = nb->notifier_call(nb,val,v);
  53. if (ret&NOTIFY_STOP_MASK) {
  54. goto exit;
  55. }
  56. nb = nb->next;
  57. }
  58. exit:
  59. mutex_unlock(&usb_notifier_lock);
  60. return ret;
  61. }
  62. /**
  63. * usb_register_notify - register a notifier callback whenever a usb change happens
  64. * @nb: pointer to the notifier block for the callback events.
  65. *
  66. * These changes are either USB devices or busses being added or removed.
  67. */
  68. void usb_register_notify(struct notifier_block *nb)
  69. {
  70. usb_notifier_chain_register(&usb_notifier_list, nb);
  71. }
  72. EXPORT_SYMBOL_GPL(usb_register_notify);
  73. /**
  74. * usb_unregister_notify - unregister a notifier callback
  75. * @nb: pointer to the notifier block for the callback events.
  76. *
  77. * usb_register_notifier() must have been previously called for this function
  78. * to work properly.
  79. */
  80. void usb_unregister_notify(struct notifier_block *nb)
  81. {
  82. usb_notifier_chain_unregister(&usb_notifier_list, nb);
  83. }
  84. EXPORT_SYMBOL_GPL(usb_unregister_notify);
  85. void usb_notify_add_device(struct usb_device *udev)
  86. {
  87. usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev);
  88. }
  89. void usb_notify_remove_device(struct usb_device *udev)
  90. {
  91. usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_REMOVE, udev);
  92. }
  93. void usb_notify_add_bus(struct usb_bus *ubus)
  94. {
  95. usb_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus);
  96. }
  97. void usb_notify_remove_bus(struct usb_bus *ubus)
  98. {
  99. usb_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus);
  100. }