summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/include/nuttx/net/iob.h91
-rw-r--r--nuttx/net/iob/Kconfig8
-rw-r--r--nuttx/net/iob/Make.defs8
-rw-r--r--nuttx/net/iob/iob.h32
-rw-r--r--nuttx/net/iob/iob_add_queue.c104
-rw-r--r--nuttx/net/iob/iob_alloc.c36
-rw-r--r--nuttx/net/iob/iob_alloc_qentry.c (renamed from nuttx/net/iob/iob_freeq.c)43
-rw-r--r--nuttx/net/iob/iob_clone.c9
-rw-r--r--nuttx/net/iob/iob_concat.c7
-rw-r--r--nuttx/net/iob/iob_copyin.c7
-rw-r--r--nuttx/net/iob/iob_copyout.c5
-rw-r--r--nuttx/net/iob/iob_free.c17
-rw-r--r--nuttx/net/iob/iob_free_chain.c (renamed from nuttx/net/iob/iob_freechain.c)35
-rw-r--r--nuttx/net/iob/iob_free_qentry.c96
-rw-r--r--nuttx/net/iob/iob_free_queue.c114
-rw-r--r--nuttx/net/iob/iob_initialize.c35
-rw-r--r--nuttx/net/iob/iob_pack.c7
-rw-r--r--nuttx/net/iob/iob_remove_queue.c94
-rw-r--r--nuttx/net/iob/iob_test.c39
-rw-r--r--nuttx/net/iob/iob_trimhead.c6
-rw-r--r--nuttx/net/iob/iob_trimtail.c7
21 files changed, 642 insertions, 158 deletions
diff --git a/nuttx/include/nuttx/net/iob.h b/nuttx/include/nuttx/net/iob.h
index 839d78b8b..0daa0f39d 100644
--- a/nuttx/include/nuttx/net/iob.h
+++ b/nuttx/include/nuttx/net/iob.h
@@ -43,7 +43,6 @@
#include <nuttx/config.h>
#include <stdint.h>
-#include <queue.h>
#include <nuttx/net/iob.h>
@@ -54,7 +53,10 @@
/* IOB flags */
#define IOBFLAGS_MCAST (1 << 0) /* Multicast packet */
-#define IOBFLAGS_VLANTAG (1 << 1) /* VLAN tag is value (not supported) */
+
+/* Queue helpers */
+
+#define IOB_QINIT(q) do { (q)->qh_head = 0; (q)->qh_tail = 0; } while (0)
/****************************************************************************
* Public Types
@@ -67,21 +69,49 @@
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 */
+ /* Singly-link list support */
+
+ FAR struct iob_s *io_flink;
+
+ /* Payload */
+
+ uint8_t io_flags; /* Flags associated with the I/O buffer */
#if CONFIG_IOB_BUFSIZE < 256
- uint8_t io_len; /* Length of the data in the entry */
- uint8_t io_offset; /* Data begins at this offset */
+ uint8_t io_len; /* Length of the data in the entry */
+ uint8_t io_offset; /* Data begins at this offset */
#else
- uint16_t io_len; /* Length of the data in the entry */
- uint16_t io_offset; /* Data begins at this offset */
+ uint16_t io_len; /* Length of the data in the entry */
+ uint16_t io_offset; /* Data begins at this offset */
#endif
- uint16_t io_pktlen; /* Total length of the packet */
-#ifdef __NO_VLAN__
- uint16_t io_vtag; /* VLAN tag (not supported) */
-#endif
- void *io_priv; /* User private data attached to the I/O buffer */
- uint8_t io_data[CONFIG_IOB_BUFSIZE];
+ uint16_t io_pktlen; /* Total length of the packet */
+ void *io_priv; /* User private data attached to the I/O buffer */
+
+ uint8_t io_data[CONFIG_IOB_BUFSIZE];
+};
+
+/* This container structure supports queuing of I/O buffer chains. This
+ * structure is intended only for internal use by the IOB module.
+ */
+
+struct iob_qentry_s
+{
+ /* Singly-link list support */
+
+ FAR struct iob_qentry_s *qe_flink;
+
+ /* Payload -- Head of the I/O buffer chain */
+
+ FAR struct iob_s *qe_head;
+};
+
+/* The I/O buffer queue head structure */
+
+struct iob_queue_s
+{
+ /* Head of the I/O buffer chain list */
+
+ FAR struct iob_qentry_s *qh_head;
+ FAR struct iob_qentry_s *qh_tail;
};
/****************************************************************************
@@ -106,7 +136,7 @@ void iob_initialize(void);
* Name: iob_alloc
*
* Description:
- * Allocate an I/O buffer by take the buffer at the head of the free list.
+ * Allocate an I/O buffer by taking the buffer at the head of the free list.
*
****************************************************************************/
@@ -124,7 +154,7 @@ FAR struct iob_s *iob_alloc(void);
FAR struct iob_s *iob_free(FAR struct iob_s *iob);
/****************************************************************************
- * Name: iob_freechain
+ * Name: iob_free_chain
*
* Description:
* Free an entire buffer chain, starting at the beginning of the I/O
@@ -132,17 +162,38 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob);
*
****************************************************************************/
-void iob_freechain(FAR struct iob_s *iob);
+void iob_free_chain(FAR struct iob_s *iob);
+
+/****************************************************************************
+ * Name: iob_add_queue
+ *
+ * Description:
+ * Add one I/O buffer chain to the end of a queue. May fail due to lack
+ * of resources.
+ *
+ ****************************************************************************/
+
+int iob_add_queue(FAR struct iob_s *iob, FAR struct iob_queue_s *iobq);
+
+/****************************************************************************
+ * Name: iob_add_queue
+ *
+ * Description:
+ * Remove one I/O buffer chain from the heaqd of a queue.
+ *
+ ****************************************************************************/
+
+FAR struct iob_s *iob_remove_queue(FAR struct iob_queue_s *iobq);
/****************************************************************************
- * Name: iob_freeq
+ * Name: iob_free_queue
*
* Description:
- * Free an entire buffer chain, starting at a queue head
+ * Free an entire queue of I/O buffer chains.
*
****************************************************************************/
-void iob_freeq(FAR sq_queue_t *q);
+void iob_free_queue(FAR struct iob_queue_s *qhead);
/****************************************************************************
* Name: iob_copyin
diff --git a/nuttx/net/iob/Kconfig b/nuttx/net/iob/Kconfig
index 0a5c8522a..a82e1c174 100644
--- a/nuttx/net/iob/Kconfig
+++ b/nuttx/net/iob/Kconfig
@@ -28,4 +28,12 @@ config IOB_BUFSIZE
chain. This setting determines the data payload each preallocated
I/O buffer.
+config IOB_NCHAINS
+ int "Number of pre-allocated I/O buffer chain heads"
+ default 8
+ ---help---
+ These tiny nodes are used as "containers" to suppor queueing of
+ I/O buffer chains. This will limit the number of I/O transactions
+ that can be "in-flight" at any give time.
+
endif # NET_IOB
diff --git a/nuttx/net/iob/Make.defs b/nuttx/net/iob/Make.defs
index f70b7821a..9ad9b871b 100644
--- a/nuttx/net/iob/Make.defs
+++ b/nuttx/net/iob/Make.defs
@@ -40,9 +40,11 @@ ifeq ($(CONFIG_NET_IOB),y)
# Include IOB src files
-NET_CSRCS += iob_alloc.c iob_clone.c iob_concat.c iob_copyin.c iob_copyout.c
-NET_CSRCS += iob_free.c iob_freechain.c iob_freeq.c iob_initialize.c
-NET_CSRCS += iob_pack.c iob_trimhead.c iob_trimtail.c
+NET_CSRCS += iob_add_queue.c iob_alloc.c iob_alloc_qentry.c iob_clone.c
+NET_CSRCS += iob_concat.c iob_copyin.c iob_copyout.c iob_free.c
+NET_CSRCS += iob_free_chain.c iob_free_qentry.c iob_free_queue.c
+NET_CSRCS += iob_initialize.c iob_pack.c iob_remove_queue.c iob_trimhead.c
+NET_CSRCS += iob_trimtail.c
# Include iob build support
diff --git a/nuttx/net/iob/iob.h b/nuttx/net/iob/iob.h
index 1a6fe540c..0507fa34d 100644
--- a/nuttx/net/iob/iob.h
+++ b/nuttx/net/iob/iob.h
@@ -42,8 +42,6 @@
#include <nuttx/config.h>
-#include <queue.h>
-
#include <nuttx/net/iob.h>
/****************************************************************************
@@ -58,13 +56,13 @@
* Public Data
****************************************************************************/
-/* This is a pool of pre-allocated I/O buffers */
+/* A list of all free, unallocated I/O buffers */
-extern struct iob_s g_iob_pool[CONFIG_IOB_NBUFFERS];
+extern FAR struct iob_s *g_iob_freelist;
-/* A list of all free, unallocated I/O buffers */
+/* A list of all free, unallocated I/O buffer queue containers */
-extern sq_queue_t g_iob_freelist;
+extern FAR struct iob_qentry_s *g_iob_freeqlist;
/****************************************************************************
* Public Data
@@ -74,5 +72,27 @@ extern sq_queue_t g_iob_freelist;
* Public Function Prototypes
****************************************************************************/
+/****************************************************************************
+ * Name: iob_alloc_qentry
+ *
+ * Description:
+ * Allocate an I/O buffer chain container by taking the buffer at the head
+ * of the free list. This function is intended only for internal use by
+ * the IOB module.
+ *
+ ****************************************************************************/
+
+FAR struct iob_qentry_s *iob_alloc_qentry(void);
+
+/****************************************************************************
+ * Name: iob_free_qentry
+ *
+ * Description:
+ * Free the I/O buffer chain container by returning it to the free list.
+ * The link to the next I/O buffer in the chain is return.
+ *
+ ****************************************************************************/
+
+FAR struct iob_qentry_s *iob_free_qentry(FAR struct iob_qentry_s *iobq);
#endif /* __NET_IOB_IOB_H */
diff --git a/nuttx/net/iob/iob_add_queue.c b/nuttx/net/iob/iob_add_queue.c
new file mode 100644
index 000000000..0a2ac3d0a
--- /dev/null
+++ b/nuttx/net/iob/iob_add_queue.c
@@ -0,0 +1,104 @@
+/****************************************************************************
+ * net/iob/iob_add_queue.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/net/iob.h>
+
+#include "iob.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef NULL
+# define NULL ((FAR void *)0)
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: iob_add_queue
+ *
+ * Description:
+ * Add one I/O buffer chain to the end of a queue. May fail due to lack
+ * of resources.
+ *
+ ****************************************************************************/
+
+int iob_add_queue(FAR struct iob_s *iob, FAR struct iob_queue_s *iobq)
+{
+ FAR struct iob_qentry_s *qentry;
+
+ /* Allocate a container to hold the I/O buffer chain */
+
+ qentry = iob_alloc_qentry();
+ if (!qentry)
+ {
+ ndbg("ERROR: Failed to allocate a container\n");
+ return -ENOMEM;
+ }
+
+ /* Add the I/O buffer chain to the container */
+
+ qentry->qe_head = iob;
+
+ /* Add the container to the end of the queue */
+
+ qentry->qe_flink = NULL;
+ if (!iobq->qh_head)
+ {
+ iobq->qh_head = qentry;
+ iobq->qh_tail = qentry;
+ }
+ else
+ {
+ DEBUGASSERT(iobq->qh_tail);
+ iobq->qh_tail->qe_flink = qentry;
+ iobq->qh_tail = qentry;
+ }
+
+ return 0;
+}
diff --git a/nuttx/net/iob/iob_alloc.c b/nuttx/net/iob/iob_alloc.c
index a3c1bc64a..39c7d5f1c 100644
--- a/nuttx/net/iob/iob_alloc.c
+++ b/nuttx/net/iob/iob_alloc.c
@@ -39,8 +39,7 @@
#include <nuttx/config.h>
-#include <queue.h>
-
+#include <nuttx/arch.h>
#include <nuttx/net/iob.h>
#include "iob.h"
@@ -69,24 +68,39 @@
* Name: iob_alloc
*
* Description:
- * Allocate an I/O buffer by take the buffer at the head of the free list.
+ * Allocate an I/O buffer by taking the buffer at the head of the free list.
*
****************************************************************************/
FAR struct iob_s *iob_alloc(void)
{
FAR struct iob_s *iob;
+ irqstate_t flags;
+
+ /* We don't know what context we are called from so we use extreme measures
+ * to protect the free list: We disable interrupts very briefly.
+ */
- iob = (FAR struct iob_s *)sq_remfirst(&g_iob_freelist);
+ flags = irqsave();
+ iob = g_iob_freelist;
if (iob)
{
- iob->io_link.flink = NULL; /* Not in a chain */
- iob->io_flags = 0; /* Flags associated with the I/O buffer */
- iob->io_len = 0; /* Length of the data in the entry */
- iob->io_offset = 0; /* Offset to the beginning of data */
- iob->io_pktlen = 0; /* Total length of the packet */
- iob->io_priv = NULL; /* User private data attached to the I/O buffer */
+ /* Remove the I/O buffer from the free list */
+
+ g_iob_freelist = iob->io_flink;
+ irqrestore(flags);
+
+ /* Put the I/O buffer in a known state */
+
+ iob->io_flink = NULL; /* Not in a chain */
+ iob->io_flags = 0; /* Flags associated with the I/O buffer */
+ iob->io_len = 0; /* Length of the data in the entry */
+ iob->io_offset = 0; /* Offset to the beginning of data */
+ iob->io_pktlen = 0; /* Total length of the packet */
+ iob->io_priv = NULL; /* User private data attached to the I/O buffer */
+ return iob;
}
- return iob;
+ irqrestore(flags);
+ return NULL;
}
diff --git a/nuttx/net/iob/iob_freeq.c b/nuttx/net/iob/iob_alloc_qentry.c
index 12eb8021e..0c29fbec1 100644
--- a/nuttx/net/iob/iob_freeq.c
+++ b/nuttx/net/iob/iob_alloc_qentry.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * net/iob/iob_freeq.c
+ * net/iob/iob_alloc_qentry.c
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@@ -39,8 +39,7 @@
#include <nuttx/config.h>
-#include <queue.h>
-
+#include <nuttx/arch.h>
#include <nuttx/net/iob.h>
#include "iob.h"
@@ -66,35 +65,37 @@
****************************************************************************/
/****************************************************************************
- * Name: iob_freeq
+ * Name: iob_alloc_qentry
*
* Description:
- * Free an entire buffer chain, starting at a queue head
+ * Allocate an I/O buffer chain container by taking the buffer at the head
+ * of the free list. This function is intended only for internal use by
+ * the IOB module.
*
****************************************************************************/
-void iob_freeq(FAR sq_queue_t *q)
+FAR struct iob_qentry_s *iob_alloc_qentry(void)
{
- /* If the free list is empty, then just move the entry queue to the free
- * list. Otherwise, append the list to the end of the free list.
+ FAR struct iob_qentry_s *iobq;
+ irqstate_t flags;
+
+ /* We don't know what context we are called from so we use extreme measures
+ * to protect the free list: We disable interrupts very briefly.
*/
- if (g_iob_freelist.tail)
- {
- g_iob_freelist.tail->flink = q->head;
- }
- else
+ flags = irqsave();
+ iobq = g_iob_freeqlist;
+ if (iobq)
{
- g_iob_freelist.head = q->head;
- }
+ /* Remove the I/O buffer chain container from the free list */
- /* In either case, the tail of the queue is the tail of queue becomes the
- * tail of the free list.
- */
+ g_iob_freeqlist = iobq->qe_flink;
- g_iob_freelist.tail = q->tail;
+ /* Put the I/O buffer in a known state */
- /* Reset the queue to empty */
+ iobq->qe_head = NULL; /* Nothing is contained */
+ }
- sq_init(q);
+ irqrestore(flags);
+ return iobq;
}
diff --git a/nuttx/net/iob/iob_clone.c b/nuttx/net/iob/iob_clone.c
index 0ba98f9f2..c44daffc7 100644
--- a/nuttx/net/iob/iob_clone.c
+++ b/nuttx/net/iob/iob_clone.c
@@ -40,7 +40,6 @@
#include <nuttx/config.h>
#include <string.h>
-#include <queue.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
@@ -92,7 +91,7 @@ int iob_clone(FAR struct iob_s *iob1, FAR struct iob_s *iob2)
unsigned int offset2;
DEBUGASSERT(iob2->io_len == 0 && iob2->io_offset == 0 &&
- iob2->io_pktlen == 0 && iob2->io_link.flink == NULL);
+ iob2->io_pktlen == 0 && iob2->io_flink == NULL);
/* Copy the header information */
@@ -106,7 +105,7 @@ int iob_clone(FAR struct iob_s *iob1, FAR struct iob_s *iob2)
while (iob1->io_len <= 0)
{
- iob1 = (FAR struct iob_s *)iob1->io_link.flink;
+ iob1 = iob1->io_flink;
}
/* Pack each entry from iob1 to iob2 */
@@ -152,7 +151,7 @@ int iob_clone(FAR struct iob_s *iob1, FAR struct iob_s *iob2)
{
/* Yes.. move to the next source I/O buffer */
- iob1 = (FAR struct iob_s *)iob1->io_link.flink;
+ iob1 = iob1->io_flink;
}
while (iob1->io_len <= 0);
@@ -180,7 +179,7 @@ int iob_clone(FAR struct iob_s *iob1, FAR struct iob_s *iob2)
return -ENOMEM;
}
- iob2->io_link.flink = &next->io_link;
+ iob2->io_flink = next;
iob2 = next;
offset2 = 0;
}
diff --git a/nuttx/net/iob/iob_concat.c b/nuttx/net/iob/iob_concat.c
index 1e2620615..9ca09b1d9 100644
--- a/nuttx/net/iob/iob_concat.c
+++ b/nuttx/net/iob/iob_concat.c
@@ -40,7 +40,6 @@
#include <nuttx/config.h>
#include <string.h>
-#include <queue.h>
#include <nuttx/net/iob.h>
@@ -78,14 +77,14 @@ void iob_concat(FAR struct iob_s *iob1, FAR struct iob_s *iob2)
{
/* Find the last buffer in the iob1 buffer chain */
- while (iob1->io_link.flink)
+ while (iob1->io_flink)
{
- iob1 = (FAR struct iob_s *)iob1->io_link.flink;
+ iob1 = iob1->io_flink;
}
/* Then connect iob2 buffer chain to the end of the iob1 chain */
- iob1->io_link.flink = iob2->io_link.flink;
+ iob1->io_flink = iob2;
/* Combine the total packet size. flags, VLAN, tags, and private
* data from iob2 are lost.
diff --git a/nuttx/net/iob/iob_copyin.c b/nuttx/net/iob/iob_copyin.c
index 48129af0c..0c9b3f037 100644
--- a/nuttx/net/iob/iob_copyin.c
+++ b/nuttx/net/iob/iob_copyin.c
@@ -41,7 +41,6 @@
#include <stdint.h>
#include <string.h>
-#include <queue.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
@@ -108,14 +107,14 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
while (offset > iob->io_len)
{
offset -= iob->io_len;
- iob = (FAR struct iob_s *)iob->io_link.flink;
+ iob = iob->io_flink;
}
/* Then loop until all of the I/O data is copied from the user buffer */
while (len > 0)
{
- next = (FAR struct iob_s *)iob->io_link.flink;
+ next = iob->io_flink;
/* Get the destination I/O buffer address and the amount of data
* available from that address.
@@ -204,7 +203,7 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
/* Add the new, empty I/O buffer to the end of the buffer chain. */
- iob->io_link.flink = &next->io_link;
+ iob->io_flink = next;
}
iob = next;
diff --git a/nuttx/net/iob/iob_copyout.c b/nuttx/net/iob/iob_copyout.c
index 4afab2616..5695eb2e9 100644
--- a/nuttx/net/iob/iob_copyout.c
+++ b/nuttx/net/iob/iob_copyout.c
@@ -42,7 +42,6 @@
#include <stdint.h>
#include <string.h>
#include <assert.h>
-#include <queue.h>
#include <nuttx/net/iob.h>
@@ -94,7 +93,7 @@ int iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob,
while (offset >= iob->io_len)
{
offset -= iob->io_len;
- iob = (FAR struct iob_s *)iob->io_link.flink;
+ iob = iob->io_flink;
}
/* Then loop until all of the I/O data is copied to the user buffer */
@@ -123,7 +122,7 @@ int iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob,
/* Skip to the next I/O buffer in the chain */
- iob = (FAR struct iob_s *)iob->io_link.flink;
+ iob = iob->io_flink;
offset = 0;
}
diff --git a/nuttx/net/iob/iob_free.c b/nuttx/net/iob/iob_free.c
index 3cebb099a..e92bf1937 100644
--- a/nuttx/net/iob/iob_free.c
+++ b/nuttx/net/iob/iob_free.c
@@ -39,9 +39,9 @@
#include <nuttx/config.h>
-#include <queue.h>
#include <assert.h>
+#include <nuttx/arch.h>
#include <nuttx/net/iob.h>
#include "iob.h"
@@ -77,7 +77,8 @@
FAR struct iob_s *iob_free(FAR struct iob_s *iob)
{
- FAR struct iob_s *next = (FAR struct iob_s *)iob->io_link.flink;
+ FAR struct iob_s *next = iob->io_flink;
+ irqstate_t flags;
/* Copy the data that only exists in the head of a I/O buffer chain into
* the next entry.
@@ -108,13 +109,19 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob)
*/
next->io_pktlen = 0;
- DEBUGASSERT(next->io_len == 0 && next->io_link.flink == NULL);
+ DEBUGASSERT(next->io_len == 0 && next->io_flink == NULL);
}
}
- /* Free the I/O buffer by adding to the end of the free list */
+ /* Free the I/O buffer by adding it to the head of the free list. We don't
+ * know what context we are called from so we use extreme measures to
+ * protect the free list: We disable interrupts very briefly.
+ */
- sq_addlast(&iob->io_link, &g_iob_freelist);
+ flags = irqsave();
+ iob->io_flink = g_iob_freelist;
+ g_iob_freelist = iob;
+ irqrestore(flags);
/* And return the I/O buffer after the one that was freed */
diff --git a/nuttx/net/iob/iob_freechain.c b/nuttx/net/iob/iob_free_chain.c
index bc66365f7..db9fc408c 100644
--- a/nuttx/net/iob/iob_freechain.c
+++ b/nuttx/net/iob/iob_free_chain.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * net/iob/iob_freechain.c
+ * net/iob/iob_free_chain.c
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@@ -39,8 +39,7 @@
#include <nuttx/config.h>
-#include <queue.h>
-
+#include <nuttx/arch.h>
#include <nuttx/net/iob.h>
#include "iob.h"
@@ -66,7 +65,7 @@
****************************************************************************/
/****************************************************************************
- * Name: iob_freechain
+ * Name: iob_free_chain
*
* Description:
* Free an entire buffer chain, starting at the beginning of the I/O
@@ -74,28 +73,22 @@
*
****************************************************************************/
-void iob_freechain(FAR struct iob_s *iob)
+void iob_free_chain(FAR struct iob_s *iob)
{
- FAR sq_entry_t *first = (sq_entry_t *)&iob->io_link;
- FAR sq_entry_t *last;
+ FAR struct iob_s *last;
+ irqstate_t flags;
/* Find the last entry in the I/O buffer list */
- for (last = first; last->flink; last = last->flink);
+ for (last = iob; last->io_flink; last = last->io_flink);
- /* If the free list is empty, then just move the I/O buffer chain to the
- * free list. Otherwise, append the I/O buffer chain to the end of the
- * free list.
+ /* Free the I/O buffer chain by adding it to the head of the free list. We
+ * don't know what context we are called from so we use extreme measures to
+ * protect the free list: We disable interrupts very briefly.
*/
- if (g_iob_freelist.tail)
- {
- g_iob_freelist.tail->flink = first;
- }
- else
- {
- g_iob_freelist.head = first;
- }
-
- g_iob_freelist.tail = last;
+ flags = irqsave();
+ last->io_flink = g_iob_freelist;
+ g_iob_freelist = iob;
+ irqrestore(flags);
}
diff --git a/nuttx/net/iob/iob_free_qentry.c b/nuttx/net/iob/iob_free_qentry.c
new file mode 100644
index 000000000..55d4cf848
--- /dev/null
+++ b/nuttx/net/iob/iob_free_qentry.c
@@ -0,0 +1,96 @@
+/****************************************************************************
+ * net/iob/iob_free_qentry.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+
+#include <assert.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/net/iob.h>
+
+#include "iob.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: iob_free_qentry
+ *
+ * Description:
+ * Free the I/O buffer chain container by returning it to the free list.
+ * The link to the next I/O buffer in the chain is return.
+ *
+ ****************************************************************************/
+
+FAR struct iob_qentry_s *iob_free_qentry(FAR struct iob_qentry_s *iobq)
+{
+ FAR struct iob_qentry_s *nextq = iobq->qe_flink;
+ irqstate_t flags;
+
+ /* Free the I/O buffer chain container by adding it to the head of the free
+ * list. We don't know what context we are called from so we use extreme
+ * measures to protect the free list: We disable interrupts very briefly.
+ */
+
+ flags = irqsave();
+ iobq->qe_flink = g_iob_freeqlist;
+ g_iob_freeqlist = iobq;
+ irqrestore(flags);
+
+ /* And return the I/O buffer chain container after the one that was freed */
+
+ return nextq;
+}
diff --git a/nuttx/net/iob/iob_free_queue.c b/nuttx/net/iob/iob_free_queue.c
new file mode 100644
index 000000000..1b1a51888
--- /dev/null
+++ b/nuttx/net/iob/iob_free_queue.c
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * net/iob/iob_free_queue.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+
+#include <assert.h>
+
+#include <nuttx/net/iob.h>
+
+#include "iob.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+#ifndef NULL
+# define NULL ((FAR void *)0)
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: iob_free_queue
+ *
+ * Description:
+ * Free an entire queue of I/O buffer chains.
+ *
+ ****************************************************************************/
+
+void iob_free_queue(FAR struct iob_queue_s *qhead)
+{
+ FAR struct iob_qentry_s *iobq;
+ FAR struct iob_qentry_s *nextq;
+ FAR struct iob_s *iob;
+
+ /* Detach the list from the queue head so first for safety (should be safe
+ * anyway).
+ */
+
+ iobq = qhead->qh_head;
+ qhead->qh_head = NULL;
+
+ /* Remove each I/O buffer chain from the queue */
+
+ while (iobq)
+ {
+ /* Remove the I/O buffer chain from the head of the queue and
+ * discard the queue container.
+ */
+
+ iob = iobq->qe_head;
+ DEBUGASSERT(iob);
+
+ /* Remove the queue container from the list and discard it */
+
+ nextq = iobq->qe_flink;
+ iob_free_qentry(iobq);
+ iobq = nextq;
+
+ /* Free the I/O chain */
+
+ iob_free_chain(iob);
+ }
+}
diff --git a/nuttx/net/iob/iob_initialize.c b/nuttx/net/iob/iob_initialize.c
index c5f72c397..5c4c122c3 100644
--- a/nuttx/net/iob/iob_initialize.c
+++ b/nuttx/net/iob/iob_initialize.c
@@ -40,7 +40,6 @@
#include <nuttx/config.h>
#include <stdbool.h>
-#include <queue.h>
#include <nuttx/net/iob.h>
@@ -60,16 +59,21 @@
/* 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;
+static struct iob_s g_iob_pool[CONFIG_IOB_NBUFFERS];
+static struct iob_qentry_s g_iob_qpool[CONFIG_IOB_NCHAINS];
/****************************************************************************
* Public Data
****************************************************************************/
+/* A list of all free, unallocated I/O buffers */
+
+FAR struct iob_s *g_iob_freelist;
+
+/* A list of all free, unallocated I/O buffer queue containers */
+
+FAR struct iob_qentry_s *g_iob_freeqlist;
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -95,7 +99,24 @@ void iob_initialize(void)
for (i = 0; i < CONFIG_IOB_NBUFFERS; i++)
{
- sq_addlast(&g_iob_pool[i].io_link, &g_iob_freelist);
+ FAR struct iob_s *iob = &g_iob_pool[i];
+
+ /* Add the pre-allocate I/O buffer to the head of the free list */
+
+ iob->io_flink = g_iob_freelist;
+ g_iob_freelist = iob;
+ }
+
+ /* Add each I/O buffer chain queue container to the free list */
+
+ for (i = 0; i < CONFIG_IOB_NCHAINS; i++)
+ {
+ FAR struct iob_qentry_s *iobq = &g_iob_qpool[i];
+
+ /* Add the pre-allocate buffer container to the head of the free list */
+
+ iobq->qe_flink = g_iob_freeqlist;
+ g_iob_freeqlist = iobq;
}
initialized = true;
diff --git a/nuttx/net/iob/iob_pack.c b/nuttx/net/iob/iob_pack.c
index 7533cf857..eb2c772c4 100644
--- a/nuttx/net/iob/iob_pack.c
+++ b/nuttx/net/iob/iob_pack.c
@@ -40,7 +40,6 @@
#include <nuttx/config.h>
#include <string.h>
-#include <queue.h>
#include <nuttx/net/iob.h>
@@ -102,7 +101,7 @@ FAR struct iob_s *iob_pack(FAR struct iob_s *iob)
while (iob)
{
- next = (FAR struct iob_s *)iob->io_link.flink;
+ next = iob->io_flink;
/* Eliminate the data offset in this entry */
@@ -149,8 +148,8 @@ FAR struct iob_s *iob_pack(FAR struct iob_s *iob)
{
/* Yes.. free the next entry in I/O buffer chain */
- next = iob_free(next);
- iob->io_link.flink = (sq_entry_t *)next;
+ next = iob_free(next);
+ iob->io_flink = next;
}
}
diff --git a/nuttx/net/iob/iob_remove_queue.c b/nuttx/net/iob/iob_remove_queue.c
new file mode 100644
index 000000000..7a64d47c7
--- /dev/null
+++ b/nuttx/net/iob/iob_remove_queue.c
@@ -0,0 +1,94 @@
+/****************************************************************************
+ * net/iob/iob_remove_queue.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+
+#include <debug.h>
+
+#include <nuttx/net/iob.h>
+
+#include "iob.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef NULL
+# define NULL ((FAR void *)0)
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: iob_add_queue
+ *
+ * Description:
+ * Remove one I/O buffer chain from the heaqd of a queue.
+ *
+ ****************************************************************************/
+
+FAR struct iob_s *iob_remove_queue(FAR struct iob_queue_s *iobq)
+{
+ FAR struct iob_qentry_s *qentry;
+ FAR struct iob_s *iob = NULL;
+
+ /* Remove the I/O buffer chain from the head of the queue */
+
+ qentry = iobq->qh_head;
+ if (qentry)
+ {
+ iobq->qh_head = qentry->qe_flink;
+ if (!iobq->qh_head)
+ {
+ iobq->qh_tail = NULL;
+ }
+
+ /* Extract the I/O buffer chain from the container and free the
+ * container.
+ */
+
+ iob = qentry->qe_head;
+ iob_free_qentry(qentry);
+ }
+
+ return iob;
+}
+
diff --git a/nuttx/net/iob/iob_test.c b/nuttx/net/iob/iob_test.c
index 70e5f526f..93ed9b245 100644
--- a/nuttx/net/iob/iob_test.c
+++ b/nuttx/net/iob/iob_test.c
@@ -90,7 +90,7 @@ static void dump_chain(struct iob_s *iob)
n, iob->io_len, iob->io_offset, iob->io_priv);
pktlen += iob->io_len;
- iob = (struct iob_s *)iob->io_link.flink;
+ iob = iob->io_flink;
n++;
}
@@ -207,40 +207,3 @@ void my_assert(bool value)
abort();
}
}
-
-/****************************************************************************
- * Non-standard queue functions cloned from libc/queue
- ****************************************************************************/
-
-sq_entry_t *sq_remfirst(sq_queue_t *queue)
-{
- sq_entry_t *ret = queue->head;
-
- if (ret)
- {
- queue->head = ret->flink;
- if (!queue->head)
- {
- queue->tail = NULL;
- }
-
- ret->flink = NULL;
- }
-
- return ret;
-}
-
-void sq_addlast(sq_entry_t *node, sq_queue_t *queue)
-{
- node->flink = NULL;
- if (!queue->head)
- {
- queue->head = node;
- queue->tail = node;
- }
- else
- {
- queue->tail->flink = node;
- queue->tail = node;
- }
-}
diff --git a/nuttx/net/iob/iob_trimhead.c b/nuttx/net/iob/iob_trimhead.c
index 7b051be46..0fe349023 100644
--- a/nuttx/net/iob/iob_trimhead.c
+++ b/nuttx/net/iob/iob_trimhead.c
@@ -49,6 +49,10 @@
* Pre-processor Definitions
****************************************************************************/
+#ifndef NULL
+# define NULL ((FAR void *)0)
+#endif
+
/****************************************************************************
* Private Types
****************************************************************************/
@@ -105,7 +109,7 @@ FAR struct iob_s *iob_trimhead(FAR struct iob_s *iob, unsigned int trimlen)
/* Check if this was the last entry in the chain */
- next = (FAR struct iob_s *)iob->io_link.flink;
+ next = iob->io_flink;
if (!next)
{
/* Yes.. break out of the loop returning the empty
diff --git a/nuttx/net/iob/iob_trimtail.c b/nuttx/net/iob/iob_trimtail.c
index 0a7dd2911..872560a49 100644
--- a/nuttx/net/iob/iob_trimtail.c
+++ b/nuttx/net/iob/iob_trimtail.c
@@ -40,7 +40,6 @@
#include <nuttx/config.h>
#include <string.h>
-#include <queue.h>
#include <nuttx/net/iob.h>
@@ -98,9 +97,7 @@ FAR struct iob_s *iob_trimtail(FAR struct iob_s *iob, unsigned int trimlen)
last = NULL;
iosize = 0;
- for (entry = iob;
- entry;
- entry = (FAR struct iob_s *)entry->io_link.flink)
+ for (entry = iob; entry; entry = entry->io_flink)
{
/* Accumulate the total size of all buffers in the list */
@@ -139,7 +136,7 @@ FAR struct iob_s *iob_trimtail(FAR struct iob_s *iob, unsigned int trimlen)
/* Unlink the penultimate from the freed buffer */
- penultimate->io_link.flink = NULL;
+ penultimate->io_flink = NULL;
}
else