summaryrefslogtreecommitdiff
path: root/cleopatre
diff options
context:
space:
mode:
authorJérémy Dufour2011-02-04 12:37:35 +0100
committerJérémy Dufour2011-02-08 15:10:46 +0100
commit7a5999db44c84275d29573cf9a6d8e119fad03cd (patch)
tree0c2cd9409af06d67aa4982ee0fb8ee18f6be1c95 /cleopatre
parent3d32fabd2a51c4adbfdf789967925e7e5aa5d3bc (diff)
cleo/devkit/plcdrv: do not remove element after been freed, closes #2286
This commit also includes: - usage of list macro defined in the linux list implementation, - simplification of code (to prevent duplication), - a sanity check when we found an empty entry.
Diffstat (limited to 'cleopatre')
-rw-r--r--cleopatre/devkit/plcdrv/arm/src/linux_drv.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/cleopatre/devkit/plcdrv/arm/src/linux_drv.c b/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
index 48a3bfacc0..3b8e658c20 100644
--- a/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
+++ b/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
@@ -817,27 +817,32 @@ int trace_cfops_release(struct inode *inp, struct file *filp)
*/
static struct sk_buff* get_skb_addr(uint32_t data_addr)
{
- struct list_head *ptr;
struct skb_addr_list *entry;
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
struct net_priv *priv = plcdrv_device->priv;
spin_lock(&priv->lock);
//Check in the list to find the sk_buff corresponding to our data_addr
- for(ptr = priv->list_head_skbs.next ; ptr != &priv->list_head_skbs ; ptr = ptr->next)
+ //No need to use the _safe version as we stop as soon we have deleted the
+ //element.
+ list_for_each_entry(entry, &priv->list_head_skbs, list)
{
- entry = list_entry(ptr, struct skb_addr_list, list);
if(((uint32_t)entry->pkt_addr) == data_addr)
{
+ //Get the content.
skb = entry->skb;
+ //We should never have a match without any sk_buff.
+ BUG_ON(skb == NULL);
+ //Remove the element first.
+ list_del(&entry->list);
+ //Delete the entry.
kfree(entry);
- list_del(ptr);
- spin_unlock(&priv->lock);
- return skb;
+ //Go out of the loop.
+ break;
}
}
spin_unlock(&priv->lock);
- return NULL;
+ return skb;
}// get_skb_addr
/**
@@ -1773,8 +1778,7 @@ err_open:
int plcdrv_stop(struct net_device *dev)
{
struct net_priv *priv = NULL;
- struct list_head *ptr;
- struct skb_addr_list *entry;
+ struct skb_addr_list *entry, *n;
//Check pointers
if(dev == NULL)
@@ -1817,11 +1821,14 @@ int plcdrv_stop(struct net_device *dev)
//(a sk_buff become free when we receive a send_done procedure)
//
//Currently, we only suppress all sk_buff in used
- for(ptr = priv->list_head_skbs.next ; ptr != &priv->list_head_skbs ; ptr = ptr->next)
+ list_for_each_entry_safe (entry, n, &priv->list_head_skbs, list)
{
- entry = list_entry(ptr, struct skb_addr_list, list);
+ //Remove the element first.
+ list_del(&entry->list);
+ //Delete the content of the element.
kfree_skb(entry->skb);
- list_del(ptr);
+ //Delete the element itself.
+ kfree(entry);
}
TRACE("stop end\n");