diff options
author | Tilman Schmidt <tilman@imap.cc> | 2006-04-11 01:55:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-11 09:18:50 -0400 |
commit | 69049cc87dccb1e6fb54aa25c63033efac805dbd (patch) | |
tree | 9db1953a831091335b98f8749865f4c8b410ff9b /drivers/isdn/gigaset/common.c | |
parent | 27d1ac2ef7d0b9250ca9fd2ef506e12866ce8fdf (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.c | 64 |
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 | ||
317 | struct event_t *gigaset_add_event(struct cardstate *cs, | 314 | struct 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 | ||
872 | int gigaset_start(struct cardstate *cs) | 873 | int 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 | ||