EHCI HCDs will now support cancellation of syncrhonous transfers

This commit is contained in:
Gregory Nutt 2015-05-11 11:43:31 -06:00
parent a2ad652509
commit 8ed11a374d
8 changed files with 95 additions and 32 deletions

View File

@ -4678,7 +4678,8 @@ static int efm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
* Name: efm32_cancel
*
* Description:
* Cancel a pending asynchronous transfer on an endpoint.
* Cancel a pending asynchronous transfer on an endpoint. Cancelled synchronous
* or asynchronous transfer will complete normally with the error -ESHUTDOWN.
*
* Input Parameters:
* drvr - The USB host driver instance obtained as a parameter from the call to

View File

@ -3224,7 +3224,8 @@ errout_with_sem:
* Name: lpc17_cancel
*
* Description:
* Cancel a pending asynchronous transfer on an endpoint.
* Cancel a pending asynchronous transfer on an endpoint. Cancelled synchronous
* or asynchronous transfer will complete normally with the error -ESHUTDOWN.
*
* Input Parameters:
* drvr - The USB host driver instance obtained as a parameter from the call to

View File

@ -3822,7 +3822,7 @@ static int lpc31_enumerate(FAR struct usbhost_connection_s *conn,
usbhost_trace2(EHCI_TRACE2_CLASSENUM_FAILED, hport->port + 1, -ret);
/* If this is a root hub port, then marking the hub port not connected will
* cause sam_wait() to return and we will try the connection again.
* cause lpc31_wait() to return and we will try the connection again.
*/
hport->connected = false;
@ -4475,7 +4475,8 @@ errout_with_sem:
* Name: lpc31_cancel
*
* Description:
* Cancel a pending asynchronous transfer on an endpoint.
* Cancel a pending asynchronous transfer on an endpoint. Cancelled synchronous
* or asynchronous transfer will complete normally with the error -ESHUTDOWN.
*
* Input Parameters:
* drvr - The USB host driver instance obtained as a parameter from the call to
@ -4494,8 +4495,11 @@ static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
struct lpc31_epinfo_s *epinfo = (struct lpc31_epinfo_s *)ep;
struct lpc31_qh_s *qh;
usbhost_asynch_t callback;
void *arg;
uint32_t *bp;
irqstate_t flags;
bool iocwait;
int ret;
DEBUGASSERT(epinfo);
@ -4507,15 +4511,21 @@ static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
lpc31_takesem(&g_ehci.exclsem);
/* If there is no asynchronous transfer in progress, then bail now */
/* Sample and reset all transfer termination information. This will prevent any
* callbacks from occurring while are performing the cancellation. The transfer
* may still be in progress, however, so this does not eliminate other DMA-
* related race conditions.
*/
flags = irqsave();
if (epinfo->callback == NULL)
{
ret = -EINVAL;
irqrestore(flags);
goto errout_with_sem;
}
callback = epinfo->callback;
arg = epinfo->arg;
iocwait = epinfo->iocwait;
epinfo->callback = NULL;
epinfo->arg = NULL;
epinfo->iocwait = false;
irqrestore(flags);
/* This will prevent any callbacks from occurring while are performing
* the cancellation. The transfer may still be in progress, however, so
@ -4549,7 +4559,8 @@ static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
/* Claim that we successfully cancelled the transfer */
return OK;
ret = OK;
goto exit_terminate;
}
}
break;
@ -4569,7 +4580,8 @@ static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
* cancelled the transfer.
*/
return OK;
ret = OK;
goto exit_terminate;
}
}
break;
@ -4602,6 +4614,27 @@ static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret);
}
/* Was there a pending synchronous transfer? */
exit_terminate:
epinfo->result = -ESHUTDOWN;
if (iocwait)
{
/* Yes... wake it up */
DEBUGASSERT(callback == NULL);
lpc31_givesem(&epinfo->iocsem);
}
/* No.. Is there a pending asynchronous transfer? */
else if (callback != NULL)
{
/* Yes.. perform the callback */
callback(arg, -ESHUTDOWN);
}
errout_with_sem:
lpc31_givesem(&g_ehci.exclsem);
return ret;

View File

