You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2020/04/02 15:26:21 UTC

[incubator-nuttx] branch master updated: Check return from nxsem_wait_uninterruptible()

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

aguettouche 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 4892c27  Check return from nxsem_wait_uninterruptible()
4892c27 is described below

commit 4892c27b4ad466bcaf1702bc30aaedbb11109af5
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Thu Apr 2 08:45:32 2020 -0600

    Check return from nxsem_wait_uninterruptible()
    
    Resolution of Issue 619 will require multiple steps, this part of the first step in that resolution:  Every call to nxsem_wait_uninterruptible() must handle the return value from nxsem_wait_uninterruptible properly.  This commit is for all SPI drivers under arch/.
---
 arch/arm/src/imx1/imx_spi.c          |  48 ++++------
 arch/arm/src/imx6/imx_ecspi.c        |  53 ++++-------
 arch/arm/src/samd2l2/sam_spi.c       |  50 ++++------
 arch/arm/src/samd5e5/sam_spi.c       |  45 +++------
 arch/arm/src/samv7/sam_spi_slave.c   | 137 +++++++++++++++++----------
 arch/arm/src/samv7/sam_ssc.c         | 175 ++++++++++++++++++++---------------
 arch/arm/src/stm32/stm32_spi.c       |  49 +++++++---
 arch/arm/src/stm32f0l0g0/stm32_spi.c |  89 ++++++++++--------
 arch/arm/src/stm32f7/stm32_spi.c     |  45 ++++++---
 arch/arm/src/stm32h7/stm32_spi.c     |  46 ++++++---
 arch/arm/src/stm32l4/stm32l4_spi.c   |  87 +++++++++--------
 arch/arm/src/tiva/common/tiva_ssi.c  |  74 ++++++---------
 12 files changed, 489 insertions(+), 409 deletions(-)

diff --git a/arch/arm/src/imx1/imx_spi.c b/arch/arm/src/imx1/imx_spi.c
index 388ae8a..a3c5895 100644
--- a/arch/arm/src/imx1/imx_spi.c
+++ b/arch/arm/src/imx1/imx_spi.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * arch/arm/src/imx1/imx_spi.c
  *
- *   Copyright (C) 2009-2017 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@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.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -567,7 +552,7 @@ static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
 
   /* Wait to be signaled from the interrupt handler */
 
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 
 #else
   /* Perform the transfer using polling logic.  This will totally
@@ -597,8 +582,9 @@ static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
       sched_yield();
     }
   while (priv->nrxwords < priv->nwords);
-#endif
+
   return OK;
+#endif
 }
 
 /****************************************************************************
diff --git a/arch/arm/src/imx6/imx_ecspi.c b/arch/arm/src/imx6/imx_ecspi.c
index 8bcc0d8..d767f18 100644
--- a/arch/arm/src/imx6/imx_ecspi.c
+++ b/arch/arm/src/imx6/imx_ecspi.c
@@ -1,40 +1,20 @@
 /****************************************************************************
  * arch/arm/src/imx6/imx_ecspi.c
  *
- *   Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Derives from the i.MX1 CSPI driver:
- *
- *   Copyright (C) 2009-2010, 2013, 2016 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@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.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -688,7 +668,7 @@ static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
 
   /* Wait to be signaled from the interrupt handler */
 
-  nxsem_wait_uninterruptible(&priv->waitsem);
+  return nxsem_wait_uninterruptible(&priv->waitsem);
 
 #else
   /* Perform the transfer using polling logic.  This will totally
@@ -718,8 +698,9 @@ static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
       sched_yield();
     }
   while (priv->nrxwords < priv->nwords);
-#endif
+
   return OK;
+#endif
 }
 
 /****************************************************************************
diff --git a/arch/arm/src/samd2l2/sam_spi.c b/arch/arm/src/samd2l2/sam_spi.c
index 74fd9cc..c918501 100644
--- a/arch/arm/src/samd2l2/sam_spi.c
+++ b/arch/arm/src/samd2l2/sam_spi.c
@@ -1,42 +1,28 @@
 /****************************************************************************
  * arch/arm/src/samd2l2/sam_spi.c
  *
- *   Copyright (C) 2014-2018 Gregory Nutt. All rights reserved.
- *   Authors: Gregory Nutt <gn...@nuttx.org>
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
  *
- * References:
- *   1. "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller
- *      Datasheet", 42129J–SAM–12/2013
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
+/* References:
+ *   1. "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller
+ *      Datasheet", 42129J–SAM–12/2013
+ */
+
 /****************************************************************************
  * Included Files
  ****************************************************************************/
@@ -1154,7 +1140,7 @@ static void spi_dma_callback(DMA_HANDLE dma, void *arg, int result)
  ****************************************************************************/
 
 static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
-              void *rxbuffer, size_t nwords)
+                         void *rxbuffer, size_t nwords)
 {
   struct sam_spidev_s *priv = (struct sam_spidev_s *)dev;
 
diff --git a/arch/arm/src/samd5e5/sam_spi.c b/arch/arm/src/samd5e5/sam_spi.c
index 0a8fd7c..e75ad22 100644
--- a/arch/arm/src/samd5e5/sam_spi.c
+++ b/arch/arm/src/samd5e5/sam_spi.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * arch/arm/src/samd5e5/sam_spi.c
  *
- *   Copyright (C) 2018 Gregory Nutt. All rights reserved.
- *   Authors: Gregory Nutt <gn...@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.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -1249,7 +1234,7 @@ static void spi_dma_callback(DMA_HANDLE dma, void *arg, int result)
  ****************************************************************************/
 
 static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
-              void *rxbuffer, size_t nwords)
+                         void *rxbuffer, size_t nwords)
 {
   struct sam_spidev_s *priv = (struct sam_spidev_s *)dev;
 
diff --git a/arch/arm/src/samv7/sam_spi_slave.c b/arch/arm/src/samv7/sam_spi_slave.c
index b4780ed..169ea1a 100644
--- a/arch/arm/src/samv7/sam_spi_slave.c
+++ b/arch/arm/src/samv7/sam_spi_slave.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * arch/arm/src/samv7/sam_spi_slave.c
  *
- *   Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
- *   Authors: Gregory Nutt <gn...@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.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -68,6 +53,7 @@
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
+
 /* Configuration ************************************************************/
 
 #ifndef CONFIG_SAMV7_SPI_SLAVE_QSIZE
@@ -110,10 +96,10 @@ struct sam_spidev_s
   /* Debug stuff */
 
 #ifdef CONFIG_SAMV7_SPI_REGDEBUG
-   bool     wrlast;            /* Last was a write */
-   uint32_t addresslast;       /* Last address */
-   uint32_t valuelast;         /* Last value */
-   int      ntimes;            /* Number of times */
+  bool     wrlast;             /* Last was a write */
+  uint32_t addresslast;        /* Last address */
+  uint32_t valuelast;          /* Last value */
+  int      ntimes;             /* Number of times */
 #endif
 };
 
