STM32 and EFM32 host will now support cancellation of synchronous methods

This commit is contained in:
Gregory Nutt 2015-05-11 11:15:28 -06:00
parent 102554adfe
commit 3f092b8f9c
5 changed files with 133 additions and 0 deletions

View File

@ -4696,11 +4696,14 @@ static int efm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
static int efm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr;
FAR struct efm32_chan_s *chan;
unsigned int chidx = (unsigned int)ep;
irqstate_t flags;
uvdbg("chidx: %u: %d\n", chidx);
DEBUGASSERT(priv && chidx < EFM32_MAX_TX_FIFOS);
chan = &priv->chan[chidx];
/* We must have exclusive access to the USB host hardware and state structures.
* And when we have that, we need to disable interrupts to avoid race conditions
@ -4713,6 +4716,44 @@ static int efm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
/* Halt the channel */
efm32_chan_halt(priv, chidx, CHREASON_CANCELLED);
chan->result = -ESHUTDOWN;
/* Is there a thread waiting for this transfer to complete? */
if (chan->waiter)
{
/* Yes.. there should not also be a callback scheduled */
DEBUGASSERT(chan->callback == NULL);
/* Wake'em up! */
efm32_givesem(&chan->waitsem);
chan->waiter = false;
}
/* No.. is an asynchronous callback expected when the transfer
* completes?
*/
else if (chan->callback)
{
usbhost_asynch_t callback;
FAR void *arg;
/* Extract the callback information */
callback = chan->callback;
arg = chan->arg;
chan->callback = NULL;
chan->arg = NULL;
chan->xfrd = 0;
/* Then perform the callback */
callback(arg, -ESHUTDOWN);
}
irqrestore(flags);
efm32_givesem(&priv->exclsem);

View File

@ -3289,6 +3289,10 @@ static int lpc17_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
if (xfrinfo->wdhwait)
{
/* Yes.. there should not also be a callback scheduled */
DEBUGASSERT(xfrinfo->callback == NULL);
/* Wake up the waiting thread */
lpc17_givesem(&ed->wdhsem);

View File

@ -3669,6 +3669,12 @@ static int sam_cancel(struct usbhost_driver_s *drvr, usbhost_ep_t ep)
if (eplist->wdhwait)
{
/* Yes.. there should not also be a callback scheduled */
DEBUGASSERT(eplist->callback == NULL);
/* Wake up the waiting thread */
sam_givesem(&eplist->wdhsem);
eplist->wdhwait = false;
}

View File

@ -4628,11 +4628,14 @@ static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
FAR struct stm32_chan_s *chan;
unsigned int chidx = (unsigned int)ep;
irqstate_t flags;
uvdbg("chidx: %u: %d\n", chidx);
DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS);
chan = &priv->chan[chidx];
/* We must have exclusive access to the USB host hardware and state structures.
* And when we have that, we need to disable interrupts to avoid race conditions
@ -4645,6 +4648,44 @@ static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
/* Halt the channel */
stm32_chan_halt(priv, chidx, CHREASON_CANCELLED);
chan->result = -ESHUTDOWN;
/* Is there a thread waiting for this transfer to complete? */
if (chan->waiter)
{
/* Yes.. there should not also be a callback scheduled */
DEBUGASSERT(chan->callback == NULL);
/* Wake'em up! */
stm32_givesem(&chan->waitsem);
chan->waiter = false;
}
/* No.. is an asynchronous callback expected when the transfer
* completes?
*/
else if (chan->callback)
{
usbhost_asynch_t callback;
FAR void *arg;
/* Extract the callback information */
callback = chan->callback;
arg = chan->arg;
chan->callback = NULL;
chan->arg = NULL;
chan->xfrd = 0;
/* Then perform the callback */
callback(arg, -ESHUTDOWN);
}
irqrestore(flags);
stm32_givesem(&priv->exclsem);

View File

@ -4628,11 +4628,14 @@ static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
FAR struct stm32_chan_s *chan;
unsigned int chidx = (unsigned int)ep;
irqstate_t flags;
uvdbg("chidx: %u: %d\n", chidx);
DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS);
chan = &priv->chan[chidx];
/* We must have exclusive access to the USB host hardware and state structures.
* And when we have that, we need to disable interrupts to avoid race conditions
@ -4645,6 +4648,44 @@ static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
/* Halt the channel */
stm32_chan_halt(priv, chidx, CHREASON_CANCELLED);
chan->result = -ESHUTDOWN;
/* Is there a thread waiting for this transfer to complete? */
if (chan->waiter)
{
/* Yes.. there should not also be a callback scheduled */
DEBUGASSERT(chan->callback == NULL);
/* Wake'em up! */
stm32_givesem(&chan->waitsem);
chan->waiter = false;
}
/* No.. is an asynchronous callback expected when the transfer
* completes?
*/
else if (chan->callback)
{
usbhost_asynch_t callback;
FAR void *arg;
/* Extract the callback information */
callback = chan->callback;
arg = chan->arg;
chan->callback = NULL;
chan->arg = NULL;
chan->xfrd = 0;
/* Then perform the callback */
callback(arg, -ESHUTDOWN);
}
irqrestore(flags);
stm32_givesem(&priv->exclsem);