Exemplo n.º 1
0
static int rs_write(struct tty_struct * tty,
		    const unsigned char *buf, int count)
{
	struct serial_state *info = tty->driver_data;
	int	c, ret = 0;
	unsigned long flags;

	if (!info->xmit.buf)
		return 0;

	local_irq_save(flags);
	while (1) {
		c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
		if (count < c)
			c = count;
		if (c <= 0) {
			break;
		}
		memcpy(info->xmit.buf + info->xmit.head, buf, c);
		info->xmit.head = ((info->xmit.head + c) &
				   (SERIAL_XMIT_SIZE-1));
		buf += c;
		count -= c;
		ret += c;
	}
	local_irq_restore(flags);
	/*
	 * Hey, we transmit directly from here in our case
	 */
	if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) &&
			!tty->stopped && !tty->hw_stopped)
		transmit_chars(tty, info, NULL);

	return ret;
}
Exemplo n.º 2
0
/**********************************************************************************************************
* Description: 	This function is used to fill tx buffer.
*
* Arguments  : 	port			is the uart port
* 				buf			is the user buffer.
*				count		is the user data length
*
* Returns    :
**********************************************************************************************************/
int tls_uart_write(struct tls_uart_port *port, char *buf, u32 count)
{
    struct tls_uart_circ_buf *xmit;
    int c;
    int ret = 0;

    xmit = &port->xmit;

    if (!xmit->buf)
        return WM_FAILED;

    while (1) {
        c = CIRC_SPACE_TO_END(xmit->head, xmit->tail, TLS_UART_TX_BUF_SIZE);
        if (count < c)
            c = count;
        if (c <= 0)
            break;
        MEMCPY((char *)(xmit->buf + xmit->head), buf, c);
        xmit->head = (xmit->head + c) & (TLS_UART_TX_BUF_SIZE - 1);
        buf += c;
        count -= c;
        ret += c;
    }

    return ret;
}
/*
 * rx_done_callback_packet_buffer()
 * We have completed a DMA xfer into the temp packet buffer.
 * Move to ring.
 *
 * flag values:
 * on init,  -EAGAIN
 * on reset, -EINTR
 * on RPE, -EIO
 * on short packet -EPIPE
 */
static void
rx_done_callback_packet_buffer( int flag, int size )
{
	 charstats.cnt_rx_complete++;

	 if ( flag == 0 || flag == -EPIPE ) {
		  size_t n;

		  charstats.bytes_rx += size;

		  n = CIRC_SPACE_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
		  n = MIN( n, size );
		  size -= n;

		  memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer, n );
		  rx_ring.in = (rx_ring.in + n) & (RBUF_SIZE-1);
		  memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer + n, size );
		  rx_ring.in = (rx_ring.in + size) & (RBUF_SIZE-1);

		  wake_up_interruptible( &wq_read );

		  last_rx_result = 0;

		  kick_start_rx();

	 } else if ( flag != -EAGAIN ) {
		  charstats.cnt_rx_errors++;
		  last_rx_result = flag;
		  wake_up_interruptible( &wq_read );
	 }
	 else  /* init, start a read */
		  kick_start_rx();
}
static void ev3_uart_receive_buf(struct tty_struct *tty,
				 const unsigned char *cp, char *fp, int count)
{
	struct ev3_uart_port_data *port = tty->disc_data;
	struct circ_buf *cb = &port->circ_buf;
	int size;

	if (port->closing)
		return;

	if (count > CIRC_SPACE(cb->head, cb->tail, EV3_UART_BUFFER_SIZE))
		return;

	size = CIRC_SPACE_TO_END(cb->head, cb->tail, EV3_UART_BUFFER_SIZE);
	if (count > size) {
		memcpy(cb->buf + cb->head, cp, size);
		memcpy(cb->buf, cp + size, count - size);
		cb->head = count - size;
	} else {
		memcpy(cb->buf + cb->head, cp, count);
		cb->head += count;
	}

	schedule_work(&port->rx_data_work);
}
Exemplo n.º 5
0
/********************************************************************************
 *  Description:
 *   Input Args:
 *  Output Args:
 * Return Value:
 ********************************************************************************/
