From b770261aaac4f940bd2167819a3fb850987e5d13 Mon Sep 17 00:00:00 2001 From: Armin Schindler Date: Fri, 27 Aug 2004 00:55:01 -0700 Subject: [PATCH] [PATCH] 2.6 ISDN CAPI: low-level drivers skb free fix CAPI skb freeing fix. On sending, the hardware/low-level driver may free a skb on no error only. The application/core side must take care otherwise. Author: Carsten Paeth, Armin Schindler --- drivers/isdn/capi/capidrv.c | 3 ++- drivers/isdn/hardware/avm/b1.c | 8 +++----- drivers/isdn/hardware/avm/b1dma.c | 2 -- drivers/isdn/hardware/avm/c4.c | 2 -- drivers/isdn/hardware/avm/t1isa.c | 7 +++---- drivers/isdn/hardware/eicon/capifunc.c | 5 +++-- 6 files changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index 150e31d32b2c1..44efe19064c07 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c @@ -512,7 +512,8 @@ static void send_message(capidrv_contr * card, _cmsg * cmsg) len = CAPIMSG_LEN(cmsg->buf); skb = alloc_skb(len, GFP_ATOMIC); memcpy(skb_put(skb, len), cmsg->buf, len); - capi20_put_message(&global.ap, skb); + if (capi20_put_message(&global.ap, skb) != CAPI_NOERROR) + kfree_skb(skb); } /* -------- state machine -------------------------------------------- */ diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c index c87516ab20b01..0c7061d550273 100644 --- a/drivers/isdn/hardware/avm/b1.c +++ b/drivers/isdn/hardware/avm/b1.c @@ -389,7 +389,7 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); if (retval != CAPI_NOERROR) - goto out; + return retval; dlen = CAPIMSG_DATALEN(skb->data); @@ -399,16 +399,14 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) b1_put_slice(port, skb->data + len, dlen); spin_unlock_irqrestore(&card->lock, flags); } else { - retval = CAPI_NOERROR; - spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_MESSAGE); b1_put_slice(port, skb->data, len); spin_unlock_irqrestore(&card->lock, flags); } - out: + dev_kfree_skb_any(skb); - return retval; + return CAPI_NOERROR; } /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c index d2c69b727281a..55bed00ca8655 100644 --- a/drivers/isdn/hardware/avm/b1dma.c +++ b/drivers/isdn/hardware/avm/b1dma.c @@ -839,8 +839,6 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) } if (retval == CAPI_NOERROR) b1dma_queue_tx(card, skb); - else - dev_kfree_skb_any(skb); return retval; } diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c index 9e1285ca57fe0..72b57d4fbf3ed 100644 --- a/drivers/isdn/hardware/avm/c4.c +++ b/drivers/isdn/hardware/avm/c4.c @@ -1029,8 +1029,6 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) spin_lock_irqsave(&card->lock, flags); c4_dispatch_tx(card); spin_unlock_irqrestore(&card->lock, flags); - } else { - dev_kfree_skb_any(skb); } return retval; } diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c index 9d777ebc862ad..cb9d9cee2a648 100644 --- a/drivers/isdn/hardware/avm/t1isa.c +++ b/drivers/isdn/hardware/avm/t1isa.c @@ -472,7 +472,7 @@ static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); if (retval != CAPI_NOERROR) - goto out; + return retval; dlen = CAPIMSG_DATALEN(skb->data); @@ -482,16 +482,15 @@ static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) t1_put_slice(port, skb->data + len, dlen); spin_unlock_irqrestore(&card->lock, flags); } else { - retval = CAPI_NOERROR; spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_MESSAGE); t1_put_slice(port, skb->data, len); spin_unlock_irqrestore(&card->lock, flags); } - out: + dev_kfree_skb_any(skb); - return retval; + return CAPI_NOERROR; } /* ------------------------------------------------------------- */ diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c index 15d081a09f645..5c138a345cf04 100644 --- a/drivers/isdn/hardware/eicon/capifunc.c +++ b/drivers/isdn/hardware/eicon/capifunc.c @@ -1,4 +1,4 @@ -/* $Id: capifunc.c,v 1.61.4.2 2004/05/05 16:09:25 armin Exp $ +/* $Id: capifunc.c,v 1.61.4.5 2004/08/27 20:10:12 armin Exp $ * * ISDN interface module for Eicon active cards DIVA. * CAPI Interface common functions @@ -998,7 +998,8 @@ static u16 diva_send_message(struct capi_ctr *ctrl, write_end: diva_os_leave_spin_lock(&api_lock, &old_irql, "send message"); - diva_os_free_message_buffer(dmb); + if (retval == CAPI_NOERROR) + diva_os_free_message_buffer(dmb); return retval; } -- 2.53.0