コード例 #1
0
ファイル: serial.c プロジェクト: HackLinux/xen
void serial_start_sync(int handle)
{
    struct serial_port *port;
    unsigned long flags;

    if ( handle == -1 )
        return;
    
    port = &com[handle & SERHND_IDX];

    spin_lock_irqsave(&port->tx_lock, flags);

    if ( port->sync++ == 0 )
    {
        while ( (port->txbufp - port->txbufc) != 0 )
        {
            while ( !port->driver->tx_ready(port) )
                cpu_relax();
            port->driver->putc(
                port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
        }
        if ( port->driver->flush )
            port->driver->flush(port);
    }

    spin_unlock_irqrestore(&port->tx_lock, flags);
}
コード例 #2
0
ファイル: serial.c プロジェクト: HackLinux/xen
void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
{
    unsigned int i, n;
    unsigned long flags;

    local_irq_save(flags);

    /*
     * Avoid spinning for a long time: if there is a long-term lock holder
     * then we know that they'll be stuffing bytes into the transmitter which
     * will therefore not be empty for long.
     */
    while ( !spin_trylock(&port->tx_lock) )
    {
        if ( !port->driver->tx_ready(port) )
            goto out;
        cpu_relax();
    }

    for ( i = 0, n = port->driver->tx_ready(port); i < n; i++ )
    {
        if ( port->txbufc == port->txbufp )
            break;
        port->driver->putc(
            port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
    }
    if ( i && port->driver->flush )
        port->driver->flush(port);

    spin_unlock(&port->tx_lock);

 out:
    local_irq_restore(flags);
}
コード例 #3
0
ファイル: serial.c プロジェクト: HPSI/xen-v4v
void serial_start_sync(int handle)
{
    struct serial_port *port;
    unsigned long flags;

    if ( handle == -1 )
        return;
    
    port = &com[handle & SERHND_IDX];

    spin_lock_irqsave(&port->tx_lock, flags);

    if ( port->sync++ == 0 )
    {
        while ( (port->txbufp - port->txbufc) != 0 )
        {
            int n;

            while ( !(n = port->driver->tx_ready(port)) )
                cpu_relax();
            if ( n < 0 )
                /* port is unavailable and might not come up until reenabled by
                   dom0, we can't really do proper sync */
                break;
            port->driver->putc(
                port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
        }
        if ( port->driver->flush )
            port->driver->flush(port);
    }

    spin_unlock_irqrestore(&port->tx_lock, flags);
}
コード例 #4
0
ファイル: serial.c プロジェクト: HackLinux/xen
static void __serial_putc(struct serial_port *port, char c)
{
    if ( (port->txbuf != NULL) && !port->sync )
    {
        /* Interrupt-driven (asynchronous) transmitter. */

        if ( port->tx_quench )
        {
            /* Buffer filled and we are dropping characters. */
            if ( (port->txbufp - port->txbufc) > (serial_txbufsz / 2) )
                return;
            port->tx_quench = 0;
        }

        if ( (port->txbufp - port->txbufc) == serial_txbufsz )
        {
            if ( port->tx_log_everything )
            {
                /* Buffer is full: we spin waiting for space to appear. */
                unsigned int n;

                while ( (n = port->driver->tx_ready(port)) == 0 )
                    cpu_relax();
                while ( n-- )
                    port->driver->putc(
                        port,
                        port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
                port->txbuf[mask_serial_txbuf_idx(port->txbufp++)] = c;
            }
            else
            {
                /* Buffer is full: drop chars until buffer is half empty. */
                port->tx_quench = 1;
            }
            return;
        }

        if ( ((port->txbufp - port->txbufc) == 0) &&
             port->driver->tx_ready(port) )
        {
            /* Buffer and UART FIFO are both empty. */
            port->driver->putc(port, c);
        }
        else
        {
            /* Normal case: buffer the character. */
            port->txbuf[mask_serial_txbuf_idx(port->txbufp++)] = c;
        }
    }
    else if ( port->driver->tx_ready )
    {
        /* Synchronous finite-capacity transmitter. */
        while ( !port->driver->tx_ready(port) )
            cpu_relax();
        port->driver->putc(port, c);
    }
    else
    {
        /* Simple synchronous transmitter. */
        port->driver->putc(port, c);
    }
}