int main (int argc, char **argv)
{
    int i, len;
    struct circ_buf        tx_ring; 
    char   data[LEN];
    char   buf[LEN];

    memset(&tx_ring, 0, sizeof(struct circ_buf)); 
    tx_ring.buf = malloc(CIRC_BUF_SIZE); 
    if( NULL == tx_ring.buf )
    {
        printf("Allocate Ring buffer failure.\n");
        return -1;
    }

    memset(data, 0, sizeof(data));
    /* Prepare for the data */
    for(i=0; i<sizeof(data); i++)
    {
        data[i] = 30+i;
    }

    printf("CIRC_SPACE: %d\n", CIRC_SPACE(tx_ring.head, tx_ring.tail, CIRC_BUF_SIZE));
    printf("CIRC_SPACE_TO_END: %d\n", CIRC_SPACE_TO_END(tx_ring.head, tx_ring.tail, CIRC_BUF_SIZE));
    printf("CIRC_CNT: %d\n", CIRC_CNT(tx_ring.head, tx_ring.tail, CIRC_BUF_SIZE));
    printf("CIRC_CNT_TO_END: %d\n", CIRC_CNT_TO_END(tx_ring.head, tx_ring.tail, CIRC_BUF_SIZE));
    while(1)
    {
       produce_item(&tx_ring, data, sizeof(data));
       len = consume_item(&tx_ring, buf, sizeof(buf) );
       sleep(1);
    }

    return 0;
} /* ----- End of main() ----- */
Exemplo n.º 6
0
/*
 * This function is called when the tty layer has data for us send.  We store
 * the data first in a circular buffer, and then dequeue as much of that data
 * as possible.
 *
 * We don't need to worry about whether there is enough room in the buffer for
 * all the data.  The purpose of ehv_bc_tty_write_room() is to tell the tty
 * layer how much data it can safely send to us.  We guarantee that
 * ehv_bc_tty_write_room() will never lie, so the tty layer will never send us
 * too much data.
 */
static int ehv_bc_tty_write(struct tty_struct *ttys, const unsigned char *s,
			    int count)
{
	struct ehv_bc_data *bc = ttys->driver_data;
	unsigned long flags;
	unsigned int len;
	unsigned int written = 0;

	while (1) {
		spin_lock_irqsave(&bc->lock, flags);
		len = CIRC_SPACE_TO_END(bc->head, bc->tail, BUF_SIZE);
		if (count < len)
			len = count;
		if (len) {
			memcpy(bc->buf + bc->head, s, len);
			bc->head = (bc->head + len) & (BUF_SIZE - 1);
		}
		spin_unlock_irqrestore(&bc->lock, flags);
		if (!len)
			break;

		s += len;
		count -= len;
		written += len;
	}

	ehv_bc_tx_dequeue(bc);

	return written;
}
Exemplo n.º 7
0
size_t whitebox_user_source_space_available(struct whitebox_user_source *user_source,
        unsigned long *dest)
{
    long tail, head, space;
    head = user_source->buf.head;
    tail = ACCESS_ONCE(user_source->buf.tail);
    space = CIRC_SPACE_TO_END(head, tail, user_source->buf_size) & ~3;
    *dest = (unsigned long)user_source->buf.buf + head;
    d_printk(7, "%ld\n", space);
    return space;
}
static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count)
{
	int	c, ret = 0;
	struct async_struct *info;
	unsigned long flags;

	info = tty->driver_data;

	if (serial_paranoia_check(info, tty->name, "rs_write"))
		return 0;

	if (!info->xmit.buf)
		return 0;

	local_irq_save(flags);
	while (1) {
		c = CIRC_SPACE_TO_END(info->xmit.head,
				      info->xmit.tail,
				      SERIAL_XMIT_SIZE);
		if (count < c)
			c = count;
		if (c <= 0) {
			break;
		}
		memcpy(info->xmit.buf + info->xmit.head, buf, c);
		info->xmit.head = ((info->xmit.head + c) &
				   (SERIAL_XMIT_SIZE-1));
		buf += c;
		count -= c;
		ret += c;
	}
	local_irq_restore(flags);

	if (info->xmit.head != info->xmit.tail
	    && !tty->stopped
	    && !tty->hw_stopped
	    && !(info->IER & UART_IER_THRI)) {
		info->IER |= UART_IER_THRI;
		local_irq_disable();
		custom.intena = IF_SETCLR | IF_TBE;
		mb();
		/* set a pending Tx Interrupt, transmitter should restart now */
		custom.intreq = IF_SETCLR | IF_TBE;
		mb();
		local_irq_restore(flags);
	}
	return ret;
}
Exemplo n.º 9
0
/*
 * serial_buf_put
 *
 * Copy data data from a user buffer and put it into the circular buffer.
 * Restrict to the amount of space available.
 *
 * Return the number of bytes copied.
 */
