From 24afc360d535a866b8865f7796e13d954b7c697a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 11 Sep 2008 04:51:14 -0700 Subject: [PATCH] --- yaml --- r: 111599 b: refs/heads/master c: a40c24a13366e324bc0ff8c3bb107db89312c984 h: refs/heads/master i: 111597: 58b3a98eaafde2b63aca9049f7ad2fa769555560 111595: 69a0e98244a9589bc8af3a1df97b13daf40704f4 111591: 2e5b4dd1c4de64ad7886df7dbad81dadbd0e8b23 111583: 52b50f0454a26efee88097aa721eab34a83c9fbe v: v3 --- [refs] | 2 +- trunk/include/linux/skbuff.h | 8 +++++ trunk/net/core/Makefile | 1 + trunk/net/core/skb_dma_map.c | 66 ++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 trunk/net/core/skb_dma_map.c diff --git a/[refs] b/[refs] index 83a77c94df9f..c98278756a2f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 271bff7afbb2cbaa81e744006ad2fff1f3e10b1b +refs/heads/master: a40c24a13366e324bc0ff8c3bb107db89312c984 diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 4b2be23903c4..aa80ad9cbc88 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -359,6 +359,14 @@ struct sk_buff { #include +#ifdef CONFIG_HAS_DMA +#include +extern int skb_dma_map(struct device *dev, struct sk_buff *skb, + enum dma_data_direction dir); +extern void skb_dma_unmap(struct device *dev, struct sk_buff *skb, + enum dma_data_direction dir); +#endif + extern void kfree_skb(struct sk_buff *skb); extern void __kfree_skb(struct sk_buff *skb); extern struct sk_buff *__alloc_skb(unsigned int size, diff --git a/trunk/net/core/Makefile b/trunk/net/core/Makefile index b1332f6d0042..26a37cb31923 100644 --- a/trunk/net/core/Makefile +++ b/trunk/net/core/Makefile @@ -6,6 +6,7 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ gen_stats.o gen_estimator.o net_namespace.o obj-$(CONFIG_SYSCTL) += sysctl_net_core.o +obj-$(CONFIG_HAS_DMA) += skb_dma_map.o obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \ neighbour.o rtnetlink.o utils.o link_watch.o filter.o diff --git a/trunk/net/core/skb_dma_map.c b/trunk/net/core/skb_dma_map.c new file mode 100644 index 000000000000..1f49afcd8e86 --- /dev/null +++ b/trunk/net/core/skb_dma_map.c @@ -0,0 +1,66 @@ +/* skb_dma_map.c: DMA mapping helpers for socket buffers. + * + * Copyright (C) David S. Miller + */ + +#include +#include +#include +#include + +int skb_dma_map(struct device *dev, struct sk_buff *skb, + enum dma_data_direction dir) +{ + struct skb_shared_info *sp = skb_shinfo(skb); + dma_addr_t map; + int i; + + map = dma_map_single(dev, skb->data, + skb_headlen(skb), dir); + if (dma_mapping_error(dev, map)) + goto out_err; + + sp->dma_maps[0] = map; + for (i = 0; i < sp->nr_frags; i++) { + skb_frag_t *fp = &sp->frags[i]; + + map = dma_map_page(dev, fp->page, fp->page_offset, + fp->size, dir); + if (dma_mapping_error(dev, map)) + goto unwind; + sp->dma_maps[i + 1] = map; + } + sp->num_dma_maps = i + 1; + + return 0; + +unwind: + while (i-- >= 0) { + skb_frag_t *fp = &sp->frags[i]; + + dma_unmap_page(dev, sp->dma_maps[i + 1], + fp->size, dir); + } + dma_unmap_single(dev, sp->dma_maps[0], + skb_headlen(skb), dir); +out_err: + return -ENOMEM; +} +EXPORT_SYMBOL(skb_dma_map); + +void skb_dma_unmap(struct device *dev, struct sk_buff *skb, + enum dma_data_direction dir) +{ + struct skb_shared_info *sp = skb_shinfo(skb); + int i; + + dma_unmap_single(dev, sp->dma_maps[0], + skb_headlen(skb), dir); + for (i = 0; i < sp->nr_frags; i++) { + skb_frag_t *fp = &sp->frags[i]; + + dma_unmap_page(dev, sp->dma_maps[i + 1], + fp->size, dir); + } +} +EXPORT_SYMBOL(skb_dma_unmap);