The Serial Driver Layer

Greg explains the interface to the new serial driver layer and how to register a serival driver and an individual serial port.
Where Is the Data?

You may have noticed there is no function in the struct uart_ops to send or receive data. The data that is sent from the user to the tty layer through a call to write(2) is placed in a circular buffer by the serial driver layer, and it is up to the specific UART driver to pick up this data and send it out of the port. Usually, every time the UART interrupt happens, the driver checks the circular buffer to see if any more data is present to be sent. The following example function shows one way of doing this:

static void tiny_tx_chars(struct uart_port *port)
{
    struct circ_buf *xmit = &port->info->xmit;
    int count;
    if (port->x_char) {
        /* send port->x_char out the port here */
        UART_SEND_DATA(port->x_char);
        port->icount.tx++;
        port->x_char = 0;
        return;
    }
    if (uart_circ_empty(xmit) ||
       uart_tx_stopped(port)) {
        tiny_stop_tx(port, 0);
        return;
    }
    count = port->fifosize >> 1;
    do {
        /* send xmit->buf[xmit->tail]
         * out the port here */
        UART_SEND_DATA(xmit->buf[xmit->tail]);
        xmit->tail = (xmit->tail + 1) &
                     (UART_XMIT_SIZE - 1);
        port->icount.tx++;
        if (uart_circ_empty(xmit))
            break;
    } while (--count > 0);
    if (uart_circ_chars_pending(xmit) <
       WAKEUP_CHARS)
        uart_event(port, EVT_WRITE_WAKEUP);
    if (uart_circ_empty(xmit))
        tiny_stop_tx(port, 0);
}

The function starts out by looking to see if the x_char is specified to be sent out at this moment in time. If so, it sends it out and increments the number of characters sent out the port. If not, the circular buffer is checked to see if it has any data in it and if the port is not currently stopped by anything. If this is true, we start taking characters out of the circular buffer and send them to the UART. In this example, we send, at most, the size of the FIFO divided by two, which is a good average amount of characters to send. After the characters are sent, we see whether we have flushed out enough characters from the circular buffer to ask for more to be sent to us. If so, we call uart_event() with the EVT_WRITE_WAKEUP parameter, telling the serial core to notify user space that we can accept more data.

Any data received by the serial driver is passed to the tty layer, exactly like a normal tty driver would, with a call to tty_insert_flip_char(). This is usually done in the UART interrupt function.

Tiny Serial Example

Listing 1 [available on the LJ FTP site at ftp.linuxjournal.com/pub/lj/listings/issue104/6331l1.txt], shows an example of how to register a serial driver with the serial driver layer and how to register a single serial port. This serial port is much like the previous tty example serial driver in that it acts like a character is received every two seconds as long as the port is opened. It also will print any characters that are sent to it with a call to write(2) to the kernel debug log.

Conclusion

In this article, the interface to the new serial driver layer has been explained, detailing how to register a serial driver and then an individual serial port. Thanks to this new driver layer being introduced in the 2.5 kernel, serial drivers can be much smaller, and creating a new one is a easier process, keeping the complexities of the tty layer away from the programmer.

Greg Kroah-Hartman is currently the Linux USB and PCI Hot Plug kernel maintainer. He works for IBM, doing various Linux kernel-related things and can be reached at greg@kroah.com.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

serial device driver

gopu's picture

I require driver that transmit and recieve data in other end of the system connected Via null modem. Now I want to recieve data from the hyper terminal of that system.

Visit

Anonymous's picture

link

taco's picture

You can find the source by entering
ftp://ftp.ssc.com/pub/lj/listings/issue104/
The file is 6331|1.txt

The link to listing 1 is

nate's picture

The link to listing 1 is broken.

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix