summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/rtlx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/rtlx.c')
-rw-r--r--arch/mips/kernel/rtlx.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 745649e15adc..e6e3047151a6 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -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 = {
OpenPOWER on IntegriCloud