aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/isdn/gigaset/asyncdata.c9
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c48
-rw-r--r--drivers/isdn/gigaset/common.c64
-rw-r--r--drivers/isdn/gigaset/ev-layer.c87
-rw-r--r--drivers/isdn/gigaset/gigaset.h18
-rw-r--r--drivers/isdn/gigaset/i4l.c19
-rw-r--r--drivers/isdn/gigaset/interface.c19
-rw-r--r--drivers/isdn/gigaset/isocdata.c6
-rw-r--r--drivers/isdn/gigaset/proc.c9
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c86
10 files changed, 211 insertions, 154 deletions
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index ce60f6521b96..ce3cd77094b3 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -566,19 +566,22 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
566int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) 566int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
567{ 567{
568 unsigned len = skb->len; 568 unsigned len = skb->len;
569 unsigned long flags;
569 570
570 if (bcs->proto2 == ISDN_PROTO_L2_HDLC) 571 if (bcs->proto2 == ISDN_PROTO_L2_HDLC)
571 skb = HDLC_Encode(skb, HW_HDR_LEN, 0); 572 skb = HDLC_Encode(skb, HW_HDR_LEN, 0);
572 else 573 else
573 skb = iraw_encode(skb, HW_HDR_LEN, 0); 574 skb = iraw_encode(skb, HW_HDR_LEN, 0);
574 if (!skb) { 575 if (!skb) {
575 dev_err(bcs->cs->dev, 576 err("unable to allocate memory for encoding!\n");
576 "unable to allocate memory for encoding!\n");
577 return -ENOMEM; 577 return -ENOMEM;
578 } 578 }
579 579
580 skb_queue_tail(&bcs->squeue, skb); 580 skb_queue_tail(&bcs->squeue, skb);
581 tasklet_schedule(&bcs->cs->write_tasklet); 581 spin_lock_irqsave(&bcs->cs->lock, flags);
582 if (bcs->cs->connected)
583 tasklet_schedule(&bcs->cs->write_tasklet);
584 spin_unlock_irqrestore(&bcs->cs->lock, flags);
582 585
583 return len; /* ok so far */ 586 return len; /* ok so far */
584} 587}
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index fa37db68c962..f86ed6af3aa2 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -367,7 +367,7 @@ static void cmd_in_timeout(unsigned long data)
367 unsigned long flags; 367 unsigned long flags;
368 368
369 spin_lock_irqsave(&cs->lock, flags); 369 spin_lock_irqsave(&cs->lock, flags);
370 if (unlikely(!atomic_read(&cs->connected))) { 370 if (unlikely(!cs->connected)) {
371 gig_dbg(DEBUG_USBREQ, "%s: disconnected", __func__); 371 gig_dbg(DEBUG_USBREQ, "%s: disconnected", __func__);
372 spin_unlock_irqrestore(&cs->lock, flags); 372 spin_unlock_irqrestore(&cs->lock, flags);
373 return; 373 return;
@@ -475,11 +475,6 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
475 unsigned l; 475 unsigned l;
476 int channel; 476 int channel;
477 477
478 if (unlikely(!atomic_read(&cs->connected))) {
479 warn("%s: disconnected", __func__);
480 return;
481 }
482
483 switch (urb->status) { 478 switch (urb->status) {
484 case 0: /* success */ 479 case 0: /* success */
485 break; 480 break;
@@ -603,7 +598,9 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
603 check_pending(ucs); 598 check_pending(ucs);
604 599
605resubmit: 600resubmit:
606 status = usb_submit_urb(urb, SLAB_ATOMIC); 601 spin_lock_irqsave(&cs->lock, flags);
602 status = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
603 spin_unlock_irqrestore(&cs->lock, flags);
607 if (unlikely(status)) { 604 if (unlikely(status)) {
608 dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", 605 dev_err(cs->dev, "could not resubmit interrupt URB: %s\n",
609 get_usb_statmsg(status)); 606 get_usb_statmsg(status));
@@ -628,7 +625,7 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
628 unsigned long flags; 625 unsigned long flags;
629 626
630 spin_lock_irqsave(&cs->lock, flags); 627 spin_lock_irqsave(&cs->lock, flags);
631 if (unlikely(!atomic_read(&cs->connected))) { 628 if (unlikely(!cs->connected)) {
632 warn("%s: disconnected", __func__); 629 warn("%s: disconnected", __func__);
633 spin_unlock_irqrestore(&cs->lock, flags); 630 spin_unlock_irqrestore(&cs->lock, flags);
634 return; 631 return;
@@ -949,6 +946,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
949 struct bas_bc_state *ubc = ucx->bcs->hw.bas; 946 struct bas_bc_state *ubc = ucx->bcs->hw.bas;
950 struct usb_iso_packet_descriptor *ifd; 947 struct usb_iso_packet_descriptor *ifd;
951 int corrbytes, nframe, rc; 948 int corrbytes, nframe, rc;
949 unsigned long flags;
952 950
953 /* urb->dev is clobbered by USB subsystem */ 951 /* urb->dev is clobbered by USB subsystem */
954 urb->dev = ucx->bcs->cs->hw.bas->udev; 952 urb->dev = ucx->bcs->cs->hw.bas->udev;
@@ -995,7 +993,11 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
995 ifd->actual_length = 0; 993 ifd->actual_length = 0;
996 } 994 }
997 if ((urb->number_of_packets = nframe) > 0) { 995 if ((urb->number_of_packets = nframe) > 0) {
998 if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { 996 spin_lock_irqsave(&ucx->bcs->cs->lock, flags);
997 rc = ucx->bcs->cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
998 spin_unlock_irqrestore(&ucx->bcs->cs->lock, flags);
999
1000 if (rc) {
999 dev_err(ucx->bcs->cs->dev, 1001 dev_err(ucx->bcs->cs->dev,
1000 "could not submit isochronous write URB: %s\n", 1002 "could not submit isochronous write URB: %s\n",
1001 get_usb_statmsg(rc)); 1003 get_usb_statmsg(rc));
@@ -1029,11 +1031,6 @@ static void write_iso_tasklet(unsigned long data)
1029 1031
1030 /* loop while completed URBs arrive in time */ 1032 /* loop while completed URBs arrive in time */
1031 for (;;) { 1033 for (;;) {
1032 if (unlikely(!atomic_read(&cs->connected))) {
1033 warn("%s: disconnected", __func__);
1034 return;
1035 }
1036
1037 if (unlikely(!(atomic_read(&ubc->running)))) { 1034 if (unlikely(!(atomic_read(&ubc->running)))) {
1038 gig_dbg(DEBUG_ISO, "%s: not running", __func__); 1035 gig_dbg(DEBUG_ISO, "%s: not running", __func__);
1039 return; 1036 return;
@@ -1190,11 +1187,6 @@ static void read_iso_tasklet(unsigned long data)
1190 1187
1191 /* loop while more completed URBs arrive in the meantime */ 1188 /* loop while more completed URBs arrive in the meantime */
1192 for (;;) { 1189 for (;;) {
1193 if (unlikely(!atomic_read(&cs->connected))) {
1194 warn("%s: disconnected", __func__);
1195 return;
1196 }
1197
1198 /* retrieve URB */ 1190 /* retrieve URB */
1199 spin_lock_irqsave(&ubc->isoinlock, flags); 1191 spin_lock_irqsave(&ubc->isoinlock, flags);
1200 if (!(urb = ubc->isoindone)) { 1192 if (!(urb = ubc->isoindone)) {
@@ -1298,7 +1290,10 @@ static void read_iso_tasklet(unsigned long data)
1298 urb->dev = bcs->cs->hw.bas->udev; 1290 urb->dev = bcs->cs->hw.bas->udev;
1299 urb->transfer_flags = URB_ISO_ASAP; 1291 urb->transfer_flags = URB_ISO_ASAP;
1300 urb->number_of_packets = BAS_NUMFRAMES; 1292 urb->number_of_packets = BAS_NUMFRAMES;
1301 if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { 1293 spin_lock_irqsave(&cs->lock, flags);
1294 rc = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
1295 spin_unlock_irqrestore(&cs->lock, flags);
1296 if (rc) {
1302 dev_err(cs->dev, 1297 dev_err(cs->dev,
1303 "could not resubmit isochronous read URB: %s\n", 1298 "could not resubmit isochronous read URB: %s\n",
1304 get_usb_statmsg(rc)); 1299 get_usb_statmsg(rc));
@@ -1639,6 +1634,7 @@ static void atrdy_timeout(unsigned long data)
1639static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) 1634static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
1640{ 1635{
1641 struct bas_cardstate *ucs = cs->hw.bas; 1636 struct bas_cardstate *ucs = cs->hw.bas;
1637 unsigned long flags;
1642 int ret; 1638 int ret;
1643 1639
1644 gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len); 1640 gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len);
@@ -1659,7 +1655,11 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
1659 (unsigned char*) &ucs->dr_cmd_out, buf, len, 1655 (unsigned char*) &ucs->dr_cmd_out, buf, len,
1660 write_command_callback, cs); 1656 write_command_callback, cs);
1661 1657
1662 if ((ret = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC)) != 0) { 1658 spin_lock_irqsave(&cs->lock, flags);
1659 ret = cs->connected ? usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC) : -ENODEV;
1660 spin_unlock_irqrestore(&cs->lock, flags);
1661
1662 if (ret) {
1663 dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n", 1663 dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n",
1664 get_usb_statmsg(ret)); 1664 get_usb_statmsg(ret));
1665 return ret; 1665 return ret;
@@ -1758,11 +1758,6 @@ static int gigaset_write_cmd(struct cardstate *cs,
1758 DEBUG_TRANSCMD : DEBUG_LOCKCMD, 1758 DEBUG_TRANSCMD : DEBUG_LOCKCMD,
1759 "CMD Transmit", len, buf); 1759 "CMD Transmit", len, buf);
1760 1760
1761 if (unlikely(!atomic_read(&cs->connected))) {
1762 err("%s: disconnected", __func__);
1763 return -ENODEV;
1764 }
1765
1766 if (len <= 0) 1761 if (len <= 0)
1767 return 0; /* nothing to do */ 1762 return 0; /* nothing to do */
1768 1763
@@ -2186,6 +2181,7 @@ static int gigaset_probe(struct usb_interface *interface,
2186 2181
2187error: 2182error:
2188 freeurbs(cs); 2183 freeurbs(cs);
2184 usb_set_intfdata(interface, NULL);
2189 gigaset_unassign(cs); 2185 gigaset_unassign(cs);
2190 return -ENODEV; 2186 return -ENODEV;
2191} 2187}
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
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 2e826d051c85..1ba3424a286b 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -482,14 +482,6 @@ static int isdn_gethex(char *p)
482 return v; 482 return v;
483} 483}
484 484
485static inline void new_index(atomic_t *index, int max)
486{
487 if (atomic_read(index) == max) //FIXME race?
488 atomic_set(index, 0);
489 else
490 atomic_inc(index);
491}
492
493/* retrieve CID from parsed response 485/* retrieve CID from parsed response
494 * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 486 * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535
495 */ 487 */
@@ -581,8 +573,8 @@ void gigaset_handle_modem_response(struct cardstate *cs)
581 } 573 }
582 574
583 spin_lock_irqsave(&cs->ev_lock, flags); 575 spin_lock_irqsave(&cs->ev_lock, flags);
584 head = atomic_read(&cs->ev_head); 576 head = cs->ev_head;
585 tail = atomic_read(&cs->ev_tail); 577 tail = cs->ev_tail;
586 578
587 abort = 1; 579 abort = 1;
588 curarg = 0; 580 curarg = 0;
@@ -715,7 +707,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
715 break; 707 break;
716 } 708 }
717 709
718 atomic_set(&cs->ev_tail, tail); 710 cs->ev_tail = tail;
719 spin_unlock_irqrestore(&cs->ev_lock, flags); 711 spin_unlock_irqrestore(&cs->ev_lock, flags);
720 712
721 if (curarg != params) 713 if (curarg != params)
@@ -734,14 +726,16 @@ static void disconnect(struct at_state_t **at_state_p)
734 struct bc_state *bcs = (*at_state_p)->bcs; 726 struct bc_state *bcs = (*at_state_p)->bcs;
735 struct cardstate *cs = (*at_state_p)->cs; 727 struct cardstate *cs = (*at_state_p)->cs;
736 728
737 new_index(&(*at_state_p)->seq_index, MAX_SEQ_INDEX); 729 spin_lock_irqsave(&cs->lock, flags);
730 ++(*at_state_p)->seq_index;
738 731
739 /* revert to selected idle mode */ 732 /* revert to selected idle mode */
740 if (!atomic_read(&cs->cidmode)) { 733 if (!cs->cidmode) {
741 cs->at_state.pending_commands |= PC_UMMODE; 734 cs->at_state.pending_commands |= PC_UMMODE;
742 atomic_set(&cs->commands_pending, 1); //FIXME 735 atomic_set(&cs->commands_pending, 1); //FIXME
743 gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); 736 gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE");
744 } 737 }
738 spin_unlock_irqrestore(&cs->lock, flags);
745 739
746 if (bcs) { 740 if (bcs) {
747 /* B channel assigned: invoke hardware specific handler */ 741 /* B channel assigned: invoke hardware specific handler */
@@ -933,17 +927,21 @@ static void bchannel_up(struct bc_state *bcs)
933 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); 927 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN);
934} 928}
935 929
936static void start_dial(struct at_state_t *at_state, void *data, int seq_index) 930static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index)
937{ 931{
938 struct bc_state *bcs = at_state->bcs; 932 struct bc_state *bcs = at_state->bcs;
939 struct cardstate *cs = at_state->cs; 933 struct cardstate *cs = at_state->cs;
940 int retval; 934 int retval;
935 unsigned long flags;
941 936
942 bcs->chstate |= CHS_NOTIFY_LL; 937 bcs->chstate |= CHS_NOTIFY_LL;
943 //atomic_set(&bcs->status, BCS_INIT);
944 938
945 if (atomic_read(&at_state->seq_index) != seq_index) 939 spin_lock_irqsave(&cs->lock, flags);
940 if (at_state->seq_index != seq_index) {
941 spin_unlock_irqrestore(&cs->lock, flags);
946 goto error; 942 goto error;
943 }
944 spin_unlock_irqrestore(&cs->lock, flags);
947 945
948 retval = gigaset_isdn_setup_dial(at_state, data); 946 retval = gigaset_isdn_setup_dial(at_state, data);
949 if (retval != 0) 947 if (retval != 0)
@@ -988,6 +986,7 @@ static void do_start(struct cardstate *cs)
988 if (atomic_read(&cs->mstate) != MS_LOCKED) 986 if (atomic_read(&cs->mstate) != MS_LOCKED)
989 schedule_init(cs, MS_INIT); 987 schedule_init(cs, MS_INIT);
990 988
989 cs->isdn_up = 1;
991 gigaset_i4l_cmd(cs, ISDN_STAT_RUN); 990 gigaset_i4l_cmd(cs, ISDN_STAT_RUN);
992 // FIXME: not in locked mode 991 // FIXME: not in locked mode
993 // FIXME 2: only after init sequence 992 // FIXME 2: only after init sequence
@@ -1003,6 +1002,12 @@ static void finish_shutdown(struct cardstate *cs)
1003 atomic_set(&cs->mode, M_UNKNOWN); 1002 atomic_set(&cs->mode, M_UNKNOWN);
1004 } 1003 }
1005 1004
1005 /* Tell the LL that the device is not available .. */
1006 if (cs->isdn_up) {
1007 cs->isdn_up = 0;
1008 gigaset_i4l_cmd(cs, ISDN_STAT_STOP);
1009 }
1010
1006 /* The rest is done by cleanup_cs () in user mode. */ 1011 /* The rest is done by cleanup_cs () in user mode. */
1007 1012
1008 cs->cmd_result = -ENODEV; 1013 cs->cmd_result = -ENODEV;
@@ -1025,6 +1030,12 @@ static void do_shutdown(struct cardstate *cs)
1025 1030
1026static void do_stop(struct cardstate *cs) 1031static void do_stop(struct cardstate *cs)
1027{ 1032{
1033 unsigned long flags;
1034
1035 spin_lock_irqsave(&cs->lock, flags);
1036 cs->connected = 0;
1037 spin_unlock_irqrestore(&cs->lock, flags);
1038
1028 do_shutdown(cs); 1039 do_shutdown(cs);
1029} 1040}
1030 1041
@@ -1153,7 +1164,7 @@ static int do_unlock(struct cardstate *cs)
1153 atomic_set(&cs->mstate, MS_UNINITIALIZED); 1164 atomic_set(&cs->mstate, MS_UNINITIALIZED);
1154 atomic_set(&cs->mode, M_UNKNOWN); 1165 atomic_set(&cs->mode, M_UNKNOWN);
1155 gigaset_free_channels(cs); 1166 gigaset_free_channels(cs);
1156 if (atomic_read(&cs->connected)) 1167 if (cs->connected)
1157 schedule_init(cs, MS_INIT); 1168 schedule_init(cs, MS_INIT);
1158 1169
1159 return 0; 1170 return 0;
@@ -1185,11 +1196,14 @@ static void do_action(int action, struct cardstate *cs,
1185 cs->at_state.pending_commands &= ~PC_INIT; 1196 cs->at_state.pending_commands &= ~PC_INIT;
1186 cs->cur_at_seq = SEQ_NONE; 1197 cs->cur_at_seq = SEQ_NONE;
1187 atomic_set(&cs->mode, M_UNIMODEM); 1198 atomic_set(&cs->mode, M_UNIMODEM);
1188 if (!atomic_read(&cs->cidmode)) { 1199 spin_lock_irqsave(&cs->lock, flags);
1200 if (!cs->cidmode) {
1201 spin_unlock_irqrestore(&cs->lock, flags);
1189 gigaset_free_channels(cs); 1202 gigaset_free_channels(cs);
1190 atomic_set(&cs->mstate, MS_READY); 1203 atomic_set(&cs->mstate, MS_READY);
1191 break; 1204 break;
1192 } 1205 }
1206 spin_unlock_irqrestore(&cs->lock, flags);
1193 cs->at_state.pending_commands |= PC_CIDMODE; 1207 cs->at_state.pending_commands |= PC_CIDMODE;
1194 atomic_set(&cs->commands_pending, 1); 1208 atomic_set(&cs->commands_pending, 1);
1195 gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); 1209 gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
@@ -1536,8 +1550,9 @@ static void do_action(int action, struct cardstate *cs,
1536 1550
1537 /* events from the proc file system */ // FIXME without ACT_xxxx? 1551 /* events from the proc file system */ // FIXME without ACT_xxxx?
1538 case ACT_PROC_CIDMODE: 1552 case ACT_PROC_CIDMODE:
1539 if (ev->parameter != atomic_read(&cs->cidmode)) { 1553 spin_lock_irqsave(&cs->lock, flags);
1540 atomic_set(&cs->cidmode, ev->parameter); 1554 if (ev->parameter != cs->cidmode) {
1555 cs->cidmode = ev->parameter;
1541 if (ev->parameter) { 1556 if (ev->parameter) {
1542 cs->at_state.pending_commands |= PC_CIDMODE; 1557 cs->at_state.pending_commands |= PC_CIDMODE;
1543 gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); 1558 gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
@@ -1547,6 +1562,7 @@ static void do_action(int action, struct cardstate *cs,
1547 } 1562 }
1548 atomic_set(&cs->commands_pending, 1); 1563 atomic_set(&cs->commands_pending, 1);
1549 } 1564 }
1565 spin_unlock_irqrestore(&cs->lock, flags);
1550 cs->waiting = 0; 1566 cs->waiting = 0;
1551 wake_up(&cs->waitqueue); 1567 wake_up(&cs->waitqueue);
1552 break; 1568 break;
@@ -1615,8 +1631,9 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1615 /* Setting the pointer to the dial array */ 1631 /* Setting the pointer to the dial array */
1616 rep = at_state->replystruct; 1632 rep = at_state->replystruct;
1617 1633
1634 spin_lock_irqsave(&cs->lock, flags);
1618 if (ev->type == EV_TIMEOUT) { 1635 if (ev->type == EV_TIMEOUT) {
1619 if (ev->parameter != atomic_read(&at_state->timer_index) 1636 if (ev->parameter != at_state->timer_index
1620 || !at_state->timer_active) { 1637 || !at_state->timer_active) {
1621 ev->type = RSP_NONE; /* old timeout */ 1638 ev->type = RSP_NONE; /* old timeout */
1622 gig_dbg(DEBUG_ANY, "old timeout"); 1639 gig_dbg(DEBUG_ANY, "old timeout");
@@ -1625,6 +1642,7 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1625 else 1642 else
1626 gig_dbg(DEBUG_ANY, "stopped waiting"); 1643 gig_dbg(DEBUG_ANY, "stopped waiting");
1627 } 1644 }
1645 spin_unlock_irqrestore(&cs->lock, flags);
1628 1646
1629 /* if the response belongs to a variable in at_state->int_var[VAR_XXXX] 1647 /* if the response belongs to a variable in at_state->int_var[VAR_XXXX]
1630 or at_state->str_var[STR_XXXX], set it */ 1648 or at_state->str_var[STR_XXXX], set it */
@@ -1686,7 +1704,7 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1686 } else { 1704 } else {
1687 /* Send command to modem if not NULL... */ 1705 /* Send command to modem if not NULL... */
1688 if (p_command/*rep->command*/) { 1706 if (p_command/*rep->command*/) {
1689 if (atomic_read(&cs->connected)) 1707 if (cs->connected)
1690 send_command(cs, p_command, 1708 send_command(cs, p_command,
1691 sendcid, cs->dle, 1709 sendcid, cs->dle,
1692 GFP_ATOMIC); 1710 GFP_ATOMIC);
@@ -1703,8 +1721,7 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1703 } else if (rep->timeout > 0) { /* new timeout */ 1721 } else if (rep->timeout > 0) { /* new timeout */
1704 at_state->timer_expires = rep->timeout * 10; 1722 at_state->timer_expires = rep->timeout * 10;
1705 at_state->timer_active = 1; 1723 at_state->timer_active = 1;
1706 new_index(&at_state->timer_index, 1724 ++at_state->timer_index;
1707 MAX_TIMER_INDEX);
1708 } 1725 }
1709 spin_unlock_irqrestore(&cs->lock, flags); 1726 spin_unlock_irqrestore(&cs->lock, flags);
1710 } 1727 }
@@ -1724,6 +1741,7 @@ static void process_command_flags(struct cardstate *cs)
1724 struct bc_state *bcs; 1741 struct bc_state *bcs;
1725 int i; 1742 int i;
1726 int sequence; 1743 int sequence;
1744 unsigned long flags;
1727 1745
1728 atomic_set(&cs->commands_pending, 0); 1746 atomic_set(&cs->commands_pending, 0);
1729 1747
@@ -1773,8 +1791,9 @@ static void process_command_flags(struct cardstate *cs)
1773 } 1791 }
1774 1792
1775 /* only switch back to unimodem mode, if no commands are pending and no channels are up */ 1793 /* only switch back to unimodem mode, if no commands are pending and no channels are up */
1794 spin_lock_irqsave(&cs->lock, flags);
1776 if (cs->at_state.pending_commands == PC_UMMODE 1795 if (cs->at_state.pending_commands == PC_UMMODE
1777 && !atomic_read(&cs->cidmode) 1796 && !cs->cidmode
1778 && list_empty(&cs->temp_at_states) 1797 && list_empty(&cs->temp_at_states)
1779 && atomic_read(&cs->mode) == M_CID) { 1798 && atomic_read(&cs->mode) == M_CID) {
1780 sequence = SEQ_UMMODE; 1799 sequence = SEQ_UMMODE;
@@ -1788,6 +1807,7 @@ static void process_command_flags(struct cardstate *cs)
1788 } 1807 }
1789 } 1808 }
1790 } 1809 }
1810 spin_unlock_irqrestore(&cs->lock, flags);
1791 cs->at_state.pending_commands &= ~PC_UMMODE; 1811 cs->at_state.pending_commands &= ~PC_UMMODE;
1792 if (sequence != SEQ_NONE) { 1812 if (sequence != SEQ_NONE) {
1793 schedule_sequence(cs, at_state, sequence); 1813 schedule_sequence(cs, at_state, sequence);
@@ -1900,18 +1920,21 @@ static void process_events(struct cardstate *cs)
1900 int i; 1920 int i;
1901 int check_flags = 0; 1921 int check_flags = 0;
1902 int was_busy; 1922 int was_busy;
1923 unsigned long flags;
1903 1924
1904 /* no locking needed (only one reader) */ 1925 spin_lock_irqsave(&cs->ev_lock, flags);
1905 head = atomic_read(&cs->ev_head); 1926 head = cs->ev_head;
1906 1927
1907 for (i = 0; i < 2 * MAX_EVENTS; ++i) { 1928 for (i = 0; i < 2 * MAX_EVENTS; ++i) {
1908 tail = atomic_read(&cs->ev_tail); 1929 tail = cs->ev_tail;
1909 if (tail == head) { 1930 if (tail == head) {
1910 if (!check_flags && !atomic_read(&cs->commands_pending)) 1931 if (!check_flags && !atomic_read(&cs->commands_pending))
1911 break; 1932 break;
1912 check_flags = 0; 1933 check_flags = 0;
1934 spin_unlock_irqrestore(&cs->ev_lock, flags);
1913 process_command_flags(cs); 1935 process_command_flags(cs);
1914 tail = atomic_read(&cs->ev_tail); 1936 spin_lock_irqsave(&cs->ev_lock, flags);
1937 tail = cs->ev_tail;
1915 if (tail == head) { 1938 if (tail == head) {
1916 if (!atomic_read(&cs->commands_pending)) 1939 if (!atomic_read(&cs->commands_pending))
1917 break; 1940 break;
@@ -1921,16 +1944,20 @@ static void process_events(struct cardstate *cs)
1921 1944
1922 ev = cs->events + head; 1945 ev = cs->events + head;
1923 was_busy = cs->cur_at_seq != SEQ_NONE; 1946 was_busy = cs->cur_at_seq != SEQ_NONE;
1947 spin_unlock_irqrestore(&cs->ev_lock, flags);
1924 process_event(cs, ev); 1948 process_event(cs, ev);
1949 spin_lock_irqsave(&cs->ev_lock, flags);
1925 kfree(ev->ptr); 1950 kfree(ev->ptr);
1926 ev->ptr = NULL; 1951 ev->ptr = NULL;
1927 if (was_busy && cs->cur_at_seq == SEQ_NONE) 1952 if (was_busy && cs->cur_at_seq == SEQ_NONE)
1928 check_flags = 1; 1953 check_flags = 1;
1929 1954
1930 head = (head + 1) % MAX_EVENTS; 1955 head = (head + 1) % MAX_EVENTS;
1931 atomic_set(&cs->ev_head, head); 1956 cs->ev_head = head;
1932 } 1957 }
1933 1958
1959 spin_unlock_irqrestore(&cs->ev_lock, flags);
1960
1934 if (i == 2 * MAX_EVENTS) { 1961 if (i == 2 * MAX_EVENTS) {
1935 dev_err(cs->dev, 1962 dev_err(cs->dev,
1936 "infinite loop in process_events; aborting.\n"); 1963 "infinite loop in process_events; aborting.\n");
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 39a883ebc696..350dfcf15e6c 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -55,9 +55,6 @@
55#define GIG_RETRYCID 55#define GIG_RETRYCID
56#define GIG_X75 56#define GIG_X75
57 57
58#define MAX_TIMER_INDEX 1000
59#define MAX_SEQ_INDEX 1000
60
61#define GIG_TICK 100 /* in milliseconds */ 58#define GIG_TICK 100 /* in milliseconds */
62 59
63/* timeout values (unit: 1 sec) */ 60/* timeout values (unit: 1 sec) */
@@ -375,7 +372,7 @@ struct at_state_t {
375 struct list_head list; 372 struct list_head list;
376 int waiting; 373 int waiting;
377 int getstring; 374 int getstring;
378 atomic_t timer_index; 375 unsigned timer_index;
379 unsigned long timer_expires; 376 unsigned long timer_expires;
380 int timer_active; 377 int timer_active;
381 unsigned int ConState; /* State of connection */ 378 unsigned int ConState; /* State of connection */
@@ -384,7 +381,7 @@ struct at_state_t {
384 int int_var[VAR_NUM]; /* see VAR_XXXX */ 381 int int_var[VAR_NUM]; /* see VAR_XXXX */
385 char *str_var[STR_NUM]; /* see STR_XXXX */ 382 char *str_var[STR_NUM]; /* see STR_XXXX */
386 unsigned pending_commands; /* see PC_XXXX */ 383 unsigned pending_commands; /* see PC_XXXX */
387 atomic_t seq_index; 384 unsigned seq_index;
388 385
389 struct cardstate *cs; 386 struct cardstate *cs;
390 struct bc_state *bcs; 387 struct bc_state *bcs;
@@ -484,10 +481,11 @@ struct cardstate {
484 unsigned fwver[4]; 481 unsigned fwver[4];
485 int gotfwver; 482 int gotfwver;
486 483
487 atomic_t running; /* !=0 if events are handled */ 484 unsigned running; /* !=0 if events are handled */
488 atomic_t connected; /* !=0 if hardware is connected */ 485 unsigned connected; /* !=0 if hardware is connected */
486 unsigned isdn_up; /* !=0 after ISDN_STAT_RUN */
489 487
490 atomic_t cidmode; 488 unsigned cidmode;
491 489
492 int myid; /* id for communication with LL */ 490 int myid; /* id for communication with LL */
493 isdn_if iif; 491 isdn_if iif;
@@ -528,7 +526,7 @@ struct cardstate {
528 526
529 /* event queue */ 527 /* event queue */
530 struct event_t events[MAX_EVENTS]; 528 struct event_t events[MAX_EVENTS];
531 atomic_t ev_tail, ev_head; 529 unsigned ev_tail, ev_head;
532 spinlock_t ev_lock; 530 spinlock_t ev_lock;
533 531
534 /* current modem response */ 532 /* current modem response */
@@ -824,7 +822,7 @@ static inline void gigaset_schedule_event(struct cardstate *cs)
824{ 822{
825 unsigned long flags; 823 unsigned long flags;
826 spin_lock_irqsave(&cs->lock, flags); 824 spin_lock_irqsave(&cs->lock, flags);
827 if (atomic_read(&cs->running)) 825 if (cs->running)
828 tasklet_schedule(&cs->event_tasklet); 826 tasklet_schedule(&cs->event_tasklet);
829 spin_unlock_irqrestore(&cs->lock, flags); 827 spin_unlock_irqrestore(&cs->lock, flags);
830} 828}
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 7059b84b96a7..0815dbfb8291 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -56,11 +56,6 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
56 "Receiving data from LL (id: %d, ch: %d, ack: %d, sz: %d)", 56 "Receiving data from LL (id: %d, ch: %d, ack: %d, sz: %d)",
57 driverID, channel, ack, len); 57 driverID, channel, ack, len);
58 58
59 if (!atomic_read(&cs->connected)) {
60 err("%s: disconnected", __func__);
61 return -ENODEV;
62 }
63
64 if (!len) { 59 if (!len) {
65 if (ack) 60 if (ack)
66 notice("%s: not ACKing empty packet", __func__); 61 notice("%s: not ACKing empty packet", __func__);
@@ -78,7 +73,7 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
78 len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]); 73 len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]);
79 74
80 /* pass to device-specific module */ 75 /* pass to device-specific module */
81 return cs->ops->send_skb(bcs, skb); 76 return cs->ops->send_skb(bcs, skb); //FIXME cs->ops->send_skb() must handle !cs->connected correctly
82} 77}
83 78
84void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) 79void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
@@ -119,11 +114,12 @@ static int command_from_LL(isdn_ctrl *cntrl)
119 struct bc_state *bcs; 114 struct bc_state *bcs;
120 int retval = 0; 115 int retval = 0;
121 struct setup_parm *sp; 116 struct setup_parm *sp;
117 unsigned param;
118 unsigned long flags;
122 119
123 gigaset_debugdrivers(); 120 gigaset_debugdrivers();
124 121
125 //FIXME "remove test for &connected" 122 if (!cs) {
126 if ((!cs || !atomic_read(&cs->connected))) {
127 warn("LL tried to access unknown device with nr. %d", 123 warn("LL tried to access unknown device with nr. %d",
128 cntrl->driver); 124 cntrl->driver);
129 return -ENODEV; 125 return -ENODEV;
@@ -166,8 +162,11 @@ static int command_from_LL(isdn_ctrl *cntrl)
166 } 162 }
167 *sp = cntrl->parm.setup; 163 *sp = cntrl->parm.setup;
168 164
169 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, 165 spin_lock_irqsave(&cs->lock, flags);
170 atomic_read(&bcs->at_state.seq_index), 166 param = bcs->at_state.seq_index;
167 spin_unlock_irqrestore(&cs->lock, flags);
168
169 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, param,
171 NULL)) { 170 NULL)) {
172 //FIXME what should we do? 171 //FIXME what should we do?
173 kfree(sp); 172 kfree(sp);
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index ac408acaaf17..08e4c4eea14d 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -33,7 +33,7 @@ static int if_lock(struct cardstate *cs, int *arg)
33 } 33 }
34 34
35 if (!cmd && atomic_read(&cs->mstate) == MS_LOCKED 35 if (!cmd && atomic_read(&cs->mstate) == MS_LOCKED
36 && atomic_read(&cs->connected)) { 36 && cs->connected) {
37 cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); 37 cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS);
38 cs->ops->baud_rate(cs, B115200); 38 cs->ops->baud_rate(cs, B115200);
39 cs->ops->set_line_ctrl(cs, CS8); 39 cs->ops->set_line_ctrl(cs, CS8);
@@ -107,6 +107,11 @@ static int if_config(struct cardstate *cs, int *arg)
107 if (atomic_read(&cs->mstate) != MS_LOCKED) 107 if (atomic_read(&cs->mstate) != MS_LOCKED)
108 return -EBUSY; 108 return -EBUSY;
109 109
110 if (!cs->connected) {
111 err("not connected!");
112 return -ENODEV;
113 }
114
110 *arg = 0; 115 *arg = 0;
111 return gigaset_enterconfigmode(cs); 116 return gigaset_enterconfigmode(cs);
112} 117}
@@ -246,7 +251,7 @@ static int if_ioctl(struct tty_struct *tty, struct file *file,
246 break; 251 break;
247 case GIGASET_BRKCHARS: 252 case GIGASET_BRKCHARS:
248 //FIXME test if MS_LOCKED 253 //FIXME test if MS_LOCKED
249 if (!atomic_read(&cs->connected)) { 254 if (!cs->connected) {
250 gig_dbg(DEBUG_ANY, 255 gig_dbg(DEBUG_ANY,
251 "can't communicate with unplugged device"); 256 "can't communicate with unplugged device");
252 retval = -ENODEV; 257 retval = -ENODEV;
@@ -327,7 +332,7 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file,
327 if (mutex_lock_interruptible(&cs->mutex)) 332 if (mutex_lock_interruptible(&cs->mutex))
328 return -ERESTARTSYS; // FIXME -EINTR? 333 return -ERESTARTSYS; // FIXME -EINTR?
329 334
330 if (!atomic_read(&cs->connected)) { 335 if (!cs->connected) {
331 gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); 336 gig_dbg(DEBUG_ANY, "can't communicate with unplugged device");
332 retval = -ENODEV; 337 retval = -ENODEV;
333 } else { 338 } else {
@@ -362,7 +367,7 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count)
362 else if (atomic_read(&cs->mstate) != MS_LOCKED) { 367 else if (atomic_read(&cs->mstate) != MS_LOCKED) {
363 warn("can't write to unlocked device"); 368 warn("can't write to unlocked device");
364 retval = -EBUSY; 369 retval = -EBUSY;
365 } else if (!atomic_read(&cs->connected)) { 370 } else if (!cs->connected) {
366 gig_dbg(DEBUG_ANY, "can't write to unplugged device"); 371 gig_dbg(DEBUG_ANY, "can't write to unplugged device");
367 retval = -EBUSY; //FIXME 372 retval = -EBUSY; //FIXME
368 } else { 373 } else {
@@ -396,7 +401,7 @@ static int if_write_room(struct tty_struct *tty)
396 else if (atomic_read(&cs->mstate) != MS_LOCKED) { 401 else if (atomic_read(&cs->mstate) != MS_LOCKED) {
397 warn("can't write to unlocked device"); 402 warn("can't write to unlocked device");
398 retval = -EBUSY; //FIXME 403 retval = -EBUSY; //FIXME
399 } else if (!atomic_read(&cs->connected)) { 404 } else if (!cs->connected) {
400 gig_dbg(DEBUG_ANY, "can't write to unplugged device"); 405 gig_dbg(DEBUG_ANY, "can't write to unplugged device");
401 retval = -EBUSY; //FIXME 406 retval = -EBUSY; //FIXME
402 } else 407 } else
@@ -428,7 +433,7 @@ static int if_chars_in_buffer(struct tty_struct *tty)
428 else if (atomic_read(&cs->mstate) != MS_LOCKED) { 433 else if (atomic_read(&cs->mstate) != MS_LOCKED) {
429 warn("can't write to unlocked device"); 434 warn("can't write to unlocked device");
430 retval = -EBUSY; 435 retval = -EBUSY;
431 } else if (!atomic_read(&cs->connected)) { 436 } else if (!cs->connected) {
432 gig_dbg(DEBUG_ANY, "can't write to unplugged device"); 437 gig_dbg(DEBUG_ANY, "can't write to unplugged device");
433 retval = -EBUSY; //FIXME 438 retval = -EBUSY; //FIXME
434 } else 439 } else
@@ -508,7 +513,7 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old)
508 goto out; 513 goto out;
509 } 514 }
510 515
511 if (!atomic_read(&cs->connected)) { 516 if (!cs->connected) {
512 gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); 517 gig_dbg(DEBUG_ANY, "can't communicate with unplugged device");
513 goto out; 518 goto out;
514 } 519 }
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index 2f1628734a38..45f017ed6e8c 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -990,13 +990,17 @@ void gigaset_isoc_input(struct inbuf_t *inbuf)
990int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb) 990int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb)
991{ 991{
992 int len = skb->len; 992 int len = skb->len;
993 unsigned long flags;
993 994
994 skb_queue_tail(&bcs->squeue, skb); 995 skb_queue_tail(&bcs->squeue, skb);
995 gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d", 996 gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d",
996 __func__, skb_queue_len(&bcs->squeue)); 997 __func__, skb_queue_len(&bcs->squeue));
997 998
998 /* tasklet submits URB if necessary */ 999 /* tasklet submits URB if necessary */
999 tasklet_schedule(&bcs->hw.bas->sent_tasklet); 1000 spin_lock_irqsave(&bcs->cs->lock, flags);
1001 if (bcs->cs->connected)
1002 tasklet_schedule(&bcs->hw.bas->sent_tasklet);
1003 spin_unlock_irqrestore(&bcs->cs->lock, flags);
1000 1004
1001 return len; /* ok so far */ 1005 return len; /* ok so far */
1002} 1006}
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index 80d8ef1874f3..d267a636b53c 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -19,8 +19,15 @@
19static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr, 19static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr,
20 char *buf) 20 char *buf)
21{ 21{
22 int ret;
23 unsigned long flags;
22 struct cardstate *cs = dev_get_drvdata(dev); 24 struct cardstate *cs = dev_get_drvdata(dev);
23 return sprintf(buf, "%d\n", atomic_read(&cs->cidmode)); 25
26 spin_lock_irqsave(&cs->lock, flags);
27 ret = sprintf(buf, "%u\n", cs->cidmode);
28 spin_unlock_irqrestore(&cs->lock, flags);
29
30 return ret;
24} 31}
25 32
26static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, 33static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index fe8435b8fa97..bfb73fd5077e 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -371,13 +371,14 @@ static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs)
371 int r; 371 int r;
372 unsigned numbytes; 372 unsigned numbytes;
373 unsigned char *src; 373 unsigned char *src;
374 374 unsigned long flags;
375 if (!atomic_read(&cs->connected)) {
376 err("%s: disconnected", __func__);
377 return;
378 }
379 375
380 if (!urb->status) { 376 if (!urb->status) {
377 if (!cs->connected) {
378 err("%s: disconnected", __func__); /* should never happen */
379 return;
380 }
381
381 numbytes = urb->actual_length; 382 numbytes = urb->actual_length;
382 383
383 if (numbytes) { 384 if (numbytes) {
@@ -399,12 +400,19 @@ static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs)
399 /* The urb might have been killed. */ 400 /* The urb might have been killed. */
400 gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", 401 gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d",
401 __func__, urb->status); 402 __func__, urb->status);
402 if (urb->status != -ENOENT) /* not killed */ 403 if (urb->status != -ENOENT) { /* not killed */
404 if (!cs->connected) {
405 err("%s: disconnected", __func__); /* should never happen */
406 return;
407 }
403 resubmit = 1; 408 resubmit = 1;
409 }
404 } 410 }
405 411
406 if (resubmit) { 412 if (resubmit) {
407 r = usb_submit_urb(urb, SLAB_ATOMIC); 413 spin_lock_irqsave(&cs->lock, flags);
414 r = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
415 spin_unlock_irqrestore(&cs->lock, flags);
408 if (r) 416 if (r)
409 dev_err(cs->dev, "error %d when resubmitting urb.\n", 417 dev_err(cs->dev, "error %d when resubmitting urb.\n",
410 -r); 418 -r);
@@ -416,21 +424,22 @@ static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs)
416static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs) 424static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
417{ 425{
418 struct cardstate *cs = urb->context; 426 struct cardstate *cs = urb->context;
427 unsigned long flags;
419 428
420#ifdef CONFIG_GIGASET_DEBUG
421 if (!atomic_read(&cs->connected)) {
422 err("%s: not connected", __func__);
423 return;
424 }
425#endif
426 if (urb->status) 429 if (urb->status)
427 dev_err(cs->dev, "bulk transfer failed (status %d)\n", 430 dev_err(cs->dev, "bulk transfer failed (status %d)\n",
428 -urb->status); 431 -urb->status);
429 /* That's all we can do. Communication problems 432 /* That's all we can do. Communication problems
430 are handled by timeouts or network protocols. */ 433 are handled by timeouts or network protocols. */
431 434
432 atomic_set(&cs->hw.usb->busy, 0); 435 spin_lock_irqsave(&cs->lock, flags);
433 tasklet_schedule(&cs->write_tasklet); 436 if (!cs->connected) {
437 err("%s: not connected", __func__);
438 } else {
439 atomic_set(&cs->hw.usb->busy, 0);
440 tasklet_schedule(&cs->write_tasklet);
441 }
442 spin_unlock_irqrestore(&cs->lock, flags);
434} 443}
435 444
436static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) 445static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
@@ -465,6 +474,8 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
465 } 474 }
466 if (cb) { 475 if (cb) {
467 count = min(cb->len, ucs->bulk_out_size); 476 count = min(cb->len, ucs->bulk_out_size);
477 gig_dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count);
478
468 usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, 479 usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
469 usb_sndbulkpipe(ucs->udev, 480 usb_sndbulkpipe(ucs->udev,
470 ucs->bulk_out_endpointAddr & 0x0f), 481 ucs->bulk_out_endpointAddr & 0x0f),
@@ -474,14 +485,15 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
474 cb->offset += count; 485 cb->offset += count;
475 cb->len -= count; 486 cb->len -= count;
476 atomic_set(&ucs->busy, 1); 487 atomic_set(&ucs->busy, 1);
477 gig_dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count);
478 488
479 status = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); 489 spin_lock_irqsave(&cs->lock, flags);
490 status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC) : -ENODEV;
491 spin_unlock_irqrestore(&cs->lock, flags);
492
480 if (status) { 493 if (status) {
481 atomic_set(&ucs->busy, 0); 494 atomic_set(&ucs->busy, 0);
482 dev_err(cs->dev, 495 err("could not submit urb (error %d)\n",
483 "could not submit urb (error %d)\n", 496 -status);
484 -status);
485 cb->len = 0; /* skip urb => remove cb+wakeup 497 cb->len = 0; /* skip urb => remove cb+wakeup
486 in next loop cycle */ 498 in next loop cycle */
487 } 499 }
@@ -502,11 +514,6 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
502 DEBUG_TRANSCMD : DEBUG_LOCKCMD, 514 DEBUG_TRANSCMD : DEBUG_LOCKCMD,
503 "CMD Transmit", len, buf); 515 "CMD Transmit", len, buf);
504 516
505 if (!atomic_read(&cs->connected)) {
506 err("%s: not connected", __func__);
507 return -ENODEV;
508 }
509
510 if (len <= 0) 517 if (len <= 0)
511 return 0; 518 return 0;
512 519
@@ -533,7 +540,10 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
533 cs->lastcmdbuf = cb; 540 cs->lastcmdbuf = cb;
534 spin_unlock_irqrestore(&cs->cmdlock, flags); 541 spin_unlock_irqrestore(&cs->cmdlock, flags);
535 542
536 tasklet_schedule(&cs->write_tasklet); 543 spin_lock_irqsave(&cs->lock, flags);
544 if (cs->connected)
545 tasklet_schedule(&cs->write_tasklet);
546 spin_unlock_irqrestore(&cs->lock, flags);
537 return len; 547 return len;
538} 548}
539 549
@@ -629,6 +639,7 @@ static int write_modem(struct cardstate *cs)
629 int count; 639 int count;
630 struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ 640 struct bc_state *bcs = &cs->bcs[0]; /* only one channel */
631 struct usb_cardstate *ucs = cs->hw.usb; 641 struct usb_cardstate *ucs = cs->hw.usb;
642 unsigned long flags;
632 643
633 gig_dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len); 644 gig_dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len);
634 645
@@ -644,20 +655,27 @@ static int write_modem(struct cardstate *cs)
644 count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); 655 count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size);
645 memcpy(ucs->bulk_out_buffer, bcs->tx_skb->data, count); 656 memcpy(ucs->bulk_out_buffer, bcs->tx_skb->data, count);
646 skb_pull(bcs->tx_skb, count); 657 skb_pull(bcs->tx_skb, count);
647
648 usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
649 usb_sndbulkpipe(ucs->udev,
650 ucs->bulk_out_endpointAddr & 0x0f),
651 ucs->bulk_out_buffer, count,
652 gigaset_write_bulk_callback, cs);
653 atomic_set(&ucs->busy, 1); 658 atomic_set(&ucs->busy, 1);
654 gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); 659 gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count);
655 660
656 ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); 661 spin_lock_irqsave(&cs->lock, flags);
662 if (cs->connected) {
663 usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
664 usb_sndbulkpipe(ucs->udev,
665 ucs->bulk_out_endpointAddr & 0x0f),
666 ucs->bulk_out_buffer, count,
667 gigaset_write_bulk_callback, cs);
668 ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC);
669 } else {
670 ret = -ENODEV;
671 }
672 spin_unlock_irqrestore(&cs->lock, flags);
673
657 if (ret) { 674 if (ret) {
658 dev_err(cs->dev, "could not submit urb (error %d)\n", -ret); 675 err("could not submit urb (error %d)\n", -ret);
659 atomic_set(&ucs->busy, 0); 676 atomic_set(&ucs->busy, 0);
660 } 677 }
678
661 if (!bcs->tx_skb->len) { 679 if (!bcs->tx_skb->len) {
662 /* skb sent completely */ 680 /* skb sent completely */
663 gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0? 681 gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0?