@@ -141,7 +127,8 @@ static void     spi_dumpregs(struct sam_spidev_s *priv, const char *msg);
 # define        spi_dumpregs(priv,msg)
 #endif
 
-static void     spi_semtake(struct sam_spidev_s *priv);
+static int      spi_semtake(struct sam_spidev_s *priv);
+static void     spi_semtake_uninterruptible(struct sam_spidev_s *priv);
 #define         spi_semgive(priv) (nxsem_post(&(priv)->spisem))
 
 /* Interrupt Handling */
@@ -348,7 +335,27 @@ static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg)
  *
  * Description:
  *   Take the semaphore that enforces mutually exclusive access to SPI
- *   resources, handling any exceptional conditions
+ *   resources.  May return ECANCELED if the calling thread was canceled.
+ *
+ * Input Parameters:
+ *   priv - A reference to the MCAN peripheral state
+ *
+ * Returned Value:
+ *  None
+ *
+ ****************************************************************************/
+
+static int spi_semtake(struct sam_spidev_s *priv)
+{
+  return nxsem_wait_uninterruptible(&priv->spisem);
+}
+
+/****************************************************************************
+ * Name: spi_semtake_uninterruptible
+ *
+ * Description:
+ *   Take the semaphore that enforces mutually exclusive access to SPI
+ *   resources, handling any exceptional conditions.  Always successful.
  *
  * Input Parameters:
  *   priv - A reference to the MCAN peripheral state
@@ -358,9 +365,19 @@ static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg)
  *
  ****************************************************************************/
 
-static void spi_semtake(struct sam_spidev_s *priv)
+static void spi_semtake_uninterruptible(struct sam_spidev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->spisem);
+  int ret;
+
+  do
+    {
+      ret = nxsem_wait_uninterruptible(&priv->spisem);
+
+      /* ECANCELED is the only error expected here */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
+    }
+  while (ret < 0);
 }
 
 /****************************************************************************
@@ -458,7 +475,8 @@ static int spi_interrupt(int irq, void *context, FAR void *arg)
            */
 
           regval = spi_getreg(priv, SAM_SPI_RDR_OFFSET);
-          data   = (uint16_t)((regval & SPI_RDR_RD_MASK) >> SPI_RDR_RD_SHIFT);
+          data   = (uint16_t)
+            ((regval & SPI_RDR_RD_MASK) >> SPI_RDR_RD_SHIFT);
 
           /* Enable TXDR/OVRE interrupts */
 
@@ -482,7 +500,8 @@ static int spi_interrupt(int irq, void *context, FAR void *arg)
        * i.e., NSS falls and there is a valid clock on the SPCK pin. When
        * the transfer occurs, the last data written in the SPI_TDR is
        * transferred in the Shift register and the TDRE flag rises. This
-       * enables frequent updates of critical variables with single transfers.
+       * enables frequent updates of critical variables with single
+       * transfers.
        *
        * Then, new data is loaded in the Shift register from the SPI_TDR. If
        * no character is ready to be transmitted, i.e., no character has been
