Example #1
0
static void spi_tty_handle_data(void *context, u8 *buf, u32 count)
{
	int cnt, crc, len;
	struct spi_tty_s *spi_tty;
	spi_msg_header header;

	SPI_IPC_INFO("%s, context=%p, buf=%p, count=%d\n", __func__, context, buf, count);

	if (!context || !buf || !count) {
		pr_err("%s - Invalid param!\n", __func__);
		return;
	}

	spi_ipc_buf_dump("rx header: ", buf, SPI_MSG_HEADER_LEN);

	spi_tty = (struct spi_tty_s *) context;
	spi_msg_get_header(buf, &header);
	crc = spi_msg_cal_crc(&header);

	// validate data
	if (header.type != 1 || header.len > SPI_MTU || header.fcs != crc) {
		pr_err("Invalid data receicved!\n");
		return;
	}

	if (spi_tty->open_count > 0 && header.len > 0) {
		len = header.len;
		spi_ipc_buf_dump_ascii("rx data: ", buf+SPI_MSG_HEADER_LEN, (len>16?16:len));
		SPI_IPC_INFO("insert data to tty\n");
		buf += SPI_MSG_HEADER_LEN;
		do {
			cnt = tty_buffer_request_room(spi_tty->tty, len);
			if (cnt == 0)
				break;
			cnt = tty_insert_flip_string(spi_tty->tty, buf, cnt);
			tty_flip_buffer_push(spi_tty->tty);
			len -= cnt;
			buf += cnt;
		}while(len > 0);
	}
}
Example #2
0
void spi_tty_write_worker(struct work_struct *work)
{
	int c;
	int crc;
	unsigned long flags;
	unsigned long start_t = 0;
	spi_msg_header header;
	struct spi_tty_s *spi_tty =
		container_of(work, struct spi_tty_s, write_work);

	start_t = jiffies;
	SPI_IPC_INFO("%s Enter\n", __func__);

	mutex_lock(&(spi_tty->work_lock));
	spin_lock_irqsave(&(spi_tty->port_lock), flags);

	while(
		((c = spi_tty_buf_data_avail(spi_tty->write_buf))
			|| (spi_tty->tx_null))
		&& (!spi_tty->throttle)
		&& (!spi_tty->spi_slave_dev->peer_is_dead))
	{
		if (spi_tty->tx_null)
			spi_tty->tx_null = 0;

		// initiate spi_big_trans
		memset(spi_big_trans.tx_buf, 0x0, SPI_TRANSACTION_LEN*2);
		spi_big_msg.actual_length = 0;

		c = MIN(c, SPI_MTU);
		spi_tty_buf_get(spi_tty->write_buf,
				spi_big_trans.tx_buf+SPI_MSG_HEADER_LEN,
				c);

		if (spi_tty->tty && spi_tty->open_count)
			tty_wakeup(spi_tty->tty);
		spin_unlock_irqrestore(&(spi_tty->port_lock), flags);

		header.type = 1;
		header.len = c;
		header.dtr = spi_tty->dtr;
		crc = spi_msg_cal_crc(&header);
		header.fcs = crc;
		spi_msg_set_header(spi_big_trans.tx_buf, &header);
		spi_big_trans.len = c + SPI_MSG_HEADER_LEN;
		spi_ipc_buf_dump("tx header: ", spi_big_trans.tx_buf, SPI_MSG_HEADER_LEN);
		spi_ipc_buf_dump_ascii("tx data: ", spi_big_trans.tx_buf + SPI_MSG_HEADER_LEN, (c>16?16:c));
		spi_slave_sync(mdm6600_spi_dev.spi, &spi_big_msg);

		if (spi_big_msg.actual_length == SPI_TRANSACTION_LEN) {
			tx_count++;
			tx_size += spi_big_trans.len - SPI_MSG_HEADER_LEN;
			spi_tty_handle_data(spi_tty, spi_big_trans.rx_buf, SPI_TRANSACTION_LEN);
		}else {
			pr_err("%s: spi_slave_sync() failed to transfer data!\n", __func__);
		}

		// wake up writes wait on queue
		wake_up_interruptible(&spi_tty->write_wait);

		spin_lock_irqsave(&(spi_tty->port_lock), flags);
	}

	spin_unlock_irqrestore(&(spi_tty->port_lock), flags);
	mutex_unlock(&(spi_tty->work_lock));
	SPI_IPC_INFO("%s Exit\n", __func__);
	tx_time += jiffies_to_msecs(jiffies - start_t);
}
Example #3
0
static void spi_tty_write_worker(struct work_struct *work)
{
	int c;
	int crc;
	unsigned long flags;
	unsigned long start_t = 0;
	spi_msg_header header;
	struct spi_tty_s *spi_tty =
		container_of(work, struct spi_tty_s, write_work);

	start_t = jiffies;
	SPI_IPC_INFO("%s\n", __func__);

	mutex_lock(&(spi_tty->work_lock));
	spin_lock_irqsave(&(spi_tty->port_lock), flags);

	while(((c = spi_tty_buf_data_avail(spi_tty->write_buf))
		|| (spi_tty->tx_null))
		&& (!spi_tty->throttle)
		&& (!(spi_tty_dev && spi_tty_dev->peer_is_dead)))
	{
		SPI_IPC_INFO("%s: %d outgoing bytes\n", __func__, c);
		if (spi_tty->tx_null)
			spi_tty->tx_null = 0;

		// initiate spi_big_trans
		memset((char*)spi_big_trans.tx_buf, 0x0,
			SPI_TRANSACTION_LEN * 2);
		spi_big_msg.actual_length = 0;

		c = MIN(c, SPI_MTU);
		spi_tty_buf_get(spi_tty->write_buf,
			(char*)spi_big_trans.tx_buf + SPI_MSG_HEADER_LEN,
			c);

		if (spi_tty->tty && spi_tty->open_count)
			tty_wakeup(spi_tty->tty);
		spin_unlock_irqrestore(&(spi_tty->port_lock), flags);

		header.type = 1;
		header.len = c;
		header.dtr = spi_tty->dtr;
		crc = spi_msg_cal_crc(&header);
		header.fcs = crc;
		spi_msg_set_header((u8*)spi_big_trans.tx_buf, &header);
#if SPI_TTY_FORCE_FULL_TRANSACTION
		spi_big_trans.len = SPI_TRANSACTION_LEN;
#else
		spi_big_trans.len = c + SPI_MSG_HEADER_LEN;
#endif
		spi_big_trans.speed_hz = SPI_SPEED_HZ;
		spi_big_trans.bits_per_word = 32;
		spi_ipc_buf_dump("tx header: ", spi_big_trans.tx_buf, SPI_MSG_HEADER_LEN);
		spi_ipc_buf_dump_ascii("tx data: ", spi_big_trans.tx_buf + SPI_MSG_HEADER_LEN, (c>16?16:c));
		if (spi_tty_dev)
			spi_sync(spi_tty_dev->spi, &spi_big_msg);
		else
			pr_warning("%s: dropping data: no spi device "
				   "registered", __func__);

		if (spi_big_msg.actual_length == SPI_TRANSACTION_LEN) {
			tx_count++;
			tx_size += spi_big_trans.len - SPI_MSG_HEADER_LEN;
			spi_tty_handle_data(spi_tty, spi_big_trans.rx_buf, SPI_TRANSACTION_LEN);
		}else {
			pr_err("%s: spi data transfer failed\n", __func__);
		}

		// wake up writes wait on queue
		wake_up_interruptible(&spi_tty->write_wait);

		spin_lock_irqsave(&(spi_tty->port_lock), flags);
	}

	spin_unlock_irqrestore(&(spi_tty->port_lock), flags);
	mutex_unlock(&(spi_tty->work_lock));
	SPI_IPC_INFO("%s: done\n", __func__);
	tx_time += jiffies_to_msecs(jiffies - start_t);
}