You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/01/08 10:54:54 UTC

[incubator-nuttx] branch master updated: Fix buffer overrun and memory leak on smartfs and improvement to cxd56xx

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 3e45517  Fix buffer overrun and memory leak on smartfs and improvement to cxd56xx
3e45517 is described below

commit 3e45517599db261deb97c42b66b7df7be2250f7f
Author: Alin Jerpelea <al...@sony.com>
AuthorDate: Wed Jan 8 07:51:11 2020 -0300

    Fix buffer overrun and memory leak on smartfs and improvement to cxd56xx
    
    Author: Alan Carvalho de Assis <ac...@gmail.com>
    
        Check all .c and .h against nxstyle and fix it.
    
    Author: Alin Jerpelea <al...@sony.com>
    
        fs: smartfs: Fix over capacity write
    
        When the remaining capacity of flash is one sector, if a new root
        directory is created by file open, then the root directory's chain is
        broken and it causes to SmartFS filesystem crash. Once this fatal
        problem occurs, it's impossible to recover even if the system reboot.
        Fix it by finally update link of root directory.
    
        fs: smartfs: Fix buffer overrun
    
        fs: smartfs: Fix uninitialized variable warnings
    
        fs: smartfs: Memory leak fix
    
        boards: cxd56xx: Update spresense board.h
    
        - Fix PMIC assignment
        - Add specific pin configurations for spresense
        - Remove unnecessary definitions
    
        arch: cxd56xx: Add ITM syslog init at startup
    
        arch: cxd56xx: Enable DMA settings dynamically
---
 arch/arm/src/cxd56xx/Make.defs                     |   4 +
 arch/arm/src/cxd56xx/cxd56_spi.c                   | 224 ++++++++++++++-------
 arch/arm/src/cxd56xx/cxd56_spi.h                   |  29 +++
 arch/arm/src/cxd56xx/cxd56_start.c                 |   6 +
 boards/arm/cxd56xx/common/src/cxd56_altmdm_spi.c   | 130 +++++++-----
 boards/arm/cxd56xx/common/src/cxd56_ili9340.c      |  30 +++
 boards/arm/cxd56xx/common/src/cxd56_lpm013m091a.c  |  30 +++
 boards/arm/cxd56xx/spresense/Kconfig               |   4 +
 boards/arm/cxd56xx/spresense/include/board.h       | 109 ++++------
 .../cxd56xx/spresense/include/board_pinconfig.h    |  29 ++-
 boards/arm/cxd56xx/spresense/src/cxd56_spi.c       |   6 -
 fs/smartfs/smartfs_smart.c                         |   3 +
 fs/smartfs/smartfs_utils.c                         |  63 ++++--
 13 files changed, 443 insertions(+), 224 deletions(-)

diff --git a/arch/arm/src/cxd56xx/Make.defs b/arch/arm/src/cxd56xx/Make.defs
index 8bfdb79..943a905 100644
--- a/arch/arm/src/cxd56xx/Make.defs
+++ b/arch/arm/src/cxd56xx/Make.defs
@@ -89,6 +89,10 @@ CMN_CSRCS += up_copyarmstate.c
 endif
 endif
 
+ifeq ($(CONFIG_ARMV7M_ITMSYSLOG),y)
+CMN_CSRCS += up_itm_syslog.c
+endif
+
 CHIP_ASRCS += cxd56_farapistub.S
 
 CHIP_CSRCS  = cxd56_allocateheap.c cxd56_idle.c
diff --git a/arch/arm/src/cxd56xx/cxd56_spi.c b/arch/arm/src/cxd56xx/cxd56_spi.c
index 98a85c8..8d40e1e 100644
--- a/arch/arm/src/cxd56xx/cxd56_spi.c
+++ b/arch/arm/src/cxd56xx/cxd56_spi.c
@@ -46,6 +46,7 @@
 #include <semaphore.h>
 #include <errno.h>
 #include <debug.h>
+#include <string.h>
 
 #include <arch/board/board.h>
 #include <nuttx/irq.h>
@@ -58,7 +59,7 @@
 #include "chip.h"
 
 #include "cxd56_spi.h"
-#include "chip/cxd56_spi.h"
+#include "hardware/cxd56_spi.h"
 #include "cxd56_clock.h"
 #include "cxd56_pinconfig.h"
 #include "cxd56_powermgr.h"
@@ -99,6 +100,7 @@ struct cxd56_spidev_s
   uint8_t          port;       /* Port number */
   int              initialized; /* Initialized flag */
 #ifdef CONFIG_CXD56_DMAC
+  bool             dmaenable;  /* Use DMA or not */
   DMA_HANDLE       rxdmach;    /* RX DMA channel handle */
   DMA_HANDLE       txdmach;    /* TX DMA channel handle */
   sem_t            dmasem;     /* Wait for DMA to complete */
@@ -187,19 +189,10 @@ static const struct spi_ops_s g_spi4ops =
 #endif
   .send              = spi_send,
 #ifdef CONFIG_SPI_EXCHANGE
-#  if defined(CONFIG_CXD56_DMAC_SPI4_TX) || defined(CONFIG_CXD56_DMAC_SPI4_RX)
-  .exchange          = spi_dmaexchange,
-#  else
   .exchange          = spi_exchange,
-#  endif
 #else
-#  if defined(CONFIG_CXD56_DMAC_SPI4_TX) || defined(CONFIG_CXD56_DMAC_SPI4_RX)
-  .sndblock          = spi_dmasndblock,
-  .recvblock         = spi_dmarecvblock,
-#  else
   .sndblock          = spi_sndblock,
   .recvblock         = spi_recvblock,
-#  endif
 #endif
 #ifdef CONFIG_SPI_CALLBACK
   .registercallback  = cxd56_spi4register, /* Provided externally */
@@ -210,7 +203,10 @@ static const struct spi_ops_s g_spi4ops =
 
 static struct cxd56_spidev_s g_spi4dev =
 {
-  .spidev            = { &g_spi4ops },
+  .spidev            =
+                        {
+                         &g_spi4ops
+                        },
   .spibase           = CXD56_IMG_SPI_BASE,
   .spibasefreq       = 0,
   .port              = 4,
@@ -236,19 +232,10 @@ static const struct spi_ops_s g_spi5ops =
 #endif
   .send              = spi_send,
 #ifdef CONFIG_SPI_EXCHANGE
-#  if defined(CONFIG_CXD56_DMAC_SPI5_TX) || defined(CONFIG_CXD56_DMAC_SPI5_RX)
-  .exchange          = spi_dmaexchange,
-#  else
   .exchange          = spi_exchange,
-#  endif
 #else
-#  if defined(CONFIG_CXD56_DMAC_SPI5_TX) || defined(CONFIG_CXD56_DMAC_SPI5_RX)
-  .sndblock          = spi_dmasndblock,
-  .recvblock         = spi_dmarecvblock,
-#  else
   .sndblock          = spi_sndblock,
   .recvblock         = spi_recvblock,
-#  endif
 #endif
 #ifdef CONFIG_SPI_CALLBACK
   .registercallback  = cxd56_spi5register, /* Provided externally */
@@ -259,7 +246,10 @@ static const struct spi_ops_s g_spi5ops =
 
 static struct cxd56_spidev_s g_spi5dev =
 {
-  .spidev            = { &g_spi5ops },
+  .spidev            =
+                        {
+                         &g_spi5ops
+                        },
   .spibase           = CXD56_IMG_WSPI_BASE,
   .spibasefreq       = 0,
   .port              = 5,
@@ -298,7 +288,10 @@ static const struct spi_ops_s g_spi0ops =
 
 static struct cxd56_spidev_s g_spi0dev =
 {
-  .spidev            = { &g_spi0ops },
+  .spidev            =
+                        {
+                         &g_spi0ops
+                        },
   .spibase           = CXD56_SPIM_BASE,
   .spibasefreq       = 0,
   .port              = 0,
@@ -337,7 +330,10 @@ static const struct spi_ops_s g_spi3ops =
 
 static struct cxd56_spidev_s g_spi3dev =
 {
-  .spidev            = { &g_spi3ops },
+  .spidev            =
+                        {
+                         &g_spi3ops
+                        },
   .spibase           = CXD56_SCU_SPI_BASE,
   .spibasefreq       = 0,
   .port              = 3,
@@ -623,6 +619,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
        */
 
       priv->nbits = nbits;
+#ifdef CONFIG_CXD56_DMAC
       if (priv->nbits > 8)
         {
           priv->txconfig.dest_width = CXD56_DMAC_WIDTH16;
@@ -637,6 +634,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
           priv->rxconfig.dest_width = CXD56_DMAC_WIDTH8;
           priv->rxconfig.src_width = CXD56_DMAC_WIDTH8;
         }
+#endif
     }
 }
 
@@ -706,10 +704,10 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
 }
 
 /****************************************************************************
- * Name: spi_exchange
+ * Name: spi_do_exchange
  *
  * Description:
- *   Exahange a block of data from SPI. Required.
+ *   Exchange a block of data from SPI. Required.
  *
  * Input Parameters:
  *   dev      - Device-specific state data
@@ -726,8 +724,8 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
  *
  ****************************************************************************/
 
-static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
-                         FAR void *rxbuffer, size_t nwords)
+static void spi_do_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
+                            FAR void *rxbuffer, size_t nwords)
 {
   FAR struct cxd56_spidev_s *priv = (FAR struct cxd56_spidev_s *)dev;
   uint32_t regval                 = 0;
@@ -738,12 +736,14 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
     FAR const uint16_t *p16;
     FAR const void *pv;
   } tx;
+
   union
   {
     FAR uint8_t *p8;
     FAR uint16_t *p16;
     FAR void *pv;
   } rx;
+
   uint32_t data;
   uint32_t datadummy = (priv->nbits > 8) ? 0xffff : 0xff;
   uint32_t rxpending = 0;
@@ -829,6 +829,44 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
 }
 
 /****************************************************************************
+ * Name: spi_exchange
+ *
+ * Description:
+ *   Wrapper function of exchange a block of data from SPI.
+ *
+ * Input Parameters:
+ *   dev      - Device-specific state data
+ *   txbuffer - A pointer to the buffer of data to be sent
+ *   rxbuffer - A pointer to the buffer in which to receive data
+ *   nwords   - the length of data that to be exchanged in units of words.
+ *              The wordsize is determined by the number of bits-per-word
+ *              selected for the SPI interface.  If nbits <= 8, the data is
+ *              packed into uint8_t's; if nbits >8, the data is packed into
+ *              uint16_t's
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
+                         FAR void *rxbuffer, size_t nwords)
+{
+#ifdef CONFIG_CXD56_DMAC
+  FAR struct cxd56_spidev_s *priv = (FAR struct cxd56_spidev_s *)dev;
+
+  if (priv->dmaenable)
+    {
+      spi_dmaexchange(dev, txbuffer, rxbuffer, nwords);
+    }
+  else
+#endif
+    {
+      spi_do_exchange(dev, txbuffer, rxbuffer, nwords);
+    }
+}
+
+/****************************************************************************
  * Name: spi_sndblock
  *
  * Description:
@@ -909,6 +947,7 @@ static void cxd56_spi_pincontrol(int ch, bool on)
             CXD56_PIN_CONFIGS(PINCONFS_SPI0_GPIO);
           }
 #endif
+
 #ifdef CONFIG_CXD56_SPI0_PINMAP_SPIFLASH
         if (on)
           {
@@ -932,6 +971,7 @@ static void cxd56_spi_pincontrol(int ch, bool on)
           {
             CXD56_PIN_CONFIGS(PINCONFS_SPI3_GPIO);
           }
+
 #ifdef CONFIG_CXD56_SPI3_CS0
         if (on)
           {
@@ -942,6 +982,7 @@ static void cxd56_spi_pincontrol(int ch, bool on)
             CXD56_PIN_CONFIGS(PINCONFS_SPI3_CS0_X_GPIO);
           }
 #endif
+
 #ifdef CONFIG_CXD56_SPI3_CS1
         if (on)
           {
@@ -952,6 +993,7 @@ static void cxd56_spi_pincontrol(int ch, bool on)
             CXD56_PIN_CONFIGS(PINCONFS_SPI3_CS1_X_GPIO);
           }
 #endif
+
 #ifdef CONFIG_CXD56_SPI3_CS2
         if (on)
           {
@@ -990,6 +1032,7 @@ static void cxd56_spi_pincontrol(int ch, bool on)
             CXD56_PIN_CONFIGS(PINCONFS_EMMCA_GPIO);
           }
 #endif
+
 #ifdef CONFIG_CXD56_SPI5_PINMAP_SDIO
         if (on)
           {
@@ -1144,54 +1187,10 @@ FAR struct spi_dev_s *cxd56_spibus_initialize(int port)
 
   /* DMA settings */
 