@@ -743,6 +762,7 @@ static void spi_bind(struct spi_sctrlr_s *sctrlr,
 {
   struct sam_spidev_s *priv = (struct sam_spidev_s *)sctrlr;
   uint32_t regval;
+  int ret;
 
   spiinfo("sdev=%p mode=%d nbits=%d\n", sdv, mode, nbits);
 
@@ -750,7 +770,16 @@ static void spi_bind(struct spi_sctrlr_s *sctrlr,
 
   /* Get exclusive access to the SPI device */
 
-  spi_semtake(priv);
+  ret = spi_semtake(priv);
+  if (ret < 0)
+    {
+      /* REVISIT:  No mechanism to report error.  This error should only
+       * occur if the calling task was canceled.
+       */
+
+      spierr("RROR: spi_semtake failed: %d\n", ret);
+      return;
+    }
 
   /* Bind the SPI slave device interface instance to the SPI slave
    * controller interface.
@@ -852,7 +881,7 @@ static void spi_unbind(struct spi_sctrlr_s *sctrlr)
 
   /* Get exclusive access to the SPI device */
 
-  spi_semtake(priv);
+  spi_semtake_uninterruptible(priv);
 
   /* Disable SPI interrupts (still enabled at the NVIC) */
 
@@ -908,7 +937,11 @@ static int spi_enqueue(struct spi_sctrlr_s *sctrlr, uint16_t data)
 
   /* Get exclusive access to the SPI device */
 
-  spi_semtake(priv);
+  ret = spi_semtake(priv);
+  if (ret < 0)
+    {
+      return ret;
+    }
 
   /* Check if this word would overflow the circular buffer
    *
@@ -972,14 +1005,24 @@ static bool spi_qfull(struct spi_sctrlr_s *sctrlr)
 {
   struct sam_spidev_s *priv = (struct sam_spidev_s *)sctrlr;
   irqstate_t flags;
+  bool bret;
+  int ret;
   int next;
-  bool ret;
 
   DEBUGASSERT(priv != NULL && priv->sdev != NULL);
 
   /* Get exclusive access to the SPI device */
 
-  spi_semtake(priv);
+  ret = spi_semtake(priv);
+  if (ret < 0)
+    {
+      /* REVISIT:  No mechanism to report error.  This error should only
+       * occurr if the calling task was canceled.
+       */
+
+      spierr("RROR: spi_semtake failed: %d\n", ret);
+      return true;
+    }
 
   /* Check if another word would overflow the circular buffer
    *
@@ -993,10 +1036,10 @@ static bool spi_qfull(struct spi_sctrlr_s *sctrlr)
       next = 0;
     }
 
-  ret = (next == priv->tail);
+  bret = (next == priv->tail);
   leave_critical_section(flags);
   spi_semgive(priv);
-  return ret;
+  return bret;
 }
 
 /****************************************************************************
@@ -1026,7 +1069,7 @@ static void spi_qflush(struct spi_sctrlr_s *sctrlr)
 
   /* Get exclusive access to the SPI device */
 
-  spi_semtake(priv);
+  spi_semtake_uninterruptible(priv);
 
   /* Mark the buffer empty, momentarily disabling interrupts */
 
diff --git a/arch/arm/src/samv7/sam_ssc.c b/arch/arm/src/samv7/sam_ssc.c
index 2e7a1fc..113278d 100644
--- a/arch/arm/src/samv7/sam_ssc.c
+++ b/arch/arm/src/samv7/sam_ssc.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * arch/arm/src/samv7/sam_ssc.c
  *
- *   Copyright (C) 2015-2017 Gregory Nutt. All rights reserved.
- *   Authors: Gregory Nutt <gn...@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.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -76,6 +61,7 @@
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
+
 /* Configuration ************************************************************/
 
 #ifndef CONFIG_SCHED_WORKQUEUE
@@ -368,7 +354,8 @@
 #define DMA_TIMEOUT_MS    (800)
 #define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS)
 
-/* Debug *******************************************************************/
+/* Debug ********************************************************************/
+
 /* Check if SSC debug is enabled */
 
 #ifndef CONFIG_DEBUG_I2S_INFO
@@ -393,6 +380,7 @@
 /****************************************************************************
  * Private Types
  ****************************************************************************/
+
 /* I2S buffer container */
 
 struct sam_buffer_s
@@ -466,10 +454,10 @@ struct sam_ssc_s
   /* Debug stuff */
 
 #ifdef CONFIG_SAMV7_SSC_REGDEBUG
-   bool     wr;                /* Last was a write */
-   uint32_t regaddr;           /* Last address */
-   uint32_t regval;            /* Last value */
-   int      count;             /* Number of times */
+  bool     wr;                 /* Last was a write */
+  uint32_t regaddr;            /* Last address */
+  uint32_t regval;             /* Last value */
+  int      count;              /* Number of times */
 #endif /* CONFIG_SAMV7_SSC_REGDEBUG */
 };
 
@@ -480,13 +468,14 @@ struct sam_ssc_s
 /* Register helpers */
 
 #ifdef CONFIG_SAMV7_SSC_REGDEBUG
-static bool     ssc_checkreg(struct sam_ssc_s *priv, bool wr, uint32_t regval,
-                  uint32_t regaddr);
+static bool     ssc_checkreg(struct sam_ssc_s *priv, bool wr,
+                  uint32_t regval, uint32_t regaddr);
 #else
 # define        ssc_checkreg(priv,wr,regval,regaddr) (false)
 #endif
 
-static inline uint32_t ssc_getreg(struct sam_ssc_s *priv, unsigned int offset);
+static inline uint32_t ssc_getreg(struct sam_ssc_s *priv,
+                  unsigned int offset);
 static inline void ssc_putreg(struct sam_ssc_s *priv, unsigned int offset,
                   uint32_t regval);
 static inline uintptr_t ssc_regaddr(struct sam_ssc_s *priv,
@@ -518,10 +507,10 @@ static void     ssc_dump_queues(struct sam_transport_s *xpt,
 
 /* Semaphore helpers */
 
-static void     ssc_exclsem_take(struct sam_ssc_s *priv);
+static int      ssc_exclsem_take(struct sam_ssc_s *priv);
 #define         ssc_exclsem_give(priv) nxsem_post(&priv->exclsem)
 
-static void     ssc_bufsem_take(struct sam_ssc_s *priv);
+static int      ssc_bufsem_take(struct sam_ssc_s *priv);
 #define         ssc_bufsem_give(priv) nxsem_post(&priv->bufsem)
 
 /* Buffer container helpers */
@@ -615,6 +604,7 @@ static void     ssc1_configure(struct sam_ssc_s *priv);
 /****************************************************************************
  * Private Data
  ****************************************************************************/
+
 /* I2S device operations */
 
 static const struct i2s_ops_s g_sscops =
@@ -749,7 +739,8 @@ static inline void ssc_putreg(struct sam_ssc_s *priv, unsigned int offset,
  *
  ****************************************************************************/
 
-static inline uintptr_t ssc_regaddr(struct sam_ssc_s *priv, unsigned int offset)
+static inline uintptr_t ssc_regaddr(struct sam_ssc_s *priv,
+                                    unsigned int offset)
 {
   return priv->base + offset;
 }
@@ -860,9 +851,9 @@ static void ssc_dump_queues(struct sam_transport_s *xpt, const char *msg)
  *
  ****************************************************************************/
 
-static void ssc_exclsem_take(struct sam_ssc_s *priv)
+static int ssc_exclsem_take(struct sam_ssc_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->exclsem);
+  return nxsem_wait_uninterruptible(&priv->exclsem);
 }
 
 /****************************************************************************
@@ -879,9 +870,9 @@ static void ssc_exclsem_take(struct sam_ssc_s *priv)
  *
  ****************************************************************************/
 
-static void ssc_bufsem_take(struct sam_ssc_s *priv)
+static int ssc_bufsem_take(struct sam_ssc_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->bufsem);
+  return nxsem_wait_uninterruptible(&priv->bufsem);
 }
 
 /****************************************************************************
@@ -908,12 +899,17 @@ static struct sam_buffer_s *ssc_buf_allocate(struct sam_ssc_s *priv)
 {
   struct sam_buffer_s *bfcontainer;
   irqstate_t flags;
+  int ret;
 
   /* Set aside a buffer container.  By doing this, we guarantee that we will
    * have at least one free buffer container.
    */
 
-  ssc_bufsem_take(priv);
+  ret = ssc_bufsem_take(priv);
+  if (ret < 0)
+    {
+      return NULL;
+    }
 
   /* Get the buffer from the head of the free list */
 
@@ -946,7 +942,8 @@ static struct sam_buffer_s *ssc_buf_allocate(struct sam_ssc_s *priv)
  *
  ****************************************************************************/
 
-static void ssc_buf_free(struct sam_ssc_s *priv, struct sam_buffer_s *bfcontainer)
+static void ssc_buf_free(struct sam_ssc_s *priv,
+                         struct sam_buffer_s *bfcontainer)
 {
   irqstate_t flags;
 
@@ -1046,6 +1043,7 @@ static void ssc_rxdma_sampledone(struct sam_ssc_s *priv, int result)
   sam_dmasample(priv->rx.dma, &priv->rx.dmaregs[DMA_END_TRANSFER]);
 
   /* Then dump the sampled DMA registers */
+
   /* Initial register values */
 
   sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_INITIAL],
@@ -1111,6 +1109,7 @@ static void ssc_txdma_sampledone(struct sam_ssc_s *priv, int result)
   sam_dmasample(priv->tx.dma, &priv->tx.dmaregs[DMA_END_TRANSFER]);
 
   /* Then dump the sampled DMA registers */
+
   /* Initial register values */
 
   sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_INITIAL],
@@ -1360,10 +1359,10 @@ static void ssc_rx_worker(void *arg)
 
   DEBUGASSERT(priv);
 
-  /* When the transfer was started, the active buffer containers were removed
-   * from the rx.pend queue and saved in the rx.act queue.  We get here when the
-   * DMA is finished... either successfully, with a DMA error, or with a DMA
-   * timeout.
+  /* When the transfer was started, the active buffer containers were
+   * removed from the rx.pend queue and saved in the rx.act queue.  We get
+   * here when the DMA is finished... either successfully, with a DMA
+   * error, or with a DMA timeout.
    *
    * In any case, the buffer containers in rx.act will be moved to the end
    * of the rx.done queue and rx.act queue will be emptied before this worker
@@ -1776,10 +1775,10 @@ static void ssc_tx_worker(void *arg)
 
   DEBUGASSERT(priv);
 
-  /* When the transfer was started, the active buffer containers were removed
-   * from the tx.pend queue and saved in the tx.act queue.  We get here when the
-   * DMA is finished... either successfully, with a DMA error, or with a DMA
-   * timeout.
+  /* When the transfer was started, the active buffer containers were
+   * removed from the tx.pend queue and saved in the tx.act queue.  We get
+   * here when the DMA is finished... either successfully, with a DMA
+   * error, or with a DMA timeout.
    *
    * In any case, the buffer containers in tx.act will be moved to the end
    * of the tx.done queue and tx.act will be emptied before this worker is
@@ -2176,11 +2175,18 @@ static int ssc_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
   /* Allocate a buffer container in advance */
 
   bfcontainer = ssc_buf_allocate(priv);
-  DEBUGASSERT(bfcontainer);
+  if (bfcontainer == NULL)
+    {
+      return -ENOMEM;
+    }
 
   /* Get exclusive access to the SSC driver data */
 
-  ssc_exclsem_take(priv);
+  ret = ssc_exclsem_take(priv);
+  if (ret < 0)
+    {
+      goto errout_with_buf;
+    }
 
   /* Has the RX channel been enabled? */
 
@@ -2209,8 +2215,8 @@ static int ssc_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
   sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.pend);
   ssc_dump_rxqueues(priv, "Receiving");
 
-  /* Then start the next transfer.  If there is already a transfer in progress,
-   * then this will do nothing.
+  /* Then start the next transfer.  If there is already a transfer in
+   * progress, then this will do nothing.
    */
 
   ret = ssc_rxdma_setup(priv);
@@ -2221,6 +2227,8 @@ static int ssc_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
 
 errout_with_exclsem:
   ssc_exclsem_give(priv);
+
+errout_with_buf:
   ssc_buf_free(priv, bfcontainer);
   return ret;
 
@@ -2393,11 +2401,18 @@ static int ssc_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
   /* Allocate a buffer container in advance */
 
   bfcontainer = ssc_buf_allocate(priv);
-  DEBUGASSERT(bfcontainer);
+  if (bfcontainer == NULL)
+    {
+      return -ENOMEM;
+    }
 
   /* Get exclusive access to the SSC driver data */
 
-  ssc_exclsem_take(priv);
+  ret = ssc_exclsem_take(priv);
+  if (ret < 0)
+    {
+      goto errout_with_buf;
+    }
 
   /* Has the TX channel been enabled? */
 
@@ -2426,8 +2441,8 @@ static int ssc_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
   sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.pend);
   ssc_dump_txqueues(priv, "Transmitting");
 
