STM32/EFM32 USB host: Implemented asynchronous cancel method

This commit is contained in:
Gregory Nutt 2015-04-30 11:24:18 -06:00
parent 2e27ff4d9e
commit 20b818ef1a
3 changed files with 75 additions and 12 deletions

View File

@ -185,7 +185,8 @@ enum efm32_chreason_e
CHREASON_STALL, /* Endpoint stalled */
CHREASON_TXERR, /* Transfer error received */
CHREASON_DTERR, /* Data toggle error received */
CHREASON_FRMOR /* Frame overrun */
CHREASON_FRMOR, /* Frame overrun */
CHREASON_CANCELLED /* Transfer cancelled */
};
/* This structure retains the state of one host channel. NOTE: Since there
@ -4546,9 +4547,29 @@ static int efm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
#ifdef CONFIG_USBHOST_ASYNCH
static int efm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
# error Missing logic
return -ENOSYS;
}
FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr;
unsigned int chidx = (unsigned int)ep;
irqstate_t flags;
uvdbg("chidx: %u: %d\n", chidx);
DEBUGASSERT(priv && chidx < EFM32_MAX_TX_FIFOS);
/* 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
* with the asynchronous completion of the transfer being cancelled.
*/
efm32_takesem(&priv->exclsem);
flags = irqsave();
/* Halt the channel */
efm32_chan_halt(priv, chidx, CHREASON_CANCELLED);
irqrestore(flags);
efm32_givesem(&priv->exclsem);
return OK;
}
#endif /* CONFIG_USBHOST_ASYNCH */
/************************************************************************************

View File

@ -192,7 +192,8 @@ enum stm32_chreason_e
CHREASON_STALL, /* Endpoint stalled */
CHREASON_TXERR, /* Transfer error received */
CHREASON_DTERR, /* Data toggle error received */
CHREASON_FRMOR /* Frame overrun */
CHREASON_FRMOR, /* Frame overrun */
CHREASON_CANCELLED /* Transfer cancelled */
};
/* This structure retains the state of one host channel. NOTE: Since there
@ -4594,9 +4595,29 @@ static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
#ifdef CONFIG_USBHOST_ASYNCH
static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
# error Missing logic
return -ENOSYS;
}
FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
unsigned int chidx = (unsigned int)ep;
irqstate_t flags;
uvdbg("chidx: %u: %d\n", chidx);
DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS);
/* 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
* with the asynchronous completion of the transfer being cancelled.
*/
stm32_takesem(&priv->exclsem);
flags = irqsave();
/* Halt the channel */
stm32_chan_halt(priv, chidx, CHREASON_CANCELLED);
irqrestore(flags);
stm32_givesem(&priv->exclsem);
return OK;
}
#endif /* CONFIG_USBHOST_ASYNCH */
/************************************************************************************

View File

@ -192,7 +192,8 @@ enum stm32_chreason_e
CHREASON_STALL, /* Endpoint stalled */
CHREASON_TXERR, /* Transfer error received */
CHREASON_DTERR, /* Data toggle error received */
CHREASON_FRMOR /* Frame overrun */
CHREASON_FRMOR, /* Frame overrun */
CHREASON_CANCELLED /* Transfer cancelled */
};
/* This structure retains the state of one host channel. NOTE: Since there
@ -4594,9 +4595,29 @@ static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
#ifdef CONFIG_USBHOST_ASYNCH
static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
# error Missing logic
return -ENOSYS;
}
FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
unsigned int chidx = (unsigned int)ep;
irqstate_t flags;
uvdbg("chidx: %u: %d\n", chidx);
DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS);
/* 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
* with the asynchronous completion of the transfer being cancelled.
*/
stm32_takesem(&priv->exclsem);
flags = irqsave();
/* Halt the channel */
stm32_chan_halt(priv, chidx, CHREASON_CANCELLED);
irqrestore(flags);
stm32_givesem(&priv->exclsem);
return OK;
}
#endif /* CONFIG_USBHOST_ASYNCH */
/************************************************************************************