aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/isdnloop/isdnloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/isdnloop/isdnloop.c')
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c73
1 files changed, 32 insertions, 41 deletions
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index fabbd461603e..c3ae2edaf6fa 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}
@@ -451,7 +446,8 @@ isdnloop_readstatus(u_char __user *buf, int len, isdnloop_card * card)
451 for (p = buf, count = 0; count < len; p++, count++) { 446 for (p = buf, count = 0; count < len; p++, count++) {
452 if (card->msg_buf_read == card->msg_buf_write) 447 if (card->msg_buf_read == card->msg_buf_write)
453 return count; 448 return count;
454 put_user(*card->msg_buf_read++, p); 449 if (put_user(*card->msg_buf_read++, p))
450 return -EFAULT;
455 if (card->msg_buf_read > card->msg_buf_end) 451 if (card->msg_buf_read > card->msg_buf_end)
456 card->msg_buf_read = card->msg_buf; 452 card->msg_buf_read = card->msg_buf;
457 } 453 }
@@ -576,8 +572,7 @@ isdnloop_atimeout(isdnloop_card * card, int ch)
576 unsigned long flags; 572 unsigned long flags;
577 char buf[60]; 573 char buf[60];
578 574
579 save_flags(flags); 575 spin_lock_irqsave(&card->isdnloop_lock, flags);
580 cli();
581 if (card->rcard) { 576 if (card->rcard) {
582 isdnloop_fake(card->rcard[ch], "DDIS_I", card->rch[ch] + 1); 577 isdnloop_fake(card->rcard[ch], "DDIS_I", card->rch[ch] + 1);
583 card->rcard[ch]->rcard[card->rch[ch]] = NULL; 578 card->rcard[ch]->rcard[card->rch[ch]] = NULL;
@@ -587,7 +582,7 @@ isdnloop_atimeout(isdnloop_card * card, int ch)
587 /* No user responding */ 582 /* No user responding */
588 sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 3)); 583 sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 3));
589 isdnloop_fake(card, buf, ch + 1); 584 isdnloop_fake(card, buf, ch + 1);
590 restore_flags(flags); 585 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
591} 586}
592 587
593/* 588/*
@@ -622,8 +617,7 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch)
622{ 617{
623 unsigned long flags; 618 unsigned long flags;
624 619
625 save_flags(flags); 620 spin_lock_irqsave(&card->isdnloop_lock, flags);
626 cli();
627 init_timer(&card->c_timer[ch]); 621 init_timer(&card->c_timer[ch]);
628 card->c_timer[ch].expires = jiffies + ISDNLOOP_TIMER_ALERTWAIT; 622 card->c_timer[ch].expires = jiffies + ISDNLOOP_TIMER_ALERTWAIT;
629 if (ch) 623 if (ch)
@@ -632,7 +626,7 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch)
632 card->c_timer[ch].function = isdnloop_atimeout0; 626 card->c_timer[ch].function = isdnloop_atimeout0;
633 card->c_timer[ch].data = (unsigned long) card; 627 card->c_timer[ch].data = (unsigned long) card;
634 add_timer(&card->c_timer[ch]); 628 add_timer(&card->c_timer[ch]);
635 restore_flags(flags); 629 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
636} 630}
637 631
638/* 632/*
@@ -647,10 +641,9 @@ isdnloop_kill_ctimer(isdnloop_card * card, int ch)
647{ 641{
648 unsigned long flags; 642 unsigned long flags;
649 643
650 save_flags(flags); 644 spin_lock_irqsave(&card->isdnloop_lock, flags);
651 cli();
652 del_timer(&card->c_timer[ch]); 645 del_timer(&card->c_timer[ch]);
653 restore_flags(flags); 646 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
654} 647}
655 648
656static u_char si2bit[] = 649static u_char si2bit[] =
@@ -706,13 +699,12 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd)
706 } 699 }
707 } 700 }
708 if (num_match) { 701 if (num_match) {
709 save_flags(flags); 702 spin_lock_irqsave(&card->isdnloop_lock, flags);
710 cli();
711 /* channel idle? */ 703 /* channel idle? */
712 if (!(cc->rcard[ch])) { 704 if (!(cc->rcard[ch])) {
713 /* Check SI */ 705 /* Check SI */
714 if (!(si2bit[cmd->parm.setup.si1] & cc->sil[ch])) { 706 if (!(si2bit[cmd->parm.setup.si1] & cc->sil[ch])) {
715 restore_flags(flags); 707 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
716 return 3; 708 return 3;
717 } 709 }
718 /* ch is idle, si and number matches */ 710 /* ch is idle, si and number matches */
@@ -720,10 +712,10 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd)
720 cc->rch[ch] = lch; 712 cc->rch[ch] = lch;
721 card->rcard[lch] = cc; 713 card->rcard[lch] = cc;
722 card->rch[lch] = ch; 714 card->rch[lch] = ch;
723 restore_flags(flags); 715 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
724 return 0; 716 return 0;
725 } else { 717 } else {
726 restore_flags(flags); 718 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
727 /* num matches, but busy */ 719 /* num matches, but busy */
728 if (ch == 1) 720 if (ch == 1)
729 return 1; 721 return 1;
@@ -1027,8 +1019,7 @@ isdnloop_stopcard(isdnloop_card * card)
1027 unsigned long flags; 1019 unsigned long flags;
1028 isdn_ctrl cmd; 1020 isdn_ctrl cmd;
1029 1021
1030 save_flags(flags); 1022 spin_lock_irqsave(&card->isdnloop_lock, flags);
1031 cli();
1032 if (card->flags & ISDNLOOP_FLAGS_RUNNING) { 1023 if (card->flags & ISDNLOOP_FLAGS_RUNNING) {
1033 card->flags &= ~ISDNLOOP_FLAGS_RUNNING; 1024 card->flags &= ~ISDNLOOP_FLAGS_RUNNING;
1034 del_timer(&card->st_timer); 1025 del_timer(&card->st_timer);
@@ -1039,7 +1030,7 @@ isdnloop_stopcard(isdnloop_card * card)
1039 cmd.driver = card->myid; 1030 cmd.driver = card->myid;
1040 card->interface.statcallb(&cmd); 1031 card->interface.statcallb(&cmd);
1041 } 1032 }
1042 restore_flags(flags); 1033 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1043} 1034}
1044 1035
1045/* 1036/*
@@ -1078,18 +1069,17 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
1078 return -EBUSY; 1069 return -EBUSY;
1079 if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef))) 1070 if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef)))
1080 return -EFAULT; 1071 return -EFAULT;
1081 save_flags(flags); 1072 spin_lock_irqsave(&card->isdnloop_lock, flags);
1082 cli();
1083 switch (sdef.ptype) { 1073 switch (sdef.ptype) {
1084 case ISDN_PTYPE_EURO: 1074 case ISDN_PTYPE_EURO:
1085 if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96", 1075 if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96",
1086 -1)) { 1076 -1)) {
1087 restore_flags(flags); 1077 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1088 return -ENOMEM; 1078 return -ENOMEM;
1089 } 1079 }
1090 card->sil[0] = card->sil[1] = 4; 1080 card->sil[0] = card->sil[1] = 4;
1091 if (isdnloop_fake(card, "TEI OK", 0)) { 1081 if (isdnloop_fake(card, "TEI OK", 0)) {
1092 restore_flags(flags); 1082 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1093 return -ENOMEM; 1083 return -ENOMEM;
1094 } 1084 }
1095 for (i = 0; i < 3; i++) 1085 for (i = 0; i < 3; i++)
@@ -1098,12 +1088,12 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
1098 case ISDN_PTYPE_1TR6: 1088 case ISDN_PTYPE_1TR6:
1099 if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95", 1089 if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95",
1100 -1)) { 1090 -1)) {
1101 restore_flags(flags); 1091 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1102 return -ENOMEM; 1092 return -ENOMEM;
1103 } 1093 }
1104 card->sil[0] = card->sil[1] = 4; 1094 card->sil[0] = card->sil[1] = 4;
1105 if (isdnloop_fake(card, "TEI OK", 0)) { 1095 if (isdnloop_fake(card, "TEI OK", 0)) {
1106 restore_flags(flags); 1096 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1107 return -ENOMEM; 1097 return -ENOMEM;
1108 } 1098 }
1109 strcpy(card->s0num[0], sdef.num[0]); 1099 strcpy(card->s0num[0], sdef.num[0]);
@@ -1111,7 +1101,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
1111 card->s0num[2][0] = '\0'; 1101 card->s0num[2][0] = '\0';
1112 break; 1102 break;
1113 default: 1103 default:
1114 restore_flags(flags); 1104 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1115 printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n", 1105 printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n",
1116 sdef.ptype); 1106 sdef.ptype);
1117 return -EINVAL; 1107 return -EINVAL;
@@ -1122,7 +1112,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
1122 card->st_timer.data = (unsigned long) card; 1112 card->st_timer.data = (unsigned long) card;
1123 add_timer(&card->st_timer); 1113 add_timer(&card->st_timer);
1124 card->flags |= ISDNLOOP_FLAGS_RUNNING; 1114 card->flags |= ISDNLOOP_FLAGS_RUNNING;
1125 restore_flags(flags); 1115 spin_unlock_irqrestore(&card->isdnloop_lock, flags);
1126 return 0; 1116 return 0;
1127} 1117}
1128 1118
@@ -1472,6 +1462,7 @@ isdnloop_initcard(char *id)
1472 skb_queue_head_init(&card->bqueue[i]); 1462 skb_queue_head_init(&card->bqueue[i]);
1473 } 1463 }
1474 skb_queue_head_init(&card->dqueue); 1464 skb_queue_head_init(&card->dqueue);
1465 card->isdnloop_lock = SPIN_LOCK_UNLOCKED;
1475 card->next = cards; 1466 card->next = cards;
1476 cards = card; 1467 cards = card;
1477 if (!register_isdn(&card->interface)) { 1468 if (!register_isdn(&card->interface)) {