aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/mISDN/hwchannel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/mISDN/hwchannel.c')
-rw-r--r--drivers/isdn/mISDN/hwchannel.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
index 2596fba4e614..ab1168a110ae 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)
169EXPORT_SYMBOL(recv_Dchannel); 166EXPORT_SYMBOL(recv_Dchannel);
170 167
171void 168void
169recv_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}
185EXPORT_SYMBOL(recv_Echannel);
186
187void
172recv_Bchannel(struct bchannel *bch) 188recv_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
200recv_Bchannel_skb(struct bchannel *bch, struct sk_buff *skb) 218recv_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) {