[MTHCA]bug fixes:
[mirror/winof/.git] / hw / mthca / kernel / mt_spinlock.h
1 #ifndef MT_SPINLOCK_H
2 #define MT_SPINLOCK_H
3
4 typedef struct spinlock {
5         KSPIN_LOCK                      lock;
6
7 #ifdef SUPPORT_SPINLOCK_ISR     
8         PKINTERRUPT     p_int_obj;
9         KIRQL                           irql;
10 #endif
11 } spinlock_t;
12
13 typedef struct {
14         KLOCK_QUEUE_HANDLE lockh;
15         KIRQL                           irql;
16 } spinlockh_t;
17
18 #ifdef SUPPORT_SPINLOCK_ISR     
19
20 static inline void
21 spin_lock_setint( 
22         IN              spinlock_t* const       l, 
23         IN PKINTERRUPT  p_int_obj )
24 {
25         MT_ASSERT( l );
26         l->p_int_obj = p_int_obj;
27 }
28
29 static inline void spin_lock_irq_init(
30         IN              spinlock_t* const l,
31         IN      PKINTERRUPT int_obj
32         )
33
34         KeInitializeSpinLock( &l->lock ); 
35         l->p_int_obj = int_obj; 
36 }
37
38 static inline unsigned long
39 spin_lock_irq( 
40         IN              spinlock_t* const       l)
41 {
42         MT_ASSERT( l );
43         MT_ASSERT( l->p_int_obj );
44         return (unsigned long)(l->irql = KeAcquireInterruptSpinLock ( l->p_int_obj ));
45 }
46
47 static inline void
48 spin_unlock_irq( 
49         IN              spinlock_t* const p_spinlock ) 
50 {
51         MT_ASSERT( p_spinlock );
52         MT_ASSERT( p_spinlock->p_int_obj );
53         KeReleaseInterruptSpinLock ( p_spinlock->p_int_obj, p_spinlock->irql );
54 }
55
56 #endif
57
58 #define SPIN_LOCK_PREP(lh)              spinlockh_t lh
59
60 static inline void spin_lock_init(
61         IN              spinlock_t* const p_spinlock )
62
63         KeInitializeSpinLock( &p_spinlock->lock ); 
64 }
65
66 static inline void
67 spin_lock( 
68         IN              spinlock_t* const       l,
69         IN              spinlockh_t * const lh)
70 {
71         KIRQL irql = KeGetCurrentIrql();
72
73         MT_ASSERT( l || lh );
74         ASSERT(irql <= DISPATCH_LEVEL);
75
76         if (irql == DISPATCH_LEVEL)
77                 KeAcquireInStackQueuedSpinLockAtDpcLevel( &l->lock, &lh->lockh );
78         else
79                 KeAcquireInStackQueuedSpinLock( &l->lock, &lh->lockh );
80         lh->irql = irql;
81 }
82
83 static inline void
84 spin_unlock(
85         IN              spinlockh_t * const lh)
86 {
87         MT_ASSERT( lh );
88         ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
89         if (lh->irql == DISPATCH_LEVEL)
90                 KeReleaseInStackQueuedSpinLockFromDpcLevel( &lh->lockh );
91         else
92                 KeReleaseInStackQueuedSpinLock( &lh->lockh );
93 }
94
95 static inline void
96 spin_lock_sync( 
97         IN              spinlock_t* const       l )
98 {
99         KLOCK_QUEUE_HANDLE lockh;
100         MT_ASSERT( l );
101         ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
102         KeAcquireInStackQueuedSpinLock ( &l->lock, &lockh );
103         KeReleaseInStackQueuedSpinLock( &lockh );
104 }
105
106 /* to be used only at DPC level */
107 static inline void
108 spin_lock_dpc( 
109         IN              spinlock_t* const       l,
110         IN              spinlockh_t * const lh)
111 {
112         MT_ASSERT( l || lh );
113         ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
114         KeAcquireInStackQueuedSpinLockAtDpcLevel( &l->lock, &lh->lockh );
115 }
116
117 /* to be used only at DPC level */
118 static inline void
119 spin_unlock_dpc(
120         IN              spinlockh_t * const lh)
121 {
122         ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
123         KeReleaseInStackQueuedSpinLockFromDpcLevel( &lh->lockh );
124 }
125
126
127 /* we are working from DPC level, so we can use usual spinlocks */
128 #define spin_lock_irq                                           spin_lock
129 #define spin_unlock_irq                                         spin_unlock
130
131 /* no diff in Windows */
132 #define spin_lock_irqsave                               spin_lock_irq
133 #define spin_unlock_irqrestore                  spin_unlock_irq
134
135 /* Windows doesn't support such kind of spinlocks so far, but may be tomorrow ... */
136 #define rwlock_init                                             spin_lock_init
137 #define read_lock_irqsave                               spin_lock_irqsave
138 #define read_unlock_irqrestore                  spin_unlock_irqrestore
139 #define write_lock_irq                                  spin_lock_irq
140 #define write_unlock_irq                                        spin_unlock_irq
141
142 #endif
143