From 11b79e6714eeaff0cf0c30b4c46a5e6e985ad4f2 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 11 May 2015 12:12:19 -0600 Subject: [PATCH] EHCI HCDs: Check for transfer in progress before attempting cancellation --- arch/arm/src/lpc31xx/lpc31_ehci.c | 23 +++++++++++++++++++---- arch/arm/src/sama5/sam_ehci.c | 23 +++++++++++++++++++---- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/arch/arm/src/lpc31xx/lpc31_ehci.c b/arch/arm/src/lpc31xx/lpc31_ehci.c index 719c5715c19..b92f80a4fac 100644 --- a/arch/arm/src/lpc31xx/lpc31_ehci.c +++ b/arch/arm/src/lpc31xx/lpc31_ehci.c @@ -4541,6 +4541,18 @@ static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) epinfo->arg = NULL; irqrestore(flags); + /* Bail if there is no transfer in progress for this endpoint */ + +#ifdef CONFIG_USBHOST_ASYNCH + if (callback == NULL && !iocwait) +#else + if (!iocwait) +#endif + { + ret = OK; + goto errout_with_sem; + } + /* Handle the cancellation according to the type of the transfer */ switch (epinfo->xfrtype) @@ -4623,25 +4635,28 @@ static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) exit_terminate: epinfo->result = -ESHUTDOWN; +#ifdef CONFIG_USBHOST_ASYNCH if (iocwait) { /* Yes... wake it up */ -#ifdef CONFIG_USBHOST_ASYNCH DEBUGASSERT(callback == NULL); -#endif lpc31_givesem(&epinfo->iocsem); } -#ifdef CONFIG_USBHOST_ASYNCH /* No.. Is there a pending asynchronous transfer? */ - else if (callback != NULL) + else /* if (callback != NULL) */ { /* Yes.. perform the callback */ callback(arg, -ESHUTDOWN); } + +#else + /* Wake up the waiting thread */ + + sam_givesem(&epinfo->iocsem); #endif errout_with_sem: diff --git a/arch/arm/src/sama5/sam_ehci.c b/arch/arm/src/sama5/sam_ehci.c index f9688d7a562..e1acab370ec 100644 --- a/arch/arm/src/sama5/sam_ehci.c +++ b/arch/arm/src/sama5/sam_ehci.c @@ -4359,6 +4359,18 @@ static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) epinfo->iocwait = false; irqrestore(flags); + /* Bail if there is no transfer in progress for this endpoint */ + +#ifdef CONFIG_USBHOST_ASYNCH + if (callback == NULL && !iocwait) +#else + if (!iocwait) +#endif + { + ret = OK; + goto errout_with_sem; + } + /* Handle the cancellation according to the type of the transfer */ switch (epinfo->xfrtype) @@ -4441,25 +4453,28 @@ static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) exit_terminate: epinfo->result = -ESHUTDOWN; +#ifdef CONFIG_USBHOST_ASYNCH if (iocwait) { /* Yes... wake it up */ -#ifdef CONFIG_USBHOST_ASYNCH DEBUGASSERT(callback == NULL); -#endif sam_givesem(&epinfo->iocsem); } -#ifdef CONFIG_USBHOST_ASYNCH /* No.. Is there a pending asynchronous transfer? */ - else if (callback != NULL) + else /* if (callback != NULL) */ { /* Yes.. perform the callback */ callback(arg, -ESHUTDOWN); } + +#else + /* Wake up the waiting thread */ + + sam_givesem(&epinfo->iocsem); #endif errout_with_sem: