Exemple #1
0
/* must be called with pipe->tx_lock held */
static int modem_pipe_send(struct m_pipe *pipe, struct modem_io *io)
{
	char hdr[M_PIPE_MAX_HDR];
	unsigned size;
	int ret;

	io->magic = 0xCAFECAFE;

	ret = pipe->push_header(io, hdr);
	if (ret)
		return ret;

	size = io->datasize + pipe->header_size;

	if (size > 0x1000 /*pipe->tx->size*/)
	{
		pr_err ("Trying to send bigger than 4kB frame - MULTIPACKET not implemented yet.\n");
		return -EINVAL;
	}

	for (;;) {
		ret = modem_acquire_mmio(pipe->mc);
		if (ret)
			return ret;

		modem_update_pipe(pipe);

		if (pipe->tx->avail >= size) {
			fifo_write(pipe->tx, hdr, pipe->header_size);
			fifo_move_head(pipe->tx, pipe->header_size);
			fifo_write_user(pipe->tx, io->data, io->datasize);
			fifo_move_head(pipe->tx, SIZ_PACKET_BUFSIZE);
			modem_update_pipe(pipe);
			modem_release_mmio(pipe->mc, pipe->tx->bits);
			MODEM_COUNT(pipe->mc, pipe_tx);
			return 0;
		}

		pr_info("modem_pipe_send: wait for space\n");
		MODEM_COUNT(pipe->mc, pipe_tx_delayed);
		modem_release_mmio(pipe->mc, 0);

		ret = wait_event_interruptible(pipe->mc->wq,
					       (pipe->tx->avail >= size)
					       || modem_offline(pipe->mc));
		if (ret)
			return ret;
	}
}
Exemple #2
0
/* must be called with pipe->tx_lock held */
static int modem_pipe_send(struct m_pipe *pipe, struct modem_io *io)
{
	char hdr[M_PIPE_MAX_HDR];
	static char ftr = 0x7e;
	unsigned size;
	int ret;

	ret = pipe->push_header(io, hdr);
	if (ret)
		return ret;

	size = io->size + pipe->header_size + 1;

	if (io->size > 0x10000000)
		return -EINVAL;
	if (size >= (pipe->tx->size - 1))
		return -EINVAL;

	for (;;) {
		ret = modem_acquire_mmio(pipe->mc);
		if (ret)
			return ret;

		modem_update_pipe(pipe);

		if (pipe->tx->avail >= size) {
			fifo_write(pipe->tx, hdr, pipe->header_size);
			fifo_write_user(pipe->tx, io->data, io->size);
			fifo_write(pipe->tx, &ftr, 1);
			modem_update_pipe(pipe);
			modem_release_mmio(pipe->mc, pipe->tx->bits);
			MODEM_COUNT(pipe->mc, pipe_tx);
			return 0;
		}

		pr_info("modem_pipe_send: wait for space\n");
		MODEM_COUNT(pipe->mc, pipe_tx_delayed);
		modem_release_mmio(pipe->mc, 0);

		ret = wait_event_interruptible_timeout(
			pipe->mc->wq,
			(pipe->tx->avail >= size) || modem_offline(pipe->mc),
			5 * HZ);
		if (ret == 0)
			return -ENODEV;
		if (ret < 0)
			return ret;
	}
}
Exemple #3
0
/* must be called with pipe->rx_lock held */
static int modem_pipe_recv(struct m_pipe *pipe, struct modem_io *io)
{
	int ret;

	ret = modem_acquire_mmio(pipe->mc);
	if (ret)
		return ret;

	ret = modem_pipe_read(pipe, io);

	modem_update_pipe(pipe);

	if ((ret != 0) && (ret != -EAGAIN)) {
		pr_err("[MODEM] purging %s fifo\n", pipe->dev.name);
		fifo_purge(pipe->rx);
		MODEM_COUNT(pipe->mc, pipe_rx_purged);
	} else if (ret == 0) {
		MODEM_COUNT(pipe->mc, pipe_rx);
	}

	modem_release_mmio(pipe->mc, 0);

	return ret;
}