aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/rtlx.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-03-16 08:16:27 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-03-16 21:03:29 -0400
commit46230aa6ea1671690e3e5efa2a961fc0745fe9b5 (patch)
tree9224af1ccdb48fac6d0b400b6a76e2d62f104972 /arch/mips/kernel/rtlx.c
parentbc4809e939b91c9642f1ddaea732e2d432ee6af6 (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.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)
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
292static inline void copy_to(void *dst, void *src, size_t count, int user) 292ssize_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
300static 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
308ssize_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
323out:
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
344ssize_t rtlx_write(int index, void *buffer, size_t count, int user) 334ssize_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
365out:
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
432static ssize_t file_write(struct file *file, const char __user * buffer, 428static 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
458static const struct file_operations rtlx_fops = { 454static const struct file_operations rtlx_fops = {