summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-08-28 10:03:48 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-08-28 10:03:48 -0600
commitb071bddd64cd63c399e518ba45394984d10bb5a0 (patch)
tree909b8534e1fef23a252048d8f833a077952170f8
parent6b35d7af6caf96b641336200afd52704b419f346 (diff)
downloadnuttx-b071bddd64cd63c399e518ba45394984d10bb5a0.tar.gz
nuttx-b071bddd64cd63c399e518ba45394984d10bb5a0.tar.bz2
nuttx-b071bddd64cd63c399e518ba45394984d10bb5a0.zip
SAMA5 EHCI: Correct and extend pool allocation logic; Fix data toggle values
-rw-r--r--nuttx/arch/arm/src/sama5/Kconfig8
-rwxr-xr-xnuttx/arch/arm/src/sama5/sam_ehci.c61
2 files changed, 57 insertions, 12 deletions
diff --git a/nuttx/arch/arm/src/sama5/Kconfig b/nuttx/arch/arm/src/sama5/Kconfig
index a492fd806..8de20d733 100644
--- a/nuttx/arch/arm/src/sama5/Kconfig
+++ b/nuttx/arch/arm/src/sama5/Kconfig
@@ -404,6 +404,14 @@ config SAMA5_EHCI_BUFSIZE
size must be an even number of 32-bit words and must be large enough
to hangle the largest transfer via a SETUP request.
+config SAMA5_EHCI_PREALLOCATE
+ bool "Preallocate descriptor pool"
+ default y
+ ---help---
+ Select this option to pre-allocate EHCI queue and descriptor
+ structure pools in .bss. Otherwise, these pools will be
+ dynamically allocated using kmemalign().
+
config SAMA5_EHCI_REGDEBUG
bool "Enable low-level EHCI register debug"
default n
diff --git a/nuttx/arch/arm/src/sama5/sam_ehci.c b/nuttx/arch/arm/src/sama5/sam_ehci.c
index 56cf2aa9d..45b53d154 100755
--- a/nuttx/arch/arm/src/sama5/sam_ehci.c
+++ b/nuttx/arch/arm/src/sama5/sam_ehci.c
@@ -415,6 +415,7 @@ static struct sam_qh_s g_perhead __attribute__ ((aligned(32)));
static uint32_t g_framelist[FRAME_LIST_SIZE] __attribute__ ((aligned(4096)));
#endif
+#ifdef CONFIG_SAMA5_EHCI_PREALLOCATE
/* Pools of pre-allocated data structures. These will all be linked into the
* free lists within g_ehci. These must all be aligned to 32-byte boundaries
*/
@@ -429,6 +430,21 @@ static struct sam_qh_s g_qhpool[CONFIG_SAMA5_EHCI_NQHS]
static struct sam_qtd_s g_qtdpool[CONFIG_SAMA5_EHCI_NQTDS]
__attribute__ ((aligned(32)));
+#else
+/* Pools of dynamically data structures. These will all be linked into the
+ * free lists within g_ehci. These must all be aligned to 32-byte boundaries
+ */
+
+/* Queue Head (QH) pool */
+
+static struct sam_qh_s *g_qhpool;
+
+/* Queue Element Transfer Descriptor (qTD) pool */
+
+static struct sam_qtd_s *g_qtdpool;
+
+#endif
+
/*******************************************************************************
* Private Functions
*******************************************************************************/
@@ -824,7 +840,7 @@ static struct sam_qtd_s *sam_qtd_alloc(void)
if (qtd)
{
g_ehci.qtdfree = ((struct sam_list_s *)qtd)->flink;
- memset(qtd, 0, sizeof(struct sam_list_s));
+ memset(qtd, 0, sizeof(struct sam_qtd_s));
}
return qtd;
@@ -1836,13 +1852,6 @@ static ssize_t sam_async_transfer(struct sam_rhport_s *rhport,
DEBUGASSERT(rhport && epinfo);
- if (req != NULL)
- {
- uvdbg("req=%02x type=%02x value=%04x index=%04x\n",
- req->req, req->type, sam_read16(req->value),
- sam_read16(req->index));
- }
-
/* A buffer may or may be supplied with an EP0 SETUP transfer. A buffer will
* always be present for normal endpoint data transfers.
*/
@@ -1908,7 +1917,7 @@ static ssize_t sam_async_transfer(struct sam_rhport_s *rhport,
/* Get the new forward link pointer and data toggle */
flink = &qtd->hw.nqp;
- toggle = 0;
+ toggle = QTD_TOKEN_TOGGLE;
}
/* A buffer may or may be supplied with an EP0 SETUP transfer. A buffer will
@@ -3717,8 +3726,6 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller)
DEBUGASSERT(controller == 0);
DEBUGASSERT(((uintptr_t)&g_asynchead & 0x1f) == 0);
- DEBUGASSERT(((uintptr_t)&g_qhpool & 0x1f) == 0);
- DEBUGASSERT(((uintptr_t)&g_qtdpool & 0x1f) == 0);
DEBUGASSERT((sizeof(struct sam_qh_s) & 0x1f) == 0);
DEBUGASSERT((sizeof(struct sam_qtd_s) & 0x1f) == 0);
@@ -3727,6 +3734,11 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller)
DEBUGASSERT(((uintptr_t)g_framelist & 0xfff) == 0);
#endif
+#ifdef CONFIG_SAMA5_EHCI_PREALLOCATE
+ DEBUGASSERT(((uintptr_t)&g_qhpool & 0x1f) == 0);
+ DEBUGASSERT(((uintptr_t)&g_qtdpool & 0x1f) == 0);
+#endif
+
/* SAMA5 Configuration *******************************************************/
/* For High-speed operations, the user has to perform the following:
*
@@ -3827,6 +3839,18 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller)
sem_init(&rhport->ep0.iocsem, 0, 0);
}
+#ifndef CONFIG_SAMA5_EHCI_PREALLOCATE
+ /* Allocate a pool of free Queue Head (QH) structures */
+
+ g_qhpool = (struct sam_qh_s *)
+ kmemalign(32, CONFIG_SAMA5_EHCI_NQHS * sizeof(struct sam_qh_s));
+ if (!g_qhpool)
+ {
+ udbg("ERROR: Failed to allocate the QH pool\n");
+ return NULL;
+ }
+#endif
+
/* Initialize the list of free Queue Head (QH) structures */
for (i = 0; i < CONFIG_SAMA5_EHCI_NQHS; i++)
@@ -3836,7 +3860,20 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller)
sam_qh_free(&g_qhpool[i]);
}
- /* Initialize the list of free Queue Head (QH) structures */
+#ifndef CONFIG_SAMA5_EHCI_PREALLOCATE
+ /* Allocate a pool of free Transfer Descriptor (qTD) structures */
+
+ g_qtdpool = (struct sam_qtd_s *)
+ kmemalign(32, CONFIG_SAMA5_EHCI_NQTDS * sizeof(struct sam_qtd_s));
+ if (!g_qtdpool)
+ {
+ udbg("ERROR: Failed to allocate the qTD pool\n");
+ kfree(g_qhpool);
+ return NULL;
+ }
+#endif
+
+ /* Initialize the list of free Transfer Descriptor (qTD) structures */
for (i = 0; i < CONFIG_SAMA5_EHCI_NQTDS; i++)
{