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 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) | |||
| 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) { |
