summaryrefslogtreecommitdiff
blob: ff06da9df07b16e8549e66441bb4b78754626f16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
--- driver.c.orig	2004-06-17 02:00:00.000000000 +0200
+++ driver.c	2005-02-26 11:02:38.000000000 +0100
@@ -18,6 +18,11 @@
  * http://www.opensource.org/licenses/lgpl-license.html
  * 
  * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de
+ *
+ * Sunday Dec 07 18:10 2003
+ * Modified by Christian 'greeny' Heckhoff to improve locking
+ * based on modifications by Joerg Lehrke for Fritz!Card DSL
+ *
  */
 
 #include <asm/io.h>
@@ -54,6 +59,8 @@
 #include "devif.h"
 #include "driver.h"
 
+#undef SINGLE_LOCK
+
 #define	KILOBYTE		1024
 #define	MEGABYTE		(1024*KILOBYTE)
 #define	_2_MEGS_		(2*MEGABYTE)
@@ -92,7 +99,11 @@ typedef struct __db {
 card_p				capi_card		= NULL;
 lib_callback_t *		capi_lib		= NULL;
 atomic_t			crit_count		= ATOMIC_INIT(0);
+#if defined (SINGLE_LOCK)
+# define stack_lock qt_lock
+#else
 spinlock_t			stack_lock		= SPIN_LOCK_UNLOCKED;
+#endif
 
 static int			nvers			= 0;
 static atomic_t			scheduler_enabled	= ATOMIC_INIT (1);
@@ -1322,9 +1333,10 @@ void msg2capi (unsigned char * msg) {
 	capi_ctr_handle_message (ctrl, appl, skb);
 } /* msg2capi */
 
-/*-S-------------------------------------------------------------------------*\
+/*---------------------------------------------------------------------------*\
 \*---------------------------------------------------------------------------*/
 static int sched_thread (void * arg) {
+	unsigned long flags;
 
 	UNUSED_ARG (arg);
 	daemonize (TARGET);
@@ -1356,6 +1368,7 @@ static int sched_thread (void * arg) {
 			continue;
 		}
 		/* Body of thread, invoke scheduler */
+		local_irq_save(flags);
 		if (spin_trylock (&stack_lock)) {
 			os_timer_poll ();
 			assert (capi_lib->cm_schedule);
@@ -1364,6 +1377,7 @@ static int sched_thread (void * arg) {
 			}
 			spin_unlock (&stack_lock);
 		}
+		local_irq_restore(flags);
 	}
 	LOG("Scheduler thread stopped.\n");
 	up (&thread_sync);