diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-08-28 10:03:48 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-08-28 10:03:48 -0600 |
commit | b071bddd64cd63c399e518ba45394984d10bb5a0 (patch) | |
tree | 909b8534e1fef23a252048d8f833a077952170f8 | |
parent | 6b35d7af6caf96b641336200afd52704b419f346 (diff) | |
download | nuttx-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/Kconfig | 8 | ||||
-rwxr-xr-x | nuttx/arch/arm/src/sama5/sam_ehci.c | 61 |
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++) { |