-  /* Then start the next transfer.  If there is already a transfer in progress,
-   * then this will do nothing.
+  /* Then start the next transfer.  If there is already a transfer in
+   * progress, then this will do nothing.
    */
 
   ret = ssc_txdma_setup(priv);
@@ -2438,6 +2453,8 @@ static int ssc_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
 
 errout_with_exclsem:
   ssc_exclsem_give(priv);
+
+errout_with_buf:
   ssc_buf_free(priv, bfcontainer);
   return ret;
 
@@ -2458,7 +2475,8 @@ errout_with_exclsem:
  *   priv - Fully initialized SSC device structure.
  *
  * Returned Value:
- *   OK is returned on failure.  A negated errno value is returned on failure.
+ *   OK is returned on failure.  A negated errno value is returned on
+ *   failure.
  *
  ****************************************************************************/
 
@@ -2474,6 +2492,7 @@ static int ssc_rx_configure(struct sam_ssc_s *priv)
   fslen  = priv->rxfslen - 1;
 
   /* RCMR settings */
+
   /* Configure the receiver input clock */
 
   regval = 0;
@@ -2539,15 +2558,16 @@ static int ssc_rx_configure(struct sam_ssc_s *priv)
              SSC_RCMR_STTDLY(priv->rxsttdly) | SSC_RCMR_PERIOD(0));
   ssc_putreg(priv, SAM_SSC_RCMR_OFFSET, regval);
 
