Loading include/linux/skbuff.h +8 −0 Original line number Diff line number Diff line Loading @@ -359,6 +359,14 @@ struct sk_buff { #include <asm/system.h> #ifdef CONFIG_HAS_DMA #include <linux/dma-mapping.h> 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, Loading net/core/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading net/core/skb_dma_map.c 0 → 100644 +66 −0 Original line number Diff line number Diff line /* skb_dma_map.c: DMA mapping helpers for socket buffers. * * Copyright (C) David S. Miller <davem@davemloft.net> */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/dma-mapping.h> #include <linux/skbuff.h> 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); Loading
include/linux/skbuff.h +8 −0 Original line number Diff line number Diff line Loading @@ -359,6 +359,14 @@ struct sk_buff { #include <asm/system.h> #ifdef CONFIG_HAS_DMA #include <linux/dma-mapping.h> 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, Loading
net/core/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
net/core/skb_dma_map.c 0 → 100644 +66 −0 Original line number Diff line number Diff line /* skb_dma_map.c: DMA mapping helpers for socket buffers. * * Copyright (C) David S. Miller <davem@davemloft.net> */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/dma-mapping.h> #include <linux/skbuff.h> 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);