diff --git a/arch/arm/src/sama5/sam_ohci.c b/arch/arm/src/sama5/sam_ohci.c index ab4b90e55c..d4e195aad3 100644 --- a/arch/arm/src/sama5/sam_ohci.c +++ b/arch/arm/src/sama5/sam_ohci.c @@ -2579,6 +2579,14 @@ static int sam_ep0configure(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, usbhost_vtrace2(OHCI_VTRACE2_EP0CONFIG, speed, funcaddr); DEBUGASSERT(rhport && maxpacketsize < 2048); + /* Expect the device to be unplugged during enumeration */ + + if (!ep0list || !ep0list->ed) + { + _err("Device was probably removed\n"); + return -ENOMEM; + } + edctrl = ep0list->ed; /* We must have exclusive access to EP0 and the control list */ @@ -3899,20 +3907,18 @@ static void sam_disconnect(struct usbhost_driver_s *drvr, DEBUGASSERT(rhport != NULL && hport != NULL && hport->ep0); ep0 = (struct sam_eplist_s *)hport->ep0; - /* Remove the disconnected port from the control list */ - - sam_ep0dequeue(ep0); - - /* Did we just dequeue EP0 from a hoot hub port? */ + /* Did we just dequeue EP0 from a root hub port? */ if (ROOTHUB(hport)) { + /* Remove the disconnected port from the control list */ + + sam_ep0dequeue(ep0); rhport->ep0init = false; } /* Unbind the class from the port */ - hport->ep0 = NULL; hport->devclass = NULL; } diff --git a/drivers/usbhost/usbhost_hub.c b/drivers/usbhost/usbhost_hub.c index a83fb95d9a..98f3f52705 100644 --- a/drivers/usbhost/usbhost_hub.c +++ b/drivers/usbhost/usbhost_hub.c @@ -965,12 +965,34 @@ static void usbhost_hub_event(FAR void *arg) if (connport->devclass != NULL) { CLASS_DISCONNECTED(connport->devclass); - connport->devclass = NULL; + + if (connport->devclass->connect == usbhost_connect) + { + /* For hubs, the usbhost_disconnect_event function + * (triggered by the CLASS_DISCONNECTED call above) + * will call usbhost_hport_deactivate for us. We + * prevent a crash when a hub is unplugged by skipping + * the second unnecessary usbhost_hport_deactivated + * call here. + */ + + connport->devclass = NULL; + } + else + { + connport->devclass = NULL; + + /* Free any resources used by the hub port */ + + usbhost_hport_deactivate(connport); + } } + else + { + /* Free any resources used by the hub port */ - /* Free any resources used by the hub port */ - - usbhost_hport_deactivate(connport); + usbhost_hport_deactivate(connport); + } } } else if (change)