-  /* RFMR settings. Some of these settings will need to be configurable as well.
-   * Currently hardcoded to:
+  /* RFMR settings. Some of these settings will need to be configurable as
+   * well.  Currently hardcoded to:
    *
    *  SSC_RFMR_DATLEN(n)    'n' determined by configuration
    *  SSC_RFMR_LOOP         Determined by configuration
    *  SSC_RFMR_MSBF         Most significant bit first
    *  SSC_RFMR_DATNB(n)     Data number 'n' per frame (hard-coded)
    *  SSC_RFMR_FSLEN        Set to LS 4 bits of (CONFIG_SSCx_RX_FSLEN-1)
-   *  SSC_RFMR_FSLEN(1)     Pulse length = FSLEN + (FSLEN_EXT * 16) + 1 = 2 clocks
+   *  SSC_RFMR_FSLEN(1)     Pulse length = FSLEN + (FSLEN_EXT * 16) + 1 =
+   *                        2 clocks
    *  SSC_RFMR_FSOS_NONE    RF pin is always in input
    *  SSC_RFMR_FSEDGE_POS   Positive frame sync edge detection
    *  SSC_RFMR_FSLENEXT   I Set to MS 4 bits of (CONFIG_SSCx_TX_FSLEN-1)
@@ -2558,7 +2578,8 @@ static int ssc_rx_configure(struct sam_ssc_s *priv)
 
   /* Set the RX frame synch  */
 
-  regval |= (SSC_RFMR_FSLEN(fslen & 0x0f) | SSC_RFMR_FSLENEXT((fslen >> 4) & 0x0f));
+  regval |= (SSC_RFMR_FSLEN(fslen & 0x0f) |
+            SSC_RFMR_FSLENEXT((fslen >> 4) & 0x0f));
 
   /* Loopback mode? */
 
@@ -2599,6 +2620,7 @@ static int ssc_tx_configure(struct sam_ssc_s *priv)
   period = SCC_PERIOD(priv->txsttdly, priv->datalen);
 
   /* TCMR settings */
+
   /* Configure the transmitter input clock */
 
   regval = 0;
@@ -2668,26 +2690,30 @@ static int ssc_tx_configure(struct sam_ssc_s *priv)
   if (priv->txclk == SSC_CLKSRC_MCKDIV)
     {
       regval |= (SSC_TCMR_CKG_CONT | SSC_TCMR_START_CONT |
-                 SSC_TCMR_STTDLY(priv->txsttdly) | SSC_TCMR_PERIOD(period / 2 - 1));
+                 SSC_TCMR_STTDLY(priv->txsttdly) |
+                 SSC_TCMR_PERIOD(period / 2 - 1));
     }
   else
     {
       regval |= (SSC_TCMR_CKG_CONT | SSC_TCMR_START_EDGE |
-                 SSC_TCMR_STTDLY(priv->txsttdly) | SSC_TCMR_PERIOD(0));
+                 SSC_TCMR_STTDLY(priv->txsttdly) |
+                 SSC_TCMR_PERIOD(0));
     }
 
   ssc_putreg(priv, SAM_SSC_TCMR_OFFSET, regval);
 
-  /* TFMR settings. Some of these settings will need to be configurable as well.
-   * Currently set to:
+  /* TFMR settings. Some of these settings will need to be configurable as
+   * well.  Currently set to:
    *
    *  SSC_TFMR_DATLEN(n)    'n' determined by configuration
    *  SSC_TFMR_DATDEF        Data default = 0
    *  SSC_TFMR_MSBF          Most significant bit first
    *  SSC_TFMR_DATNB(n)      Data number 'n' per frame (hard-coded)
    *  SSC_TFMR_FSDEN         Enabled if CONFIG_SSCx_TX_FSLEN > 0
-   *  SSC_TFMR_FSLEN         If enabled, set to LS 4 bits of (CONFIG_SSCx_TX_FSLEN-1)
-   *  SSC_TFMR_FSLENEXT      If enabled, set to MS 4 bits of (CONFIG_SSCx_TX_FSLEN-1)
+   *  SSC_TFMR_FSLEN         If enabled, set to LS 4 bits of
+   *                         (CONFIG_SSCx_TX_FSLEN-1)
+   *  SSC_TFMR_FSLENEXT      If enabled, set to MS 4 bits of
+   *                         (CONFIG_SSCx_TX_FSLEN-1)
    *
    * If master (i.e., provides clocking):
    *  SSC_TFMR_FSOS_NEGATIVE Negative pulse TF output
@@ -2852,7 +2878,8 @@ static void ssc_clocking(struct sam_ssc_s *priv)
 
   /* Reset, disable receiver & transmitter */
 
-  ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST);
+  ssc_putreg(priv, SAM_SSC_CR_OFFSET,
+             SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST);
 
   /* Configure MCK/2 divider */
 
diff --git a/arch/arm/src/stm32/stm32_spi.c b/arch/arm/src/stm32/stm32_spi.c
index 160e277..e6d3f73 100644
--- a/arch/arm/src/stm32/stm32_spi.c
+++ b/arch/arm/src/stm32/stm32_spi.c
@@ -247,8 +247,8 @@ static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint16_t byte)
 /* DMA support */
 
 #ifdef CONFIG_STM32_SPI_DMA
-static void        spi_dmarxwait(FAR struct stm32_spidev_s *priv);
-static void        spi_dmatxwait(FAR struct stm32_spidev_s *priv);
+static int         spi_dmarxwait(FAR struct stm32_spidev_s *priv);
+static int         spi_dmatxwait(FAR struct stm32_spidev_s *priv);
 static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv);
 static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv);
 static void        spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
@@ -889,17 +889,27 @@ static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint16_t word)
  ************************************************************************************/
 
 #ifdef CONFIG_STM32_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv)
 {
+  int ret;
+
   /* Take the semaphore (perhaps waiting).  If the result is zero, then the DMA
    * must not really have completed???
    */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->rxsem);
+      ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+      /* The only expected error is ECANCELED which would occur if the calling
+       * thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
     }
-  while (priv->rxresult == 0);
+  while (priv->rxresult == 0 && ret == OK);
+
+  return ret;
 }
 #endif
 
@@ -912,17 +922,27 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
  ************************************************************************************/
 
 #ifdef CONFIG_STM32_SPI_DMA
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv)
 {
+  int ret;
+
   /* Take the semaphore (perhaps waiting).  If the result is zero, then the DMA
    * must not really have completed???
    */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->txsem);
