]> git.hungrycats.org Git - linux/commitdiff
[PATCH] 2.6 ISDN CAPI: low-level drivers skb free fix
authorArmin Schindler <armin@melware.de>
Fri, 27 Aug 2004 07:55:01 +0000 (00:55 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 27 Aug 2004 07:55:01 +0000 (00:55 -0700)
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
drivers/isdn/hardware/avm/b1.c
drivers/isdn/hardware/avm/b1dma.c
drivers/isdn/hardware/avm/c4.c
drivers/isdn/hardware/avm/t1isa.c
drivers/isdn/hardware/eicon/capifunc.c

index 150e31d32b2c18ec7d8ea442d4ae7eaf44091947..44efe19064c07a5835cbf5e6d609f8202a8e6199 100644 (file)
@@ -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 -------------------------------------------- */
index c87516ab20b01864948f66c4a89dc86110b7873e..0c7061d550273792c749e83d40dc1b86ff53896a 100644 (file)
@@ -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;
 }
 
 /* ------------------------------------------------------------- */
index d2c69b727281a364e4f3acff9ac0dfdd35853c2f..55bed00ca86557ec9d8bf91a69e85cb8aca4cb4a 100644 (file)
@@ -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;
 }
index 9e1285ca57fe090d281e963d562ced65d24ddc7d..72b57d4fbf3edd5ae9e0e73f25f5c3ce379ccaa7 100644 (file)
@@ -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;
 }
index 9d777ebc862ad80a8eb4b8dcc166b96170040873..cb9d9cee2a648f2ef3793102f74363fbbd8fc865 100644 (file)
@@ -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;
 }
 /* ------------------------------------------------------------- */
 
index 15d081a09f645e08a6ce3c28d7f6e2485ccde34f..5c138a345cf0403951e2b71be8cb618aa6bc023d 100644 (file)
@@ -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;
 }