aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/gigaset/common.c
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2006-04-11 01:55:16 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-11 09:18:50 -0400
commit69049cc87dccb1e6fb54aa25c63033efac805dbd (patch)
tree9db1953a831091335b98f8749865f4c8b410ff9b /drivers/isdn/gigaset/common.c
parent27d1ac2ef7d0b9250ca9fd2ef506e12866ce8fdf (diff)
[PATCH] isdn4linux: Siemens Gigaset drivers: make some variables non-atomic
With Hansjoerg Lipp <hjlipp@web.de> Replace some atomic_t variables in the Gigaset drivers by non-atomic ones, using spinlocks instead to assure atomicity, as proposed in discussions on the linux-kernel mailing list. Signed-off-by: Hansjoerg Lipp <hjlipp@web.de> Signed-off-by: Tilman Schmidt <tilman@imap.cc> Cc: Karsten Keil <kkeil@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/isdn/gigaset/common.c')
-rw-r--r--drivers/isdn/gigaset/common.c64
1 files changed, 32 insertions, 32 deletions
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index f8e5759c636c..d00acddd6213 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -129,11 +129,6 @@ int gigaset_enterconfigmode(struct cardstate *cs)
129{ 129{
130 int i, r; 130 int i, r;
131 131
132 if (!atomic_read(&cs->connected)) {
133 err("not connected!");
134 return -1;
135 }
136
137 cs->control_state = TIOCM_RTS; //FIXME 132 cs->control_state = TIOCM_RTS; //FIXME
138 133
139 r = setflags(cs, TIOCM_DTR, 200); 134 r = setflags(cs, TIOCM_DTR, 200);
@@ -176,7 +171,7 @@ static int test_timeout(struct at_state_t *at_state)
176 } 171 }
177 172
178 if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL, 173 if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL,
179 atomic_read(&at_state->timer_index), NULL)) { 174 at_state->timer_index, NULL)) {
180 //FIXME what should we do? 175 //FIXME what should we do?
181 } 176 }
182 177
@@ -204,7 +199,7 @@ static void timer_tick(unsigned long data)
204 if (test_timeout(at_state)) 199 if (test_timeout(at_state))
205 timeout = 1; 200 timeout = 1;
206 201
207 if (atomic_read(&cs->running)) { 202 if (cs->running) {
208 mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK)); 203 mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK));
209 if (timeout) { 204 if (timeout) {
210 gig_dbg(DEBUG_CMD, "scheduling timeout"); 205 gig_dbg(DEBUG_CMD, "scheduling timeout");
@@ -298,20 +293,22 @@ static void clear_events(struct cardstate *cs)
298{ 293{
299 struct event_t *ev; 294 struct event_t *ev;
300 unsigned head, tail; 295 unsigned head, tail;
296 unsigned long flags;
301 297
302 /* no locking needed (no reader/writer allowed) */ 298 spin_lock_irqsave(&cs->ev_lock, flags);
303 299
304 head = atomic_read(&cs->ev_head); 300 head = cs->ev_head;
305 tail = atomic_read(&cs->ev_tail); 301 tail = cs->ev_tail;
306 302
307 while (tail != head) { 303 while (tail != head) {
308 ev = cs->events + head; 304 ev = cs->events + head;
309 kfree(ev->ptr); 305 kfree(ev->ptr);
310
311 head = (head + 1) % MAX_EVENTS; 306 head = (head + 1) % MAX_EVENTS;
312 } 307 }
313 308
314 atomic_set(&cs->ev_head, tail); 309 cs->ev_head = tail;
310
311 spin_unlock_irqrestore(&cs->ev_lock, flags);
315} 312}
316 313
317struct event_t *gigaset_add_event(struct cardstate *cs, 314struct event_t *gigaset_add_event(struct cardstate *cs,
@@ -324,9 +321,9 @@ struct event_t *gigaset_add_event(struct cardstate *cs,
324 321
325 spin_lock_irqsave(&cs->ev_lock, flags); 322 spin_lock_irqsave(&cs->ev_lock, flags);
326 323
327 tail = atomic_read(&cs->ev_tail); 324 tail = cs->ev_tail;
328 next = (tail + 1) % MAX_EVENTS; 325 next = (tail + 1) % MAX_EVENTS;
329 if (unlikely(next == atomic_read(&cs->ev_head))) 326 if (unlikely(next == cs->ev_head))
330 err("event queue full"); 327 err("event queue full");
331 else { 328 else {
332 event = cs->events + tail; 329 event = cs->events + tail;
@@ -336,7 +333,7 @@ struct event_t *gigaset_add_event(struct cardstate *cs,
336 event->ptr = ptr; 333 event->ptr = ptr;
337 event->arg = arg; 334 event->arg = arg;
338 event->parameter = parameter; 335 event->parameter = parameter;
339 atomic_set(&cs->ev_tail, next); 336 cs->ev_tail = next;
340 } 337 }
341 338
342 spin_unlock_irqrestore(&cs->ev_lock, flags); 339 spin_unlock_irqrestore(&cs->ev_lock, flags);
@@ -454,7 +451,7 @@ void gigaset_freecs(struct cardstate *cs)
454 goto f_bcs; 451 goto f_bcs;
455 452
456 spin_lock_irqsave(&cs->lock, flags); 453 spin_lock_irqsave(&cs->lock, flags);
457 atomic_set(&cs->running, 0); 454 cs->running = 0;
458 spin_unlock_irqrestore(&cs->lock, flags); /* event handler and timer are 455 spin_unlock_irqrestore(&cs->lock, flags); /* event handler and timer are
459 not rescheduled below */ 456 not rescheduled below */
460 457
@@ -513,8 +510,8 @@ void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs,
513 at_state->pending_commands = 0; 510 at_state->pending_commands = 0;
514 at_state->timer_expires = 0; 511 at_state->timer_expires = 0;
515 at_state->timer_active = 0; 512 at_state->timer_active = 0;
516 atomic_set(&at_state->timer_index, 0); 513 at_state->timer_index = 0;
517 atomic_set(&at_state->seq_index, 0); 514 at_state->seq_index = 0;
518 at_state->ConState = 0; 515 at_state->ConState = 0;
519 for (i = 0; i < STR_NUM; ++i) 516 for (i = 0; i < STR_NUM; ++i)
520 at_state->str_var[i] = NULL; 517 at_state->str_var[i] = NULL;
@@ -665,6 +662,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
665 int cidmode, const char *modulename) 662 int cidmode, const char *modulename)
666{ 663{
667 struct cardstate *cs = NULL; 664 struct cardstate *cs = NULL;
665 unsigned long flags;
668 int i; 666 int i;
669 667
670 gig_dbg(DEBUG_INIT, "allocating cs"); 668 gig_dbg(DEBUG_INIT, "allocating cs");
@@ -685,11 +683,11 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
685 cs->onechannel = onechannel; 683 cs->onechannel = onechannel;
686 cs->ignoreframes = ignoreframes; 684 cs->ignoreframes = ignoreframes;
687 INIT_LIST_HEAD(&cs->temp_at_states); 685 INIT_LIST_HEAD(&cs->temp_at_states);
688 atomic_set(&cs->running, 0); 686 cs->running = 0;
689 init_timer(&cs->timer); /* clear next & prev */ 687 init_timer(&cs->timer); /* clear next & prev */
690 spin_lock_init(&cs->ev_lock); 688 spin_lock_init(&cs->ev_lock);
691 atomic_set(&cs->ev_tail, 0); 689 cs->ev_tail = 0;
692 atomic_set(&cs->ev_head, 0); 690 cs->ev_head = 0;
693 mutex_init(&cs->mutex); 691 mutex_init(&cs->mutex);
694 mutex_lock(&cs->mutex); 692 mutex_lock(&cs->mutex);
695 693
@@ -701,7 +699,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
701 cs->open_count = 0; 699 cs->open_count = 0;
702 cs->dev = NULL; 700 cs->dev = NULL;
703 cs->tty = NULL; 701 cs->tty = NULL;
704 atomic_set(&cs->cidmode, cidmode != 0); 702 cs->cidmode = cidmode != 0;
705 703
706 //if(onechannel) { //FIXME 704 //if(onechannel) { //FIXME
707 cs->tabnocid = gigaset_tab_nocid_m10x; 705 cs->tabnocid = gigaset_tab_nocid_m10x;
@@ -737,7 +735,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
737 } else 735 } else
738 gigaset_inbuf_init(cs->inbuf, NULL, cs, INS_command); 736 gigaset_inbuf_init(cs->inbuf, NULL, cs, INS_command);
739 737
740 atomic_set(&cs->connected, 0); 738 cs->connected = 0;
739 cs->isdn_up = 0;
741 740
742 gig_dbg(DEBUG_INIT, "setting up cmdbuf"); 741 gig_dbg(DEBUG_INIT, "setting up cmdbuf");
743 cs->cmdbuf = cs->lastcmdbuf = NULL; 742 cs->cmdbuf = cs->lastcmdbuf = NULL;
@@ -761,7 +760,9 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
761 760
762 gigaset_if_init(cs); 761 gigaset_if_init(cs);
763 762
764 atomic_set(&cs->running, 1); 763 spin_lock_irqsave(&cs->lock, flags);
764 cs->running = 1;
765 spin_unlock_irqrestore(&cs->lock, flags);
765 setup_timer(&cs->timer, timer_tick, (unsigned long) cs); 766 setup_timer(&cs->timer, timer_tick, (unsigned long) cs);
766 cs->timer.expires = jiffies + msecs_to_jiffies(GIG_TICK); 767 cs->timer.expires = jiffies + msecs_to_jiffies(GIG_TICK);
767 /* FIXME: can jiffies increase too much until the timer is added? 768 /* FIXME: can jiffies increase too much until the timer is added?
@@ -871,10 +872,14 @@ static void cleanup_cs(struct cardstate *cs)
871 872
872int gigaset_start(struct cardstate *cs) 873int gigaset_start(struct cardstate *cs)
873{ 874{
875 unsigned long flags;
876
874 if (mutex_lock_interruptible(&cs->mutex)) 877 if (mutex_lock_interruptible(&cs->mutex))
875 return 0; 878 return 0;
876 879
877 atomic_set(&cs->connected, 1); 880 spin_lock_irqsave(&cs->lock, flags);
881 cs->connected = 1;
882 spin_unlock_irqrestore(&cs->lock, flags);
878 883
879 if (atomic_read(&cs->mstate) != MS_LOCKED) { 884 if (atomic_read(&cs->mstate) != MS_LOCKED) {
880 cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); 885 cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS);
@@ -950,11 +955,6 @@ void gigaset_stop(struct cardstate *cs)
950{ 955{
951 mutex_lock(&cs->mutex); 956 mutex_lock(&cs->mutex);
952 957
953 /* clear device sysfs */
954 gigaset_free_dev_sysfs(cs);
955
956 atomic_set(&cs->connected, 0);
957
958 cs->waiting = 1; 958 cs->waiting = 1;
959 959
960 if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL)) { 960 if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL)) {
@@ -970,8 +970,8 @@ void gigaset_stop(struct cardstate *cs)
970 //FIXME 970 //FIXME
971 } 971 }
972 972
973 /* Tell the LL that the device is not available .. */ 973 /* clear device sysfs */
974 gigaset_i4l_cmd(cs, ISDN_STAT_STOP); // FIXME move to event layer? 974 gigaset_free_dev_sysfs(cs);
975 975
976 cleanup_cs(cs); 976 cleanup_cs(cs);
977 977