aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/isdnloop
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/isdnloop')
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c70
-rw-r--r--drivers/isdn/isdnloop/isdnloop.h1
2 files changed, 31 insertions, 40 deletions
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index fabbd461603e..23afba46433e 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -100,12 +100,11 @@ isdnloop_pollbchan(unsigned long data)
100 isdnloop_bchan_send(card, 1); 100 isdnloop_bchan_send(card, 1);
101 if (card->flags & (ISDNLOOP_FLAGS_B1ACTIVE | ISDNLOOP_FLAGS_B2ACTIVE)) { 101 if (card->flags & (ISDNLOOP_FLAGS_B1ACTIVE | ISDNLOOP_FLAGS_B2ACTIVE)) {
102 /* schedule b-channel polling again */ 102 /* schedule b-channel polling again */
103 save_flags(flags); 103 spin_lock_irqsave(&card->isdnloop_lock, flags);
104 cli();
105 card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD; 104 card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD;
106 add_timer(&card->rb_timer); 105 add_timer(&card->rb_timer);
107 card->flags |= ISDNLOOP_FLAGS_RBTIMER; 106 card->flags |= ISDNLOOP_FLAGS_RBTIMER;
108 restore_flags(flags); 107 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
109 } else 108 } else
110 card->flags &= ~ISDNLOOP_FLAGS_RBTIMER; 109 card->flags &= ~ISDNLOOP_FLAGS_RBTIMER;
111} 110}
@@ -281,8 +280,7 @@ isdnloop_putmsg(isdnloop_card * card, unsigned char c)
281{ 280{
282 ulong flags; 281 ulong flags;
283 282
284 save_flags(flags); 283 spin_lock_irqsave(&card->isdnloop_lock, flags);
285 cli();
286 *card->msg_buf_write++ = (c == 0xff) ? '\n' : c; 284 *card->msg_buf_write++ = (c == 0xff) ? '\n' : c;
287 if (card->msg_buf_write == card->msg_buf_read) { 285 if (card->msg_buf_write == card->msg_buf_read) {
288 if (++card->msg_buf_read > card->msg_buf_end) 286 if (++card->msg_buf_read > card->msg_buf_end)
@@ -290,7 +288,7 @@ isdnloop_putmsg(isdnloop_card * card, unsigned char c)
290 } 288 }
291 if (card->msg_buf_write > card->msg_buf_end) 289 if (card->msg_buf_write > card->msg_buf_end)
292 card->msg_buf_write = card->msg_buf; 290 card->msg_buf_write = card->msg_buf;
293 restore_flags(flags); 291 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
294} 292}
295 293
296/* 294/*
@@ -372,21 +370,19 @@ isdnloop_polldchan(unsigned long data)
372 if (!(card->flags & ISDNLOOP_FLAGS_RBTIMER)) { 370 if (!(card->flags & ISDNLOOP_FLAGS_RBTIMER)) {
373 /* schedule b-channel polling */ 371 /* schedule b-channel polling */
374 card->flags |= ISDNLOOP_FLAGS_RBTIMER; 372 card->flags |= ISDNLOOP_FLAGS_RBTIMER;
375 save_flags(flags); 373 spin_lock_irqsave(&card->isdnloop_lock, flags);
376 cli();
377 del_timer(&card->rb_timer); 374 del_timer(&card->rb_timer);
378 card->rb_timer.function = isdnloop_pollbchan; 375 card->rb_timer.function = isdnloop_pollbchan;
379 card->rb_timer.data = (unsigned long) card; 376 card->rb_timer.data = (unsigned long) card;
380 card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD; 377 card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD;
381 add_timer(&card->rb_timer); 378 add_timer(&card->rb_timer);
382 restore_flags(flags); 379 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
383 } 380 }
384 /* schedule again */ 381 /* schedule again */
385 save_flags(flags); 382 spin_lock_irqsave(&card->isdnloop_lock, flags);
386 cli();
387 card->st_timer.expires = jiffies + ISDNLOOP_TIMER_DCREAD; 383 card->st_timer.expires = jiffies + ISDNLOOP_TIMER_DCREAD;
388 add_timer(&card->st_timer); 384 add_timer(&card->st_timer);
389 restore_flags(flags); 385 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
390} 386}
391 387
392/* 388/*
@@ -416,8 +412,7 @@ isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card * card)
416 return 0; 412 return 0;
417 if (card->sndcount[channel] > ISDNLOOP_MAX_SQUEUE) 413 if (card->sndcount[channel] > ISDNLOOP_MAX_SQUEUE)
418 return 0; 414 return 0;
419 save_flags(flags); 415 spin_lock_irqsave(&card->isdnloop_lock, flags);
420 cli();
421 nskb = dev_alloc_skb(skb->len); 416 nskb = dev_alloc_skb(skb->len);
422 if (nskb) { 417 if (nskb) {
423 memcpy(skb_put(nskb, len), skb->data, len); 418 memcpy(skb_put(nskb, len), skb->data, len);
@@ -426,7 +421,7 @@ isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card * card)
426 } else 421 } else
427 len = 0; 422 len = 0;
428 card->sndcount[channel] += len; 423 card->sndcount[channel] += len;
429 restore_flags(flags); 424 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
430 } 425 }
431 return len; 426 return len;
432} 427}
@@ -576,8 +571,7 @@ isdnloop_atimeout(isdnloop_card * card, int ch)
576 unsigned long flags; 571 unsigned long flags;
577 char buf[60]; 572 char buf[60];
578 573
579 save_flags(flags); 574 spin_lock_irqsave(&card->isdnloop_lock, flags);
580 cli();
581 if (card->rcard) { 575 if (card->rcard) {
582 isdnloop_fake(card->rcard[ch], "DDIS_I", card->rch[ch] + 1); 576 isdnloop_fake(card->rcard[ch], "DDIS_I", card->rch[ch] + 1);
583 card->rcard[ch]->rcard[card->rch[ch]] = NULL; 577 card->rcard[ch]->rcard[card->rch[ch]] = NULL;
@@ -587,7 +581,7 @@ isdnloop_atimeout(isdnloop_card * card, int ch)
587 /* No user responding */ 581 /* No user responding */
588 sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 3)); 582 sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 3));
589 isdnloop_fake(card, buf, ch + 1); 583 isdnloop_fake(card, buf, ch + 1);
590 restore_flags(flags); 584 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
591} 585}
592 586
593/* 587/*
@@ -622,8 +616,7 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch)
622{ 616{
623 unsigned long flags; 617 unsigned long flags;
624 618
625 save_flags(flags); 619 spin_lock_irqsave(&card->isdnloop_lock, flags);
626 cli();
627 init_timer(&card->c_timer[ch]); 620 init_timer(&card->c_timer[ch]);
628 card->c_timer[ch].expires = jiffies + ISDNLOOP_TIMER_ALERTWAIT; 621 card->c_timer[ch].expires = jiffies + ISDNLOOP_TIMER_ALERTWAIT;
629 if (ch) 622 if (ch)
@@ -632,7 +625,7 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch)
632 card->c_timer[ch].function = isdnloop_atimeout0; 625 card->c_timer[ch].function = isdnloop_atimeout0;
633 card->c_timer[ch].data = (unsigned long) card; 626 card->c_timer[ch].data = (unsigned long) card;
634 add_timer(&card->c_timer[ch]); 627 add_timer(&card->c_timer[ch]);
635 restore_flags(flags); 628 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
636} 629}
637 630
638/* 631/*
@@ -647,10 +640,9 @@ isdnloop_kill_ctimer(isdnloop_card * card, int ch)
647{ 640{
648 unsigned long flags; 641 unsigned long flags;
649 642
650 save_flags(flags); 643 spin_lock_irqsave(&card->isdnloop_lock, flags);
651 cli();
652 del_timer(&card->c_timer[ch]); 644 del_timer(&card->c_timer[ch]);
653 restore_flags(flags); 645 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
654} 646}
655 647
656static u_char si2bit[] = 648static u_char si2bit[] =
@@ -706,13 +698,12 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd)
706 } 698 }
707 } 699 }
708 if (num_match) { 700 if (num_match) {
709 save_flags(flags); 701 spin_lock_irqsave(&card->isdnloop_lock, flags);
710 cli();
711 /* channel idle? */ 702 /* channel idle? */
712 if (!(cc->rcard[ch])) { 703 if (!(cc->rcard[ch])) {
713 /* Check SI */ 704 /* Check SI */
714 if (!(si2bit[cmd->parm.setup.si1] & cc->sil[ch])) { 705 if (!(si2bit[cmd->parm.setup.si1] & cc->sil[ch])) {
715 restore_flags(flags); 706 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
716 return 3; 707 return 3;
717 } 708 }
718 /* ch is idle, si and number matches */ 709 /* ch is idle, si and number matches */
@@ -720,10 +711,10 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd)
720 cc->rch[ch] = lch; 711 cc->rch[ch] = lch;
721 card->rcard[lch] = cc; 712 card->rcard[lch] = cc;
722 card->rch[lch] = ch; 713 card->rch[lch] = ch;
723 restore_flags(flags); 714 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
724 return 0; 715 return 0;
725 } else { 716 } else {
726 restore_flags(flags); 717 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
727 /* num matches, but busy */ 718 /* num matches, but busy */
728 if (ch == 1) 719 if (ch == 1)
729 return 1; 720 return 1;
@@ -1027,8 +1018,7 @@ isdnloop_stopcard(isdnloop_card * card)
1027 unsigned long flags; 1018 unsigned long flags;
1028 isdn_ctrl cmd; 1019 isdn_ctrl cmd;
1029 1020
1030 save_flags(flags); 1021 spin_lock_irqsave(&card->isdnloop_lock, flags);
1031 cli();
1032 if (card->flags & ISDNLOOP_FLAGS_RUNNING) { 1022 if (card->flags & ISDNLOOP_FLAGS_RUNNING) {
1033 card->flags &= ~ISDNLOOP_FLAGS_RUNNING; 1023 card->flags &= ~ISDNLOOP_FLAGS_RUNNING;
1034 del_timer(&card->st_timer); 1024 del_timer(&card->st_timer);
@@ -1039,7 +1029,7 @@ isdnloop_stopcard(isdnloop_card * card)
1039 cmd.driver = card->myid; 1029 cmd.driver = card->myid;
1040 card->interface.statcallb(&cmd); 1030 card->interface.statcallb(&cmd);
1041 } 1031 }
1042 restore_flags(flags); 1032 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1043} 1033}
1044 1034
1045/* 1035/*
@@ -1078,18 +1068,17 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
1078 return -EBUSY; 1068 return -EBUSY;
1079 if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef))) 1069 if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef)))
1080 return -EFAULT; 1070 return -EFAULT;
1081 save_flags(flags); 1071 spin_lock_irqsave(&card->isdnloop_lock, flags);
1082 cli();
1083 switch (sdef.ptype) { 1072 switch (sdef.ptype) {
1084 case ISDN_PTYPE_EURO: 1073 case ISDN_PTYPE_EURO:
1085 if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96", 1074 if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96",
1086 -1)) { 1075 -1)) {
1087 restore_flags(flags); 1076 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1088 return -ENOMEM; 1077 return -ENOMEM;
1089 } 1078 }
1090 card->sil[0] = card->sil[1] = 4; 1079 card->sil[0] = card->sil[1] = 4;
1091 if (isdnloop_fake(card, "TEI OK", 0)) { 1080 if (isdnloop_fake(card, "TEI OK", 0)) {
1092 restore_flags(flags); 1081 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1093 return -ENOMEM; 1082 return -ENOMEM;
1094 } 1083 }
1095 for (i = 0; i < 3; i++) 1084 for (i = 0; i < 3; i++)
@@ -1098,12 +1087,12 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
1098 case ISDN_PTYPE_1TR6: 1087 case ISDN_PTYPE_1TR6:
1099 if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95", 1088 if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95",
1100 -1)) { 1089 -1)) {
1101 restore_flags(flags); 1090 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1102 return -ENOMEM; 1091 return -ENOMEM;
1103 } 1092 }
1104 card->sil[0] = card->sil[1] = 4; 1093 card->sil[0] = card->sil[1] = 4;
1105 if (isdnloop_fake(card, "TEI OK", 0)) { 1094 if (isdnloop_fake(card, "TEI OK", 0)) {
1106 restore_flags(flags); 1095 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1107 return -ENOMEM; 1096 return -ENOMEM;
1108 } 1097 }
1109 strcpy(card->s0num[0], sdef.num[0]); 1098 strcpy(card->s0num[0], sdef.num[0]);
@@ -1111,7 +1100,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
1111 card->s0num[2][0] = '\0'; 1100 card->s0num[2][0] = '\0';
1112 break; 1101 break;
1113 default: 1102 default:
1114 restore_flags(flags); 1103 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1115 printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n", 1104 printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n",
1116 sdef.ptype); 1105 sdef.ptype);
1117 return -EINVAL; 1106 return -EINVAL;
@@ -1122,7 +1111,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
1122 card->st_timer.data = (unsigned long) card; 1111 card->st_timer.data = (unsigned long) card;
1123 add_timer(&card->st_timer); 1112 add_timer(&card->st_timer);
1124 card->flags |= ISDNLOOP_FLAGS_RUNNING; 1113 card->flags |= ISDNLOOP_FLAGS_RUNNING;
1125 restore_flags(flags); 1114 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1126 return 0; 1115 return 0;
1127} 1116}
1128 1117
@@ -1472,6 +1461,7 @@ isdnloop_initcard(char *id)
1472 skb_queue_head_init(&card->bqueue[i]); 1461 skb_queue_head_init(&card->bqueue[i]);
1473 } 1462 }
1474 skb_queue_head_init(&card->dqueue); 1463 skb_queue_head_init(&card->dqueue);
1464 card->isdnloop_lock = SPIN_LOCK_UNLOCKED;
1475 card->next = cards; 1465 card->next = cards;
1476 cards = card; 1466 cards = card;
1477 if (!register_isdn(&card->interface)) { 1467 if (!register_isdn(&card->interface)) {
diff --git a/drivers/isdn/isdnloop/isdnloop.h b/drivers/isdn/isdnloop/isdnloop.h
index d699fe53e1c3..0d458a86f529 100644
--- a/drivers/isdn/isdnloop/isdnloop.h
+++ b/drivers/isdn/isdnloop/isdnloop.h
@@ -94,6 +94,7 @@ typedef struct isdnloop_card {
94 struct sk_buff_head 94 struct sk_buff_head
95 bqueue[ISDNLOOP_BCH]; /* B-Channel queues */ 95 bqueue[ISDNLOOP_BCH]; /* B-Channel queues */
96 struct sk_buff_head dqueue; /* D-Channel queue */ 96 struct sk_buff_head dqueue; /* D-Channel queue */
97 spinlock_t isdnloop_lock;
97} isdnloop_card; 98} isdnloop_card;
98 99
99/* 100/*