Browse Source

[MIPS] RTLX: Protect rtlx_{read,write} with mutex.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Ralf Baechle 18 years ago
parent
commit
bc4809e939
1 changed files with 6 additions and 0 deletions
  1. 6 0
      arch/mips/kernel/rtlx.c

+ 6 - 0
arch/mips/kernel/rtlx.c

@@ -54,6 +54,7 @@ static struct chan_waitqueues {
 	wait_queue_head_t rt_queue;
 	wait_queue_head_t rt_queue;
 	wait_queue_head_t lx_queue;
 	wait_queue_head_t lx_queue;
 	atomic_t in_open;
 	atomic_t in_open;
+	struct mutex mutex;
 } channel_wqs[RTLX_CHANNELS];
 } channel_wqs[RTLX_CHANNELS];
 
 
 static struct irqaction irq;
 static struct irqaction irq;
@@ -314,6 +315,7 @@ ssize_t rtlx_read(int index, void *buff, size_t count, int user)
 
 
 	lx = &rtlx->channel[index];
 	lx = &rtlx->channel[index];
 
 
+	mutex_lock(&channel_wqs[index].mutex);
 	smp_rmb();
 	smp_rmb();
 	lx_write = lx->lx_write;
 	lx_write = lx->lx_write;
 
 
@@ -334,6 +336,7 @@ ssize_t rtlx_read(int index, void *buff, size_t count, int user)
 	smp_wmb();
 	smp_wmb();
 	lx->lx_read = (lx->lx_read + count) % lx->buffer_size;
 	lx->lx_read = (lx->lx_read + count) % lx->buffer_size;
 	smp_wmb();
 	smp_wmb();
+	mutex_unlock(&channel_wqs[index].mutex);
 
 
 	return count;
 	return count;
 }
 }
@@ -349,6 +352,7 @@ ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
 
 
 	rt = &rtlx->channel[index];
 	rt = &rtlx->channel[index];
 
 
+	mutex_lock(&channel_wqs[index].mutex);
 	smp_rmb();
 	smp_rmb();
 	rt_read = rt->rt_read;
 	rt_read = rt->rt_read;
 
 
@@ -368,6 +372,7 @@ ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
 	smp_wmb();
 	smp_wmb();
 	rt->rt_write = (rt->rt_write + count) % rt->buffer_size;
 	rt->rt_write = (rt->rt_write + count) % rt->buffer_size;
 	smp_wmb();
 	smp_wmb();
+	mutex_unlock(&channel_wqs[index].mutex);
 
 
 	return count;
 	return count;
 }
 }
@@ -486,6 +491,7 @@ static int rtlx_module_init(void)
 		init_waitqueue_head(&channel_wqs[i].rt_queue);
 		init_waitqueue_head(&channel_wqs[i].rt_queue);
 		init_waitqueue_head(&channel_wqs[i].lx_queue);
 		init_waitqueue_head(&channel_wqs[i].lx_queue);
 		atomic_set(&channel_wqs[i].in_open, 0);
 		atomic_set(&channel_wqs[i].in_open, 0);
+		mutex_init(&channel_wqs[i].mutex);
 
 
 		dev = device_create(mt_class, NULL, MKDEV(major, i),
 		dev = device_create(mt_class, NULL, MKDEV(major, i),
 		                    "%s%d", module_name, i);
 		                    "%s%d", module_name, i);