diff options
author | Linus Torvalds | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/block/paride/pseudo.h |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
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 @@ +/* + pseudo.h (c) 1997-8 Grant R. Guenther <grant@torque.net> + Under the terms of the GNU General Public License. + + This is the "pseudo-interrupt" logic for parallel port drivers. + + This module is #included into each driver. It makes one + function available: + + ps_set_intr( void (*continuation)(void), + int (*ready)(void), + int timeout, + int nice ) + + Which will arrange for ready() to be evaluated frequently and + when either it returns true, or timeout jiffies have passed, + continuation() will be invoked. + + If nice is 1, the test will done approximately once a + jiffy. If nice is 0, the test will also be done whenever + the scheduler runs (by adding it to a task queue). If + nice is greater than 1, the test will be done once every + (nice-1) jiffies. + +*/ + +/* Changes: + + 1.01 1998.05.03 Switched from cli()/sti() to spinlocks + 1.02 1998.12.14 Added support for nice > 1 +*/ + +#define PS_VERSION "1.02" + +#include <linux/sched.h> +#include <linux/workqueue.h> + +static void ps_tq_int( void *data); + +static void (* ps_continuation)(void); +static int (* ps_ready)(void); +static unsigned long ps_timeout; +static int ps_tq_active = 0; +static int ps_nice = 0; + +static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused))); + +static DECLARE_WORK(ps_tq, ps_tq_int, NULL); + +static void ps_set_intr(void (*continuation)(void), + int (*ready)(void), + int timeout, int nice) +{ + unsigned long flags; + + spin_lock_irqsave(&ps_spinlock,flags); + + ps_continuation = continuation; + ps_ready = ready; + ps_timeout = jiffies + timeout; + ps_nice = nice; + + if (!ps_tq_active) { + ps_tq_active = 1; + if (!ps_nice) + schedule_work(&ps_tq); + else + schedule_delayed_work(&ps_tq, ps_nice-1); + } + spin_unlock_irqrestore(&ps_spinlock,flags); +} + +static void ps_tq_int(void *data) +{ + void (*con)(void); + unsigned long flags; + + spin_lock_irqsave(&ps_spinlock,flags); + + con = ps_continuation; + ps_tq_active = 0; + + if (!con) { + spin_unlock_irqrestore(&ps_spinlock,flags); + return; + } + if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) { + ps_continuation = NULL; + spin_unlock_irqrestore(&ps_spinlock,flags); + con(); + return; + } + ps_tq_active = 1; + if (!ps_nice) + schedule_work(&ps_tq); + else + schedule_delayed_work(&ps_tq, ps_nice-1); + spin_unlock_irqrestore(&ps_spinlock,flags); +} + +/* end of pseudo.h */ + |