-#if defined(CONFIG_CXD56_DMAC_SPI4_TX) || defined(CONFIG_CXD56_DMAC_SPI4_RX)
-  if (port == 4)
-    {
-#if defined(CONFIG_CXD56_DMAC_SPI4_TX)
-      priv->txconfig.channel_cfg = CXD56_DMA_PERIPHERAL_SPI4_TX;
-      priv->txdmach  = cxd56_dmachannel(CONFIG_CXD56_DMAC_SPI4_TX_CH,
-                                        CONFIG_CXD56_DMAC_SPI4_TX_MAXSIZE);
-      if (priv->txdmach == NULL)
-        {
-          return NULL;
-        }
-#endif
-#if defined(CONFIG_CXD56_DMAC_SPI4_RX)
-      priv->rxconfig.channel_cfg = CXD56_DMA_PERIPHERAL_SPI4_RX;
-      priv->rxdmach  = cxd56_dmachannel(CONFIG_CXD56_DMAC_SPI4_RX_CH,
-                                        CONFIG_CXD56_DMAC_SPI4_RX_MAXSIZE);
-      if (priv->rxdmach == NULL)
-        {
-          return NULL;
-        }
-#endif
-      nxsem_init(&priv->dmasem, 0, 0);
-    }
-#endif
-
-#if defined(CONFIG_CXD56_DMAC_SPI5_TX) || defined(CONFIG_CXD56_DMAC_SPI5_RX)
-  if (port == 5)
-    {
-#if defined(CONFIG_CXD56_DMAC_SPI5_TX)
-      priv->txconfig.channel_cfg = CXD56_DMA_PERIPHERAL_SPI5_TX;
-      priv->txdmach  = cxd56_dmachannel(CONFIG_CXD56_DMAC_SPI5_TX_CH,
-                                        CONFIG_CXD56_DMAC_SPI5_TX_MAXSIZE);
-      if (priv->txdmach == NULL)
-        {
-          return NULL;
-        }
-#endif
-#if defined(CONFIG_CXD56_DMAC_SPI5_RX)
-      priv->rxconfig.channel_cfg = CXD56_DMA_PERIPHERAL_SPI5_RX;
-      priv->rxdmach  = cxd56_dmachannel(CONFIG_CXD56_DMAC_SPI5_RX_CH,
-                                        CONFIG_CXD56_DMAC_SPI5_RX_MAXSIZE);
-      if (priv->rxdmach == NULL)
-        {
-          return NULL;
-        }
-#endif
-      nxsem_init(&priv->dmasem, 0, 0);
-    }
+#ifdef CONFIG_CXD56_DMAC
+  priv->dmaenable = false;
+  priv->txdmach   = NULL;
+  priv->rxdmach   = NULL;
 #endif
 
   /* CS control */
@@ -1263,6 +1262,81 @@ FAR struct spi_dev_s *cxd56_spibus_initialize(int port)
   return &priv->spidev;
 }
 
+#ifdef CONFIG_CXD56_DMAC
+
+/****************************************************************************
+ * Name: cxd56_spi_dmaconfig
+ *
+ * Description:
+ *   Enable DMA configuration.
+ *
+ * Input Parameter:
+ *   port   - Port number
+ *   chtype - Channel type(TX or RX)
+ *   handle - DMA channel handle
+ *   conf   - DMA configuration
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void cxd56_spi_dmaconfig(int port, int chtype, DMA_HANDLE handle,
+                         FAR dma_config_t *conf)
+{
+  FAR struct cxd56_spidev_s *priv = NULL;
+
+  switch (port)
+    {
+#if defined(CONFIG_CXD56_SPI4) && defined(CONFIG_CXD56_DMAC_SPI4_TX)
+      case 4:
+        priv = &g_spi4dev;
+        break;
+#endif
+
+#if defined(CONFIG_CXD56_SPI5) && defined(CONFIG_CXD56_DMAC_SPI5_TX)
+      case 5:
+        priv = &g_spi5dev;
+        break;
+#endif
+
+      default:
+        break;
+    }
+
+  if (priv && priv->initialized)
+    {
+      if ((chtype == CXD56_SPI_DMAC_CHTYPE_TX) && (!priv->txdmach))
+        {
+          /* TX DMA setting */
+
+          priv->txdmach = handle;
+          memcpy(&priv->txconfig, conf, sizeof(dma_config_t));
+
+          if (!priv->dmaenable)
+            {
+              sem_init(&priv->dmasem, 0, 0);
+              priv->dmaenable = true;
+            }
+        }
+      else if ((chtype == CXD56_SPI_DMAC_CHTYPE_RX) && (!priv->rxdmach))
+        {
+          /* RX DMA setting */
+
+          priv->rxdmach = handle;
+          memcpy(&priv->rxconfig, conf, sizeof(dma_config_t));
+
+          if (!priv->dmaenable)
+            {
+              sem_init(&priv->dmasem, 0, 0);
+              priv->dmaenable = true;
+            }
+        }
+    }
+}
+
+#endif
+
 /****************************************************************************
  * Name: spi_flush
  *
diff --git a/arch/arm/src/cxd56xx/cxd56_spi.h b/arch/arm/src/cxd56xx/cxd56_spi.h
index c33ba9f..351e15b 100644
--- a/arch/arm/src/cxd56xx/cxd56_spi.h
+++ b/arch/arm/src/cxd56xx/cxd56_spi.h
@@ -44,6 +44,9 @@
 #include <nuttx/config.h>
 #include <nuttx/spi/spi.h>
 #include "hardware/cxd56_spi.h"
+#ifdef CONFIG_CXD56_DMAC
+#include "cxd56_dmac.h"
+#endif
 
 #if defined(CONFIG_CXD56_SPI0) || defined(CONFIG_CXD56_SPI3) || \
     defined(CONFIG_CXD56_SPI4) || defined(CONFIG_CXD56_SPI5)
@@ -51,6 +54,7 @@
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
+
 /* This header file defines interfaces to common SPI logic.
  * To use this common SPI logic on your board:
  *
@@ -68,6 +72,9 @@
  *    for example, will bind the SPI driver to the SPI MMC/SD driver).
  */
 
