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/04/01 17:20:13 UTC

[incubator-nuttx] branch pr685 updated: Check return from nxsem_wait_initialize()

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

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


The following commit(s) were added to refs/heads/pr685 by this push:
     new 9ff1795  Check return from nxsem_wait_initialize()
9ff1795 is described below

commit 9ff17957600c823dee96a7df96e225d019f0ca4a
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Wed Apr 1 10:13:52 2020 -0600

    Check return from nxsem_wait_initialize()
    
    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 only for rwbuffer.c and those files under drivers/serial, drivers/timers, and drivers/usbdev.
    
    This commit completes that step for all of the files under drivers/.  Still remaining:  All of the files under arch/.
---
 drivers/net/tun.c            |   2 +-
 drivers/rwbuffer.c           | 101 ++++++-
 drivers/serial/ptmx.c        |  71 ++---
 drivers/serial/pty.c         | 127 +++++----
 drivers/timers/pwm.c         | 105 ++++---
 drivers/usbdev/usbmsc.c      | 177 +++++++-----
 drivers/usbdev/usbmsc.h      |  58 ++--
 drivers/usbdev/usbmsc_scsi.c | 635 ++++++++++++++++++++++++-------------------
 8 files changed, 727 insertions(+), 549 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 05c9762..9d198f1 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1260,7 +1260,7 @@ static ssize_t tun_read(FAR struct file *filep, FAR char *buffer,
                         size_t buflen)
 {
   FAR struct tun_device_s *priv = filep->f_priv;
-  ssize_t nread;
+  ssize_t nread = 0;
   int ret;
 
   if (priv == NULL)
diff --git a/drivers/rwbuffer.c b/drivers/rwbuffer.c
index a827821..f7b0972 100644
--- a/drivers/rwbuffer.c
+++ b/drivers/rwbuffer.c
@@ -63,9 +63,37 @@
  * Name: rwb_semtake
  ****************************************************************************/
 
-static void rwb_semtake(FAR sem_t *sem)
+static int rwb_semtake(FAR sem_t *sem)
 {
-  nxsem_wait_uninterruptible(sem);
+  return nxsem_wait_uninterruptible(sem);
+}
+
+/****************************************************************************
+ * Name: rwb_forcetake
+ ****************************************************************************/
+
+static int rwb_forcetake(FAR sem_t *sem)
+{
+  int result;
+  int ret = OK;
+
+  do
+    {
+      result = rwb_semtake(sem);
+
+      /* The only expected failure is if the thread is canceled */
+
+      DEBUGASSERT(result == OK || result == -ECANCELED);
+      if (ret == OK && result < 0)
+        {
+          /* Remember the first error */
+
+          ret = result;
+        }
+    }
+  while (result < 0);
+
+  return ret;
 }
 
 /****************************************************************************
@@ -166,7 +194,7 @@ static void rwb_wrtimeout(FAR void *arg)
    * worker thread.
    */
 
-  rwb_semtake(&rwb->wrsem);
+  rwb_forcetake(&rwb->wrsem);
   rwb_wrflush(rwb);
   rwb_semgive(&rwb->wrsem);
 }
@@ -394,7 +422,11 @@ int rwb_invalidate_writebuffer(FAR struct rwbuffer_s *rwb,
 
       finfo("startblock=%d blockcount=%p\n", startblock, blockcount);
 
-      rwb_semtake(&rwb->wrsem);
+      ret = rwb_semtake(&rwb->wrsem);
+      if (ret < 0)
+        {
+          return ret;
+        }
 
       /* Now there are five cases:
        *
@@ -531,7 +563,11 @@ int rwb_invalidate_readahead(FAR struct rwbuffer_s *rwb,
 
       finfo("startblock=%d blockcount=%p\n", startblock, blockcount);
 
-      rwb_semtake(&rwb->rhsem);
+      ret = rwb_semtake(&rwb->rhsem);
+      if (ret < 0)
+        {
+          return ret;
+        }
 
       /* Now there are five cases:
        *
@@ -763,9 +799,14 @@ static ssize_t rwb_read_(FAR struct rwbuffer_s *rwb, off_t startblock,
     {
       size_t remaining;
 
+      ret = nxsem_wait(&rwb->rhsem);
+      if (ret < 0)
+        {
+          return (ssize_t)ret;
+        }
+
       /* Loop until we have read all of the requested blocks */
 
-      rwb_semtake(&rwb->rhsem);
       for (remaining = nblocks; remaining > 0; )
         {
           /* Is there anything in the read-ahead buffer? */
@@ -852,9 +893,14 @@ ssize_t rwb_read(FAR struct rwbuffer_s *rwb, off_t startblock,
 
   if (rwb->wrmaxblocks > 0)
     {
+      ret = nxsem_wait(&rwb->wrsem);
+      if (ret < 0)
+        {
+          return (ssize_t)ret;
+        }
+
       /* If the write buffer overlaps the block(s) requested */
 
-      rwb_semtake(&rwb->wrsem);
       if (rwb_overlap(rwb->wrblockstart, rwb->wrnblocks, startblock,
                       nblocks))
         {
@@ -924,7 +970,12 @@ ssize_t rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock,
        * streaming applications.
        */
 
-      rwb_semtake(&rwb->rhsem);
+      ret = nxsem_wait(&rwb->rhsem);
+      if (ret < 0)
+        {
+          return (ssize_t)ret;
+        }
+
       if (rwb_overlap(rwb->rhblockstart, rwb->rhnblocks, startblock,
                       nblocks))
         {
@@ -958,7 +1009,12 @@ ssize_t rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock,
         {
           /* First flush the cache */
 
-          rwb_semtake(&rwb->wrsem);
+          ret = nxsem_wait(&rwb->wrsem);
+          if (ret < 0)
+            {
+              return (ssize_t)ret;
+            }
+
           rwb_wrflush(rwb);
           rwb_semgive(&rwb->wrsem);
 
@@ -970,7 +1026,12 @@ ssize_t rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock,
         {
           /* Buffer the data in the write buffer */
 
-          rwb_semtake(&rwb->wrsem);
+          ret = nxsem_wait(&rwb->wrsem);
+          if (ret < 0)
+            {
+              return (ssize_t)ret;
+            }
+
           ret = rwb_writebuffer(rwb, startblock, nblocks, wrbuffer);
           rwb_semgive(&rwb->wrsem);
         }
@@ -1036,7 +1097,12 @@ int rwb_mediaremoved(FAR struct rwbuffer_s *rwb)
 #ifdef CONFIG_DRVR_WRITEBUFFER
   if (rwb->wrmaxblocks > 0)
     {
-      rwb_semtake(&rwb->wrsem);
+      ret = rwb_semtake(&rwb->wrsem);
+      if (ret < 0)
+        {
+          return ret;
+        }
+
       rwb_resetwrbuffer(rwb);
       rwb_semgive(&rwb->wrsem);
     }
@@ -1045,7 +1111,12 @@ int rwb_mediaremoved(FAR struct rwbuffer_s *rwb)
 #ifdef CONFIG_DRVR_READAHEAD
   if (rwb->rhmaxblocks > 0)
     {
-      rwb_semtake(&rwb->rhsem);
+      ret = rwb_semtake(&rwb->rhsem);
+      if (ret < 0)
+        {
+          return ret;
+        }
+
       rwb_resetrhbuffer(rwb);
       rwb_semgive(&rwb->rhsem);
     }
@@ -1102,12 +1173,14 @@ int rwb_invalidate(FAR struct rwbuffer_s *rwb,
 #ifdef CONFIG_DRVR_WRITEBUFFER
 int rwb_flush(FAR struct rwbuffer_s *rwb)
 {
-  rwb_semtake(&rwb->wrsem);
+  int ret;
+
+  ret = rwb_forcetake(&rwb->wrsem);
   rwb_wrcanceltimeout(rwb);
   rwb_wrflush(rwb);
   rwb_semgive(&rwb->wrsem);
 
-  return OK;
+  return ret;
 }
 #endif
 
diff --git a/drivers/serial/ptmx.c b/drivers/serial/ptmx.c
index 16dc180..6abca5c 100644
--- a/drivers/serial/ptmx.c
+++ b/drivers/serial/ptmx.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * drivers/serial/ptmx.c
  *
- *   Copyright (C) 2016-2018 Gregory Nutt. All rights reserved.
- *   Author: 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
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
  *
  ****************************************************************************/
 
@@ -117,22 +102,6 @@ static struct ptmx_dev_s g_ptmx;
  ****************************************************************************/
 
 /****************************************************************************
- * Name: ptmx_semtake and ptmx_semgive
- *
- * Description:
- *   This is just a wrapper to handle the annoying behavior of semaphore
- *   waits that return due to the receipt of a signal.
- *
- ****************************************************************************/
-
-static void ptmx_semtake(void)
-{
-  nxsem_wait_uninterruptible(&g_ptmx.px_exclsem);
-}
-
-#define ptmx_semgive() nxsem_post(&g_ptmx.px_exclsem)
-
-/****************************************************************************
  * Name: ptmx_minor_allocate
  *
  * Description:
@@ -204,7 +173,11 @@ static int ptmx_open(FAR struct file *filep)
 
   /* Get exclusive access */
 
-  ptmx_semtake();
+  ret = nxsem_wait(&g_ptmx.px_exclsem);
+  if (ret < 0)
+    {
+      return ret;
+    }
 
   /* Allocate a PTY minor */
 
@@ -246,7 +219,7 @@ static int ptmx_open(FAR struct file *filep)
 
   /* Return the encoded, master file descriptor */
 
-  ptmx_semgive();
+  nxsem_post(&g_ptmx.px_exclsem);
   DEBUGASSERT((unsigned)fd <= OPEN_MAXFD);
   return (int)OPEN_SETFD(fd);
 
@@ -254,7 +227,7 @@ errout_with_minor:
   ptmx_minor_free(minor);
 
 errout_with_sem:
-  ptmx_semgive();
+  nxsem_post(&g_ptmx.px_exclsem);
   return ret;
 }
 
@@ -262,7 +235,8 @@ errout_with_sem:
  * Name: ptmx_read
  ****************************************************************************/
 
-static ssize_t ptmx_read(FAR struct file *filep, FAR char *buffer, size_t len)
+static ssize_t ptmx_read(FAR struct file *filep,
+                         FAR char *buffer, size_t len)
 {
   return 0; /* Return EOF */
 }
@@ -271,7 +245,8 @@ static ssize_t ptmx_read(FAR struct file *filep, FAR char *buffer, size_t len)
  * Name: ptmx_write
  ****************************************************************************/
 
-static ssize_t ptmx_write(FAR struct file *filep, FAR const char *buffer, size_t len)
+static ssize_t ptmx_write(FAR struct file *filep,
+                          FAR const char *buffer, size_t len)
 {
   return len; /* Say that everything was written */
 }
diff --git a/drivers/serial/pty.c b/drivers/serial/pty.c
index 1557b8a..3530b95 100644
--- a/drivers/serial/pty.c
+++ b/drivers/serial/pty.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * drivers/serial/pty.c
  *
- *   Copyright (C) 2016-2018 Gregory Nutt. All rights reserved.
- *   Author: 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
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
  *
  ****************************************************************************/
 
@@ -168,7 +153,7 @@ struct pty_devpair_s
  * Private Function Prototypes
  ****************************************************************************/
 
-static void    pty_semtake(FAR struct pty_devpair_s *devpair);
+static int     pty_semtake(FAR struct pty_devpair_s *devpair);
 #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
 static void    pty_destroy(FAR struct pty_devpair_s *devpair);
 #endif
@@ -219,9 +204,9 @@ static const struct file_operations g_pty_fops =
  * Name: pty_semtake
  ****************************************************************************/
 
-static void pty_semtake(FAR struct pty_devpair_s *devpair)
+static int pty_semtake(FAR struct pty_devpair_s *devpair)
 {
-  nxsem_wait_uninterruptible(&devpair->pp_exclsem);
+  return nxsem_wait_uninterruptible(&devpair->pp_exclsem);
 }
 
 /****************************************************************************
@@ -309,36 +294,48 @@ static int pty_open(FAR struct file *filep)
         {
           /* Wait until unlocked.  We will also most certainly suspend here. */
 
-          nxsem_wait(&devpair->pp_slavesem);
+          ret = nxsem_wait(&devpair->pp_slavesem);
+          if (ret < 0)
+            {
+              return ret;
+            }
 
           /* Get exclusive access to the device structure.  This might also
            * cause suspension.
            */
 
-          pty_semtake(devpair);
+          ret = pty_semtake(devpair);
+          if (ret < 0)
+            {
+              return ret;
+            }
 
           /* Check again in case something happened asynchronously while we
            * were suspended.
            */
 
           if (devpair->pp_locked)
-           {
-             /* This cannot suspend because we have the scheduler locked.
-              * So pp_locked cannot change asyncrhonously between this test
-              * and the redundant test at the top of the loop.
-              */
-
-             pty_semgive(devpair);
-           }
+            {
+              /* This cannot suspend because we have the scheduler locked.
+               * So pp_locked cannot change asyncrhonously between this test
+               * and the redundant test at the top of the loop.
+               */
+
+              pty_semgive(devpair);
+            }
         }
 
       sched_unlock();
     }
   else
     {
-       /* Master ... Get exclusive access to the device structure */
+      /* Master ... Get exclusive access to the device structure */
 
-       pty_semtake(devpair);
+      ret = pty_semtake(devpair);
+      if (ret < 0)
+        {
+          goto errout_with_sem;
+        }
     }
 
 #ifndef CONFIG_PSEUDOTERM_SUSV1
@@ -364,6 +361,7 @@ static int pty_open(FAR struct file *filep)
       ret = OK;
     }
 
+errout_with_sem:
   pty_semgive(devpair);
   return ret;
 }
@@ -379,6 +377,7 @@ static int pty_close(FAR struct file *filep)
   FAR struct inode *inode;
   FAR struct pty_dev_s *dev;
   FAR struct pty_devpair_s *devpair;
+  int ret;
 
   DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
   inode     = filep->f_inode;
@@ -388,7 +387,11 @@ static int pty_close(FAR struct file *filep)
 
   /* Get exclusive access */
 
-  pty_semtake(devpair);
+  ret = pty_semtake(devpair);
+  if (ret < 0)
+    {
+      return ret;
+    }
 
 #ifdef CONFIG_PSEUDOTERM_SUSV1
   /* Did the (single) master just close its reference? */
@@ -561,6 +564,7 @@ static ssize_t pty_read(FAR struct file *filep, FAR char *buffer, size_t len)
             }
 
           /* Perform input processing */
+
           /* \n -> \r or \r -> \n translation? */
 
           if (ch == '\n' && (dev->pd_iflag & INLCR) != 0)
@@ -578,7 +582,6 @@ static ssize_t pty_read(FAR struct file *filep, FAR char *buffer, size_t len)
 
           if (ch != '\r' || (dev->pd_iflag & IGNCR) == 0)
             {
-
               /* Transfer the (possibly translated) character and update the
                * count of bytes transferred.
                */
@@ -612,7 +615,8 @@ static ssize_t pty_read(FAR struct file *filep, FAR char *buffer, size_t len)
  * Name: pty_write
  ****************************************************************************/
 
-static ssize_t pty_write(FAR struct file *filep, FAR const char *buffer, size_t len)
+static ssize_t pty_write(FAR struct file *filep,
+                         FAR const char *buffer, size_t len)
 {
   FAR struct inode *inode;
   FAR struct pty_dev_s *dev;
@@ -743,7 +747,11 @@ static int pty_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
 
   /* Get exclusive access */
 
-  pty_semtake(devpair);
+  ret = pty_semtake(devpair);
+  if (ret < 0)
+    {
+      return ret;
+    }
 
   /* Handle IOCTL commands */
 
@@ -920,7 +928,7 @@ static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
   FAR struct pty_dev_s *dev;
   FAR struct pty_devpair_s *devpair;
   FAR struct pty_poll_s *pollp = NULL;
-  int ret = -ENOSYS;
+  int ret;
   int i;
 
   DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
@@ -928,7 +936,13 @@ static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
   dev     = inode->i_private;
   devpair = dev->pd_devpair;
 
-  pty_semtake(devpair);
+  ret = pty_semtake(devpair);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  ret = -ENOSYS;
 
   if (setup)
     {
@@ -983,6 +997,7 @@ static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
 
           goto errout;
         }
+
       pollp->sink = fds->priv;
     }
 
@@ -1005,6 +1020,7 @@ static int pty_unlink(FAR struct inode *inode)
 {
   FAR struct pty_dev_s *dev;
   FAR struct pty_devpair_s *devpair;
+  int ret;
 
   DEBUGASSERT(inode != NULL && inode->i_private != NULL);
   dev       = inode->i_private;
@@ -1013,7 +1029,11 @@ static int pty_unlink(FAR struct inode *inode)
 
   /* Get exclusive access */
 
-  pty_semtake(devpair);
+  ret = pty_semtake(devpair);
+  if (ret < 0)
+    {
+      return ret;
+    }
 
   /* Indicate that the driver has been unlinked */
 
@@ -1033,6 +1053,7 @@ static int pty_unlink(FAR struct inode *inode)
   return OK;
 }
 #endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -1230,8 +1251,8 @@ errout_with_pipea:
     }
 
 errout_with_devpair:
-   nxsem_destroy(&devpair->pp_exclsem);
-   nxsem_destroy(&devpair->pp_slavesem);
-   kmm_free(devpair);
-   return ret;
+  nxsem_destroy(&devpair->pp_exclsem);
+  nxsem_destroy(&devpair->pp_slavesem);
+  kmm_free(devpair);
+  return ret;
 }
diff --git a/drivers/timers/pwm.c b/drivers/timers/pwm.c
index 060082f..d7533f1 100644
--- a/drivers/timers/pwm.c
+++ b/drivers/timers/pwm.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * drivers/timers/pwm.c
  *
- *   Copyright (C) 2011-2013, 2016-2017 Gregory Nutt. All rights reserved.
- *   Author: 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
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
  *
  ****************************************************************************/
 
@@ -68,16 +53,20 @@
 
 struct pwm_upperhalf_s
 {
-  uint8_t           crefs;    /* The number of times the device has been opened */
-  volatile bool     started;  /* True: pulsed output is being generated */
+  uint8_t           crefs;          /* The number of times the device has
+                                     * been opened */
+  volatile bool     started;        /* True: pulsed output is being
+                                     * generated */
 #ifdef CONFIG_PWM_PULSECOUNT
-  volatile bool     waiting;  /* True: Caller is waiting for the pulse count to expire */
+  volatile bool     waiting;        /* True: Caller is waiting for the pulse
+                                     * count to expire */
 #endif
-  sem_t             exclsem;  /* Supports mutual exclusion */
+  sem_t             exclsem;        /* Supports mutual exclusion */
 #ifdef CONFIG_PWM_PULSECOUNT
-  sem_t             waitsem;  /* Used to wait for the pulse count to expire */
+  sem_t             waitsem;        /* Used to wait for the pulse count to
+                                     * expire */
 #endif
-  struct pwm_info_s info;     /* Pulsed output characteristics */
+  struct pwm_info_s info;           /* Pulsed output characteristics */
   FAR struct pwm_lowerhalf_s *dev;  /* lower-half state */
 };
 
@@ -336,7 +325,8 @@ static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags)
        * We do these things before starting the PWM to avoid race conditions.
        */
 
-      upper->waiting = (upper->info.count > 0) && ((oflags & O_NONBLOCK) == 0);
+      upper->waiting = (upper->info.count > 0) &&
+                       ((oflags & O_NONBLOCK) == 0);
       upper->started = true;
 
       /* Invoke the bottom half method to start the pulse train */
@@ -360,7 +350,12 @@ static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags)
                * clear the waiting flag.
                */
 
-              nxsem_wait_uninterruptible(&upper->waitsem);
+              ret = nxsem_wait_uninterruptible(&upper->waitsem);
+              if (ret < 0)
+                {
+                  upper->started = false;
+                  upper->waiting = false;
+                }
             }
         }
       else
@@ -440,14 +435,15 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
 
   switch (cmd)
     {
-      /* PWMIOC_SETCHARACTERISTICS - Set the characteristics of the next pulsed
-       *   output.  This command will neither start nor stop the pulsed output.
-       *   It will either setup the configuration that will be used when the
-       *   output is started; or it will change the characteristics of the pulsed
-       *   output on the fly if the timer is already started.
+      /* PWMIOC_SETCHARACTERISTICS - Set the characteristics of the next
+       *   pulsed output.  This command will neither start nor stop the
+       *   pulsed output.  It will either setup the configuration that will
+       *   be used when the output is started; or it will change the
+       *   characteristics of the pulsed output on the fly if the timer is
+       *   already started.
        *
-       *   ioctl argument:  A read-only reference to struct pwm_info_s that provides
-       *   the characteristics of the pulsed output.
+       *   ioctl argument:  A read-only reference to struct pwm_info_s that
+       *   provides the characteristics of the pulsed output.
        */
 
       case PWMIOC_SETCHARACTERISTICS:
@@ -475,8 +471,9 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
         }
         break;
 
-      /* PWMIOC_GETCHARACTERISTICS - Get the currently selected characteristics of
-       *   the pulsed output (independent of whether the output is start or stopped).
+      /* PWMIOC_GETCHARACTERISTICS - Get the currently selected
+       * characteristics of the pulsed output (independent of whether the
+       * output is start or stopped).
        *
        *   ioctl argument:  A reference to struct pwm_info_s to receive the
        *   characteristics of the pulsed output.
@@ -484,7 +481,8 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
 
       case PWMIOC_GETCHARACTERISTICS:
         {
-          FAR struct pwm_info_s *info = (FAR struct pwm_info_s *)((uintptr_t)arg);
+          FAR struct pwm_info_s *info =
+            (FAR struct pwm_info_s *)((uintptr_t)arg);
           DEBUGASSERT(info != NULL);
 
           memcpy(info, &upper->info, sizeof(struct pwm_info_s));
@@ -493,8 +491,8 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
         }
         break;
 
-      /* PWMIOC_START - Start the pulsed output.  The PWMIOC_SETCHARACTERISTICS
-       *   command must have previously been sent.
+      /* PWMIOC_START - Start the pulsed output.  The
+       *   PWMIOC_SETCHARACTERISTICS  command must have previously been sent.
        *
        *   ioctl argument:  None
        */
@@ -569,9 +567,9 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
  *     filesystem.  The recommended convention is to name all PWM drivers
  *     as "/dev/pwm0", "/dev/pwm1", etc.  where the driver path differs only
  *     in the "minor" number at the end of the device name.
- *   dev - A pointer to an instance of lower half timer driver.  This instance
- *     is bound to the PWM driver and must persists as long as the driver
- *     persists.
+ *   dev - A pointer to an instance of lower half timer driver.  This
+ *     instance is bound to the PWM driver and must persists as long as the
+ *     driver persists.
  *
  * Returned Value:
  *   Zero on success; a negated errno value on failure.
@@ -584,7 +582,8 @@ int pwm_register(FAR const char *path, FAR struct pwm_lowerhalf_s *dev)
 
   /* Allocate the upper-half data structure */
 
-  upper = (FAR struct pwm_upperhalf_s *)kmm_zalloc(sizeof(struct pwm_upperhalf_s));
+  upper = (FAR struct pwm_upperhalf_s *)
+    kmm_zalloc(sizeof(struct pwm_upperhalf_s));
   if (!upper)
     {
       pwmerr("Allocation failed\n");
@@ -597,8 +596,8 @@ int pwm_register(FAR const char *path, FAR struct pwm_lowerhalf_s *dev)
 #ifdef CONFIG_PWM_PULSECOUNT
   nxsem_init(&upper->waitsem, 0, 0);
 
-  /* The wait semaphore is used for signaling and, hence, should not have priority
-   * inheritance enabled.
+  /* The wait semaphore is used for signaling and, hence, should not have
+   * priority inheritance enabled.
    */
 
   nxsem_setprotocol(&upper->waitsem, SEM_PRIO_NONE);
diff --git a/drivers/usbdev/usbmsc.c b/drivers/usbdev/usbmsc.c
index a8b69a4..a61a8b2 100644
--- a/drivers/usbdev/usbmsc.c
+++ b/drivers/usbdev/usbmsc.c
@@ -1,12 +1,25 @@
 /****************************************************************************
  * drivers/usbdev/usbmsc.c
+ * Mass storage class device.  Bulk-only with SCSI subclass.
  *
- *   Copyright (C) 2008-2012, 2016-2017 Gregory Nutt. All rights reserved.
- *   Author: 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
  *
- * Mass storage class device.  Bulk-only with SCSI subclass.
+ *   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.
  *
- * References:
+ ****************************************************************************/
+
+/* References:
  *   "Universal Serial Bus Mass Storage Class, Specification Overview,"
  *   Revision 1.2,  USB Implementer's Forum, June 23, 2003.
  *
@@ -24,35 +37,7 @@
  *
  *   "SCSI Multimedia Commands - 3 (MMC-3),"  American National Standard
  *   for Information Technology, November 12, 2001
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
+ */
 
 /****************************************************************************
  * Included Files
@@ -174,9 +159,6 @@ FAR struct usbmsc_dev_s *g_usbmsc_handoff;
  ****************************************************************************/
 
 /****************************************************************************
- * Class Driver Support
- ****************************************************************************/
-/****************************************************************************
  * Name: usbmsc_ep0incomplete
  *
  * Description:
@@ -230,7 +212,8 @@ static struct usbdev_req_s *usbmsc_allocreq(FAR struct usbdev_ep_s *ep,
  *
  ****************************************************************************/
 
-static void usbmsc_freereq(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req)
+static void usbmsc_freereq(FAR struct usbdev_ep_s *ep,
+                           FAR struct usbdev_req_s *req)
 {
   if (ep != NULL && req != NULL)
     {
@@ -238,6 +221,7 @@ static void usbmsc_freereq(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req)
         {
           EP_FREEBUFFER(ep, req->buf);
         }
+
       EP_FREEREQ(ep, req);
     }
 }
@@ -257,7 +241,8 @@ static void usbmsc_freereq(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req)
 static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
                        FAR struct usbdev_s *dev)
 {
-  FAR struct usbmsc_dev_s *priv = ((FAR struct usbmsc_driver_s *)driver)->dev;
+  FAR struct usbmsc_dev_s *priv =
+    ((FAR struct usbmsc_driver_s *)driver)->dev;
   FAR struct usbmsc_req_s *reqcontainer;
   irqstate_t flags;
   int ret = OK;
@@ -416,7 +401,7 @@ static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver,
     {
       usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNBINDINVALIDARGS), 0);
       return;
-     }
+    }
 #endif
 
   /* Extract reference to private data */
@@ -435,7 +420,8 @@ static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver,
    * driver un-initialize logic.
    */
 
-  DEBUGASSERT(priv->thstate == USBMSC_STATE_TERMINATED || priv->thstate == USBMSC_STATE_NOTSTARTED);
+  DEBUGASSERT(priv->thstate == USBMSC_STATE_TERMINATED ||
+              priv->thstate == USBMSC_STATE_NOTSTARTED);
 
   /* Make sure that we are not already unbound */
 
@@ -550,6 +536,7 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
       return -ENODEV;
     }
 #endif
+
   ctrlreq = priv->ctrlreq;
 
   /* Extract the little-endian 16-bit values to host order */
@@ -571,8 +558,9 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
         {
         case USB_REQ_GETDESCRIPTOR:
           {
-            /* The value field specifies the descriptor type in the MS byte and the
-             * descriptor index in the LS byte (order is little endian)
+            /* The value field specifies the descriptor type in the MS byte
+             * and the descriptor index in the LS byte (order is little
+             * endian)
              */
 
             switch (ctrl->value[1])
@@ -607,9 +595,9 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
               case USB_DESC_TYPE_OTHERSPEEDCONFIG:
 #endif
 
-                /* If the mass storage device is used in as part of a composite device,
-                 * then the configuration descriptor is provided by logic in the
-                 * composite device implementation.
+                /* If the mass storage device is used in as part of a
+                 * composite device, then the configuration descriptor is
+                 * provided by logic in the composite device implementation.
                  */
 
 #ifndef CONFIG_USBMSC_COMPOSITE
@@ -636,14 +624,16 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
                   /* index == language code. */
 
                   ret = usbmsc_mkstrdesc(ctrl->value[0],
-                                         (struct usb_strdesc_s *)ctrlreq->buf);
+                                         (FAR struct usb_strdesc_s *)
+                                         ctrlreq->buf);
                 }
                 break;
 #endif
 
               default:
                 {
-                  usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETUNKNOWNDESC), value);
+                  usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETUNKNOWNDESC),
+                           value);
                 }
                 break;
               }
@@ -730,7 +720,8 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
            break;
 
         default:
-          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNSUPPORTEDSTDREQ), ctrl->req);
+          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNSUPPORTEDSTDREQ),
+                   ctrl->req);
           break;
         }
     }
@@ -758,7 +749,8 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
 
                 if (index != USBMSC_INTERFACEID)
                   {
-                    usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_MSRESETNDX), index);
+                    usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_MSRESETNDX),
+                             index);
                     ret = -EDOM;
                   }
                 else
@@ -788,7 +780,8 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
 
                 if (index != USBMSC_INTERFACEID)
                   {
-                    usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETMAXLUNNDX), index);
+                    usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETMAXLUNNDX),
+                             index);
                     ret = -EDOM;
                   }
                 else
@@ -867,7 +860,7 @@ static void usbmsc_disconnect(FAR struct usbdevclass_driver_s *driver,
     {
       usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_DISCONNECTINVALIDARGS), 0);
       return;
-     }
+    }
 #endif
 
   /* Extract reference to private data */
@@ -1289,9 +1282,9 @@ void usbmsc_deferredresponse(FAR struct usbmsc_dev_s *priv, bool failed)
  *
  ****************************************************************************/
 
-static inline void usbmsc_sync_wait(FAR struct usbmsc_dev_s *priv)
+static int usbmsc_sync_wait(FAR struct usbmsc_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->thsynch);
+  return nxsem_wait_uninterruptible(&priv->thsynch);
 }
 
 /****************************************************************************
@@ -1336,7 +1329,8 @@ int usbmsc_configure(unsigned int nluns, void **handle)
 
   /* Allocate the structures needed */
 
-  alloc = (FAR struct usbmsc_alloc_s *)kmm_malloc(sizeof(struct usbmsc_alloc_s));
+  alloc = (FAR struct usbmsc_alloc_s *)
+    kmm_malloc(sizeof(struct usbmsc_alloc_s));
   if (!alloc)
     {
       usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCDEVSTRUCT), 0);
@@ -1390,15 +1384,17 @@ int usbmsc_configure(unsigned int nluns, void **handle)
 
   /* Initialize the device information if we are not part of a composite.
    * If we are part of a composite, the device information will be
-   * initialized through coordinated actions of usbmsc_get_composite_devdesc()
-   * and board-specific logic.
+   * initialized through coordinated actions of
+   * usbmsc_get_composite_devdesc() and board-specific logic.
    */
 
 #ifndef CONFIG_USBMSC_COMPOSITE
   /* minor - not used */
+
   /* Interfaces (ifnobase == 0) */
 
-  priv->devinfo.ninterfaces = USBMSC_NINTERFACES; /* Number of interfaces in the configuration */
+  priv->devinfo.ninterfaces = USBMSC_NINTERFACES; /* Number of interfaces
+                                                   * in the configuration */
 
   /* Strings (strbase == 0) */
 
@@ -1428,7 +1424,8 @@ errout:
  *   Bind the block driver specified by drvrpath to a USB storage LUN.
  *
  * Input Parameters:
- *   handle      - The handle returned by a previous call to usbmsc_configure().
+ *   handle      - The handle returned by a previous call to
+ *                 usbmsc_configure().
  *   drvrpath    - the full path to the block driver
  *   startsector - A sector offset into the block driver to the start of the
  *                 partition on drvrpath (0 if no partitions)
@@ -1536,7 +1533,8 @@ int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath,
       priv->iobuffer = (FAR uint8_t *)kmm_malloc(geo.geo_sectorsize);
       if (!priv->iobuffer)
         {
-          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCIOBUFFER), geo.geo_sectorsize);
+          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCIOBUFFER),
+                   geo.geo_sectorsize);
           return -ENOMEM;
         }
 
@@ -1549,7 +1547,8 @@ int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath,
       tmp = (FAR void *)kmm_realloc(priv->iobuffer, geo.geo_sectorsize);
       if (!tmp)
         {
-          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_REALLOCIOBUFFER), geo.geo_sectorsize);
+          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_REALLOCIOBUFFER),
+                   geo.geo_sectorsize);
           return -ENOMEM;
         }
 
@@ -1620,7 +1619,11 @@ int usbmsc_unbindlun(FAR void *handle, unsigned int lunno)
 #endif
 
   lun = &priv->luntab[lunno];
-  usbmsc_scsi_lock(priv);
+  ret = usbmsc_scsi_lock(priv);
+  if (ret < 0)
+    {
+      return ret;
+    }
 
 #ifdef CONFIG_DEBUG_FEATURES
   if (lun->inode == NULL)
@@ -1630,12 +1633,12 @@ int usbmsc_unbindlun(FAR void *handle, unsigned int lunno)
     }
   else
 #endif
-   {
+    {
       /* Close the block driver */
 
-     usbmsc_lununinitialize(lun);
-     ret = OK;
-   }
+      usbmsc_lununinitialize(lun);
+      ret = OK;
+    }
 
   usbmsc_scsi_unlock(priv);
   return ret;
@@ -1667,7 +1670,7 @@ int usbmsc_exportluns(FAR void *handle)
   FAR struct usbmsc_driver_s *drvr;
 #endif
   irqstate_t flags;
-  int ret = OK;
+  int ret;
 
 #ifdef CONFIG_DEBUG_FEATURES
   if (!alloc)
@@ -1688,7 +1691,11 @@ int usbmsc_exportluns(FAR void *handle)
    * some protection against re-entrant usage.
    */
 
-  usbmsc_scsi_lock(priv);
+  ret = usbmsc_scsi_lock(priv);
+  if (ret < 0)
+    {
+      return ret;
+    }
 
   priv->thstate = USBMSC_STATE_NOTSTARTED;
   priv->theventset = USBMSC_EVENT_NOEVENTS;
@@ -1709,7 +1716,12 @@ int usbmsc_exportluns(FAR void *handle)
   /* Wait for the worker thread to run and initialize */
 
   uinfo("Waiting for the SCSI worker thread\n");
-  usbmsc_sync_wait(priv);
+  ret = usbmsc_sync_wait(priv);
+  if (ret < 0)
+    {
+      goto errout_with_lock;
+    }
+
   DEBUGASSERT(g_usbmsc_handoff == NULL);
 
   /* Register the USB storage class driver (unless we are part of a composite device) */
@@ -1800,6 +1812,7 @@ void usbmsc_uninitialize(FAR void *handle)
   FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
   FAR struct usbmsc_dev_s *priv;
   irqstate_t flags;
+  int ret;
   int i;
 
 #ifdef CONFIG_DEBUG_FEATURES
@@ -1832,9 +1845,23 @@ void usbmsc_uninitialize(FAR void *handle)
 
   if (priv->thstate != USBMSC_STATE_NOTSTARTED)
     {
-       /* The thread was started.. Is it still running? */
+      /* Get exclusive access to SCSI state data */
+
+      do
+        {
+          ret = usbmsc_scsi_lock(priv);
+
+          /* usbmsc_scsi_lock() will fail with ECANCELED, only
+           * if this thread is canceled.  At this point, we
+           * have no option but to continue with the teardown.
+           */
+
+          DEBUGASSERT(ret == OK || ret == -ECANCLED);
+        }
+      while (ret < 0);
+
+      /* The thread was started.. Is it still running? */
 
-      usbmsc_scsi_lock(priv);
       if (priv->thstate != USBMSC_STATE_TERMINATED)
         {
           /* Yes.. Ask the thread to stop */
@@ -1851,7 +1878,15 @@ void usbmsc_uninitialize(FAR void *handle)
 
       while ((priv->theventset & USBMSC_EVENT_TERMINATEREQUEST) != 0)
         {
-          usbmsc_sync_wait(priv);
+          ret = usbmsc_sync_wait(priv);
+          if (ret < 0)
+            {
+              /* Just break out and continue if the thread has been
+               * canceled.
+               */
+
+              break;
+            }
         }
     }
 
diff --git a/drivers/usbdev/usbmsc.h b/drivers/usbdev/usbmsc.h
index 8924e6c..d0f5658 100644
--- a/drivers/usbdev/usbmsc.h
+++ b/drivers/usbdev/usbmsc.h
@@ -1,37 +1,21 @@
 /****************************************************************************
  * drivers/usbdev/usbmsc.h
+ * Mass storage class device.  Bulk-only with SCSI subclass.
  *
- *   Copyright (C) 2008-2013, 2015, 2017 Gregory Nutt. All rights reserved.
- *   Author: 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
  *
- * Mass storage class device.  Bulk-only with SCSI subclass.
+ *   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.
  *
  ****************************************************************************/
 
@@ -425,7 +409,7 @@ struct usbmsc_dev_s
 
   struct usbmsc_lun_s *lun;           /* Currently selected LUN */
   struct usbmsc_lun_s *luntab;        /* Allocated table of all LUNs */
-  uint8_t cdb[USBMSC_MAXCDBLEN];     /* Command data (cdb[]) from CBW */
+  uint8_t cdb[USBMSC_MAXCDBLEN];      /* Command data (cdb[]) from CBW */
   uint8_t           phaseerror:1;     /* Need to send phase sensing status */
   uint8_t           shortpacket:1;    /* Host transmission stopped unexpectedly */
   uint8_t           cbwdir:2;         /* Direction from CBW. See USBMSC_FLAGS_DIR* definitions */
@@ -483,8 +467,8 @@ EXTERN const char g_mscvendorstr[];
 EXTERN const char g_mscproductstr[];
 EXTERN const char g_mscserialstr[];
 
-/* If we are using a composite device, then vendor/product/serial number strings
- * are provided by the composite device logic.
+/* If we are using a composite device, then vendor/product/serial number
+ * strings are provided by the composite device logic.
  */
 
 #else
@@ -513,7 +497,7 @@ EXTERN FAR struct usbmsc_dev_s *g_usbmsc_handoff;
  *
  ****************************************************************************/
 
-void usbmsc_scsi_lock(FAR struct usbmsc_dev_s *priv);
+int usbmsc_scsi_lock(FAR struct usbmsc_dev_s *priv);
 
 /****************************************************************************
  * Name: usbmsc_scsi_unlock
@@ -525,7 +509,7 @@ void usbmsc_scsi_lock(FAR struct usbmsc_dev_s *priv);
 
 #define usbmsc_scsi_unlock(priv) nxsem_post(&priv->thlock)
 
-/*****************************************************************************
+/****************************************************************************
  * Name: usbmsc_scsi_signal
  *
  * Description:
@@ -591,10 +575,12 @@ int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid,
  ****************************************************************************/
 
 #ifdef CONFIG_USBDEV_DUALSPEED
-int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_devinfo_s *devinfo,
+int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf,
+                         FAR struct usbdev_devinfo_s *devinfo,
                          uint8_t speed, uint8_t type);
 #else
