diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2007-03-16 08:16:27 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-03-16 21:03:29 -0400 |
commit | 46230aa6ea1671690e3e5efa2a961fc0745fe9b5 (patch) | |
tree | 9224af1ccdb48fac6d0b400b6a76e2d62f104972 /arch/mips/kernel/rtlx.c | |
parent | bc4809e939b91c9642f1ddaea732e2d432ee6af6 (diff) |
[MIPS] RTLX: Handle copy_*_user return values.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/rtlx.c')
-rw-r--r-- | arch/mips/kernel/rtlx.c | 46 |
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) | |||
289 | return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); | 289 | return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); |
290 | } | 290 | } |
291 | 291 | ||
292 | static inline void copy_to(void *dst, void *src, size_t count, int user) | 292 | ssize_t rtlx_read(int index, void __user *buff, size_t count, int user) |
293 | { | ||
294 | if (user) | ||
295 | copy_to_user(dst, src, count); | ||
296 | else | ||
297 | memcpy(dst, src, count); | ||
298 | } | ||
299 | |||
300 | static inline void copy_from(void *dst, void *src, size_t count, int user) | ||
301 | { | ||
302 | if (user) | ||
303 | copy_from_user(dst, src, count); | ||
304 | else | ||
305 | memcpy(dst, src, count); | ||
306 | } | ||
307 | |||
308 | ssize_t rtlx_read(int index, void *buff, size_t count, int user) | ||
309 | { | 293 | { |
310 | size_t lx_write, fl = 0L; | 294 | size_t lx_write, fl = 0L; |
311 | struct rtlx_channel *lx; | 295 | struct rtlx_channel *lx; |
296 | unsigned long failed; | ||
312 | 297 | ||
313 | if (rtlx == NULL) | 298 | if (rtlx == NULL) |
314 | return -ENOSYS; | 299 | return -ENOSYS; |
@@ -327,11 +312,16 @@ ssize_t rtlx_read(int index, void *buff, size_t count, int user) | |||
327 | /* then how much from the read pointer onwards */ | 312 | /* then how much from the read pointer onwards */ |
328 | fl = min(count, (size_t)lx->buffer_size - lx->lx_read); | 313 | fl = min(count, (size_t)lx->buffer_size - lx->lx_read); |
329 | 314 | ||
330 | copy_to(buff, lx->lx_buffer + lx->lx_read, fl, user); | 315 | failed = copy_to_user(buff, lx->lx_buffer + lx->lx_read, fl); |
316 | if (failed) | ||
317 | goto out; | ||
331 | 318 | ||
332 | /* and if there is anything left at the beginning of the buffer */ | 319 | /* and if there is anything left at the beginning of the buffer */ |
333 | if (count - fl) | 320 | if (count - fl) |
334 | copy_to(buff + fl, lx->lx_buffer, count - fl, user); | 321 | failed = copy_to_user(buff + fl, lx->lx_buffer, count - fl); |
322 | |||
323 | out: | ||
324 | count -= failed; | ||
335 | 325 | ||
336 | smp_wmb(); | 326 | smp_wmb(); |
337 | lx->lx_read = (lx->lx_read + count) % lx->buffer_size; | 327 | 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) | |||
341 | return count; | 331 | return count; |
342 | } | 332 | } |
343 | 333 | ||
344 | ssize_t rtlx_write(int index, void *buffer, size_t count, int user) | 334 | ssize_t rtlx_write(int index, const void __user *buffer, size_t count, int user) |
345 | { | 335 | { |
346 | struct rtlx_channel *rt; | 336 | struct rtlx_channel *rt; |
347 | size_t rt_read; | 337 | size_t rt_read; |
@@ -363,11 +353,17 @@ ssize_t rtlx_write(int index, void *buffer, size_t count, int user) | |||
363 | /* first bit from write pointer to the end of the buffer, or count */ | 353 | /* first bit from write pointer to the end of the buffer, or count */ |
364 | fl = min(count, (size_t) rt->buffer_size - rt->rt_write); | 354 | fl = min(count, (size_t) rt->buffer_size - rt->rt_write); |
365 | 355 | ||
366 | copy_from(rt->rt_buffer + rt->rt_write, buffer, fl, user); | 356 | failed = copy_from_user(rt->rt_buffer + rt->rt_write, buffer, fl); |
357 | if (failed) | ||
358 | goto out; | ||
367 | 359 | ||
368 | /* if there's any left copy to the beginning of the buffer */ | 360 | /* if there's any left copy to the beginning of the buffer */ |
369 | if (count - fl) | 361 | if (count - fl) { |
370 | copy_from(rt->rt_buffer, buffer + fl, count - fl, user); | 362 | failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl); |
363 | } | ||
364 | |||
365 | out: | ||
366 | count -= cailed; | ||
371 | 367 | ||
372 | smp_wmb(); | 368 | smp_wmb(); |
373 | rt->rt_write = (rt->rt_write + count) % rt->buffer_size; | 369 | 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, | |||
426 | return 0; // -EAGAIN makes cat whinge | 422 | return 0; // -EAGAIN makes cat whinge |
427 | } | 423 | } |
428 | 424 | ||
429 | return rtlx_read(minor, buffer, count, 1); | 425 | return rtlx_read(minor, buffer, count); |
430 | } | 426 | } |
431 | 427 | ||
432 | static ssize_t file_write(struct file *file, const char __user * buffer, | 428 | 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, | |||
452 | return ret; | 448 | return ret; |
453 | } | 449 | } |
454 | 450 | ||
455 | return rtlx_write(minor, (void *)buffer, count, 1); | 451 | return rtlx_write(minor, buffer, count); |
456 | } | 452 | } |
457 | 453 | ||
458 | static const struct file_operations rtlx_fops = { | 454 | static const struct file_operations rtlx_fops = { |