Commit b01faf05 authored by Vijay Kumar B's avatar Vijay Kumar B Committed by Greg Kroah-Hartman
Browse files

Staging: poch: Fetch Flush IOCTL interface



Change user space interface to an IOCTL based interface instead of a
memory mapped circular buffer. The circular buffer had some serious
cache(?) issues and never worked.

Signed-off-by: default avatarVijay Kumar B. <vijaykumar@bravegnu.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 16fbf4cb
Loading
Loading
Loading
Loading
+56 −2
Original line number Diff line number Diff line
@@ -201,6 +201,8 @@ struct channel_info {
	struct page *header_pg;
	unsigned long header_size;

	/* Last group consumed by user space. */
	unsigned int consumed;
	/* Last group indicated as 'complete' to user space. */
	unsigned int transfer;

@@ -589,6 +591,7 @@ static int poch_channel_init(struct channel_info *channel,
	if (ret != 0)
		goto out;

	channel->consumed = 0;
	channel->transfer = 0;

	/* Allocate memory to hold group information. */
@@ -1033,6 +1036,51 @@ static int poch_ioctl(struct inode *inode, struct file *filp,
			break;
		}
		break;
	case POCH_IOC_CONSUME:
	{
		int available;
		int nfetch;
		unsigned int from;
		unsigned int count;
		unsigned int i, j;
		struct poch_consume consume;
		struct poch_consume *uconsume;

		uconsume = argp;
		ret = copy_from_user(&consume, uconsume, sizeof(consume));
		if (ret)
			return ret;

		spin_lock_irq(&channel->group_offsets_lock);

		channel->consumed += consume.nflush;
		channel->consumed %= channel->group_count;

		available = channel->transfer - channel->consumed;
		if (available < 0)
			available += channel->group_count;

		from = channel->consumed;

		spin_unlock_irq(&channel->group_offsets_lock);

		nfetch = consume.nfetch;
		count = min(available, nfetch);

		for (i = 0; i < count; i++) {
			j = (from + i) % channel->group_count;
			ret = put_user(channel->groups[j].user_offset,
				       &consume.offsets[i]);
			if (ret)
				return -EFAULT;
		}

		ret = put_user(count, &uconsume->nfetch);
		if (ret)
			return -EFAULT;

		break;
	}
	case POCH_IOC_GET_COUNTERS:
		if (!access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters)))
			return -EFAULT;
@@ -1108,12 +1156,18 @@ static void poch_irq_dma(struct channel_info *channel)
	for (i = 0; i < groups_done; i++) {
		j = (prev_transfer + i) % channel->group_count;
		group_offsets[j] = groups[j].user_offset;

		channel->transfer += 1;
		channel->transfer %= channel->group_count;

		if (channel->transfer == channel->consumed) {
			channel->consumed += 1;
			channel->consumed %= channel->group_count;
		}
	}

	spin_unlock(&channel->group_offsets_lock);

	channel->transfer = curr_transfer;

	wake_up_interruptible(&channel->wq);
}

+9 −0
Original line number Diff line number Diff line
@@ -19,6 +19,12 @@ struct poch_counters {
	__u32 pll_unlock;
};

struct poch_consume {
	__u32 __user *offsets;
	__u32 nfetch;
	__u32 nflush;
};

#define POCH_IOC_NUM			'9'

#define POCH_IOC_TRANSFER_START		_IO(POCH_IOC_NUM, 0)
@@ -27,3 +33,6 @@ struct poch_counters {
					     struct poch_counters)
#define POCH_IOC_SYNC_GROUP_FOR_USER	_IO(POCH_IOC_NUM, 3)
#define POCH_IOC_SYNC_GROUP_FOR_DEVICE	_IO(POCH_IOC_NUM, 4)

#define POCH_IOC_CONSUME		_IOWR(POCH_IOC_NUM, 5, \
					      struct poch_consume)