Commit b770261a authored by Armin Schindler's avatar Armin Schindler Committed by Linus Torvalds

[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
parent ef33e507
......@@ -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 -------------------------------------------- */
......
......@@ -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;
}
/* ------------------------------------------------------------- */
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
}
/* ------------------------------------------------------------- */
......
/* $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,6 +998,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
write_end:
diva_os_leave_spin_lock(&api_lock, &old_irql, "send message");
if (retval == CAPI_NOERROR)
diva_os_free_message_buffer(dmb);
return retval;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment