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

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
...@@ -201,6 +201,8 @@ struct channel_info { ...@@ -201,6 +201,8 @@ struct channel_info {
struct page *header_pg; struct page *header_pg;
unsigned long header_size; unsigned long header_size;
/* Last group consumed by user space. */
unsigned int consumed;
/* Last group indicated as 'complete' to user space. */ /* Last group indicated as 'complete' to user space. */
unsigned int transfer; unsigned int transfer;
...@@ -589,6 +591,7 @@ static int poch_channel_init(struct channel_info *channel, ...@@ -589,6 +591,7 @@ static int poch_channel_init(struct channel_info *channel,
if (ret != 0) if (ret != 0)
goto out; goto out;
channel->consumed = 0;
channel->transfer = 0; channel->transfer = 0;
/* Allocate memory to hold group information. */ /* Allocate memory to hold group information. */
...@@ -1033,6 +1036,51 @@ static int poch_ioctl(struct inode *inode, struct file *filp, ...@@ -1033,6 +1036,51 @@ static int poch_ioctl(struct inode *inode, struct file *filp,
break; break;
} }
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: case POCH_IOC_GET_COUNTERS:
if (!access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters))) if (!access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters)))
return -EFAULT; return -EFAULT;
...@@ -1108,12 +1156,18 @@ static void poch_irq_dma(struct channel_info *channel) ...@@ -1108,12 +1156,18 @@ static void poch_irq_dma(struct channel_info *channel)
for (i = 0; i < groups_done; i++) { for (i = 0; i < groups_done; i++) {
j = (prev_transfer + i) % channel->group_count; j = (prev_transfer + i) % channel->group_count;
group_offsets[j] = groups[j].user_offset; 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); spin_unlock(&channel->group_offsets_lock);
channel->transfer = curr_transfer;
wake_up_interruptible(&channel->wq); wake_up_interruptible(&channel->wq);
} }
......
...@@ -19,6 +19,12 @@ struct poch_counters { ...@@ -19,6 +19,12 @@ struct poch_counters {
__u32 pll_unlock; __u32 pll_unlock;
}; };
struct poch_consume {
__u32 __user *offsets;
__u32 nfetch;
__u32 nflush;
};
#define POCH_IOC_NUM '9' #define POCH_IOC_NUM '9'
#define POCH_IOC_TRANSFER_START _IO(POCH_IOC_NUM, 0) #define POCH_IOC_TRANSFER_START _IO(POCH_IOC_NUM, 0)
...@@ -27,3 +33,6 @@ struct poch_counters { ...@@ -27,3 +33,6 @@ struct poch_counters {
struct poch_counters) struct poch_counters)
#define POCH_IOC_SYNC_GROUP_FOR_USER _IO(POCH_IOC_NUM, 3) #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_SYNC_GROUP_FOR_DEVICE _IO(POCH_IOC_NUM, 4)
#define POCH_IOC_CONSUME _IOWR(POCH_IOC_NUM, 5, \
struct poch_consume)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment