Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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(struct work_struct *work);
 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_DELAYED_WORK(ps_tq, ps_tq_int);
 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_delayed_work(&ps_tq, 0);
 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(struct work_struct *work)
 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_delayed_work(&ps_tq, 0);
 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 
103 
  This page was automatically generated by the LXR engine.