static int serial_buf_put(struct circ_buf *cb, const char *buf, int count)
{
	int c, ret = 0;
	while (1) {
		c = CIRC_SPACE_TO_END(cb->head, cb->tail, AIRCABLE_BUF_SIZE);
		if (count < c)
			c = count;
		if (c <= 0)
			break;
		memcpy(cb->buf + cb->head, buf, c);
		cb->head = (cb->head + c) & (AIRCABLE_BUF_SIZE-1);
		buf += c;
		count -= c;
		ret= c;
	}
	return ret;
}
Exemplo n.º 10
0
int mcuio_soft_hc_push_chars(struct mcuio_soft_hc *shc, const u8 *in, int len)
{
	int s = sizeof(shc->rx_buf), available, actual;
	struct circ_buf *buf = &shc->rx_circ_buf;
	available = CIRC_SPACE_TO_END(buf->head, buf->tail, s);
	if (available < sizeof(u32)) {
		pr_debug("%s %d\n", __func__, __LINE__);
		return -EAGAIN;
	}
	actual = min(len, available);
	memcpy(&buf->buf[buf->head], in, actual);
	buf->head = (buf->head + actual) & (s - 1);
	/* set irq status register RX_RDY bit */
	shc->irqstat |= RX_RDY;
	if (shc->irq_enabled)
		queue_kthread_work(&shc->irq_kworker, &shc->do_irq);
	return actual;
}
Exemplo n.º 11
0
static void send_tx_char (struct uart_btlinux_port *up)
{
	struct circ_buf *xmit = &up->port.info->xmit;
	unsigned char *buf;
	int c, d, count;
	count = uart_circ_chars_pending(xmit);

	buf = &xmit->buf[xmit->tail];
	/* write to tx buffer */
	while (1) {
		c = CIRC_SPACE_TO_END(up->tx_data_head, up->tx_data_tail, TX_BUFFERS_SIZE);
		if (count < c)
			c = count;
		if (c <= 0)
			break;

		if (xmit->head > xmit->tail) {
			memcpy(up->tx_data + up->tx_data_head, buf, c);
			buf += c;
			xmit->tail = (xmit->tail + c) & (UART_XMIT_SIZE - 1);
		} else {
			d = (UART_XMIT_SIZE - xmit->tail);
			if (c < d)
				d = c;
			memcpy(up->tx_data + up->tx_data_head, buf, d);
			xmit->tail = (xmit->tail + d) & (UART_XMIT_SIZE - 1);
			buf = &xmit->buf[xmit->tail];
			if (c > d) {
				memcpy(up->tx_data + up->tx_data_head + d, buf, (c-d));
				xmit->tail = (xmit->tail + (c-d)) & (UART_XMIT_SIZE - 1);
				buf = &xmit->buf[xmit->tail];
			}
		}
		up->tx_data_head = (up->tx_data_head + c) & (TX_BUFFERS_SIZE - 1);
		count -= c;
	}

	if (uart_circ_chars_pending(xmit) < 1024)
		uart_write_wakeup(&up->port);
	/*    dbg("tx head %d - tx tail = %d", up->tx_data_head, up->tx_data_tail);*/
}
Exemplo n.º 12
0
void d_printk_loop(int level) {
    unsigned long src;
    struct circ_buf *mock_buf = &whitebox_device->mock_buf;
    struct whitebox_user_sink *user_sink = &whitebox_device->user_sink;
    struct whitebox_user_source *user_source = &whitebox_device->user_source;
    struct whitebox_rf_sink *rf_sink = &whitebox_device->rf_sink;
    struct whitebox_rf_source *rf_source = &whitebox_device->rf_source;
    u32 exciter_state = rf_sink->exciter->ops->get_state(rf_sink->exciter);
    u32 receiver_state = rf_source->receiver->ops->get_state(rf_source->receiver);

    d_printk(level, "stats %c%c user_source_data/space=%d/%d rf_sink_space=%d mock_data/space=%d/%d rf_source_data=%d user_sink_data/space=%d/%d\n",
        exciter_state & WES_TXEN ? 'T' : ' ',
        receiver_state & WRS_RXEN ? 'R' : ' ',
        whitebox_user_source_data_available(user_source, &src),
        whitebox_user_source_space_available(user_source, &src),
        whitebox_rf_sink_space_available(rf_sink, &src),
        CIRC_CNT_TO_END(mock_buf->head, mock_buf->tail, PAGE_SIZE << whitebox_mock_order),
        CIRC_SPACE_TO_END(mock_buf->head, mock_buf->tail, PAGE_SIZE << whitebox_mock_order),
        whitebox_rf_source_data_available(rf_source, &src),
        whitebox_user_sink_data_available(user_sink, &src),
        whitebox_user_sink_space_available(user_sink, &src));
}
Exemplo n.º 13
0
static int uart_write(struct tty_struct *tty,
					const unsigned char *buf, int count)
{
	struct uart_state *state = tty->driver_data;
	struct uart_port *port;
	struct circ_buf *circ;
	unsigned long flags;
	int c, ret = 0;

	if (!state) {
		WARN_ON(1);
		return -EL3HLT;
	}

	port = state->uart_port;
	circ = &state->xmit;

	if (!circ->buf)
		return 0;

	spin_lock_irqsave(&port->lock, flags);
	while (1) {
		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
		if (count < c)
			c = count;
		if (c <= 0)
			break;
		memcpy(circ->buf + circ->head, buf, c);
		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
		buf += c;
		count -= c;
		ret += c;
	}
	spin_unlock_irqrestore(&port->lock, flags);

	uart_start(tty);
	return ret;
}
Exemplo n.º 14
0
static unsigned _fifo_write(struct m_fifo *q, void *src,
			    unsigned count, copyfunc copy)
{
	unsigned n;
	unsigned head = *q->head;
	unsigned tail = *q->tail;
	unsigned size = q->size;

	if (CIRC_SPACE(head, tail, size) < count)
		return 0;

	n = CIRC_SPACE_TO_END(head, tail, size);

	if (likely(n >= count)) {
		copy(q->data + head, src, count);
	} else {
		copy(q->data + head, src, n);
		copy(q->data, src + n, count - n);
	}
	//*q->head = (head + count) & (size - 1);

	return count;
}
Exemplo n.º 15
0
int produce_item(struct circ_buf *ring, char *data, int  count)
{
    int len = 0;
    int left,i,size;
    int to_end_space=0;

    if ( (size=CIRC_SPACE(ring->head, ring->tail, CIRC_BUF_SIZE)) >= 1 )
    {
        left = len = count<=size ? count : size;
        to_end_space = CIRC_SPACE_TO_END(ring->head, ring->tail, CIRC_BUF_SIZE);

        if(left > to_end_space)
        { 
            memcpy(&(ring->buf[ring->head]), data, to_end_space); 
            for(i=0; i<to_end_space; i++) 
            { 
                printf("produec_item %02d bytes: ring->buf[%02d]=%d\n", to_end_space, ring->head+i, ring->buf[ring->head+i]); 
            }
            ring->head = (ring->head + to_end_space) & (CIRC_BUF_SIZE - 1); 
            left -= to_end_space; 
        }
        else
        { 
            to_end_space = 0;
        }

        memcpy(&(ring->buf[ring->head]), &data[to_end_space], left);
        for(i=0; i<left; i++)
        {
           printf("produec_item %02d bytes: ring->buf[%02d]=%d\n", left, ring->head+i, ring->buf[ring->head+i]);
        }
        ring->head = (ring->head + left) & (CIRC_BUF_SIZE - 1);
    }
    printf("-----------------------------------------------------------------------------------------------\n");

    return len;
}
Exemplo n.º 16
0
/*
 * Send a packet of bytes to the device
 */
