From 1a4c219626d636d8e408eeaa9f35414cad0e74ab Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 3 Jun 2014 12:41:34 -0600 Subject: [PATCH] NET: Add generic I/O buffering logic --- include/nuttx/net/iob.h | 160 +++++++++++++++++++++++++++++++++++++++ net/Kconfig | 1 + net/Makefile | 1 + net/iob/Kconfig | 31 ++++++++ net/iob/Make.defs | 52 +++++++++++++ net/iob/iob.h | 78 +++++++++++++++++++ net/iob/iob_alloc.c | 79 +++++++++++++++++++ net/iob/iob_concat.c | 158 ++++++++++++++++++++++++++++++++++++++ net/iob/iob_copyout.c | 129 +++++++++++++++++++++++++++++++ net/iob/iob_free.c | 83 ++++++++++++++++++++ net/iob/iob_freeq.c | 96 +++++++++++++++++++++++ net/iob/iob_initialize.c | 103 +++++++++++++++++++++++++ net/iob/iob_trimhead.c | 113 +++++++++++++++++++++++++++ net/iob/iob_trimtail.c | 151 ++++++++++++++++++++++++++++++++++++ 14 files changed, 1235 insertions(+) create mode 100644 include/nuttx/net/iob.h create mode 100644 net/iob/Kconfig create mode 100644 net/iob/Make.defs create mode 100644 net/iob/iob.h create mode 100644 net/iob/iob_alloc.c create mode 100644 net/iob/iob_concat.c create mode 100644 net/iob/iob_copyout.c create mode 100644 net/iob/iob_free.c create mode 100644 net/iob/iob_freeq.c create mode 100644 net/iob/iob_initialize.c create mode 100644 net/iob/iob_trimhead.c create mode 100644 net/iob/iob_trimtail.c diff --git a/include/nuttx/net/iob.h b/include/nuttx/net/iob.h new file mode 100644 index 0000000000..1db82d0a32 --- /dev/null +++ b/include/nuttx/net/iob.h @@ -0,0 +1,160 @@ +/**************************************************************************** + * include/nuttx/net/iob.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef _INCLUDE_NUTTX_NET_IOB_H +#define _INCLUDE_NUTTX_NET_IOB_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Represents one I/O buffer. A packet is contained by one or more I/O + * buffers in a chain. + */ + +struct iob_s +{ + sq_entry_t io_link; /* Link to the next I/O buffer in the chain */ + uint8_t io_flags; /* Flags associated with the I/O buffer */ + uint16_t io_len; /* Length of the data in the entry */ + uint16_t io_pktlen; /* Total length of the packet */ + uint16_t io_vtag; /* VLAN tag */ + void *io_priv; /* User private data attached to the I/O buffer */ + uint8_t io_data[CONFIG_IOB_BUFSIZE]; +}; + +/**************************************************************************** + * Global Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_initialize + * + * Description: + * Set up the I/O buffers for normal operations. + * + ****************************************************************************/ + +void iob_initialize(void); + +/**************************************************************************** + * Name: iob_alloc + * + * Description: + * Allocate an I/O buffer by take the buffer at the head of the free list. + * + ****************************************************************************/ + +FAR struct iob_s *iob_alloc(void); + +/**************************************************************************** + * Name: iob_free + * + * Description: + * Free the I/O buffer at the head of a buffer chain returning it to the + * free list. The link to the next I/O buffer in the chain is return. + * + ****************************************************************************/ + +FAR struct iob_s *iob_free(FAR struct iob_s *iob); + +/**************************************************************************** + * Name: iob_freeq + * + * Description: + * Free an entire buffer chain + * + ****************************************************************************/ + +void iob_freeq(FAR sq_queue_t *q); + +/**************************************************************************** + * Name: iob_copyout + * + * Description: + * Copy data 'len' bytes of data into the user buffer starting at 'offset' + * in the I/O buffer. + * + ****************************************************************************/ + +void iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob, + unsigned int len, unsigned int offset); + +/**************************************************************************** + * Name: iob_concat + * + * Description: + * Concatenate iob_s chain iob2 to iob1. + * + ****************************************************************************/ + +void iob_concat(FAR struct iob_s *iob1, FAR struct iob_s *iob2); + +/**************************************************************************** + * Name: iob_trimhead + * + * Description: + * Remove bytes from the beginning of an I/O chain + * + ****************************************************************************/ + +void iob_trimhead(FAR struct iob_s *iob, unsigned int trimlen); + +/**************************************************************************** + * Name: iob_trimtail + * + * Description: + * Remove bytes from the end of an I/O chain + * + ****************************************************************************/ + +void iob_trimtail(FAR struct iob_s *iob, unsigned int trimlen); + +#endif /* _INCLUDE_NUTTX_NET_IOB_H */ diff --git a/net/Kconfig b/net/Kconfig index 2f4cb2a523..be415289b8 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -349,6 +349,7 @@ config NET_RECEIVE_WINDOW data quickly. source "net/arp/Kconfig" +source "net/iob/Kconfig" config NET_ROUTE bool "Routing table suport" diff --git a/net/Makefile b/net/Makefile index fa0ea57537..9209176a94 100644 --- a/net/Makefile +++ b/net/Makefile @@ -99,6 +99,7 @@ ifeq ($(CONFIG_NET_RXAVAIL),y) NETDEV_CSRCS += netdev_rxnotify.c endif +include iob/Make.defs include arp/Make.defs include icmp/Make.defs include igmp/Make.defs diff --git a/net/iob/Kconfig b/net/iob/Kconfig new file mode 100644 index 0000000000..0a5c8522ab --- /dev/null +++ b/net/iob/Kconfig @@ -0,0 +1,31 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +config NET_IOB + bool "Network I/O buffer support" + default n + ---help--- + This setting will build the networking I/O buffer (IOB) support + library. + +if NET_IOB + +config IOB_NBUFFERS + int "Number of pre-allocated network I/O buffers" + default 16 + ---help--- + Each packet is represented by a series of small I/O buffers in a + chain. This setting determines the number of preallocated I/O + buffers available for packet data. + +config IOB_BUFSIZE + int "Payload size of one network I/O buffer" + default 256 + ---help--- + Each packet is represented by a series of small I/O buffers in a + chain. This setting determines the data payload each preallocated + I/O buffer. + +endif # NET_IOB diff --git a/net/iob/Make.defs b/net/iob/Make.defs new file mode 100644 index 0000000000..6783e597bc --- /dev/null +++ b/net/iob/Make.defs @@ -0,0 +1,52 @@ +############################################################################ +# net/iob/Make.defs +# +# Copyright (C) 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +NET_ASRCS = +NET_CSRCS = + +ifeq ($(CONFIG_NET_IOB),y) + +# Include IOB src files + +NET_CSRCS += iob_alloc.c iob_concat.c iob_copyout.c iob_free.c iob_freeq.c +NET_CSRCS += iob_initialize.c iob_trimhead.c iob_trimtail.c + +# Include iob build support + +DEPPATH += --dep-path iob +VPATH += :iob +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)net$(DELIM)iob} + +endif diff --git a/net/iob/iob.h b/net/iob/iob.h new file mode 100644 index 0000000000..1a6fe540cf --- /dev/null +++ b/net/iob/iob.h @@ -0,0 +1,78 @@ +/**************************************************************************** + * net/iob/iob.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __NET_IOB_IOB_H +#define __NET_IOB_IOB_H 1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This is a pool of pre-allocated I/O buffers */ + +extern struct iob_s g_iob_pool[CONFIG_IOB_NBUFFERS]; + +/* A list of all free, unallocated I/O buffers */ + +extern sq_queue_t g_iob_freelist; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + + +#endif /* __NET_IOB_IOB_H */ diff --git a/net/iob/iob_alloc.c b/net/iob/iob_alloc.c new file mode 100644 index 0000000000..c2c060d84f --- /dev/null +++ b/net/iob/iob_alloc.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * net/iob/iob_alloc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_alloc + * + * Description: + * Allocate an I/O buffer by take the buffer at the head of the free list. + * + ****************************************************************************/ + +FAR struct iob_s *iob_alloc(void) +{ + return (FAR struct iob_s *)sq_remfirst(&g_iob_freelist); +} diff --git a/net/iob/iob_concat.c b/net/iob/iob_concat.c new file mode 100644 index 0000000000..d7b03e1fce --- /dev/null +++ b/net/iob/iob_concat.c @@ -0,0 +1,158 @@ +/**************************************************************************** + * net/iob/iob_concat.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_concat + * + * Description: + * Concatenate iob_s chain iob2 to iob1. + * + ****************************************************************************/ + +void iob_concat(FAR struct iob_s *iob1, FAR struct iob_s *iob2) +{ + unsigned int offset2; + unsigned int ncopy; + unsigned int navail; + + /* Find the last buffer in the iob1 buffer chain */ + + while (iob1->io_link.flink) + { + iob1 = (FAR struct iob_s *)iob1->io_link.flink; + } + + /* Then add data to the end of iob1 */ + + offset2 = 0; + while (iob2) + { + /* Is the iob1 tail buffer full? */ + + if (iob1->io_len >= CONFIG_IOB_BUFSIZE) + { + /* Yes.. Just connect the chains */ + + iob1->io_link.flink = iob2->io_link.flink; + + /* Has the data offset in iob2? */ + + if (offset2 > 0) + { + /* Yes, move the data down and adjust the size */ + + iob2->io_len -= offset2; + memcpy(iob2->io_data, &iob2->io_data[offset2], iob2->io_len); + + /* Set up to continue packing, but now into iob2 */ + + iob1 = iob2; + iob2 = (FAR struct iob_s *)iob2->io_link.flink; + + iob1->io_link.flink = NULL; + offset2 = 0; + } + else + { + /* Otherwise, we are done */ + + return; + } + } + + /* How many bytes can we copy from the source (iob2) */ + + ncopy = iob2->io_len - offset2; + + /* Limit the size of the copy to the amount of free space in iob1 */ + + navail = CONFIG_IOB_BUFSIZE - iob1->io_len; + if (ncopy > navail) + { + ncopy = navail; + } + + /* Copy the data from iob2 into iob1 */ + + memcpy(iob1->io_data + iob1->io_len, iob2->io_data, ncopy); + iob1->io_len += ncopy; + offset2 += ncopy; + + /* Have we consumed all of the data in the iob2 entry? */ + + if (offset2 >= iob2->io_len) + { + /* Yes.. free the iob2 entry and start processing the next I/O + * buffer in the iob2 chain. + */ + + iob2 = iob_free(iob2); + offset2 = 0; + } + } +} diff --git a/net/iob/iob_copyout.c b/net/iob/iob_copyout.c new file mode 100644 index 0000000000..5997c7f973 --- /dev/null +++ b/net/iob/iob_copyout.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * net/iob/iob_copyout.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_copyout + * + * Description: + * Copy data 'len' bytes of data into the user buffer starting at 'offset' + * in the I/O buffer. + * + ****************************************************************************/ + +void iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob, + unsigned int len, unsigned int offset) +{ + FAR const uint8_t *src; + unsigned int ncopy; + unsigned int avail; + + /* Skip to the I/O buffer containing the offset */ + + while (offset >= iob->io_len) + { + offset -= iob->io_len; + iob = (FAR struct iob_s *)iob->io_link.flink; + } + + /* Then loop until all of the I/O data is copied to the user buffer */ + + while (len > 0) + { + ASSERT(iob); + + /* Get the source I/O buffer offset address and the amount of data + * available from that address. + */ + + src = &iob->io_data[offset]; + avail = iob->io_len - offset; + + /* Copy the whole I/O buffer in to the user buffer */ + + ncopy = MIN(avail, len); + memcpy(dest, src, ncopy); + + /* Adjust the total length of the copy and the destination address in + * the user buffer. + */ + + len -= ncopy; + dest += ncopy; + + /* Skip to the next I/O buffer in the chain */ + + iob = (FAR struct iob_s *)iob->io_link.flink; + offset = 0; + } +} diff --git a/net/iob/iob_free.c b/net/iob/iob_free.c new file mode 100644 index 0000000000..273f4b5a00 --- /dev/null +++ b/net/iob/iob_free.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * net/iob/iob_free.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_free + * + * Description: + * Free the I/O buffer at the head of a buffer chain returning it to the + * free list. The link to the next I/O buffer in the chain is return. + * + ****************************************************************************/ + +FAR struct iob_s *iob_free(FAR struct iob_s *iob) +{ + sq_entry_t *next = iob->io_link.flink; + + sq_addlast(&iob->io_link, &g_iob_freelist); + return (FAR struct iob_s *)next; +} diff --git a/net/iob/iob_freeq.c b/net/iob/iob_freeq.c new file mode 100644 index 0000000000..fa9cce8ab5 --- /dev/null +++ b/net/iob/iob_freeq.c @@ -0,0 +1,96 @@ +/**************************************************************************** + * net/iob/iob_freeq.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_freeq + * + * Description: + * Free an entire buffer chain + * + ****************************************************************************/ + +void iob_freeq(FAR sq_queue_t *q) +{ + /* If the free list is empty, then just move the entry queue to the the + * free list. Otherwise, append the list to the end of the free list. + */ + + if (g_iob_freelist.tail) + { + g_iob_freelist.tail->flink = q->head; + } + else + { + g_iob_freelist.head = q->head; + } + + /* In either case, the tail of the queue is the tail of queue becomes the + * tail of the free list. + */ + + g_iob_freelist.tail = q->tail; +} diff --git a/net/iob/iob_initialize.c b/net/iob/iob_initialize.c new file mode 100644 index 0000000000..c5f72c397b --- /dev/null +++ b/net/iob/iob_initialize.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * net/iob/iob_initialize.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is a pool of pre-allocated I/O buffers */ + +struct iob_s g_iob_pool[CONFIG_IOB_NBUFFERS]; + +/* A list of all free, unallocated I/O buffers */ + +sq_queue_t g_iob_freelist; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_initialize + * + * Description: + * Set up the I/O buffers for normal operations. + * + ****************************************************************************/ + +void iob_initialize(void) +{ + static bool initialized = false; + int i; + + /* Perform one-time initialization */ + + if (!initialized) + { + /* Add each I/O buffer to the free list */ + + for (i = 0; i < CONFIG_IOB_NBUFFERS; i++) + { + sq_addlast(&g_iob_pool[i].io_link, &g_iob_freelist); + } + + initialized = true; + } +} diff --git a/net/iob/iob_trimhead.c b/net/iob/iob_trimhead.c new file mode 100644 index 0000000000..ef6e1c2f61 --- /dev/null +++ b/net/iob/iob_trimhead.c @@ -0,0 +1,113 @@ +/**************************************************************************** + * net/iob/iob_trimhead.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_trimhead + * + * Description: + * Remove bytes from the beginning of an I/O chain + * + ****************************************************************************/ + +void iob_trimhead(FAR struct iob_s *iob, unsigned int trimlen) +{ + FAR struct iob_s *entry; + unsigned int len; + + if (iob && trimlen > 0) + { + entry = iob; + len = trimlen; + + /* Trim from the head of the I/IO buffer chain */ + + while (entry != NULL && len > 0) + { + /* Do we trim this entire I/O buffer away? */ + + if (entry->io_len <= len) + { + /* Yes.. just set is length to zero and skip to the next */ + + len -= entry->io_len; + entry->io_len = 0; + entry = (FAR struct iob_s *)entry->io_link.flink; + } + else + { + /* No, then just take what we need from this I/O buffer and + * stop the trim. + */ + + entry->io_len -= len; + memcpy(entry->io_data, &entry->io_data[len], entry->io_len); + len = 0; + } + } + } +} diff --git a/net/iob/iob_trimtail.c b/net/iob/iob_trimtail.c new file mode 100644 index 0000000000..030042be9d --- /dev/null +++ b/net/iob/iob_trimtail.c @@ -0,0 +1,151 @@ +/**************************************************************************** + * net/iob/iob_trimtail.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_trimtail + * + * Description: + * Remove bytes from the end of an I/O chain + * + ****************************************************************************/ + +void iob_trimtail(FAR struct iob_s *iob, unsigned int trimlen) +{ + FAR struct iob_s *entry; + FAR struct iob_s *penultimate; + FAR struct iob_s *last; + unsigned int iosize; + int len; + + if (iob && trimlen > 0) + { + len = trimlen; + + /* Loop until complete the trim */ + + while (len > 0) + { + /* Calculate the total length of the data in the I/O buffer + * chain and find the last entry in the chain. + */ + + penultimate = NULL; + last = NULL; + iosize = 0; + + for (entry = iob; + entry; + entry = (FAR struct iob_s *)entry->io_link.flink) + { + /* Accumulate the total size of all buffers in the list */ + + iosize += entry->io_len; + + /* Remember the last and the next to the last in the chain */ + + penultimate = last; + last = entry; + } + + /* Trim from the last entry in the chain. Do we trim this entire + * I/O buffer away? + */ + + if (last->io_len <= len) + { + /* Yes.. just set is length to zero and skip to the next */ + + len -= last->io_len; + last->io_len = 0; + + /* There should be a buffer before this one */ + + if (!penultimate) + { + return; + } + + /* Free the last, empty buffer in the list */ + + iob_free(last); + penultimate->io_link.flink = NULL; + } + + else + { + /* No, then just take what we need from this I/O buffer and + * stop the trim. + */ + + last->io_len -= len; + memcpy(last->io_data, &last->io_data[len], last->io_len); + len = 0; + } + } + } +}