⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skbuff.c

📁 sparc硬件平台上的红外协议
💻 C
字号:
/**    Routines having to do with the 'struct sk_buff' memory handlers.**    Authors:    Alan Cox <iiitac@pyr.swan.ac.uk>*            Florian La Roche <rzsfl@rz.uni-sb.de>**    Version:    $Id: skbuff.c,v 1.5 2008/07/30 05:03:25 huangzhiwei Exp $**    Fixes:*        Alan Cox    :    Fixed the worst of the load balancer bugs**    NOTE:*        The __skb_ routines should be called with interrupts*    disabled, or you better be *real* sure that the operation is atomic*    with respect to whatever list is being frobbed (e.g. via lock_sock()*    or via disabling bottom half handlers, etc).**    This program is free software; you can redistribute it and/or*    modify it under the terms of the GNU General Public License*    as published by the Free Software Foundation; either version*    2 of the License, or (at your option) any later version.*//**    The functions in this file will not compile correctly with gcc 2.4.x*/#include "netdevice.h"#include "string.h"#include "skbuff.h"#include "af_irda.h"/***    __alloc_skb    -    allocate a network buffer*    @size: size to allocate*    @gfp_mask: allocation mask*    @fclone: allocate from fclone cache instead of head cache*        and allocate a cloned (child) skb*    @node: numa node to allocate memory on**    Allocate a new &sk_buff. The returned buffer has no headroom and a*    tail room of size bytes. The object has a reference count of one.*    The return is the buffer. On a failure the return is %NULL.**    Buffers may only be allocated from interrupts using a @gfp_mask of*    %GFP_ATOMIC.*/extern struct irda_cb* irda_self;struct sk_buff *skb_alloc(D_UINT32 size){    struct sk_buff *skb;    D_UINT8 *data;	    /* Get the HEAD */    skb = (struct sk_buff *)malloc(sizeof(struct sk_buff));    if (!skb)	{		IRDA_ERROR("%s: can't allocate memory\n", __FUNCTION__);        goto out;	}		memset(skb,0,sizeof(struct sk_buff));    skb->users = 0;    data = (D_UINT8 *)malloc(size);    if (!data)	{		IRDA_ERROR("%s: can't allocate memory\n", __FUNCTION__);        goto nodata;	}	memset(data,0,size);	    /*	* See comment in sk_buff definition, just before the 'tail' member	*/	    skb->truesize = size + sizeof(struct sk_buff);    //atomic_set(&skb->users, 1);    skb->head = data;    skb->data = data;    skb_reset_tail_pointer(skb);    skb->end = skb->tail + size;    out:    return skb;nodata:    free(skb);    skb = NULL;    goto out;}void skb_free(struct sk_buff *skb){	    if (!skb)	{        return;	}		//add by xugangan	if (--skb->users >=0)	{		return;	}	    if(skb->head != NULL)	{		free(skb->head);	}	    free(skb);	skb = NULL;	}/***    skb_dequeue - remove from the head of the queue*    @list: list to dequeue from**    Remove the head of the list. The list lock is taken so the function*    may be used safely with other locking list functions. The head item is*    returned or %NULL if the list is empty.*/struct sk_buff *skb_dequeue(struct sk_buff_head *list){	    struct sk_buff *next, *prev, *result;		    prev = (struct sk_buff *) list;	    next = prev->next;	    result = NULL;    if (next != prev)     {		        result         = next;        next         = next->next;        list->qlen--;        next->prev   = prev;        prev->next   = next;        result->next = result->prev = NULL;    }	    return result;}/***    skb_dequeue_tail - remove from the tail of the queue*    @list: list to dequeue from**    Remove the tail of the list. The list lock is taken so the function*    may be used safely with other locking list functions. The tail item is*    returned or %NULL if the list is empty.*/struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list){    //unsigned long flags;    struct sk_buff *skb = skb_peek_tail(list);    if (skb)        skb_unlink(skb, list);    return skb;}/***    skb_queue_purge - empty a list*    @list: list to empty**    Delete all buffers on an &sk_buff list. Each buffer is removed from*    the list and one reference dropped. This function takes the list*    lock and is atomic with respect to other list locking functions.*/void skb_queue_purge(void){    struct sk_buff_head *list = &(irda_self->sk_receive_queue);    struct sk_buff *skb;    while ((skb = skb_dequeue(list)) != NULL)    {        skb_free(skb);    }}/***    skb_queue_head - queue a buffer at the list head*    @list: list to use*    @newsk: buffer to queue**    Queue a buffer at the start of the list. This function takes the*    list lock and can be used safely with other locking &sk_buff functions*    safely.**    A buffer cannot be placed on two lists at the same time.*/void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk){	    struct sk_buff *prev,*next;	    list->qlen++;    prev = (struct sk_buff *)list;    next = prev->next;    newsk->next = next;    newsk->prev = prev;    next->prev  = prev->next = newsk;}/***    skb_queue_tail - queue a buffer at the list tail*    @list: list to use*    @newsk: buffer to queue**    Queue a buffer at the tail of the list. This function takes the*    list lock and can be used safely with other locking &sk_buff functions*    safely.**    A buffer cannot be placed on two lists at the same time.*/void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk){    IRDA_DEBUG(1, "%s()\n", __FUNCTION__ );    struct sk_buff *prev, *next;	    list->qlen++;    next = (struct sk_buff *)list;    prev = next->prev;    newsk->next = next;    newsk->prev = prev;    next->prev  = prev->next = newsk;}/***    skb_unlink    -    remove a buffer from a list*    @skb: buffer to remove*    @list: list to use*    remove sk_buff from list*    Remove a packet from a list. The list locks are taken and this*    function is atomic with respect to other list locked calls**    You must know what list the SKB is on.*/void skb_unlink(struct sk_buff *skb, struct sk_buff_head *list){    struct sk_buff *next, *prev;	    list->qlen--;    next       = skb->next;    prev       = skb->prev;    skb->next  = skb->prev = NULL;    next->prev = prev;    prev->next = next;    }/***    skb_insert    -    insert a buffer*    @old: buffer to insert before*    @newsk: buffer to insert*    @list: list to use*    *    Insert a packet on a list.*    Place a packet before a given packet in a list. The list locks are*     taken and this function is atomic with respect to other list locked*    calls.**    A buffer cannot be placed on two lists at the same time.*/void skb_insert(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list){    struct sk_buff *prev, *next;    //__skb_insert(newsk, old->prev, old, list);    prev = old->prev;    next = old;	    newsk->next = next;    newsk->prev = prev;    next->prev  = prev->next = newsk;    list->qlen++;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -