diff options
Diffstat (limited to 'net/caif/cfpkt_skbuff.c')
-rw-r--r-- | net/caif/cfpkt_skbuff.c | 193 |
1 files changed, 84 insertions, 109 deletions
diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c index 32f23ca02fb..83fff2ff665 100644 --- a/net/caif/cfpkt_skbuff.c +++ b/net/caif/cfpkt_skbuff.c @@ -1,5 +1,5 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ @@ -7,8 +7,7 @@ #include <linux/string.h> #include <linux/skbuff.h> #include <linux/hardirq.h> -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/cfpkt.h> +#include <net/caif/cfpkt.h> #define PKT_PREFIX CAIF_NEEDED_HEADROOM #define PKT_POSTFIX CAIF_NEEDED_TAILROOM @@ -21,12 +20,13 @@ struct cfpktq { struct sk_buff_head head; - cfglu_atomic_t count; + atomic_t count; + /* Lock protects count updates */ spinlock_t lock; }; /* - * net/caif/generic/ is generic and does not + * net/caif/ is generic and does not * understand SKB, so we do this typecast */ struct cfpkt { @@ -59,14 +59,11 @@ inline struct cfpkt *skb_to_pkt(struct sk_buff *skb) return (struct cfpkt *) skb; } -cfglu_atomic_t cfpkt_packet_count; -EXPORT_SYMBOL(cfpkt_packet_count); struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt) { struct cfpkt *pkt = skb_to_pkt(nativepkt); cfpkt_priv(pkt)->erronous = false; - cfglu_atomic_inc(cfpkt_packet_count); return pkt; } EXPORT_SYMBOL(cfpkt_fromnative); @@ -77,7 +74,7 @@ void *cfpkt_tonative(struct cfpkt *pkt) } EXPORT_SYMBOL(cfpkt_tonative); -struct cfpkt *cfpkt_create_pfx(uint16 len, uint16 pfx) +static struct cfpkt *cfpkt_create_pfx(u16 len, u16 pfx) { struct sk_buff *skb; @@ -90,11 +87,10 @@ struct cfpkt *cfpkt_create_pfx(uint16 len, uint16 pfx) return NULL; skb_reserve(skb, pfx); - cfglu_atomic_inc(cfpkt_packet_count); return skb_to_pkt(skb); } -inline struct cfpkt *cfpkt_create(uint16 len) +inline struct cfpkt *cfpkt_create(u16 len) { return cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX); } @@ -103,8 +99,6 @@ EXPORT_SYMBOL(cfpkt_create); void cfpkt_destroy(struct cfpkt *pkt) { struct sk_buff *skb = pkt_to_skb(pkt); - cfglu_atomic_dec(cfpkt_packet_count); - caif_assert(cfglu_atomic_read(cfpkt_packet_count) >= 0); kfree_skb(skb); } EXPORT_SYMBOL(cfpkt_destroy); @@ -116,82 +110,82 @@ inline bool cfpkt_more(struct cfpkt *pkt) } EXPORT_SYMBOL(cfpkt_more); -int cfpkt_peek_head(struct cfpkt *pkt, void *data, uint16 len) +int cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len) { struct sk_buff *skb = pkt_to_skb(pkt); - if (skb->tail - skb->data >= len) { + if (skb_headlen(skb) >= len) { memcpy(data, skb->data, len); - return CFGLU_EOK; + return 0; } return !cfpkt_extr_head(pkt, data, len) && !cfpkt_add_head(pkt, data, len); } EXPORT_SYMBOL(cfpkt_peek_head); -int cfpkt_extr_head(struct cfpkt *pkt, void *data, uint16 len) +int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len) { struct sk_buff *skb = pkt_to_skb(pkt); - uint8 *from; + u8 *from; if (unlikely(is_erronous(pkt))) - return CFGLU_EPKT; + return -EPROTO; if (unlikely(len > skb->len)) { PKT_ERROR(pkt, "cfpkt_extr_head read beyond end of packet\n"); - return CFGLU_EPKT; + return -EPROTO; } if (unlikely(len > skb_headlen(skb))) { if (unlikely(skb_linearize(skb) != 0)) { PKT_ERROR(pkt, "cfpkt_extr_head linearize failed\n"); - return CFGLU_EPKT; + return -EPROTO; } } from = skb_pull(skb, len); from -= len; memcpy(data, from, len); - return CFGLU_EOK; + return 0; } EXPORT_SYMBOL(cfpkt_extr_head); -int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, uint16 len) +int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, u16 len) { struct sk_buff *skb = pkt_to_skb(pkt); - uint8 *data = dta; - uint8 *from; + u8 *data = dta; + u8 *from; if (unlikely(is_erronous(pkt))) - return CFGLU_EPKT; + return -EPROTO; if (unlikely(skb_linearize(skb) != 0)) { PKT_ERROR(pkt, "cfpkt_extr_trail linearize failed\n"); - return CFGLU_EPKT; + return -EPROTO; } if (unlikely(skb->data + len > skb_tail_pointer(skb))) { PKT_ERROR(pkt, "cfpkt_extr_trail read beyond end of packet\n"); - return CFGLU_EPKT; + return -EPROTO; } from = skb_tail_pointer(skb) - len; skb_trim(skb, skb->len - len); memcpy(data, from, len); - return CFGLU_EOK; + return 0; } EXPORT_SYMBOL(cfpkt_extr_trail); -int cfpkt_pad_trail(struct cfpkt *pkt, uint16 len) +int cfpkt_pad_trail(struct cfpkt *pkt, u16 len) { return cfpkt_add_body(pkt, NULL, len); } EXPORT_SYMBOL(cfpkt_pad_trail); -int cfpkt_add_body(struct cfpkt *pkt, const void *data, uint16 len) +int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len) { struct sk_buff *skb = pkt_to_skb(pkt); struct sk_buff *lastskb; - uint8 *to; - uint16 addlen = 0; + u8 *to; + u16 addlen = 0; if (unlikely(is_erronous(pkt))) - return CFGLU_EPKT; + return -EPROTO; lastskb = skb; @@ -209,7 +203,7 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *data, uint16 len) /* Make sure data is writable */ if (unlikely(skb_cow_data(skb, addlen, &lastskb) < 0)) { PKT_ERROR(pkt, "cfpkt_add_body: cow failed\n"); - return CFGLU_EPKT; + return -EPROTO; } /* * Is the SKB non-linear after skb_cow_data()? If so, we are @@ -228,79 +222,79 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *data, uint16 len) to = skb_put(lastskb, len); if (likely(data)) memcpy(to, data, len); - return CFGLU_EOK; + return 0; } EXPORT_SYMBOL(cfpkt_add_body); -inline int cfpkt_addbdy(struct cfpkt *pkt, uint8 data) +inline int cfpkt_addbdy(struct cfpkt *pkt, u8 data) { return cfpkt_add_body(pkt, &data, 1); } EXPORT_SYMBOL(cfpkt_addbdy); -int cfpkt_add_head(struct cfpkt *pkt, const void *data2, uint16 len) +int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len) { struct sk_buff *skb = pkt_to_skb(pkt); struct sk_buff *lastskb; - uint8 *to; - const uint8 *data = data2; + u8 *to; + const u8 *data = data2; if (unlikely(is_erronous(pkt))) - return CFGLU_EPKT; + return -EPROTO; if (unlikely(skb_headroom(skb) < len)) { PKT_ERROR(pkt, "cfpkt_add_head: no headroom\n"); - return CFGLU_EPKT; + return -EPROTO; } /* Make sure data is writable */ if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) { PKT_ERROR(pkt, "cfpkt_add_head: cow failed\n"); - return CFGLU_EPKT; + return -EPROTO; } to = skb_push(skb, len); memcpy(to, data, len); - return CFGLU_EOK; + return 0; } EXPORT_SYMBOL(cfpkt_add_head); -inline int cfpkt_add_trail(struct cfpkt *pkt, const void *data, uint16 len) +inline int cfpkt_add_trail(struct cfpkt *pkt, const void *data, u16 len) { return cfpkt_add_body(pkt, data, len); } EXPORT_SYMBOL(cfpkt_add_trail); -inline uint16 cfpkt_getlen(struct cfpkt *pkt) +inline u16 cfpkt_getlen(struct cfpkt *pkt) { struct sk_buff *skb = pkt_to_skb(pkt); return skb->len; } EXPORT_SYMBOL(cfpkt_getlen); -inline uint16 cfpkt_iterate(struct cfpkt *pkt, - uint16 (*iter_func)(uint16, void *, uint16), - uint16 data) +inline u16 cfpkt_iterate(struct cfpkt *pkt, + u16 (*iter_func)(u16, void *, u16), + u16 data) { /* * Don't care about the performance hit of linearizing, * Checksum should not be used on high-speed interfaces anyway. */ if (unlikely(is_erronous(pkt))) - return CFGLU_EPKT; + return -EPROTO; if (unlikely(skb_linearize(&pkt->skb) != 0)) { PKT_ERROR(pkt, "cfpkt_iterate: linearize failed\n"); - return CFGLU_EPKT; + return -EPROTO; } return iter_func(data, pkt->skb.data, cfpkt_getlen(pkt)); } EXPORT_SYMBOL(cfpkt_iterate); -int cfpkt_setlen(struct cfpkt *pkt, uint16 len) +int cfpkt_setlen(struct cfpkt *pkt, u16 len) { struct sk_buff *skb = pkt_to_skb(pkt); if (unlikely(is_erronous(pkt))) - return CFGLU_EPKT; + return -EPROTO; if (likely(len <= skb->len)) { if (unlikely(skb->data_len)) @@ -328,18 +322,17 @@ struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len) } EXPORT_SYMBOL(cfpkt_create_uplink); - struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, struct cfpkt *addpkt, - uint16 expectlen) + u16 expectlen) { struct sk_buff *dst = pkt_to_skb(dstpkt); struct sk_buff *add = pkt_to_skb(addpkt); - uint16 addlen = add->tail - add->data; - uint16 neededtailspace; + u16 addlen = skb_headlen(add); + u16 neededtailspace; struct sk_buff *tmp; - uint16 dstlen; - uint16 createlen; + u16 dstlen; + u16 createlen; if (unlikely(is_erronous(dstpkt) || is_erronous(addpkt))) { cfpkt_destroy(addpkt); return dstpkt; @@ -351,19 +344,19 @@ struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, if (dst->tail + neededtailspace > dst->end) { /* Create a dumplicate of 'dst' with more tail space */ - dstlen = dst->tail - dst->data; + dstlen = skb_headlen(dst); createlen = dstlen + neededtailspace; tmp = pkt_to_skb( cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX)); if (!tmp) return NULL; - tmp->tail = tmp->data + dstlen; + skb_set_tail_pointer(tmp, dstlen); tmp->len = dstlen; memcpy(tmp->data, dst->data, dstlen); cfpkt_destroy(dstpkt); dst = tmp; } - memcpy(dst->tail, add->data, add->tail - add->data); + memcpy(skb_tail_pointer(dst), add->data, skb_headlen(add)); cfpkt_destroy(addpkt); dst->tail += addlen; dst->len += addlen; @@ -371,17 +364,17 @@ struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, } EXPORT_SYMBOL(cfpkt_append); -struct cfpkt *cfpkt_split(struct cfpkt *pkt, uint16 pos) +struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos) { struct sk_buff *skb2; struct sk_buff *skb = pkt_to_skb(pkt); - uint8 *split = skb->data + pos; - uint16 len2nd = skb->tail - split; + u8 *split = skb->data + pos; + u16 len2nd = skb_tail_pointer(skb) - split; if (unlikely(is_erronous(pkt))) return NULL; - if (skb->data + pos > skb->tail) { + if (skb->data + pos > skb_tail_pointer(skb)) { PKT_ERROR(pkt, "cfpkt_split: trying to split beyond end of packet"); return NULL; @@ -396,7 +389,7 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, uint16 pos) return NULL; /* Reduce the length of the original packet */ - skb->tail = split; + skb_set_tail_pointer(skb, pos); skb->len = pos; memcpy(skb2->data, split, len2nd); @@ -406,7 +399,6 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, uint16 pos) } EXPORT_SYMBOL(cfpkt_split); - char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen) { struct sk_buff *skb = pkt_to_skb(pkt); @@ -420,17 +412,18 @@ char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen) if (buflen < 50) return NULL; - snprintf(buf, buflen, "%s: pkt:%p len:%d(%d+%d) {%d,%d} data: [", + snprintf(buf, buflen, "%s: pkt:%p len:%ld(%ld+%ld) {%ld,%ld} data: [", is_erronous(pkt) ? "ERRONOUS-SKB" : (skb->data_len != 0 ? "COMPLEX-SKB" : "SKB"), - skb, - skb->len, - skb->tail - skb->data, - skb->data_len, - skb->data - skb->head, skb->tail - skb->head); + skb, + (long) skb->len, + (long) (skb_tail_pointer(skb) - skb->data), + (long) skb->data_len, + (long) (skb->data - skb->head), + (long) (skb_tail_pointer(skb) - skb->head)); p = buf + strlen(buf); - for (i = 0; i < skb->tail - skb->data && i < 300; i++) { + for (i = 0; i < skb_tail_pointer(skb) - skb->data && i < 300; i++) { if (p > buf + buflen - 10) { sprintf(p, "..."); p = buf + strlen(buf); @@ -451,21 +444,21 @@ int cfpkt_raw_append(struct cfpkt *pkt, void **buf, unsigned int buflen) caif_assert(buf != NULL); if (unlikely(is_erronous(pkt))) - return CFGLU_EPKT; + return -EPROTO; /* Make sure SKB is writable */ if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) { PKT_ERROR(pkt, "cfpkt_raw_append: skb_cow_data failed\n"); - return CFGLU_EPKT; + return -EPROTO; } if (unlikely(skb_linearize(skb) != 0)) { PKT_ERROR(pkt, "cfpkt_raw_append: linearize failed\n"); - return CFGLU_EPKT; + return -EPROTO; } if (unlikely(skb_tailroom(skb) < buflen)) { PKT_ERROR(pkt, "cfpkt_raw_append: buffer too short - failed\n"); - return CFGLU_EPKT; + return -EPROTO; } *buf = skb_put(skb, buflen); @@ -479,18 +472,18 @@ int cfpkt_raw_extract(struct cfpkt *pkt, void **buf, unsigned int buflen) caif_assert(buf != NULL); if (unlikely(is_erronous(pkt))) - return CFGLU_EPKT; + return -EPROTO; if (unlikely(buflen > skb->len)) { PKT_ERROR(pkt, "cfpkt_raw_extract: buflen too large " "- failed\n"); - return CFGLU_EPKT; + return -EPROTO; } if (unlikely(buflen > skb_headlen(skb))) { if (unlikely(skb_linearize(skb) != 0)) { PKT_ERROR(pkt, "cfpkt_raw_extract: linearize failed\n"); - return CFGLU_EPKT; + return -EPROTO; } } @@ -507,30 +500,13 @@ inline bool cfpkt_erroneous(struct cfpkt *pkt) } EXPORT_SYMBOL(cfpkt_erroneous); -struct cfpkt *cfpkt_create_pkt(enum caif_direction dir, - const unsigned char *data, unsigned int len) -{ - struct cfpkt *pkt; - if (dir == CAIF_DIR_OUT) - pkt = cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX); - else - pkt = cfpkt_create_pfx(len, 0); - if (unlikely(!pkt)) - return NULL; - if (unlikely(data)) - cfpkt_add_body(pkt, data, len); - cfpkt_priv(pkt)->erronous = false; - return pkt; -} -EXPORT_SYMBOL(cfpkt_create_pkt); - -struct cfpktq *cfpktq_create() +struct cfpktq *cfpktq_create(void) { - struct cfpktq *q = cfglu_alloc(sizeof(struct cfpktq)); + struct cfpktq *q = kmalloc(sizeof(struct cfpktq), GFP_ATOMIC); if (!q) return NULL; skb_queue_head_init(&q->head); - cfglu_atomic_set(q->count, 0); + atomic_set(&q->count, 0); spin_lock_init(&q->lock); return q; } @@ -538,7 +514,7 @@ EXPORT_SYMBOL(cfpktq_create); void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt, unsigned short prio) { - cfglu_atomic_inc(pktq->count); + atomic_inc(&pktq->count); spin_lock(&pktq->lock); skb_queue_tail(&pktq->head, pkt_to_skb(pkt)); spin_unlock(&pktq->lock); @@ -562,8 +538,8 @@ struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq) spin_lock(&pktq->lock); pkt = skb_to_pkt(skb_dequeue(&pktq->head)); if (pkt) { - cfglu_atomic_dec(pktq->count); - caif_assert(cfglu_atomic_read(pktq->count) >= 0); + atomic_dec(&pktq->count); + caif_assert(atomic_read(&pktq->count) >= 0); } spin_unlock(&pktq->lock); return pkt; @@ -572,7 +548,7 @@ EXPORT_SYMBOL(cfpkt_dequeue); int cfpkt_qcount(struct cfpktq *pktq) { - return cfglu_atomic_read(pktq->count); + return atomic_read(&pktq->count); } EXPORT_SYMBOL(cfpkt_qcount); @@ -584,13 +560,12 @@ struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt) cfpkt_destroy(pkt); if (!clone) return NULL; - cfglu_atomic_inc(cfpkt_packet_count); return clone; } EXPORT_SYMBOL(cfpkt_clone_release); -struct payload_info *cfpkt_info(struct cfpkt *pkt) +struct caif_payload_info *cfpkt_info(struct cfpkt *pkt) { - return (struct payload_info *)&pkt_to_skb(pkt)->cb; + return (struct caif_payload_info *)&pkt_to_skb(pkt)->cb; } EXPORT_SYMBOL(cfpkt_info); |