-int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_devinfo_s *devinfo);
+int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf,
+                         FAR struct usbdev_devinfo_s *devinfo);
 #endif
 
 /****************************************************************************
diff --git a/drivers/usbdev/usbmsc_scsi.c b/drivers/usbdev/usbmsc_scsi.c
index 8e99919..3e7620a 100644
--- a/drivers/usbdev/usbmsc_scsi.c
+++ b/drivers/usbdev/usbmsc_scsi.c
@@ -1,13 +1,25 @@
 /****************************************************************************
  * drivers/usbdev/usbmsc_scsi.c
+ * Mass storage class device.  Bulk-only with SCSI subclass.
  *
- *   Copyright (C) 2008-2010, 2012, 2016-2017, 2019 Gregory Nutt. All rights
- *     reserved.
- *   Author: 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
  *
- * Mass storage class device.  Bulk-only with SCSI subclass.
+ *   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.
  *
- * References:
+ ****************************************************************************/
+
+/* References:
  *   "Universal Serial Bus Mass Storage Class, Specification Overview,"
  *   Revision 1.2,  USB Implementer's Forum, June 23, 2003.
  *
@@ -22,35 +34,7 @@
  *
  *   "SCSI Block Commands -2 (SBC-2)," American National Standard
  *   for Information Technology, November 13, 2004
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
+ */
 
 /****************************************************************************
  * Included Files
@@ -155,7 +139,8 @@ static int    usbmsc_modepage(FAR struct usbmsc_dev_s *priv,
 static inline int usbmsc_cmdmodesense6(FAR struct usbmsc_dev_s *priv,
                 FAR uint8_t *buf);
 static inline int usbmsc_cmdstartstopunit(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdpreventmediumremoval(FAR struct usbmsc_dev_s *priv);
+static inline int usbmsc_cmdpreventmediumremoval(
+                FAR struct usbmsc_dev_s *priv);
 static inline int usbmsc_cmdreadformatcapacity(FAR struct usbmsc_dev_s *priv,
                 FAR uint8_t *buf);
 static inline int usbmsc_cmdreadcapacity10(FAR struct usbmsc_dev_s *priv,
@@ -163,7 +148,8 @@ static inline int usbmsc_cmdreadcapacity10(FAR struct usbmsc_dev_s *priv,
 static inline int usbmsc_cmdread10(FAR struct usbmsc_dev_s *priv);
 static inline int usbmsc_cmdwrite10(FAR struct usbmsc_dev_s *priv);
 static inline int usbmsc_cmdverify10(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdsynchronizecache10(FAR struct usbmsc_dev_s *priv);
+static inline int usbmsc_cmdsynchronizecache10(
+                FAR struct usbmsc_dev_s *priv);
 static inline int usbmsc_cmdmodeselect10(FAR struct usbmsc_dev_s *priv);
 static inline int usbmsc_cmdmodesense10(FAR struct usbmsc_dev_s *priv,
                 FAR uint8_t *buf);
@@ -366,9 +352,11 @@ static void usbmsc_putle32(uint8_t *buf, uint32_t val)
  *
  ****************************************************************************/
 
-static void usbmsc_scsi_wait(FAR struct usbmsc_dev_s *priv)
+static int usbmsc_scsi_wait(FAR struct usbmsc_dev_s *priv)
 {
   irqstate_t flags;
+  int ret;
+  int ret2;
 
   /* We must hold the SCSI lock to call this function */
 
@@ -388,18 +376,19 @@ static void usbmsc_scsi_wait(FAR struct usbmsc_dev_s *priv)
 
   usbmsc_scsi_unlock(priv);
 
-  /* Now wait for a SCSI event to be signalled */
+  /* Now wait for a SCSI event to be signaled */
 
   do
     {
-      nxsem_wait_uninterruptible(&priv->thwaitsem);
+      ret = nxsem_wait_uninterruptible(&priv->thwaitsem);
     }
-  while (priv->thwaiting);
+  while (priv->thwaiting && ret >= 0);
 
   /* Re-acquire our lock on the SCSI state data */
 
-  usbmsc_scsi_lock(priv);
+  ret2 = usbmsc_scsi_lock(priv);
   leave_critical_section(flags);
+  return ret >= 0 ? ret2 : ret;
 }
 
 /****************************************************************************
@@ -457,8 +446,10 @@ static inline int usbmsc_cmdrequestsense(FAR struct usbmsc_dev_s *priv,
     }
 
   ret = usbmsc_setupcmd(priv, cdblen,
-                        USBMSC_FLAGS_DIRDEVICE2HOST | USBMSC_FLAGS_LUNNOTNEEDED |
-                        USBMSC_FLAGS_UACOKAY | USBMSC_FLAGS_RETAINSENSEDATA);
+                        USBMSC_FLAGS_DIRDEVICE2HOST |
+                        USBMSC_FLAGS_LUNNOTNEEDED |
+                        USBMSC_FLAGS_UACOKAY |
+                        USBMSC_FLAGS_RETAINSENSEDATA);
   if (ret == OK)
     {
       lun = priv->lun;
@@ -509,7 +500,8 @@ static inline int usbmsc_cmdrequestsense(FAR struct usbmsc_dev_s *priv,
 
 static inline int usbmsc_cmdread6(FAR struct usbmsc_dev_s *priv)
 {
-  FAR struct scsicmd_read6_s *read6 = (FAR struct scsicmd_read6_s *)priv->cdb;
+  FAR struct scsicmd_read6_s *read6 =
+    (FAR struct scsicmd_read6_s *)priv->cdb;
   FAR struct usbmsc_lun_s *lun;
   int ret;
 
@@ -527,8 +519,9 @@ static inline int usbmsc_cmdread6(FAR struct usbmsc_dev_s *priv)
 
       /* Get the Logical Block Address (LBA) from cdb[] as the starting sector */
 
-      priv->sector = (uint32_t)(read6->mslba & SCSICMD_READ6_MSLBAMASK) << 16 |
-                     (uint32_t)usbmsc_getbe16(read6->lslba);
+      priv->sector =
+        (uint32_t)(read6->mslba & SCSICMD_READ6_MSLBAMASK) << 16 |
+        (uint32_t)usbmsc_getbe16(read6->lslba);
 
       /* Verify that a block driver has been bound to the LUN */
 
@@ -571,7 +564,8 @@ static inline int usbmsc_cmdread6(FAR struct usbmsc_dev_s *priv)
 
 static inline int usbmsc_cmdwrite6(FAR struct usbmsc_dev_s *priv)
 {
-  FAR struct scsicmd_write6_s *write6 = (FAR struct scsicmd_write6_s *)priv->cdb;
+  FAR struct scsicmd_write6_s *write6 =
+    (FAR struct scsicmd_write6_s *)priv->cdb;
   FAR struct usbmsc_lun_s *lun;
   int ret;
 
@@ -589,8 +583,9 @@ static inline int usbmsc_cmdwrite6(FAR struct usbmsc_dev_s *priv)
 
       /* Get the Logical Block Address (LBA) from cdb[] as the starting sector */
 
-      priv->sector = (uint32_t)(write6->mslba & SCSICMD_WRITE6_MSLBAMASK) << 16 |
-                     (uint32_t)usbmsc_getbe16(write6->lslba);
+      priv->sector =
+        (uint32_t)(write6->mslba & SCSICMD_WRITE6_MSLBAMASK) << 16 |
+        (uint32_t)usbmsc_getbe16(write6->lslba);
 
       /* Verify that a block driver has been bound to the LUN */
 
@@ -643,14 +638,17 @@ static inline int usbmsc_cmdwrite6(FAR struct usbmsc_dev_s *priv)
 static inline int usbmsc_cmdinquiry(FAR struct usbmsc_dev_s *priv,
                                     FAR uint8_t *buf)
 {
-  FAR struct scscicmd_inquiry_s *inquiry = (FAR struct scscicmd_inquiry_s *)priv->cdb;
-  FAR struct scsiresp_inquiry_s *response = (FAR struct scsiresp_inquiry_s *)buf;
+  FAR struct scscicmd_inquiry_s *inquiry =
+    (FAR struct scscicmd_inquiry_s *)priv->cdb;
+  FAR struct scsiresp_inquiry_s *response =
+    (FAR struct scsiresp_inquiry_s *)buf;
   int len;
   int ret;
 
   priv->u.alloclen = usbmsc_getbe16(inquiry->alloclen);
   ret = usbmsc_setupcmd(priv, SCSICMD_INQUIRY_SIZEOF,
-                        USBMSC_FLAGS_DIRDEVICE2HOST | USBMSC_FLAGS_LUNNOTNEEDED |
+                        USBMSC_FLAGS_DIRDEVICE2HOST |
+                        USBMSC_FLAGS_LUNNOTNEEDED |
                         USBMSC_FLAGS_UACOKAY);
   if (ret == OK)
     {
@@ -769,14 +767,24 @@ static int usbmsc_modepage(FAR struct usbmsc_dev_s *priv, FAR uint8_t *buf,
 
       /* None of the fields are changeable */
 
-      if (((pcpgcode & SCSICMD_MODESENSE_PCMASK) != SCSICMD_MODESENSE_PCCHANGEABLE))
+      if (((pcpgcode & SCSICMD_MODESENSE_PCMASK) !=
+          SCSICMD_MODESENSE_PCCHANGEABLE))
         {
           cmp->flags1    = SCSIRESP_CACHINGMODEPG_WCE; /* Write cache enable */
-          cmp->dpflen[0] = 0xff;  /* Disable prefetch transfer length = 0xffffffff */
+
+          /* Disable prefetch transfer length = 0xffffffff */
+
+          cmp->dpflen[0] = 0xff;
           cmp->dpflen[1] = 0xff;
-          cmp->maxpf[0]  = 0xff;  /* Maximum pre-fetch  = 0xffffffff */
+
+          /* Maximum pre-fetch  = 0xffffffff */
+
+          cmp->maxpf[0]  = 0xff;
           cmp->maxpf[1]  = 0xff;
-          cmp->maxpfc[0] = 0xff;  /* Maximum pref-fetch ceiling  = 0xffffffff */
+
+          /* Maximum pref-fetch ceiling  = 0xffffffff */
+
+          cmp->maxpfc[0] = 0xff;
           cmp->maxpfc[1] = 0xff;
         }
 
@@ -833,19 +841,23 @@ static int inline usbmsc_cmdmodesense6(FAR struct usbmsc_dev_s *priv,
            */
 
           mph->type  = 0; /* Medium type */
-          mph->param = (priv->lun->readonly ? SCSIRESP_MODEPARMHDR_DAPARM_WP : 0x00);
+          mph->param =
+            (priv->lun->readonly ? SCSIRESP_MODEPARMHDR_DAPARM_WP : 0x00);
           mph->bdlen = 0; /* Block descriptor length */
 
           /* There are no block descriptors, only the following mode page: */
 
-          ret = usbmsc_modepage(priv, &buf[SCSIRESP_MODEPARAMETERHDR6_SIZEOF],
+          ret = usbmsc_modepage(priv,
+                                &buf[SCSIRESP_MODEPARAMETERHDR6_SIZEOF],
                                 modesense->pcpgcode, &mdlen);
           if (ret == OK)
             {
               /* Store the mode data length and return the total message size */
 
-              mph->mdlen      = mdlen + SCSIRESP_MODEPARAMETERHDR6_SIZEOF - 1;
-              priv->nreqbytes = mdlen + SCSIRESP_MODEPARAMETERHDR6_SIZEOF;
+              mph->mdlen      =
+                mdlen + SCSIRESP_MODEPARAMETERHDR6_SIZEOF - 1;
+              priv->nreqbytes =
+                mdlen + SCSIRESP_MODEPARAMETERHDR6_SIZEOF;
             }
         }
     }
@@ -892,7 +904,8 @@ static inline int usbmsc_cmdstartstopunit(FAR struct usbmsc_dev_s *priv)
  *
  ****************************************************************************/
 
-static inline int usbmsc_cmdpreventmediumremoval(FAR struct usbmsc_dev_s *priv)
+static inline int
+  usbmsc_cmdpreventmediumremoval(FAR struct usbmsc_dev_s *priv)
 {
 #ifdef CONFIG_USBMSC_REMOVABLE
   FAR struct scsicmd_preventmediumremoval_s *pmr =
@@ -914,7 +927,10 @@ static inline int usbmsc_cmdpreventmediumremoval(FAR struct usbmsc_dev_s *priv)
 #else
       if ((pmr->prevent & ~SCSICMD_PREVENTMEDIUMREMOVAL_TRANSPORT) != 0)
         {
-          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_PREVENTMEDIUMREMOVALPREVENT), 0);
+          usbtrace(
+            TRACE_CLSERROR(USBMSC_TRACEERR_PREVENTMEDIUMREMOVALPREVENT),
+            0);
+
           lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
           ret = -EINVAL;
         }
@@ -1039,7 +1055,8 @@ static inline int usbmsc_cmdread10(FAR struct usbmsc_dev_s *priv)
 
       /* Verify that we can support this read command */
 
-      if ((read10->flags & ~(SCSICMD_READ10FLAGS_DPO | SCSICMD_READ10FLAGS_FUA)) != 0)
+      if ((read10->flags & ~(SCSICMD_READ10FLAGS_DPO |
+                             SCSICMD_READ10FLAGS_FUA)) != 0)
         {
           usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ10FLAGS), 0);
           lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
@@ -1116,7 +1133,8 @@ static inline int usbmsc_cmdwrite10(FAR struct usbmsc_dev_s *priv)
 
       else if (!lun->inode)
         {
-          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE10MEDIANOTPRESENT), 0);
+          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE10MEDIANOTPRESENT),
+                   0);
           lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
           ret     = -EINVAL;
         }
