summaryrefslogtreecommitdiff
path: root/drivers/staging/comedi/comedi_fops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/comedi_fops.c')
-rw-r--r--drivers/staging/comedi/comedi_fops.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 8c784c483c3e..4dd42890c641 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -2346,6 +2346,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
add_wait_queue(&async->wait_head, &wait);
while (count == 0 && !retval) {
unsigned runflags;
+ unsigned int wp, n1, n2;
set_current_state(TASK_INTERRUPTIBLE);
@@ -2360,9 +2361,6 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
/* Allocate all free buffer space. */
comedi_buf_write_alloc(s, async->prealloc_bufsz);
m = comedi_buf_write_n_allocated(s);
- /* Avoid buffer wraparound. */
- if (async->buf_write_ptr + m > async->prealloc_bufsz)
- m = async->prealloc_bufsz - async->buf_write_ptr;
n = min_t(size_t, m, nbytes);
if (n == 0) {
@@ -2388,8 +2386,14 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
continue;
}
- m = copy_from_user(async->prealloc_buf + async->buf_write_ptr,
- buf, n);
+ wp = async->buf_write_ptr;
+ n1 = min(n, async->prealloc_bufsz - wp);
+ n2 = n - n1;
+ m = copy_from_user(async->prealloc_buf + wp, buf, n1);
+ if (m)
+ m += n2;
+ else if (n2)
+ m = copy_from_user(async->prealloc_buf, buf + n1, n2);
if (m) {
n -= m;
retval = -EFAULT;