Пример #1
0
static int mmio_owner_p(struct modemctl *mc)
{
    unsigned long flags;
    int ret;
    spin_lock_irqsave(&mc->lock, flags);
    ret = mc->mmio_owner || modem_offline(mc);
    spin_unlock_irqrestore(&mc->lock, flags);
    return ret;
}
Пример #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;
	}
}
Пример #3
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;
	}
}
static unsigned int pipe_poll(struct file *filp, poll_table *wait)
{
	unsigned long flags;
	struct m_pipe *pipe = filp->private_data;
	int ret;

	poll_wait(filp, &pipe->mc->wq, wait);

	spin_lock_irqsave(&pipe->mc->lock, flags);
	if (pipe->rx->avail || modem_offline(pipe->mc))
		ret = POLLIN | POLLRDNORM;
	else
		ret = 0;
	spin_unlock_irqrestore(&pipe->mc->lock, flags);

	return ret;
}