[MIPS] RTLX: Handle copy_*_user return values.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
@@ -289,26 +289,11 @@ unsigned int rtlx_write_poll(int index)
|
||||
return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size);
|
||||
}
|
||||
|
||||
static inline void copy_to(void *dst, void *src, size_t count, int user)
|
||||
{
|
||||
if (user)
|
||||
copy_to_user(dst, src, count);
|
||||
else
|
||||
memcpy(dst, src, count);
|
||||
}
|
||||
|
||||
static inline void copy_from(void *dst, void *src, size_t count, int user)
|
||||
{
|
||||
if (user)
|
||||
copy_from_user(dst, src, count);
|
||||
else
|
||||
memcpy(dst, src, count);
|
||||
}
|
||||
|
||||
ssize_t rtlx_read(int index, void *buff, size_t count, int user)
|
||||
ssize_t rtlx_read(int index, void __user *buff, size_t count, int user)
|
||||
{
|
||||
size_t lx_write, fl = 0L;
|
||||
struct rtlx_channel *lx;
|
||||
unsigned long failed;
|
||||
|
||||
if (rtlx == NULL)
|
||||
return -ENOSYS;
|
||||
@@ -327,11 +312,16 @@ ssize_t rtlx_read(int index, void *buff, size_t count, int user)
|
||||
/* then how much from the read pointer onwards */
|
||||
fl = min(count, (size_t)lx->buffer_size - lx->lx_read);
|
||||
|
||||
copy_to(buff, lx->lx_buffer + lx->lx_read, fl, user);
|
||||
failed = copy_to_user(buff, lx->lx_buffer + lx->lx_read, fl);
|
||||
if (failed)
|
||||
goto out;
|
||||
|
||||
/* and if there is anything left at the beginning of the buffer */
|
||||
if (count - fl)
|
||||
copy_to(buff + fl, lx->lx_buffer, count - fl, user);
|
||||
failed = copy_to_user(buff + fl, lx->lx_buffer, count - fl);
|
||||
|
||||
out:
|
||||
count -= failed;
|
||||
|
||||
smp_wmb();
|
||||
lx->lx_read = (lx->lx_read + count) % lx->buffer_size;
|
||||
@@ -341,7 +331,7 @@ ssize_t rtlx_read(int index, void *buff, size_t count, int user)
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
|
||||
ssize_t rtlx_write(int index, const void __user *buffer, size_t count, int user)
|
||||
{
|
||||
struct rtlx_channel *rt;
|
||||
size_t rt_read;
|
||||
@@ -363,11 +353,17 @@ ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
|
||||
/* first bit from write pointer to the end of the buffer, or count */
|
||||
fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
|
||||
|
||||
copy_from(rt->rt_buffer + rt->rt_write, buffer, fl, user);
|
||||
failed = copy_from_user(rt->rt_buffer + rt->rt_write, buffer, fl);
|
||||
if (failed)
|
||||
goto out;
|
||||
|
||||
/* if there's any left copy to the beginning of the buffer */
|
||||
if (count - fl)
|
||||
copy_from(rt->rt_buffer, buffer + fl, count - fl, user);
|
||||
if (count - fl) {
|
||||
failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
|
||||
}
|
||||
|
||||
out:
|
||||
count -= cailed;
|
||||
|
||||
smp_wmb();
|
||||
rt->rt_write = (rt->rt_write + count) % rt->buffer_size;
|
||||
@@ -426,7 +422,7 @@ static ssize_t file_read(struct file *file, char __user * buffer, size_t count,
|
||||
return 0; // -EAGAIN makes cat whinge
|
||||
}
|
||||
|
||||
return rtlx_read(minor, buffer, count, 1);
|
||||
return rtlx_read(minor, buffer, count);
|
||||
}
|
||||
|
||||
static ssize_t file_write(struct file *file, const char __user * buffer,
|
||||
@@ -452,7 +448,7 @@ static ssize_t file_write(struct file *file, const char __user * buffer,
|
||||
return ret;
|
||||
}
|
||||
|
||||
return rtlx_write(minor, (void *)buffer, count, 1);
|
||||
return rtlx_write(minor, buffer, count);
|
||||
}
|
||||
|
||||
static const struct file_operations rtlx_fops = {
|
||||
|
Reference in New Issue
Block a user