@@ -1162,7 +1180,8 @@ static inline int usbmsc_cmdwrite10(FAR struct usbmsc_dev_s *priv)
 
 static inline int usbmsc_cmdverify10(FAR struct usbmsc_dev_s *priv)
 {
-  FAR struct scsicmd_verify10_s *verf = (FAR struct scsicmd_verify10_s *)priv->cdb;
+  FAR struct scsicmd_verify10_s *verf =
+    (FAR struct scsicmd_verify10_s *)priv->cdb;
   FAR struct usbmsc_lun_s *lun;
   uint32_t  lba;
   uint16_t  blocks;
@@ -1198,7 +1217,8 @@ static inline int usbmsc_cmdverify10(FAR struct usbmsc_dev_s *priv)
 
       else if (!lun->inode)
         {
-          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_VERIFY10MEDIANOTPRESENT), 0);
+          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_VERIFY10MEDIANOTPRESENT),
+                   0);
           lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
           ret = -EINVAL;
         }
@@ -1215,12 +1235,15 @@ static inline int usbmsc_cmdverify10(FAR struct usbmsc_dev_s *priv)
         {
           /* Try to read the requested blocks */
 
-          for (i = 0, sector = lba + lun->startsector; i < blocks; i++, sector++)
+          for (i = 0, sector = lba + lun->startsector;
+               i < blocks;
+               i++, sector++)
             {
               nread = USBMSC_DRVR_READ(lun, priv->iobuffer, sector, 1);
               if (nread < 0)
                 {
-                  usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_VERIFY10READFAIL), i);
+                  usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_VERIFY10READFAIL),
+                           i);
                   lun->sd     = SCSI_KCQME_UNRRE1;
                   lun->sdinfo = sector;
                   ret         = -EIO;
@@ -1327,11 +1350,13 @@ static int inline usbmsc_cmdmodesense10(FAR struct usbmsc_dev_s *priv,
            */
 
           memset(mph, 0, SCSIRESP_MODEPARAMETERHDR10_SIZEOF);
-          mph->param = (priv->lun->readonly ? SCSIRESP_MODEPARMHDR_DAPARM_WP : 0x00);
+          mph->param =
+            (priv->lun->readonly ? SCSIRESP_MODEPARMHDR_DAPARM_WP : 0x00);
 
           /* There are no block descriptors, only the following mode page: */
 
-          ret = usbmsc_modepage(priv, &buf[SCSIRESP_MODEPARAMETERHDR10_SIZEOF],
+          ret = usbmsc_modepage(priv,
+                                &buf[SCSIRESP_MODEPARAMETERHDR10_SIZEOF],
                                 modesense->pcpgcode, &mdlen);
           if (ret == OK)
             {
@@ -1373,7 +1398,8 @@ static inline int usbmsc_cmdread12(FAR struct usbmsc_dev_s *priv)
 
       /* Verify that we can support this read command */
 
-      if ((read12->flags & ~(SCSICMD_READ12FLAGS_DPO | SCSICMD_READ12FLAGS_FUA)) != 0)
+      if ((read12->flags & ~(SCSICMD_READ12FLAGS_DPO |
+                             SCSICMD_READ12FLAGS_FUA)) != 0)
         {
           usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ12FLAGS), 0);
           lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
@@ -1449,7 +1475,8 @@ static inline int usbmsc_cmdwrite12(FAR struct usbmsc_dev_s *priv)
 
       else if (!lun->inode)
         {
-          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE12MEDIANOTPRESENT), 0);
+          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE12MEDIANOTPRESENT),
+                   0);
           lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
           ret = -EINVAL;
         }
@@ -1626,11 +1653,13 @@ static int inline usbmsc_setupcmd(FAR struct usbmsc_dev_s *priv,
        * commands is permitted.
        */
 
-      if (lun->uad != SCSI_KCQ_NOSENSE && (flags & USBMSC_FLAGS_UACOKAY) != 0)
+      if (lun->uad != SCSI_KCQ_NOSENSE &&
+          (flags & USBMSC_FLAGS_UACOKAY) != 0)
         {
           /* Command not permitted */
 
-          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDUNEVIOLATION), priv->cbwlun);
+          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDUNEVIOLATION),
+                   priv->cbwlun);
           lun->sd  = lun->uad;
           lun->uad = SCSI_KCQ_NOSENSE;
           ret      = -EINVAL;
@@ -1663,9 +1692,9 @@ static int inline usbmsc_setupcmd(FAR struct usbmsc_dev_s *priv,
  *   for the receipt of a bulk CBW.
  *
  * Returned Value:
- *   If no new, valid CBW is available, this function returns a negated errno.
- *   Otherwise, when a new CBW is successfully parsed, this function sets
- *   priv->thstate to USBMSC_STATE_CMDPARSE and returns OK.
+ *   If no new, valid CBW is available, this function returns a negated
+ *   errno value.  Otherwise, when a new CBW is successfully parsed, this
+ *   function sets priv->thstate to USBMSC_STATE_CMDPARSE and returns OK.
  *
  ****************************************************************************/
 
@@ -1712,8 +1741,8 @@ static int usbmsc_idlestate(FAR struct usbmsc_dev_s *priv)
       cbw->signature[2] != 'B' ||
       cbw->signature[3] != 'C')
     {
-      /* CBS BAD: Stall the bulk endpoints.  If the CBW is bad we must stall the
-       * bulk IN endpoint and either (1) stall the bulk OUT endpoint, or
+      /* CBS BAD: Stall the bulk endpoints.  If the CBW is bad we must stall
+       * the bulk IN endpoint and either (1) stall the bulk OUT endpoint, or
        * (2) discard data from the endpoint.
        */
 
@@ -1724,11 +1753,13 @@ static int usbmsc_idlestate(FAR struct usbmsc_dev_s *priv)
 
   /* Is the CBW meaningful? */
 
-  else if (cbw->lun >= priv->nluns || (cbw->flags & ~USBMSC_CBWFLAG_IN) != 0 ||
-           cbw->cdblen < 6 || cbw->cdblen > USBMSC_MAXCDBLEN)
+  else if (cbw->lun >= priv->nluns ||
+           (cbw->flags & ~USBMSC_CBWFLAG_IN) != 0 ||
+           cbw->cdblen < 6 ||
+           cbw->cdblen > USBMSC_MAXCDBLEN)
     {
-      /* CBS BAD: Stall the bulk endpoints.  If the CBW is bad we must stall the
-       * bulk IN endpoint and either (1) stall the bulk OUT endpoint, or
+      /* CBS BAD: Stall the bulk endpoints.  If the CBW is bad we must stall
+       * the bulk IN endpoint and either (1) stall the bulk OUT endpoint, or
        * (2) discard data from the endpoint.
        */
 
@@ -1785,7 +1816,8 @@ static int usbmsc_idlestate(FAR struct usbmsc_dev_s *priv)
 
       /* Change to the CMDPARSE state and return success */
 
-      usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_IDLECMDPARSE), priv->cdb[0]);
+      usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_IDLECMDPARSE),
+               priv->cdb[0]);
       priv->thstate = USBMSC_STATE_CMDPARSE;
       ret = OK;
     }
