pseudo.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* 
  2.         pseudo.h    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  3.                                 Under the terms of the GNU General Public License.
  4. This is the "pseudo-interrupt" logic for parallel port drivers.
  5.         This module is #included into each driver.  It makes one
  6.         function available:
  7. ps_set_intr( void (*continuation)(void),
  8.      int  (*ready)(void),
  9.      int timeout,
  10.      int nice )
  11. Which will arrange for ready() to be evaluated frequently and
  12. when either it returns true, or timeout jiffies have passed,
  13. continuation() will be invoked.
  14. If nice is 1, the test will done approximately once a
  15. jiffy.  If nice is 0, the test will also be done whenever
  16. the scheduler runs (by adding it to a task queue).  If
  17. nice is greater than 1, the test will be done once every
  18. (nice-1) jiffies. 
  19. */
  20. /* Changes:
  21. 1.01 1998.05.03 Switched from cli()/sti() to spinlocks
  22. 1.02    1998.12.14      Added support for nice > 1
  23. */
  24. #define PS_VERSION "1.02"
  25. #include <linux/sched.h>
  26. #include <linux/timer.h>
  27. #include <linux/tqueue.h>
  28. static void ps_timer_int( unsigned long data);
  29. static void ps_tq_int( void *data);
  30. static void (* ps_continuation)(void);
  31. static int (* ps_ready)(void);
  32. static int ps_then;
  33. static int ps_timeout;
  34. static int ps_timer_active = 0;
  35. static int ps_tq_active = 0;
  36. static int ps_nice = 0;
  37. static spinlock_t ps_spinlock __attribute__((unused)) = SPIN_LOCK_UNLOCKED;
  38. static struct timer_list ps_timer = { function: ps_timer_int };
  39. static struct tq_struct ps_tq = { routine: ps_tq_int };
  40. static void ps_set_intr( void (*continuation)(void), 
  41.  int (*ready)(void),
  42.  int timeout, int nice )
  43. {       long flags;
  44. spin_lock_irqsave(&ps_spinlock,flags);
  45. ps_continuation = continuation;
  46. ps_ready = ready;
  47.         ps_then = jiffies;
  48. ps_timeout = jiffies + timeout;
  49. ps_nice = nice;
  50.         if (!ps_nice && !ps_tq_active) {
  51. #ifdef HAVE_DISABLE_HLT
  52.                 disable_hlt();
  53. #endif
  54. ps_tq_active = 1;
  55.                 schedule_task(&ps_tq);
  56. }
  57.         if (!ps_timer_active) {
  58. ps_timer_active = 1;
  59.                 ps_timer.expires = jiffies + ((ps_nice>0)?(ps_nice-1):0);
  60.                 add_timer(&ps_timer);
  61.         }
  62. spin_unlock_irqrestore(&ps_spinlock,flags);
  63. }
  64. static void ps_tq_int( void *data )
  65. {       void (*con)(void);
  66. long flags;
  67. spin_lock_irqsave(&ps_spinlock,flags);
  68.         con = ps_continuation;
  69. #ifdef HAVE_DISABLE_HLT
  70.         enable_hlt();
  71. #endif
  72.         ps_tq_active = 0;
  73.         if (!con) {
  74. spin_unlock_irqrestore(&ps_spinlock,flags);
  75. return;
  76. }
  77.         if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) {
  78.                 ps_continuation = NULL;
  79.          spin_unlock_irqrestore(&ps_spinlock,flags);
  80.                 con();
  81.                 return;
  82.                 }
  83. #ifdef HAVE_DISABLE_HLT
  84.         disable_hlt();
  85. #endif
  86.         ps_tq_active = 1;
  87. schedule_task(&ps_tq);
  88.         spin_unlock_irqrestore(&ps_spinlock,flags);
  89. }
  90. static void ps_timer_int( unsigned long data)
  91. {       void (*con)(void);
  92. long flags;
  93. spin_lock_irqsave(&ps_spinlock,flags);
  94. con = ps_continuation;
  95. ps_timer_active = 0;
  96. if (!con) {
  97.         spin_unlock_irqrestore(&ps_spinlock,flags);
  98. return;
  99. }
  100.         if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) {
  101.                 ps_continuation = NULL;
  102.         spin_unlock_irqrestore(&ps_spinlock,flags);
  103.                 con();
  104. return;
  105. }
  106. ps_timer_active = 1;
  107.         ps_timer.expires = jiffies + ((ps_nice>0)?(ps_nice-1):0);
  108.         add_timer(&ps_timer);
  109.         spin_unlock_irqrestore(&ps_spinlock,flags);
  110. }
  111. /* end of pseudo.h */