diff options
Diffstat (limited to 'drivers/isdn/mISDN/hwchannel.c')
-rw-r--r-- | drivers/isdn/mISDN/hwchannel.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c index 2596fba4e61..ab1168a110a 100644 --- a/drivers/isdn/mISDN/hwchannel.c +++ b/drivers/isdn/mISDN/hwchannel.c | |||
@@ -50,9 +50,6 @@ bchannel_bh(struct work_struct *ws) | |||
50 | 50 | ||
51 | if (test_and_clear_bit(FLG_RECVQUEUE, &bch->Flags)) { | 51 | if (test_and_clear_bit(FLG_RECVQUEUE, &bch->Flags)) { |
52 | while ((skb = skb_dequeue(&bch->rqueue))) { | 52 | while ((skb = skb_dequeue(&bch->rqueue))) { |
53 | if (bch->rcount >= 64) | ||
54 | printk(KERN_WARNING "B-channel %p receive " | ||
55 | "queue if full, but empties...\n", bch); | ||
56 | bch->rcount--; | 53 | bch->rcount--; |
57 | if (likely(bch->ch.peer)) { | 54 | if (likely(bch->ch.peer)) { |
58 | err = bch->ch.recv(bch->ch.peer, skb); | 55 | err = bch->ch.recv(bch->ch.peer, skb); |
@@ -169,6 +166,25 @@ recv_Dchannel(struct dchannel *dch) | |||
169 | EXPORT_SYMBOL(recv_Dchannel); | 166 | EXPORT_SYMBOL(recv_Dchannel); |
170 | 167 | ||
171 | void | 168 | void |
169 | recv_Echannel(struct dchannel *ech, struct dchannel *dch) | ||
170 | { | ||
171 | struct mISDNhead *hh; | ||
172 | |||
173 | if (ech->rx_skb->len < 2) { /* at least 2 for sapi / tei */ | ||
174 | dev_kfree_skb(ech->rx_skb); | ||
175 | ech->rx_skb = NULL; | ||
176 | return; | ||
177 | } | ||
178 | hh = mISDN_HEAD_P(ech->rx_skb); | ||
179 | hh->prim = PH_DATA_E_IND; | ||
180 | hh->id = get_sapi_tei(ech->rx_skb->data); | ||
181 | skb_queue_tail(&dch->rqueue, ech->rx_skb); | ||
182 | ech->rx_skb = NULL; | ||
183 | schedule_event(dch, FLG_RECVQUEUE); | ||
184 | } | ||
185 | EXPORT_SYMBOL(recv_Echannel); | ||
186 | |||
187 | void | ||
172 | recv_Bchannel(struct bchannel *bch) | 188 | recv_Bchannel(struct bchannel *bch) |
173 | { | 189 | { |
174 | struct mISDNhead *hh; | 190 | struct mISDNhead *hh; |
@@ -177,8 +193,10 @@ recv_Bchannel(struct bchannel *bch) | |||
177 | hh->prim = PH_DATA_IND; | 193 | hh->prim = PH_DATA_IND; |
178 | hh->id = MISDN_ID_ANY; | 194 | hh->id = MISDN_ID_ANY; |
179 | if (bch->rcount >= 64) { | 195 | if (bch->rcount >= 64) { |
180 | dev_kfree_skb(bch->rx_skb); | 196 | printk(KERN_WARNING "B-channel %p receive queue overflow, " |
181 | bch->rx_skb = NULL; | 197 | "fushing!\n", bch); |
198 | skb_queue_purge(&bch->rqueue); | ||
199 | bch->rcount = 0; | ||
182 | return; | 200 | return; |
183 | } | 201 | } |
184 | bch->rcount++; | 202 | bch->rcount++; |
@@ -200,8 +218,10 @@ void | |||
200 | recv_Bchannel_skb(struct bchannel *bch, struct sk_buff *skb) | 218 | recv_Bchannel_skb(struct bchannel *bch, struct sk_buff *skb) |
201 | { | 219 | { |
202 | if (bch->rcount >= 64) { | 220 | if (bch->rcount >= 64) { |
203 | dev_kfree_skb(skb); | 221 | printk(KERN_WARNING "B-channel %p receive queue overflow, " |
204 | return; | 222 | "fushing!\n", bch); |
223 | skb_queue_purge(&bch->rqueue); | ||
224 | bch->rcount = 0; | ||
205 | } | 225 | } |
206 | bch->rcount++; | 226 | bch->rcount++; |
207 | skb_queue_tail(&bch->rqueue, skb); | 227 | skb_queue_tail(&bch->rqueue, skb); |
@@ -245,8 +265,12 @@ confirm_Bsend(struct bchannel *bch) | |||
245 | { | 265 | { |
246 | struct sk_buff *skb; | 266 | struct sk_buff *skb; |
247 | 267 | ||
248 | if (bch->rcount >= 64) | 268 | if (bch->rcount >= 64) { |
249 | return; | 269 | printk(KERN_WARNING "B-channel %p receive queue overflow, " |
270 | "fushing!\n", bch); | ||
271 | skb_queue_purge(&bch->rqueue); | ||
272 | bch->rcount = 0; | ||
273 | } | ||
250 | skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(bch->tx_skb), | 274 | skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(bch->tx_skb), |
251 | 0, NULL, GFP_ATOMIC); | 275 | 0, NULL, GFP_ATOMIC); |
252 | if (!skb) { | 276 | if (!skb) { |