+#define CXD56_SPI_DMAC_CHTYPE_TX (0)
+#define CXD56_SPI_DMAC_CHTYPE_RX (1)
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
@@ -108,6 +115,28 @@ extern "C"
 FAR struct spi_dev_s *cxd56_spibus_initialize(int port);
 
 /****************************************************************************
+ * Name: cxd56_spi_dmaconfig
+ *
+ * Description:
+ *   Enable DMA configuration.
+ *
+ * Input Parameter:
+ *   port   - Port number
+ *   chtype - Channel type(TX or RX)
+ *   handle - DMA channel handle
+ *   conf   - DMA configuration
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_CXD56_DMAC
+void cxd56_spi_dmaconfig(int port, int chtype, DMA_HANDLE handle,
+                         FAR dma_config_t *conf);
+#endif
+
+/****************************************************************************
  * Name:  cxd56_spiXselect, cxd56_spiXstatus, and cxd56_spiXcmddata
  *
  * Description:
diff --git a/arch/arm/src/cxd56xx/cxd56_start.c b/arch/arm/src/cxd56xx/cxd56_start.c
index d656d1d..2024ade 100644
--- a/arch/arm/src/cxd56xx/cxd56_start.c
+++ b/arch/arm/src/cxd56xx/cxd56_start.c
@@ -320,6 +320,12 @@ void __start(void)
 
   fpuconfig();
 
+#ifdef CONFIG_ARMV7M_ITMSYSLOG
+  /* Perform ARMv7-M ITM SYSLOG initialization */
+
+  itm_syslog_initialize();
+#endif
+
   /* Perform early serial initialization */
 
 #ifdef USE_EARLYSERIALINIT
diff --git a/boards/arm/cxd56xx/common/src/cxd56_altmdm_spi.c b/boards/arm/cxd56xx/common/src/cxd56_altmdm_spi.c
index 41bcace..5e7516a 100644
--- a/boards/arm/cxd56xx/common/src/cxd56_altmdm_spi.c
+++ b/boards/arm/cxd56xx/common/src/cxd56_altmdm_spi.c
@@ -50,6 +50,7 @@
 #include <nuttx/modem/altmdm.h>
 #include <arch/board/cxd56_altmdm.h>
 #include "cxd56_spi.h"
+#include "cxd56_dmac.h"
 #include "cxd56_pinconfig.h"
 
 /****************************************************************************
@@ -57,29 +58,27 @@
  ****************************************************************************/
 
 #if defined(CONFIG_CXD56_LTE_SPI4)
-#define SPI_CH (4)
-#if  defined(CONFIG_CXD56_LTE_SPI4_DMAC)
-#  if defined(CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE)
-#    if (CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE > CONFIG_CXD56_DMAC_SPI4_TX_MAXSIZE)
-#      error CONFIG_CXD56_DMAC_SPI4_TX_MAXSIZE too small
-#    endif
-#    if (CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE > CONFIG_CXD56_DMAC_SPI4_RX_MAXSIZE)
-#      error CONFIG_CXD56_DMAC_SPI4_RX_MAXSIZE too small
+#  define SPI_CH (4)
+#  if  defined(CONFIG_CXD56_LTE_SPI4_DMAC)
+#    define DMA_TXCH    (2)
+#    define DMA_RXCH    (3)
+#    define DMA_TXCHCHG (CXD56_DMA_PERIPHERAL_SPI4_TX)
+#    define DMA_RXCHCFG (CXD56_DMA_PERIPHERAL_SPI4_RX)
+#    if !defined(CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE)
+#        error CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE is not set
 #    endif
 #  endif
-#endif
 #elif defined(CONFIG_CXD56_LTE_SPI5)
-#define SPI_CH (5)
-#if  defined(CONFIG_CXD56_LTE_SPI5_DMAC)
-#  if defined(CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE)
-#    if (CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE > CONFIG_CXD56_DMAC_SPI5_TX_MAXSIZE)
-#      error CONFIG_CXD56_DMAC_SPI5_TX_MAXSIZE too small
-#    endif
-#    if (CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE > CONFIG_CXD56_DMAC_SPI5_RX_MAXSIZE)
-#      error CONFIG_CXD56_DMAC_SPI5_RX_MAXSIZE too small
+#  define SPI_CH (5)
+#  if  defined(CONFIG_CXD56_LTE_SPI5_DMAC)
+#    define DMA_TXCH    (4)
+#    define DMA_RXCH    (5)
+#    define DMA_TXCHCHG (CXD56_DMA_PERIPHERAL_SPI5_TX)
+#    define DMA_RXCHCFG (CXD56_DMA_PERIPHERAL_SPI5_RX)
+#    if !defined(CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE)
+#        error CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE is not set
 #    endif
 #  endif
-#endif
 #else
 #  error "Select LTE SPI 4 or 5"
 #endif
@@ -110,44 +109,45 @@ static void spi_pincontrol(int bus, bool on)
   switch (bus)
     {
 #ifdef CONFIG_CXD56_SPI4
-    case 4:
-      if (on)
-        {
-          CXD56_PIN_CONFIGS(PINCONFS_SPI4);
-        }
-      else
-        {
-          CXD56_PIN_CONFIGS(PINCONFS_SPI4_GPIO);
-        }
-      break;
-#endif  /* CONFIG_CXD56_SPI4 */
+      case 4:
+        if (on)
+          {
+            CXD56_PIN_CONFIGS(PINCONFS_SPI4);
+          }
+        else
+          {
+            CXD56_PIN_CONFIGS(PINCONFS_SPI4_GPIO);
+          }
+        break;
+#endif /* CONFIG_CXD56_SPI4 */
 
 #ifdef CONFIG_CXD56_SPI5
-    case 5:
+      case 5:
 #ifdef CONFIG_CXD56_SPI5_PINMAP_EMMC
-      if (on)
-        {
-          CXD56_PIN_CONFIGS(PINCONFS_EMMCA_SPI5);
-        }
-      else
-        {
-          CXD56_PIN_CONFIGS(PINCONFS_EMMCA_GPIO);
-        }
-#endif  /* CONFIG_CXD56_SPI5_PINMAP_EMMC */
+        if (on)
+          {
+            CXD56_PIN_CONFIGS(PINCONFS_EMMCA_SPI5);
+          }
+        else
+          {
+            CXD56_PIN_CONFIGS(PINCONFS_EMMCA_GPIO);
+          }
+#endif /* CONFIG_CXD56_SPI5_PINMAP_EMMC */
+
 #ifdef CONFIG_CXD56_SPI5_PINMAP_SDIO
-      if (on)
-        {
-          CXD56_PIN_CONFIGS(PINCONFS_SDIOA_SPI5);
-        }
-      else
-        {
-          CXD56_PIN_CONFIGS(PINCONFS_SDIOA_GPIO);
-        }
-#endif  /* CONFIG_CXD56_SPI5_PINMAP_SDIO */
-      break;
-#endif  /* CONFIG_CXD56_SPI5 */
-    default:
-      break;
+        if (on)
+          {
+            CXD56_PIN_CONFIGS(PINCONFS_SDIOA_SPI5);
+          }
+        else
+          {
+            CXD56_PIN_CONFIGS(PINCONFS_SDIOA_GPIO);
+          }
+#endif /* CONFIG_CXD56_SPI5_PINMAP_SDIO */
+        break;
+#endif /* CONFIG_CXD56_SPI5 */
+      default:
+        break;
     }
 }
 
