EHCI HCDs will now support cancellation of syncrhonous transfers
This commit is contained in:
parent
a2ad652509
commit
8ed11a374d
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user