EHCI HCDs will now support cancellation of syncrhonous transfers
This commit is contained in:
parent
3f092b8f9c
commit
cac9879ad2
@ -4678,7 +4678,8 @@ static int efm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
|
|||||||
* Name: efm32_cancel
|
* Name: efm32_cancel
|
||||||
*
|
*
|
||||||
* Description:
|
* 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:
|
* Input Parameters:
|
||||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||||
|
@ -3224,7 +3224,8 @@ errout_with_sem:
|
|||||||
* Name: lpc17_cancel
|
* Name: lpc17_cancel
|
||||||
*
|
*
|
||||||
* Description:
|
* 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:
|
* Input Parameters:
|
||||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
* 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);
|
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
|
/* 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;
|
hport->connected = false;
|
||||||
@ -4475,7 +4475,8 @@ errout_with_sem:
|
|||||||
* Name: lpc31_cancel
|
* Name: lpc31_cancel
|
||||||
*
|
*
|
||||||
* Description:
|
* 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:
|
* Input Parameters:
|
||||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
* 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_epinfo_s *epinfo = (struct lpc31_epinfo_s *)ep;
|
||||||
struct lpc31_qh_s *qh;
|
struct lpc31_qh_s *qh;
|
||||||
|
usbhost_asynch_t callback;
|
||||||
|
void *arg;
|
||||||
uint32_t *bp;
|
uint32_t *bp;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
bool iocwait;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DEBUGASSERT(epinfo);
|
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);
|
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();
|
flags = irqsave();
|
||||||
if (epinfo->callback == NULL)
|
callback = epinfo->callback;
|
||||||
{
|
arg = epinfo->arg;
|
||||||
ret = -EINVAL;
|
iocwait = epinfo->iocwait;
|
||||||
irqrestore(flags);
|
|
||||||
goto errout_with_sem;
|
epinfo->callback = NULL;
|
||||||
}
|
epinfo->arg = NULL;
|
||||||
|
epinfo->iocwait = false;
|
||||||
|
irqrestore(flags);
|
||||||
|
|
||||||
/* This will prevent any callbacks from occurring while are performing
|
/* This will prevent any callbacks from occurring while are performing
|
||||||
* the cancellation. The transfer may still be in progress, however, so
|
* 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 */
|
/* Claim that we successfully cancelled the transfer */
|
||||||
|
|
||||||
return OK;
|
ret = OK;
|
||||||
|
goto exit_terminate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4569,7 +4580,8 @@ static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
|
|||||||
* cancelled the transfer.
|
* cancelled the transfer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return OK;
|
ret = OK;
|
||||||
|
goto exit_terminate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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);
|
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:
|
errout_with_sem:
|
||||||
lpc31_givesem(&g_ehci.exclsem);
|
lpc31_givesem(&g_ehci.exclsem);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -4302,7 +4302,8 @@ errout_with_sem:
|
|||||||
* Name: sam_cancel
|
* Name: sam_cancel
|
||||||
*
|
*
|
||||||
* Description:
|
* 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:
|
* Input Parameters:
|
||||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
* 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_epinfo_s *epinfo = (struct sam_epinfo_s *)ep;
|
||||||
struct sam_qh_s *qh;
|
struct sam_qh_s *qh;
|
||||||
|
usbhost_asynch_t callback;
|
||||||
|
void *arg;
|
||||||
uint32_t *bp;
|
uint32_t *bp;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
bool iocwait;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DEBUGASSERT(epinfo);
|
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);
|
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();
|
flags = irqsave();
|
||||||
if (epinfo->callback == NULL)
|
callback = epinfo->callback;
|
||||||
{
|
arg = epinfo->arg;
|
||||||
ret = -EINVAL;
|
iocwait = epinfo->iocwait;
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
epinfo->callback = NULL;
|
epinfo->callback = NULL;
|
||||||
epinfo->arg = NULL;
|
epinfo->arg = NULL;
|
||||||
|
epinfo->iocwait = false;
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
|
|
||||||
/* Handle the cancellation according to the type of the transfer */
|
/* 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 */
|
/* Claim that we successfully cancelled the transfer */
|
||||||
|
|
||||||
return OK;
|
ret = OK;
|
||||||
|
goto exit_terminate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4396,7 +4398,8 @@ static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
|
|||||||
* cancelled the transfer.
|
* cancelled the transfer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return OK;
|
ret = OK;
|
||||||
|
goto exit_terminate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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);
|
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:
|
errout_with_sem:
|
||||||
sam_givesem(&g_ehci.exclsem);
|
sam_givesem(&g_ehci.exclsem);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -3605,7 +3605,8 @@ errout:
|
|||||||
* Name: sam_cancel
|
* Name: sam_cancel
|
||||||
*
|
*
|
||||||
* Description:
|
* 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:
|
* Input Parameters:
|
||||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
* 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
|
* Name: stm32_cancel
|
||||||
*
|
*
|
||||||
* Description:
|
* 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:
|
* Input Parameters:
|
||||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
* 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
|
* Name: stm32_cancel
|
||||||
*
|
*
|
||||||
* Description:
|
* 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:
|
* Input Parameters:
|
||||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||||
|
Loading…
Reference in New Issue
Block a user