@ -4302,7 +4302,8 @@ errout_with_sem:
* Name: sam_cancel
*
* Description:
* Cancel a pending asynchronous transfer on an endpoint.
* Cancel a pending asynchronous transfer on an endpoint. Cancelled synchronous
* or asynchronous transfer will complete normally with the error -ESHUTDOWN.
*
* Input Parameters:
* drvr - The USB host driver instance obtained as a parameter from the call to
@ -4321,8 +4322,11 @@ static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
struct sam_epinfo_s *epinfo = (struct sam_epinfo_s *)ep;
struct sam_qh_s *qh;
usbhost_asynch_t callback;
void *arg;
uint32_t *bp;
irqstate_t flags;
bool iocwait;
int ret;
DEBUGASSERT(epinfo);
@ -4334,23 +4338,20 @@ static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
sam_takesem(&g_ehci.exclsem);
/* If there is no asynchronous transfer in progress, then bail now */
/* Sample and reset all transfer termination information. This will prevent any
* callbacks from occurring while are performing the cancellation. The transfer
* may still be in progress, however, so this does not eliminate other DMA-
* related race conditions.
*/
flags = irqsave();
if (epinfo->callback == NULL)
{
ret = -EINVAL;
irqrestore(flags);
goto errout_with_sem;
}
/* This will prevent any callbacks from occurring while are performing
* the cancellation. The transfer may still be in progress, however, so
* this does not eliminate other DMA-related race conditions.
*/
callback = epinfo->callback;
arg = epinfo->arg;
iocwait = epinfo->iocwait;
epinfo->callback = NULL;
epinfo->arg = NULL;
epinfo->iocwait = false;
irqrestore(flags);
/* Handle the cancellation according to the type of the transfer */
@ -4376,7 +4377,8 @@ static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
/* Claim that we successfully cancelled the transfer */
return OK;
ret = OK;
goto exit_terminate;
}
}
break;
@ -4396,7 +4398,8 @@ static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
* cancelled the transfer.
*/
return OK;
ret = OK;
goto exit_terminate;
}
}
break;
@ -4429,6 +4432,27 @@ static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret);
}
/* Was there a pending synchronous transfer? */
exit_terminate:
epinfo->result = -ESHUTDOWN;
if (iocwait)
{
/* Yes... wake it up */
DEBUGASSERT(callback == NULL);
sam_givesem(&epinfo->iocsem);
}
/* No.. Is there a pending asynchronous transfer? */
else if (callback != NULL)
{
/* Yes.. perform the callback */
callback(arg, -ESHUTDOWN);
}
errout_with_sem:
sam_givesem(&g_ehci.exclsem);
return ret;

View File

@ -3605,7 +3605,8 @@ errout:
* Name: sam_cancel
*
* Description:
* Cancel a pending asynchronous transfer on an endpoint.
* Cancel a pending asynchronous transfer on an endpoint. Cancelled synchronous
* or asynchronous transfer will complete normally with the error -ESHUTDOWN.
*
* Input Parameters:
* drvr - The USB host driver instance obtained as a parameter from the call to

View File

@ -4610,7 +4610,8 @@ static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
* Name: stm32_cancel
*
* Description:
* Cancel a pending asynchronous transfer on an endpoint.
* Cancel a pending asynchronous transfer on an endpoint. Cancelled synchronous
* or asynchronous transfer will complete normally with the error -ESHUTDOWN.
*
* Input Parameters:
* drvr - The USB host driver instance obtained as a parameter from the call to

View File

@ -4610,7 +4610,8 @@ static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
* Name: stm32_cancel
*
* Description:
* Cancel a pending asynchronous transfer on an endpoint.
* Cancel a pending asynchronous transfer on an endpoint. Cancelled synchronous
* or asynchronous transfer will complete normally with the error -ESHUTDOWN.
*
* Input Parameters:
* drvr - The USB host driver instance obtained as a parameter from the call to

View File

@ -552,7 +552,8 @@
* Name: DRVR_CANCEL
*
* Description:
* Cancel a pending asynchronous transfer on an endpoint.
* Cancel a pending asynchronous transfer on an endpoint. Cancelled synchronous
* or asynchronous transfer will complete normally with the error -ESHUTDOWN.
*
* Input Parameters:
* drvr - The USB host driver instance obtained as a parameter from the call to