serial: start_tx & buffer handling
Hi All, I’m trying to understand how user mode buffer is written to low level serial hardware registers. For this I read the kernel code and I came to know that from user mode write() API lands into kernel’s tty_write() ("drivers/tty/tty_io.c") and then it calls a uart_write() ("drivers/tty/serial/serial_core.c"). In uart_write(), the buffer is copied to circ_buf and then it calls low level serial hardware driver’s start_tx() (struct uart_ops .start_tx). But here I could not find how the buffer kept in circ_buf is copied to serial port’s TX_FIFO registers? Can someone take a moment to explain me on this? -- Thanks, Sekhar
On Thu, May 03, 2018 at 08:08:48PM +0530, Muni Sekhar wrote:
Hi All,
I’m trying to understand how user mode buffer is written to low level serial hardware registers.
For this I read the kernel code and I came to know that from user mode write() API lands into kernel’s tty_write() ("drivers/tty/tty_io.c") and then it calls a uart_write() ("drivers/tty/serial/serial_core.c").
In uart_write(), the buffer is copied to circ_buf and then it calls low level serial hardware driver’s start_tx() (struct uart_ops .start_tx). But here I could not find how the buffer kept in circ_buf is copied to serial port’s TX_FIFO registers?
Can someone take a moment to explain me on this?
It all depends on which specific UART driver you are looking at, they all do it a bit different depending on the hardware. Which one are you looking at? Look at what the start_tx callback does for that specific driver, that should give you a hint as to how data starts flowing. Usually an interrupt is enabled that is used to flush the buffer out to the hardware. thanks, greg k-h
On Fri, May 4, 2018 at 12:04 AM, Greg KH <greg@kroah.com> wrote:
On Thu, May 03, 2018 at 08:08:48PM +0530, Muni Sekhar wrote:
Hi All,
I’m trying to understand how user mode buffer is written to low level serial hardware registers.
For this I read the kernel code and I came to know that from user mode write() API lands into kernel’s tty_write() ("drivers/tty/tty_io.c") and then it calls a uart_write() ("drivers/tty/serial/serial_core.c").
In uart_write(), the buffer is copied to circ_buf and then it calls low level serial hardware driver’s start_tx() (struct uart_ops .start_tx). But here I could not find how the buffer kept in circ_buf is copied to serial port’s TX_FIFO registers?
Can someone take a moment to explain me on this?
It all depends on which specific UART driver you are looking at, they all do it a bit different depending on the hardware.
Which one are you looking at? Look at what the start_tx callback does for that specific driver, that should give you a hint as to how data starts flowing. Usually an interrupt is enabled that is used to flush the buffer out to the hardware.
I’m looking for any existing sample code which does DMA transfers of UART transmitted data. I looked at the bcm63xx_uart.c, it looks it does not handle DMA transfers. Even copying the Tx buffer (from circ_buf) to UART_FIFO_REG happening in ISR.
thanks,
greg k-h
-- Thanks, Sekhar
Hi On Fri, May 4, 2018 at 6:31 AM, Muni Sekhar <munisekharrms@gmail.com> wrote:
On Fri, May 4, 2018 at 12:04 AM, Greg KH <greg@kroah.com> wrote:
On Thu, May 03, 2018 at 08:08:48PM +0530, Muni Sekhar wrote:
Hi All,
I’m trying to understand how user mode buffer is written to low level serial hardware registers.
For this I read the kernel code and I came to know that from user mode write() API lands into kernel’s tty_write() ("drivers/tty/tty_io.c") and then it calls a uart_write() ("drivers/tty/serial/serial_core.c").
In uart_write(), the buffer is copied to circ_buf and then it calls low level serial hardware driver’s start_tx() (struct uart_ops .start_tx). But here I could not find how the buffer kept in circ_buf is copied to serial port’s TX_FIFO registers?
Can someone take a moment to explain me on this?
It all depends on which specific UART driver you are looking at, they all do it a bit different depending on the hardware.
Which one are you looking at? Look at what the start_tx callback does for that specific driver, that should give you a hint as to how data starts flowing. Usually an interrupt is enabled that is used to flush the buffer out to the hardware.
I’m looking for any existing sample code which does DMA transfers of UART transmitted data. I looked at the bcm63xx_uart.c, it looks it does not handle DMA transfers. Even copying the Tx buffer (from circ_buf) to UART_FIFO_REG happening in ISR.
You can have a look at atmel_serial kernel module (built for ARM). https://elixir.bootlin.com/linux/latest/source/drivers/tty/serial/atmel_seri... The dma buffer is linked to uart circular buffer in prepare_tx() function called from uart_startup(). It's released in release_tx() function called from uart_shutdown(). DMA buffer is managed in schedule_tx() function called from a tasklet triggered by the ISR. HTH
thanks,
greg k-h
-- Thanks, Sekhar
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Hi On Fri, May 4, 2018 at 6:31 AM, Muni Sekhar <munisekharrms@gmail.com> wrote:
On Fri, May 4, 2018 at 12:04 AM, Greg KH <greg@kroah.com> wrote:
On Thu, May 03, 2018 at 08:08:48PM +0530, Muni Sekhar wrote:
Hi All,
I’m trying to understand how user mode buffer is written to low level serial hardware registers.
For this I read the kernel code and I came to know that from user mode write() API lands into kernel’s tty_write() ("drivers/tty/tty_io.c") and then it calls a uart_write() ("drivers/tty/serial/serial_core.c").
In uart_write(), the buffer is copied to circ_buf and then it calls low level serial hardware driver’s start_tx() (struct uart_ops .start_tx). But here I could not find how the buffer kept in circ_buf is copied to serial port’s TX_FIFO registers?
Can someone take a moment to explain me on this?
It all depends on which specific UART driver you are looking at, they all do it a bit different depending on the hardware.
Which one are you looking at? Look at what the start_tx callback does for that specific driver, that should give you a hint as to how data starts flowing. Usually an interrupt is enabled that is used to flush the buffer out to the hardware.
I’m looking for any existing sample code which does DMA transfers of UART transmitted data. I looked at the bcm63xx_uart.c, it looks it does not handle DMA transfers. Even copying the Tx buffer (from circ_buf) to UART_FIFO_REG happening in ISR.
You can have a look at atmel_serial kernel module (built for ARM). https://elixir.bootlin.com/linux/latest/source/drivers/tty/serial/atmel_seri... The dma buffer is linked to uart circular buffer in prepare_tx() function called from uart_startup(). It's released in release_tx() function called from uart_shutdown(). DMA buffer is managed in schedule_tx() function called from a tasklet triggered by the ISR. HTH
thanks,
greg k-h
-- Thanks, Sekhar
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On Fri, May 4, 2018 at 5:44 PM, loïc tourlonias <loic.tourlonias@gmail.com> wrote:
Hi
On Fri, May 4, 2018 at 6:31 AM, Muni Sekhar <munisekharrms@gmail.com> wrote:
On Fri, May 4, 2018 at 12:04 AM, Greg KH <greg@kroah.com> wrote:
On Thu, May 03, 2018 at 08:08:48PM +0530, Muni Sekhar wrote:
Hi All,
I’m trying to understand how user mode buffer is written to low level serial hardware registers.
For this I read the kernel code and I came to know that from user mode write() API lands into kernel’s tty_write() ("drivers/tty/tty_io.c") and then it calls a uart_write() ("drivers/tty/serial/serial_core.c").
In uart_write(), the buffer is copied to circ_buf and then it calls low level serial hardware driver’s start_tx() (struct uart_ops .start_tx). But here I could not find how the buffer kept in circ_buf is copied to serial port’s TX_FIFO registers?
Can someone take a moment to explain me on this?
It all depends on which specific UART driver you are looking at, they all do it a bit different depending on the hardware.
Which one are you looking at? Look at what the start_tx callback does for that specific driver, that should give you a hint as to how data starts flowing. Usually an interrupt is enabled that is used to flush the buffer out to the hardware.
I’m looking for any existing sample code which does DMA transfers of UART transmitted data. I looked at the bcm63xx_uart.c, it looks it does not handle DMA transfers. Even copying the Tx buffer (from circ_buf) to UART_FIFO_REG happening in ISR.
You can have a look at atmel_serial kernel module (built for ARM). https://elixir.bootlin.com/linux/latest/source/drivers/tty/serial/atmel_seri...
The dma buffer is linked to uart circular buffer in prepare_tx() function called from uart_startup(). It's released in release_tx() function called from uart_shutdown(). DMA buffer is managed in schedule_tx() function called from a tasklet triggered by the ISR. Thanks a lot for this information.
HTH
thanks,
greg k-h
-- Thanks, Sekhar
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-- Thanks, Sekhar
participants (3)
-
Greg KH -
loïc tourlonias -
Muni Sekhar