@@ -166,7 +166,11 @@ static void spi_pincontrol(int bus, bool on)
 int board_altmdm_initialize(FAR const char *devpath)
 {
   FAR struct spi_dev_s *spi;
-  int spi_ch = SPI_CH;
+  int                   spi_ch = SPI_CH;
+#if defined(CONFIG_CXD56_LTE_SPI4_DMAC) || defined(CONFIG_CXD56_LTE_SPI5_DMAC)
+  DMA_HANDLE            hdl;
+  dma_config_t          conf;
+#endif
 
   m_info("Initializing ALTMDM..\n");
 
@@ -181,6 +185,26 @@ int board_altmdm_initialize(FAR const char *devpath)
           return -ENODEV;
         }
 
+#if defined(CONFIG_CXD56_LTE_SPI4_DMAC) || defined(CONFIG_CXD56_LTE_SPI5_DMAC)
+      hdl = cxd56_dmachannel(DMA_TXCH, CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE);
+      if (hdl)
+        {
+          conf.channel_cfg = DMA_TXCHCHG;
+          conf.dest_width  = CXD56_DMAC_WIDTH8;
+          conf.src_width   = CXD56_DMAC_WIDTH8;
+          cxd56_spi_dmaconfig(spi_ch, CXD56_SPI_DMAC_CHTYPE_TX, hdl, &conf);
+        }
+
+      hdl = cxd56_dmachannel(DMA_RXCH, CONFIG_MODEM_ALTMDM_MAX_PACKET_SIZE);
+      if (hdl)
+        {
+          conf.channel_cfg = DMA_RXCHCFG;
+          conf.dest_width  = CXD56_DMAC_WIDTH8;
+          conf.src_width   = CXD56_DMAC_WIDTH8;
+          cxd56_spi_dmaconfig(spi_ch, CXD56_SPI_DMAC_CHTYPE_RX, hdl, &conf);
+        }
+#endif
+
       spi_pincontrol(spi_ch, false);
 
       g_devhandle = altmdm_register(devpath, spi);
diff --git a/boards/arm/cxd56xx/common/src/cxd56_ili9340.c b/boards/arm/cxd56xx/common/src/cxd56_ili9340.c
index 9a0e4e9..ae5b667 100644
--- a/boards/arm/cxd56xx/common/src/cxd56_ili9340.c
+++ b/boards/arm/cxd56xx/common/src/cxd56_ili9340.c
@@ -334,6 +334,10 @@ int board_lcd_initialize(void)
 {
   FAR struct ili93404ws_lcd_s *priv = &g_lcddev;
   FAR struct spi_dev_s *spi;
+#if defined(CONFIG_CXD56_DMAC)
+  DMA_HANDLE            hdl;
+  dma_config_t          conf;
+#endif
 
   lcdinfo("Initializing lcd\n");
 
@@ -345,8 +349,33 @@ int board_lcd_initialize(void)
           lcderr("ERROR: Failed to initialize spi bus.\n");
           return -ENODEV;
         }
+
       priv->spi = spi;
 
+#if defined(CONFIG_CXD56_DMAC)
+      /* DMA settings */
+
+      hdl = cxd56_dmachannel(DISPLAY_DMA_TXCH, DISPLAY_DMA_TX_MAXSIZE);
+      if (hdl)
+        {
+          conf.channel_cfg = DISPLAY_DMA_TXCH_CFG;
+          conf.dest_width  = CXD56_DMAC_WIDTH8;
+          conf.src_width   = CXD56_DMAC_WIDTH8;
+          cxd56_spi_dmaconfig(DISPLAY_SPI, CXD56_SPI_DMAC_CHTYPE_TX,
+                              hdl, &conf);
+        }
+
+      hdl = cxd56_dmachannel(DISPLAY_DMA_RXCH, DISPLAY_DMA_RX_MAXSIZE);
+      if (hdl)
+        {
+          conf.channel_cfg = DISPLAY_DMA_RXCH_CFG;
+          conf.dest_width  = CXD56_DMAC_WIDTH8;
+          conf.src_width   = CXD56_DMAC_WIDTH8;
+          cxd56_spi_dmaconfig(DISPLAY_SPI, CXD56_SPI_DMAC_CHTYPE_RX,
+                              hdl, &conf);
+        }
+#endif
+
       /* Reset ILI9340 */
 
       up_mdelay(10);
@@ -394,5 +423,6 @@ FAR struct lcd_dev_s *board_lcd_getdev(int lcddev)
     {
       return g_lcd;
     }
+
   return NULL;
 }
diff --git a/boards/arm/cxd56xx/common/src/cxd56_lpm013m091a.c b/boards/arm/cxd56xx/common/src/cxd56_lpm013m091a.c
index 9a6baa8..9a22833 100644
--- a/boards/arm/cxd56xx/common/src/cxd56_lpm013m091a.c
+++ b/boards/arm/cxd56xx/common/src/cxd56_lpm013m091a.c
@@ -334,6 +334,10 @@ int board_lcd_initialize(void)
 {
   FAR struct lpm013m091a_lcd_s *priv = &g_lcddev;
   FAR struct spi_dev_s *spi;
+#if defined(CONFIG_CXD56_DMAC)
+  DMA_HANDLE            hdl;
+  dma_config_t          conf;
+#endif
 
   lcdinfo("Initializing lcd\n");
 
@@ -345,8 +349,33 @@ int board_lcd_initialize(void)
           lcderr("ERROR: Failed to initialize spi bus.\n");
           return -ENODEV;
         }
+
       priv->spi = spi;
 