@@ -1821,7 +1853,7 @@ static int usbmsc_cmdparsestate(FAR struct usbmsc_dev_s *priv)
 {
   FAR struct usbmsc_req_s *privreq;
   FAR uint8_t *buf;
-  int ret = -EINVAL;
+  int ret;
 
   usbmsc_dumpdata("SCSCI CDB", priv->cdb, priv->cdblen);
 
@@ -1833,8 +1865,8 @@ static int usbmsc_cmdparsestate(FAR struct usbmsc_dev_s *priv)
 
   /* If there no request structures available, then just return an error.
    * This will cause us to remain in the CMDPARSE state.  When a request is
-   * returned, the worker thread will be awakened in the USBMSC_STATE_CMDPARSE
-   * and we will be called again.
+   * returned, the worker thread will be awakened in the
+   * USBMSC_STATE_CMDPARSE and we will be called again.
    */
 
   if (!privreq)
@@ -1858,196 +1890,203 @@ static int usbmsc_cmdparsestate(FAR struct usbmsc_dev_s *priv)
 
   /* Get exclusive access to the block driver */
 
-  usbmsc_scsi_lock(priv);
+  ret = usbmsc_scsi_lock(priv);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  ret = -EINVAL;
+
   switch (priv->cdb[0])
     {
-    case SCSI_CMD_TESTUNITREADY:                     /* 0x00 Mandatory */
+    case SCSI_CMD_TESTUNITREADY:            /* 0x00 Mandatory */
       ret = usbmsc_cmdtestunitready(priv);
       break;
 
-    /* case SCSI_CMD_REZEROUNIT:                      * 0x01 Obsolete
-     *                                                * 0x02 Vendor-specific
+    /* case SCSI_CMD_REZEROUNIT:               0x01 Obsolete
+     *                                         0x02 Vendor-specific
      */
 
-    case SCSI_CMD_REQUESTSENSE:                      /* 0x03 Mandatory */
+    case SCSI_CMD_REQUESTSENSE:             /* 0x03 Mandatory */
       ret = usbmsc_cmdrequestsense(priv, buf);
       break;
 
-    /* case SCSI_CMD_FORMAT_UNIT:                     * 0x04 Mandatory, but not impl.
-     *                                                * 0x05 Vendor specific
-     *                                                * 0x06 Vendor specific
-     * case SCSI_CMD_REASSIGNBLOCKS:                  * 0x07 Optional
+    /* case SCSI_CMD_FORMAT_UNIT:              0x04 Mandatory, but not impl.
+     *                                         0x05 Vendor specific
+     *                                         0x06 Vendor specific
+     * case SCSI_CMD_REASSIGNBLOCKS:           0x07 Optional
      */
 
-    case SCSI_CMD_READ6:                             /* 0x08 Mandatory */
+    case SCSI_CMD_READ6:                    /* 0x08 Mandatory */
       ret = usbmsc_cmdread6(priv);
       break;
 
-    /*                                                * 0x09 Vendor specific */
+    /*                                         0x09 Vendor specific */
 
-    case SCSI_CMD_WRITE6:                            /* 0x0a Optional */
+    case SCSI_CMD_WRITE6:                   /* 0x0a Optional */
       ret = usbmsc_cmdwrite6(priv);
       break;
 
-    /* case SCSI_CMD_SEEK6:                           * 0x0b Obsolete
-     *                                                * 0x0c-0x10 Vendor specific
-     * case SCSI_CMD_SPACE6:                          * 0x11 Vendor specific
+    /* case SCSI_CMD_SEEK6:                    0x0b Obsolete
+     *                                         0x0c-0x10 Vendor specific
+     * case SCSI_CMD_SPACE6:                   0x11 Vendor specific
      */
 
-    case SCSI_CMD_INQUIRY:                           /* 0x12 Mandatory */
+    case SCSI_CMD_INQUIRY:                  /* 0x12 Mandatory */
       ret = usbmsc_cmdinquiry(priv, buf);
       break;
 
-    /*                                                * 0x13-0x14 Vendor specific */
+    /*                                         0x13-0x14 Vendor specific */
 
-    case SCSI_CMD_MODESELECT6:                       /* 0x15 Optional */
+    case SCSI_CMD_MODESELECT6:              /* 0x15 Optional */
       ret = usbmsc_cmdmodeselect6(priv);
       break;
 
-    /* case SCSI_CMD_RESERVE6:                        * 0x16 Obsolete
-     * case SCSI_CMD_RELEASE6:                        * 0x17 Obsolete
-     * case SCSI_CMD_COPY:                            * 0x18 Obsolete
-     *                                                * 0x19 Vendor specific
+    /* case SCSI_CMD_RESERVE6:                 0x16 Obsolete
+     * case SCSI_CMD_RELEASE6:                 0x17 Obsolete
+     * case SCSI_CMD_COPY:                     0x18 Obsolete
+     *                                         0x19 Vendor specific
      */
 
-    case SCSI_CMD_MODESENSE6:                        /* 0x1a Optional */
+    case SCSI_CMD_MODESENSE6:               /* 0x1a Optional */
       ret = usbmsc_cmdmodesense6(priv, buf);
       break;
 
-    case SCSI_CMD_STARTSTOPUNIT:                     /* 0x1b Optional */
+    case SCSI_CMD_STARTSTOPUNIT:            /* 0x1b Optional */
       ret = usbmsc_cmdstartstopunit(priv);
       break;
 
-    /* case SCSI_CMD_RECEIVEDIAGNOSTICRESULTS:        * 0x1c Optional
-     * case SCSI_CMD_SENDDIAGNOSTIC:                  * 0x1d Mandatory, but not impl.
+    /* case SCSI_CMD_RECEIVEDIAGNOSTICRESULTS: 0x1c Optional
+     * case SCSI_CMD_SENDDIAGNOSTIC:           0x1d Mandatory, but not impl.
      */
 
-    case SCSI_CMD_PREVENTMEDIAREMOVAL:               /* 0x1e Optional */
+    case SCSI_CMD_PREVENTMEDIAREMOVAL:      /* 0x1e Optional */
       ret = usbmsc_cmdpreventmediumremoval(priv);
       break;
 
-    /*                                                * 0x20-22 Vendor specific */
+    /*                                         0x20-22 Vendor specific */
 
-    case SCSI_CMD_READFORMATCAPACITIES:              /* 0x23 Vend-spec (def. MMC spec) */
+    case SCSI_CMD_READFORMATCAPACITIES:     /* 0x23 Vend-spec (def. MMC spec) */
       ret = usbmsc_cmdreadformatcapacity(priv, buf);
       break;
 
-    /*                                                * 0x24 Vendor specific */
+    /*                                         0x24 Vendor specific */
 
-    case SCSI_CMD_READCAPACITY10:                    /* 0x25 Mandatory */
+    case SCSI_CMD_READCAPACITY10:           /* 0x25 Mandatory */
       ret = usbmsc_cmdreadcapacity10(priv, buf);
       break;
 
-    /*                                                * 0x26-27 Vendor specific */
+    /*                                         0x26-27 Vendor specific */
 
-    case SCSI_CMD_READ10:                            /* 0x28 Mandatory */
+    case SCSI_CMD_READ10:                   /* 0x28 Mandatory */
       ret = usbmsc_cmdread10(priv);
       break;
 
-    /*                                                * 0x29 Vendor specific */
+    /*                                         0x29 Vendor specific */
 
-    case SCSI_CMD_WRITE10:                           /* 0x2a Optional */
+    case SCSI_CMD_WRITE10:                  /* 0x2a Optional */
       ret = usbmsc_cmdwrite10(priv);
       break;
 
-    /* case SCSI_CMD_SEEK10:                          * 0x2b Obsolete
-     *                                                * 0x2c-2d Vendor specific
-     * case SCSI_CMD_WRITEANDVERIFY:                  * 0x2e Optional
+    /* case SCSI_CMD_SEEK10:                   0x2b Obsolete
+     *                                         0x2c-2d Vendor specific
+     * case SCSI_CMD_WRITEANDVERIFY:           0x2e Optional
      */
 
-    case SCSI_CMD_VERIFY10:                          /* 0x2f Opt, excpt Windows */
+    case SCSI_CMD_VERIFY10:                 /* 0x2f Opt, excpt Windows */
       ret = usbmsc_cmdverify10(priv);
       break;
 
-    /* case SCSI_CMD_SEARCHDATAHIGH:                  * 0x30 Obsolete
-     * case SCSI_CMD_SEARCHDATAEQUAL:                 * 0x31 Obsolete
-     * case SCSI_CMD_SEARCHDATALOW:                   * 0x32 Obsolete
-     * case SCSI_CMD_SETLIMITS10:                     * 0x33 Obsolete
-     * case SCSI_CMD_PREFETCH10:                      * 0x34 Optional
+    /* case SCSI_CMD_SEARCHDATAHIGH:           0x30 Obsolete
+     * case SCSI_CMD_SEARCHDATAEQUAL:          0x31 Obsolete
+     * case SCSI_CMD_SEARCHDATALOW:            0x32 Obsolete
+     * case SCSI_CMD_SETLIMITS10:              0x33 Obsolete
+     * case SCSI_CMD_PREFETCH10:               0x34 Optional
      */
 
-    case SCSI_CMD_SYNCHCACHE10:                      /* 0x35 Optional */
+    case SCSI_CMD_SYNCHCACHE10:             /* 0x35 Optional */
       ret = usbmsc_cmdsynchronizecache10(priv);
       break;
 
-    /* case SCSI_CMD_LOCKCACHE:                       * 0x36 Obsolete
-     * case SCSI_CMD_READDEFECTDATA10:                * 0x37 Optional
-     * case SCSI_CMD_COMPARE:                         * 0x39 Obsolete
-     * case SCSI_CMD_COPYANDVERIFY:                   * 0x3a Obsolete
-     * case SCSI_CMD_WRITEBUFFER:                     * 0x3b Optional
-     * case SCSI_CMD_READBUFFER:                      * 0x3c Optional
-     * case SCSI_CMD_READLONG10:                      * 0x3e Optional
-     * case SCSI_CMD_WRITELONG10:                     * 0x3f Optional
-     * case SCSI_CMD_CHANGEDEFINITION:                * 0x40 Obsolete
-     * case SCSI_CMD_WRITESAME10:                     * 0x41 Optional
-     * case SCSI_CMD_LOGSELECT:                       * 0x4c Optional
-     * case SCSI_CMD_LOGSENSE:                        * 0x4d Optional
-     * case SCSI_CMD_XDWRITE10:                       * 0x50 Optional
-     * case SCSI_CMD_XPWRITE10:                       * 0x51 Optional
-     * case SCSI_CMD_XDREAD10:                        * 0x52 Optional
+    /* case SCSI_CMD_LOCKCACHE:                0x36 Obsolete
+     * case SCSI_CMD_READDEFECTDATA10:         0x37 Optional
+     * case SCSI_CMD_COMPARE:                  0x39 Obsolete
+     * case SCSI_CMD_COPYANDVERIFY:            0x3a Obsolete
+     * case SCSI_CMD_WRITEBUFFER:              0x3b Optional
+     * case SCSI_CMD_READBUFFER:               0x3c Optional
+     * case SCSI_CMD_READLONG10:               0x3e Optional
+     * case SCSI_CMD_WRITELONG10:              0x3f Optional
+     * case SCSI_CMD_CHANGEDEFINITION:         0x40 Obsolete
+     * case SCSI_CMD_WRITESAME10:              0x41 Optional
+     * case SCSI_CMD_LOGSELECT:                0x4c Optional
+     * case SCSI_CMD_LOGSENSE:                 0x4d Optional
+     * case SCSI_CMD_XDWRITE10:                0x50 Optional
+     * case SCSI_CMD_XPWRITE10:                0x51 Optional
+     * case SCSI_CMD_XDREAD10:                 0x52 Optional
      */
 
-    case SCSI_CMD_MODESELECT10:                      /* 0x55 Optional */
+    case SCSI_CMD_MODESELECT10:             /* 0x55 Optional */
       ret = usbmsc_cmdmodeselect10(priv);
       break;
 
-    /* case SCSI_CMD_RESERVE10:                       * 0x56 Obsolete
-     * case SCSI_CMD_RELEASE10:                       * 0x57 Obsolete
+    /* case SCSI_CMD_RESERVE10:                0x56 Obsolete
+     * case SCSI_CMD_RELEASE10:                0x57 Obsolete
      */
 
-    case SCSI_CMD_MODESENSE10:                    /* 0x5a Optional */
+    case SCSI_CMD_MODESENSE10:              /* 0x5a Optional */
       ret = usbmsc_cmdmodesense10(priv, buf);
       break;
 
-    /* case SCSI_CMD_PERSISTENTRESERVEIN:             * 0x5e Optional
-     * case SCSI_CMD_PERSISTENTRESERVEOUT:            * 0x5f Optional
-     * case SCSI_CMD_32:                              * 0x7f Optional
-     * case SCSI_CMD_XDWRITEEXTENDED:                 * 0x80 Obsolete
-     * case SCSI_CMD_REBUILD:                         * 0x81 Obsolete
-     * case SCSI_CMD_REGENERATE:                      * 0x82 Obsolete
-     * case SCSI_CMD_EXTENDEDCOPY:                    * 0x83 Optional
-     * case SCSI_CMD_COPYRESULTS:                     * 0x84 Optional
-     * case SCSI_CMD_ACCESSCONTROLIN:                 * 0x86 Optional
-     * case SCSI_CMD_ACCESSCONTROLOUT:                * 0x87 Optional
-     * case SCSI_CMD_READ16:                          * 0x88 Optional
-     * case SCSI_CMD_WRITE16:                         * 0x8a Optional
-     * case SCSI_CMD_READATTRIBUTE:                   * 0x8c Optional
-     * case SCSI_CMD_WRITEATTRIBUTE:                  * 0x8d Optional
-     * case SCSI_CMD_WRITEANDVERIFY16:                * 0x8e Optional
-     * case SCSI_CMD_SYNCHCACHE16:                    * 0x91 Optional
-     * case SCSI_CMD_LOCKUNLOCKACACHE:                * 0x92 Optional
-     * case SCSI_CMD_WRITESAME16:                     * 0x93 Optional
-     * case SCSI_CMD_READCAPACITY16:                  * 0x9e Optional
-     * case SCSI_CMD_READLONG16:                      * 0x9e Optional
-     * case SCSI_CMD_WRITELONG16                      * 0x9f Optional
-     * case SCSI_CMD_REPORTLUNS:                      * 0xa0 Mandatory, but no-impl
-     * case SCSI_CMD_MAINTENANCEIN:                   * 0xa3 Optional (SCCS==0)
-     * case SCSI_CMD_MAINTENANCEOUT:                  * 0xa4 Optional (SCCS==0)
-     * case SCSI_CMD_MOVEMEDIUM:                      * 0xa5 ?
-     * case SCSI_CMD_MOVEMEDIUMATTACHED:              * 0xa7 Optional (MCHNGR==0)
+    /* case SCSI_CMD_PERSISTENTRESERVEIN:      0x5e Optional
+     * case SCSI_CMD_PERSISTENTRESERVEOUT:     0x5f Optional
+     * case SCSI_CMD_32:                       0x7f Optional
+     * case SCSI_CMD_XDWRITEEXTENDED:          0x80 Obsolete
+     * case SCSI_CMD_REBUILD:                  0x81 Obsolete
+     * case SCSI_CMD_REGENERATE:               0x82 Obsolete
+     * case SCSI_CMD_EXTENDEDCOPY:             0x83 Optional
+     * case SCSI_CMD_COPYRESULTS:              0x84 Optional
+     * case SCSI_CMD_ACCESSCONTROLIN:          0x86 Optional
+     * case SCSI_CMD_ACCESSCONTROLOUT:         0x87 Optional
+     * case SCSI_CMD_READ16:                   0x88 Optional
+     * case SCSI_CMD_WRITE16:                  0x8a Optional
+     * case SCSI_CMD_READATTRIBUTE:            0x8c Optional
+     * case SCSI_CMD_WRITEATTRIBUTE:           0x8d Optional
+     * case SCSI_CMD_WRITEANDVERIFY16:         0x8e Optional
+     * case SCSI_CMD_SYNCHCACHE16:             0x91 Optional
+     * case SCSI_CMD_LOCKUNLOCKACACHE:         0x92 Optional
+     * case SCSI_CMD_WRITESAME16:              0x93 Optional
+     * case SCSI_CMD_READCAPACITY16:           0x9e Optional
+     * case SCSI_CMD_READLONG16:               0x9e Optional
+     * case SCSI_CMD_WRITELONG16               0x9f Optional
+     * case SCSI_CMD_REPORTLUNS:               0xa0 Mandatory, but no-impl
+     * case SCSI_CMD_MAINTENANCEIN:            0xa3 Optional (SCCS==0)
+     * case SCSI_CMD_MAINTENANCEOUT:           0xa4 Optional (SCCS==0)
+     * case SCSI_CMD_MOVEMEDIUM:               0xa5 ?
+     * case SCSI_CMD_MOVEMEDIUMATTACHED:       0xa7 Optional (MCHNGR==0)
      */
 
-    case SCSI_CMD_READ12:                         /* 0xa8 Optional */
+    case SCSI_CMD_READ12:                   /* 0xa8 Optional */
       ret = usbmsc_cmdread12(priv);
       break;
 
-    case SCSI_CMD_WRITE12:                        /* 0xaa Optional */
+    case SCSI_CMD_WRITE12:                  /* 0xaa Optional */
       ret = usbmsc_cmdwrite12(priv);
       break;
 
-    /* case SCSI_CMD_READMEDIASERIALNUMBER:           * 0xab Optional
-     * case SCSI_CMD_WRITEANDVERIFY12:                * 0xae Optional
-     * case SCSI_CMD_VERIFY12:                        * 0xaf Optional
-     * case SCSI_CMD_SETLIMITS12                      * 0xb3 Obsolete
-     * case SCSI_CMD_READELEMENTSTATUS:               * 0xb4 Optional (MCHNGR==0)
-     * case SCSI_CMD_READDEFECTDATA12:                * 0xb7 Optional
-     * case SCSI_CMD_REDUNDANCYGROUPIN:               * 0xba Optional
-     * case SCSI_CMD_REDUNDANCYGROUPOUT:              * 0xbb Optional
-     * case SCSI_CMD_SPAREIN:                         * 0xbc Optional (SCCS==0)
-     * case SCSI_CMD_SPAREOUT:                        * 0xbd Optional (SCCS==0)
-     * case SCSI_CMD_VOLUMESETIN:                     * 0xbe Optional (SCCS==0)
-     * case SCSI_CMD_VOLUMESETOUT:                    * 0xbe Optional (SCCS==0)
-     *                                                * 0xc0-0xff Vendor specific
+    /* case SCSI_CMD_READMEDIASERIALNUMBER:    0xab Optional
+     * case SCSI_CMD_WRITEANDVERIFY12:         0xae Optional
+     * case SCSI_CMD_VERIFY12:                 0xaf Optional
+     * case SCSI_CMD_SETLIMITS12               0xb3 Obsolete
+     * case SCSI_CMD_READELEMENTSTATUS:        0xb4 Optional (MCHNGR==0)
+     * case SCSI_CMD_READDEFECTDATA12:         0xb7 Optional
+     * case SCSI_CMD_REDUNDANCYGROUPIN:        0xba Optional
+     * case SCSI_CMD_REDUNDANCYGROUPOUT:       0xbb Optional
+     * case SCSI_CMD_SPAREIN:                  0xbc Optional (SCCS==0)
+     * case SCSI_CMD_SPAREOUT:                 0xbd Optional (SCCS==0)
+     * case SCSI_CMD_VOLUMESETIN:              0xbe Optional (SCCS==0)
+     * case SCSI_CMD_VOLUMESETOUT:             0xbe Optional (SCCS==0)
+     *                                         0xc0-0xff Vendor specific
      */
 
     default:
@@ -2064,9 +2103,9 @@ static int usbmsc_cmdparsestate(FAR struct usbmsc_dev_s *priv)
 
   if (priv->thstate == USBMSC_STATE_CMDPARSE)
     {
-      /* All commands come through this path (EXCEPT read6/10/12 and write6/10/12).
-       * For all other commands, the following setup is expected for the response
-       * based on data direction:
+      /* All commands come through this path (EXCEPT read6/10/12 and
+       * write6/10/12).  For all other commands, the following setup is
+       * expected for the response based on data direction:
        *
        * For direction NONE:
        *   1. priv->u.alloclen == 0
@@ -2077,13 +2116,14 @@ static int usbmsc_cmdparsestate(FAR struct usbmsc_dev_s *priv)
        *      host to receive the device data.  The size of the response
        *      cannot exceed this value.
        *   2. response data is in the request currently at the head of
-       *      the priv->wrreqlist queue.  priv->nreqbytes is set to the length
-       *      of data in the response.
+       *      the priv->wrreqlist queue.  priv->nreqbytes is set to the
+       *      length of data in the response.
        *
        * For direction host-to-device
-       *   At present, there are no supported commands that should have host-to-device
-       *   transfers (except write6/10/12 and that command logic does not take this
-       *   path.  The 'residue' is left at the full host-to-device data size.
+       *   At present, there are no supported commands that should have
+       *   host-to-device transfers (except write6/10/12 and that command
+       *   logic does not take this path.  The 'residue' is left at the full
+       *   host-to-device data size.
        *
        * For all:
        *   ret set to <0 if an error occurred in parsing the commands.
@@ -2113,12 +2153,13 @@ static int usbmsc_cmdparsestate(FAR struct usbmsc_dev_s *priv)
       /* On return, we need the following:
        *
        *   1. Setup for CMDFINISH state if appropriate
-       *   2. priv->thstate set to either CMDPARSE if no buffer was available or
-       *      CMDFINISH to send the response
+       *   2. priv->thstate set to either CMDPARSE if no buffer was
+       *     available or CMDFINISH to send the response
        *   3. Return OK to continue; <0 to wait for the next event
        */
 
-      usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDPARSECMDFINISH), priv->cdb[0]);
+      usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDPARSECMDFINISH),
+               priv->cdb[0]);
       priv->thstate = USBMSC_STATE_CMDFINISH;
       ret = OK;
     }
