diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-09-10 11:38:40 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-09-10 11:38:40 -0600 |
commit | 669c2200146850f70228b5a1323156c506f8e224 (patch) | |
tree | 1548ad36f83852e0c11eb94fc5d131927664cc91 /nuttx/drivers/usbhost/usbhost_storage.c | |
parent | 2a9410a2ae8ce12d6c0bbf768d6d8d82281d97c9 (diff) | |
download | px4-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.c | 54 |
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; } |