diff options
Diffstat (limited to 'drivers/block/paride/pseudo.h')
-rw-r--r-- | drivers/block/paride/pseudo.h | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/block/paride/pseudo.h b/drivers/block/paride/pseudo.h new file mode 100644 index 000000000000..932342d7a8eb --- /dev/null +++ b/drivers/block/paride/pseudo.h | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | pseudo.h (c) 1997-8 Grant R. Guenther <grant@torque.net> | ||
3 | Under the terms of the GNU General Public License. | ||
4 | |||
5 | This is the "pseudo-interrupt" logic for parallel port drivers. | ||
6 | |||
7 | This module is #included into each driver. It makes one | ||
8 | function available: | ||
9 | |||
10 | ps_set_intr( void (*continuation)(void), | ||
11 | int (*ready)(void), | ||
12 | int timeout, | ||
13 | int nice ) | ||
14 | |||
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. | ||
18 | |||
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 | ||
23 | (nice-1) jiffies. | ||
24 | |||
25 | */ | ||
26 | |||
27 | /* Changes: | ||
28 | |||
29 | 1.01 1998.05.03 Switched from cli()/sti() to spinlocks | ||
30 | 1.02 1998.12.14 Added support for nice > 1 | ||
31 | */ | ||
32 | |||
33 | #define PS_VERSION "1.02" | ||
34 | |||
35 | #include <linux/sched.h> | ||
36 | #include <linux/workqueue.h> | ||
37 | |||
38 | static void ps_tq_int( void *data); | ||
39 | |||
40 | static void (* ps_continuation)(void); | ||
41 | static int (* ps_ready)(void); | ||
42 | static unsigned long ps_timeout; | ||
43 | static int ps_tq_active = 0; | ||
44 | static int ps_nice = 0; | ||
45 | |||
46 | static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused))); | ||
47 | |||
48 | static DECLARE_WORK(ps_tq, ps_tq_int, NULL); | ||
49 | |||
50 | static void ps_set_intr(void (*continuation)(void), | ||
51 | int (*ready)(void), | ||
52 | int timeout, int nice) | ||
53 | { | ||
54 | unsigned long flags; | ||
55 | |||
56 | spin_lock_irqsave(&ps_spinlock,flags); | ||
57 | |||
58 | ps_continuation = continuation; | ||
59 | ps_ready = ready; | ||
60 | ps_timeout = jiffies + timeout; | ||
61 | ps_nice = nice; | ||
62 | |||
63 | if (!ps_tq_active) { | ||
64 | ps_tq_active = 1; | ||
65 | if (!ps_nice) | ||
66 | schedule_work(&ps_tq); | ||
67 | else | ||
68 | schedule_delayed_work(&ps_tq, ps_nice-1); | ||
69 | } | ||
70 | spin_unlock_irqrestore(&ps_spinlock,flags); | ||
71 | } | ||
72 | |||
73 | static void ps_tq_int(void *data) | ||
74 | { | ||
75 | void (*con)(void); | ||
76 | unsigned long flags; | ||
77 | |||
78 | spin_lock_irqsave(&ps_spinlock,flags); | ||
79 | |||
80 | con = ps_continuation; | ||
81 | ps_tq_active = 0; | ||
82 | |||
83 | if (!con) { | ||
84 | spin_unlock_irqrestore(&ps_spinlock,flags); | ||
85 | return; | ||
86 | } | ||
87 | if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) { | ||
88 | ps_continuation = NULL; | ||
89 | spin_unlock_irqrestore(&ps_spinlock,flags); | ||
90 | con(); | ||
91 | return; | ||
92 | } | ||
93 | ps_tq_active = 1; | ||
94 | if (!ps_nice) | ||
95 | schedule_work(&ps_tq); | ||
96 | else | ||
97 | schedule_delayed_work(&ps_tq, ps_nice-1); | ||
98 | spin_unlock_irqrestore(&ps_spinlock,flags); | ||
99 | } | ||
100 | |||
101 | /* end of pseudo.h */ | ||
102 | |||