You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by "chenzhihong007 (via GitHub)" <gi...@apache.org> on 2023/09/25 05:56:34 UTC
[GitHub] [nuttx] chenzhihong007 opened a new issue, #10802: usb host: cdcacm: IN transition failure
chenzhihong007 opened a new issue, #10802:
URL: https://github.com/apache/nuttx/issues/10802
## Issue Description
When usb as host to connect cdcacm device, using read() API to get data from cdcacm device many times, EHCI driver, such as **sam_transfer() - sam_ioc_setup()**, will trigger assert in **sam_ioc_setup()**, because **epinfo->iocwait** is true.
``` c
DEBUGASSERT(rhport && epinfo && !epinfo->iocwait);
```
## Analysis
read() API caller as follows:
read() - uart_read() - uart_disablerxint()【usbhost_rxint()】 - uart_enablerxint()【usbhost_rxint()】 - usbhost_rxdata_work() - DRVR_TRANSFER()【sam_transfer()】.
In **usbhost_rxdata_work()**, while loop call **DRVR_TRANSFER()【sam_transfer()】** to excute usb IN transition. DRVR_TRANSFER() is a blocking method, this functions will not return until the transfer has completed, the comments as follows:
```
* Name: sam_transfer
*
* Description:
* Process a request to handle a transfer descriptor. This method will
* enqueue the transfer request, blocking until the transfer completes.
* Only one transfer may be queued; Neither this method nor the ctrlin or
* ctrlout methods can be called again until this function returns.
*
* This is a blocking method; this functions will not return until the
* transfer has completed.
```
But every read() operation, call uart_disablerxint() first, then call uart_enablerxint(). So excute read() one time, call DRVR_TRANSFER() one time, even DRVR_TRANSFER() in progress or not finish. Thus will cause usb transfer abnormal, such as **epinfo->iocwait** is true.
## Solution
I have two sulution ideas.
- fix uart_read() logic,delete serial.c 986 line —— uart_disablerxint(dev).
- fix usbhost_rxint() logic, cancel disable opertion. When rx is enabled, keep **priv->rxena** always enable.
```
static void usbhost_rxint(FAR struct uart_dev_s *uartdev, bool enable)
{
FAR struct usbhost_cdcacm_s *priv;
int ret;
DEBUGASSERT(uartdev && uartdev->priv);
priv = (FAR struct usbhost_cdcacm_s *)uartdev->priv;
/* Are we enabling or disabling RX reception? */
if (enable && !priv->rxena)
{
/* Cancel any pending, delayed RX data reception work */
work_cancel(LPWORK, &priv->rxwork);
/* Restart immediate RX data reception work (unless RX flow control
* is in effect.
*/
#ifdef CONFIG_SERIAL_IFLOWCONTROL
if (priv->rts)
#endif
{
ret = work_queue(LPWORK, &priv->rxwork,
usbhost_rxdata_work, priv, 0);
DEBUGASSERT(ret >= 0);
UNUSED(ret);
}
/* Save the new RX enable state */
priv->rxena = enable;
}
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] usb host: cdcacm: IN transition failure [nuttx]
Posted by "acassis (via GitHub)" <gi...@apache.org>.
acassis commented on issue #10802:
URL: https://github.com/apache/nuttx/issues/10802#issuecomment-1749389825
@chenzhihong007 I think the second option is safer because modifying serial.c will impact in name drivers, but modify usbhost_rxint() only will affect the CDC/ACM. @xiaoxiang781216 @jkivilin @patacongo @masayuki2009 @raiden00pl what do you guys think about it?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org