diff --git a/arch/arm/src/efm32/efm32_usbhost.c b/arch/arm/src/efm32/efm32_usbhost.c index c73764d4bc..bbe69d78a2 100644 --- a/arch/arm/src/efm32/efm32_usbhost.c +++ b/arch/arm/src/efm32/efm32_usbhost.c @@ -467,7 +467,8 @@ static int efm32_connect(FAR struct usbhost_driver_s *drvr, FAR struct usbhost_hubport_s *hport, bool connected); #endif -static void efm32_disconnect(FAR struct usbhost_driver_s *drvr); +static void efm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); /* Initialization **************************************************************/ @@ -4761,12 +4762,13 @@ static int efm32_connect(FAR struct usbhost_driver_s *drvr, * *******************************************************************************/ -static void efm32_disconnect(FAR struct usbhost_driver_s *drvr) +static void efm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) { FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr; - DEBUGASSERT(priv); + DEBUGASSERT(priv != NULL && hport != NULL); - priv->rhport.hport.devclass = NULL; + hport->devclass = NULL; } /******************************************************************************* diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c index 567e9aafbe..351e78d42d 100644 --- a/arch/arm/src/lpc17xx/lpc17_usbhost.c +++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c @@ -390,7 +390,8 @@ static int lpc17_connect(FAR struct usbhost_driver_s *drvr, FAR struct usbhost_hubport_s *hport, bool connected); #endif -static void lpc17_disconnect(struct usbhost_driver_s *drvr); +static void lpc17_disconnect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport); /* Initialization **************************************************************/ @@ -3213,6 +3214,8 @@ static int lpc17_connect(FAR struct usbhost_driver_s *drvr, * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. * * Returned Values: * None @@ -3223,12 +3226,13 @@ static int lpc17_connect(FAR struct usbhost_driver_s *drvr, * *******************************************************************************/ -static void lpc17_disconnect(struct usbhost_driver_s *drvr) +static void lpc17_disconnect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport) { struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; - DEBUGASSERT(priv); + DEBUGASSERT(priv != NULL && hport != NULL); - priv->rhport.hport.devclass = NULL; + hport->devclass = NULL; } /******************************************************************************* diff --git a/arch/arm/src/lpc31xx/lpc31_ehci.c b/arch/arm/src/lpc31xx/lpc31_ehci.c index 073fe6e76c..e74cc1c2f6 100644 --- a/arch/arm/src/lpc31xx/lpc31_ehci.c +++ b/arch/arm/src/lpc31xx/lpc31_ehci.c @@ -549,7 +549,8 @@ static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); static int lpc31_connect(FAR struct usbhost_driver_s *drvr, FAR struct usbhost_hubport_s *hport, bool connected); #endif -static void lpc31_disconnect(FAR struct usbhost_driver_s *drvr); +static void lpc31_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); /* Initialization **************************************************************/ @@ -4638,6 +4639,8 @@ static int lpc31_connect(FAR struct usbhost_driver_s *drvr, * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. * * Returned Values: * None @@ -4648,15 +4651,16 @@ static int lpc31_connect(FAR struct usbhost_driver_s *drvr, * *******************************************************************************/ -static void lpc31_disconnect(FAR struct usbhost_driver_s *drvr) +static void lpc31_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) { struct lpc31_rhport_s *rhport = (struct lpc31_rhport_s *)drvr; - DEBUGASSERT(rhport); + DEBUGASSERT(rhport != NULL && hport != NULL); /* Unbind the class */ /* REVISIT: Is there more that needs to be done? */ - rhport->hport.hport.devclass = NULL; + hport->devclass = NULL; } /******************************************************************************* diff --git a/arch/arm/src/sama5/sam_ehci.c b/arch/arm/src/sama5/sam_ehci.c index 280d9b93ae..bf6d9a9e88 100644 --- a/arch/arm/src/sama5/sam_ehci.c +++ b/arch/arm/src/sama5/sam_ehci.c @@ -425,7 +425,8 @@ static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); static int sam_connect(FAR struct usbhost_driver_s *drvr, FAR struct usbhost_hubport_s *hport, bool connected); #endif -static void sam_disconnect(FAR struct usbhost_driver_s *drvr); +static void sam_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); /* Initialization **************************************************************/ @@ -4464,6 +4465,8 @@ static int sam_connect(FAR struct usbhost_driver_s *drvr, * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. * * Returned Values: * None @@ -4474,10 +4477,11 @@ static int sam_connect(FAR struct usbhost_driver_s *drvr, * *******************************************************************************/ -static void sam_disconnect(FAR struct usbhost_driver_s *drvr) +static void sam_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) { struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; - DEBUGASSERT(rhport); + DEBUGASSERT(rhport != NULL && hport != NULL); /* Unbind the class */ /* REVISIT: Is there more that needs to be done? */ diff --git a/arch/arm/src/sama5/sam_ohci.c b/arch/arm/src/sama5/sam_ohci.c index 1bd442fdbe..83f2d1dafa 100644 --- a/arch/arm/src/sama5/sam_ohci.c +++ b/arch/arm/src/sama5/sam_ohci.c @@ -388,7 +388,7 @@ static int sam_enqueuetd(struct sam_rhport_s *rhport, struct sam_eplist_s *eplis struct sam_ed_s *ed, uint32_t dirpid, uint32_t toggle, volatile uint8_t *buffer, size_t buflen); static int sam_ep0enqueue(struct sam_rhport_s *rhport); -static void sam_ep0dequeue(struct sam_rhport_s *rhport); +static void sam_ep0dequeue(struct sam_eplist_s *ep0); static int sam_wdhwait(struct sam_rhport_s *rhport, struct sam_ed_s *ed); #ifdef CONFIG_USBHOST_ASYNCH static int sam_wdhasynch(struct sam_rhport_s *rhport, struct sam_ed_s *ed, @@ -448,7 +448,8 @@ static int sam_connect(struct usbhost_driver_s *drvr, struct usbhost_hubport_s *hport, bool connected); #endif -static void sam_disconnect(struct usbhost_driver_s *drvr); +static void sam_disconnect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport); /******************************************************************************* * Private Data @@ -1520,8 +1521,8 @@ static int sam_enqueuetd(struct sam_rhport_s *rhport, struct sam_eplist_s *eplis * Name: sam_ep0enqueue * * Description: - * Initialize ED for EP0, add it to the control ED list, and enable control - * transfers. + * Initialize ED for a root hub EP0, add it to the control ED list, and + * enable control transfers. * * Input Parameters: * rhpndx - Root hub port index. @@ -1609,14 +1610,15 @@ static int sam_ep0enqueue(struct sam_rhport_s *rhport) * list processing. * * Input Parameters: - * rhpndx - Root hub port index. + * ep0 - The control endpoint to be released. May be the control endpoint for + * an attached hub. * * Returned Values: * None * *******************************************************************************/ -static void sam_ep0dequeue(struct sam_rhport_s *rhport) +static void sam_ep0dequeue(struct sam_eplist_s *ep0) { struct sam_ed_s *edctrl; struct sam_ed_s *curred; @@ -1627,8 +1629,7 @@ static void sam_ep0dequeue(struct sam_rhport_s *rhport) uintptr_t physcurr; uint32_t regval; - DEBUGASSERT(rhport && rhport->ep0init && rhport->ep0.ed != NULL && - rhport->ep0.tail != NULL); + DEBUGASSERT(ep0->ed != NULL && ep0->tail != NULL); /* ControlListEnable. This bit is cleared to disable the processing of the * Control list. We should never modify the control list while CLE is set. @@ -1643,7 +1644,7 @@ static void sam_ep0dequeue(struct sam_rhport_s *rhport) * precedessor). */ - edctrl = rhport->ep0.ed; + edctrl = ep0->ed; physcurr = sam_getreg(SAM_USBHOST_CTRLHEADED); for (curred = (struct sam_ed_s *)sam_virtramaddr(physcurr), @@ -1692,7 +1693,7 @@ static void sam_ep0dequeue(struct sam_rhport_s *rhport) /* Release any TDs that may still be attached to the ED. */ - tdtail = rhport->ep0.tail; + tdtail = ep0->tail; physcurr = edctrl->hw.headp; for (currtd = (struct sam_gtd_s *)sam_virtramaddr(physcurr); @@ -1708,8 +1709,8 @@ static void sam_ep0dequeue(struct sam_rhport_s *rhport) sam_tdfree(tdtail); sam_edfree(edctrl); - rhport->ep0.ed = NULL; - rhport->ep0.tail = NULL; + ep0->ed = NULL; + ep0->tail = NULL; } /******************************************************************************* @@ -2408,7 +2409,7 @@ static int sam_rh_enumerate(struct usbhost_connection_s *conn, return -ENODEV; } - /* Add EP0 to the control list */ + /* Add root hub EP0 to the control list */ if (!rhport->ep0init) { @@ -3659,6 +3660,8 @@ static int sam_connect(struct usbhost_driver_s *drvr, * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. * * Returned Values: * None @@ -3669,19 +3672,29 @@ static int sam_connect(struct usbhost_driver_s *drvr, * *******************************************************************************/ -static void sam_disconnect(struct usbhost_driver_s *drvr) +static void sam_disconnect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport) { struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; - DEBUGASSERT(rhport); + struct sam_eplist_s *ep0; + + DEBUGASSERT(rhport != NULL && hport != NULL && hport->ep0); + ep0 = (struct sam_eplist_s *)hport->ep0; /* Remove the disconnected port from the control list */ - sam_ep0dequeue(rhport); - rhport->ep0init = false; + sam_ep0dequeue(ep0); - /* Unbind the class */ + /* Did we just dequeue EP0 from a hoot hub port? */ - rhport->hport.hport.devclass = NULL; + if (ROOTHUB(hport)) + { + rhport->ep0init = false; + } + + /* Unbind the class from the port */ + + hport->devclass = NULL; } /******************************************************************************* diff --git a/arch/arm/src/stm32/stm32_otgfshost.c b/arch/arm/src/stm32/stm32_otgfshost.c index c030241169..ab5455d643 100644 --- a/arch/arm/src/stm32/stm32_otgfshost.c +++ b/arch/arm/src/stm32/stm32_otgfshost.c @@ -454,7 +454,8 @@ static int stm32_connect(FAR struct usbhost_driver_s *drvr, FAR struct usbhost_hubport_s *hport, bool connected); #endif -static void stm32_disconnect(FAR struct usbhost_driver_s *drvr); +static void stm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); /* Initialization **************************************************************/ @@ -4684,6 +4685,8 @@ static int stm32_connect(FAR struct usbhost_driver_s *drvr, * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. * * Returned Values: * None @@ -4694,12 +4697,13 @@ static int stm32_connect(FAR struct usbhost_driver_s *drvr, * *******************************************************************************/ -static void stm32_disconnect(FAR struct usbhost_driver_s *drvr) +static void stm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) { FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; - DEBUGASSERT(priv); + DEBUGASSERT(priv != NULL && hport != NULL); - priv->rhport.hport.devclass = NULL; + hport->devclass = NULL; } /******************************************************************************* diff --git a/arch/arm/src/stm32/stm32_otghshost.c b/arch/arm/src/stm32/stm32_otghshost.c index e85105dc23..2bc898442f 100644 --- a/arch/arm/src/stm32/stm32_otghshost.c +++ b/arch/arm/src/stm32/stm32_otghshost.c @@ -454,7 +454,8 @@ static int stm32_connect(FAR struct usbhost_driver_s *drvr, FAR struct usbhost_hubport_s *hport, bool connected); #endif -static void stm32_disconnect(FAR struct usbhost_driver_s *drvr); +static void stm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); /* Initialization **************************************************************/ @@ -4684,6 +4685,8 @@ static int stm32_connect(FAR struct usbhost_driver_s *drvr, * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. * * Returned Values: * None @@ -4694,12 +4697,13 @@ static int stm32_connect(FAR struct usbhost_driver_s *drvr, * *******************************************************************************/ -static void stm32_disconnect(FAR struct usbhost_driver_s *drvr) +static void stm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) { FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; - DEBUGASSERT(priv); + DEBUGASSERT(priv != NULL && hport != NULL); - priv->rhport.hport.devclass = NULL; + hport->devclass = NULL; } /*******************************************************************************