aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hardware/avm/c4.c
diff options
context:
space:
mode:
authorKarsten Keil <kkeil@suse.de>2007-10-18 06:04:32 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-18 17:37:17 -0400
commit1ccfd63367c1a6aaf8b33943f18856dde85f2f0b (patch)
tree86cbe65716f8f6181f158b537b5d0ba1e3c07c73 /drivers/isdn/hardware/avm/c4.c
parent9713d9e650045f7f2afd81d58a068827be306993 (diff)
i4l: Fix random hard freeze with AVM c4 card
The patch - Includes the call to capilib_data_b3_req in the spinlock. This routine in turn calls the offending mq_enqueue routine that triggered the freeze if not locked. This should also fix other indicators of incosistent capilib_msgidqueue list, that trigger messages like: Oct 5 03:05:57 BERL0 kernel: kcapi: msgid 3019 ncci 0x30301 not on queue that we saw several times a day (usually several in a row). - Fixes all occurrences of c4_dispatch_tx to be called with active spinlock, there were some instances where no lock was active. Mostly these are in very infrequently called routines, so the additional performance penalty is minimal. Signed-off-by: Karsten Keil <kkeil@suse.de> Signed-off-by: Rainer Brestan <rainer.brestan@frequentis.com> Signed-off-by: Ralf Schlatterbeck <rsc@runtux.com> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/isdn/hardware/avm/c4.c')
-rw-r--r--drivers/isdn/hardware/avm/c4.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index d58f927e766a..8710cf6214d9 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -727,6 +727,7 @@ static void c4_send_init(avmcard *card)
727{ 727{
728 struct sk_buff *skb; 728 struct sk_buff *skb;
729 void *p; 729 void *p;
730 unsigned long flags;
730 731
731 skb = alloc_skb(15, GFP_ATOMIC); 732 skb = alloc_skb(15, GFP_ATOMIC);
732 if (!skb) { 733 if (!skb) {
@@ -744,12 +745,15 @@ static void c4_send_init(avmcard *card)
744 skb_put(skb, (u8 *)p - (u8 *)skb->data); 745 skb_put(skb, (u8 *)p - (u8 *)skb->data);
745 746
746 skb_queue_tail(&card->dma->send_queue, skb); 747 skb_queue_tail(&card->dma->send_queue, skb);
748 spin_lock_irqsave(&card->lock, flags);
747 c4_dispatch_tx(card); 749 c4_dispatch_tx(card);
750 spin_unlock_irqrestore(&card->lock, flags);
748} 751}
749 752
750static int queue_sendconfigword(avmcard *card, u32 val) 753static int queue_sendconfigword(avmcard *card, u32 val)
751{ 754{
752 struct sk_buff *skb; 755 struct sk_buff *skb;
756 unsigned long flags;
753 void *p; 757 void *p;
754 758
755 skb = alloc_skb(3+4, GFP_ATOMIC); 759 skb = alloc_skb(3+4, GFP_ATOMIC);
@@ -766,7 +770,9 @@ static int queue_sendconfigword(avmcard *card, u32 val)
766 skb_put(skb, (u8 *)p - (u8 *)skb->data); 770 skb_put(skb, (u8 *)p - (u8 *)skb->data);
767 771
768 skb_queue_tail(&card->dma->send_queue, skb); 772 skb_queue_tail(&card->dma->send_queue, skb);
773 spin_lock_irqsave(&card->lock, flags);
769 c4_dispatch_tx(card); 774 c4_dispatch_tx(card);
775 spin_unlock_irqrestore(&card->lock, flags);
770 return 0; 776 return 0;
771} 777}
772 778
@@ -986,7 +992,9 @@ static void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
986 struct sk_buff *skb; 992 struct sk_buff *skb;
987 void *p; 993 void *p;
988 994
995 spin_lock_irqsave(&card->lock, flags);
989 capilib_release_appl(&cinfo->ncci_head, appl); 996 capilib_release_appl(&cinfo->ncci_head, appl);
997 spin_unlock_irqrestore(&card->lock, flags);
990 998
991 if (ctrl->cnr == card->cardnr) { 999 if (ctrl->cnr == card->cardnr) {
992 skb = alloc_skb(7, GFP_ATOMIC); 1000 skb = alloc_skb(7, GFP_ATOMIC);
@@ -1019,7 +1027,8 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
1019 u16 retval = CAPI_NOERROR; 1027 u16 retval = CAPI_NOERROR;
1020 unsigned long flags; 1028 unsigned long flags;
1021 1029
1022 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { 1030 spin_lock_irqsave(&card->lock, flags);
1031 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
1023 retval = capilib_data_b3_req(&cinfo->ncci_head, 1032 retval = capilib_data_b3_req(&cinfo->ncci_head,
1024 CAPIMSG_APPID(skb->data), 1033 CAPIMSG_APPID(skb->data),
1025 CAPIMSG_NCCI(skb->data), 1034 CAPIMSG_NCCI(skb->data),
@@ -1027,10 +1036,9 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
1027 } 1036 }
1028 if (retval == CAPI_NOERROR) { 1037 if (retval == CAPI_NOERROR) {
1029 skb_queue_tail(&card->dma->send_queue, skb); 1038 skb_queue_tail(&card->dma->send_queue, skb);
1030 spin_lock_irqsave(&card->lock, flags);
1031 c4_dispatch_tx(card); 1039 c4_dispatch_tx(card);
1032 spin_unlock_irqrestore(&card->lock, flags);
1033 } 1040 }
1041 spin_unlock_irqrestore(&card->lock, flags);
1034 return retval; 1042 return retval;
1035} 1043}
1036 1044