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
6 * http://www.opensource.org/licenses/lgpl-license.html
8 * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de
10 + * Mon Oct 20 22:43:31 2003
11 + * Modified by Joerg Lehrke to improve locking
22 #if defined (LOG_MESSAGES)
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
32 static spinlock_t stack_lock = SPIN_LOCK_UNLOCKED;
34 static atomic_t rx_flag = ATOMIC_INIT (0);
35 static atomic_t tx_flag = ATOMIC_INIT (0);
36 static unsigned long qt_flags;
40 /*---------------------------------------------------------------------------*\
41 -\*-L-------------------------------------------------------------------------*/
42 +\*---------------------------------------------------------------------------*/
44 unsigned long local_flags;
49 /*---------------------------------------------------------------------------*\
50 -\*-C-------------------------------------------------------------------------*/
51 +\*---------------------------------------------------------------------------*/
52 static inline int in_critical (void) {
54 return (0 < atomic_read (&crit_count));
55 @@ -1108,17 +1118,16 @@
56 \*---------------------------------------------------------------------------*/
57 static inline void check (void) {
59 - spinlock_t chk_lock = SPIN_LOCK_UNLOCKED;
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);
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);
78 return ncci_data_buffer (capi_card->appls, appp, ncci, handle);
81 -/*-S-------------------------------------------------------------------------*\
82 +/*---------------------------------------------------------------------------*\
83 \*---------------------------------------------------------------------------*/
84 static void scheduler_control (unsigned ena) {
85 int enabled = (int) ena;
87 /*---------------------------------------------------------------------------*\
88 \*---------------------------------------------------------------------------*/
89 static int sched_thread (void * arg) {
90 + unsigned long flags;
97 /* Body of thread, invoke scheduler */
98 + local_irq_save(flags);
99 if (spin_trylock (&stack_lock)) {
101 assert (capi_lib->cm_schedule);
102 @@ -1700,6 +1711,7 @@
104 spin_unlock (&stack_lock);
106 + local_irq_restore(flags);
108 log ("Scheduler thread stopped.\n");
110 @@ -1802,17 +1814,22 @@
111 /*---------------------------------------------------------------------------*\
112 \*---------------------------------------------------------------------------*/
113 static void tx_task (unsigned long data) {
115 + unsigned long flags;
118 if (in_critical ()) {
119 atomic_set (&tx_flag, 1);
121 - } else if (spin_trylock (&stack_lock)) {
122 - tx_handler (capi_card);
123 - spin_unlock (&stack_lock);
125 - atomic_set (&tx_flag, 1);
127 + local_irq_save(flags);
128 + if (spin_trylock (&stack_lock)) {
129 + tx_handler (capi_card);
130 + spin_unlock (&stack_lock);
132 + atomic_set (&tx_flag, 1);
135 + local_irq_restore(flags);
139 @@ -1865,17 +1882,22 @@
140 /*---------------------------------------------------------------------------*\
141 \*---------------------------------------------------------------------------*/
142 static void rx_task (unsigned long data) {
143 + unsigned long flags;
146 if (in_critical ()) {
147 atomic_set (&rx_flag, 1);
149 - } else if (spin_trylock (&stack_lock)) {
150 - rx_handler (capi_card);
151 - spin_unlock (&stack_lock);
153 - atomic_set (&rx_flag, 1);
155 + local_irq_save(flags);
156 + if (spin_trylock (&stack_lock)) {
157 + rx_handler (capi_card);
158 + spin_unlock (&stack_lock);
160 + atomic_set (&rx_flag, 1);
163 + local_irq_restore(flags);
167 @@ -1894,6 +1916,7 @@
168 if (capi_card != (card_p) args) {
171 + spin_lock (&stack_lock);
172 while (0 != ((flags = PEEK (capi_card->io_base + INT_CTL)) & CARD_PCI_INT_ASSERT)) {
173 #if !defined (NDEBUG)
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);
182 tx_flag = PEEK (capi_card->io_base + XFER_TOTM_STATUS) == TM_READY;
183 @@ -1920,6 +1944,7 @@
186 info (0 == (PEEK (capi_card->io_base + INT_CTL) & CARD_PCI_INT_ASSERT));
187 + spin_unlock (&stack_lock);
190 /*---------------------------------------------------------------------------*\