summaryrefslogtreecommitdiff
path: root/nuttx/drivers/usbhost/usbhost_storage.c
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-09-10 11:38:40 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-09-10 11:38:40 -0600
commit669c2200146850f70228b5a1323156c506f8e224 (patch)
tree1548ad36f83852e0c11eb94fc5d131927664cc91 /nuttx/drivers/usbhost/usbhost_storage.c
parent2a9410a2ae8ce12d6c0bbf768d6d8d82281d97c9 (diff)
downloadpx4-nuttx-669c2200146850f70228b5a1323156c506f8e224.tar.gz
px4-nuttx-669c2200146850f70228b5a1323156c506f8e224.tar.bz2
px4-nuttx-669c2200146850f70228b5a1323156c506f8e224.zip
Fix a reference counting error in the USB host mass storage class
Diffstat (limited to 'nuttx/drivers/usbhost/usbhost_storage.c')
-rw-r--r--nuttx/drivers/usbhost/usbhost_storage.c54
1 files changed, 26 insertions, 28 deletions
diff --git a/nuttx/drivers/usbhost/usbhost_storage.c b/nuttx/drivers/usbhost/usbhost_storage.c
index c6126131f..e0d662286 100644
--- a/nuttx/drivers/usbhost/usbhost_storage.c
+++ b/nuttx/drivers/usbhost/usbhost_storage.c
@@ -1322,45 +1322,43 @@ static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv)
ret = register_blockdriver(devname, &g_bops, 0, priv);
}
- /* Check if we successfully initialized. We now have to be concerned
- * about asynchronous modification of crefs because the block
+ /* Decrement the reference count. We incremented the reference count
+ * above so that usbhost_destroy() could not be called. We now have to
+ * be concerned about asynchronous modification of crefs because the block
* driver has been registerd.
*/
- if (ret == OK)
- {
- usbhost_takesem(&priv->exclsem);
- DEBUGASSERT(priv->crefs >= 2);
-
- /* Decrement the reference count */
-
- priv->crefs--;
+ usbhost_takesem(&priv->exclsem);
+ DEBUGASSERT(priv->crefs >= 2);
- /* Handle a corner case where (1) open() has been called so the
- * reference count was > 2, but the device has been disconnected.
- * In this case, the class instance needs to persist until close()
- * is called.
- */
+ /* Decrement the reference count */
- if (priv->crefs <= 1 && priv->disconnected)
- {
- /* The will cause the enumeration logic to disconnect
- * the class driver.
- */
+ priv->crefs--;
- ret = -ENODEV;
- }
+ /* Check if we successfully initialized. If so, handle a corner case
+ * where (1) open() has been called so the reference count was > 2, but
+ * the device has been disconnected. In this case, the class instance
+ * needs to persist until close()
+ * is called.
+ */
- /* Release the semaphore... there is a race condition here.
- * Decrementing the reference count and releasing the semaphore
- * allows usbhost_destroy() to execute (on the worker thread);
- * the class driver instance could get destoryed before we are
- * ready to handle it!
+ if (ret == OK && priv->crefs <= 1 && priv->disconnected)
+ {
+ /* The will cause the enumeration logic to disconnect the class
+ * driver.
*/
- usbhost_givesem(&priv->exclsem);
+ ret = -ENODEV;
}
+ /* Release the semaphore... there is a race condition here.
+ * Decrementing the reference count and releasing the semaphore
+ * allows usbhost_destroy() to execute (on the worker thread);
+ * the class driver instance could get destroyed before we are
+ * ready to handle it!
+ */
+
+ usbhost_givesem(&priv->exclsem);
return ret;
}