]>
Commit | Line | Data |
---|---|---|
cd1a2927 MT |
1 | # patch found at http://freiburg.linux.de/~zeisberg/howtos/fritzcarddsl.html |
2 | --- fritz.old/src.drv/driver.c.orig 2003-12-19 00:00:00.000000000 +0200 | |
3 | +++ fritz/src.drv/driver.c 2004-07-18 17:03:36.000000000 +0200 | |
4 | @@ -18,6 +18,14 @@ | |
5 | * http://www.opensource.org/licenses/lgpl-license.html | |
6 | * | |
7 | * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de | |
8 | + * | |
9 | + * Sunday Dec 07 18:10 2003 | |
10 | + * Modified by Christian 'greeny' Heckhoff to improve locking | |
11 | + * based on modifications by Joerg Lehrke for Fritz!Card DSL | |
12 | + * | |
13 | + * Saturday Jul 24 2004, Oswin Horvath | |
14 | + * small modifications to make the patch work for the Fritz!Card SL USB (03.11.94) | |
15 | + * | |
16 | */ | |
17 | ||
18 | #include <asm/io.h> | |
19 | @@ -54,6 +62,8 @@ | |
20 | #include "devif.h" | |
21 | #include "driver.h" | |
22 | ||
23 | +#undef SINGLE_LOCK | |
24 | + | |
25 | #if defined (LOG_MESSAGES) | |
26 | # define mlog log | |
27 | #else | |
28 | @@ -118,7 +128,11 @@ | |
29 | static bundle_t ctrl_context[2]; | |
30 | static per_ctrl_t ctrl_params[2]; | |
31 | static unsigned long qt_flags; | |
32 | +#if defined (SINGLE_LOCK) | |
33 | +# define stack_lock qt_lock | |
34 | +#else | |
35 | static spinlock_t qt_lock = SPIN_LOCK_UNLOCKED; | |
36 | +#endif | |
37 | static atomic_t thread_flag = ATOMIC_INIT (0); | |
38 | static atomic_t thread_capi_flag = ATOMIC_INIT (0); | |
39 | static int thread_pid = -1; | |
40 | @@ -946,7 +960,7 @@ | |
41 | } /* fdslusb_remove_ctrl */ | |
42 | ||
43 | /*---------------------------------------------------------------------------*\ | |
44 | -\*-L-------------------------------------------------------------------------*/ | |
45 | +\*---------------------------------------------------------------------------*/ | |
46 | void lock (void) { | |
47 | unsigned long local_flags; | |
48 | ||
49 | @@ -966,12 +980,17 @@ | |
50 | /*---------------------------------------------------------------------------*\ | |
51 | \*-C-------------------------------------------------------------------------*/ | |
52 | static inline void check (void) { | |
53 | + unsigned long flags; | |
54 | ||
55 | if (atomic_read (&rx_flag) > 0) { | |
56 | + spin_lock_irqsave (&stack_lock, flags); | |
57 | rx_handler (fcslusb_capi_card); | |
58 | + spin_unlock_irqrestore (&stack_lock, flags); | |
59 | } | |
60 | if (atomic_read (&tx_flag) > 0) { | |
61 | + spin_lock_irqsave (&stack_lock, flags); | |
62 | tx_handler (fcslusb_capi_card); | |
63 | + spin_unlock_irqrestore (&stack_lock, flags); | |
64 | } | |
65 | } /* check */ | |
66 | ||
67 | @@ -1519,6 +1538,7 @@ | |
68 | /*-S-------------------------------------------------------------------------*\ | |
69 | \*---------------------------------------------------------------------------*/ | |
70 | static int scheduler (void * arg) { | |
71 | + unsigned long flags; | |
72 | ||
73 | UNUSED_ARG (arg); | |
74 | daemonize (); | |
75 | @@ -1551,6 +1571,7 @@ | |
76 | continue; | |
77 | } | |
78 | /* Body of thread, invoke scheduler */ | |
79 | + local_irq_save(flags); | |
80 | if (spin_trylock (&stack_lock)) { | |
81 | info (!atomic_xchg (&in_scheduler, 1)); | |
82 | os_timer_poll (); | |
83 | @@ -1561,6 +1582,7 @@ | |
84 | debug (atomic_set (&in_scheduler, 0)); | |
85 | spin_unlock (&stack_lock); | |
86 | } | |
87 | + local_irq_restore(flags); | |
88 | } | |
89 | log ("Scheduler thread stopped.\n"); | |
90 | up (&thread_sync); | |
91 | @@ -1743,22 +1765,43 @@ | |
92 | /*---------------------------------------------------------------------------*\ | |
93 | \*---------------------------------------------------------------------------*/ | |
94 | static void tx_task (unsigned long data) { | |
95 | - | |
96 | + unsigned long flags; | |
97 | UNUSED_ARG (data); | |
98 | - if (!in_critical () && spin_trylock (&stack_lock)) { | |
99 | - tx_handler (fcslusb_capi_card); | |
100 | - spin_unlock (&stack_lock); | |
101 | + | |
102 | + if (in_critical ()){ | |
103 | + atomic_set (&tx_flag, 1); | |
104 | + kick_scheduler (); | |
105 | + } else { | |
106 | + local_irq_save(flags); | |
107 | + if (spin_trylock (&stack_lock)) { | |
108 | + tx_handler (fcslusb_capi_card); | |
109 | + spin_unlock (&stack_lock); | |
110 | + } else { | |
111 | + atomic_set (&tx_flag, 1); | |
112 | + kick_scheduler (); | |
113 | + } | |
114 | + local_irq_restore(flags); | |
115 | } | |
116 | } /* tx_task */ | |
117 | ||
118 | /*---------------------------------------------------------------------------*\ | |
119 | \*---------------------------------------------------------------------------*/ | |
120 | static void rx_task (unsigned long data) { | |
121 | - | |
122 | + unsigned long flags; | |
123 | UNUSED_ARG (data); | |
124 | - if (!in_critical () && spin_trylock (&stack_lock)) { | |
125 | - rx_handler (fcslusb_capi_card); | |
126 | - spin_unlock (&stack_lock); | |
127 | + if (in_critical ()){ | |
128 | + atomic_set (&rx_flag, 1); | |
129 | + kick_scheduler (); | |
130 | + } else { | |
131 | + local_irq_save(flags); | |
132 | + if (spin_trylock (&stack_lock)) { | |
133 | + rx_handler (fcslusb_capi_card); | |
134 | + spin_unlock (&stack_lock); | |
135 | + } else { | |
136 | + atomic_set (&rx_flag, 1); | |
137 | + kick_scheduler (); | |
138 | + } | |
139 | + local_irq_restore(flags); | |
140 | } | |
141 | } /* rx_task */ | |
142 |