]>
Commit | Line | Data |
---|---|---|
cd1a2927 MT |
1 | # patch found at http://freiburg.linux.de/~zeisberg/howtos/fritzcarddsl.html |
2 | diff -u -r fritz.old/src.drv/driver.c fritz/src.drv/driver.c | |
3 | --- fritz.old/src.drv/driver.c Tue Jul 8 00:02:00 2003 | |
4 | +++ fritz/src.drv/driver.c Fri Nov 7 14:21:49 2003 | |
5 | @@ -18,6 +18,10 @@ | |
6 | * http://www.opensource.org/licenses/lgpl-license.html | |
7 | * | |
8 | * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de | |
9 | + * | |
10 | + * Mon Oct 20 22:43:31 2003 | |
11 | + * Modified by Joerg Lehrke to improve locking | |
12 | + * | |
13 | */ | |
14 | ||
15 | #include <asm/io.h> | |
16 | @@ -57,6 +61,8 @@ | |
17 | #include "dbgif.h" | |
18 | #endif | |
19 | ||
20 | +#undef SINGLE_LOCK | |
21 | + | |
22 | #if defined (LOG_MESSAGES) | |
23 | # define mlog log | |
24 | #else | |
25 | @@ -107,7 +113,11 @@ | |
26 | struct capi_ctr * capi_controller[2] = { NULL, NULL } ; | |
27 | static bundle_t ctrl_context[2]; | |
28 | static per_ctrl_t ctrl_params[2]; | |
29 | +#if defined (SINGLE_LOCK) | |
30 | +# define stack_lock qt_lock | |
31 | +#else | |
32 | static spinlock_t stack_lock = SPIN_LOCK_UNLOCKED; | |
33 | +#endif | |
34 | static atomic_t rx_flag = ATOMIC_INIT (0); | |
35 | static atomic_t tx_flag = ATOMIC_INIT (0); | |
36 | static unsigned long qt_flags; | |
37 | @@ -1080,7 +1090,7 @@ | |
38 | } /* remove_ctrl */ | |
39 | ||
40 | /*---------------------------------------------------------------------------*\ | |
41 | -\*-L-------------------------------------------------------------------------*/ | |
42 | +\*---------------------------------------------------------------------------*/ | |
43 | void lock (void) { | |
44 | unsigned long local_flags; | |
45 | ||
46 | @@ -1098,7 +1108,7 @@ | |
47 | } /* unlock */ | |
48 | ||
49 | /*---------------------------------------------------------------------------*\ | |
50 | -\*-C-------------------------------------------------------------------------*/ | |
51 | +\*---------------------------------------------------------------------------*/ | |
52 | static inline int in_critical (void) { | |
53 | ||
54 | return (0 < atomic_read (&crit_count)); | |
55 | @@ -1108,17 +1118,16 @@ | |
56 | \*---------------------------------------------------------------------------*/ | |
57 | static inline void check (void) { | |
58 | unsigned long flags; | |
59 | - spinlock_t chk_lock = SPIN_LOCK_UNLOCKED; | |
60 | ||
61 | if (atomic_xchg (&rx_flag, 0)) { | |
62 | - spin_lock_irqsave (&chk_lock, flags); | |
63 | + spin_lock_irqsave (&stack_lock, flags); | |
64 | rx_handler (capi_card); | |
65 | - spin_unlock_irqrestore (&chk_lock, flags); | |
66 | + spin_unlock_irqrestore (&stack_lock, flags); | |
67 | } | |
68 | if (atomic_xchg (&tx_flag, 0)) { | |
69 | - spin_lock_irqsave (&chk_lock, flags); | |
70 | + spin_lock_irqsave (&stack_lock, flags); | |
71 | tx_handler (capi_card); | |
72 | - spin_unlock_irqrestore (&chk_lock, flags); | |
73 | + spin_unlock_irqrestore (&stack_lock, flags); | |
74 | } | |
75 | } /* check */ | |
76 | ||
77 | @@ -1640,7 +1649,7 @@ | |
78 | return ncci_data_buffer (capi_card->appls, appp, ncci, handle); | |
79 | } /* data_block */ | |
80 | ||
81 | -/*-S-------------------------------------------------------------------------*\ | |
82 | +/*---------------------------------------------------------------------------*\ | |
83 | \*---------------------------------------------------------------------------*/ | |
84 | static void scheduler_control (unsigned ena) { | |
85 | int enabled = (int) ena; | |
86 | @@ -1662,6 +1671,7 @@ | |
87 | /*---------------------------------------------------------------------------*\ | |
88 | \*---------------------------------------------------------------------------*/ | |
89 | static int sched_thread (void * arg) { | |
90 | + unsigned long flags; | |
91 | ||
92 | UNUSED_ARG (arg); | |
93 | daemonize (); | |
94 | @@ -1692,6 +1702,7 @@ | |
95 | continue; | |
96 | } | |
97 | /* Body of thread, invoke scheduler */ | |
98 | + local_irq_save(flags); | |
99 | if (spin_trylock (&stack_lock)) { | |
100 | os_timer_poll (); | |
101 | assert (capi_lib->cm_schedule); | |
102 | @@ -1700,6 +1711,7 @@ | |
103 | } | |
104 | spin_unlock (&stack_lock); | |
105 | } | |
106 | + local_irq_restore(flags); | |
107 | } | |
108 | log ("Scheduler thread stopped.\n"); | |
109 | up (&hotplug); | |
110 | @@ -1802,17 +1814,22 @@ | |
111 | /*---------------------------------------------------------------------------*\ | |
112 | \*---------------------------------------------------------------------------*/ | |
113 | static void tx_task (unsigned long data) { | |
114 | - | |
115 | + unsigned long flags; | |
116 | + | |
117 | UNUSED_ARG (data); | |
118 | if (in_critical ()) { | |
119 | atomic_set (&tx_flag, 1); | |
120 | kick_scheduler (); | |
121 | - } else if (spin_trylock (&stack_lock)) { | |
122 | - tx_handler (capi_card); | |
123 | - spin_unlock (&stack_lock); | |
124 | } else { | |
125 | - atomic_set (&tx_flag, 1); | |
126 | - kick_scheduler (); | |
127 | + local_irq_save(flags); | |
128 | + if (spin_trylock (&stack_lock)) { | |
129 | + tx_handler (capi_card); | |
130 | + spin_unlock (&stack_lock); | |
131 | + } else { | |
132 | + atomic_set (&tx_flag, 1); | |
133 | + kick_scheduler (); | |
134 | + } | |
135 | + local_irq_restore(flags); | |
136 | } | |
137 | } /* tx_task */ | |
138 | ||
139 | @@ -1865,17 +1882,22 @@ | |
140 | /*---------------------------------------------------------------------------*\ | |
141 | \*---------------------------------------------------------------------------*/ | |
142 | static void rx_task (unsigned long data) { | |
143 | + unsigned long flags; | |
144 | ||
145 | UNUSED_ARG (data); | |
146 | if (in_critical ()) { | |
147 | atomic_set (&rx_flag, 1); | |
148 | kick_scheduler (); | |
149 | - } else if (spin_trylock (&stack_lock)) { | |
150 | - rx_handler (capi_card); | |
151 | - spin_unlock (&stack_lock); | |
152 | } else { | |
153 | - atomic_set (&rx_flag, 1); | |
154 | - kick_scheduler (); | |
155 | + local_irq_save(flags); | |
156 | + if (spin_trylock (&stack_lock)) { | |
157 | + rx_handler (capi_card); | |
158 | + spin_unlock (&stack_lock); | |
159 | + } else { | |
160 | + atomic_set (&rx_flag, 1); | |
161 | + kick_scheduler (); | |
162 | + } | |
163 | + local_irq_restore(flags); | |
164 | } | |
165 | } /* rx_task */ | |
166 | ||
167 | @@ -1894,6 +1916,7 @@ | |
168 | if (capi_card != (card_p) args) { | |
169 | return; | |
170 | } | |
171 | + spin_lock (&stack_lock); | |
172 | while (0 != ((flags = PEEK (capi_card->io_base + INT_CTL)) & CARD_PCI_INT_ASSERT)) { | |
173 | #if !defined (NDEBUG) | |
174 | ++count; | |
175 | @@ -1906,6 +1929,7 @@ | |
176 | assert ((PEEK (capi_card->io_base + INT_CTL) | |
177 | & ~(CARD_PCI_INT_ASSERT | CARD_PCI_INT_ISASSERTED)) != 0); | |
178 | if (!atomic_read (&link_open)) { | |
179 | + spin_unlock (&stack_lock); | |
180 | return; | |
181 | } | |
182 | tx_flag = PEEK (capi_card->io_base + XFER_TOTM_STATUS) == TM_READY; | |
183 | @@ -1920,6 +1944,7 @@ | |
184 | } | |
185 | } | |
186 | info (0 == (PEEK (capi_card->io_base + INT_CTL) & CARD_PCI_INT_ASSERT)); | |
187 | + spin_unlock (&stack_lock); | |
188 | } /* irq_handler */ | |
189 | ||
190 | /*---------------------------------------------------------------------------*\ |