+      ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+      /* The only expected error is ECANCELED which would occur if the calling
+       * thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
     }
-  while (priv->txresult == 0);
+  while (priv->txresult == 0 && ret == OK);
+
+  return ret;
 }
 #endif
 
@@ -1745,7 +1765,9 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
                          FAR void *rxbuffer, size_t nwords)
 {
   FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
-  FAR void * xbuffer = rxbuffer;
+  FAR void *xbuffer = rxbuffer;
+  int ret;
+
   DEBUGASSERT(priv != NULL);
 
   /* Convert the number of word to a number of bytes */
@@ -1843,10 +1865,13 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
 
       /* Then wait for each to complete */
 
-      spi_dmarxwait(priv);
-      spi_dmatxwait(priv);
+      ret = spi_dmarxwait(priv);
+      if (ret < 0)
+        {
+          ret = spi_dmatxwait(priv);
+        }
 
-      if (rxbuffer && priv->rxbuf)
+      if (rxbuffer != NULL && priv->rxbuf != NULL && ret >= 0)
         {
           memcpy(xbuffer, priv->rxbuf, nbytes);
         }
diff --git a/arch/arm/src/stm32f0l0g0/stm32_spi.c b/arch/arm/src/stm32f0l0g0/stm32_spi.c
index c035785..d7a11d4 100644
--- a/arch/arm/src/stm32f0l0g0/stm32_spi.c
+++ b/arch/arm/src/stm32f0l0g0/stm32_spi.c
@@ -2,35 +2,20 @@
  * arch/arm/src/stm32f0l0g0/stm32_spi.c
  * copied from arch/arm/src/stm32
  *
- *   Copyright (C) 2009-2013, 2016 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@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.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -198,8 +183,8 @@ static inline bool spi_16bitmode(FAR struct stm32_spidev_s *priv);
 /* DMA support */
 
 #ifdef CONFIG_STM32F0L0G0_SPI_DMA
-static void        spi_dmarxwait(FAR struct stm32_spidev_s *priv);
-static void        spi_dmatxwait(FAR struct stm32_spidev_s *priv);
+static int         spi_dmarxwait(FAR struct stm32_spidev_s *priv);
+static int         spi_dmatxwait(FAR struct stm32_spidev_s *priv);
 static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv);
 static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv);
 static void        spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
@@ -581,7 +566,7 @@ static inline bool spi_16bitmode(FAR struct stm32_spidev_s *priv)
 }
 
 /****************************************************************************
- * Name: spi_dmarxwaitw
+ * Name: spi_dmarxwait
  *
  * Description:
  *   Wait for DMA to complete.
@@ -589,17 +574,27 @@ static inline bool spi_16bitmode(FAR struct stm32_spidev_s *priv)
  ****************************************************************************/
 
 #ifdef CONFIG_STM32F0L0G0_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv)
 {
+  int ret;
+
   /* Take the semaphore (perhaps waiting).  If the result is zero, then the
    * DMA must not really have completed???
    */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->rxsem);
+      ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+      /* The only expected error is ECANCELED which would occur if the
+       * calling thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
     }
-  while (priv->rxresult == 0);
+  while (priv->rxresult == 0 && ret == OK);
+
+  return ret;
 }
 #endif
 
@@ -612,17 +607,27 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
  ****************************************************************************/
 
 #ifdef CONFIG_STM32F0L0G0_SPI_DMA
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv)
 {
+  int ret;
+
   /* Take the semaphore (perhaps waiting).  If the result is zero, then the
    * DMA must not really have completed???
    */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->txsem);
+      ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+      /* The only expected error is ECANCELED which would occur if the
+       * calling thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
     }
-  while (priv->txresult == 0);
+  while (priv->txresult == 0 && ret == OK);
+
+  return ret;
 }
 #endif
 
@@ -1446,8 +1451,12 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
 
       /* Then wait for each to complete */
 
-      spi_dmarxwait(priv);
-      spi_dmatxwait(priv);
+      ret = spi_dmarxwait(priv);
+      if (ret >= 0)
+        {
+          ret = spi_dmatxwait(priv);
+          UNUSED(ret);
+        }
 
 #ifdef CONFIG_SPI_TRIGGER
       priv->trigarmed = false;
diff --git a/arch/arm/src/stm32f7/stm32_spi.c b/arch/arm/src/stm32f7/stm32_spi.c
index 9d82b48..31c70b6 100644
--- a/arch/arm/src/stm32f7/stm32_spi.c
+++ b/arch/arm/src/stm32f7/stm32_spi.c
@@ -230,8 +230,8 @@ static inline void spi_writeword(FAR struct stm32_spidev_s *priv,
 /* DMA support */
 
 #ifdef CONFIG_STM32F7_SPI_DMA
-static void        spi_dmarxwait(FAR struct stm32_spidev_s *priv);
-static void        spi_dmatxwait(FAR struct stm32_spidev_s *priv);
+static int         spi_dmarxwait(FAR struct stm32_spidev_s *priv);
+static int         spi_dmatxwait(FAR struct stm32_spidev_s *priv);
 static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv);
 static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv);
 static void        spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
@@ -897,17 +897,27 @@ static inline void spi_writebyte(FAR struct stm32_spidev_s *priv,
  ****************************************************************************/
 
 #ifdef CONFIG_STM32F7_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv)
 {
+  int ret;
+
   /* Take the semaphore (perhaps waiting).  If the result is zero, then the
    * DMA must not really have completed???
    */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->rxsem);
+      ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+      /* The only expected error is ECANCELED which would occur if the
+       * calling thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
     }
-  while (priv->rxresult == 0);
+  while (priv->rxresult == 0 && ret == OK);
+
+  return ret;
 }
 #endif
 
@@ -920,17 +930,27 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
  ****************************************************************************/
 
 #ifdef CONFIG_STM32F7_SPI_DMA
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv)
 {
+  int ret;
+
   /* Take the semaphore (perhaps waiting).  If the result is zero, then the
    * DMA must not really have completed???
    */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->txsem);
