2 pseudo.h (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
5 This is the "pseudo-interrupt" logic for parallel port drivers.
7 This module is #included into each driver. It makes one
10 ps_set_intr( void (*continuation)(void),
15 Which will arrange for ready() to be evaluated frequently and
16 when either it returns true, or timeout jiffies have passed,
17 continuation() will be invoked.
19 If nice is 1, the test will done approximately once a
20 jiffy. If nice is 0, the test will also be done whenever
21 the scheduler runs (by adding it to a task queue). If
22 nice is greater than 1, the test will be done once every
29 1.01 1998.05.03 Switched from cli()/sti() to spinlocks
30 1.02 1998.12.14 Added support for nice > 1
33 #define PS_VERSION "1.02"
35 #include <linux/sched.h>
36 #include <linux/timer.h>
37 #include <linux/tqueue.h>
39 static void ps_timer_int( unsigned long data);
40 static void ps_tq_int( void *data);
42 static void (* ps_continuation)(void);
43 static int (* ps_ready)(void);
45 static int ps_timeout;
46 static int ps_timer_active = 0;
47 static int ps_tq_active = 0;
48 static int ps_nice = 0;
50 static spinlock_t ps_spinlock __attribute__((unused)) = SPIN_LOCK_UNLOCKED;
52 static struct timer_list ps_timer = { function: ps_timer_int };
53 static struct tq_struct ps_tq = { routine: ps_tq_int };
55 static void ps_set_intr( void (*continuation)(void),
57 int timeout, int nice )
59 { unsigned long flags;
61 spin_lock_irqsave(&ps_spinlock,flags);
63 ps_continuation = continuation;
66 ps_timeout = jiffies + timeout;
69 if (!ps_nice && !ps_tq_active) {
70 #ifdef HAVE_DISABLE_HLT
74 schedule_task(&ps_tq);
77 if (!ps_timer_active) {
79 ps_timer.expires = jiffies + ((ps_nice>0)?(ps_nice-1):0);
83 spin_unlock_irqrestore(&ps_spinlock,flags);
86 static void ps_tq_int( void *data )
91 spin_lock_irqsave(&ps_spinlock,flags);
93 con = ps_continuation;
95 #ifdef HAVE_DISABLE_HLT
102 spin_unlock_irqrestore(&ps_spinlock,flags);
105 if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) {
106 ps_continuation = NULL;
107 spin_unlock_irqrestore(&ps_spinlock,flags);
112 #ifdef HAVE_DISABLE_HLT
117 schedule_task(&ps_tq);
118 spin_unlock_irqrestore(&ps_spinlock,flags);
121 static void ps_timer_int( unsigned long data)
126 spin_lock_irqsave(&ps_spinlock,flags);
128 con = ps_continuation;
131 spin_unlock_irqrestore(&ps_spinlock,flags);
134 if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) {
135 ps_continuation = NULL;
136 spin_unlock_irqrestore(&ps_spinlock,flags);
141 ps_timer.expires = jiffies + ((ps_nice>0)?(ps_nice-1):0);
142 add_timer(&ps_timer);
143 spin_unlock_irqrestore(&ps_spinlock,flags);
146 /* end of pseudo.h */