+#if defined(CONFIG_CXD56_DMAC)
+      /* DMA settings */
+
+      hdl = cxd56_dmachannel(DISPLAY_DMA_TXCH, DISPLAY_DMA_TX_MAXSIZE);
+      if (hdl)
+        {
+          conf.channel_cfg = DISPLAY_DMA_TXCH_CFG;
+          conf.dest_width  = CXD56_DMAC_WIDTH8;
+          conf.src_width   = CXD56_DMAC_WIDTH8;
+          cxd56_spi_dmaconfig(DISPLAY_SPI, CXD56_SPI_DMAC_CHTYPE_TX,
+                              hdl, &conf);
+        }
+
+      hdl = cxd56_dmachannel(DISPLAY_DMA_RXCH, DISPLAY_DMA_RX_MAXSIZE);
+      if (hdl)
+        {
+          conf.channel_cfg = DISPLAY_DMA_RXCH_CFG;
+          conf.dest_width  = CXD56_DMAC_WIDTH8;
+          conf.src_width   = CXD56_DMAC_WIDTH8;
+          cxd56_spi_dmaconfig(DISPLAY_SPI, CXD56_SPI_DMAC_CHTYPE_RX,
+                              hdl, &conf);
+        }
+#endif
+
       /* Reset LPM013M091A */
 
       up_mdelay(10);
@@ -394,5 +423,6 @@ FAR struct lcd_dev_s *board_lcd_getdev(int lcddev)
     {
       return g_lcd;
     }
+
   return NULL;
 }
diff --git a/boards/arm/cxd56xx/spresense/Kconfig b/boards/arm/cxd56xx/spresense/Kconfig
index 30a1001..d43655f 100644
--- a/boards/arm/cxd56xx/spresense/Kconfig
+++ b/boards/arm/cxd56xx/spresense/Kconfig
@@ -59,12 +59,16 @@ choice
 config LCD_ON_EXTENSION_BOARD
 	bool "Extension board: SPI4"
 	select CXD56_SPI4
+	select CXD56_DMAC_SPI4_TX
+	select CXD56_DMAC_SPI4_RX
 	---help---
 		Display connected to extension board.
 
 config LCD_ON_MAIN_BOARD
 	bool "Main board: SPI5"
 	select CXD56_SPI5
+	select CXD56_DMAC_SPI5_TX
+	select CXD56_DMAC_SPI5_RX
 	---help---
 		Display connected to main board.
 
diff --git a/boards/arm/cxd56xx/spresense/include/board.h b/boards/arm/cxd56xx/spresense/include/board.h
index a1df198..90df77a 100644
--- a/boards/arm/cxd56xx/spresense/include/board.h
+++ b/boards/arm/cxd56xx/spresense/include/board.h
@@ -80,63 +80,19 @@
 
 /* Clocking ****************************************************************/
 
-#define BOARD_XTAL_FREQUENCY        (26000000)  /* XTAL oscillator frequency */
-#define BOARD_RTCCLK_FREQUENCY      (32768)     /* RTC oscillator frequency */
-#define BOARD_INTRCOSC_FREQUENCY    (8192000)   /* Internal RC oscillator frequency */
-
 #ifdef CONFIG_CXD56_80MHz
 #  define BOARD_FCLKOUT_FREQUENCY   (80000000)
 #else
-#  define BOARD_FCLKOUT_FREQUENCY   (97500000)
-#endif
-
-#define CXD56_CCLK                  BOARD_FCLKOUT_FREQUENCY
-
-/* USB0 ********************************************************************/
-
-#define BOARD_USB0_CLKSRC           PLL0USB_CLKSEL_XTAL
-#define BOARD_USB0_MDIV             0x06167ffa /* Table 149 datsheet, valid for 12Mhz Fclkin */
-#define BOARD_USB0_NP_DIV           0x00302062 /* Table 149 datsheet, valid for 12Mhz Fclkin */
-
-/* SPIFI clocking **********************************************************/
-
-/* The SPIFI will receive clocking from a divider per the settings provided
- * in this file.  The NuttX code will configure PLL1 as the input clock
- * for the selected divider
- */
-
-#undef  BOARD_SPIFI_PLL1                        /* No division */
-#undef  BOARD_SPIFI_DIVA                        /* Supports division by 1-4 */
-#undef  BOARD_SPIFI_DIVB                        /* Supports division by 1-16 */
-#undef  BOARD_SPIFI_DIVC                        /* Supports division by 1-16 */
-#undef  BOARD_SPIFI_DIVD                        /* Supports division by 1-16 */
-#undef  BOARD_SPIFI_DIVE                        /* Supports division by 1-256 */
-
-#if BOARD_FCLKOUT_FREQUENCY < 20000000
-#  define BOARD_SPIFI_PLL1          1           /* Use PLL1 directly */
-#else
-#  define BOARD_SPIFI_DIVB          1           /* Use IDIVB */
-#endif
-
-/* We need to configure the divider so that its output is as close to the
- * desired SCLK value.  The peak data transfer rate will be about half of
- * this frequency in bytes per second.
- */
-
-#if BOARD_FCLKOUT_FREQUENCY < 20000000
-#  define BOARD_SPIFI_FREQUENCY     BOARD_FCLKOUT_FREQUENCY  /* 72Mhz? */
-#else
-#  define BOARD_SPIFI_DIVIDER       (14)        /* 204MHz / 14 = 14.57MHz */
-#  define BOARD_SPIFI_FREQUENCY     (102000000) /* 204MHz / 14 = 14.57MHz */
+#  define BOARD_FCLKOUT_FREQUENCY   (100000000)
 #endif
 
 /* UART clocking ***********************************************************/
 
 /* Configure all UARTs to use the XTAL input frequency */
 
-#define BOARD_UART0_BASEFREQ        BOARD_XTAL_FREQUENCY
-#define BOARD_UART1_BASEFREQ        48750000
-#define BOARD_UART2_BASEFREQ        BOARD_XTAL_FREQUENCY
+#define BOARD_UART0_BASEFREQ        CONFIG_CXD56_XOSC_CLOCK
+#define BOARD_UART1_BASEFREQ        BOARD_FCLKOUT_FREQUENCY
+#define BOARD_UART2_BASEFREQ        CONFIG_CXD56_XOSC_CLOCK
 
 /* LED definitions *********************************************************/
 
@@ -175,19 +131,24 @@
 
 /* Power Control definitions ***********************************************/
 
