HvLpEvent.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright 2001 Mike Corrigan IBM Corp
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. */
  9. #include <linux/stddef.h>
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <asm/system.h>
  13. #include <asm/iSeries/HvLpEvent.h>
  14. #include <asm/iSeries/HvCallEvent.h>
  15. #include <asm/iSeries/ItLpNaca.h>
  16. /* Array of LpEvent handler functions */
  17. LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
  18. unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
  19. /* Register a handler for an LpEvent type */
  20. int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler handler )
  21. {
  22. int rc = 1;
  23. if ( eventType < HvLpEvent_Type_NumTypes ) {
  24. lpEventHandler[eventType] = handler;
  25. rc = 0;
  26. }
  27. return rc;
  28. }
  29. int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
  30. {
  31. int rc = 1;
  32. might_sleep();
  33. if ( eventType < HvLpEvent_Type_NumTypes ) {
  34. if ( !lpEventHandlerPaths[eventType] ) {
  35. lpEventHandler[eventType] = NULL;
  36. rc = 0;
  37. /* We now sleep until all other CPUs have scheduled. This ensures that
  38. * the deletion is seen by all other CPUs, and that the deleted handler
  39. * isn't still running on another CPU when we return. */
  40. synchronize_rcu();
  41. }
  42. }
  43. return rc;
  44. }
  45. EXPORT_SYMBOL(HvLpEvent_registerHandler);
  46. EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
  47. /* (lpIndex is the partition index of the target partition.
  48. * needed only for VirtualIo, VirtualLan and SessionMgr. Zero
  49. * indicates to use our partition index - for the other types)
  50. */
  51. int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
  52. {
  53. int rc = 1;
  54. if ( eventType < HvLpEvent_Type_NumTypes &&
  55. lpEventHandler[eventType] ) {
  56. if ( lpIndex == 0 )
  57. lpIndex = itLpNaca.xLpIndex;
  58. HvCallEvent_openLpEventPath( lpIndex, eventType );
  59. ++lpEventHandlerPaths[eventType];
  60. rc = 0;
  61. }
  62. return rc;
  63. }
  64. int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
  65. {
  66. int rc = 1;
  67. if ( eventType < HvLpEvent_Type_NumTypes &&
  68. lpEventHandler[eventType] &&
  69. lpEventHandlerPaths[eventType] ) {
  70. if ( lpIndex == 0 )
  71. lpIndex = itLpNaca.xLpIndex;
  72. HvCallEvent_closeLpEventPath( lpIndex, eventType );
  73. --lpEventHandlerPaths[eventType];
  74. rc = 0;
  75. }
  76. return rc;
  77. }