drivers/serial/serial_dma.c: Avoid uart_xmitchars_done() move the tail bigger then head. If ioctl(TCOFLUSH) occurs between uart_xmitchars_dma() and uart_xmitchars_done(), TCOFLUSH will reset xmit buffer, then uart_xmitchars_done() will move the 'tail' ahead of 'head', then sends lots of wrong data.
This commit is contained in:
parent
3e8366775f
commit
8fb19a4359
@ -193,11 +193,18 @@ void uart_xmitchars_done(FAR uart_dev_t *dev)
|
|||||||
size_t nbytes = xfer->nbytes;
|
size_t nbytes = xfer->nbytes;
|
||||||
struct uart_buffer_s *txbuf = &dev->xmit;
|
struct uart_buffer_s *txbuf = &dev->xmit;
|
||||||
|
|
||||||
/* Move tail for nbytes. */
|
/* Skip the update if the tail position change which mean
|
||||||
|
* someone reset (e.g. TCOFLUSH) the xmit buffer during DMA.
|
||||||
|
*/
|
||||||
|
|
||||||
txbuf->tail = (txbuf->tail + nbytes) % txbuf->size;
|
if (xfer->buffer == &txbuf->buffer[txbuf->tail])
|
||||||
xfer->nbytes = 0;
|
{
|
||||||
xfer->length = xfer->nlength = 0;
|
/* Move tail for nbytes. */
|
||||||
|
|
||||||
|
txbuf->tail = (txbuf->tail + nbytes) % txbuf->size;
|
||||||
|
xfer->nbytes = 0;
|
||||||
|
xfer->length = xfer->nlength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* If any bytes were removed from the buffer, inform any waiters there there is
|
/* If any bytes were removed from the buffer, inform any waiters there there is
|
||||||
* space available.
|
* space available.
|
||||||
|
Loading…
Reference in New Issue
Block a user