-/*     Switch    Device
+/*   For SPRESENSE board:
+ *
+ *     Switch    Device
  *     --------- -------------------------------
- *     LSW2      AcaPulco Audio Digital VDD
- *     LSW3      SPI-Flash & TCXO
- *     LSW4      GNSS LNA
- *     GPO0      AcaPulco Audio Analog VDD
- *     GPO1      Sensor 1.8V
- *     GPO2      Sensor 3.3V
- *     GPO3      Bluetooth/Bluetooth Low Energy
- *     GPO4      Image Sensor 1.2V
- *     GPO5      Image Sensor 3.3V
- *     GPO6      eMMC 3.3V/1.8V
- *     GPO7      Image Sensor 1.8V
+ *     LDO_EMMC  GNSS A-ANT
+ *     DDC_ANA   N/A
+ *     LDO_PERI  N/A
+ *     LSW2      CXD5247 Audio Digital VDD
+ *     LSW3      SPI-Flash
+ *     LSW4      TCXO & GNSS LNA
+ *     GPO0
+ *     GPO1      CXD5247 Audio Analog VDD
+ *     GPO2
+ *     GPO3
+ *     GPO4      Camera
+ *     GPO5      Camera
+ *     GPO6      Audio External Amp.
+ *     GPO7      Camera
  *
  */
 
@@ -223,16 +184,12 @@ enum board_power_device
 
   POWER_AUDIO_AVDD      = PMIC_GPO(1),
   POWER_AUDIO_MUTE      = PMIC_GPO(6),
-  POWER_SENSOR_18V      = PMIC_GPO(1),
-  POWER_SENSOR_33V      = PMIC_GPO(2),
-  POWER_BMI160          = POWER_SENSOR_18V,
-  POWER_SENSOR          = POWER_SENSOR_18V | POWER_SENSOR_33V,
-  POWER_BTBLE           = PMIC_GPO(3),
-  POWER_EINK            = PMIC_NONE,
-  POWER_EMMC            = PMIC_GPO(6),
-  POWER_LFOUR           = PMIC_NONE,
-  POWER_LTE             = PMIC_NONE,
   POWER_IMAGE_SENSOR    = PMIC_GPO(4) | PMIC_GPO(5) | PMIC_GPO(7),
+
+  POWER_BTBLE           = PMIC_NONE,
+  POWER_SENSOR          = PMIC_NONE,
+  POWER_EMMC            = PMIC_NONE,
+  POWER_LTE             = PMIC_GPO(2),
 };
 
 /* CXD5247 audio control definitions ***************************************/
@@ -254,6 +211,13 @@ enum board_power_device
 
 #define DISPLAY_SPI     5
 
+#define DISPLAY_DMA_TXCH       (4)
+#define DISPLAY_DMA_RXCH       (5)
+#define DISPLAY_DMA_TXCH_CFG   CXD56_DMA_PERIPHERAL_SPI5_TX
+#define DISPLAY_DMA_RXCH_CFG   CXD56_DMA_PERIPHERAL_SPI5_RX
+#define DISPLAY_DMA_TX_MAXSIZE (192000)
+#define DISPLAY_DMA_RX_MAXSIZE (192000)
+
 #else /* Display is connected through extension board. */
 
 #define DISPLAY_RST     PIN_SPI2_MISO
@@ -261,6 +225,13 @@ enum board_power_device
 
 #define DISPLAY_SPI     4
 
+#define DISPLAY_DMA_TXCH       (2)
+#define DISPLAY_DMA_RXCH       (3)
+#define DISPLAY_DMA_TXCH_CFG   CXD56_DMA_PERIPHERAL_SPI4_TX
+#define DISPLAY_DMA_RXCH_CFG   CXD56_DMA_PERIPHERAL_SPI4_RX
+#define DISPLAY_DMA_TX_MAXSIZE (192000)
+#define DISPLAY_DMA_RX_MAXSIZE (192000)
+
 #endif
 
 /* Sensor device bus definitions *******************************************/
diff --git a/boards/arm/cxd56xx/spresense/include/board_pinconfig.h b/boards/arm/cxd56xx/spresense/include/board_pinconfig.h
index c8078ac..75ac628 100644
--- a/boards/arm/cxd56xx/spresense/include/board_pinconfig.h
+++ b/boards/arm/cxd56xx/spresense/include/board_pinconfig.h
@@ -53,14 +53,20 @@
  *   4mA : Drive Current 1=4mA, 0=2mA
  *   Pull: 0=HiZ floating, PINCONF_PULLUP, PINCONF_PULLDOWN
  *
- *                       M  E     P
- *   P                   o  N  4  u
- *   i                   d  Z  m  l
- *   n                   e  I  A  l
+ *                                                            M  E     P
+ *                                        P                   o  N  4  u
+ *                                        i                   d  Z  m  l
+ *                                        n                   e  I  A  l
  */
 
+#undef PINCONF_UART2_TXD
+#undef PINCONF_UART2_RXD
 #undef PINCONF_UART2_CTS
-#define PINCONF_UART2_CTS          PINCONF(PIN_UART2_CTS,      1, 1, 0, PINCONF_PULLDOWN)
+#undef PINCONF_UART2_RTS
+#define PINCONF_UART2_TXD          PINCONF(PIN_UART2_TXD,      1, 0, 1, 0)
+#define PINCONF_UART2_RXD          PINCONF(PIN_UART2_RXD,      1, 1, 1, 0)
+#define PINCONF_UART2_CTS          PINCONF(PIN_UART2_CTS,      1, 1, 1, PINCONF_PULLDOWN)
+#define PINCONF_UART2_RTS          PINCONF(PIN_UART2_RTS,      1, 0, 1, 0)
 
 #undef PINCONF_SPI4_CS_X
 #undef PINCONF_SPI4_SCK
@@ -69,6 +75,19 @@
 #define PINCONF_SPI4_SCK           PINCONF(PIN_SPI4_SCK,       1, 0, 1, 0)
 #define PINCONF_SPI4_MOSI          PINCONF(PIN_SPI4_MOSI,      1, 0, 1, 0)
 
