コード例 #1
0
static void
l4ser_shm_rx_chars(struct uart_port *port)
{
	struct l4ser_shm_uart_port *l4port = (struct l4ser_shm_uart_port *)port;
	struct tty_struct *tty = port->state->port.tty;

	struct chunk_head *chhead;
	struct ring_chunk_head *rph;
	unsigned long offs;

	chhead = (struct chunk_head *)l4shmc_chunk_ptr(&l4port->rx_chunk);
	offs = chhead->next_offs_to_read;

	while (1) {
		unsigned long l;

		rph = (struct ring_chunk_head *)(l4port->rx_ring_start + offs);
		if (!rph->size)
			break;
		offs += sizeof(struct ring_chunk_head);
		offs %= l4port->rx_ring_size;

		if (offs + rph->size > l4port->rx_ring_size)
			l = l4port->rx_ring_size - offs;
		else
			l = rph->size;


		port->icount.rx += rph->size;

		tty_insert_flip_string(tty,
		                       (const unsigned char *)l4port->rx_ring_start + offs,
		                       l);
		if (l != rph->size)
			tty_insert_flip_string(tty,
			                       (const unsigned char *)l4port->rx_ring_start,
			                       rph->size - l);


		offs = (offs + rph->size + sizeof(struct ring_chunk_head) - 1)
		       & ~(sizeof(struct ring_chunk_head) - 1);
		offs %= l4port->rx_ring_size;
		chhead->next_offs_to_read = offs;
		rph->size = 0;

	}
	tty_flip_buffer_push(tty);

	if (chhead->writer_blocked) {
		L4XV_V(f);
		L4XV_L(f);
		l4shmc_trigger(&l4port->tx_sig);
		L4XV_U(f);
	}

	chhead = (struct chunk_head *)l4shmc_chunk_ptr(&l4port->tx_chunk);
	chhead->writer_blocked = 0;

	return;
}
コード例 #2
0
static void l4ser_shm_tx_chars(struct uart_port *port)
{
	struct l4ser_shm_uart_port *l4port = (struct l4ser_shm_uart_port *)port;
	struct circ_buf *xmit = &port->state->xmit;
	int c, do_trigger = 0;

	struct tty_struct *tty = port->state->port.tty;
	tty->hw_stopped = 0;
	tty->stopped = 0;

	if (port->x_char) {
		if (tx_buf(port, &port->x_char, 1)) {
			L4XV_V(f);
			port->icount.tx++;
			port->x_char = 0;
			L4XV_L(f);
			l4shmc_trigger(&l4port->tx_sig);
			L4XV_U(f);
		}
		return;
	}

	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
		return;
	}

	while (!uart_circ_empty(xmit)) {
		unsigned long r;
		c = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
		if (!(r = tx_buf(port, &xmit->buf[xmit->tail], c)))
			break;
		xmit->tail = (xmit->tail + r) & (UART_XMIT_SIZE - 1);
		port->icount.tx += r;
		do_trigger = 1;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (do_trigger) {
		L4XV_V(f);
		L4XV_L(f);
		l4shmc_trigger(&l4port->tx_sig);
		L4XV_U(f);
	}
}
コード例 #3
0
ファイル: prodcons.c プロジェクト: michas2/l4re-snapshot
static void *thread_consume(void *d)
{
  (void)d;
  l4shmc_area_t shmarea;
  l4shmc_chunk_t p_one;
  l4shmc_signal_t s_one, s_done;

  // attach to shared memory area
  CHK(l4shmc_attach("testshm", &shmarea));

  // get chunk 'one'
  CHK(l4shmc_get_chunk(&shmarea, "one", &p_one));

  // add a signal
  CHK(l4shmc_add_signal(&shmarea, "done", &s_done));

  // attach signal to this thread
  CHK(l4shmc_attach_signal_to(&shmarea, "prod",
                              pthread_l4_cap(pthread_self()), 10000, &s_one));

  // connect chunk and signal
  CHK(l4shmc_connect_chunk_signal(&p_one, &s_one));

  while (1)
    {
      CHK(l4shmc_wait_chunk(&p_one));

      printf("CONSUMER: Received from chunk one: %s\n",
             (char *)l4shmc_chunk_ptr(&p_one));
      memset(l4shmc_chunk_ptr(&p_one), 0, l4shmc_chunk_size(&p_one));

      CHK(l4shmc_chunk_consumed(&p_one));
      CHK(l4shmc_trigger(&s_done));
    }

  return NULL;
}
コード例 #4
0
ファイル: l4ser_shm.c プロジェクト: allen123/L4Reap
static unsigned long tx_buf(struct uart_port *port, const char *chunk, int length)
{
	struct l4ser_shm_uart_port *l4port = (struct l4ser_shm_uart_port *)port;
	struct chunk_head *chhead;
	struct ring_chunk_head *rph;
	unsigned long l, offs, nextoffs, free_bytes;
	unsigned long flags;
	struct tty_struct *tty = port->state->port.tty;

	spin_lock_irqsave(&txlock, flags);

	chhead = (struct chunk_head *)l4shmc_chunk_ptr(&l4port->tx_chunk);
	offs = chhead->next_offs_to_write;

	rph = (struct ring_chunk_head *)(l4port->tx_ring_start + offs);
	BUILD_BUG_ON(sizeof(struct ring_chunk_head) & (sizeof(struct ring_chunk_head) - 1));

	// get max free space
	if (chhead->next_offs_to_write >= chhead->next_offs_to_read)
		free_bytes = l4port->tx_ring_size - (chhead->next_offs_to_write - chhead->next_offs_to_read);
	else
		free_bytes = chhead->next_offs_to_read - chhead->next_offs_to_write;

	if (free_bytes <= sizeof(struct ring_chunk_head) * 2) {
		chhead->writer_blocked = 1;
		spin_unlock_irqrestore(&txlock, flags);
		tty->hw_stopped = 1;
		tty->stopped = 1;
		l4shmc_trigger(&l4port->tx_sig);
		return 0;
	}

	if (length > free_bytes - sizeof(struct ring_chunk_head) * 2)
		length = free_bytes - sizeof(struct ring_chunk_head) * 2;

	nextoffs = (offs + length + sizeof(struct ring_chunk_head) + sizeof(struct ring_chunk_head) - 1)
	           & ~(sizeof(struct ring_chunk_head) - 1);

	nextoffs %= l4port->tx_ring_size;

	offs += sizeof(struct ring_chunk_head);
	offs %= l4port->tx_ring_size;

	if (offs + length > l4port->tx_ring_size)
		l = l4port->tx_ring_size - offs;
	else
		l = length;

	memcpy(l4port->tx_ring_start + offs, chunk, l);
	if (l != length)
		memcpy(l4port->tx_ring_start, chunk + l, length - l);

	// now write header
	((struct ring_chunk_head *)(l4port->tx_ring_start + nextoffs))->size = 0;
	smp_wmb();
	rph->size = length;
	chhead->next_offs_to_write = nextoffs;

	spin_unlock_irqrestore(&txlock, flags);
	return length;
}