forked from nuttx/nuttx-update
Correct unitialization of composite USB device. A stale pointer was being reused. From David Sidrane
This commit is contained in:
parent
4cb6c0ad80
commit
f67ee984f3
4 changed files with 64 additions and 13 deletions
|
@ -5966,4 +5966,8 @@
|
|||
logic when buffers larger than the EP0 packet size are sent.
|
||||
Also add support for decoded USB trace strings. From David
|
||||
Sidrane (2013-11-5).
|
||||
|
||||
* drivers/usbdev/cdcacm.c, composite.c, usbmsc.c: uninitialization
|
||||
logic cause re-use of a stale pointer. Changed to a two pass
|
||||
uninitialization for the case of the composite driver: Memory
|
||||
resources are not freed until the second uninitialization pass.
|
||||
From David Sidrane (2011-1105).
|
||||
|
|
|
@ -2398,6 +2398,22 @@ void cdcacm_uninitialize(FAR void *handle)
|
|||
char devname[CDCACM_DEVNAME_SIZE];
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_CDCACM_COMPOSITE
|
||||
/* Check for pass 2 uninitialization. We did most of the work on the
|
||||
* first pass uninitialization.
|
||||
*/
|
||||
|
||||
if (priv->minor == (uint8_t)-1)
|
||||
{
|
||||
/* In this second and final pass, all that remains to be done is to
|
||||
* free the memory resources.
|
||||
*/
|
||||
|
||||
kfree(priv);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Un-register the CDC/ACM TTY device */
|
||||
|
||||
sprintf(devname, CDCACM_DEVNAME_FORMAT, priv->minor);
|
||||
|
@ -2420,9 +2436,19 @@ void cdcacm_uninitialize(FAR void *handle)
|
|||
|
||||
#ifndef CONFIG_CDCACM_COMPOSITE
|
||||
usbdev_unregister(&drvr->drvr);
|
||||
#endif
|
||||
|
||||
/* And free the driver structure */
|
||||
|
||||
kfree(priv);
|
||||
|
||||
#else
|
||||
/* For the case of the composite driver, there is a two pass
|
||||
* uninitialization sequence. We cannot yet free the driver structure.
|
||||
* We will do that on the second pass. We mark the fact that we have
|
||||
* already unitialized by setting the minor number to -1. If/when we
|
||||
* are called again, then we will free the memory resources.
|
||||
*/
|
||||
|
||||
priv->minor = (uint8_t)-1;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -880,20 +880,12 @@ void composite_uninitialize(FAR void *handle)
|
|||
|
||||
DEBUGASSERT(alloc != NULL);
|
||||
|
||||
/* Uninitialize each of the member classes */
|
||||
/* First phase uninitialization each of the member classes */
|
||||
|
||||
priv = &alloc->dev;
|
||||
if (priv->dev1)
|
||||
{
|
||||
DEV1_UNINITIALIZE(priv->dev1);
|
||||
priv->dev1 = NULL;
|
||||
}
|
||||
|
||||
if (priv->dev2)
|
||||
{
|
||||
DEV2_UNINITIALIZE(priv->dev2);
|
||||
priv->dev2 = NULL;
|
||||
}
|
||||
DEV1_UNINITIALIZE(priv->dev1);
|
||||
DEV2_UNINITIALIZE(priv->dev2);
|
||||
|
||||
/* Then unregister and destroy the composite class */
|
||||
|
||||
|
@ -902,6 +894,11 @@ void composite_uninitialize(FAR void *handle)
|
|||
/* Free any resources used by the composite driver */
|
||||
/* None */
|
||||
|
||||
/* Second phase uninitialization: Clean up all memory resources */
|
||||
|
||||
DEV1_UNINITIALIZE(priv->dev1);
|
||||
DEV2_UNINITIALIZE(priv->dev2);
|
||||
|
||||
/* Then free the composite driver state structure itself */
|
||||
|
||||
kfree(priv);
|
||||
|
|
|
@ -1739,6 +1739,22 @@ void usbmsc_uninitialize(FAR void *handle)
|
|||
|
||||
priv = &alloc->dev;
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
/* Check for pass 2 uninitialization. We did most of the work on the
|
||||
* first pass uninitialization.
|
||||
*/
|
||||
|
||||
if (priv->thread == 0)
|
||||
{
|
||||
/* In this second and final pass, all that remains to be done is to
|
||||
* free the memory resources.
|
||||
*/
|
||||
|
||||
kfree(priv);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the thread hasn't already exitted, tell it to exit now */
|
||||
|
||||
if (priv->thstate != USBMSC_STATE_NOTSTARTED)
|
||||
|
@ -1821,5 +1837,13 @@ void usbmsc_uninitialize(FAR void *handle)
|
|||
pthread_mutex_destroy(&priv->mutex);
|
||||
pthread_cond_destroy(&priv->cond);
|
||||
|
||||
#ifndef CONFIG_USBMSC_COMPOSITE
|
||||
/* For the case of the composite driver, there is a two pass
|
||||
* uninitialization sequence. We cannot yet free the driver structure.
|
||||
* We will do that on the second pass (and we will know that it is the
|
||||
* second pass because of priv->thread == 0)
|
||||
*/
|
||||
|
||||
kfree(priv);
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue