STM32 and EFM32 host will now support cancellation of synchronous methods
This commit is contained in:
parent
7a3fafb67f
commit
a2ad652509
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user