]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.22.14/i4l-fix-random-freezes-with-avm-b1-drivers.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 2.6.22.14 / i4l-fix-random-freezes-with-avm-b1-drivers.patch
CommitLineData
38f540a8
GKH
1From stable-bounces@linux.kernel.org Thu Oct 18 03:05:05 2007
2From: Karsten Keil <kkeil@suse.de>
3Date: Thu, 18 Oct 2007 03:04:31 -0700
4Subject: i4l: fix random freezes with AVM B1 drivers
5To: torvalds@linux-foundation.org
6Cc: akpm@linux-foundation.org, stable@kernel.org, kkeil@suse.de
7Message-ID: <200710181004.l9IA4VVS005629@imap1.linux-foundation.org>
8
9
10From: Karsten Keil <kkeil@suse.de>
11
12patch 9713d9e650045f7f2afd81d58a068827be306993 in mainline.
13
14This fix the same issue which was debbuged for the C4 controller for the B1
15versions.
16
17The capilib_ function modify or traverse a linked list without locking.
18
19This patch extends the existing locking to the calls of these function to
20prevent access to a list which is in the middle of a modification.
21
22Signed-off-by: Karsten Keil <kkeil@suse.de>
23Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
24Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
25Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
26
27---
28 drivers/isdn/hardware/avm/b1.c | 28 +++++++++++++---------------
29 1 file changed, 13 insertions(+), 15 deletions(-)
30
31--- a/drivers/isdn/hardware/avm/b1.c
32+++ b/drivers/isdn/hardware/avm/b1.c
33@@ -321,12 +321,15 @@ void b1_reset_ctr(struct capi_ctr *ctrl)
34 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
35 avmcard *card = cinfo->card;
36 unsigned int port = card->port;
37+ unsigned long flags;
38
39 b1_reset(port);
40 b1_reset(port);
41
42 memset(cinfo->version, 0, sizeof(cinfo->version));
43+ spin_lock_irqsave(&card->lock, flags);
44 capilib_release(&cinfo->ncci_head);
45+ spin_unlock_irqrestore(&card->lock, flags);
46 capi_ctr_reseted(ctrl);
47 }
48
49@@ -361,9 +364,8 @@ void b1_release_appl(struct capi_ctr *ct
50 unsigned int port = card->port;
51 unsigned long flags;
52
53- capilib_release_appl(&cinfo->ncci_head, appl);
54-
55 spin_lock_irqsave(&card->lock, flags);
56+ capilib_release_appl(&cinfo->ncci_head, appl);
57 b1_put_byte(port, SEND_RELEASE);
58 b1_put_word(port, appl);
59 spin_unlock_irqrestore(&card->lock, flags);
60@@ -380,27 +382,27 @@ u16 b1_send_message(struct capi_ctr *ctr
61 u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
62 u16 dlen, retval;
63
64+ spin_lock_irqsave(&card->lock, flags);
65 if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
66 retval = capilib_data_b3_req(&cinfo->ncci_head,
67 CAPIMSG_APPID(skb->data),
68 CAPIMSG_NCCI(skb->data),
69 CAPIMSG_MSGID(skb->data));
70- if (retval != CAPI_NOERROR)
71+ if (retval != CAPI_NOERROR) {
72+ spin_unlock_irqrestore(&card->lock, flags);
73 return retval;
74+ }
75
76 dlen = CAPIMSG_DATALEN(skb->data);
77
78- spin_lock_irqsave(&card->lock, flags);
79 b1_put_byte(port, SEND_DATA_B3_REQ);
80 b1_put_slice(port, skb->data, len);
81 b1_put_slice(port, skb->data + len, dlen);
82- spin_unlock_irqrestore(&card->lock, flags);
83 } else {
84- spin_lock_irqsave(&card->lock, flags);
85 b1_put_byte(port, SEND_MESSAGE);
86 b1_put_slice(port, skb->data, len);
87- spin_unlock_irqrestore(&card->lock, flags);
88 }
89+ spin_unlock_irqrestore(&card->lock, flags);
90
91 dev_kfree_skb_any(skb);
92 return CAPI_NOERROR;
93@@ -534,17 +536,17 @@ irqreturn_t b1_interrupt(int interrupt,
94
95 ApplId = (unsigned) b1_get_word(card->port);
96 MsgLen = b1_get_slice(card->port, card->msgbuf);
97- spin_unlock_irqrestore(&card->lock, flags);
98 if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
99 printk(KERN_ERR "%s: incoming packet dropped\n",
100 card->name);
101+ spin_unlock_irqrestore(&card->lock, flags);
102 } else {
103 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
104 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
105 capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
106 CAPIMSG_NCCI(skb->data),
107 CAPIMSG_MSGID(skb->data));
108-
109+ spin_unlock_irqrestore(&card->lock, flags);
110 capi_ctr_handle_message(ctrl, ApplId, skb);
111 }
112 break;
113@@ -554,21 +556,17 @@ irqreturn_t b1_interrupt(int interrupt,
114 ApplId = b1_get_word(card->port);
115 NCCI = b1_get_word(card->port);
116 WindowSize = b1_get_word(card->port);
117- spin_unlock_irqrestore(&card->lock, flags);
118-
119 capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
120-
121+ spin_unlock_irqrestore(&card->lock, flags);
122 break;
123
124 case RECEIVE_FREE_NCCI:
125
126 ApplId = b1_get_word(card->port);
127 NCCI = b1_get_word(card->port);
128- spin_unlock_irqrestore(&card->lock, flags);
129-
130 if (NCCI != 0xffffffff)
131 capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
132-
133+ spin_unlock_irqrestore(&card->lock, flags);
134 break;
135
136 case RECEIVE_START: