/**
 * Kernel Queue를 2개를 생성하여 2개를 각각의 쓰레드로 실행시키는 함수.
 */
int __init init_fifo_test(void)
{
	unsigned int i;
	
	printk("fifo start\n");
	filp1 = filp_open("/tmp/read_sense", O_WRONLY, S_IRUSR|S_IWUSR);
	if (IS_ERR(filp1)) {
		const int open_errno = -PTR_ERR(filp1);
        printk("fifo1 open error: %s\n errno=%d", __FUNCTION__, open_errno);
		return 0;
	} else {
		printk("fifo1 open success\n");
	}

	filp = filp_open("/tmp/read_sense2", O_WRONLY, S_IRUSR|S_IWUSR);
	if (IS_ERR(filp)) {
		const int open_errno = -PTR_ERR(filp);
        printk("fifo open error: %s\n errno=%d", __FUNCTION__, open_errno);
		return 0;
	} else {
		printk("fifo open success\n");
	}
	
	printk("fifo1 module insert-----------\n");
	if( kfifo_alloc(&fifo1, FIFOSIZE, GFP_KERNEL) ) {
		printk(KERN_WARNING "fifo1 error kfifo_alloc1 \n");
		return -ENOMEM;
	}

	printk("fifo module insert-----------\n");
	if( kfifo_alloc(&fifo, FIFOSIZE, GFP_KERNEL) ) {
		printk(KERN_WARNING "fifo error kfifo_alloc \n");
		return -ENOMEM;
	}

	printk(KERN_INFO "queue1 size : %u \n", kfifo_size(&fifo1));
	printk(KERN_INFO "queue size : %u \n", kfifo_size(&fifo));

	printk(KERN_INFO "queue1 available : %u\n", kfifo_avail(&fifo1));
	printk(KERN_INFO "queue available : %u\n", kfifo_avail(&fifo));

#if 1
	printk(KERN_INFO "thread_start1\n");
	t_id1 = (struct task_struct *)kthread_run(thread_loop1, NULL, "%s", "create_test1");
	
	printk(KERN_INFO "thread_start\n");
	t_id = (struct task_struct *)kthread_run(thread_loop, NULL, "%s", "create_test");
#endif
	return 0;

}
示例#2
0
static int whiteheat_ioctl(struct tty_struct *tty,
					unsigned int cmd, unsigned long arg)
{
	struct usb_serial_port *port = tty->driver_data;
	struct serial_struct serstruct;
	void __user *user_arg = (void __user *)arg;

	dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);

	switch (cmd) {
	case TIOCGSERIAL:
		memset(&serstruct, 0, sizeof(serstruct));
		serstruct.type = PORT_16654;
		serstruct.line = port->serial->minor;
		serstruct.port = port->number;
		serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
		serstruct.xmit_fifo_size = kfifo_size(&port->write_fifo);
		serstruct.custom_divisor = 0;
		serstruct.baud_base = 460800;
		serstruct.close_delay = CLOSING_DELAY;
		serstruct.closing_wait = CLOSING_DELAY;

		if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
			return -EFAULT;
		break;
	default:
		break;
	}

	return -ENOIOCTLCMD;
}
示例#3
0
文件: kfifo.c 项目: HackLinux/kbuf
int kfifo_ready(struct kfifo *kfifo)
{
	if (kfifo) {
		return kfifo_size(kfifo) - kfifo_free(kfifo);
	}
	return 0;
}
示例#4
0
static long rpmsg_dev_ioctl(struct file *filp, unsigned int cmd,
                            unsigned long arg)
{
    unsigned int tmp;
    struct _rpmsg_device *_prpmsg_device = (struct _rpmsg_device *)filp->private_data;
    struct _rpmsg_params *local = ( struct _rpmsg_params *)&_prpmsg_device->rpmsg_params;

    switch (cmd)
    {
    case IOCTL_CMD_GET_KFIFO_SIZE:
        tmp = kfifo_size(&local->rpmsg_kfifo);
        if (copy_to_user((unsigned int *)arg, &tmp, sizeof(int)))
            return -EACCES;
        break;

    case IOCTL_CMD_GET_AVAIL_DATA_SIZE:
        tmp = kfifo_len(&local->rpmsg_kfifo);
        pr_info("kfifo len ioctl = %d ", kfifo_len(&local->rpmsg_kfifo));
        if (copy_to_user((unsigned int *)arg, &tmp, sizeof(int)))
            return -EACCES;
        break;
    case IOCTL_CMD_GET_FREE_BUFF_SIZE:
        tmp = kfifo_avail(&local->rpmsg_kfifo);
        if (copy_to_user((unsigned int *)arg, &tmp, sizeof(int)))
            return -EACCES;
        break;

    default:
        return -EINVAL;
    }

    return 0;
}
static int __logic_dispatch_push(ccif_msg_t *msg, void *ctl_b)
{
	logic_channel_info_t *ch_info;
	int ret = 0;
	logic_dispatch_ctl_block_t *ctl_block = (logic_dispatch_ctl_block_t*)ctl_b;
	int md_id = ctl_block->m_md_id;
	int drop = 1;

	if (unlikely(msg->channel >= CCCI_MAX_CH_NUM)){
		CCCI_MSG_INF(md_id, "cci", "%s get invalid logic ch id:%d\n", \
							__FUNCTION__, msg->channel);
		ret = -CCCI_ERR_INVALID_LOGIC_CHANNEL_ID;
		goto _out;
	}

	ch_info = &(ctl_block->m_logic_ch_table[msg->channel]);
	if (unlikely(ch_info->m_attrs&L_CH_ATTR_TX)){
		CCCI_MSG_INF(md_id, "cci", "%s CH:%d %s is tx channel\n", __FUNCTION__, \
							msg->channel, ch_info->m_ch_name);
		ret = -CCCI_ERR_PUSH_RX_DATA_TO_TX_CHANNEL;
		goto _out;
	}

	// check whether fifo is ready
	if (!ch_info->m_kfifo_ready){
		CCCI_MSG_INF(md_id, "cci", "%s CH:%d %s's kfifo is not ready\n", \
							__FUNCTION__, msg->channel, ch_info->m_ch_name);
		ret = -CCCI_ERR_KFIFO_IS_NOT_READY;
		goto _out;
	}

	// Check fifo free space
	if (kfifo_is_full(&ch_info->m_kfifo))
	{
		if (ch_info->m_attrs&L_CH_DROP_TOLERATED){
			CCCI_CTL_MSG(md_id, "Drop (%08X %08X %02d %08X) is tolerated\n", \
							msg->data[0], msg->data[1], msg->channel, msg->reserved);
			ret = sizeof(ccif_msg_t);
		} else {
			// message should NOT be droped
			CCCI_DBG_MSG(md_id, "cci", "kfifo full: ch:%s size:%d (%08X %08X %02d %08X)\n",
							ch_info->m_ch_name, kfifo_size(&ch_info->m_kfifo),msg->data[0], 
							msg->data[1], msg->channel, msg->reserved);
			// disalbe CCIF interrupt here????
			ret = 0; // Fix this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		}
		goto _out;
	}

	// Push data
	ret = kfifo_in(&ch_info->m_kfifo,msg,sizeof(ccif_msg_t));
	WARN_ON(ret!=sizeof(ccif_msg_t));
	ctl_block->m_has_pending_data = 1;
	drop = 0;
_out:
	add_logic_layer_record(md_id, (ccci_msg_t*)msg, drop);
	return ret;
}
示例#6
0
static int iio_kfifo_remove_from(struct iio_buffer *r, void *data)
{
	int ret;
	struct iio_kfifo *kf = iio_to_kfifo(r);

	if (kfifo_size(&kf->kf) < r->bytes_per_datum)
		return -EBUSY;

	ret = kfifo_out(&kf->kf, data, r->bytes_per_datum);
	if (ret != r->bytes_per_datum)
		return -EBUSY;

	wake_up_interruptible_poll(&r->pollq, POLLOUT | POLLWRNORM);

	return 0;
}
示例#7
0
static int whiteheat_get_serial(struct tty_struct *tty,
				struct serial_struct *ss)
{
	struct usb_serial_port *port = tty->driver_data;

	ss->type = PORT_16654;
	ss->line = port->minor;
	ss->port = port->port_number;
	ss->xmit_fifo_size = kfifo_size(&port->write_fifo);
	ss->custom_divisor = 0;
	ss->baud_base = 460800;
	ss->close_delay = CLOSING_DELAY;
	ss->closing_wait = CLOSING_DELAY;

	return 0;
}
示例#8
0
static int __init queue_init(void)
{
	int          i;
	unsigned int ret;
	unsigned int val;

	printk(KERN_INFO "FIFO start\n");

	if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) {
		printk(KERN_WARNING "error kfifo\n");
		return -ENOMEM;
	}

	printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo));

	kfifo_in(&fifo, "test", 4);

	for (i = 0; i < 4; i++)
		kfifo_in(&fifo, &i, sizeof(i));

	ret = kfifo_out(&fifo, buffer, 4);
	if (ret != 4)
		return -EINVAL;
	printk(KERN_INFO "%s\n", buffer);

	printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo));

	while (!kfifo_is_empty(&fifo)) {
		ret = kfifo_out(&fifo, &val, sizeof(val));
		if (ret != sizeof(val))
			return -EINVAL;
		printk(KERN_INFO "%u\n", val);
	}

	return 0;
}
示例#9
0
static int __init example_init(void)
{
	int			i;
	unsigned int		ret;
	unsigned int		nents;
	struct scatterlist	sg[10];

	printk(KERN_INFO "DMA fifo test start\n");

	if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) {
		printk(KERN_WARNING "error kfifo_alloc\n");
		return -ENOMEM;
	}

	printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo));

	kfifo_in(&fifo, "test", 4);

	for (i = 0; i != 9; i++)
		kfifo_put(&fifo, i);

	/* kick away first byte */
	kfifo_skip(&fifo);

	printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo));

	/*
	 * Configure the kfifo buffer to receive data from DMA input.
	 *
	 *  .--------------------------------------.
	 *  | 0 | 1 | 2 | ... | 12 | 13 | ... | 31 |
	 *  |---|------------------|---------------|
	 *   \_/ \________________/ \_____________/
	 *    \          \                  \
	 *     \          \_allocated data   \
	 *      \_*free space*                \_*free space*
	 *
	 * We need two different SG entries: one for the free space area at the
	 * end of the kfifo buffer (19 bytes) and another for the first free
	 * byte at the beginning, after the kfifo_skip().
	 */
	sg_init_table(sg, ARRAY_SIZE(sg));
	nents = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE);
	printk(KERN_INFO "DMA sgl entries: %d\n", nents);
	if (!nents) {
		/* fifo is full and no sgl was created */
		printk(KERN_WARNING "error kfifo_dma_in_prepare\n");
		return -EIO;
	}

	/* receive data */
	printk(KERN_INFO "scatterlist for receive:\n");
	for (i = 0; i < nents; i++) {
		printk(KERN_INFO
		"sg[%d] -> "
		"page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
			i, sg[i].page_link, sg[i].offset, sg[i].length);

		if (sg_is_last(&sg[i]))
			break;
	}

	/* put here your code to setup and exectute the dma operation */
	/* ... */

	/* example: zero bytes received */
	ret = 0;

	/* finish the dma operation and update the received data */
	kfifo_dma_in_finish(&fifo, ret);

	/* Prepare to transmit data, example: 8 bytes */
	nents = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8);
	printk(KERN_INFO "DMA sgl entries: %d\n", nents);
	if (!nents) {
		/* no data was available and no sgl was created */
		printk(KERN_WARNING "error kfifo_dma_out_prepare\n");
		return -EIO;
	}

	printk(KERN_INFO "scatterlist for transmit:\n");
	for (i = 0; i < nents; i++) {
		printk(KERN_INFO
		"sg[%d] -> "
		"page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
			i, sg[i].page_link, sg[i].offset, sg[i].length);

		if (sg_is_last(&sg[i]))
			break;
	}

	/* put here your code to setup and exectute the dma operation */
	/* ... */

	/* example: 5 bytes transmitted */
	ret = 5;

	/* finish the dma operation and update the transmitted data */
	kfifo_dma_out_finish(&fifo, ret);

	ret = kfifo_len(&fifo);
	printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo));

	if (ret != 7) {
		printk(KERN_WARNING "size mismatch: test failed");
		return -EIO;
	}
	printk(KERN_INFO "test passed\n");

	return 0;
}
示例#10
0
static int __init example_init(void)
{
	int			i;
	unsigned int		ret;
	struct scatterlist	sg[10];

	printk(KERN_INFO "DMA fifo test start\n");

	if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) {
		printk(KERN_ERR "error kfifo_alloc\n");
		return 1;
	}

	printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo));

	kfifo_in(&fifo, "test", 4);

	for (i = 0; i != 9; i++)
		kfifo_put(&fifo, &i);

	/* kick away first byte */
	ret = kfifo_get(&fifo, &i);

	printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo));

	ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE);
	printk(KERN_INFO "DMA sgl entries: %d\n", ret);

	/* if 0 was returned, fifo is full and no sgl was created */
	if (ret) {
		printk(KERN_INFO "scatterlist for receive:\n");
		for (i = 0; i < ARRAY_SIZE(sg); i++) {
			printk(KERN_INFO
			"sg[%d] -> "
			"page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
				i, sg[i].page_link, sg[i].offset, sg[i].length);

			if (sg_is_last(&sg[i]))
				break;
		}

		/* but here your code to setup and exectute the dma operation */
		/* ... */

		/* example: zero bytes received */
		ret = 0;

		/* finish the dma operation and update the received data */
		kfifo_dma_in_finish(&fifo, ret);
	}

	ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8);
	printk(KERN_INFO "DMA sgl entries: %d\n", ret);

	/* if 0 was returned, no data was available and no sgl was created */
	if (ret) {
		printk(KERN_INFO "scatterlist for transmit:\n");
		for (i = 0; i < ARRAY_SIZE(sg); i++) {
			printk(KERN_INFO
			"sg[%d] -> "
			"page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
				i, sg[i].page_link, sg[i].offset, sg[i].length);

			if (sg_is_last(&sg[i]))
				break;
		}

		/* but here your code to setup and exectute the dma operation */
		/* ... */

		/* example: 5 bytes transmitted */
		ret = 5;

		/* finish the dma operation and update the transmitted data */
		kfifo_dma_out_finish(&fifo, ret);
	}

	printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo));

	return 0;
}
示例#11
0
/**
 * kfifo_avail - returns the number of bytes available in the FIFO
 * @fifo: the fifo to be used.
 */
 unsigned int kfifo_avail(struct kfifo *fifo)
{
	return kfifo_size(fifo) - kfifo_len(fifo);
}
示例#12
0
/**
 * kfifo_is_full - returns true if the fifo is full
 * @fifo: the fifo to be used.
 */
  int kfifo_is_full(struct kfifo *fifo)
{
	return kfifo_len(fifo) == kfifo_size(fifo);
}