int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
{
	/* Copy data to buffer */
	int n = LO(cmd);
	int c;
	int empty;
	int head, tail;
	unsigned long flags;

/*
 * Update head and tail of xmit buffer
 */
	spin_lock_irqsave(&iforce->xmit_lock, flags);

	head = iforce->xmit.head;
	tail = iforce->xmit.tail;


	if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) {
		warn("not enough space in xmit buffer to send new packet");
		spin_unlock_irqrestore(&iforce->xmit_lock, flags);
		return -1;
	}

	empty = head == tail;
	XMIT_INC(iforce->xmit.head, n+2);

/*
 * Store packet in xmit buffer
 */
	iforce->xmit.buf[head] = HI(cmd);
	XMIT_INC(head, 1);
	iforce->xmit.buf[head] = LO(cmd);
	XMIT_INC(head, 1);

	c = CIRC_SPACE_TO_END(head, tail, XMIT_SIZE);
	if (n < c) c=n;

	memcpy(&iforce->xmit.buf[head],
	       data,
	       c);
	if (n != c) {
		memcpy(&iforce->xmit.buf[0],
		       data + c,
		       n - c);
	}
	XMIT_INC(head, n);

	spin_unlock_irqrestore(&iforce->xmit_lock, flags);
/*
 * If necessary, start the transmission
 */
	switch (iforce->bus) {

#ifdef CONFIG_JOYSTICK_IFORCE_232
		case IFORCE_232:
		if (empty)
			iforce_serial_xmit(iforce);
		break;
#endif
#ifdef CONFIG_JOYSTICK_IFORCE_USB
		case IFORCE_USB:

		if (iforce->usbdev && empty &&
			!test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) {

			iforce_usb_xmit(iforce);
		}
		break;
#endif
	}
	return 0;
}
Exemplo n.º 17
0
static int uart_write(struct tty_struct *tty,
					const unsigned char *buf, int count)
{
	struct uart_state *state = tty->driver_data;
	struct uart_port *port;
	struct circ_buf *circ;
	unsigned long flags;
	int c, ret = 0;
#ifdef CONFIG_IMC_UART2DM_HANDSHAKE
	u8 retries=0;
#endif

	if (!state) {
		WARN_ON(1);
		return -EL3HLT;
	}

	port = state->uart_port;
	circ = &state->xmit;

#ifdef CONFIG_IMC_UART2DM_HANDSHAKE
	
	if (!strcmp(tty->name,"ttyHS1") && !modem_fatal) {
		if (!radio_state) {
			printk("[GSM_RADIO] %s %s radio is off \n",__func__, tty->name);
			return -EINVAL;
		}

		imc_msm_hs_request_clock_on(port);

		pr_uartdm_debug("%s %s PDA_INT_BB + \n",__func__, tty->name);
		gpio_set_value(JEL_DD_GPIO_GSM_AP_XMM_WAKE, 1);
		mdelay(1);
		while(!gpio_get_value(JEL_DD_GPIO_GSM_XMM_AP_STATUS)){
			gpio_set_value(JEL_DD_GPIO_GSM_AP_XMM_STATUS, 0);
			msleep(5);
			gpio_set_value(JEL_DD_GPIO_GSM_AP_XMM_STATUS, 1);
			msleep(20);
			if (retries>40){
				printk("[GSM_RADIO] %s %s wait for BB_STATUS + timeout \n",__func__, tty->name);
				return -EAGAIN;
			}
			retries++;
		}
	}
#endif

	if (!circ->buf)
		return 0;

	spin_lock_irqsave(&port->lock, flags);
	while (1) {
		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
		if (count < c)
			c = count;
		if (c <= 0)
			break;
		memcpy(circ->buf + circ->head, buf, c);
		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
		buf += c;
		count -= c;
		ret += c;
	}
	spin_unlock_irqrestore(&port->lock, flags);

	uart_start(tty);
	return ret;
}
Exemplo n.º 18
0
static int rs_write(struct tty_struct * tty, int from_user,
                    const unsigned char *buf, int count)
{
    int	c, ret = 0;
    struct async_struct *info = (struct async_struct *)tty->driver_data;
    unsigned long flags;

    if (!tty || !info->xmit.buf || !tmp_buf) return 0;

    if (from_user) {
        down(&tmp_buf_sem);
        while (1) {
            int c1;
            c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
            if (count < c)
                c = count;
            if (c <= 0)
                break;

            c -= copy_from_user(tmp_buf, buf, c);
            if (!c) {
                if (!ret)
                    ret = -EFAULT;
                break;
            }

            local_irq_save(flags);
            {
                c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail,
                                       SERIAL_XMIT_SIZE);
                if (c1 < c)
                    c = c1;
                memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
                info->xmit.head = ((info->xmit.head + c) &
                                   (SERIAL_XMIT_SIZE-1));
            }
            local_irq_restore(flags);

            buf += c;
            count -= c;
            ret += c;
        }
        up(&tmp_buf_sem);
    } else {
        local_irq_save(flags);
        while (1) {
            c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
            if (count < c)
                c = count;
            if (c <= 0) {
                break;
            }
            memcpy(info->xmit.buf + info->xmit.head, buf, c);
            info->xmit.head = ((info->xmit.head + c) &
                               (SERIAL_XMIT_SIZE-1));
            buf += c;
            count -= c;
            ret += c;
        }
        local_irq_restore(flags);
    }
    /*
     * Hey, we transmit directly from here in our case
     */
    if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE)
            && !tty->stopped && !tty->hw_stopped) {
        transmit_chars(info, NULL);
    }
    return ret;
}