@@ -2137,10 +2178,11 @@ static int usbmsc_cmdparsestate(FAR struct usbmsc_dev_s *priv)
  *   command handling.
  *
  * Returned Value:
- *   If no USBDEV write request is available or certain other errors occur, this
- *   function returns a negated errno and stays in the USBMSC_STATE_CMDREAD
- *   state.  Otherwise, when the new SCSI read command is fully processed,
- *   this function sets priv->thstate to USBMSC_STATE_CMDFINISH and returns OK.
+ *   If no USBDEV write request is available or certain other errors occur,
+ *   this function returns a negated errno and stays in the
+ *   USBMSC_STATE_CMDREAD state.  Otherwise, when the new SCSI read command
+ *   is fully processed, this function sets priv->thstate to
+ *   USBMSC_STATE_CMDFINISH and returns OK.
  *
  * State variables:
  *   xfrlen     - holds the number of sectors read to be read.
@@ -2164,8 +2206,8 @@ static int usbmsc_cmdreadstate(FAR struct usbmsc_dev_s *priv)
   int ret;
 
   /* Loop transferring data until either (1) all of the data has been
-   * transferred, or (2) we have used up all of the write requests that we have
-   * available.
+   * transferred, or (2) we have used up all of the write requests that we
+   * have available.
    */
 
   while (priv->u.xfrlen > 0 || priv->nsectbytes > 0)
@@ -2181,7 +2223,8 @@ static int usbmsc_cmdreadstate(FAR struct usbmsc_dev_s *priv)
           nread = USBMSC_DRVR_READ(lun, priv->iobuffer, priv->sector, 1);
           if (nread < 0)
             {
-              usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDREADREADFAIL), -nread);
+              usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDREADREADFAIL),
+                       -nread);
               lun->sd     = SCSI_KCQME_UNRRE1;
               lun->sdinfo = priv->sector;
               break;
@@ -2198,10 +2241,10 @@ static int usbmsc_cmdreadstate(FAR struct usbmsc_dev_s *priv)
 
       privreq = (FAR struct usbmsc_req_s *)sq_peek(&priv->wrreqlist);
 
-      /* If there no request structures available, then just return an error.
-       * This will cause us to remain in the CMDREAD state.  When a request is
-       * returned, the worker thread will be awakened in the USBMSC_STATE_CMDREAD
-       * and we will be called again.
+      /* If there no request structures available, then just return an
+       * error.  This will cause us to remain in the CMDREAD state.  When a
+       * request is returned, the worker thread will be awakened in the
+       * USBMSC_STATE_CMDREAD and we will be called again.
        */
 
       if (!privreq)
@@ -2213,14 +2256,15 @@ static int usbmsc_cmdreadstate(FAR struct usbmsc_dev_s *priv)
 
       req = privreq->req;
 
-      /* Transfer all of the data that will (1) fit into the request buffer, OR (2)
-       * all of the data available in the sector buffer.
+      /* Transfer all of the data that will (1) fit into the request buffer,
+       * OR (2) all of the data available in the sector buffer.
        */
 
       src    = &priv->iobuffer[lun->sectorsize - priv->nsectbytes];
       dest   = &req->buf[priv->nreqbytes];
 
-      nbytes = MIN(priv->epbulkin->maxpacket - priv->nreqbytes, priv->nsectbytes);
+      nbytes = MIN(priv->epbulkin->maxpacket - priv->nreqbytes,
+                   priv->nsectbytes);
 
       /* Copy the data from the sector buffer to the USB request and update counts */
 
@@ -2254,14 +2298,16 @@ static int usbmsc_cmdreadstate(FAR struct usbmsc_dev_s *priv)
           ret           = EP_SUBMIT(priv->epbulkin, req);
           if (ret != OK)
             {
-              usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDREADSUBMIT), (uint16_t)-ret);
+              usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDREADSUBMIT),
+                       (uint16_t)-ret);
               lun->sd     = SCSI_KCQME_UNRRE1;
               lun->sdinfo = priv->sector;
               break;
             }
 
-          /* Assume success... residue should probably really be decremented in
-           * wrcomplete when we know that the transfer completed successfully.
+          /* Assume success... residue should probably really be decremented
+           * in wrcomplete when we know that the transfer completed
+           * successfully.
            */
 
           priv->residue  -= priv->nreqbytes;
@@ -2269,7 +2315,8 @@ static int usbmsc_cmdreadstate(FAR struct usbmsc_dev_s *priv)
         }
     }
 
-  usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDREADCMDFINISH), priv->u.xfrlen);
+  usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDREADCMDFINISH),
+           priv->u.xfrlen);
   priv->thstate  = USBMSC_STATE_CMDFINISH;
   return OK;
 }
@@ -2285,10 +2332,11 @@ static int usbmsc_cmdreadstate(FAR struct usbmsc_dev_s *priv)
  *   command handling.
  *
  * Returned Value:
- *   If no USBDEV write request is available or certain other errors occur, this
- *   function returns a negated errno and stays in the USBMSC_STATE_CMDWRITE
- *   state.  Otherwise, when the new SCSI write command is fully processed,
- *   this function sets priv->thstate to USBMSC_STATE_CMDFINISH and returns OK.
+ *   If no USBDEV write request is available or certain other errors occur,
+ *   this function returns a negated errno and stays in the
+ *   USBMSC_STATE_CMDWRITE state.  Otherwise, when the new SCSI write
+ *   command is fully processed, this function sets priv->thstate to
+ *   USBMSC_STATE_CMDFINISH and returns OK.
  *
  * State variables:
  *   xfrlen     - holds the number of sectors read to be written.
@@ -2329,9 +2377,9 @@ static int usbmsc_cmdwritestate(FAR struct usbmsc_dev_s *priv)
       leave_critical_section(flags);
 
       /* If there no request data available, then just return an error.
-       * This will cause us to remain in the CMDWRITE state.  When a filled request is
-       * received, the worker thread will be awakened in the USBMSC_STATE_CMDWRITE
-       * and we will be called again.
+       * This will cause us to remain in the CMDWRITE state.  When a filled
+       * request is received, the worker thread will be awakened in the
+       * USBMSC_STATE_CMDWRITE and we will be called again.
        */
 
       if (!privreq)