+#undef PINCONF_SPI3_CS0_X
+#undef PINCONF_SPI3_CS1_X
+#undef PINCONF_SPI3_CS2_X
+#undef PINCONF_SPI3_SCK
+#undef PINCONF_SPI3_MOSI
+#undef PINCONF_SPI3_MISO
+#define PINCONF_SPI3_CS0_X         PINCONF(PIN_SPI3_CS0_X,     1, 0, 1, 0)
+#define PINCONF_SPI3_CS1_X         PINCONF(PIN_SPI3_CS1_X,     1, 0, 1, 0)
+#define PINCONF_SPI3_CS2_X         PINCONF(PIN_SPI3_CS2_X,     1, 0, 1, 0)
+#define PINCONF_SPI3_SCK           PINCONF(PIN_SPI3_SCK,       1, 0, 1, 0)
+#define PINCONF_SPI3_MOSI          PINCONF(PIN_SPI3_MOSI,      1, 0, 1, 0)
+#define PINCONF_SPI3_MISO          PINCONF(PIN_SPI3_MISO,      1, 1, 1, 0)
+
 #undef PINCONF_PWM0
 #undef PINCONF_PWM1
 #undef PINCONF_PWM2
diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_spi.c b/boards/arm/cxd56xx/spresense/src/cxd56_spi.c
index 7435aa3..54ffba5 100644
--- a/boards/arm/cxd56xx/spresense/src/cxd56_spi.c
+++ b/boards/arm/cxd56xx/spresense/src/cxd56_spi.c
@@ -54,12 +54,6 @@
 #include "cxd56_gpio.h"
 
 /****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#define MMCSD_DETECT    PIN_AP_CLK
-
-/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
diff --git a/fs/smartfs/smartfs_smart.c b/fs/smartfs/smartfs_smart.c
index 3e7d38c..24503ec 100644
--- a/fs/smartfs/smartfs_smart.c
+++ b/fs/smartfs/smartfs_smart.c
@@ -383,6 +383,9 @@ errout_with_buffer:
       sf->entry.name = NULL;
     }
 
+#ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER
+  kmm_free(sf->buffer);
+#endif  /* CONFIG_SMARTFS_USE_SECTOR_BUFFER */
   kmm_free(sf);
 
 errout_with_semaphore:
diff --git a/fs/smartfs/smartfs_utils.c b/fs/smartfs/smartfs_utils.c
index 8731f7b..2074414 100644
--- a/fs/smartfs/smartfs_utils.c
+++ b/fs/smartfs/smartfs_utils.c
@@ -57,6 +57,12 @@
 #include "smartfs.h"
 
 /****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define WORKBUFFER_SIZE 256
+
+/****************************************************************************
  * Private Data
  ****************************************************************************/
 
@@ -269,7 +275,7 @@ int smartfs_mount(struct smartfs_mountpt_s *fs, bool writeable)
   if (nextfs == NULL)
     {
       fs->fs_rwbuffer = (char *) kmm_malloc(fs->fs_llformat.availbytes);
-      fs->fs_workbuffer = (char *) kmm_malloc(256);
+      fs->fs_workbuffer = (char *) kmm_malloc(WORKBUFFER_SIZE);
     }
 
   /* Now add ourselves to the linked list of SMART mounts */
@@ -292,12 +298,12 @@ int smartfs_mount(struct smartfs_mountpt_s *fs, bool writeable)
   g_mounthead = fs;
 #endif
 
-#endif /* CONFIG_SMARTFS_MULTI_ROOT_DIRS */
-
   fs->fs_rwbuffer = (char *) kmm_malloc(fs->fs_llformat.availbytes);
-  fs->fs_workbuffer = (char *) kmm_malloc(256);
+  fs->fs_workbuffer = (char *) kmm_malloc(WORKBUFFER_SIZE);
   fs->fs_rootsector = SMARTFS_ROOT_DIR_SECTOR;
 
+#endif /* CONFIG_SMARTFS_MULTI_ROOT_DIRS */
+
   /* We did it! */
 
   fs->fs_mounted = TRUE;
@@ -486,6 +492,11 @@ int smartfs_finddirentry(struct smartfs_mountpt_s *fs,
   struct      smart_read_write_s readwrite;
   struct      smartfs_entry_header_s *entry;
 
+  /* Set the initial value of the output */
+
+  *parentdirsector = 0xffff;
+  *filename = NULL;
+
   /* Initialize directory level zero as the root sector */
 
   dirstack[0] = fs->fs_rootsector;
@@ -523,6 +534,14 @@ int smartfs_finddirentry(struct smartfs_mountpt_s *fs,
           ptr++;
         }
 
+      /* Check to avoid buffer overflow */
+
+      if (seglen >= WORKBUFFER_SIZE)
+        {
+          ret = -ENAMETOOLONG;
+          goto errout;
+        }
+
       strncpy(fs->fs_workbuffer, segment, seglen);
       fs->fs_workbuffer[seglen] = '\0';
 
@@ -832,6 +851,9 @@ int smartfs_createentry(FAR struct smartfs_mountpt_s *fs,
   uint16_t  entrysize;
   struct    smartfs_entry_header_s *entry;
   struct    smartfs_chain_header_s *chainheader;
+  int       update_chain = 0;
+  struct    smart_read_write_s     update_readwrite;
+  struct    smartfs_chain_header_s update_header;
 
   /* Start at the 1st sector in the parent directory */
 
@@ -924,19 +946,15 @@ int smartfs_createentry(FAR struct smartfs_mountpt_s *fs,
 
           nextsector = (uint16_t) ret;
 
-          /* Chain the next sector into this sector sector */
+          /* Chain the next sector into this sector. */
 
-          *((FAR uint16_t *)chainheader->nextsector) = nextsector;
-          readwrite.offset = offsetof(struct smartfs_chain_header_s,
-              nextsector);
-          readwrite.count = sizeof(uint16_t);
-          readwrite.buffer = chainheader->nextsector;
-          ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite);
-          if (ret < 0)
-            {
-              ferr("ERROR: Error chaining sector %d\n", nextsector);
-              goto errout;
-            }
+          *((uint16_t *)update_header.nextsector) = nextsector;
+          update_readwrite.logsector = psector;
+          update_readwrite.offset = offsetof(struct smartfs_chain_header_s,
+                                             nextsector);
+          update_readwrite.count = sizeof(uint16_t);
+          update_readwrite.buffer = update_header.nextsector;
+          update_chain = 1;
         }
 
       /* Now update to the next sector */
@@ -1048,6 +1066,19 @@ int smartfs_createentry(FAR struct smartfs_mountpt_s *fs,
       goto errout;
     }
 
+  if (update_chain)
+    {
+      /* Update chain header after the next sector was written */
+
+      ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &update_readwrite);
+      if (ret < 0)
+        {
+          ferr("ERROR: Error chaining sector %d\n",
+               update_readwrite.logsector);
+          goto errout;
+        }
+    }
+
   /* Now fill in the entry */
 
   direntry->firstsector = nextsector;