diff options
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/rtlx.c | 41 |
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 | ||
307 | ssize_t rtlx_read(int index, void *buff, size_t count, int user) | 307 | ssize_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) | |||
338 | ssize_t rtlx_write(int index, void *buffer, size_t count, int user) | 341 | ssize_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 | ||