+      ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+      /* The only expected error is ECANCELED which would occur if the
+       * calling thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
     }
-  while (priv->txresult == 0);
+  while (priv->txresult == 0 && ret == OK);
+
+  return ret;
 }
 #endif
 
@@ -1878,8 +1898,11 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
 
       /* Then wait for each to complete */
 
-      spi_dmarxwait(priv);
-      spi_dmatxwait(priv);
+      ret = spi_dmarxwait(priv);
+      if (ret >= 0)
+        {
+          ret = spi_dmatxwait(priv);
+        }
 
 #ifdef CONFIG_SPI_TRIGGER
       priv->trigarmed = false;
@@ -1887,7 +1910,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
 
       /* Force RAM re-read */
 
-      if (rxbuffer)
+      if (rxbuffer != NULL && ret >= 0)
         {
           up_invalidate_dcache((uintptr_t)rxbuffer,
                                (uintptr_t)rxbuffer + nbytes);
diff --git a/arch/arm/src/stm32h7/stm32_spi.c b/arch/arm/src/stm32h7/stm32_spi.c
index a9251bb..c071585 100644
--- a/arch/arm/src/stm32h7/stm32_spi.c
+++ b/arch/arm/src/stm32h7/stm32_spi.c
@@ -226,8 +226,8 @@ static inline void spi_dumpregs(FAR struct stm32_spidev_s *priv);
 /* DMA support */
 
 #ifdef CONFIG_STM32H7_SPI_DMA
-static void        spi_dmarxwait(FAR struct stm32_spidev_s *priv);
-static void        spi_dmatxwait(FAR struct stm32_spidev_s *priv);
+static int         spi_dmarxwait(FAR struct stm32_spidev_s *priv);
+static int         spi_dmatxwait(FAR struct stm32_spidev_s *priv);
 static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv);
 static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv);
 static void        spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
@@ -844,17 +844,27 @@ static inline bool spi_9to16bitmode(FAR struct stm32_spidev_s *priv)
  ****************************************************************************/
 
 #ifdef CONFIG_STM32H7_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmarxwait(FAR struct stm32_spidev_s *priv)
 {
+  int ret;
+
   /* Take the semaphore (perhaps waiting).  If the result is zero, then the
    * DMA must not really have completed???
    */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->rxsem);
+      ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+      /* The only expected error is ECANCELED which would occur if the
+       * calling thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
     }
-  while (priv->rxresult == 0);
+  while (priv->rxresult == 0 && ret == OK);
+
+  return ret;
 }
 #endif
 
@@ -867,17 +877,27 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
  ****************************************************************************/
 
 #ifdef CONFIG_STM32H7_SPI_DMA
-static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
+static int spi_dmatxwait(FAR struct stm32_spidev_s *priv)
 {
+  int ret;
+
   /* Take the semaphore (perhaps waiting).  If the result is zero, then the
    * DMA must not really have completed???
    */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->txsem);
+      ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+      /* The only expected error is ECANCELED which would occur if the
+       * calling thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
     }
-  while (priv->txresult == 0);
+  while (priv->txresult == 0 && ret == OK);
+
+  return ret;
 }
 #endif
 
@@ -1828,8 +1848,12 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
 
       /* Then wait for each to complete */
 
-      spi_dmarxwait(priv);
-      spi_dmatxwait(priv);
+      ret = spi_dmarxwait(priv);
+      if (ret >= 0)
+        {
+          ret = spi_dmatxwait(priv);
+          UNUSED(ret);
+        }
 
 #ifdef CONFIG_SPI_TRIGGER
       priv->trigarmed = false;
@@ -1837,7 +1861,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
 
       /* Force RAM re-read */
 
-      if (rxbuffer)
+      if (rxbuffer != NULL)
         {
           up_invalidate_dcache((uintptr_t)rxbuffer,
                                (uintptr_t)rxbuffer + buflen);
diff --git a/arch/arm/src/stm32l4/stm32l4_spi.c b/arch/arm/src/stm32l4/stm32l4_spi.c
index e264758..0771a1b 100644
--- a/arch/arm/src/stm32l4/stm32l4_spi.c
+++ b/arch/arm/src/stm32l4/stm32l4_spi.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * arch/arm/src/stm32l4/stm32l4_spi.c
  *
- *   Copyright (C) 2009-2013, 2016 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@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.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -199,8 +184,8 @@ static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv);
 /* DMA support */
 
 #ifdef CONFIG_STM32L4_SPI_DMA
-static void        spi_dmarxwait(FAR struct stm32l4_spidev_s *priv);
-static void        spi_dmatxwait(FAR struct stm32l4_spidev_s *priv);
+static int         spi_dmarxwait(FAR struct stm32l4_spidev_s *priv);
+static int         spi_dmatxwait(FAR struct stm32l4_spidev_s *priv);
 static inline void spi_dmarxwakeup(FAR struct stm32l4_spidev_s *priv);
 static inline void spi_dmatxwakeup(FAR struct stm32l4_spidev_s *priv);
 static void        spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
@@ -640,17 +625,27 @@ static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv)
  ****************************************************************************/
 
 #ifdef CONFIG_STM32L4_SPI_DMA
-static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv)
+static int spi_dmarxwait(FAR struct stm32l4_spidev_s *priv)
 {
+  int ret;
+
   /* Take the semaphore (perhaps waiting).  If the result is zero, then the
    * DMA must not really have completed???
    */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->rxsem);
+      ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+      /* The only expected error is ECANCELED which would occur if the
+       * calling thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
     }
-  while (priv->rxresult == 0);
+  while (priv->rxresult == 0 && ret == OK);
+
+  return ret;
 }
 #endif
 
@@ -663,17 +658,27 @@ static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv)
  ****************************************************************************/
 
 #ifdef CONFIG_STM32L4_SPI_DMA
-static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv)
+static int spi_dmatxwait(FAR struct stm32l4_spidev_s *priv)
 {
+  int ret;
+
   /* Take the semaphore (perhaps waiting).  If the result is zero, then the
    * DMA must not really have completed???
    */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->txsem);
+      ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+      /* The only expected error is ECANCELED which would occur if the
+       * calling thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
     }
-  while (priv->txresult == 0);
+  while (priv->txresult == 0 && ret == OK);
+
+  return ret;
 }
 #endif
 
@@ -1496,8 +1501,12 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
 
       /* Then wait for each to complete */
 