@@ -2345,8 +2393,9 @@ static int usbmsc_cmdwritestate(FAR struct usbmsc_dev_s *priv)
       xfrd            = req->xfrd;
       priv->nreqbytes = xfrd;
 
-      /* Now loop until all of the data in the read request has been transferred
-       * to the block driver OR all of the request data has been transferred.
+      /* Now loop until all of the data in the read request has been
+       * transferred to the block driver OR all of the request data has been
+       * transferred.
        */
 
       while (priv->nreqbytes > 0 && priv->u.xfrlen > 0)
@@ -2370,7 +2419,8 @@ static int usbmsc_cmdwritestate(FAR struct usbmsc_dev_s *priv)
             {
               /* Yes.. Write the next sector */
 
-              nwritten = USBMSC_DRVR_WRITE(lun, priv->iobuffer, priv->sector, 1);
+              nwritten = USBMSC_DRVR_WRITE(lun, priv->iobuffer,
+                                           priv->sector, 1);
               if (nwritten < 0)
                 {
                   usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDWRITEWRITEFAIL),
@@ -2387,9 +2437,9 @@ static int usbmsc_cmdwritestate(FAR struct usbmsc_dev_s *priv)
             }
         }
 
-      /* In either case, we are finished with this read request and can return it
-       * to the endpoint.  Then we will go back to the top of the top and attempt
-       * to get the next read request.
+      /* In either case, we are finished with this read request and can
+       * return it to the endpoint.  Then we will go back to the top of the
+       * top and attempt to get the next read request.
        */
 
       req->len      = priv->epbulkout->maxpacket;
@@ -2399,7 +2449,8 @@ static int usbmsc_cmdwritestate(FAR struct usbmsc_dev_s *priv)
       ret = EP_SUBMIT(priv->epbulkout, req);
       if (ret != OK)
         {
-          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDWRITERDSUBMIT), (uint16_t)-ret);
+          usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDWRITERDSUBMIT),
+                   (uint16_t)-ret);
         }
 
       /* Did the host decide to stop early? */
@@ -2412,7 +2463,8 @@ static int usbmsc_cmdwritestate(FAR struct usbmsc_dev_s *priv)
     }
 
 errout:
-  usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDWRITECMDFINISH), priv->u.xfrlen);
+  usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDWRITECMDFINISH),
+           priv->u.xfrlen);
   priv->thstate  = USBMSC_STATE_CMDFINISH;
   return OK;
 }
@@ -2426,10 +2478,11 @@ errout:
  *   command has finished but before status has been returned.
  *
  * Returned Value:
- *   If no USBDEV write request is available or certain other errors occur, this
- *   function returns a negated errno and stays in the USBMSC_STATE_CMDFINISH
- *   state.  Otherwise, when the command is fully processed, this function
- *   sets priv->thstate to USBMSC_STATE_CMDSTATUS and returns OK.
+ *   If no USBDEV write request is available or certain other errors occur,
+ *   this function returns a negated errno and stays in the
+ *   USBMSC_STATE_CMDFINISH state.  Otherwise, when the command is fully
+ *   processed, this function sets priv->thstate to USBMSC_STATE_CMDSTATUS
+ *   and returns OK.
  *
  ****************************************************************************/
 
@@ -2479,7 +2532,8 @@ static int usbmsc_cmdfinishstate(FAR struct usbmsc_dev_s *priv)
                */
 
               flags = enter_critical_section();
-              privreq = (FAR struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist);
+              privreq = (FAR struct usbmsc_req_s *)
+                sq_remfirst(&priv->wrreqlist);
               leave_critical_section(flags);
 
               /* Send the write request */
@@ -2507,7 +2561,8 @@ static int usbmsc_cmdfinishstate(FAR struct usbmsc_dev_s *priv)
 
 #ifdef USBMSC_STALL_RACEWAR
               /* (See description of the workaround at the top of the file).
-               * First, wait for the transfer to complete, then stall the endpoint
+               * First, wait for the transfer to complete, then stall the
+               * endpoint
                */
 
               nxsig_usleep (100000);
@@ -2598,9 +2653,9 @@ static int usbmsc_cmdstatusstate(FAR struct usbmsc_dev_s *priv)
   leave_critical_section(flags);
 
   /* If there no request structures available, then just return an error.
-   * This will cause us to remain in the CMDSTATUS status.  When a request is
-   * returned, the worker thread will be awakened in the USBMSC_STATE_CMDSTATUS
-   * and we will be called again.
+   * This will cause us to remain in the CMDSTATUS status.  When a request
+   * is returned, the worker thread will be awakened in the
+   * USBMSC_STATE_CMDSTATUS and we will be called again.
    */
 
   if (!privreq)
@@ -2657,7 +2712,8 @@ static int usbmsc_cmdstatusstate(FAR struct usbmsc_dev_s *priv)
   ret            = EP_SUBMIT(priv->epbulkin, req);
   if (ret < 0)
     {
-      usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SNDSTATUSSUBMIT), (uint16_t)-ret);
+      usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SNDSTATUSSUBMIT),
+               (uint16_t)-ret);
       flags = enter_critical_section();
       sq_addlast((FAR sq_entry_t *)privreq, &priv->wrreqlist);
       leave_critical_section(flags);
@@ -2700,17 +2756,33 @@ int usbmsc_scsi_main(int argc, char *argv[])
   g_usbmsc_handoff = NULL;
   usbmsc_synch_signal(priv);
 
-  /* This thread is started before the USB storage class is fully initialized.
-   * wait here until we are told to begin.  Start in the NOTINITIALIZED state
+  /* Get exclusive access to SCSI state data */
+
+  ret = usbmsc_scsi_lock(priv);
+  if (ret < 0)
+    {
+      return EXIT_FAILURE;
+    }
+
+  /* This thread is started before the USB storage class is fully
+   * initialized.  Wait here until we are told to begin.  Start in the
+   * NOTINITIALIZED state
    */
 
-  uinfo("Waiting to be signalled\n");
-  usbmsc_scsi_lock(priv);
+  uinfo("Waiting to be signaled\n");
+
   priv->thstate = USBMSC_STATE_STARTED;
   while ((priv->theventset & USBMSC_EVENT_READY) == 0 &&
          (priv->theventset & USBMSC_EVENT_TERMINATEREQUEST) == 0)
     {
-      usbmsc_scsi_wait(priv);
+      ret = usbmsc_scsi_wait(priv);
+      if (ret < 0)
+        {
+          /* The thread has been canceled */
+
+          usbmsc_scsi_unlock(priv);
+          return EXIT_FAILURE;
+        }
     }
 
   uinfo("Running\n");
@@ -2728,14 +2800,28 @@ int usbmsc_scsi_main(int argc, char *argv[])
     {
       /* Wait for some interesting event.  Note that we must both take the
        * lock (to eliminate race conditions with other threads) and disable
-       * interrupts (to eliminate race conditions with USB interrupt handling.
+       * interrupts (to eliminate race conditions with USB interrupt
+       * handling.
        */
 
-      usbmsc_scsi_lock(priv);
+      ret = usbmsc_scsi_lock(priv);
+      if (ret < 0)
+        {
+          return EXIT_FAILURE;
+        }
+
       flags = enter_critical_section();
       if (priv->theventset == USBMSC_EVENT_NOEVENTS)
         {
-          usbmsc_scsi_wait(priv);
+          ret = usbmsc_scsi_wait(priv);
+          if (ret < 0)
+            {
+              /* The thread has been canceled */
+
+              leave_critical_section(flags);
+              usbmsc_scsi_unlock(priv);
+              return EXIT_FAILURE;
+            }
         }
 
       /* Sample any events before re-enabling interrupts.  Any events that
@@ -2749,12 +2835,13 @@ int usbmsc_scsi_main(int argc, char *argv[])
 
       /* Were we awakened by some event that requires immediate action?
        *
-       * - The USBMSC_EVENT_DISCONNECT is signalled from the disconnect method
-       *   after all transfers have been stopped, when the host is disconnected.
+       * - The USBMSC_EVENT_DISCONNECT is signaled from the disconnect
+       *   method after all transfers have been stopped, when the host is
+       *   disconnected.
        *
-       * - The CUSBMSC_EVENT_RESET is signalled when the bulk-storage-specific
-       *   USBMSC_REQ_MSRESET EP0 setup received.  We must stop the current
-       *   operation and reinialize state.
+       * - The CUSBMSC_EVENT_RESET is signaled when the bulk-storage
+       *   specific USBMSC_REQ_MSRESET EP0 setup received.  We must stop the
+       *   current operation and reinitialize state.
        *
        * - The USBMSC_EVENT_CFGCHANGE is signaled when the EP0 setup logic
        *   receives a valid USB_REQ_SETCONFIGURATION request
@@ -2762,7 +2849,7 @@ int usbmsc_scsi_main(int argc, char *argv[])
        * - The USBMSC_EVENT_IFCHANGE is signaled when the EP0 setup logic
        *   receives a valid USB_REQ_SETINTERFACE request
        *
-       * - The USBMSC_EVENT_ABORTBULKOUT event is signalled by the CMDFINISH
+       * - The USBMSC_EVENT_ABORTBULKOUT event is signaled by the CMDFINISH
        *   logic when there is a residue after processing a host-to-device
        *   transfer.  We need to discard all incoming request.
        *
@@ -2799,7 +2886,8 @@ int usbmsc_scsi_main(int argc, char *argv[])
       /* Loop processing each SCSI command state.  Each state handling
        * function will do the following:
        *
-       * - If it must block for an event, it will return a negated errno value
+       * - If it must block for an event, it will return a negated errno
+       *   value
        * - If it completes the processing for that state, it will (1) set
        *   the next appropriate state value and (2) return OK.
        *
@@ -2812,35 +2900,36 @@ int usbmsc_scsi_main(int argc, char *argv[])
         {
           switch (priv->thstate)
             {
-            case USBMSC_STATE_IDLE:             /* Started and waiting for commands */
+            case USBMSC_STATE_IDLE:        /* Started and waiting for commands */
                ret = usbmsc_idlestate(priv);
                break;
 
-            case USBMSC_STATE_CMDPARSE:         /* Parsing the received a command */
+            case USBMSC_STATE_CMDPARSE:    /* Parsing the received a command */
                ret = usbmsc_cmdparsestate(priv);
                break;
 
-            case USBMSC_STATE_CMDREAD:          /* Continuing to process a SCSI read command */
+            case USBMSC_STATE_CMDREAD:     /* Continuing to process a SCSI read command */
                ret = usbmsc_cmdreadstate(priv);
                break;
 
-            case USBMSC_STATE_CMDWRITE:         /* Continuing to process a SCSI write command */
+            case USBMSC_STATE_CMDWRITE:    /* Continuing to process a SCSI write command */
                ret = usbmsc_cmdwritestate(priv);
                break;
 
-            case USBMSC_STATE_CMDFINISH:        /* Finish command processing */
+            case USBMSC_STATE_CMDFINISH:   /* Finish command processing */
                ret = usbmsc_cmdfinishstate(priv);
                break;
 
-            case USBMSC_STATE_CMDSTATUS:        /* Processing the status phase of a command */
+            case USBMSC_STATE_CMDSTATUS:   /* Processing the status phase of a command */
               ret = usbmsc_cmdstatusstate(priv);
               break;
 
-            case USBMSC_STATE_NOTSTARTED:       /* Thread has not yet been started */
-            case USBMSC_STATE_STARTED:          /* Started, but is not yet initialized */
-            case USBMSC_STATE_TERMINATED:       /* Thread has exitted */
+            case USBMSC_STATE_NOTSTARTED:  /* Thread has not yet been started */
+            case USBMSC_STATE_STARTED:     /* Started, but is not yet initialized */
+            case USBMSC_STATE_TERMINATED:  /* Thread has exited */
             default:
-              usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INVALIDSTATE), priv->thstate);
+              usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INVALIDSTATE),
+                       priv->thstate);
               priv->thstate = USBMSC_STATE_IDLE;
               ret           = OK;
               break;
@@ -2892,7 +2981,7 @@ void usbmsc_scsi_signal(FAR struct usbmsc_dev_s *priv)
  *
  ****************************************************************************/
 
-void usbmsc_scsi_lock(FAR struct usbmsc_dev_s *priv)
+int usbmsc_scsi_lock(FAR struct usbmsc_dev_s *priv)
 {
-  nxsem_wait_uninterruptible(&priv->thlock);
+  return nxsem_wait_uninterruptible(&priv->thlock);
 }