Fixes some crashes when the hub is removed and/or reinserted

This commit is contained in:
Gregory Nutt 2015-04-25 12:16:22 -06:00
parent 38e0a4a1cb
commit e46cb394f9
2 changed files with 23 additions and 16 deletions

View File

@ -3105,7 +3105,7 @@ static int lpc17_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
/* We really need some kind of atomic test and set to do this right */
td = (struct lpc17_gtd_s *)ed->hw.headp;
td = (struct lpc17_gtd_s *)(ed->hw.headp & ED_HEADP_ADDR_MASK);
ed->hw.headp = LPC17_TDTAIL_ADDR;
ed->asynch = NULL;

View File

@ -221,25 +221,26 @@ static void usbhost_hport_deactivate(FAR struct usbhost_hubport_s *hport)
{
uvdbg("Deactivating: %d\n", hport->port);
/* Don't deactivate root hub ports! */
/* Don't free the control pipe of root hub ports! */
if (!ROOTHUB(hport))
if (!ROOTHUB(hport) && hport->ep0 != NULL)
{
/* Free the control endpoint */
if (hport->ep0 != NULL)
{
DRVR_EPFREE(hport->drvr, hport->ep0);
hport->ep0 = NULL;
}
/* Free the function address if one has been assigned */
usbhost_devaddr_destroy(hport, hport->funcaddr);
hport->funcaddr = 0;
DEBUGASSERT(hport->devclass == NULL);
DRVR_EPFREE(hport->drvr, hport->ep0);
hport->ep0 = NULL;
}
/* Free the function address if one has been assigned */
usbhost_devaddr_destroy(hport, hport->funcaddr);
hport->funcaddr = 0;
/* If this is a downstream hub port, then there should be no class driver
* associated wit it.
*/
DEBUGASSERT(ROOTHUB(hport) || hport->devclass == NULL);
}
/****************************************************************************
@ -1398,13 +1399,19 @@ static int usbhost_connect(FAR struct usbhost_class_s *hubclass,
static int usbhost_disconnected(struct usbhost_class_s *hubclass)
{
FAR struct usbhost_hubpriv_s *priv;
FAR struct usbhost_hubport_s *hport;
irqstate_t flags;
int ret;
/* Execute the disconnect action from the worker thread. */
DEBUGASSERT(hubclass != NULL);
DEBUGASSERT(hubclass != NULL && hubclass->hport != NULL);
priv = &((FAR struct usbhost_hubclass_s *)hubclass)->hubpriv;
hport = hubclass->hport;
/* Cancel any pending transfers on the interrupt IN pipe */
DRVR_CANCEL(hport->drvr, priv->intin);
/* NOTE: There may be pending HUB work associated with hub interrupt
* pipe events. That work may be overwritten and lost by this action.