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: Vijay Kumar B. <vijaykumar@bravegnu.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
16fbf4cba0
commit
b01faf0574
2 changed files with 65 additions and 2 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Reference in a new issue