aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/rtlx.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 16d3fdecf3ea..0441c7c1e44c 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -306,7 +306,7 @@ static inline void copy_from(void *dst, void *src, size_t count, int user)
306 306
307ssize_t rtlx_read(int index, void *buff, size_t count, int user) 307ssize_t rtlx_read(int index, void *buff, size_t count, int user)
308{ 308{
309 size_t fl = 0L; 309 size_t lx_write, fl = 0L;
310 struct rtlx_channel *lx; 310 struct rtlx_channel *lx;
311 311
312 if (rtlx == NULL) 312 if (rtlx == NULL)
@@ -314,23 +314,26 @@ ssize_t rtlx_read(int index, void *buff, size_t count, int user)
314 314
315 lx = &rtlx->channel[index]; 315 lx = &rtlx->channel[index];
316 316
317 smp_rmb();
318 lx_write = lx->lx_write;
319
317 /* find out how much in total */ 320 /* find out how much in total */
318 count = min(count, 321 count = min(count,
319 (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) 322 (size_t)(lx_write + lx->buffer_size - lx->lx_read)
320 % lx->buffer_size); 323 % lx->buffer_size);
321 324
322 /* then how much from the read pointer onwards */ 325 /* then how much from the read pointer onwards */
323 fl = min( count, (size_t)lx->buffer_size - lx->lx_read); 326 fl = min(count, (size_t)lx->buffer_size - lx->lx_read);
324 327
325 copy_to(buff, &lx->lx_buffer[lx->lx_read], fl, user); 328 copy_to(buff, lx->lx_buffer + lx->lx_read, fl, user);
326 329
327 /* and if there is anything left at the beginning of the buffer */ 330 /* and if there is anything left at the beginning of the buffer */
328 if ( count - fl ) 331 if (count - fl)
329 copy_to (buff + fl, lx->lx_buffer, count - fl, user); 332 copy_to(buff + fl, lx->lx_buffer, count - fl, user);
330 333
331 /* update the index */ 334 smp_wmb();
332 lx->lx_read += count; 335 lx->lx_read = (lx->lx_read + count) % lx->buffer_size;
333 lx->lx_read %= lx->buffer_size; 336 smp_wmb();
334 337
335 return count; 338 return count;
336} 339}
@@ -338,6 +341,7 @@ ssize_t rtlx_read(int index, void *buff, size_t count, int user)
338ssize_t rtlx_write(int index, void *buffer, size_t count, int user) 341ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
339{ 342{
340 struct rtlx_channel *rt; 343 struct rtlx_channel *rt;
344 size_t rt_read;
341 size_t fl; 345 size_t fl;
342 346
343 if (rtlx == NULL) 347 if (rtlx == NULL)
@@ -345,24 +349,27 @@ ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
345 349
346 rt = &rtlx->channel[index]; 350 rt = &rtlx->channel[index];
347 351
352 smp_rmb();
353 rt_read = rt->rt_read;
354
348 /* total number of bytes to copy */ 355 /* total number of bytes to copy */
349 count = min(count, 356 count = min(count,
350 (size_t)write_spacefree(rt->rt_read, rt->rt_write, 357 (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size));
351 rt->buffer_size));
352 358
353 /* first bit from write pointer to the end of the buffer, or count */ 359 /* first bit from write pointer to the end of the buffer, or count */
354 fl = min(count, (size_t) rt->buffer_size - rt->rt_write); 360 fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
355 361
356 copy_from (&rt->rt_buffer[rt->rt_write], buffer, fl, user); 362 copy_from(rt->rt_buffer + rt->rt_write, buffer, fl, user);
357 363
358 /* if there's any left copy to the beginning of the buffer */ 364 /* if there's any left copy to the beginning of the buffer */
359 if( count - fl ) 365 if (count - fl)
360 copy_from (rt->rt_buffer, buffer + fl, count - fl, user); 366 copy_from(rt->rt_buffer, buffer + fl, count - fl, user);
361 367
362 rt->rt_write += count; 368 smp_wmb();
363 rt->rt_write %= rt->buffer_size; 369 rt->rt_write = (rt->rt_write + count) % rt->buffer_size;
370 smp_wmb();
364 371
365 return(count); 372 return count;
366} 373}
367 374
368 375