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 7a3fafb67f
commit a2ad652509
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) 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_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr;
FAR struct efm32_chan_s *chan;
unsigned int chidx = (unsigned int)ep; unsigned int chidx = (unsigned int)ep;
irqstate_t flags; irqstate_t flags;
uvdbg("chidx: %u: %d\n", chidx); uvdbg("chidx: %u: %d\n", chidx);
DEBUGASSERT(priv && chidx < EFM32_MAX_TX_FIFOS); DEBUGASSERT(priv && chidx < EFM32_MAX_TX_FIFOS);
chan = &priv->chan[chidx];
/* We must have exclusive access to the USB host hardware and state structures. /* 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 * 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 */ /* Halt the channel */
efm32_chan_halt(priv, chidx, CHREASON_CANCELLED); 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); irqrestore(flags);
efm32_givesem(&priv->exclsem); 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) if (xfrinfo->wdhwait)
{ {
/* Yes.. there should not also be a callback scheduled */
DEBUGASSERT(xfrinfo->callback == NULL);
/* Wake up the waiting thread */ /* Wake up the waiting thread */
lpc17_givesem(&ed->wdhsem); 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) 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); sam_givesem(&eplist->wdhsem);
eplist->wdhwait = false; 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) 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_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
FAR struct stm32_chan_s *chan;
unsigned int chidx = (unsigned int)ep; unsigned int chidx = (unsigned int)ep;
irqstate_t flags; irqstate_t flags;
uvdbg("chidx: %u: %d\n", chidx); uvdbg("chidx: %u: %d\n", chidx);
DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS); DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS);
chan = &priv->chan[chidx];
/* We must have exclusive access to the USB host hardware and state structures. /* 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 * 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 */ /* Halt the channel */
stm32_chan_halt(priv, chidx, CHREASON_CANCELLED); 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); irqrestore(flags);
stm32_givesem(&priv->exclsem); 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) 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_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
FAR struct stm32_chan_s *chan;
unsigned int chidx = (unsigned int)ep; unsigned int chidx = (unsigned int)ep;
irqstate_t flags; irqstate_t flags;
uvdbg("chidx: %u: %d\n", chidx); uvdbg("chidx: %u: %d\n", chidx);
DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS); DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS);
chan = &priv->chan[chidx];
/* We must have exclusive access to the USB host hardware and state structures. /* 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 * 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 */ /* Halt the channel */
stm32_chan_halt(priv, chidx, CHREASON_CANCELLED); 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); irqrestore(flags);
stm32_givesem(&priv->exclsem); stm32_givesem(&priv->exclsem);