-      spi_dmarxwait(priv);
-      spi_dmatxwait(priv);
+      ret = spi_dmarxwait(priv);
+      if (ret >= 0)
+        {
+          ret = spi_dmatxwait(priv);
+          UNUSED(ret);
+        }
 
 #ifdef CONFIG_SPI_TRIGGER
       priv->trigarmed = false;
diff --git a/arch/arm/src/tiva/common/tiva_ssi.c b/arch/arm/src/tiva/common/tiva_ssi.c
index 7a10329..3eab257 100644
--- a/arch/arm/src/tiva/common/tiva_ssi.c
+++ b/arch/arm/src/tiva/common/tiva_ssi.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * arch/arm/src/tiva/common/tiva_ssi.c
  *
- *   Copyright (C) 2009-2017 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@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.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -239,7 +224,7 @@ static uint32_t ssi_disable(struct tiva_ssidev_s *priv);
 static void ssi_enable(struct tiva_ssidev_s *priv, uint32_t enable);
 
 #ifndef CONFIG_SSI_POLLWAIT
-static void ssi_semtake(sem_t *sem);
+static int ssi_semtake(sem_t *sem);
 #define ssi_semgive(s) nxsem_post(s);
 #endif
 
@@ -501,9 +486,9 @@ static void ssi_enable(struct tiva_ssidev_s *priv, uint32_t enable)
  ****************************************************************************/
 
 #ifndef CONFIG_SSI_POLLWAIT
-static void ssi_semtake(sem_t *sem)
+static int ssi_semtake(sem_t *sem)
 {
-  nxsem_wait_uninterruptible(sem);
+  return nxsem_wait_uninterruptible(sem);
 }
 #endif
 
@@ -842,9 +827,9 @@ static int ssi_transfer(struct tiva_ssidev_s *priv, const void *txbuffer,
 
   priv->txbuffer     = (uint8_t *)txbuffer; /* Source buffer */
   priv->rxbuffer     = (uint8_t *)rxbuffer; /* Destination buffer */
-  priv->ntxwords     = nwords;             /* Number of words left to send */
-  priv->nrxwords     = 0;                  /* Number of words received */
-  priv->nwords       = nwords;             /* Total number of exchanges */
+  priv->ntxwords     = nwords;              /* Number of words left to send */
+  priv->nrxwords     = 0;                   /* Number of words received */
+  priv->nwords       = nwords;              /* Total number of exchanges */
 
   /* Set up the low-level data transfer function pointers */
 
@@ -905,9 +890,10 @@ static int ssi_transfer(struct tiva_ssidev_s *priv, const void *txbuffer,
   leave_critical_section(flags);
   do
     {
-      ssi_semtake(&priv->xfrsem);
+      ret = ssi_semtake(&priv->xfrsem);
     }
-  while (priv->nrxwords < priv->nwords);
+  while (priv->nrxwords < priv->nwords && ret >= 0);
+
   spiinfo("Transfer complete\n");
 
 #else
@@ -1527,12 +1513,11 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
       tiva_ssi0_enablepwr();
       tiva_ssi0_enableclk();
 
-      /* Configure SSI0 GPIOs (NOTE that SS is not initialized here, the
-       * logic in this file makes no assumptions about chip select)
+      /* Configure SSI0 GPIOs (NOTE that SSI0Fss is not initialized here,
+       * the logic in this file makes no assumptions about chip select).
        */
 
       tiva_configgpio(GPIO_SSI0_CLK);  /* PA2: SSI0 clock (SSI0Clk) */
-      /* tiva_configgpio(GPIO_SSI0_FSS);     PA3: SSI0 frame (SSI0Fss) */
       tiva_configgpio(GPIO_SSI0_RX);   /* PA4: SSI0 receive (SSI0Rx) */
       tiva_configgpio(GPIO_SSI0_TX);   /* PA5: SSI0 transmit (SSI0Tx) */
       break;
@@ -1559,10 +1544,9 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
       tiva_ssi1_enablepwr();
       tiva_ssi1_enableclk();
 
-      /* Configure SSI1 GPIOs */
+      /* Configure SSI1 GPIOs (except for SSI1Fss) */
 
       tiva_configgpio(GPIO_SSI1_CLK);  /* PE0: SSI1 clock (SSI1Clk) */
-      /* tiva_configgpio(GPIO_SSI1_FSS);     PE1: SSI1 frame (SSI1Fss) */
       tiva_configgpio(GPIO_SSI1_RX);   /* PE2: SSI1 receive (SSI1Rx) */
       tiva_configgpio(GPIO_SSI1_TX);   /* PE3: SSI1 transmit (SSI1Tx) */
       break;
@@ -1589,10 +1573,9 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
       tiva_ssi2_enablepwr();
       tiva_ssi2_enableclk();
 
-      /* Configure SSI2 GPIOs */
+      /* Configure SSI2 GPIOs (except for SSI2Fss) */
 
       tiva_configgpio(GPIO_SSI2_CLK);  /* PE0: SSI2 clock (SSI2Clk) */
-      /* tiva_configgpio(GPIO_SSI2_FSS);     PE1: SSI2 frame (SSI2Fss) */
       tiva_configgpio(GPIO_SSI2_RX);   /* PE2: SSI2 receive (SSI2Rx) */
       tiva_configgpio(GPIO_SSI2_TX);   /* PE3: SSI2 transmit (SSI2Tx) */
       break;
@@ -1619,10 +1602,9 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
       tiva_ssi3_enablepwr();
       tiva_ssi3_enableclk();
 
-      /* Configure SSI3 GPIOs */
+      /* Configure SSI3 GPIOs (except for SSI3Fss) */
 
       tiva_configgpio(GPIO_SSI3_CLK);  /* PE0: SSI3 clock (SSI3Clk) */
-      /* tiva_configgpio(GPIO_SSI3_FSS);     PE1: SSI3 frame (SSI3Fss) */
       tiva_configgpio(GPIO_SSI3_RX);   /* PE2: SSI3 receive (SSI3Rx) */
       tiva_configgpio(GPIO_SSI3_TX);   /* PE3: SSI3 transmit (SSI3Tx) */
       break;